From 2dd143376d763a6c45c537c711f1a5e29cb36333 Mon Sep 17 00:00:00 2001 From: Alexandru Munteanu <alexandru.munteanu@thinslices.com> Date: Thu, 1 Feb 2018 21:21:01 +0200 Subject: [PATCH] Create withFilter decorator --- .../src/components/Dashboard/Dashboard.js | 45 +++++++++---------- .../components/Dashboard/DashboardFilters.js | 12 ++++- .../src/components/Dashboard/DashboardPage.js | 43 ++++++++++++++++-- .../src/components/Dashboard/withFilters.js | 30 +++++++++++++ 4 files changed, 100 insertions(+), 30 deletions(-) create mode 100644 packages/components-faraday/src/components/Dashboard/withFilters.js diff --git a/packages/components-faraday/src/components/Dashboard/Dashboard.js b/packages/components-faraday/src/components/Dashboard/Dashboard.js index 03de9a484..36429611c 100644 --- a/packages/components-faraday/src/components/Dashboard/Dashboard.js +++ b/packages/components-faraday/src/components/Dashboard/Dashboard.js @@ -17,6 +17,11 @@ const Dashboard = ({ listView, filters, getItems, + getFilterOptions, + changeFilterValue, + filterValues, + filterItems, + ...rest }) => ( <div className={classes.root}> <div className={classes.header}> @@ -25,7 +30,12 @@ const Dashboard = ({ New </Button> </div> - <DashboardFilters changeView={changeViewMode} listView={listView} /> + <DashboardFilters + changeFilterValue={changeFilterValue} + changeView={changeViewMode} + getFilterOptions={getFilterOptions} + listView={listView} + /> <DashboardItems deleteProject={deleteProject} list={getItems()} @@ -40,33 +50,18 @@ export default compose( sortOrder: state.filters.sortValue, })), withHandlers({ - getItems: ({ filters, sortOrder, currentUser, dashboard }) => () => { + getItems: ({ + filters, + sortOrder, + currentUser, + dashboard, + filterItems, + }) => () => { const userItems = get(currentUser, 'admin') ? dashboard.all : dashboard.owner - const statusItems = - filters.status === 'all' - ? userItems - : userItems.filter(item => { - const itemStatus = get(item, 'status') - if (!itemStatus && filters.status === 'draft') { - return true - } - return itemStatus === filters.status - }) - const ownerItems = - filters.owner === 'all' - ? statusItems - : statusItems.filter(item => { - const itemOwnerIds = item.owners.map(o => o.id) - if (filters.owner === 'me') { - return itemOwnerIds.includes(currentUser.id) - } else if (filters.owner === 'other') { - return !itemOwnerIds.includes(currentUser.id) - } - return false - }) - return ownerItems.sort((a, b) => { + + return filterItems(userItems).sort((a, b) => { if (sortOrder === 'newest') return a.created - b.created < 0 return a.created - b.created > 0 }) diff --git a/packages/components-faraday/src/components/Dashboard/DashboardFilters.js b/packages/components-faraday/src/components/Dashboard/DashboardFilters.js index 45ceb6508..898778b14 100644 --- a/packages/components-faraday/src/components/Dashboard/DashboardFilters.js +++ b/packages/components-faraday/src/components/Dashboard/DashboardFilters.js @@ -31,17 +31,25 @@ const DashboardFilters = ({ listView, changeFilter, changeSort, + getFilterOptions, + changeFilterValue, }) => ( <div className={classes.filtersContainer}> <div className={classes.filters}> Filter view: <div className={classes['filter-group']}> <span>Owner</span> - <Menu onChange={changeFilter('owner')} options={ownerFilterOptions} /> + <Menu + onChange={changeFilterValue('owner')} + options={getFilterOptions('owner')} + /> </div> <div className={classes['filter-group']}> <span>Status</span> - <Menu onChange={changeFilter('status')} options={statusFilterOptions} /> + <Menu + onChange={changeFilterValue('status')} + options={getFilterOptions('status')} + /> </div> <div className={classes['filter-group']}> <span>Sort</span> diff --git a/packages/components-faraday/src/components/Dashboard/DashboardPage.js b/packages/components-faraday/src/components/Dashboard/DashboardPage.js index 8b9978eba..3006b1890 100644 --- a/packages/components-faraday/src/components/Dashboard/DashboardPage.js +++ b/packages/components-faraday/src/components/Dashboard/DashboardPage.js @@ -1,13 +1,16 @@ -import { compose, withState, withHandlers } from 'recompose' +import { get } from 'lodash' import { connect } from 'react-redux' -import { withRouter } from 'react-router-dom' import { actions } from 'pubsweet-client' -import { newestFirst, selectCurrentUser } from 'xpub-selectors' import { ConnectPage } from 'xpub-connect' +import { withRouter } from 'react-router-dom' +import { compose, withState, withHandlers } from 'recompose' +import { newestFirst, selectCurrentUser } from 'xpub-selectors' import { createDraftSubmission } from 'pubsweet-component-wizard/src/redux/conversion' import Dashboard from './Dashboard' +import withFilters from './withFilters' + export default compose( ConnectPage(() => [ actions.getCollections(), @@ -51,4 +54,38 @@ export default compose( }), ), withRouter, + withFilters({ + status: { + options: [ + { label: 'All', value: 'all' }, + { label: 'Submitted', value: 'submitted' }, + { label: 'Draft', value: 'draft' }, + ], + filterFn: filterValue => item => { + if (filterValue === 'all' || filterValue === '') return true + const itemStatus = get(item, 'status') + if (!itemStatus && filterValue === 'draft') { + return true + } + return itemStatus === filterValue + }, + }, + owner: { + options: [ + { label: 'Everyone', value: 'all' }, + { label: 'My work', value: 'me' }, + { label: `Other's work`, value: 'other' }, + ], + filterFn: (filterValue, { currentUser }) => item => { + if (filterValue === 'all' || filterValue === '') return true + const itemOwnerIds = item.owners.map(o => o.id) + if (filterValue === 'me') { + return itemOwnerIds.includes(currentUser.id) + } else if (filterValue === 'other') { + return !itemOwnerIds.includes(currentUser.id) + } + return false + }, + }, + }), )(Dashboard) diff --git a/packages/components-faraday/src/components/Dashboard/withFilters.js b/packages/components-faraday/src/components/Dashboard/withFilters.js new file mode 100644 index 000000000..b51b7b6eb --- /dev/null +++ b/packages/components-faraday/src/components/Dashboard/withFilters.js @@ -0,0 +1,30 @@ +import { get } from 'lodash' +import { compose, withState, withHandlers } from 'recompose' + +export default config => Component => { + const filterFns = Object.entries(config).map(([filterKey, { filterFn }]) => ({ + key: filterKey, + fn: filterFn, + })) + const filterValues = Object.keys(config).reduce( + (acc, el) => ({ ...acc, [el]: '' }), + {}, + ) + return compose( + withState('filterValues', 'setFilterValues', filterValues), + withHandlers({ + getFilterOptions: () => key => get(config, `${key}.options`) || [], + changeFilterValue: ({ setFilterValues }) => filterKey => value => { + setFilterValues(v => ({ + ...v, + [filterKey]: value, + })) + }, + filterItems: ({ filterValues, ...props }) => items => + filterFns.reduce( + (acc, { key, fn }) => acc.filter(fn(filterValues[key], props)), + items, + ), + }), + )(Component) +} -- GitLab