Skip to content
Snippets Groups Projects
Commit 6a9f6176 authored by Alexandru Munteanu's avatar Alexandru Munteanu
Browse files

feat(filters): add priority filter

parent 371a64c2
No related branches found
No related tags found
1 merge request!13Sprint #14
......@@ -81,3 +81,10 @@ export const canMakeRevision = (state, collection) => {
collection.owners.map(o => o.id).includes(currentUserId)
)
}
export const getUserPermissions = ({ currentUser }) =>
get(currentUser, 'user.teams').map(t => ({
objectId: t.object.id,
objectType: t.object.type,
role: t.teamType.permissions,
}))
import React from 'react'
import styled from 'styled-components'
import { Button, th } from '@pubsweet/ui'
import { compose, withHandlers } from 'recompose'
import { compose, withProps } from 'recompose'
import { DashboardItems, DashboardFilters } from './'
const Dashboard = ({
filters,
getItems,
dashboard,
currentUser,
filterItems,
filterValues,
deleteProject,
dashboardItems,
getFilterOptions,
changeFilterValue,
getDefaultFilterValue,
createDraftSubmission,
...rest
}) => (
<Root>
<Header>
......@@ -33,26 +31,17 @@ const Dashboard = ({
</Header>
<DashboardFilters
changeFilterValue={changeFilterValue}
getDefaultFilterValue={getDefaultFilterValue}
getFilterOptions={getFilterOptions}
/>
<DashboardItems deleteProject={deleteProject} list={getItems()} />
<DashboardItems deleteProject={deleteProject} list={dashboardItems} />
</Root>
)
export default compose(
withHandlers({
getItems: ({
filters,
dashboard,
currentUser,
filterItems,
filterValues = {},
}) => () =>
filterItems(dashboard.all).sort((a, b) => {
if (filterValues.order === 'newest') return a.created - b.created < 0
return a.created - b.created > 0
}),
}),
withProps(({ dashboard, filterItems }) => ({
dashboardItems: filterItems(dashboard.all),
})),
)(Dashboard)
// #region styles
......
......@@ -12,36 +12,28 @@ const DashboardFilters = ({
changeFilter,
getFilterOptions,
changeFilterValue,
getDefaultFilterValue,
}) => (
<Root>
<FiltersContainer>
<span>Filter view:</span>
<FilterGroup>
<span>Owner</span>
<Menu
inline
onChange={changeFilterValue('owner')}
options={getFilterOptions('owner')}
/>
</FilterGroup>
<FilterGroup>
<span>Status</span>
<Menu
inline
onChange={changeFilterValue('status')}
options={getFilterOptions('status')}
/>
</FilterGroup>
<FilterGroup>
<span>Sort</span>
<Menu
inline
onChange={changeFilterValue('order')}
options={getFilterOptions('order')}
/>
</FilterGroup>
</FiltersContainer>
</Root>
<FiltersContainer>
<span>Filter view:</span>
<FilterGroup>
<span>Priority</span>
<Menu
inline
onChange={changeFilterValue('priority')}
options={getFilterOptions('priority')}
value={getDefaultFilterValue('priority')}
/>
</FilterGroup>
<FilterGroup>
<span>Sort</span>
<Menu
inline
onChange={changeFilterValue('order')}
options={getFilterOptions('order')}
/>
</FilterGroup>
</FiltersContainer>
)
export default compose(
......@@ -53,19 +45,14 @@ export default compose(
)(DashboardFilters)
// #region styles
const Root = styled.div`
const FiltersContainer = styled.div`
align-items: center;
border-bottom: ${th('borderDefault')};
color: ${th('colorPrimary')};
display: flex;
justify-content: space-between;
justify-content: flex-start;
margin: calc(${th('subGridUnit')} * 2) 0;
padding-bottom: calc(${th('subGridUnit')} * 2);
`
const FiltersContainer = styled.div`
align-items: center;
display: flex;
> span {
align-self: flex-end;
......
......@@ -12,6 +12,16 @@ import { createDraftSubmission } from 'pubsweet-component-wizard/src/redux/conve
import { Dashboard } from './'
import withFilters from './withFilters'
import { getHandlingEditors } from '../../redux/editors'
import cfg from '../../../../xpub-faraday/config/default'
import { getUserPermissions } from '../../../../component-faraday-selectors/src'
const statuses = get(cfg, 'statuses')
const getUserRole = (user, role) => {
if (user.admin) return 'admin'
if (user.editorInChief) return 'editorInChief'
return role
}
export default compose(
ConnectPage(() => [actions.getCollections(), actions.getUsers()]),
......@@ -37,7 +47,14 @@ export default compose(
),
all: sortedCollections,
}
return { collections, conversion, currentUser, dashboard }
const userPermissions = getUserPermissions(state)
return {
dashboard,
conversion,
collections,
currentUser,
userPermissions,
}
},
(dispatch, { history }) => ({
deleteProject: collection =>
......@@ -54,40 +71,26 @@ export default compose(
withRouter,
withJournal,
withFilters({
status: {
priority: {
options: [
{ label: 'All', value: 'all' },
{ label: 'Submitted', value: 'submitted' },
{ label: 'Draft', value: 'draft' },
{ label: 'HE Invited', value: 'heInvited' },
{ label: 'HE Assigned', value: 'heAssigned' },
{ label: 'Reviewers Invited', value: 'reviewersInvited' },
{ label: 'Under Review', value: 'underReview' },
],
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' },
{ label: 'Needs Attention', value: 'needsAttention' },
{ label: 'In Progress', value: 'inProgress' },
],
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)
filterFn: (filterValue, { currentUser, userPermissions = [] }) => ({
id,
status = 'draft',
}) => {
const permission = userPermissions.find(p => p.objectId === id)
const userRole = getUserRole(currentUser, get(permission, 'role'))
switch (filterValue) {
case 'needsAttention':
return get(statuses, `${status}.${userRole}.needsAttention`)
case 'inProgress':
return !get(statuses, `${status}.${userRole}.needsAttention`)
default:
return true
}
return false
},
},
order: {
......
import { get } from 'lodash'
import { compose, withState, withHandlers } from 'recompose'
const hydrateFilters = defaultValues => {
const filterValues = localStorage.getItem('filterValues')
if (filterValues) return JSON.parse(filterValues)
return defaultValues
}
export default config => Component => {
const filterFns = Object.entries(config).map(([filterKey, { filterFn }]) => ({
key: filterKey,
......@@ -11,14 +17,29 @@ export default config => Component => {
{},
)
return compose(
withState('filterValues', 'setFilterValues', filterValues),
withState('filterValues', 'setFilterValues', hydrateFilters(filterValues)),
withHandlers({
getFilterOptions: () => key => get(config, `${key}.options`) || [],
changeFilterValue: ({ setFilterValues }) => filterKey => value => {
setFilterValues(v => ({
...v,
[filterKey]: value,
}))
getDefaultFilterValue: ({ filterValues }) => key =>
get(filterValues, key) || '',
changeFilterValue: ({
setFilterValues,
filterValues,
}) => filterKey => value => {
// ugly but recompose doesn't pass the new state in the callback function
let newState = {}
setFilterValues(
v => {
newState = {
...v,
[filterKey]: value,
}
return newState
},
() => {
localStorage.setItem('filterValues', JSON.stringify(newState))
},
)
},
filterItems: ({ filterValues, ...props }) => items =>
filterFns.reduce(
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment