From 5fd5b90f510d95ab189dc2f074f55a8b4f223599 Mon Sep 17 00:00:00 2001 From: Boris Kovar Date: Tue, 15 Aug 2023 14:05:24 +0200 Subject: [PATCH] Squashed commit of the following: commit b6c21b9f74a0281bcf9883a7da07165bbbdc5695 Author: Boris Kovar Date: Tue Aug 15 12:32:55 2023 +0200 Squashed commit of the following: commit 60528709e830d424c07d290a7daf65cfcf3d9b2c Author: Boris Kovar Date: Tue Aug 15 12:31:31 2023 +0200 - implemented #1129 commit 86a1a7c9e26d899d34af4f6cdb85ceb19f207d0d Author: Boris Kovar Date: Tue Aug 15 09:49:39 2023 +0200 Squashed commit of the following: commit 0550be26180579a58c85c520b0930c44f4999011 Author: Boris Kovar Date: Tue Aug 15 08:46:33 2023 +0200 - fixed #1092 commit fcf418da068289847e2d7da1d72a19570a8832b0 Author: Boris Kovar Date: Fri Aug 11 09:19:38 2023 +0200 Squashed commit of the following: commit 5adc61adf29db66e7e09fd2d663c18d064305c33 Merge: a8c90f24 1aef079a Author: RobertMatuska Date: Thu Aug 10 15:31:40 2023 +0200 Merge branch '#1118' of https://github.com/m2ms/fragalysis-frontend into #1118 commit a8c90f245cf29df1cfee1b7053454cb7d0c0ad4a Author: RobertMatuska Date: Thu Aug 10 15:31:35 2023 +0200 #1118 fixed filter and sort bugs commit 1aef079a1728061be8c56f41967bf60666c79a17 Author: boriskovar-m2ms Date: Thu Aug 10 08:25:48 2023 +0200 Update package.json triggering build action commit 594ac1970c7099ecfb94cecc3707a6cc9ef2894f Merge: 5564d2ce de09cdc6 Author: RobertMatuska Date: Wed Aug 9 11:59:25 2023 +0200 Merge branch '#1106' into #1118 commit 5564d2ceaaea797542514f1a9fdfd8901591fb2b Author: RobertMatuska Date: Wed Aug 9 11:26:34 2023 +0200 #1118 change priority and fix bugs commit de09cdc6e9386ca3f6aea63fa373ef75938dec6d Merge: 4caeef7b 8b73ee22 Author: Boris Kovar Date: Tue Aug 8 11:38:09 2023 +0200 Merge branch '#1106' of https://github.com/m2ms/fragalysis-frontend into #1106 commit 4caeef7b2f6f9acbf617989b94e62030e6ed8052 Author: Boris Kovar Date: Tue Aug 8 11:37:40 2023 +0200 - updated table styling commit 8b73ee22d38fb5b93435c4c03fc537334adc3ebc Author: boriskovar-m2ms Date: Mon Aug 7 13:24:08 2023 +0200 Update package.json just to trigger build action commit d16130686039662cd7ebe0f9b6eeaadbe57d7d37 Author: Boris Kovar Date: Mon Aug 7 12:55:44 2023 +0200 - table is now autosized commit e867e77c40598a12fa10ca6ab526880274936752 Author: RobertMatuska Date: Mon Aug 7 09:03:11 2023 +0200 #1106 edited columns size # Conflicts: # js/components/projects/index.js # package.json --- js/components/nglView/renderingObjects.js | 2 +- js/components/projects/helperConstants.js | 6 +- js/components/projects/index.js | 370 ++------- .../projects/projectListSortFilterDialog.js | 104 ++- .../projects/projectListSortFilterItem.js | 777 +++++++++++------- js/components/projects/redux/actions.js | 50 +- js/components/projects/redux/constants.js | 40 +- js/components/projects/redux/reducer.js | 39 +- js/hooks/useGetJobDefinition.js | 14 +- js/reducers/ngl/dispatchActions.js | 58 +- package.json | 2 +- 11 files changed, 776 insertions(+), 686 deletions(-) diff --git a/js/components/nglView/renderingObjects.js b/js/components/nglView/renderingObjects.js index 070da083a..22a56f43a 100644 --- a/js/components/nglView/renderingObjects.js +++ b/js/components/nglView/renderingObjects.js @@ -355,7 +355,7 @@ const showArrow = ({ stage, input_dict, object_name, representations, orientatio let radius = input_dict.radius === undefined ? 0.3 : input_dict.radius; // Handle undefined start and finish if (input_dict.start === undefined || input_dict.end === undefined) { - const msgs = 'START OR END UNDEFINED FOR ARROW ' + input_dict.toString(); + const msgs = 'START OR END UNDEFINED FOR ARROW ' + JSON.stringify(input_dict); return Promise.reject(msgs); } let shape = new Shape(object_name, { disableImpostor: true }); diff --git a/js/components/projects/helperConstants.js b/js/components/projects/helperConstants.js index 8f738af0c..d1c609c7e 100644 --- a/js/components/projects/helperConstants.js +++ b/js/components/projects/helperConstants.js @@ -1,9 +1,9 @@ -export const moleculeProperty = { - createdAt: 'createdAt', +export const projectProperty = { + createdAt: 'init_date', name: 'name', target: 'target', targetAccessString: 'targetAccessString', description: 'description', authority: 'authority', - tags: 'tags', + tags: 'tags' }; diff --git a/js/components/projects/index.js b/js/components/projects/index.js index 025042784..1f376f174 100644 --- a/js/components/projects/index.js +++ b/js/components/projects/index.js @@ -34,7 +34,7 @@ import { setProjectModalOpen, setAddButton } from './redux/actions'; import { useDispatch, useSelector } from 'react-redux'; import { ProjectModal } from './projectModal'; import { loadListOfAllProjects, removeProject } from './redux/dispatchActions'; -import { setListOfFilteredProjects } from './redux/actions'; +import { setListOfFilteredProjects, setListOfProjects } from './redux/actions'; import { DJANGO_CONTEXT } from '../../utils/djangoContext'; import { isDiscourseAvailable, getExistingPost, openDiscourseLink } from '../../utils/discourse'; import { setOpenDiscourseErrorModal } from '../../reducers/api/actions'; @@ -52,8 +52,18 @@ import { compareCreatedAtDateAsc, compareCreatedAtDateDesc } from './sortProjects/sortProjects'; -import { setSortDialogOpen, setDefaultFilter } from './redux/actions'; -import { ProjectListSortFilterDialog } from './projectListSortFilterDialog'; +import { + setSortDialogOpen, + setDefaultFilter, + setSearchTarget, + setSearchName, + setSearchTargetAccessString, + setSearchDescription, + setSearchAuthority, + setSearchDateFrom, + setSearchDateTo +} from './redux/actions'; +import { ProjectListSortFilterDialog, sortProjects } from './projectListSortFilterDialog'; import { setFilter } from '../../reducers/selection/actions'; const useStyles = makeStyles(theme => ({ @@ -101,7 +111,8 @@ export const Projects = memo(({}) => { let filteredListOfProjects = useSelector(state => state.projectReducers.listOfFilteredProjects); let filteredListOfProjectsByDate = useSelector(state => state.projectReducers.listOfFilteredProjectsByDate); - const listOfAllProjectsDefault = useSelector(state => state.projectReducers.listOfProjects); + let listOfAllProjectsDefaultWithoutSort = useSelector(state => state.projectReducers.listOfProjects); + let listOfAllProjectsDefault = [...listOfAllProjectsDefaultWithoutSort].sort(compareCreatedAtDateDesc); // window height for showing rows per page const [windowHeight, setWindowHeight] = useState(window.innerHeight); @@ -118,102 +129,63 @@ export const Projects = memo(({}) => { let searchedByTargetAccessString = []; let searchedByAuthority = []; - let priorityOrder = []; let tags = []; let searchString = ''; const filterClean = useSelector(state => state.projectReducers.filterClean); const filter = useSelector(state => state.selectionReducers.filter); - const listOfAllProjects = [...listOfAllProjectsDefault].sort(compareCreatedAtDateDesc); + const isActiveFilter = !!(filter || {}).active; - useEffect(() => { - dispatch(loadListOfAllProjects()).catch(error => { - throw new Error(error); - }); - }, [dispatch]); + let listOfAllProjects = [...listOfAllProjectsDefault]; useEffect(() => { - sortProjects(); - }, [filter]); - - useEffect(() => { - // remove filter data - if (filterClean === true) { - dispatch(setListOfFilteredProjects(listOfAllProjects)); - dispatch(setDefaultFilter(false)); - searchedByName = []; - searchedByTarget = []; - searchedByDescription = []; - searchedByTargetAccessString = []; - searchedByAuthority = []; - priorityOrder = []; - const newFilter = { ...filter }; - newFilter.priorityOrder = ['createdAt', 'name', 'target', 'targetAccessString', 'description', 'authority']; - newFilter.filter.authority.order = 1; - newFilter.filter.description.order = 1; - newFilter.filter.name.order = 1; - newFilter.filter.target.order = 1; - newFilter.filter.createdAt.order = 1; - newFilter.filter.targetAccessString.order = 1; - dispatch(setFilter(newFilter)); - searchString = ''; + if (isActiveFilter) { + listOfAllProjectsDefault = sortProjects(listOfAllProjectsDefault, filter); + dispatch(setListOfProjects(listOfAllProjectsDefault)); + if (filteredListOfProjects !== undefined) { + filteredListOfProjects = sortProjects(filteredListOfProjects, filter); + dispatch(setListOfFilteredProjects(filteredListOfProjects)); + } } - }, [filterClean]); - - useEffect(() => { - sortProjects(); }, [filter]); useEffect(() => { - // remove filter data - if (filterClean === true) { - dispatch(setListOfFilteredProjects(listOfAllProjects)); - dispatch(setDefaultFilter(false)); - searchedByName = []; - searchedByTarget = []; - searchedByDescription = []; - searchedByTargetAccessString = []; - searchedByAuthority = []; - priorityOrder = []; - const newFilter = { ...filter }; - newFilter.priorityOrder = ['createdAt', 'name', 'target', 'targetAccessString', 'description', 'authority']; - newFilter.filter.authority.order = 1; - newFilter.filter.description.order = 1; - newFilter.filter.name.order = 1; - newFilter.filter.target.order = 1; - newFilter.filter.createdAt.order = 1; - newFilter.filter.targetAccessString.order = 1; - dispatch(setFilter(newFilter)); - searchString = ''; - } - }, [filterClean]); - - useEffect(() => { - sortProjects(); - }, [filter]); + dispatch(loadListOfAllProjects()).catch(error => { + throw new Error(error); + }); + }, [dispatch]); useEffect(() => { // remove filter data if (filterClean === true) { - dispatch(setListOfFilteredProjects(listOfAllProjects)); + dispatch(setListOfFilteredProjects(listOfAllProjectsDefault)); + dispatch(setListOfProjects(listOfAllProjectsDefault)); dispatch(setDefaultFilter(false)); - searchedByName = []; - searchedByTarget = []; - searchedByDescription = []; - searchedByTargetAccessString = []; - searchedByAuthority = []; - priorityOrder = []; + dispatch(setSearchTarget('')); + dispatch(setSearchName('')); + dispatch(setSearchTargetAccessString('')); + dispatch(setSearchDescription('')); + dispatch(setSearchAuthority('')); + dispatch(setSearchDateFrom('')); + dispatch(setSearchDateTo('')); const newFilter = { ...filter }; - newFilter.priorityOrder = ['createdAt', 'name', 'target', 'targetAccessString', 'description', 'authority']; + newFilter.priorityOrder = ['init_date', 'title', 'target', 'targetAccessString', 'description', 'authority']; + newFilter.sortOptions = [ + ['init_date', undefined], + ['title', undefined], + ['target', 'target.title'], + ['targetAccessString', 'project.target_access_string'], + ['description', undefined], + ['authority', 'project.authority'] + ]; newFilter.filter.authority.order = 1; newFilter.filter.description.order = 1; - newFilter.filter.name.order = 1; + newFilter.filter.title.order = 1; newFilter.filter.target.order = 1; - newFilter.filter.createdAt.order = 1; + newFilter.filter.init_date.order = 1; newFilter.filter.targetAccessString.order = 1; dispatch(setFilter(newFilter)); - searchString = ''; } }, [filterClean]); @@ -236,228 +208,6 @@ export const Projects = memo(({}) => { const offsetAuthority = 60; const offsetCreatedAt = 70; - const sortProjects = () => { - if (filter !== undefined) { - priorityOrder = filter.priorityOrder; - if (filteredListOfProjects === undefined && filteredListOfProjectsByDate === undefined) { - switch (priorityOrder[0]) { - case 'name': - if (filter.filter.name.order === -1) { - dispatch(setListOfFilteredProjects([...listOfAllProjects].sort(compareNameDesc))); - } else { - dispatch(setListOfFilteredProjects([...listOfAllProjects].sort(compareNameAsc))); - } - break; - case 'target': - if (filter.filter.target.order === -1) { - dispatch(setListOfFilteredProjects([...listOfAllProjects].sort(compareTargetDesc))); - } else { - dispatch(setListOfFilteredProjects([...listOfAllProjects].sort(compareTargetAsc))); - } - break; - case 'description': - if (filter.filter.description.order === -1) { - dispatch(setListOfFilteredProjects([...listOfAllProjects].sort(compareDescriptionDesc))); - } else { - dispatch(setListOfFilteredProjects([...listOfAllProjects].sort(compareDescriptionAsc))); - } - break; - case 'targetAccessString': - if (filter.filter.targetAccessString.order === -1) { - dispatch(setListOfFilteredProjects([...listOfAllProjects].sort(compareTargetAccessStringDesc))); - } else { - dispatch(setListOfFilteredProjects([...listOfAllProjects].sort(compareTargetAccessStringAsc))); - } - break; - case 'authority': - if (filter.filter.targetAccessString.order === -1) { - dispatch(setListOfFilteredProjects([...listOfAllProjects].sort(compareAuthorityDesc))); - } else { - dispatch(setListOfFilteredProjects([...listOfAllProjects].sort(compareAuthorityAsc))); - } - break; - case 'createdAt': - if (filter.filter.targetAccessString.order === -1) { - dispatch(setListOfFilteredProjects([...listOfAllProjects].sort(compareCreatedAtDateDesc))); - } else { - dispatch(setListOfFilteredProjects([...listOfAllProjects].sort(compareCreatedAtDateAsc))); - } - break; - } - } - if (filteredListOfProjects !== undefined && filteredListOfProjectsByDate === undefined) { - switch (priorityOrder[0]) { - case 'name': - if (filter.filter.name.order === -1) { - for (let a = 1; a < filteredListOfProjects.length; a++) { - dispatch(setListOfFilteredProjects([...filteredListOfProjects].sort(compareNameDesc))); - if (filteredListOfProjects[a - 1].title === filteredListOfProjects[a].title) { - if (priorityOrder[1] === 'createdAt') { - dispatch(setListOfFilteredProjects([...filteredListOfProjects].sort(compareCreatedAtDateDesc))); - } - } - } - dispatch(setListOfFilteredProjects([...filteredListOfProjects].sort(compareNameDesc))); - } else { - dispatch(setListOfFilteredProjects([...filteredListOfProjects].sort(compareNameAsc))); - } - break; - case 'target': - if (filter.filter.target.order === -1) { - dispatch(setListOfFilteredProjects([...filteredListOfProjects].sort(compareTargetDesc))); - } else { - dispatch(setListOfFilteredProjects([...filteredListOfProjects].sort(compareTargetAsc))); - } - break; - case 'description': - if (filter.filter.description.order === -1) { - dispatch(setListOfFilteredProjects([...filteredListOfProjects].sort(compareDescriptionDesc))); - } else { - dispatch(setListOfFilteredProjects([...filteredListOfProjects].sort(compareDescriptionAsc))); - } - break; - case 'targetAccessString': - if (filter.filter.targetAccessString.order === -1) { - dispatch(setListOfFilteredProjects([...filteredListOfProjects].sort(compareTargetAccessStringDesc))); - } else { - dispatch(setListOfFilteredProjects([...filteredListOfProjects].sort(compareTargetAccessStringAsc))); - } - break; - case 'authority': - if (filter.filter.authority.order === -1) { - dispatch(setListOfFilteredProjects([...filteredListOfProjects].sort(compareAuthorityDesc))); - } else { - dispatch(setListOfFilteredProjects([...filteredListOfProjects].sort(compareAuthorityAsc))); - } - break; - case 'createdAt': - if (filter.filter.createdAt.order === -1) { - dispatch(setListOfFilteredProjects([...filteredListOfProjects].sort(compareCreatedAtDateDesc))); - } else { - dispatch(setListOfFilteredProjects([...filteredListOfProjects].sort(compareCreatedAtDateAsc))); - } - break; - } - } - if (filteredListOfProjects === undefined && filteredListOfProjectsByDate !== undefined) { - switch (priorityOrder[0]) { - case 'name': - if (filter.filter.name.order === -1) { - for (let a = 1; a < filteredListOfProjectsByDate.length; a++) { - dispatch(setListOfFilteredProjects([...filteredListOfProjectsByDate].sort(compareNameDesc))); - if (filteredListOfProjectsByDate[a - 1].title === filteredListOfProjectsByDate[a].title) { - if (priorityOrder[1] === 'createdAt') { - dispatch( - setListOfFilteredProjects([...filteredListOfProjectsByDate].sort(compareCreatedAtDateDesc)) - ); - } - } - } - dispatch(setListOfFilteredProjects([...filteredListOfProjectsByDate].sort(compareNameDesc))); - } else { - dispatch(setListOfFilteredProjects([...filteredListOfProjectsByDate].sort(compareNameAsc))); - } - break; - case 'target': - if (filter.filter.target.order === -1) { - dispatch(setListOfFilteredProjects([...filteredListOfProjectsByDate].sort(compareTargetDesc))); - } else { - dispatch(setListOfFilteredProjects([...filteredListOfProjectsByDate].sort(compareTargetAsc))); - } - break; - case 'description': - if (filter.filter.description.order === -1) { - dispatch(setListOfFilteredProjects([...filteredListOfProjectsByDate].sort(compareDescriptionDesc))); - } else { - dispatch(setListOfFilteredProjects([...filteredListOfProjectsByDate].sort(compareDescriptionAsc))); - } - break; - case 'targetAccessString': - if (filter.filter.targetAccessString.order === -1) { - dispatch( - setListOfFilteredProjects([...filteredListOfProjectsByDate].sort(compareTargetAccessStringDesc)) - ); - } else { - dispatch(setListOfFilteredProjects([...filteredListOfProjectsByDate].sort(compareTargetAccessStringAsc))); - } - break; - case 'authority': - if (filter.filter.authority.order === -1) { - dispatch(setListOfFilteredProjects([...filteredListOfProjectsByDate].sort(compareAuthorityDesc))); - } else { - dispatch(setListOfFilteredProjects([...filteredListOfProjectsByDate].sort(compareAuthorityAsc))); - } - break; - case 'createdAt': - if (filter.filter.createdAt.order === -1) { - dispatch(setListOfFilteredProjects([...filteredListOfProjectsByDate].sort(compareCreatedAtDateDesc))); - } else { - dispatch(setListOfFilteredProjects([...filteredListOfProjectsByDate].sort(compareCreatedAtDateAsc))); - } - break; - } - } - } - if (filteredListOfProjects !== undefined && filteredListOfProjectsByDate !== undefined) { - const mergedFilteredList = filteredListOfProjects.filter(item1 => - filteredListOfProjectsByDate.some(item2 => item2.id === item1.id) - ); - - switch (priorityOrder[0]) { - case 'name': - if (filter.filter.name.order === -1) { - for (let a = 1; a < mergedFilteredList.length; a++) { - dispatch(setListOfFilteredProjects([...mergedFilteredList].sort(compareNameDesc))); - if (mergedFilteredList[a - 1].title === mergedFilteredList[a].title) { - if (priorityOrder[1] === 'createdAt') { - dispatch(setListOfFilteredProjects([...mergedFilteredList].sort(compareCreatedAtDateDesc))); - } - } - } - dispatch(setListOfFilteredProjects([...mergedFilteredList].sort(compareNameDesc))); - } else { - dispatch(setListOfFilteredProjects([...mergedFilteredList].sort(compareNameAsc))); - } - break; - case 'target': - if (filter.filter.target.order === -1) { - dispatch(setListOfFilteredProjects([...mergedFilteredList].sort(compareTargetDesc))); - } else { - dispatch(setListOfFilteredProjects([...mergedFilteredList].sort(compareTargetAsc))); - } - break; - case 'description': - if (filter.filter.description.order === -1) { - dispatch(setListOfFilteredProjects([...mergedFilteredList].sort(compareDescriptionDesc))); - } else { - dispatch(setListOfFilteredProjects([...mergedFilteredList].sort(compareDescriptionAsc))); - } - break; - case 'targetAccessString': - if (filter.filter.targetAccessString.order === -1) { - dispatch(setListOfFilteredProjects([...mergedFilteredList].sort(compareTargetAccessStringDesc))); - } else { - dispatch(setListOfFilteredProjects([...mergedFilteredList].sort(compareTargetAccessStringAsc))); - } - break; - case 'authority': - if (filter.filter.authority.order === -1) { - dispatch(setListOfFilteredProjects([...mergedFilteredList].sort(compareAuthorityDesc))); - } else { - dispatch(setListOfFilteredProjects([...mergedFilteredList].sort(compareAuthorityAsc))); - } - break; - case 'createdAt': - if (filter.filter.createdAt.order === -1) { - dispatch(setListOfFilteredProjects([...mergedFilteredList].sort(compareCreatedAtDateDesc))); - } else { - dispatch(setListOfFilteredProjects([...mergedFilteredList].sort(compareCreatedAtDateAsc))); - } - break; - } - } - }; - const changePrioOrder = (column, priorityOrder) => { const newPrioOrder = [...priorityOrder]; const withoutColumn = newPrioOrder.filter(item => item !== column); @@ -467,7 +217,7 @@ export const Projects = memo(({}) => { const handleHeaderSort = type => { if (filteredListOfProjects === undefined) { switch (type) { - case 'name': + case 'title': if (sortSwitch === offsetName + 1) { dispatch(setListOfFilteredProjects([...listOfAllProjects].sort(compareNameAsc))); setSortSwitch(sortSwitch + 1); @@ -546,7 +296,7 @@ export const Projects = memo(({}) => { } else { filteredListOfProjects = [...filteredListOfProjects].sort(compareCreatedAtDateDesc); switch (type) { - case 'name': + case 'title': if (filter !== undefined) { const newFilter = { ...filter }; newFilter.priorityOrder = changePrioOrder(type, newFilter.priorityOrder); @@ -556,7 +306,7 @@ export const Projects = memo(({}) => { if (filter !== undefined) { // change radio button in project list filter const newFilter = { ...filter }; - newFilter.filter.name.order = -1; + newFilter.filter.title.order = -1; dispatch(setFilter(newFilter)); } dispatch(setListOfFilteredProjects([...filteredListOfProjects].sort(compareNameAsc))); @@ -565,7 +315,7 @@ export const Projects = memo(({}) => { if (filter !== undefined) { // change radio button in project list filter const newFilter = { ...filter }; - newFilter.filter.name.order = 1; + newFilter.filter.title.order = 1; dispatch(setFilter(newFilter)); } dispatch(setListOfFilteredProjects([...filteredListOfProjects].sort(compareNameAsc))); @@ -587,12 +337,6 @@ export const Projects = memo(({}) => { newFilter.filter.target.order = -1; dispatch(setFilter(newFilter)); } - - for (let a = 1; a < filteredListOfProjects.length; a++) { - if (filteredListOfProjects[a - 1].target.title === filteredListOfProjects[a].target.title) { - //dva riadky maju rovnaký target - } - } dispatch(setListOfFilteredProjects([...filteredListOfProjects].sort(compareTargetAsc))); setSortSwitch(sortSwitch + 1); } else if (sortSwitch === offsetTarget + 2) { @@ -781,7 +525,11 @@ export const Projects = memo(({}) => { dispatch(setListOfFilteredProjects(uniqueArray)); }; - if (filteredListOfProjectsByDate !== undefined) { + if (filteredListOfProjects === undefined) { + filteredListOfProjects = [...listOfAllProjects]; + } + + if (filteredListOfProjectsByDate !== undefined && filteredListOfProjects !== undefined) { filteredListOfProjects = filteredListOfProjects.filter(item1 => filteredListOfProjectsByDate.some(item2 => item2.id === item1.id) ); @@ -847,7 +595,7 @@ export const Projects = memo(({}) => {
- + { /> Name - handleHeaderSort('name')}> + handleHeaderSort('title')}> {[1, 2].includes(sortSwitch - offsetName) ? ( sortSwitch % offsetName < 2 ? ( diff --git a/js/components/projects/projectListSortFilterDialog.js b/js/components/projects/projectListSortFilterDialog.js index 9f58d6775..bfd4a5e8a 100644 --- a/js/components/projects/projectListSortFilterDialog.js +++ b/js/components/projects/projectListSortFilterDialog.js @@ -7,11 +7,18 @@ import ProjectListSortFilterItem from './projectListSortFilterItem'; import WarningIcon from '@material-ui/icons/Warning'; import { makeStyles } from '@material-ui/styles'; import { useDispatch, useSelector } from 'react-redux'; -import { MOL_ATTRIBUTES } from './redux/constants'; +import { PROJECTS_ATTR } from './redux/constants'; import { setFilter } from '../../reducers/selection/actions'; import { Panel } from '../common/Surfaces/Panel'; -import { setSortDialogOpen, setListOfFilteredProjects, setListOfProjects, setDefaultFilter, setListOfFilteredProjectsByDate } from './redux/actions'; +import { + setSortDialogOpen, + setListOfFilteredProjects, + setListOfProjects, + setDefaultFilter, + setListOfFilteredProjectsByDate +} from './redux/actions'; import { debounce } from 'lodash'; +import { compareCreatedAtDateDesc } from './sortProjects/sortProjects'; const useStyles = makeStyles(theme => ({ title: { @@ -44,28 +51,54 @@ const useStyles = makeStyles(theme => ({ }, paper: { width: 490, - overflow: 'none', + overflow: 'none' } })); const widthPrio = 50; const widthOrder = 60; const widthProperty = 170; -const filterData = 160 - +const filterData = 160; export const getAttrDefinition = attr => { - return MOL_ATTRIBUTES.find(molAttr => molAttr.key === attr); + return PROJECTS_ATTR.find(molAttr => molAttr.key === attr); +}; + +const getNestedAttributeValue = (object, attribute, path) => { + if (!path) { + return object[attribute]; + } + + const pathAttributes = path.split('.'); + let attributeValue = object; + for (const pathAttribute of pathAttributes) { + attributeValue = attributeValue[pathAttribute]; + if (attributeValue === undefined) return undefined; + } + return attributeValue; +}; + +export const sortProjects = (projects, filter) => { + let sortedAttributes = filter.sortOptions.map(attr => attr); + return projects.sort((a, b) => { + for (const [attrName, path] of sortedAttributes) { + const order = filter.filter[attrName].order; + const val1 = getNestedAttributeValue(a, attrName, path); + const val2 = getNestedAttributeValue(b, attrName, path); + + if (val1 === val2) continue; + if (order === -1) { + return val1 > val2 ? -1 : 1; + } else { + return val1 < val2 ? -1 : 1; + } + } + return 0; + }); }; export const ProjectListSortFilterDialog = memo( - ({ - filter, - anchorEl, - open, - parentID = 'default', - placement = 'right-start', - }) => { + ({ filter, anchorEl, open, parentID = 'default', placement = 'right-start' }) => { let classes = useStyles(); const dispatch = useDispatch(); const initialize = useCallback(() => { @@ -73,16 +106,17 @@ export const ProjectListSortFilterDialog = memo( active: false, predefined: 'none', filter: {}, - priorityOrder: MOL_ATTRIBUTES.map(molecule => molecule.key) + priorityOrder: PROJECTS_ATTR.map(project => project.key), + sortOptions: PROJECTS_ATTR.map(project => [project.key, project.path]) }; - for (let attr of MOL_ATTRIBUTES) { + for (let attr of PROJECTS_ATTR) { const lowAttr = attr.key.toLowerCase(); initObject.filter[attr.key] = { priority: 0, order: 1, - isFloat: attr.isFloat, + isFloat: attr.isFloat }; } return initObject; @@ -91,17 +125,18 @@ export const ProjectListSortFilterDialog = memo( useEffect(() => { const init = initialize(); setInitState(init); - }, []) + }, []); const [initState, setInitState] = useState(initialize()); - const defaultListOfProjects = useSelector(state => state.projectReducers.listOfProjects); + let defaultListOfProjectsWithoutSort = useSelector(state => state.projectReducers.listOfProjects); + let defaultListOfProjects = [...defaultListOfProjectsWithoutSort].sort(compareCreatedAtDateDesc); filter = filter || initState; const handleFilterChange = useCallback( filter => { const filterSet = Object.assign({}, filter); - for (let attr of MOL_ATTRIBUTES) { + for (let attr of PROJECTS_ATTR) { if (filterSet.filter[attr.key].priority === undefined || filterSet.filter[attr.key].priority === '') { filterSet.filter[attr.key].priority = 0; } @@ -111,7 +146,6 @@ export const ProjectListSortFilterDialog = memo( [dispatch] ); - const handleItemChange = key => setting => { console.log(`handleItemChange attr: ${key} values: ${JSON.stringify(setting)}`); let newFilter = Object.assign({}, filter); @@ -121,11 +155,18 @@ export const ProjectListSortFilterDialog = memo( handleFilterChange(newFilter); }; + const findIndexByKey = key => { + const sortIndex = filter.sortOptions.findIndex(item => item[0] === key); + return sortIndex; + }; + const handlePrioChange = key => inc => () => { const maxPrio = 5; const minPrio = 0; let priorityOrder = filter.priorityOrder; + let sortOptions = filter.sortOptions; const index = filter.priorityOrder.indexOf(key); + const sortIndex = findIndexByKey(key); if (index > -1 && index + inc >= minPrio && index <= maxPrio) { priorityOrder.splice(index, 1); priorityOrder.splice(index + inc, 0, key); @@ -135,21 +176,31 @@ export const ProjectListSortFilterDialog = memo( dispatch(setFilter(newFilter)); handleFilterChange(newFilter); } + if (sortIndex > -1 && sortIndex + inc >= minPrio && sortIndex <= maxPrio) { + const path = sortOptions[sortIndex][1]; + sortOptions.splice(sortIndex, 1); + sortOptions.splice(sortIndex + inc, 0, [key, path]); + let newFilter = Object.assign({}, filter); + newFilter.sortOptions = sortOptions; + newFilter.active = true; + dispatch(setFilter(newFilter)); + handleFilterChange(newFilter); + } }; const handleClearFilter = debounce(() => { dispatch(setDefaultFilter(true)); dispatch(setSortDialogOpen(false)); - dispatch(setListOfFilteredProjects(defaultListOfProjects)); - dispatch(setListOfFilteredProjectsByDate(defaultListOfProjects)); - dispatch(setListOfProjects(defaultListOfProjects)); + dispatch(setListOfFilteredProjects(defaultListOfProjects.sort(compareCreatedAtDateDesc))); + dispatch(setListOfFilteredProjectsByDate(defaultListOfProjects.sort(compareCreatedAtDateDesc))); + dispatch(setListOfProjects(defaultListOfProjects.sort(compareCreatedAtDateDesc))); dispatch(setSortDialogOpen(true)); }); - dispatch(setFilter(filter)); + // Check for multiple attributes with same sorting priority let prioWarning = false; let prioWarningTest = {}; - for (const attr of MOL_ATTRIBUTES) { + for (const attr of PROJECTS_ATTR) { const prioKey = filter.filter[attr.key].priority; if (prioKey > 0) { prioWarningTest[prioKey] = prioWarningTest[prioKey] ? prioWarningTest[prioKey] + 1 : 1; @@ -207,10 +258,9 @@ export const ProjectListSortFilterDialog = memo( property - Filter data + Filter data - {filter.priorityOrder.map(attr => { let attrDef = getAttrDefinition(attr); return ( diff --git a/js/components/projects/projectListSortFilterItem.js b/js/components/projects/projectListSortFilterItem.js index 3ccda2527..ee65a18c8 100644 --- a/js/components/projects/projectListSortFilterItem.js +++ b/js/components/projects/projectListSortFilterItem.js @@ -12,10 +12,23 @@ import { makeStyles } from '@material-ui/styles'; import classNames from 'classnames'; import { useDispatch, useSelector } from 'react-redux'; import { debounce } from 'lodash'; -import { setListOfProjects, setListOfFilteredProjects, setListOfFilteredProjectsByDate } from './redux/actions'; -import DatePicker from "react-datepicker"; -import "react-datepicker/dist/react-datepicker.css"; -import { compareCreatedAtDateDesc} from './sortProjects/sortProjects'; +import { + setListOfProjects, + setListOfFilteredProjects, + setListOfFilteredProjectsByDate, + setSearchName, + setSearchTarget, + setSearchTargetAccessString, + setSearchAuthority, + setSearchDescription, + setSearchDateFrom, + setSearchDateTo +} from './redux/actions'; +import DatePicker from 'react-datepicker'; +import 'react-datepicker/dist/react-datepicker.css'; +import { compareCreatedAtDateDesc } from './sortProjects/sortProjects'; +import moment from 'moment'; +import { sortProjects } from './projectListSortFilterDialog'; const useStyles = makeStyles(theme => ({ centered: { @@ -65,8 +78,7 @@ const useStyles = makeStyles(theme => ({ propertyChip: { fontWeight: 'bolder' }, - dateInputWidth: - { + dateInputWidth: { width: '93px' }, dateFont: { @@ -87,11 +99,11 @@ const gridDateFromInputWidth = 90; const filterDataWidth = 185; let filteredProjectList = []; -let searchNameString = ""; -let searchTargetString = ""; -let searchTargetAccessString = ""; -let searchDescriptionString = ""; -let searchAuthorityString = ""; +let searchNameString = ''; +let searchTargetString = ''; +let searchTargetAccessString = ''; +let searchDescriptionString = ''; +let searchAuthorityString = ''; let filteredProjectListByName = []; let filteredProjectListByTarget = []; @@ -105,7 +117,7 @@ let filteredProjectListDate = []; const ProjectListSortFilterItem = memo(props => { const dispatch = useDispatch(); const { property, onChange, color, onChangePrio, filter, dateFilter } = props; - const { order} = props; + const { order } = props; let classes = useStyles(); @@ -117,253 +129,403 @@ const ProjectListSortFilterItem = memo(props => { const [startDate, setStartDate] = useState(); const [endDate, setEndDate] = useState(); - const [searchString, setSearchString] = useState(""); + const [searchString, setSearchString] = useState(''); - let listOfAllProjectsDefault = useSelector(state => state.projectReducers.listOfProjects); - const filteredListOfProjects = useSelector(state => state.projectReducers.listOfFilteredProjects); + let listOfAllProjectsDefaultWithOutSort = useSelector(state => state.projectReducers.listOfProjects); + let listOfAllProjectsDefault = [...listOfAllProjectsDefaultWithOutSort].sort(compareCreatedAtDateDesc); + let filteredListOfProjects = useSelector(state => state.projectReducers.listOfFilteredProjects); + + const searchName = useSelector(state => state.projectReducers.searchName); + const searchTarget = useSelector(state => state.projectReducers.searchTarget); + const searchDescription = useSelector(state => state.projectReducers.searchDescription); + const searchTargetAccessStringValue = useSelector(state => state.projectReducers.searchTargetAccessString); + const searchAuthority = useSelector(state => state.projectReducers.searchAuthority); + const searchDateFrom = useSelector(state => state.projectReducers.searchDateFrom); + const searchDateTo = useSelector(state => state.projectReducers.searchDateTo); + + const filters = useSelector(state => state.selectionReducers.filter); + + const isActiveFilter = !!(filters || {}).active; + const filterClean = useSelector(state => state.projectReducers.filterClean); let listOfAllProjects = [...listOfAllProjectsDefault].sort(compareCreatedAtDateDesc); useEffect(() => { if (filteredProjectList.length !== 0) { - dispatch(setListOfProjects(filteredProjectList))} - if (resetFilter === true) { - setSearchString(" "); + dispatch(setListOfProjects(filteredProjectList)); + } + if (resetFilter === true) { + setSearchString(' '); + } + }, [filteredProjectListByName, startDate, endDate, searchString, resetFilter]); + + useEffect(() => { + if (isActiveFilter) { + listOfAllProjectsDefault = sortProjects(listOfAllProjectsDefault, filters); + dispatch(setListOfProjects(listOfAllProjectsDefault)); + if (filteredListOfProjects !== undefined) { + filteredListOfProjects = sortProjects(filteredListOfProjects, filters); + dispatch(setListOfFilteredProjects(filteredListOfProjects.sort(compareCreatedAtDateDesc))); } - - },[filteredProjectListByName, startDate, endDate, searchString, resetFilter, searchNameString]); + } + }, [filter]); + + useEffect(() => { + // remove filter data + if (filterClean === true) { + searchNameString = ''; + searchTargetString = ''; + searchTargetAccessString = ''; + searchDescriptionString = ''; + searchAuthorityString = ''; + filteredProjectListByName = []; + filteredProjectListByTarget = []; + filteredProjectListByTargetAccessString = []; + filteredProjectListByDescription = []; + filteredProjectListByAuthority = []; + filteredProjectListByCreatedFrom = []; + filteredProjectListByCreatedTo = []; + filteredProjectListDate = []; + } + }, [filterClean]); + + const onChangeFilterString = (event, property) => { + if (property === 'Name') { + dispatch(setSearchName(event.target.value)); + } else if (property === 'Target') { + dispatch(setSearchTarget(event.target.value)); + } else if (property === 'Target access string') { + dispatch(setSearchTargetAccessString(event.target.value)); + } else if (property === 'Description') { + dispatch(setSearchDescription(event.target.value)); + } else if (property === 'Authority') { + dispatch(setSearchAuthority(event.target.value)); + } - const onChangeFilterString = event => { if (resetFilter === false) { - setSearchString(event.target.value) } - else if (resetFilter === true) { + setSearchString(event.target.value); + } else if (resetFilter === true) { return ProjectListSortFilterItem; - setSearchString(" "); } /* signal to React not to nullify the event object */ onChangeFilterStringDebounce(event.target.value); - } + }; const onChangeFilterStartDate = event => { + const formattedDate = moment(event).format('MM/DD/YYYY'); + const formattedStartDate = event.toISOString(); + dispatch(setSearchDateFrom(formattedDate)); setStartDate(event); - const formattedStartDate = event.toISOString(); + if (filteredListOfProjects === undefined) { - filteredProjectListByCreatedFrom = listOfAllProjects.filter(date => (date.init_date > formattedStartDate)); + filteredProjectListByCreatedFrom = listOfAllProjects.filter(date => date.init_date > formattedStartDate); + } else { + filteredProjectListByCreatedFrom = filteredListOfProjects.filter(date => date.init_date > formattedStartDate); } - else { - filteredProjectListByCreatedFrom = filteredListOfProjects.filter(date => (date.init_date > formattedStartDate)); - } - if (filteredProjectListByCreatedTo.length > 0 && filteredProjectListByCreatedFrom.length > 0 ) { - const filteredListOfProjectsByDate = filteredProjectListByCreatedFrom.filter(item1 => - filteredProjectListByCreatedTo.some(item2 => item2.id === item1.id)) - dispatch(setListOfFilteredProjectsByDate(filteredListOfProjectsByDate)); - } - else { + if (filteredProjectListByCreatedTo.length > 0 && filteredProjectListByCreatedFrom.length > 0) { + const filteredListOfProjectsByDate = filteredProjectListByCreatedFrom.filter(item1 => + filteredProjectListByCreatedTo.some(item2 => item2.id === item1.id) + ); + dispatch(setListOfFilteredProjectsByDate(filteredListOfProjectsByDate)); + } else { filteredProjectListDate = filteredProjectListByCreatedFrom; dispatch(setListOfFilteredProjectsByDate(filteredProjectListDate)); } - } - + }; + const onChangeFilterEndDate = event => { + const formattedEndDate = new Date(event.getTime() - event.getTimezoneOffset() * 779900).toISOString(); + const formattedDate = moment(event).format('MM/DD/YYYY'); + dispatch(setSearchDateTo(formattedDate)); setEndDate(event); - const formattedEndDate = new Date(event.getTime() - event.getTimezoneOffset() * 779900).toISOString(); if (filteredListOfProjects === undefined) { - filteredProjectListByCreatedTo = listOfAllProjects.filter(date => (date.init_date <= formattedEndDate +1)); - } - else { - filteredProjectListByCreatedTo = filteredListOfProjects.filter(date => (date.init_date <= formattedEndDate +1)); + filteredProjectListByCreatedTo = listOfAllProjects.filter(date => date.init_date <= formattedEndDate + 1); + } else { + filteredProjectListByCreatedTo = filteredListOfProjects.filter(date => date.init_date <= formattedEndDate + 1); } - if (filteredProjectListByCreatedTo.length > 0 && filteredProjectListByCreatedFrom.length > 0 ) { + if (filteredProjectListByCreatedTo.length > 0 && filteredProjectListByCreatedFrom.length > 0) { const filteredListOfProjectsByDate = filteredProjectListByCreatedFrom.filter(item1 => - filteredProjectListByCreatedTo.some(item2 => item2.id === item1.id)); - dispatch(setListOfFilteredProjectsByDate(filteredListOfProjectsByDate)); - } - else { + filteredProjectListByCreatedTo.some(item2 => item2.id === item1.id) + ); + dispatch(setListOfFilteredProjectsByDate(filteredListOfProjectsByDate)); + } else { filteredProjectListDate = filteredProjectListByCreatedTo; dispatch(setListOfFilteredProjects(filteredProjectListDate)); } - } + }; -const filterAllData = (value) => { - if (searchNameString !== "" && searchTargetString !== "" && (property === "Name" || property === "Target")) { - let filteredData1 = filteredProjectListByName.filter(item1 => - filteredProjectListByTarget.some(item2 => item2.id === item1.id) - ); - dispatch(setListOfFilteredProjects(filteredData1))} - - if (searchNameString !== "" && searchTargetAccessString !== "" && (property === "Name" || property === "Target access string")) { - let filteredData1 = filteredProjectListByName.filter(item1 => - filteredProjectListByTargetAccessString.some(item2 => item2.id === item1.id) - ); - dispatch(setListOfFilteredProjects(filteredData1))} - - if (searchNameString !== "" && searchDescriptionString !== "" && (property === "Name" || property === "Description")) { - let filteredData1 = filteredProjectListByName.filter(item1 => - filteredProjectListByDescription.some(item2 => item2.id === item1.id) - ); - dispatch(setListOfFilteredProjects(filteredData1))} - - if (searchNameString !== "" && searchAuthorityString !== "" && (property === "Name" || property === "Authority")) { - let filteredData1 = filteredProjectListByName.filter(item1 => - filteredProjectListByAuthority.some(item2 => item2.id === item1.id) - ); - dispatch(setListOfFilteredProjects(filteredData1))} - - if (searchTargetString !== "" && searchTargetAccessString !== "" && (property === "Target" || property === "Target access string")) { - let filteredData1 = filteredProjectListByTarget.filter(item1 => - filteredProjectListByTargetAccessString.some(item2 => item2.id === item1.id) - ); - dispatch(setListOfFilteredProjects(filteredData1))} - - if (searchTargetString !== "" && searchDescriptionString !== "" && (property === "Target" || property === "Description")) { - let filteredData1 = filteredProjectListByTarget.filter(item1 => - filteredProjectListByDescription.some(item2 => item2.id === item1.id) - ); - dispatch(setListOfFilteredProjects(filteredData1))} - - if (searchTargetString !== "" && searchAuthorityString !== "" && (property === "Target" || property === "Authority")) { - let filteredData1 = filteredProjectListByTarget.filter(item1 => - filteredProjectListByAuthority.some(item2 => item2.id === item1.id) - ); - dispatch(setListOfFilteredProjects(filteredData1))} - - if (searchTargetAccessString !== "" && searchDescriptionString !== "" && (property === "Target access string" || property === "Description")) { - let filteredData1 = filteredProjectListByTargetAccessString.filter(item1 => - filteredProjectListByDescription.some(item2 => item2.id === item1.id) - ); - dispatch(setListOfFilteredProjects(filteredData1))} - - if (searchDescriptionString !== "" && searchAuthorityString !== "" && (property === "Description" || property === "Authority")) { - let filteredData1 = filteredProjectListByDescription.filter(item1 => - filteredProjectListByAuthority.some(item2 => item2.id === item1.id) - ); - dispatch(setListOfFilteredProjects(filteredData1))} - - if (searchNameString !== "" && searchTargetString !== "" && searchTargetAccessString !== "" && (property === "Name" || property === "Target" || property === "Target access string")) { - let filteredData1 = filteredProjectListByName.filter(item1 => - filteredProjectListByTarget.some(item2 => item2.id === item1.id) && - filteredProjectListByTargetAccessString.some(item3=> item3.id === item1.id) - ); - dispatch(setListOfFilteredProjects(filteredData1))} - - if (searchNameString !== "" && searchTargetString !== "" && searchDescriptionString !== "" && (property === "Name" || property === "Target" || property === "Description")) { - let filteredData1 = filteredProjectListByName.filter(item1 => - filteredProjectListByTarget.some(item2 => item2.id === item1.id) && - filteredProjectListByDescription.some(item3=> item3.id === item1.id) - ); - dispatch(setListOfFilteredProjects(filteredData1))} - - if (searchNameString !== "" && searchTargetString !== "" && searchAuthorityString !== "" && (property === "Name" || property === "Target" || property === "Authority")) { - let filteredData1 = filteredProjectListByName.filter(item1 => - filteredProjectListByTarget.some(item2 => item2.id === item1.id) && - filteredProjectListByAuthority.some(item3=> item3.id === item1.id) - ); - - dispatch(setListOfFilteredProjects(filteredData1))} - if (searchTargetString !== "" && searchTargetAccessString !== "" && searchDescriptionString !== "" && (property === "Target access string" || property === "Target" || property === "Description")) { - let filteredData1 = filteredProjectListByTarget.filter(item1 => - filteredProjectListByTargetAccessString.some(item2 => item2.id === item1.id) && - filteredProjectListByDescription.some(item3=> item3.id === item1.id) - ); - dispatch(setListOfFilteredProjects(filteredData1))} - - if (searchTargetString !== "" && searchTargetAccessString !== "" && searchAuthorityString !== "" && (property === "Target" || property === "Target access string" || property === "Authority")) { - let filteredData1 = filteredProjectListByTarget.filter(item1 => - filteredProjectListByTargetAccessString.some(item2 => item2.id === item1.id) && - filteredProjectListByAuthority.some(item3=> item3.id === item1.id) - ); - dispatch(setListOfFilteredProjects(filteredData1))} - - if (searchTargetAccessString !== "" && searchDescriptionString !== "" && searchAuthorityString !== "" && (property === "Target access string" || property === "Description" || property === "Authority")) { - let filteredData1 = filteredProjectListByTargetAccessString.filter(item1 => - filteredProjectListByDescription.some(item2 => item2.id === item1.id) && - filteredProjectListByAuthority.some(item3=> item3.id === item1.id) - ); - dispatch(setListOfFilteredProjects(filteredData1))} - - if (searchNameString !== "" && property === "Name" && searchTargetString === "" && searchDescriptionString === "") { - const filteredData1 = listOfAllProjects.filter(item => item.title.toLowerCase().includes(value.toLowerCase())); - dispatch(setListOfFilteredProjects(filteredData1)) - } - if (searchTargetString !== "" && property === "Target" && searchNameString === "" && searchDescriptionString === "") { - const filteredData1 = listOfAllProjects.filter(item => item.target.title.toLowerCase().includes(value.toLowerCase())); - dispatch(setListOfFilteredProjects(filteredData1)) - } - if (searchDescriptionString !== "" && property === "Description" && searchTargetString === "" && searchTargetAccessString === "") { - const filteredData1 = listOfAllProjects.filter(item => item.description.toLowerCase().includes(value.toLowerCase())); - dispatch(setListOfFilteredProjects(filteredData1)) - } - if (searchTargetAccessString !== "" && property === "Target access string" && searchTargetString === "" && searchDescriptionString === "") { - const filteredData1 = listOfAllProjects.filter(item => item.project.target_access_string.toLowerCase().includes(value.toLowerCase())); - dispatch(setListOfFilteredProjects(filteredData1)) - } - if (searchAuthorityString !== "" && property === "Authority" && searchTargetString === "" && searchDescriptionString === "") { - const filteredData1 = listOfAllProjects.filter(item => item.project?.authority.toLowerCase().includes(value.toLowerCase())); - dispatch(setListOfFilteredProjects(filteredData1)) - } - if (searchNameString === "" && searchTargetString === "" && searchDescriptionString === "" && searchTargetAccessString === "" && searchAuthorityString === "") { - const filteredData1 = listOfAllProjects.filter(item => item.project?.authority.toLowerCase().includes(value.toLowerCase())); - dispatch(setListOfFilteredProjects(filteredData1)) - } -} - - - const onChangeFilterStringDebounce = debounce((value) => { - if (property === "Name") { - searchNameString = value; - if (filteredProjectListDate.length > 0) { - filteredProjectListByName = listOfAllProjects.filter(item => item.title.toLowerCase().includes(value.toLowerCase()));} - else { - filteredProjectListByName = listOfAllProjects.filter(item => item.title.toLowerCase().includes(value.toLowerCase())); - } - dispatch(setListOfFilteredProjects(filteredProjectListByName)); + const filterAllData = value => { + if (searchNameString !== '' && searchTargetString !== '') { + let filteredData1 = filteredProjectListByName.filter(item1 => + filteredProjectListByTarget.some(item2 => item2.id === item1.id) + ); + dispatch(setListOfFilteredProjects(filteredData1)); + } + + if (searchNameString !== '' && searchTargetAccessString !== '') { + let filteredData1 = filteredProjectListByName.filter(item1 => + filteredProjectListByTargetAccessString.some(item2 => item2.id === item1.id) + ); + dispatch(setListOfFilteredProjects(filteredData1)); + } + + if (searchNameString !== '' && searchDescriptionString !== '') { + let filteredData1 = filteredProjectListByName.filter(item1 => + filteredProjectListByDescription.some(item2 => item2.id === item1.id) + ); + dispatch(setListOfFilteredProjects(filteredData1)); + } + + if (searchNameString !== '' && searchAuthorityString !== '') { + let filteredData1 = filteredProjectListByName.filter(item1 => + filteredProjectListByAuthority.some(item2 => item2.id === item1.id) + ); + dispatch(setListOfFilteredProjects(filteredData1)); + } + + if (searchTargetString !== '' && searchTargetAccessString !== '') { + let filteredData1 = filteredProjectListByTarget.filter(item1 => + filteredProjectListByTargetAccessString.some(item2 => item2.id === item1.id) + ); + dispatch(setListOfFilteredProjects(filteredData1)); + } + + if (searchTargetString !== '' && searchDescriptionString !== '') { + let filteredData1 = filteredProjectListByTarget.filter(item1 => + filteredProjectListByDescription.some(item2 => item2.id === item1.id) + ); + dispatch(setListOfFilteredProjects(filteredData1)); + } + + if (searchTargetString !== '' && searchAuthorityString !== '') { + let filteredData1 = filteredProjectListByTarget.filter(item1 => + filteredProjectListByAuthority.some(item2 => item2.id === item1.id) + ); + dispatch(setListOfFilteredProjects(filteredData1)); + } + + if (searchTargetAccessString !== '' && searchDescriptionString !== '') { + let filteredData1 = filteredProjectListByTargetAccessString.filter(item1 => + filteredProjectListByDescription.some(item2 => item2.id === item1.id) + ); + dispatch(setListOfFilteredProjects(filteredData1)); + } + + if (searchDescriptionString !== '' && searchAuthorityString !== '') { + let filteredData1 = filteredProjectListByDescription.filter(item1 => + filteredProjectListByAuthority.some(item2 => item2.id === item1.id) + ); + dispatch(setListOfFilteredProjects(filteredData1)); + } + + if ( + searchNameString !== '' && + searchTargetString !== '' && + searchTargetAccessString !== '' && + (property === 'Name' || property === 'Target' || property === 'Target access string') + ) { + let filteredData1 = filteredProjectListByName.filter( + item1 => + filteredProjectListByTarget.some(item2 => item2.id === item1.id) && + filteredProjectListByTargetAccessString.some(item3 => item3.id === item1.id) + ); + dispatch(setListOfFilteredProjects(filteredData1)); + } + + if (searchNameString !== '' && searchTargetString !== '' && searchDescriptionString !== '') { + let filteredData1 = filteredProjectListByName.filter( + item1 => + filteredProjectListByTarget.some(item2 => item2.id === item1.id) && + filteredProjectListByDescription.some(item3 => item3.id === item1.id) + ); + dispatch(setListOfFilteredProjects(filteredData1)); + } + + if (searchNameString !== '' && searchTargetString !== '' && searchAuthorityString !== '') { + let filteredData1 = filteredProjectListByName.filter( + item1 => + filteredProjectListByTarget.some(item2 => item2.id === item1.id) && + filteredProjectListByAuthority.some(item3 => item3.id === item1.id) + ); + + dispatch(setListOfFilteredProjects(filteredData1)); + } + if (searchTargetString !== '' && searchTargetAccessString !== '' && searchDescriptionString !== '') { + let filteredData1 = filteredProjectListByTarget.filter( + item1 => + filteredProjectListByTargetAccessString.some(item2 => item2.id === item1.id) && + filteredProjectListByDescription.some(item3 => item3.id === item1.id) + ); + dispatch(setListOfFilteredProjects(filteredData1)); + } + + if (searchTargetString !== '' && searchTargetAccessString !== '' && searchAuthorityString !== '') { + let filteredData1 = filteredProjectListByTarget.filter( + item1 => + filteredProjectListByTargetAccessString.some(item2 => item2.id === item1.id) && + filteredProjectListByAuthority.some(item3 => item3.id === item1.id) + ); + dispatch(setListOfFilteredProjects(filteredData1)); + } + + if (searchTargetAccessString !== '' && searchDescriptionString !== '' && searchAuthorityString !== '') { + let filteredData1 = filteredProjectListByTargetAccessString.filter( + item1 => + filteredProjectListByDescription.some(item2 => item2.id === item1.id) && + filteredProjectListByAuthority.some(item3 => item3.id === item1.id) + ); + dispatch(setListOfFilteredProjects(filteredData1)); + } + + if ( + searchNameString !== '' && + searchTargetString === '' && + searchDescriptionString === '' && + searchTargetAccessString === '' && + searchAuthorityString === '' + ) { + const filteredData1 = listOfAllProjects.filter(item => + item.title.toLowerCase().includes(searchNameString.toLowerCase()) + ); + dispatch(setListOfFilteredProjects(filteredData1)); + } + if ( + searchTargetString !== '' && + searchNameString === '' && + searchDescriptionString === '' && + searchTargetAccessString === '' && + searchAuthorityString === '' + ) { + const filteredData1 = listOfAllProjects.filter(item => + item.target.title.toLowerCase().includes(searchTargetString.toLowerCase()) + ); + dispatch(setListOfFilteredProjects(filteredData1)); + } + if ( + searchDescriptionString !== '' && + searchTargetString === '' && + searchTargetAccessString === '' && + searchNameString == '' && + searchAuthorityString === '' + ) { + const filteredData1 = listOfAllProjects.filter(item => + item.description.toLowerCase().includes(searchDescriptionString.toLowerCase()) + ); + dispatch(setListOfFilteredProjects(filteredData1)); + } + if ( + searchTargetAccessString !== '' && + searchTargetString === '' && + searchDescriptionString === '' && + searchNameString === '' && + searchTargetAccessString === '' + ) { + const filteredData1 = listOfAllProjects.filter(item => + item.project.target_access_string.toLowerCase().includes(searchTargetAccessString.toLowerCase()) + ); + dispatch(setListOfFilteredProjects(filteredData1)); + } + if ( + searchAuthorityString !== '' && + searchTargetString === '' && + searchDescriptionString === '' && + searchNameString === '' && + searchTargetAccessString === '' + ) { + const filteredData1 = listOfAllProjects.filter(item => + item.project?.authority.toLowerCase().includes(searchAuthorityString.toLowerCase()) + ); + dispatch(setListOfFilteredProjects(filteredData1)); + } + if ( + searchNameString === '' && + searchTargetString === '' && + searchDescriptionString === '' && + searchTargetAccessString === '' && + searchAuthorityString === '' + ) { + const filteredData1 = sortProjects(listOfAllProjects, filters); + dispatch(setListOfFilteredProjects(filteredData1)); + dispatch(setListOfProjects(filteredData1)); + } + }; + + const onChangeFilterStringDebounce = debounce(value => { + if (property === 'Name') { + searchNameString = value; + if (filteredProjectListDate.length > 0) { + filteredProjectListByName = listOfAllProjects.filter(item => + item.title.toLowerCase().includes(value.toLowerCase()) + ); + } else { + filteredProjectListByName = listOfAllProjects.filter(item => + item.title.toLowerCase().includes(value.toLowerCase()) + ); + } + dispatch(setListOfFilteredProjects(filteredProjectListByName)); filterAllData(value); } - if (property === "Target") { + if (property === 'Target') { searchTargetString = value; - if (filteredProjectListDate.length > 0) { - filteredProjectListByTarget = listOfAllProjects.filter(item => item.target.title.toLowerCase().includes(value.toLowerCase()));} - else { - filteredProjectListByTarget = listOfAllProjects.filter(item => item.target.title.toLowerCase().includes(value.toLowerCase())); - } - dispatch(setListOfFilteredProjects(filteredProjectListByTarget)); + if (filteredProjectListDate.length > 0) { + filteredProjectListByTarget = listOfAllProjects.filter(item => + item.target.title.toLowerCase().includes(value.toLowerCase()) + ); + } else { + filteredProjectListByTarget = listOfAllProjects.filter(item => + item.target.title.toLowerCase().includes(value.toLowerCase()) + ); + } + dispatch(setListOfFilteredProjects(filteredProjectListByTarget)); filterAllData(value); } - - if(property === "Target access string") { + + if (property === 'Target access string') { searchTargetAccessString = value; - if (filteredProjectListDate.length > 0) { - filteredProjectListByTargetAccessString = listOfAllProjects.filter(item => item.project.target_access_string.toLowerCase().includes(value.toLowerCase()));} - else { - filteredProjectListByTargetAccessString = listOfAllProjects.filter(item => item.project.target_access_string.toLowerCase().includes(value.toLowerCase())); - } - dispatch(setListOfFilteredProjects(filteredProjectListByTargetAccessString)); + if (filteredProjectListDate.length > 0) { + filteredProjectListByTargetAccessString = listOfAllProjects.filter(item => + item.project.target_access_string.toLowerCase().includes(value.toLowerCase()) + ); + } else { + filteredProjectListByTargetAccessString = listOfAllProjects.filter(item => + item.project.target_access_string.toLowerCase().includes(value.toLowerCase()) + ); + } + dispatch(setListOfFilteredProjects(filteredProjectListByTargetAccessString)); filterAllData(value); } - if(property === "Description") { + if (property === 'Description') { searchDescriptionString = value; - if (filteredProjectListDate.length > 0) { - filteredProjectListByDescription = listOfAllProjects.filter(item => item.description.toLowerCase().includes(value.toLowerCase()));} - else { - filteredProjectListByDescription = listOfAllProjects.filter(item => item.description.toLowerCase().includes(value.toLowerCase())); - } - dispatch(setListOfFilteredProjects(filteredProjectListByDescription)); + if (filteredProjectListDate.length > 0) { + filteredProjectListByDescription = listOfAllProjects.filter(item => + item.description.toLowerCase().includes(value.toLowerCase()) + ); + } else { + filteredProjectListByDescription = listOfAllProjects.filter(item => + item.description.toLowerCase().includes(value.toLowerCase()) + ); + } + dispatch(setListOfFilteredProjects(filteredProjectListByDescription)); filterAllData(value); } - if(property === "Authority") { + if (property === 'Authority') { searchAuthorityString = value; - if (filteredProjectListDate.length > 0) { - filteredProjectListByAuthority = listOfAllProjects.filter(item => item.project?.authority.toLowerCase().includes(value.toLowerCase()));} - else { - filteredProjectListByAuthority = listOfAllProjects.filter(item => item.project?.authority.toLowerCase().includes(value.toLowerCase())); - } - dispatch(setListOfFilteredProjects(filteredProjectListByAuthority)); + if (filteredProjectListDate.length > 0) { + filteredProjectListByAuthority = listOfAllProjects.filter(item => + item.project?.authority.toLowerCase().includes(value.toLowerCase()) + ); + } else { + filteredProjectListByAuthority = listOfAllProjects.filter(item => + item.project?.authority.toLowerCase().includes(value.toLowerCase()) + ); + } + dispatch(setListOfFilteredProjects(filteredProjectListByAuthority)); filterAllData(value); } - },1000); + }, 1000); const handleChangeOrder = e => { const value = parseInt(e.target.value); @@ -416,91 +578,118 @@ const filterAllData = (value) => { - { resetFilter === false ? - filter && ( - - <> - - {dateFilter === true ? ( - - - - Created from - - - onChangeFilterStartDate(event)} - placeholderText='MM/DD/YYYY' - /> + {resetFilter === false + ? filter && ( + <> + + {dateFilter === true ? ( + + + Created from + + + onChangeFilterStartDate(event)} + placeholderText="MM/DD/YYYY" + value={searchDateFrom} + /> + + + + Created to + + + onChangeFilterEndDate(event)} + placeholderText="MM/DD/YYYY" + value={searchDateTo} + /> + - - - - Created to - - - onChangeFilterEndDate(event)} - placeholderText='MM/DD/YYYY' - /> + ) : ( + onChangeFilterString(event)} + key={property} + value={ + property === 'Name' + ? searchName + : property === 'Target' + ? searchTarget + : property === 'Description' + ? searchDescription + : property === 'Target access string' + ? searchTargetAccessStringValue + : property === 'Authority' + ? searchAuthority + : '' + } + > + )} + + + ) + : filter && ( + <> + + {dateFilter === true ? ( + + + Created from + + + onChangeFilterStartDate(event)} + placeholderText="MM/DD/YYYY" + value={searchDateFrom} + /> + + + Created to + + + onChangeFilterEndDate(event)} + placeholderText="MM/DD/YYYY" + value={searchDateTo} + /> + - - ) : - onChangeFilterString(event)} - key={property} - > - } - - - ) - : filter && ( - <> - - {dateFilter === true ? ( - - - - Created from - - - onChangeFilterStartDate(event)} - placeholderText='MM/DD/YYYY' - /> - - - Created to - - - onChangeFilterEndDate(event)} - placeholderText='MM/DD/YYYY' - /> - + ) : ( + onChangeFilterString(event, property)} + key={property} + value={ + property === 'Name' + ? searchName + : property === 'Target' + ? searchTarget + : property === 'Description' + ? searchDescription + : property === 'Target access string' + ? searchTargetAccessStringValue + : property === 'Authority' + ? searchAuthority + : '' + } + > + )} - ) : - onChangeFilterString(event)} - key={property} - > - } - - - ) - } + + )} ); }); diff --git a/js/components/projects/redux/actions.js b/js/components/projects/redux/actions.js index 8705b5fb2..d4837292e 100644 --- a/js/components/projects/redux/actions.js +++ b/js/components/projects/redux/actions.js @@ -34,8 +34,6 @@ export const setAddButton = isOpen => ({ payload: isOpen }); -setAddButton - export const setProjectModalIsLoading = isLoading => ({ type: constants.SET_PROJECT_MODAL_IS_LOADING, payload: isLoading @@ -159,3 +157,51 @@ export const refreshJobsData = () => { type: constants.REFRESH_JOBS_DATA }; }; + +export const setSearchName = searchName => { + return { + type: constants.SEARCH_NAME, + payload: searchName + }; +}; + +export const setSearchTarget = searchTarget => { + return { + type: constants.SEARCH_TARGET, + payload: searchTarget + }; +}; + +export const setSearchTargetAccessString = searchTargetAccessString => { + return { + type: constants.SEARCH_TARGET_ACCESS_STRING, + payload: searchTargetAccessString + }; +}; + +export const setSearchDescription = searchDescription => { + return { + type: constants.SEARCH_DESCRIPTION, + payload: searchDescription + }; +}; + +export const setSearchAuthority = searchAuthority => { + return { + type: constants.SEARCH_AUTHORITY, + payload: searchAuthority + }; +}; +export const setSearchDateFrom = searchDateFrom => { + return { + type: constants.SEARCH_DATE_FROM, + payload: searchDateFrom + }; +}; + +export const setSearchDateTo = searchDateTo => { + return { + type: constants.SEARCH_DATE_TO, + payload: searchDateTo + }; +}; diff --git a/js/components/projects/redux/constants.js b/js/components/projects/redux/constants.js index 9aca7afe8..ddc7cb684 100644 --- a/js/components/projects/redux/constants.js +++ b/js/components/projects/redux/constants.js @@ -39,7 +39,15 @@ export const constants = { SET_SORT_DIALOG_OPEN: prefix + 'SET_SORT_DIALOG_OPEN', SET_FILTER_CLEAN: prefix + 'SET_FILTER_CLEAN', - SET_ADD_BUTTON: prefix + 'SET_ADD_BUTTON' + SET_ADD_BUTTON: prefix + 'SET_ADD_BUTTON', + + SEARCH_NAME: prefix + 'SEARCH_NAME', + SEARCH_TARGET: prefix + 'SEARCH_TARGET', + SEARCH_DESCRIPTION: prefix + 'SEARCH_DESCRIPTION', + SEARCH_AUTHORITY: prefix + 'SEARCH_AUTHORITY', + SEARCH_TARGET_ACCESS_STRING: prefix + 'SEARCH_TARGET_ACCESS_STRING', + SEARCH_DATE_FROM: prefix + 'SEARCH_DATE_FROM', + SEARCH_DATE_TO: prefix + 'SEARCH_DATE_TO' }; export const ProjectCreationType = { @@ -58,22 +66,24 @@ export const SnapshotProjectType = { NOT_ASSIGNED: 'Not assigned to project' }; -export const MOL_ATTR = { +export const PROJECTS_ATT = { createdAt: { - key: 'createdAt', + key: 'init_date', name: 'Created at', isFloat: true, color: '#72e5be', filter: true, - dateFilter: true + dateFilter: true, + path: undefined }, name: { - key: 'name', + key: 'title', name: 'Name', isFloat: true, color: '#daa520', filter: true, - dateFilter: false + dateFilter: false, + path: undefined }, target: { key: 'target', @@ -81,7 +91,8 @@ export const MOL_ATTR = { isFloat: true, color: '#f96587', filter: true, - dateFilter: false + dateFilter: false, + path: 'target.title' }, targetAccessString: { key: 'targetAccessString', @@ -89,23 +100,26 @@ export const MOL_ATTR = { isFloat: true, color: '#ffe119', filter: true, - dateFilter: false + dateFilter: false, + path: 'project.target_access_string' }, description: { key: 'description', name: 'Description', - isFloat: false, + isFloat: true, color: '#f58231', filter: true, - dateFilter: false + dateFilter: false, + path: undefined }, authority: { key: 'authority', name: 'Authority', - isFloat: false, + isFloat: true, color: '#86844a', filter: true, - dateFilter: false + dateFilter: false, + path: 'project.authority' } /*tags: { key: 'tags', @@ -118,4 +132,4 @@ export const MOL_ATTR = { }*/ }; -export const MOL_ATTRIBUTES = Object.values(MOL_ATTR); +export const PROJECTS_ATTR = Object.values(PROJECTS_ATT); diff --git a/js/components/projects/redux/reducer.js b/js/components/projects/redux/reducer.js index 770942942..0908f78d7 100644 --- a/js/components/projects/redux/reducer.js +++ b/js/components/projects/redux/reducer.js @@ -165,8 +165,43 @@ export const projectReducers = (state = INITIAL_STATE, action = {}) => { case constants.SET_ADD_BUTTON: return Object.assign({}, state, { addButton: action.payload }); - - default: + + case constants.SEARCH_NAME: + return Object.assign({}, state, { + searchName: action.payload + }); + + case constants.SEARCH_TARGET: + return Object.assign({}, state, { + searchTarget: action.payload + }); + + case constants.SEARCH_DESCRIPTION: + return Object.assign({}, state, { + searchDescription: action.payload + }); + + case constants.SEARCH_TARGET_ACCESS_STRING: + return Object.assign({}, state, { + searchTargetAccessString: action.payload + }); + + case constants.SEARCH_AUTHORITY: + return Object.assign({}, state, { + searchAuthority: action.payload + }); + + case constants.SEARCH_DATE_FROM: + return Object.assign({}, state, { + searchDateFrom: action.payload + }); + + case constants.SEARCH_DATE_TO: + return Object.assign({}, state, { + searchDateTo: action.payload + }); + + default: return state; } }; diff --git a/js/hooks/useGetJobDefinition.js b/js/hooks/useGetJobDefinition.js index 9b5b4e90a..904c9e5eb 100644 --- a/js/hooks/useGetJobDefinition.js +++ b/js/hooks/useGetJobDefinition.js @@ -3,13 +3,19 @@ import { deepMerge } from '../utils/merge'; // Merges job definitions with fragalysis-jobs definitions const getSchemaDefinition = (configDefinitions, overrideDefinitions) => { - const mergedDefinitions = { ...configDefinitions }; + let mergedDefinitions = { ...configDefinitions }; Object.entries(overrideDefinitions).forEach(([key, overrideDefinition]) => { - let mergedDefinition = mergedDefinitions[key] || {}; + if (overrideDefinition.hasOwnProperty('ignore') && overrideDefinition['ignore'].toLowerCase() === 'true') { + if (mergedDefinitions.hasOwnProperty(key)) { + delete mergedDefinitions[key]; + } + } else { + let mergedDefinition = mergedDefinitions[key] || {}; - // mergedDefinitions[key] = { ...mergedDefinition, ...overrideDefinition }; - mergedDefinitions[key] = deepMerge({ ...mergedDefinition }, { ...overrideDefinition }); + // mergedDefinitions[key] = { ...mergedDefinition, ...overrideDefinition }; + mergedDefinitions[key] = deepMerge({ ...mergedDefinition }, { ...overrideDefinition }); + } }); return mergedDefinitions; diff --git a/js/reducers/ngl/dispatchActions.js b/js/reducers/ngl/dispatchActions.js index c36420e90..830afad77 100644 --- a/js/reducers/ngl/dispatchActions.js +++ b/js/reducers/ngl/dispatchActions.js @@ -97,36 +97,38 @@ export const loadObject = ({ }; export const deleteObject = (target, stage, deleteFromSelections) => dispatch => { - const comps = stage.getComponentsByName(target.name); - comps.list.forEach(component => stage.removeComponent(component)); - - if (deleteFromSelections === true && target && target.selectionType && target.moleculeId) { - const objectId = { id: target.moleculeId }; - switch (target.selectionType) { - case SELECTION_TYPE.LIGAND: - dispatch(removeFromFragmentDisplayList(objectId)); - break; - case SELECTION_TYPE.HIT_PROTEIN: - dispatch(removeFromProteinList(objectId)); - break; - case SELECTION_TYPE.COMPLEX: - dispatch(removeFromComplexList(objectId)); - break; - case SELECTION_TYPE.SURFACE: - dispatch(removeFromSurfaceList(objectId)); - break; - case SELECTION_TYPE.DENSITY: - dispatch(removeFromDensityList(objectId)); - dispatch(removeFromDensityListCustom(objectId, true)); - dispatch(removeFromDensityListType({ id: objectId })); - break; - case SELECTION_TYPE.VECTOR: - dispatch(removeFromVectorOnList(objectId)); - break; + if (stage && target) { + const comps = stage.getComponentsByName(target.name); + comps.list.forEach(component => stage.removeComponent(component)); + + if (deleteFromSelections === true && target && target.selectionType && target.moleculeId) { + const objectId = { id: target.moleculeId }; + switch (target.selectionType) { + case SELECTION_TYPE.LIGAND: + dispatch(removeFromFragmentDisplayList(objectId)); + break; + case SELECTION_TYPE.HIT_PROTEIN: + dispatch(removeFromProteinList(objectId)); + break; + case SELECTION_TYPE.COMPLEX: + dispatch(removeFromComplexList(objectId)); + break; + case SELECTION_TYPE.SURFACE: + dispatch(removeFromSurfaceList(objectId)); + break; + case SELECTION_TYPE.DENSITY: + dispatch(removeFromDensityList(objectId)); + dispatch(removeFromDensityListCustom(objectId, true)); + dispatch(removeFromDensityListType({ id: objectId })); + break; + case SELECTION_TYPE.VECTOR: + dispatch(removeFromVectorOnList(objectId)); + break; + } } - } - dispatch(deleteNglObject(target)); + dispatch(deleteNglObject(target)); + } }; export const checkRemoveFromDensityList = (target, objectsInView) => () => { diff --git a/package.json b/package.json index ad1836460..44f0e1cd7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fragalysis-frontend", - "version": "0.10.183", + "version": "0.10.184", "default_squonk_project": "project-8f32b412-8329-4469-a39c-8581efa93796", "description": "Frontend for fragalysis", "main": "webpack.config.js",