From e2a6260b6de390649e861a6deb8643f9cabad826 Mon Sep 17 00:00:00 2001
From: Alexandru Munteanu <alexandru.munt@gmail.com>
Date: Thu, 28 Jun 2018 18:37:15 +0300
Subject: [PATCH] feat(sort-by-importance): add sorting by importance

---
 .../components/Dashboard/DashboardFilters.js  |  1 +
 .../src/components/Dashboard/DashboardPage.js | 10 ++----
 .../src/components/Filters/importanceSort.js  | 31 +++++++++++++++++++
 .../src/components/Filters/index.js           |  1 +
 .../src/components/Filters/priorityFilter.js  | 17 +++++++---
 .../components/Filters/priorityFilter.test.js |  7 +----
 .../src/components/Filters/utils.js           | 25 ++++++++++++---
 .../src/components/Filters/withFilters.js     | 11 ++++---
 8 files changed, 76 insertions(+), 27 deletions(-)
 create mode 100644 packages/components-faraday/src/components/Filters/importanceSort.js

diff --git a/packages/components-faraday/src/components/Dashboard/DashboardFilters.js b/packages/components-faraday/src/components/Dashboard/DashboardFilters.js
index b291f63ef..06063f305 100644
--- a/packages/components-faraday/src/components/Dashboard/DashboardFilters.js
+++ b/packages/components-faraday/src/components/Dashboard/DashboardFilters.js
@@ -31,6 +31,7 @@ const DashboardFilters = ({
         inline
         onChange={changeFilterValue('order')}
         options={getFilterOptions('order')}
+        value={getDefaultFilterValue('order')}
       />
     </FilterGroup>
   </FiltersContainer>
diff --git a/packages/components-faraday/src/components/Dashboard/DashboardPage.js b/packages/components-faraday/src/components/Dashboard/DashboardPage.js
index fde2ae956..999e87de3 100644
--- a/packages/components-faraday/src/components/Dashboard/DashboardPage.js
+++ b/packages/components-faraday/src/components/Dashboard/DashboardPage.js
@@ -13,7 +13,7 @@ import { Dashboard } from './'
 import { getHandlingEditors } from '../../redux/editors'
 import { getUserPermissions } from '../../../../component-faraday-selectors/src'
 
-import { priorityFilter, withFiltersHOC } from '../Filters'
+import { priorityFilter, importanceSort, withFiltersHOC } from '../Filters'
 
 export default compose(
   ConnectPage(() => [actions.getCollections(), actions.getUsers()]),
@@ -64,13 +64,7 @@ export default compose(
   withJournal,
   withFiltersHOC({
     priority: priorityFilter,
-    order: {
-      options: [
-        { label: 'Newest first', value: 'newest' },
-        { label: 'Oldest first', value: 'oldest' },
-      ],
-      filterFn: () => () => true,
-    },
+    order: importanceSort,
   }),
   withContext(
     {
diff --git a/packages/components-faraday/src/components/Filters/importanceSort.js b/packages/components-faraday/src/components/Filters/importanceSort.js
new file mode 100644
index 000000000..b86f37c80
--- /dev/null
+++ b/packages/components-faraday/src/components/Filters/importanceSort.js
@@ -0,0 +1,31 @@
+import { get } from 'lodash'
+
+import { utils } from './'
+import cfg from '../../../../xpub-faraday/config/default'
+
+const statuses = get(cfg, 'statuses')
+export const SORT_VALUES = {
+  MORE_IMPORTANT: 'more_important',
+  LESS_IMPORTANT: 'less_important',
+}
+
+const options = [
+  { label: 'Imporant first', value: SORT_VALUES.MORE_IMPORTANT },
+  { label: 'Less important first', value: SORT_VALUES.LESS_IMPORTANT },
+]
+
+const sortFn = sortValue => (item1, item2) => {
+  const item1Importance = utils.getCollectionImportance(statuses, item1)
+  const item2Importance = utils.getCollectionImportance(statuses, item2)
+
+  if (sortValue === SORT_VALUES.MORE_IMPORTANT) {
+    return item2Importance - item1Importance
+  }
+  return item1Importance - item2Importance
+}
+
+export default {
+  sortFn,
+  options,
+  type: 'sort',
+}
diff --git a/packages/components-faraday/src/components/Filters/index.js b/packages/components-faraday/src/components/Filters/index.js
index 478766405..cec651407 100644
--- a/packages/components-faraday/src/components/Filters/index.js
+++ b/packages/components-faraday/src/components/Filters/index.js
@@ -3,3 +3,4 @@ import * as utils from './utils'
 export { utils }
 export { default as withFiltersHOC } from './withFilters'
 export { default as priorityFilter } from './priorityFilter'
+export { default as importanceSort } from './importanceSort'
diff --git a/packages/components-faraday/src/components/Filters/priorityFilter.js b/packages/components-faraday/src/components/Filters/priorityFilter.js
index 6821e81a2..4222f85fd 100644
--- a/packages/components-faraday/src/components/Filters/priorityFilter.js
+++ b/packages/components-faraday/src/components/Filters/priorityFilter.js
@@ -5,10 +5,16 @@ import cfg from '../../../../xpub-faraday/config/default'
 
 const statuses = get(cfg, 'statuses')
 
+export const FILTER_VALUES = {
+  ALL: 'all',
+  NEEDS_ATTENTION: 'needsAttention',
+  IN_PROGRESS: 'inProgress',
+}
+
 const options = [
-  { label: 'All', value: 'all' },
-  { label: 'Needs Attention', value: 'needsAttention' },
-  { label: 'In Progress', value: 'inProgress' },
+  { label: 'All', value: FILTER_VALUES.ALL },
+  { label: 'Needs Attention', value: FILTER_VALUES.NEEDS_ATTENTION },
+  { label: 'In Progress', value: FILTER_VALUES.IN_PROGRESS },
 ]
 
 const filterFn = (filterValue, { currentUser, userPermissions = [] }) => ({
@@ -21,9 +27,9 @@ const filterFn = (filterValue, { currentUser, userPermissions = [] }) => ({
   )
   const userRole = utils.getUserRole(currentUser, get(permission, 'role'))
   switch (filterValue) {
-    case 'needsAttention':
+    case FILTER_VALUES.NEEDS_ATTENTION:
       return get(statuses, `${status}.${userRole}.needsAttention`)
-    case 'inProgress':
+    case FILTER_VALUES.IN_PROGRESS:
       return !get(statuses, `${status}.${userRole}.needsAttention`)
     default:
       return true
@@ -33,4 +39,5 @@ const filterFn = (filterValue, { currentUser, userPermissions = [] }) => ({
 export default {
   options,
   filterFn,
+  type: 'filter',
 }
diff --git a/packages/components-faraday/src/components/Filters/priorityFilter.test.js b/packages/components-faraday/src/components/Filters/priorityFilter.test.js
index 398869d18..ce0d9b6b0 100644
--- a/packages/components-faraday/src/components/Filters/priorityFilter.test.js
+++ b/packages/components-faraday/src/components/Filters/priorityFilter.test.js
@@ -1,5 +1,6 @@
 import fixturesService from 'pubsweet-component-fixture-service'
 
+import { FILTER_VALUES } from './priorityFilter'
 import { priorityFilter, utils } from './'
 
 const {
@@ -8,12 +9,6 @@ const {
 
 const { filterFn } = priorityFilter
 
-const FILTER_VALUES = {
-  ALL: 'all',
-  NEEDS_ATTENTION: 'needsAttention',
-  IN_PROGRESS: 'inProgress',
-}
-
 describe('Priority filter function for reviewersInvited status', () => {
   describe('ALL', () => {
     it('should return true if ALL is selected', () => {
diff --git a/packages/components-faraday/src/components/Filters/utils.js b/packages/components-faraday/src/components/Filters/utils.js
index adb36cf50..8dabf8b2f 100644
--- a/packages/components-faraday/src/components/Filters/utils.js
+++ b/packages/components-faraday/src/components/Filters/utils.js
@@ -1,3 +1,5 @@
+import { get } from 'lodash'
+
 export const hydrateFilters = defaultValues => {
   const filterValues = localStorage.getItem('filterValues')
   if (filterValues) return JSON.parse(filterValues)
@@ -5,10 +7,22 @@ export const hydrateFilters = defaultValues => {
 }
 
 export const makeFilterFunctions = config =>
-  Object.entries(config).map(([filterKey, { filterFn }]) => ({
-    key: filterKey,
-    fn: filterFn,
-  }))
+  Object.entries(config)
+    .filter(([filterKey, { type }]) => type === 'filter')
+    .map(([filterKey, { filterFn }]) => ({
+      key: filterKey,
+      fn: filterFn,
+    }))
+
+export const makeSortFunction = config => {
+  const [sortKey, { sortFn }] = Object.entries(config).find(
+    ([filterKey, { type }]) => type !== 'filter',
+  )
+  return {
+    sortKey,
+    sortFn,
+  }
+}
 
 export const makeFilterValues = config =>
   Object.keys(config).reduce((acc, el) => ({ ...acc, [el]: '' }), {})
@@ -23,3 +37,6 @@ export const parsePermission = permission => ({
   objectId: permission.object.id,
   role: permission.group,
 })
+
+export const getCollectionImportance = (statuses, item) =>
+  get(statuses, `${get(item, 'status') || 'draft'}.importance`)
diff --git a/packages/components-faraday/src/components/Filters/withFilters.js b/packages/components-faraday/src/components/Filters/withFilters.js
index baee35d21..22c8ce546 100644
--- a/packages/components-faraday/src/components/Filters/withFilters.js
+++ b/packages/components-faraday/src/components/Filters/withFilters.js
@@ -6,6 +6,7 @@ import { utils } from './'
 export default config => Component => {
   const filterFns = utils.makeFilterFunctions(config)
   const filterValues = utils.makeFilterValues(config)
+  const { sortKey, sortFn } = utils.makeSortFunction(config)
 
   return compose(
     withState(
@@ -37,10 +38,12 @@ export default config => Component => {
         )
       },
       filterItems: ({ filterValues, ...props }) => items =>
-        filterFns.reduce(
-          (acc, { key, fn }) => acc.filter(fn(filterValues[key], props)),
-          items,
-        ),
+        filterFns
+          .reduce(
+            (acc, { key, fn }) => acc.filter(fn(filterValues[key], props)),
+            items,
+          )
+          .sort(sortFn(filterValues[sortKey], props)),
     }),
   )(Component)
 }
-- 
GitLab