Skip to content

Commit

Permalink
Merge pull request #59 from p632-sp-2017/filtering
Browse files Browse the repository at this point in the history
Filtering
  • Loading branch information
PrashanthKumarM authored Apr 21, 2017
2 parents 02d0637 + abd1cf9 commit 516f4ee
Show file tree
Hide file tree
Showing 13 changed files with 253 additions and 48 deletions.
3 changes: 0 additions & 3 deletions actionlist/.flowconfig
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@
; Ignore unexpected extra "@providesModule"
.*/node_modules/.*/node_modules/fbjs/.*

; Ignore unexpected extra "@providesModule"
.*/node_modules/react-native-router-flux/node_modules/.*

; Ignore duplicate module providers
; For RN Apps installed via npm, "Libraries" folder is inside
; "node_modules/react-native" but in the source repo it is in the root
Expand Down
4 changes: 2 additions & 2 deletions actionlist/__tests__/components/sideMenuSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ describe('SideMenu', () => {
<Provider store={store}>
<SideMenu />
</Provider>);
expect(wrapper.find(View).length).to.equal(9);
expect(wrapper.find(Text).length).to.equal(8);
expect(wrapper.find(View).length).to.equal(21);
expect(wrapper.find(Text).length).to.equal(15);
expect(wrapper.find(Text).first().text()).to.equal('Home');
expect(wrapper.find(Text).at(1).text()).to.equal('Preferences');
expect(wrapper.find(Text).at(2).text()).to.equal('Filter');
Expand Down
4 changes: 3 additions & 1 deletion actionlist/app/actions/action_items.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { createAction } from 'redux-actions';
import { TOGGLE_DRAWER, SORT_ACTION_LIST, SELECT_DROPDOWN_OPTION } from './types';
import { TOGGLE_DRAWER, SORT_ACTION_LIST, FILTER_ACTION_LIST, RESET_FILTERS, SELECT_DROPDOWN_OPTION } from './types';

export const toggleDrawer = createAction(TOGGLE_DRAWER);
export const filterActionList = createAction(FILTER_ACTION_LIST);
export const sortActionList = createAction(SORT_ACTION_LIST);
export const selectDropdownOption = createAction(SELECT_DROPDOWN_OPTION);
export const resetFilters = createAction(RESET_FILTERS);
2 changes: 2 additions & 0 deletions actionlist/app/actions/types.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export const TOGGLE_DRAWER = 'toggle_drawer';
export const FILTER_ACTION_LIST = 'filter_action_list';
export const SORT_ACTION_LIST = 'sort_action_list';
export const SELECT_DROPDOWN_OPTION = 'select_dropdown_option';
export const RESET_FILTERS = 'reset_filters';
138 changes: 101 additions & 37 deletions actionlist/app/components/SideMenu.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import React from 'react';

import {
StyleSheet,
View,
Text,
ScrollView,
TouchableHighlight,
} from 'react-native';

import Button from 'react-native-button';
import { Actions } from 'react-native-router-flux';
import Actions from 'react-native-router-flux';
import { connect } from 'react-redux';
import { sortActionList } from '../actions/action_items';
import { Colors, sortTypes } from '../lib/commons';
import { sortActionList, resetFilters } from '../actions/action_items';
import { Colors, sortTypes, filterTypes } from '../lib/commons';
import FilterPicker from './filterPicker';
import ContentHeader from './contentHeader';

const style = StyleSheet.create({
view: {
Expand All @@ -29,6 +31,29 @@ const style = StyleSheet.create({
textAlign: 'left',
borderBottomWidth: 0.5,
},
resetContainer: {
backgroundColor: '#990000',
padding: 5,
borderRadius: 8,
marginRight: 10,
marginLeft: 70,
marginBottom: 10,
marginTop: 10,
width: 100,
},
resetButton: {
fontSize: 10,
color: '#ffffff',
},
picker: {
fontSize: 10,
color: Colors.iuGray,
fontFamily: 'BentonSansBold, Arial, sans-serif',
},
container: {
backgroundColor: '#f4f7f9',
paddingTop: 0,
},
subtext: {
color: Colors.iuCrimson,
marginLeft: 15,
Expand All @@ -48,54 +73,93 @@ const style = StyleSheet.create({
},
});

const SideMenu = ({ optionSelected, onSort }) => (
<View style={style.view}>
<Button style={style.text} onPress={() => Actions.home()}>Home</Button>
<Button style={style.text} onPress={() => Actions.pref()} >Preferences</Button>
<Button style={style.text}>Filter</Button>
const SideMenu = ({ optionSelected,
filters,
onSort,
onReset,
}) => (
<ScrollView style={style.container}>
<View style={style.view}>
<Text style={style.text}>
Sort
</Text>
<TouchableHighlight onPress={() => onSort(sortTypes.creationDate)}>
<Text
style={(optionSelected === sortTypes.creationDate) ?
style.selected_text : style.subtext}
>Date Created</Text>
</TouchableHighlight>
<TouchableHighlight onPress={() => onSort(sortTypes.lastApprovedDate)}>
<Text
style={(optionSelected === sortTypes.lastApprovedDate) ?
style.selected_text : style.subtext}
>Date Last Approved</Text>
</TouchableHighlight>
<TouchableHighlight onPress={() => onSort(sortTypes.processType)}>
<Text
style={(optionSelected === sortTypes.processType) ?
style.selected_text : style.subtext}
>Process Type</Text>
</TouchableHighlight>
<TouchableHighlight onPress={() => onSort(sortTypes.actionRequested)}>
<Text
style={(optionSelected === sortTypes.actionRequested) ?
style.selected_text : style.subtext}
>Action Requested</Text>
</TouchableHighlight>
<Button style={style.text} onPress={() => Actions.home()}>Home</Button>
<Button style={style.text} onPress={() => Actions.pref()} >Preferences</Button>
<Button style={style.text}>Filter</Button>
<View style={style.view}>
<Text style={style.text}>
Sort
</Text>
<TouchableHighlight onPress={() => onSort(sortTypes.creationDate)}>
<Text
style={(optionSelected === sortTypes.creationDate) ?
style.selected_text : style.subtext}
>Date Created</Text>
</TouchableHighlight>
<TouchableHighlight onPress={() => onSort(sortTypes.lastApprovedDate)}>
<Text
style={(optionSelected === sortTypes.lastApprovedDate) ?
style.selected_text : style.subtext}
>Date Last Approved</Text>
</TouchableHighlight>
<TouchableHighlight onPress={() => onSort(sortTypes.processType)}>
<Text
style={(optionSelected === sortTypes.processType) ?
style.selected_text : style.subtext}
>Process Type</Text>
</TouchableHighlight>
<TouchableHighlight onPress={() => onSort(sortTypes.actionRequested)}>
<Text
style={(optionSelected === sortTypes.actionRequested) ?
style.selected_text : style.subtext}
>Action Requested</Text>
</TouchableHighlight>
<Text style={style.text}>Filter</Text>
<FilterPicker
filter={filterTypes.DocumentRouteStatus}
value={filters.documentRouteStatus}
filterKey={'documentRouteStatus'}
/>
<FilterPicker
filter={filterTypes.DocumentType}
value={filters.documentType}
filterKey={'documentType'}
/>
<FilterPicker
filter={filterTypes.ActionRequested}
value={filters.actionRequested}
filterKey={'actionRequested'}
/>
<ContentHeader>{filterTypes.DocumentCreatedDate.title}</ContentHeader>
<ContentHeader>{filterTypes.DocumentAssignedDate.title}</ContentHeader>
</View>
<Button
containerStyle={style.resetContainer}
style={style.resetButton}
onPress={() => onReset()}
>Reset Filters</Button>
</View>
</View>
</ScrollView>
);

const mapStateToProps = state => ({
optionSelected: state.actionItemsReducer.optionSelected,
filters: state.actionItemsReducer.filterStatus,
});

const mapDispatchToProps = dispatch => ({
onReset: () => dispatch(resetFilters()),
onSort: criteria => dispatch(sortActionList(criteria)),
});

SideMenu.propTypes = {
onSort: React.PropTypes.func.isRequired,
optionSelected: React.PropTypes.string.isRequired,
onReset: React.PropTypes.func.isRequired,
filters: React.PropTypes.shape({
documentRouteStatus: React.PropTypes.string,
documentType: React.PropTypes.string,
documentCreationDate: React.PropTypes.string,
documentAssignedDate: React.PropTypes.string,
actionRequested: React.PropTypes.string,
}).isRequired,
};

export default connect(mapStateToProps, mapDispatchToProps)(SideMenu);
1 change: 0 additions & 1 deletion actionlist/app/components/action_item_header.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,3 @@ ActionItemHeader.propTypes = {
};

export default ActionItemHeader;

28 changes: 28 additions & 0 deletions actionlist/app/components/contentHeader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react';
import {
StyleSheet,
View,
Text,
} from 'react-native';
import { Colors } from '../lib/commons';

const style = StyleSheet.create({
headerText: {
fontSize: 10,
color: Colors.iuCrimson,
fontFamily: 'BentonSansBold, Arial, sans-serif',
margin: 10,
},
});

const ContentHeader = props => (
<View>
<Text style={style.headerText}>{props.children}</Text>
</View>
);

ContentHeader.propTypes = {
children: React.PropTypes.node.isRequired,
};

export default ContentHeader;
16 changes: 14 additions & 2 deletions actionlist/app/components/display_list.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,17 @@ const styles = StyleSheet.create({
},
});

const DisplayList = ({ dataSource }) => (
const filterData = (dataSource, filters) => (
dataSource.filter(item => ((item.actionRequested.label === filters.actionRequested || filters.actionRequested === 'All') &&
(item.processType.label === filters.documentType || filters.documentType === 'All') &&
(item.processInstanceStatus.label === filters.documentRouteStatus || filters.documentRouteStatus === 'All')))
);

const DisplayList = ({ dataSource, filterStatus }) => (
<View style={styles.full_container}>
<LazyloadScrollView>
<Accordion
sections={dataSource}
sections={filterData(dataSource, filterStatus)}
renderHeader={ActionItemHeader}
renderContent={ActionItemBody}
/>
Expand All @@ -35,10 +41,16 @@ const DisplayList = ({ dataSource }) => (

const mapStateToProps = state => ({
dataSource: state.actionItemsReducer.dataSource,
filterStatus: state.actionItemsReducer.filterStatus,
});

DisplayList.propTypes = {
dataSource: React.PropTypes.arrayOf(React.PropTypes.shape({})).isRequired,
filterStatus: React.PropTypes.shape({
actionRequested: React.PropTypes.string,
documentType: React.PropTypes.string,
documentRouteStatus: React.PropTypes.string,
}).isRequired,
};

export default connect(mapStateToProps)(DisplayList);
43 changes: 43 additions & 0 deletions actionlist/app/components/filterPicker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from 'react';
import {
View,
Picker,
} from 'react-native';

/* eslint-disable no-unused-vars */
import { connect } from 'react-redux';
import { filterActionList } from '../actions/action_items';
import ContentHeader from './contentHeader';

const FilterPicker = ({ filter, value, filterKey, onActionListFiltering }) => (
<View>
<ContentHeader>{filter.title}</ContentHeader>
<Picker
selectedValue={value}
onValueChange={selectedOption => onActionListFiltering(filterKey, selectedOption)}
>
{
filter.data.map(i => (
<Picker.Item value={i} label={i} key={i} />
))
}
</Picker>
</View>
);

const mapDispatchToProps = dispatch => ({
onActionListFiltering: (filterType, value) =>
dispatch(filterActionList({ filterType, value })),
});

FilterPicker.propTypes = {
onActionListFiltering: React.PropTypes.func.isRequired,
filter: React.PropTypes.shape({
title: React.PropTypes.string,
data: React.PropTypes.arrayOf(React.PropTypes.string),
}).isRequired,
value: React.PropTypes.string.isRequired,
filterKey: React.PropTypes.string.isRequired,
};

export default connect(null, mapDispatchToProps)(FilterPicker);
30 changes: 30 additions & 0 deletions actionlist/app/lib/commons.js

Large diffs are not rendered by default.

24 changes: 22 additions & 2 deletions actionlist/app/reducers/action_items.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
/* eslint arrow-body-style: ["error", "as-needed", { "requireReturnForObjectLiteral": true }] */
import { handleActions } from 'redux-actions';
import { TOGGLE_DRAWER, SORT_ACTION_LIST, SELECT_DROPDOWN_OPTION } from '../actions/types';
import { processInstances, sortTypes, Colors } from '../lib/commons';
import { TOGGLE_DRAWER, SORT_ACTION_LIST, FILTER_ACTION_LIST, RESET_FILTERS, SELECT_DROPDOWN_OPTION } from '../actions/types';
import { processInstances, sortTypes, filterStatus, Colors } from '../lib/commons';

export const defaultState = {
dataSource: processInstances,
drawerExpanded: false,
filterStatus,
optionSelected: '',
dropdownColors: {
Saved: Colors.white,
Expand Down Expand Up @@ -94,8 +95,27 @@ const selectDropdownOption = (state, action) => {
};
};

const filterActionList = (state, action) => {
return {
...state,
filterStatus: {
...state.filterStatus,
[action.payload.filterType]: action.payload.value,
},
};
};

const resetFilters = (state) => {
return {
...state,
filterStatus,
};
};

export default handleActions({
[TOGGLE_DRAWER]: toggleDrawer,
[SORT_ACTION_LIST]: sortActionList,
[FILTER_ACTION_LIST]: filterActionList,
[SELECT_DROPDOWN_OPTION]: selectDropdownOption,
[RESET_FILTERS]: resetFilters,
}, defaultState);
1 change: 1 addition & 0 deletions actionlist/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"react-native-button": "^1.8.2",
"react-native-collapsible": "^0.8.0",
"react-native-drawer": "^2.3.0",
"react-native-radio-buttons": "^0.14.0",
"react-native-modal-dropdown": "^0.4.2",
"react-native-router-flux": "^3.38.0",
"react-native-side-menu": "^0.20.1",
Expand Down
7 changes: 7 additions & 0 deletions actionlist/test_constants/componentTests.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,12 @@ export const Middlewares = [];
export const InitialState = {
actionItemsReducer: {
sortValue: 'test',
filterStatus: {
documentRouteStatus: 'All',
documentType: 'All',
documentCreationDate: 'All',
documentAssignedDate: 'All',
actionRequested: 'All',
},
},
};

0 comments on commit 516f4ee

Please sign in to comment.