From 3a9db85cea1a00290b80ad9b28d35f643921d0a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1na=20Kohanov=C3=A1?= Date: Fri, 6 Nov 2020 08:31:44 +0100 Subject: [PATCH] #429 Restore current state as a result of the actions applied on the default state --- js/components/datasets/redux/reducer.js | 10 ++- js/components/preview/Preview.js | 5 +- .../preview/molecule/moleculeList.js | 43 ++++++----- js/components/tracking/trackingModal.js | 73 +++++++++++++------ js/reducers/tracking/actions.js | 14 ++++ js/reducers/tracking/constants.js | 4 +- js/reducers/tracking/dispatchActions.js | 36 +++++---- js/reducers/tracking/trackingReducers.js | 14 +++- 8 files changed, 135 insertions(+), 64 deletions(-) diff --git a/js/components/datasets/redux/reducer.js b/js/components/datasets/redux/reducer.js index ea0263ee8..449fe15ee 100644 --- a/js/components/datasets/redux/reducer.js +++ b/js/components/datasets/redux/reducer.js @@ -363,7 +363,15 @@ export const datasetsReducers = (state = INITIAL_STATE, action = {}) => { return Object.assign({}, state, lists); case constants.RESET_DATASETS_STATE: - return INITIAL_STATE; + const datasetsLists = { + ligandLists: reloadLists([], 'ligandLists'), + proteinLists: reloadLists([], 'proteinLists'), + complexLists: reloadLists([], 'complexLists'), + surfaceLists: reloadLists([], 'surfaceLists'), + inspirationLists: reloadLists([], 'inspirationLists'), + compoundsToBuyDatasetMap: reloadLists([], 'compoundsToBuyDatasetMap') + }; + return Object.assign({}, state, { ...INITIAL_STATE, ...datasetsLists }); default: return state; diff --git a/js/components/preview/Preview.js b/js/components/preview/Preview.js index 8724037fa..be374f61b 100644 --- a/js/components/preview/Preview.js +++ b/js/components/preview/Preview.js @@ -94,12 +94,13 @@ const Preview = memo(({ isStateLoaded, hideProjects }) => { const [selectedDatasetIndex, setSelectedDatasetIndex] = useState(); const currentDataset = customDatasets[selectedDatasetIndex]; const target_on = useSelector(state => state.apiReducers.target_on); + const isTrackingRestoring = useSelector(state => state.trackingReducers.isTrackingCompoundsRestoring); /* Loading datasets */ useEffect(() => { - if (customDatasets.length === 0) { + if (customDatasets.length === 0 && isTrackingRestoring === false) { dispatch(setMoleculeListIsLoading(true)); dispatch(loadDataSets(target_on)) .then(results => { @@ -115,7 +116,7 @@ const Preview = memo(({ isStateLoaded, hideProjects }) => { dispatch(setMoleculeListIsLoading(false)); }); } - }, [customDatasets.length, dispatch, target_on]); + }, [customDatasets.length, dispatch, target_on, isTrackingRestoring]); const [molGroupsHeight, setMolGroupsHeight] = useState(0); const [filterItemsHeight, setFilterItemsHeight] = useState(0); diff --git a/js/components/preview/molecule/moleculeList.js b/js/components/preview/molecule/moleculeList.js index 999212ee7..25e4c301f 100644 --- a/js/components/preview/molecule/moleculeList.js +++ b/js/components/preview/molecule/moleculeList.js @@ -60,7 +60,7 @@ import { useRouteMatch } from 'react-router-dom'; import { setSortDialogOpen } from './redux/actions'; import { setMoleculeList, setAllMolLists } from '../../../reducers/api/actions'; import { AlertModal } from '../../common/Modal/AlertModal'; -import {selectMoleculeGroup} from '../moleculeGroups/redux/dispatchActions' +import { selectMoleculeGroup } from '../moleculeGroups/redux/dispatchActions'; const useStyles = makeStyles(theme => ({ container: { @@ -252,7 +252,8 @@ export const MoleculeList = memo(({ height, setFilterItemsHeight, filterItemsHei const all_mol_lists = useSelector(state => state.apiReducers.all_mol_lists); const directDisplay = useSelector(state => state.apiReducers.direct_access); const directAccessProcessed = useSelector(state => state.apiReducers.direct_access_processed); - + const isTrackingRestoring = useSelector(state => state.trackingReducers.isTrackingMoleculesRestoring); + const proteinsHasLoaded = useSelector(state => state.nglReducers.proteinsHasLoaded); const [predefinedFilter, setPredefinedFilter] = useState(filter !== undefined ? filter.predefined : DEFAULT_FILTER); @@ -314,26 +315,31 @@ export const MoleculeList = memo(({ height, setFilterItemsHeight, filterItemsHei target_on && mol_group_list && mol_group_list.length > 0 && - Object.keys(all_mol_lists).length <= 0 + Object.keys(all_mol_lists).length <= 0 && + isTrackingRestoring === false ) { let promises = []; mol_group_list.forEach(molGroup => { let id = molGroup.id; let url = getUrl({ list_type, target_on, mol_group_on: id }); - promises.push(loadAllMolsFromMolGroup({ - url, - mol_group: id - })) + promises.push( + loadAllMolsFromMolGroup({ + url, + mol_group: id + }) + ); }); - Promise.all(promises).then((results) => { - let listToSet = {}; - results.forEach(molResult => { - listToSet[molResult.mol_group] = molResult.molecules; - }); - dispatch(setAllMolLists(listToSet)) - }).catch((err) => console.log(err)); + Promise.all(promises) + .then(results => { + let listToSet = {}; + results.forEach(molResult => { + listToSet[molResult.mol_group] = molResult.molecules; + }); + dispatch(setAllMolLists(listToSet)); + }) + .catch(err => console.log(err)); } - }, [proteinsHasLoaded, mol_group_list, list_type, target_on, dispatch, all_mol_lists]); + }, [proteinsHasLoaded, mol_group_list, list_type, target_on, dispatch, all_mol_lists, isTrackingRestoring]); useEffect(() => { loadAllMolecules(); @@ -345,16 +351,13 @@ export const MoleculeList = memo(({ height, setFilterItemsHeight, filterItemsHei mol_group_list.forEach(mg => { molGroupMap[mg.description] = mg.id; }); - return molGroupMap; + return molGroupMap; } }, [mol_group_list]); useEffect(() => { const allMolsGroupsCount = Object.keys(all_mol_lists || {}).length; - if ( - (proteinsHasLoaded === true || proteinsHasLoaded === null) && - allMolsGroupsCount > 0 - ) { + if ((proteinsHasLoaded === true || proteinsHasLoaded === null) && allMolsGroupsCount > 0) { dispatch(setMoleculeList({ ...(all_mol_lists[mol_group_on] || []) })); if (!directAccessProcessed && directDisplay && directDisplay.molecules && directDisplay.molecules.length > 0) { dispatch(applyDirectSelection(stage, stageSummaryView)); diff --git a/js/components/tracking/trackingModal.js b/js/components/tracking/trackingModal.js index 24d78e6fb..03e3c7cc5 100644 --- a/js/components/tracking/trackingModal.js +++ b/js/components/tracking/trackingModal.js @@ -1,11 +1,13 @@ -import React, { memo } from 'react'; -import { useSelector } from 'react-redux'; +import React, { memo, useContext } from 'react'; +import { useSelector, useDispatch } from 'react-redux'; import Modal from '../common/Modal'; -import { Grid, makeStyles } from '@material-ui/core'; +import { Grid, makeStyles, IconButton, Tooltip } from '@material-ui/core'; import { Timeline, TimelineEvent } from 'react-event-timeline'; -import { Check, Clear } from '@material-ui/icons'; +import { Check, Clear, Save, Restore, Close } from '@material-ui/icons'; import palette from '../../theme/palette'; import { Panel } from '../common'; +import { selectCurrentActionsList, restoreCurrentActionsList } from '../../reducers/tracking/dispatchActions'; +import { NglContext } from '../nglView/nglProvider'; const useStyles = makeStyles(theme => ({ customModal: { @@ -34,6 +36,9 @@ const useStyles = makeStyles(theme => ({ export const TrackingModal = memo(({ openModal, onModalClose }) => { const classes = useStyles(); + const dispatch = useDispatch(); + const { nglViewList } = useContext(NglContext); + const actionList = useSelector(state => state.trackingReducers.truck_actions_list); const orderedActionList = actionList.sort((a, b) => a.timestamp - b.timestamp); @@ -42,6 +47,24 @@ export const TrackingModal = memo(({ openModal, onModalClose }) => { onModalClose(); } + const actions = [ + dispatch(selectCurrentActionsList())}> + + + + , + dispatch(restoreCurrentActionsList(nglViewList))}> + + + + , + onModalClose()}> + + + + + ]; + return ( { open={openModal} onClose={() => onModalClose()} > - +
{orderedActionList && - orderedActionList.map((data, index) => ( - - ) : ( - - ) - } - iconColor={palette.primary.main} - className={classes.timelineEvent} - > - ))} + orderedActionList.map((data, index) => { + if (data && data != null) { + return ( + + ) : ( + + ) + } + iconColor={palette.primary.main} + className={classes.timelineEvent} + > + ); + } + })}
diff --git a/js/reducers/tracking/actions.js b/js/reducers/tracking/actions.js index decfb1e3a..65c3f301c 100644 --- a/js/reducers/tracking/actions.js +++ b/js/reducers/tracking/actions.js @@ -20,3 +20,17 @@ export const setCurrentActionsList = function(current_actions_list) { current_actions_list: current_actions_list }; }; + +export const setIsTrackingMoleculesRestoring = function(isTrackingMoleculesRestoring) { + return { + type: constants.SET_IS_TRACKING_MOLECULES_RESTORING, + isTrackingMoleculesRestoring: isTrackingMoleculesRestoring + }; +}; + +export const setIsTrackingCompoundsRestoring = function(isTrackingCompoundsRestoring) { + return { + type: constants.SET_IS_TRACKING_COMPOUNDS_RESTORING, + isTrackingCompoundsRestoring: isTrackingCompoundsRestoring + }; +}; diff --git a/js/reducers/tracking/constants.js b/js/reducers/tracking/constants.js index 18b77abef..8863e0915 100644 --- a/js/reducers/tracking/constants.js +++ b/js/reducers/tracking/constants.js @@ -3,7 +3,9 @@ const prefix = 'REDUCERS_TRACKING_'; export const constants = { SET_ACTIONS_LIST: prefix + 'SET_ACTIONS_LIST', APPEND_ACTIONS_LIST: prefix + 'APPEND_ACTIONS_LIST', - SET_CURRENT_ACTIONS_LIST: prefix + 'SET_CURRENT_ACTIONS_LIST' + SET_CURRENT_ACTIONS_LIST: prefix + 'SET_CURRENT_ACTIONS_LIST', + SET_IS_TRACKING_COMPOUNDS_RESTORING: prefix + 'SET_IS_TRACKING_COMPOUNDS_RESTORING', + SET_IS_TRACKING_MOLECULES_RESTORING: prefix + 'SET_IS_TRACKING_MOLECULES_RESTORING' }; export const actionType = { diff --git a/js/reducers/tracking/dispatchActions.js b/js/reducers/tracking/dispatchActions.js index 1bdb72b50..f98ba1d78 100644 --- a/js/reducers/tracking/dispatchActions.js +++ b/js/reducers/tracking/dispatchActions.js @@ -1,4 +1,4 @@ -import { setCurrentActionsList } from './actions'; +import { setCurrentActionsList, setIsTrackingMoleculesRestoring, setIsTrackingCompoundsRestoring } from './actions'; import { actionType, actionObjectType } from './constants'; import { VIEWS } from '../../../js/constants/constants'; import { setCurrentVector } from '../selection/actions'; @@ -24,7 +24,10 @@ import { loadDataSets, loadDatasetCompoundsWithScores } from '../../components/datasets/redux/dispatchActions'; -import { appendMoleculeToCompoundsOfDatasetToBuy } from '../../components/datasets/redux/actions'; +import { + appendMoleculeToCompoundsOfDatasetToBuy, + setMoleculeListIsLoading +} from '../../components/datasets/redux/actions'; import { setAllMolLists } from '../api/actions'; import { getUrl, loadAllMolsFromMolGroup } from '../../../js/utils/genericList'; import * as listType from '../../constants/listTypes'; @@ -157,7 +160,8 @@ const mapCurrentAction = action => { timestamp: action.timestamp, object_name: action.object_name, object_type: action.object_type, - action_type: action.type + action_type: action.type, + dataset_id: action.dataset_id }); }; @@ -212,6 +216,8 @@ const getCollectionOfDatasetOfRepresentation = dataList => { }; export const restoreCurrentActionsList = (stages = []) => (dispatch, getState) => { + dispatch(setIsTrackingMoleculesRestoring(true)); + dispatch(setIsTrackingCompoundsRestoring(true)); dispatch(unmountPreviewComponent(stages)); dispatch(resetTargetState()); dispatch(restoreStateBySavedActionList(stages)); @@ -226,9 +232,10 @@ const restoreStateBySavedActionList = stages => (dispatch, getState) => { dispatch(restoreTargetActions(orderedActionList, stages)); }; -const restoreTargetActions = (orderedActionList, stages, state) => (dispatch, getState) => { +const restoreTargetActions = (orderedActionList, stages) => (dispatch, getState) => { const state = getState(); + const majorView = stages.find(view => view.id === VIEWS.MAJOR_VIEW); const summaryView = stages.find(view => view.id === VIEWS.SUMMARY_VIEW); let targetAction = orderedActionList.find(action => action.action_type === actionType.TARGET_LOADED); @@ -250,32 +257,28 @@ const restoreTargetActions = (orderedActionList, stages, state) => (dispatch, ge throw error; }) .finally(() => { - const majorView = stages.find(view => view.id === VIEWS.MAJOR_VIEW); - const stage = majorView.stage; - dispatch(restoreSitesActions(orderedActionList, summaryView)); - dispatch(loadAllMolecules(orderedActionList, target.id, stage)); + dispatch(loadAllMolecules(orderedActionList, target.id, majorView.stage)); }); - dispatch(loadAllDatasaets); + dispatch(loadAllDatasets(orderedActionList, target.id, majorView.stage)); } } }; -const loadAllDatasaets = (orderedActionList, target_on, stage) => (dispatch, getState) => { - //dispatch(setMoleculeListIsLoading(true)); +const loadAllDatasets = (orderedActionList, target_on, stage) => (dispatch, getState) => { + dispatch(setMoleculeListIsLoading(true)); dispatch(loadDataSets(target_on)) .then(results => { - //setSelectedDatasetIndex(0); - return dispatch(loadDatasetCompoundsWithScores()); }) .catch(error => { throw new Error(error); }) .finally(() => { - //dispatch(setMoleculeListIsLoading(false)); dispatch(restoreCompoundsActions(orderedActionList, stage)); + dispatch(setMoleculeListIsLoading(false)); + dispatch(setIsTrackingCompoundsRestoring(false)); }); }; @@ -304,6 +307,7 @@ const loadAllMolecules = (orderedActionList, target_on, stage) => (dispatch, get }); dispatch(setAllMolLists(listToSet)); dispatch(restoreMoleculesActions(orderedActionList, stage)); + dispatch(setIsTrackingMoleculesRestoring(false)); }) .catch(err => console.log(err)); }; @@ -390,7 +394,7 @@ const addNewType = (moleculesAction, actionType, type, stage, state) => dispatch actions.forEach(action => { let data = getMolecule(action.object_name, state); if (data) { - dispatch(addType[type](stage, data, colourList[data.id % colourList.length]), true); + dispatch(addType[type](stage, data, colourList[data.id % colourList.length])); } }); } @@ -402,7 +406,7 @@ const addNewTypeCompound = (moleculesAction, actionType, type, stage, state) => actions.forEach(action => { let data = getCompound(action.object_name, state); if (data) { - dispatch(addTypeCompound[type](stage, data, colourList[data.id % colourList.length]), data.datasetID); + dispatch(addTypeCompound[type](stage, data, colourList[data.id % colourList.length], action.dataset_id)); } }); } diff --git a/js/reducers/tracking/trackingReducers.js b/js/reducers/tracking/trackingReducers.js index a9e9e793b..4f2ddea98 100644 --- a/js/reducers/tracking/trackingReducers.js +++ b/js/reducers/tracking/trackingReducers.js @@ -2,7 +2,9 @@ import { constants } from './constants'; export const INITIAL_STATE = { truck_actions_list: [], - current_actions_list: [] + current_actions_list: [], + isTrackingMoleculesRestoring: false, + isTrackingCompoundsRestoring: false }; export default function trackingReducers(state = INITIAL_STATE, action = {}) { @@ -22,6 +24,16 @@ export default function trackingReducers(state = INITIAL_STATE, action = {}) { current_actions_list: action.current_actions_list }); + case constants.SET_IS_TRACKING_MOLECULES_RESTORING: + return Object.assign({}, state, { + isTrackingMoleculesRestoring: action.isTrackingMoleculesRestoring + }); + + case constants.SET_IS_TRACKING_COMPOUNDS_RESTORING: + return Object.assign({}, state, { + isTrackingCompoundsRestoring: action.isTrackingCompoundsRestoring + }); + default: return state; }