diff --git a/js/components/datasets/crossReferenceDialog.js b/js/components/datasets/crossReferenceDialog.js index 9f719cc88..d8aeb4a4a 100644 --- a/js/components/datasets/crossReferenceDialog.js +++ b/js/components/datasets/crossReferenceDialog.js @@ -146,7 +146,7 @@ export const CrossReferenceDialog = memo( const complexListAllDatasets = useSelector(state => state.datasetsReducers.complexLists); const surfaceListAllDatasets = useSelector(state => state.datasetsReducers.surfaceLists); - const removeOfAllSelectedTypes = () => { + const removeOfAllSelectedTypes = skipTracking => { Object.keys(ligandListAllDatasets).forEach(datasetKey => { ligandListAllDatasets[datasetKey]?.forEach(moleculeID => { const foundedMolecule = moleculeList?.find(mol => mol?.molecule?.id === moleculeID); @@ -155,7 +155,8 @@ export const CrossReferenceDialog = memo( stage, foundedMolecule?.molecule, colourList[foundedMolecule?.molecule?.id % colourList.length], - datasetKey + datasetKey, + skipTracking ) ); }); @@ -168,7 +169,8 @@ export const CrossReferenceDialog = memo( stage, foundedMolecule?.molecule, colourList[foundedMolecule?.molecule?.id % colourList.length], - datasetKey + datasetKey, + skipTracking ) ); }); @@ -181,7 +183,8 @@ export const CrossReferenceDialog = memo( stage, foundedMolecule?.molecule, colourList[foundedMolecule?.molecule?.id % colourList.length], - datasetKey + datasetKey, + skipTracking ) ); }); @@ -194,7 +197,8 @@ export const CrossReferenceDialog = memo( stage, foundedMolecule?.molecule, colourList[foundedMolecule?.molecule?.id % colourList.length], - datasetKey + datasetKey, + skipTracking ) ); }); diff --git a/js/components/datasets/datasetMoleculeList.js b/js/components/datasets/datasetMoleculeList.js index ed8c5b157..e8d1686bd 100644 --- a/js/components/datasets/datasetMoleculeList.js +++ b/js/components/datasets/datasetMoleculeList.js @@ -296,16 +296,16 @@ export const DatasetMoleculeList = memo( surface: removeDatasetSurface }; - const removeOfAllSelectedTypesOfInspirations = () => { + const removeOfAllSelectedTypesOfInspirations = skipTracking => { let molecules = [...getJoinedMoleculeList, ...inspirationMoleculeDataList]; - dispatch(hideAllSelectedMolecules(stage, [...molecules])); + dispatch(hideAllSelectedMolecules(stage, [...molecules], false, skipTracking)); }; - const removeOfAllSelectedTypes = () => { - dispatch(removeAllSelectedDatasetMolecules(stage)); + const removeOfAllSelectedTypes = skipTracking => { + dispatch(removeAllSelectedDatasetMolecules(stage, skipTracking)); }; - const moveSelectedMoleculeInspirationsSettings = (data, newItemData) => (dispatch, getState) => { + const moveSelectedMoleculeInspirationsSettings = (data, newItemData, skipTracking) => (dispatch, getState) => { dispatch( moveMoleculeInspirationsSettings( data, @@ -317,7 +317,8 @@ export const DatasetMoleculeList = memo( complexListMolecule, surfaceListMolecule, densityListMolecule, - vectorOnListMolecule + vectorOnListMolecule, + skipTracking ) ); }; diff --git a/js/components/datasets/datasetMoleculeView.js b/js/components/datasets/datasetMoleculeView.js index 43aa58a57..e908677fb 100644 --- a/js/components/datasets/datasetMoleculeView.js +++ b/js/components/datasets/datasetMoleculeView.js @@ -8,7 +8,7 @@ import { Grid, Button, makeStyles, Tooltip, Checkbox, IconButton } from '@materi import { ClearOutlined, CheckOutlined } from '@material-ui/icons'; import SVGInline from 'react-svg-inline'; import classNames from 'classnames'; -import { VIEWS } from '../../constants/constants'; +import { VIEWS, ARROW_TYPE } from '../../constants/constants'; import { NglContext } from '../nglView/nglProvider'; // import { useDisableUserInteraction } from '../helpers/useEnableUserInteracion'; import { @@ -21,28 +21,26 @@ import { addDatasetSurface, removeDatasetSurface, clickOnInspirations, - getDatasetMoleculeID + getDatasetMoleculeID, + moveSelectedMoleculeSettings, + getInspirationsForMol } from './redux/dispatchActions'; -import { base_url } from '../routes/constants'; -import { api } from '../../utils/api'; import { isAnyInspirationTurnedOn, getFilteredDatasetMoleculeList } from './redux/selectors'; import { appendMoleculeToCompoundsOfDatasetToBuy, removeMoleculeFromCompoundsOfDatasetToBuy, setCrossReferenceCompoundName, setIsOpenCrossReferenceDialog, - setInspirationFragmentList, setInspirationMoleculeDataList, setSelectedAll, - setDeselectedAll + setDeselectedAll, + setArrowUpDown } from './redux/actions'; import { centerOnLigandByMoleculeID } from '../../reducers/ngl/dispatchActions'; import { ArrowDownward, ArrowUpward, MyLocation } from '@material-ui/icons'; import { isString } from 'lodash'; import { SvgTooltip } from '../common'; -import { OBJECT_TYPE } from '../nglView/constants'; -import { getRepresentationsByType } from '../nglView/generatingObjects'; import { getMolImage } from '../preview/molecule/redux/dispatchActions'; import { MOL_TYPE } from '../preview/molecule/redux/constants'; @@ -262,7 +260,11 @@ export const DatasetMoleculeView = memo( removeOfAllSelectedTypes, removeOfAllSelectedTypesOfInspirations, moveSelectedMoleculeInspirationsSettings, - L, P, C, S, V + L, + P, + C, + S, + V }) => { const selectedAll = useRef(false); const currentID = (data && data.id) || undefined; @@ -319,18 +321,7 @@ export const DatasetMoleculeView = memo( dispatch(getMolImage(data.smiles, MOL_TYPE.DATASET, imageHeight, imageWidth)).then(i => { setImage(i); }); - }, [ - C, - currentID, - data, - L, - imageHeight, - imageWidth, - data.smiles, - data.id, - filteredDatasetMoleculeList, - dispatch - ]); + }, [C, currentID, data, L, imageHeight, imageWidth, data.smiles, data.id, filteredDatasetMoleculeList, dispatch]); const svg_image = ( { - if (newItemData) { - if (isLigandOn) { - let representations = getRepresentationsByType(objectsInView, data, OBJECT_TYPE.LIGAND, datasetID); - dispatch(addDatasetLigand(stage, newItemData, colourToggle, datasetIdOfMolecule, representations)); - } - if (isProteinOn) { - let representations = getRepresentationsByType(objectsInView, data, OBJECT_TYPE.PROTEIN, datasetID); - dispatch(addDatasetHitProtein(stage, newItemData, colourToggle, datasetIdOfMolecule, representations)); - } - if (isComplexOn) { - let representations = getRepresentationsByType(objectsInView, data, OBJECT_TYPE.COMPLEX, datasetID); - dispatch(addDatasetComplex(stage, newItemData, colourToggle, datasetIdOfMolecule, representations)); - } - if (isSurfaceOn) { - let representations = getRepresentationsByType(objectsInView, data, OBJECT_TYPE.SURFACE, datasetID); - dispatch(addDatasetSurface(stage, newItemData, colourToggle, datasetIdOfMolecule, representations)); - } - } - }; - const scrollToElement = element => { element.scrollIntoView({ behavior: 'auto', @@ -515,31 +485,24 @@ export const DatasetMoleculeView = memo( }); }; - const getInspirationsForMol = (datasetId, molId) => { - let inspirations = []; - - if (allInspirations && allInspirations.hasOwnProperty(datasetId) && allInspirations[datasetId].hasOwnProperty(molId)) { - inspirations = allInspirations[datasetId][molId]; - } - - return inspirations; - }; - const handleClickOnDownArrow = () => { const refNext = ref.current.nextSibling; scrollToElement(refNext); - removeOfAllSelectedTypes(); - removeOfAllSelectedTypesOfInspirations(); - const nextItem = (nextItemData.hasOwnProperty('molecule') && nextItemData.molecule) || nextItemData; const nextDatasetID = (nextItemData.hasOwnProperty('datasetID') && nextItemData.datasetID) || datasetID; const moleculeTitleNext = nextItem && nextItem.name; - const inspirations = getInspirationsForMol(datasetID, nextItem.id); + let dataValue = { objectsInView, colourToggle, isLigandOn, isProteinOn, isComplexOn, isSurfaceOn }; + dispatch(setArrowUpDown(datasetID, data, nextItem, ARROW_TYPE.DOWN, dataValue)); + + removeOfAllSelectedTypes(true); + removeOfAllSelectedTypesOfInspirations(true); + + const inspirations = getInspirationsForMol(allInspirations, datasetID, nextItem.id); dispatch(setInspirationMoleculeDataList(inspirations)); - moveSelectedMoleculeSettings(nextItem, nextDatasetID); - dispatch(moveSelectedMoleculeInspirationsSettings(data, nextItem)); + dispatch(moveSelectedMoleculeSettings(stage, data, nextItem, nextDatasetID, datasetID, dataValue, true)); + dispatch(moveSelectedMoleculeInspirationsSettings(data, nextItem, true)); dispatch(setCrossReferenceCompoundName(moleculeTitleNext)); if (setRef && ref.current) { setRef(refNext); @@ -550,19 +513,23 @@ export const DatasetMoleculeView = memo( const refPrevious = ref.current.previousSibling; scrollToElement(refPrevious); - removeOfAllSelectedTypes(); - removeOfAllSelectedTypesOfInspirations(); - const previousItem = (previousItemData.hasOwnProperty('molecule') && previousItemData.molecule) || previousItemData; const previousDatasetID = (previousItemData.hasOwnProperty('datasetID') && previousItemData.datasetID) || datasetID; const moleculeTitlePrev = previousItem && previousItem.name; - const inspirations = getInspirationsForMol(datasetID, previousItem.id); + let dataValue = { objectsInView, colourToggle, isLigandOn, isProteinOn, isComplexOn, isSurfaceOn }; + dispatch(setArrowUpDown(datasetID, data, previousItem, ARROW_TYPE.UP, dataValue)); + + removeOfAllSelectedTypes(true); + removeOfAllSelectedTypesOfInspirations(true); + + const inspirations = getInspirationsForMol(allInspirations, datasetID, previousItem.id); dispatch(setInspirationMoleculeDataList(inspirations)); - moveSelectedMoleculeSettings(previousItem, previousDatasetID); - dispatch(moveSelectedMoleculeInspirationsSettings(data, previousItem)); + dispatch(moveSelectedMoleculeSettings(stage, data, previousItem, previousDatasetID, datasetID, dataValue, true)); + + dispatch(moveSelectedMoleculeInspirationsSettings(data, previousItem, true)); dispatch(setCrossReferenceCompoundName(moleculeTitlePrev)); if (setRef && ref.current) { setRef(refPrevious); @@ -755,7 +722,7 @@ export const DatasetMoleculeView = memo( clickOnInspirations({ datasetID, currentID, - computed_inspirations: getInspirationsForMol(datasetID, currentID) + computed_inspirations: getInspirationsForMol(allInspirations, datasetID, currentID) }) ); if (setRef) { diff --git a/js/components/datasets/inspirationDialog.js b/js/components/datasets/inspirationDialog.js index f124f75c3..7046b424e 100644 --- a/js/components/datasets/inspirationDialog.js +++ b/js/components/datasets/inspirationDialog.js @@ -208,37 +208,45 @@ export const InspirationDialog = memo( const selectMoleculeSite = moleculeGroupSite => {}; - const removeOfAllSelectedTypes = () => { + const removeOfAllSelectedTypes = (skipTracking = false) => { proteinList?.forEach(moleculeID => { let foundedMolecule = moleculeList?.find(mol => mol.id === moleculeID); foundedMolecule = foundedMolecule && Object.assign({ isInspiration: true }, foundedMolecule); - dispatch(removeHitProtein(stage, foundedMolecule, colourList[foundedMolecule.id % colourList.length])); + dispatch( + removeHitProtein(stage, foundedMolecule, colourList[foundedMolecule.id % colourList.length], skipTracking) + ); }); complexList?.forEach(moleculeID => { let foundedMolecule = moleculeList?.find(mol => mol.id === moleculeID); foundedMolecule = foundedMolecule && Object.assign({ isInspiration: true }, foundedMolecule); - dispatch(removeComplex(stage, foundedMolecule, colourList[foundedMolecule.id % colourList.length])); + dispatch( + removeComplex(stage, foundedMolecule, colourList[foundedMolecule.id % colourList.length], skipTracking) + ); }); ligandList?.forEach(moleculeID => { let foundedMolecule = moleculeList?.find(mol => mol.id === moleculeID); foundedMolecule = foundedMolecule && Object.assign({ isInspiration: true }, foundedMolecule); - dispatch(removeLigand(stage, foundedMolecule, colourList[foundedMolecule.id % colourList.length])); + dispatch(removeLigand(stage, foundedMolecule, skipTracking)); }); surfaceList?.forEach(moleculeID => { let foundedMolecule = moleculeList?.find(mol => mol.id === moleculeID); foundedMolecule = foundedMolecule && Object.assign({ isInspiration: true }, foundedMolecule); - dispatch(removeSurface(stage, foundedMolecule, colourList[foundedMolecule.id % colourList.length])); + dispatch( + removeSurface(stage, foundedMolecule, colourList[foundedMolecule.id % colourList.length], skipTracking) + ); }); densityList?.forEach(moleculeID => { let foundedMolecule = moleculeList?.find(mol => mol.id === moleculeID); foundedMolecule = foundedMolecule && Object.assign({ isInspiration: true }, foundedMolecule); - dispatch(removeDensity(stage, foundedMolecule, colourList[foundedMolecule.id % colourList.length])); + dispatch( + removeDensity(stage, foundedMolecule, colourList[foundedMolecule.id % colourList.length], skipTracking) + ); }); vectorOnList?.forEach(moleculeID => { let foundedMolecule = moleculeList?.find(mol => mol.id === moleculeID); foundedMolecule = foundedMolecule && Object.assign({ isInspiration: true }, foundedMolecule); - dispatch(removeVector(stage, foundedMolecule, colourList[foundedMolecule.id % colourList.length])); + dispatch(removeVector(stage, foundedMolecule, skipTracking)); }); }; diff --git a/js/components/datasets/redux/actions.js b/js/components/datasets/redux/actions.js index 53cbcbe7e..378e1f4df 100644 --- a/js/components/datasets/redux/actions.js +++ b/js/components/datasets/redux/actions.js @@ -254,7 +254,7 @@ export const setInspirationMoleculeDataList = (moleculeList = []) => ({ payload: moleculeList }); -export const setAllInspirations = (allInspirationsMap) => ({ +export const setAllInspirations = allInspirationsMap => ({ type: constants.SET_ALL_INSPIRATIONS, payload: allInspirationsMap }); @@ -368,3 +368,14 @@ export const setDeselectedAllByType = (type, datsetID, items, isCrossReference) isCrossReference: isCrossReference } }); + +export const setArrowUpDown = (datasetID, item, newItem, arrowType, data) => ({ + type: constants.SET_ARROW_UP_DOWN, + payload: { + datasetID, + item: item, + newItem: newItem, + arrowType: arrowType, + data + } +}); diff --git a/js/components/datasets/redux/constants.js b/js/components/datasets/redux/constants.js index e1d95a045..a8fcd4cf9 100644 --- a/js/components/datasets/redux/constants.js +++ b/js/components/datasets/redux/constants.js @@ -69,7 +69,8 @@ export const constants = { SET_DESELECTED_ALL: prefix + 'SET_DESELECTED_ALL', SET_SELECTED_ALL_BY_TYPE: prefix + 'SET_SELECTED_ALL_BY_TYPE', - SET_DESELECTED_ALL_BY_TYPE: prefix + 'SET_DESELECTED_ALL_BY_TYPE' + SET_DESELECTED_ALL_BY_TYPE: prefix + 'SET_DESELECTED_ALL_BY_TYPE', + SET_ARROW_UP_DOWN: prefix + 'SET_ARROW_UP_DOWN' }; export const COUNT_OF_VISIBLE_SCORES = 7; diff --git a/js/components/datasets/redux/dispatchActions.js b/js/components/datasets/redux/dispatchActions.js index 9a0956056..633efeaa7 100644 --- a/js/components/datasets/redux/dispatchActions.js +++ b/js/components/datasets/redux/dispatchActions.js @@ -64,7 +64,14 @@ export const initializeDatasetFilter = datasetID => (dispatch, getState) => { dispatch(setFilterProperties(datasetID, initFilterProperties)); }; -export const addDatasetHitProtein = (stage, data, colourToggle, datasetID, skipTracking = false, representations = undefined) => dispatch => { +export const addDatasetHitProtein = ( + stage, + data, + colourToggle, + datasetID, + skipTracking = false, + representations = undefined +) => dispatch => { dispatch( loadObject({ target: Object.assign( @@ -95,7 +102,14 @@ export const removeDatasetHitProtein = (stage, data, colourToggle, datasetID, sk dispatch(removeFromProteinList(datasetID, generateMoleculeCompoundId(data), skipTracking)); }; -export const addDatasetComplex = (stage, data, colourToggle, datasetID, skipTracking = false, representations = undefined) => dispatch => { +export const addDatasetComplex = ( + stage, + data, + colourToggle, + datasetID, + skipTracking = false, + representations = undefined +) => dispatch => { dispatch( loadObject({ target: Object.assign( @@ -151,7 +165,14 @@ export const removeDatasetSurface = (stage, data, colourToggle, datasetID) => di dispatch(removeFromSurfaceList(datasetID, generateMoleculeCompoundId(data))); }; -export const addDatasetLigand = (stage, data, colourToggle, datasetID, skipTracking = false, representations = undefined) => dispatch => { +export const addDatasetLigand = ( + stage, + data, + colourToggle, + datasetID, + skipTracking = false, + representations = undefined +) => dispatch => { const currentOrientation = stage.viewerControls.getOrientation(); dispatch( loadObject({ @@ -607,7 +628,7 @@ export const autoHideDatasetDialogsOnScroll = ({ inspirationDialogRef, crossRefe } }; -export const removeAllSelectedDatasetMolecules = stage => (dispatch, getState) => { +export const removeAllSelectedDatasetMolecules = (stage, skipTracking) => (dispatch, getState) => { const state = getState(); const datasets = state.datasetsReducers.datasets; const currentMolecules = state.datasetsReducers.moleculeLists; @@ -623,31 +644,69 @@ export const removeAllSelectedDatasetMolecules = stage => (dispatch, getState) = ligandList?.forEach(moleculeID => { const foundedMolecule = molecules?.find(mol => mol.id === moleculeID); dispatch( - removeDatasetLigand(stage, foundedMolecule, colourList[foundedMolecule.id % colourList.length], datasetID) + removeDatasetLigand( + stage, + foundedMolecule, + colourList[foundedMolecule.id % colourList.length], + datasetID, + skipTracking + ) ); }); proteinList?.forEach(moleculeID => { const foundedMolecule = molecules?.find(mol => mol.id === moleculeID); dispatch( - removeDatasetHitProtein(stage, foundedMolecule, colourList[foundedMolecule.id % colourList.length], datasetID) + removeDatasetHitProtein( + stage, + foundedMolecule, + colourList[foundedMolecule.id % colourList.length], + datasetID, + skipTracking + ) ); }); complexList?.forEach(moleculeID => { const foundedMolecule = molecules?.find(mol => mol.id === moleculeID); dispatch( - removeDatasetComplex(stage, foundedMolecule, colourList[foundedMolecule.id % colourList.length], datasetID) + removeDatasetComplex( + stage, + foundedMolecule, + colourList[foundedMolecule.id % colourList.length], + datasetID, + skipTracking + ) ); }); surfaceList?.forEach(moleculeID => { const foundedMolecule = molecules?.find(mol => mol.id === moleculeID); dispatch( - removeDatasetSurface(stage, foundedMolecule, colourList[foundedMolecule.id % colourList.length], datasetID) + removeDatasetSurface( + stage, + foundedMolecule, + colourList[foundedMolecule.id % colourList.length], + datasetID, + skipTracking + ) ); }); }); } }; +export const getInspirationsForMol = (allInspirations, datasetId, molId) => { + let inspirations = []; + + if ( + allInspirations && + allInspirations.hasOwnProperty(datasetId) && + allInspirations[datasetId].hasOwnProperty(molId) + ) { + inspirations = allInspirations[datasetId][molId]; + } + + return inspirations; +}; + export const moveMoleculeInspirationsSettings = ( data, newItemData, @@ -658,7 +717,8 @@ export const moveMoleculeInspirationsSettings = ( complexListMolecule, surfaceListMolecule, densityListMolecule, - vectorOnListMolecule + vectorOnListMolecule, + skipTracking ) => (dispatch, getState) => { dispatch(clearAllInspirationsOfDataset()); if (newItemData) { @@ -679,18 +739,19 @@ export const moveMoleculeInspirationsSettings = ( isAnyInspirationVectorOn ) { // dispatch(loadInspirationMoleculesDataList(newItemData.computed_inspirations)).then(() => { - dispatch( - moveInspirations( - stage, - objectsInView, - isAnyInspirationLigandOn, - isAnyInspirationProteinOn, - isAnyInspirationComplexOn, - isAnyInspirationSurfaceOn, - isAnyInspirationDensityOn, - isAnyInspirationVectorOn - ) - ); + dispatch( + moveInspirations( + stage, + objectsInView, + isAnyInspirationLigandOn, + isAnyInspirationProteinOn, + isAnyInspirationComplexOn, + isAnyInspirationSurfaceOn, + isAnyInspirationDensityOn, + isAnyInspirationVectorOn, + skipTracking + ) + ); // }); } } @@ -704,7 +765,8 @@ const moveInspirations = ( isAnyInspirationComplexOn, isAnyInspirationSurfaceOn, isAnyInspirationDensityOn, - isAnyInspirationVectorOn + isAnyInspirationVectorOn, + skipTracking ) => (dispatch, getState) => { const state = getState(); const molecules = state.datasetsReducers.inspirationMoleculeDataList; @@ -713,30 +775,136 @@ const moveInspirations = ( if (molecule) { if (isAnyInspirationLigandOn) { let representations = getRepresentationsByType(objectsInView, molecule, OBJECT_TYPE.LIGAND); - dispatch(addLigand(stage, molecule, colourList[molecule.id % colourList.length], false, representations)); + dispatch( + addLigand( + stage, + molecule, + colourList[molecule.id % colourList.length], + false, + skipTracking, + representations + ) + ); } if (isAnyInspirationProteinOn) { let representations = getRepresentationsByType(objectsInView, molecule, OBJECT_TYPE.HIT_PROTEIN); - dispatch(addHitProtein(stage, molecule, colourList[molecule.id % colourList.length], representations)); + dispatch( + addHitProtein(stage, molecule, colourList[molecule.id % colourList.length], skipTracking, representations) + ); } if (isAnyInspirationComplexOn) { let representations = getRepresentationsByType(objectsInView, molecule, OBJECT_TYPE.COMPLEX); - dispatch(addComplex(stage, molecule, colourList[molecule.id % colourList.length], representations)); + dispatch( + addComplex(stage, molecule, colourList[molecule.id % colourList.length], skipTracking, representations) + ); } if (isAnyInspirationSurfaceOn) { let representations = getRepresentationsByType(objectsInView, molecule, OBJECT_TYPE.SURFACE); - dispatch(addSurface(stage, molecule, colourList[molecule.id % colourList.length], representations)); + dispatch( + addSurface(stage, molecule, colourList[molecule.id % colourList.length], skipTracking, representations) + ); } if (isAnyInspirationDensityOn) { let representations = getRepresentationsByType(objectsInView, molecule, OBJECT_TYPE.DENSITY); - dispatch(addDensity(stage, molecule, colourList[molecule.id % colourList.length], representations)); + dispatch( + addDensity(stage, molecule, colourList[molecule.id % colourList.length], skipTracking, representations) + ); } if (isAnyInspirationVectorOn) { - dispatch(addVector(stage, molecule, colourList[molecule.id % colourList.length])); + dispatch(addVector(stage, molecule, colourList[molecule.id % colourList.length], skipTracking)); } } }); } }; +export const moveSelectedInspirations = ( + stage, + objectsInView, + fragmentDisplayListMolecule, + proteinListMolecule, + complexListMolecule, + surfaceListMolecule, + vectorOnListMolecule, + skipTracking +) => (dispatch, getState) => { + const state = getState(); + const molecules = state.datasetsReducers.inspirationMoleculeDataList; + if (molecules) { + molecules.forEach(molecule => { + if (molecule) { + if (fragmentDisplayListMolecule.includes(molecule.id)) { + let representations = getRepresentationsByType(objectsInView, molecule, OBJECT_TYPE.LIGAND); + dispatch( + addLigand( + stage, + molecule, + colourList[molecule.id % colourList.length], + false, + skipTracking, + representations + ) + ); + } + if (proteinListMolecule.includes(molecule.id)) { + let representations = getRepresentationsByType(objectsInView, molecule, OBJECT_TYPE.HIT_PROTEIN); + dispatch( + addHitProtein(stage, molecule, colourList[molecule.id % colourList.length], skipTracking, representations) + ); + } + if (complexListMolecule.includes(molecule.id)) { + let representations = getRepresentationsByType(objectsInView, molecule, OBJECT_TYPE.COMPLEX); + dispatch( + addComplex(stage, molecule, colourList[molecule.id % colourList.length], skipTracking, representations) + ); + } + if (surfaceListMolecule.includes(molecule.id)) { + let representations = getRepresentationsByType(objectsInView, molecule, OBJECT_TYPE.SURFACE); + dispatch( + addSurface(stage, molecule, colourList[molecule.id % colourList.length], skipTracking, representations) + ); + } + if (vectorOnListMolecule.includes(molecule.id)) { + dispatch(addVector(stage, molecule, colourList[molecule.id % colourList.length], skipTracking)); + } + } + }); + } +}; + +export const moveSelectedMoleculeSettings = ( + stage, + item, + newItem, + datasetIdOfMolecule, + datasetID, + data, + skipTracking +) => (dispatch, getState) => { + if (newItem && data) { + if (data.isLigandOn) { + let representations = getRepresentationsByType(data.objectsInView, item, OBJECT_TYPE.LIGAND, datasetID); + dispatch(addDatasetLigand(stage, newItem, data.colourToggle, datasetIdOfMolecule, skipTracking, representations)); + } + if (data.isProteinOn) { + let representations = getRepresentationsByType(data.objectsInView, item, OBJECT_TYPE.PROTEIN, datasetID); + dispatch( + addDatasetHitProtein(stage, newItem, data.colourToggle, datasetIdOfMolecule, skipTracking, representations) + ); + } + if (data.isComplexOn) { + let representations = getRepresentationsByType(data.objectsInView, item, OBJECT_TYPE.COMPLEX, datasetID); + dispatch( + addDatasetComplex(stage, newItem, data.colourToggle, datasetIdOfMolecule, skipTracking, representations) + ); + } + if (data.isSurfaceOn) { + let representations = getRepresentationsByType(data.objectsInView, item, OBJECT_TYPE.SURFACE, datasetID); + dispatch( + addDatasetSurface(stage, newItem, data.colourToggle, datasetIdOfMolecule, skipTracking, representations) + ); + } + } +}; + export const getDatasetMoleculeID = (datasetID, moleculeID) => `datasetID-${datasetID}_moleculeID-${moleculeID}`; diff --git a/js/components/preview/molecule/moleculeList.js b/js/components/preview/molecule/moleculeList.js index 6568e7f4c..bd8778b9b 100644 --- a/js/components/preview/molecule/moleculeList.js +++ b/js/components/preview/molecule/moleculeList.js @@ -18,7 +18,7 @@ import { ButtonGroup } from '@material-ui/core'; import React, { useState, useEffect, useCallback, memo, useRef, useContext, useMemo } from 'react'; -import { useDispatch, useSelector, useStore } from 'react-redux'; +import { useDispatch, useSelector } from 'react-redux'; import MoleculeView, { colourList } from './moleculeView'; import { MoleculeListSortFilterDialog, filterMolecules, getAttrDefinition } from './moleculeListSortFilterDialog'; import InfiniteScroll from 'react-infinite-scroller'; @@ -45,7 +45,8 @@ import { removeLigand, hideAllSelectedMolecules, initializeMolecules, - applyDirectSelection + applyDirectSelection, + removeAllSelectedMolTypes } from './redux/dispatchActions'; import { DEFAULT_FILTER, PREDEFINED_FILTERS } from '../../../reducers/selection/constants'; import { DeleteSweep, FilterList, Search } from '@material-ui/icons'; @@ -58,7 +59,7 @@ import { getUrl, loadAllMolsFromMolGroup } from '../../../utils/genericList'; import * as listType from '../../../constants/listTypes'; import { useRouteMatch } from 'react-router-dom'; import { setSortDialogOpen } from './redux/actions'; -import { setMoleculeList, setAllMolLists } from '../../../reducers/api/actions'; +import { setMoleculeList, setAllMolLists, setAllMolecules } from '../../../reducers/api/actions'; import { AlertModal } from '../../common/Modal/AlertModal'; import { onSelectMoleculeGroup } from '../moleculeGroups/redux/dispatchActions'; import { setSelectedAllByType, setDeselectedAllByType } from '../../../reducers/selection/actions'; @@ -292,45 +293,53 @@ export const MoleculeList = memo(({ height, setFilterItemsHeight, filterItemsHei } }, [getJoinedMoleculeList, getAllMoleculeList, searchString]); - const addSelectedMoleculesFromUnselectedSites = useCallback((joinedMoleculeLists, list) => { - const result = [...joinedMoleculeLists]; - list?.forEach(moleculeID => { - const foundJoinedMolecule = result.find(mol => mol.id === moleculeID); - if (!foundJoinedMolecule) { - const molecule = getAllMoleculeList.find(mol => mol.id === moleculeID); - if (molecule) { - result.push(molecule); + const addSelectedMoleculesFromUnselectedSites = useCallback( + (joinedMoleculeLists, list) => { + const result = [...joinedMoleculeLists]; + list?.forEach(moleculeID => { + const foundJoinedMolecule = result.find(mol => mol.id === moleculeID); + if (!foundJoinedMolecule) { + const molecule = getAllMoleculeList.find(mol => mol.id === moleculeID); + if (molecule) { + result.push(molecule); + } } - } - }); - - return result; - }, [getAllMoleculeList]); + }); - joinedMoleculeLists = useMemo( - () => addSelectedMoleculesFromUnselectedSites(joinedMoleculeLists, proteinList), - [addSelectedMoleculesFromUnselectedSites, joinedMoleculeLists, proteinList] - ); - joinedMoleculeLists = useMemo( - () => addSelectedMoleculesFromUnselectedSites(joinedMoleculeLists, complexList), - [addSelectedMoleculesFromUnselectedSites, joinedMoleculeLists, complexList] + return result; + }, + [getAllMoleculeList] ); + + joinedMoleculeLists = useMemo(() => addSelectedMoleculesFromUnselectedSites(joinedMoleculeLists, proteinList), [ + addSelectedMoleculesFromUnselectedSites, + joinedMoleculeLists, + proteinList + ]); + joinedMoleculeLists = useMemo(() => addSelectedMoleculesFromUnselectedSites(joinedMoleculeLists, complexList), [ + addSelectedMoleculesFromUnselectedSites, + joinedMoleculeLists, + complexList + ]); joinedMoleculeLists = useMemo( () => addSelectedMoleculesFromUnselectedSites(joinedMoleculeLists, fragmentDisplayList), [addSelectedMoleculesFromUnselectedSites, joinedMoleculeLists, fragmentDisplayList] ); - joinedMoleculeLists = useMemo( - () => addSelectedMoleculesFromUnselectedSites(joinedMoleculeLists, surfaceList), - [addSelectedMoleculesFromUnselectedSites, joinedMoleculeLists, surfaceList] - ); - joinedMoleculeLists = useMemo( - () => addSelectedMoleculesFromUnselectedSites(joinedMoleculeLists, densityList), - [addSelectedMoleculesFromUnselectedSites, joinedMoleculeLists, densityList] - ); - joinedMoleculeLists = useMemo( - () => addSelectedMoleculesFromUnselectedSites(joinedMoleculeLists, vectorOnList), - [addSelectedMoleculesFromUnselectedSites, joinedMoleculeLists, vectorOnList] - ); + joinedMoleculeLists = useMemo(() => addSelectedMoleculesFromUnselectedSites(joinedMoleculeLists, surfaceList), [ + addSelectedMoleculesFromUnselectedSites, + joinedMoleculeLists, + surfaceList + ]); + joinedMoleculeLists = useMemo(() => addSelectedMoleculesFromUnselectedSites(joinedMoleculeLists, densityList), [ + addSelectedMoleculesFromUnselectedSites, + joinedMoleculeLists, + densityList + ]); + joinedMoleculeLists = useMemo(() => addSelectedMoleculesFromUnselectedSites(joinedMoleculeLists, vectorOnList), [ + addSelectedMoleculesFromUnselectedSites, + joinedMoleculeLists, + vectorOnList + ]); if (!isActiveFilter) { // default sort is by site @@ -378,10 +387,13 @@ export const MoleculeList = memo(({ height, setFilterItemsHeight, filterItemsHei Promise.all(promises) .then(results => { let listToSet = {}; + let allMolecules = []; results.forEach(molResult => { listToSet[molResult.mol_group] = molResult.molecules; + allMolecules.push(...molResult.molecules); }); dispatch(setAllMolLists(listToSet)); + dispatch(setAllMolecules(allMolecules)); }) .catch(err => console.log(err)); } @@ -448,13 +460,13 @@ export const MoleculeList = memo(({ height, setFilterItemsHeight, filterItemsHei setFilterItemsHeight(0); } }, [isActiveFilter, setFilterItemsHeight]); - + const joinedMoleculeListsCopy = useMemo(() => [...joinedMoleculeLists], [joinedMoleculeLists]); useEffect(() => { if (!joinedMoleculeListsCopy.length) { dispatch(setSortDialogOpen(false)); - } + } }, [dispatch, joinedMoleculeListsCopy.length]); const handleFilterChange = filter => { @@ -559,33 +571,9 @@ export const MoleculeList = memo(({ height, setFilterItemsHeight, filterItemsHei selectedAll.current = false; }; - const removeOfAllSelectedTypes = () => { + const removeOfAllSelectedTypes = (skipTracking = false) => { let molecules = [...getJoinedMoleculeList, ...allInspirationMoleculeDataList]; - - proteinList?.forEach(moleculeID => { - const foundedMolecule = joinedMoleculeLists?.find(mol => mol.id === moleculeID); - dispatch(removeHitProtein(majorViewStage, foundedMolecule, colourList[foundedMolecule.id % colourList.length])); - }); - complexList?.forEach(moleculeID => { - const foundedMolecule = joinedMoleculeLists?.find(mol => mol.id === moleculeID); - dispatch(removeComplex(majorViewStage, foundedMolecule, colourList[foundedMolecule.id % colourList.length])); - }); - fragmentDisplayList?.forEach(moleculeID => { - const foundedMolecule = joinedMoleculeLists?.find(mol => mol.id === moleculeID); - dispatch(removeLigand(majorViewStage, foundedMolecule, colourList[foundedMolecule.id % colourList.length])); - }); - surfaceList?.forEach(moleculeID => { - const foundedMolecule = joinedMoleculeLists?.find(mol => mol.id === moleculeID); - dispatch(removeSurface(majorViewStage, foundedMolecule, colourList[foundedMolecule.id % colourList.length])); - }); - densityList?.forEach(moleculeID => { - const foundedMolecule = joinedMoleculeLists?.find(mol => mol.id === moleculeID); - dispatch(removeDensity(majorViewStage, foundedMolecule, colourList[foundedMolecule.id % colourList.length])); - }); - vectorOnList?.forEach(moleculeID => { - const foundedMolecule = joinedMoleculeLists?.find(mol => mol.id === moleculeID); - dispatch(removeVector(majorViewStage, foundedMolecule, colourList[foundedMolecule.id % colourList.length])); - }); + dispatch(removeAllSelectedMolTypes(majorViewStage, molecules, skipTracking)); }; const selectMoleculeSite = moleculeGroupSite => { @@ -709,7 +697,7 @@ export const MoleculeList = memo(({ height, setFilterItemsHeight, filterItemsHei dispatch(hideAllSelectedMolecules(majorViewStage, joinedMoleculeLists))} + onClick={() => dispatch(hideAllSelectedMolecules(majorViewStage, joinedMoleculeLists, true, true))} > diff --git a/js/components/preview/molecule/moleculeView.js b/js/components/preview/molecule/moleculeView.js index c2667f31d..aef3ced61 100644 --- a/js/components/preview/molecule/moleculeView.js +++ b/js/components/preview/molecule/moleculeView.js @@ -5,13 +5,11 @@ import React, { memo, useEffect, useState, useRef, useContext, useCallback } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { Grid, Button, makeStyles, Typography, Tooltip, IconButton } from '@material-ui/core'; -import { MyLocation, ArrowDownward, ArrowUpward, FormatListBulletedTwoTone, FormatListBulletedSharp, FormatListNumbered } from '@material-ui/icons'; +import { MyLocation, ArrowDownward, ArrowUpward } from '@material-ui/icons'; import SVGInline from 'react-svg-inline'; import classNames from 'classnames'; -import { VIEWS } from '../../../constants/constants'; -import { loadFromServer } from '../../../utils/genericView'; +import { VIEWS, ARROW_TYPE } from '../../../constants/constants'; import { NglContext } from '../../nglView/nglProvider'; -// import { useDisableUserInteraction } from '../../helpers/useEnableUserInteracion'; import { addVector, removeVector, @@ -26,16 +24,15 @@ import { addLigand, removeLigand, searchMoleculeGroupByMoleculeID, - getMolImage + getMolImage, + moveSelectedMolSettings } from './redux/dispatchActions'; -import { setSelectedAll, setDeselectedAll } from '../../../reducers/selection/actions'; +import { setSelectedAll, setDeselectedAll, setArrowUpDown } from '../../../reducers/selection/actions'; import { base_url } from '../../routes/constants'; import { moleculeProperty } from './helperConstants'; import { centerOnLigandByMoleculeID } from '../../../reducers/ngl/dispatchActions'; import { SvgTooltip } from '../../common'; -import { OBJECT_TYPE } from '../../nglView/constants'; -import { getRepresentationsByType } from '../../nglView/generatingObjects'; -import {MOL_TYPE} from './redux/constants'; +import { MOL_TYPE } from './redux/constants'; const useStyles = makeStyles(theme => ({ container: { @@ -210,7 +207,11 @@ const MoleculeView = memo( previousItemData, nextItemData, removeOfAllSelectedTypes, - L, P, C, S, V, + L, + P, + C, + S, + V, selectMoleculeSite }) => { // const [countOfVectors, setCountOfVectors] = useState('-'); @@ -498,36 +499,6 @@ const MoleculeView = memo( return cssClass; }; - const moveSelectedMolSettings = newItemDataset => { - if (newItemDataset) { - if (isLigandOn) { - let representations = getRepresentationsByType(objectsInView, data, OBJECT_TYPE.LIGAND); - dispatch(addLigand(stage, newItemDataset, colourToggle, false, representations)); - } - if (isProteinOn) { - let representations = getRepresentationsByType(objectsInView, data, OBJECT_TYPE.HIT_PROTEIN); - dispatch(addHitProtein(stage, newItemDataset, colourToggle, representations)); - } - if (isComplexOn) { - let representations = getRepresentationsByType(objectsInView, data, OBJECT_TYPE.COMPLEX); - dispatch(addComplex(stage, newItemDataset, colourToggle, representations)); - } - if (isSurfaceOn) { - let representations = getRepresentationsByType(objectsInView, data, OBJECT_TYPE.SURFACE); - dispatch(addSurface(stage, newItemDataset, colourToggle, representations)); - } - // if (isDensityOn) { - // let representations = getRepresentationsByType(objectsInView, data, OBJECT_TYPE.DENSITY); - // dispatch(addDensity(stage, newItemDataset, colourToggle, representations)); - // } - if (isVectorOn) { - dispatch(addVector(stage, newItemDataset)).catch(error => { - throw new Error(error); - }); - } - } - }; - const scrollToElement = element => { element.scrollIntoView({ behavior: 'auto', @@ -540,16 +511,36 @@ const MoleculeView = memo( const refNext = ref.current.nextSibling; scrollToElement(refNext); - removeOfAllSelectedTypes(); - moveSelectedMolSettings(nextItemData); + let dataValue = { + isLigandOn: isLigandOn, + isProteinOn: isProteinOn, + isComplexOn: isComplexOn, + isSurfaceOn: isSurfaceOn, + isVectorOn: isVectorOn, + objectsInView: objectsInView, + colourToggle: colourToggle + }; + removeOfAllSelectedTypes(true); + dispatch(moveSelectedMolSettings(stage, data, nextItemData, dataValue, true)); + dispatch(setArrowUpDown(data, nextItemData, ARROW_TYPE.DOWN, dataValue)); }; const handleClickOnUpArrow = () => { const refPrevious = ref.current.previousSibling; scrollToElement(refPrevious); - removeOfAllSelectedTypes(); - moveSelectedMolSettings(previousItemData); + let dataValue = { + isLigandOn: isLigandOn, + isProteinOn: isProteinOn, + isComplexOn: isComplexOn, + isSurfaceOn: isSurfaceOn, + isVectorOn: isVectorOn, + objectsInView: objectsInView, + colourToggle: colourToggle + }; + removeOfAllSelectedTypes(true); + dispatch(moveSelectedMolSettings(stage, data, previousItemData, dataValue, true)); + dispatch(setArrowUpDown(data, previousItemData, ARROW_TYPE.UP, dataValue)); }; let moleculeTitle = data?.protein_code.replace(new RegExp(`${target_on_name}-`, 'i'), ''); diff --git a/js/components/preview/molecule/redux/dispatchActions.js b/js/components/preview/molecule/redux/dispatchActions.js index c419d947f..a6db8ccbd 100644 --- a/js/components/preview/molecule/redux/dispatchActions.js +++ b/js/components/preview/molecule/redux/dispatchActions.js @@ -44,9 +44,11 @@ import { noCompoundImage } from '../../summary/redux/reducer'; import { getMoleculeOfCurrentVector } from '../../../../reducers/selection/selectors'; import { resetCurrentCompoundsSettings } from '../../compounds/redux/actions'; import { selectMoleculeGroup } from '../../moleculeGroups/redux/dispatchActions'; -import { setDirectAccess, setDirectAccessProcessed } from '../../../../reducers/api/actions'; -import {MOL_TYPE} from './constants'; -import {addImageToCache} from './actions'; +import { setDirectAccessProcessed } from '../../../../reducers/api/actions'; +import { MOL_TYPE } from './constants'; +import { addImageToCache } from './actions'; +import { OBJECT_TYPE } from '../../../nglView/constants'; +import { getRepresentationsByType } from '../../../nglView/generatingObjects'; /** * Convert the JSON into a list of arrow objects @@ -181,7 +183,13 @@ export const removeVector = (stage, data, skipTracking = false) => async (dispat dispatch(setVectorList(vector_list.filter(item => item.moleculeId !== data.id))); }; -export const addHitProtein = (stage, data, colourToggle, skipTracking = false, representations = undefined) => dispatch => { +export const addHitProtein = ( + stage, + data, + colourToggle, + skipTracking = false, + representations = undefined +) => dispatch => { dispatch( loadObject({ target: Object.assign({ display_div: VIEWS.MAJOR_VIEW }, generateHitProteinObject(data, colourToggle, base_url)), @@ -206,7 +214,13 @@ export const removeHitProtein = (stage, data, colourToggle, skipTracking = false dispatch(removeFromProteinList(generateMoleculeId(data), skipTracking)); }; -export const addComplex = (stage, data, colourToggle, skipTracking = false, representations = undefined) => dispatch => { +export const addComplex = ( + stage, + data, + colourToggle, + skipTracking = false, + representations = undefined +) => dispatch => { dispatch( loadObject({ target: Object.assign({ display_div: VIEWS.MAJOR_VIEW }, generateComplexObject(data, colourToggle, base_url)), @@ -231,7 +245,13 @@ export const removeComplex = (stage, data, colourToggle, skipTracking = false) = dispatch(removeFromComplexList(generateMoleculeId(data), skipTracking)); }; -export const addSurface = (stage, data, colourToggle, skipTracking = false, representations = undefined) => dispatch => { +export const addSurface = ( + stage, + data, + colourToggle, + skipTracking = false, + representations = undefined +) => dispatch => { dispatch( loadObject({ target: Object.assign({ display_div: VIEWS.MAJOR_VIEW }, generateSurfaceObject(data, colourToggle, base_url)), @@ -256,7 +276,13 @@ export const removeSurface = (stage, data, colourToggle, skipTracking = false) = dispatch(removeFromSurfaceList(generateMoleculeId(data), skipTracking)); }; -export const addDensity = (stage, data, colourToggle, representations = undefined) => dispatch => { +export const addDensity = ( + stage, + data, + colourToggle, + skipTracking = false, + representations = undefined +) => dispatch => { console.log('TODO'); return; dispatch( @@ -273,7 +299,7 @@ export const addDensity = (stage, data, colourToggle, representations = undefine dispatch(appendDensityList(generateMoleculeId(data))); }; -export const removeDensity = (stage, data, colourToggle) => dispatch => { +export const removeDensity = (stage, data, colourToggle, skipTracking = false) => dispatch => { console.log('TODO'); return; dispatch( @@ -285,10 +311,14 @@ export const removeDensity = (stage, data, colourToggle) => dispatch => { dispatch(removeFromDensityList(generateMoleculeId(data))); }; -export const addLigand = (stage, data, colourToggle, centerOn = false, skipTracking = false, representations = undefined) => ( - dispatch, - getState -) => { +export const addLigand = ( + stage, + data, + colourToggle, + centerOn = false, + skipTracking = false, + representations = undefined +) => (dispatch, getState) => { const currentOrientation = stage.viewerControls.getOrientation(); dispatch(appendFragmentDisplayList(generateMoleculeId(data), skipTracking)); return dispatch( @@ -330,14 +360,13 @@ export const initializeMolecules = (majorView, moleculeList, first) => dispatch } }; -export const hideAllSelectedMolecules = (stage, currentMolecules) => (dispatch, getState) => { +export const hideAllSelectedMolecules = (stage, currentMolecules, isHideAll, skipTracking) => (dispatch, getState) => { const state = getState(); const fragmentDisplayList = state.selectionReducers.fragmentDisplayList; const complexList = state.selectionReducers.complexList; const vectorOnList = state.selectionReducers.vectorOnList; const surfaceList = state.selectionReducers.surfaceList; const proteinList = state.selectionReducers.proteinList; - const vectorList = state.selectionReducers.vector_list; let ligandDataList = []; let complexDataList = []; @@ -349,21 +378,21 @@ export const hideAllSelectedMolecules = (stage, currentMolecules) => (dispatch, const data = currentMolecules.find(molecule => molecule.id === moleculeId); if (data) { ligandDataList.push(data); - dispatch(removeLigand(stage, data, true)); + dispatch(removeLigand(stage, data, skipTracking)); } }); complexList.forEach(moleculeId => { const data = currentMolecules.find(molecule => molecule.id === moleculeId); if (data) { complexDataList.push(data); - dispatch(removeComplex(stage, data, colourList[0], true)); + dispatch(removeComplex(stage, data, colourList[0], skipTracking)); } }); vectorOnList.forEach(moleculeId => { const data = currentMolecules.find(molecule => molecule.id === moleculeId); if (data) { vectorOnDataList.push(data); - dispatch(removeVector(stage, data, true)); + dispatch(removeVector(stage, data, skipTracking)); } }); @@ -372,7 +401,7 @@ export const hideAllSelectedMolecules = (stage, currentMolecules) => (dispatch, const data = currentMolecules.find(molecule => molecule.id === moleculeId); if (data) { surfaceDataList.push(data); - dispatch(removeSurface(stage, data, colourList[0], true)); + dispatch(removeSurface(stage, data, colourList[0], skipTracking)); } }); @@ -381,7 +410,7 @@ export const hideAllSelectedMolecules = (stage, currentMolecules) => (dispatch, const data = currentMolecules.find(molecule => molecule.id === moleculeId); if (data) { proteinDataList.push(data); - dispatch(removeHitProtein(stage, data, colourList[0], true)); + dispatch(removeHitProtein(stage, data, colourList[0], skipTracking)); } }); @@ -398,7 +427,78 @@ export const hideAllSelectedMolecules = (stage, currentMolecules) => (dispatch, surfaceList: surfaceDataList, vectorOnList: vectorOnDataList }; - dispatch(setHideAll(data)); + + if (isHideAll === true) { + dispatch(setHideAll(data)); + } +}; + +export const moveSelectedMolSettings = (stage, item, newItem, data, skipTracking) => (dispatch, getState) => { + if (newItem && data) { + if (data.isLigandOn) { + let representations = getRepresentationsByType(data.objectsInView, item, OBJECT_TYPE.LIGAND); + dispatch(addLigand(stage, newItem, data.colourToggle, false, skipTracking, representations)); + } + if (data.isProteinOn) { + let representations = getRepresentationsByType(data.objectsInView, item, OBJECT_TYPE.HIT_PROTEIN); + dispatch(addHitProtein(stage, newItem, data.colourToggle, skipTracking, representations)); + } + if (data.isComplexOn) { + let representations = getRepresentationsByType(data.objectsInView, item, OBJECT_TYPE.COMPLEX); + dispatch(addComplex(stage, newItem, data.colourToggle, skipTracking, representations)); + } + if (data.isSurfaceOn) { + let representations = getRepresentationsByType(data.objectsInView, item, OBJECT_TYPE.SURFACE); + dispatch(addSurface(stage, newItem, data.colourToggle, skipTracking, representations)); + } + if (data.isVectorOn) { + dispatch(addVector(stage, newItem, skipTracking)).catch(error => { + throw new Error(error); + }); + } + } +}; + +export const removeAllSelectedMolTypes = (majorViewStage, molecules, skipTracking = false) => (dispatch, getState) => { + const state = getState(); + const fragmentDisplayList = state.selectionReducers.fragmentDisplayList; + const complexList = state.selectionReducers.complexList; + const vectorOnList = state.selectionReducers.vectorOnList; + const surfaceList = state.selectionReducers.surfaceList; + const proteinList = state.selectionReducers.proteinList; + let joinedMoleculeLists = molecules; + + proteinList?.forEach(moleculeID => { + const foundedMolecule = joinedMoleculeLists?.find(mol => mol.id === moleculeID); + dispatch( + removeHitProtein( + majorViewStage, + foundedMolecule, + colourList[foundedMolecule.id % colourList.length], + skipTracking + ) + ); + }); + complexList?.forEach(moleculeID => { + const foundedMolecule = joinedMoleculeLists?.find(mol => mol.id === moleculeID); + dispatch( + removeComplex(majorViewStage, foundedMolecule, colourList[foundedMolecule.id % colourList.length], skipTracking) + ); + }); + fragmentDisplayList?.forEach(moleculeID => { + const foundedMolecule = joinedMoleculeLists?.find(mol => mol.id === moleculeID); + dispatch(removeLigand(majorViewStage, foundedMolecule, skipTracking)); + }); + surfaceList?.forEach(moleculeID => { + const foundedMolecule = joinedMoleculeLists?.find(mol => mol.id === moleculeID); + dispatch( + removeSurface(majorViewStage, foundedMolecule, colourList[foundedMolecule.id % colourList.length], skipTracking) + ); + }); + vectorOnList?.forEach(moleculeID => { + const foundedMolecule = joinedMoleculeLists?.find(mol => mol.id === moleculeID); + dispatch(removeVector(majorViewStage, foundedMolecule, skipTracking)); + }); }; // export const searchMoleculeGroupByMoleculeID = moleculeID => (dispatch, getState) => @@ -429,15 +529,15 @@ export const searchMoleculeGroupByMoleculeID = moleculeId => (dispatch, getState if (mol.id === moleculeId) { resultMolGroupID = groupId; break; - }; - }; + } + } if (resultMolGroupID != null) { break; - }; - }; + } + } return Promise.resolve(resultMolGroupID); -} +}; export const applyDirectSelection = (stage, stageSummaryView) => (dispatch, getState) => { const state = getState(); @@ -515,7 +615,7 @@ export const getMolImage = (molId, molType, width, height) => (dispatch, getStat return loadMolImage(molId, molType, width, height).then(i => { if (!imageCache.hasOwnProperty(molIdStr)) { dispatch(addImageToCache(molId.toString(), i)); - }; + } return i; }); } diff --git a/js/constants/constants.js b/js/constants/constants.js index afd9e0200..76fa775f0 100644 --- a/js/constants/constants.js +++ b/js/constants/constants.js @@ -25,3 +25,8 @@ export const SUFFIX = { MAIN: '_MAIN', INTERACTION: '_INTERACTION' }; + +export const ARROW_TYPE = { + UP: 'UP', + DOWN: 'DOWN' +}; diff --git a/js/reducers/api/actions.js b/js/reducers/api/actions.js index d384e30e4..e90283943 100644 --- a/js/reducers/api/actions.js +++ b/js/reducers/api/actions.js @@ -95,6 +95,13 @@ export const setAllMolLists = all_mol_lists => { }; }; +export const setAllMolecules = molecules => { + return { + type: constants.SET_ALL_MOLECULES, + allMolecules: molecules + }; +}; + export const setSavingState = function(savingState) { return { type: constants.SET_SAVING_STATE, diff --git a/js/reducers/api/apiReducers.js b/js/reducers/api/apiReducers.js index 6a65919fa..fc390916b 100644 --- a/js/reducers/api/apiReducers.js +++ b/js/reducers/api/apiReducers.js @@ -12,6 +12,7 @@ export const INITIAL_STATE = { molecule_list: [], cached_mol_lists: {}, all_mol_lists: {}, + allMolecules: [], duck_yank_data: {}, pandda_event_on: undefined, pandda_site_on: undefined, @@ -115,6 +116,9 @@ export default function apiReducers(state = INITIAL_STATE, action = {}) { case constants.SET_ALL_MOL_LISTS: return { ...state, all_mol_lists: action.all_mol_lists }; + case constants.SET_ALL_MOLECULES: + return { ...state, allMolecules: action.allMolecules }; + case constants.SET_PANNDA_EVENT_LIST: return Object.assign({}, state, { pandda_event_list: action.pandda_event_list @@ -171,10 +175,10 @@ export default function apiReducers(state = INITIAL_STATE, action = {}) { }); case constants.SET_DIRECT_ACCESS: - return {...state, direct_access: action.direct_access}; - + return { ...state, direct_access: action.direct_access }; + case constants.SET_DIRECT_ACCESS_PROCESSED: - return {...state, direct_access_processed: action.direct_access_processed}; + return { ...state, direct_access_processed: action.direct_access_processed }; case constants.SET_SESSION_ID_LIST: let sessionSummaryNew = []; diff --git a/js/reducers/api/constants.js b/js/reducers/api/constants.js index 00208acbc..d646b877a 100644 --- a/js/reducers/api/constants.js +++ b/js/reducers/api/constants.js @@ -16,6 +16,7 @@ export const constants = { SET_MOLECULE_LIST: prefix + 'SET_MOLECULE_LIST', SET_CACHED_MOL_LISTS: prefix + 'SET_CACHED_MOL_LISTS', SET_ALL_MOL_LISTS: prefix + 'SET_ALL_MOL_LISTS', + SET_ALL_MOLECULES: prefix + 'SET_ALL_MOLECULES', SET_SAVING_STATE: prefix + 'SET_SAVING_STATE', SET_SESH_LIST_SAVING: prefix + 'SET_SESH_LIST_SAVING', SET_LATEST_SNAPSHOT: prefix + 'SET_LATEST_SNAPSHOT', diff --git a/js/reducers/selection/actions.js b/js/reducers/selection/actions.js index 9055a1112..201594e5e 100644 --- a/js/reducers/selection/actions.js +++ b/js/reducers/selection/actions.js @@ -285,3 +285,13 @@ export const setHideAll = (data, isHide = true) => ({ isHide: isHide, data: data }); + +export const setArrowUpDown = (item, newItem, arrowType, data) => ({ + type: constants.SET_ARROW_UP_DOWN, + payload: { + item: item, + newItem: newItem, + arrowType: arrowType, + data + } +}); diff --git a/js/reducers/selection/constants.js b/js/reducers/selection/constants.js index d91a8af26..c7e8c1979 100644 --- a/js/reducers/selection/constants.js +++ b/js/reducers/selection/constants.js @@ -39,6 +39,7 @@ export const constants = { SET_SELECTED_ALL_BY_TYPE: prefix + 'SET_SELECTED_ALL_BY_TYPE', SET_DESELECTED_ALL_BY_TYPE: prefix + 'SET_DESELECTED_ALL_BY_TYPE', SET_HIDE_ALL: prefix + 'SET_HIDE_ALL', + SET_ARROW_UP_DOWN: prefix + 'SET_ARROW_UP_DOWN', RESET_COMPOUNDS_OF_VECTORS: prefix + 'RESET_COMPOUNDS_OF_VECTORS', UPDATE_VECTOR_COMPOUNDS: prefix + 'UPDATE_VECTOR_COMPOUNDS', diff --git a/js/reducers/tracking/constants.js b/js/reducers/tracking/constants.js index 7f2183f77..e2389c316 100644 --- a/js/reducers/tracking/constants.js +++ b/js/reducers/tracking/constants.js @@ -57,6 +57,7 @@ export const actionType = { NGL_STATE: 'NGL_STATE', UNDO: 'UNDO', REDO: 'REDO', + ARROW_NAVIGATION: 'ARROW_NAVIGATION', SNAPSHOT: 'SNAPSHOT', ALL_HIDE: 'ALL_HIDE', ALL_TURNED_ON: 'ALL_TURNED_ON', @@ -75,6 +76,7 @@ export const actionDescription = { LOADED: 'was loaded', TURNED_ON: 'was turned on', TURNED_OFF: 'was turned off', + MOVED: 'was moved', SELECTED: 'was selected', DESELECTED: 'was deselected', HIDDEN: 'hidden', @@ -92,6 +94,9 @@ export const actionDescription = { INTERACTION: 'Interaction', VECTOR: 'Vector', COMPOUND: 'Compound', + MOLECULE: 'Molecule', + INSPIRATION: 'Inspiration', + CROSS_REFERENCE: 'Cross reference', CLASS: 'Compound colour', SURFACE: 'Surface', SITE: 'Site', diff --git a/js/reducers/tracking/dispatchActions.js b/js/reducers/tracking/dispatchActions.js index c048772c1..07b2ec971 100644 --- a/js/reducers/tracking/dispatchActions.js +++ b/js/reducers/tracking/dispatchActions.js @@ -7,7 +7,7 @@ import { import { createInitAction } from './trackingActions'; import { actionType, actionObjectType, NUM_OF_SECONDS_TO_IGNORE_MERGE } from './constants'; import { VIEWS } from '../../../js/constants/constants'; -import { setCurrentVector, appendToBuyList, setHideAll } from '../selection/actions'; +import { setCurrentVector, appendToBuyList, setHideAll, setArrowUpDown } from '../selection/actions'; import { resetReducersForRestoringActions, shouldLoadProtein, @@ -31,7 +31,10 @@ import { removeLigand, removeHitProtein, removeSurface, - removeVector + removeVector, + moveSelectedMolSettings, + removeAllSelectedMolTypes, + hideAllSelectedMolecules } from '../../components/preview/molecule/redux/dispatchActions'; import { handleBuyList, @@ -50,7 +53,12 @@ import { removeDatasetHitProtein, removeDatasetSurface, loadDataSets, - loadDatasetCompoundsWithScores + loadDatasetCompoundsWithScores, + removeAllSelectedDatasetMolecules, + moveSelectedMoleculeSettings, + moveSelectedInspirations, + moveMoleculeInspirationsSettings, + getInspirationsForMol } from '../../components/datasets/redux/dispatchActions'; import { appendMoleculeToCompoundsOfDatasetToBuy, @@ -110,7 +118,10 @@ import { setSelectedAll as setSelectedAllOfDataset, setDeselectedAll as setDeselectedAllOfDataset, setSelectedAllByType as setSelectedAllByTypeOfDataset, - setDeselectedAllByType as setDeselectedAllByTypeOfDataset + setDeselectedAllByType as setDeselectedAllByTypeOfDataset, + setArrowUpDown as setArrowUpDownOfDataset, + setCrossReferenceCompoundName, + setInspirationMoleculeDataList } from '../../components/datasets/redux/actions'; import { selectVectorAndResetCompounds } from '../../../js/reducers/selection/dispatchActions'; @@ -1337,6 +1348,9 @@ const handleUndoAction = (action, stages) => (dispatch, getState) => { case actionType.VECTORS_TURNED_OFF: dispatch(handleMoleculeAction(action, 'vector', true, majorViewStage, state)); break; + case actionType.ARROW_NAVIGATION: + dispatch(handleArrowNavigationAction(action, false, majorViewStage)); + break; case actionType.VECTOR_SELECTED: dispatch(handleVectorAction(action, false)); break; @@ -1480,6 +1494,9 @@ const handleRedoAction = (action, stages) => (dispatch, getState) => { case actionType.VECTORS_TURNED_OFF: dispatch(handleMoleculeAction(action, 'vector', false, majorViewStage, state)); break; + case actionType.ARROW_NAVIGATION: + dispatch(handleArrowNavigationAction(action, true, majorViewStage)); + break; case actionType.VECTOR_SELECTED: dispatch(handleVectorAction(action, true)); break; @@ -2002,6 +2019,97 @@ const changeMolecularRepresentation = (action, representation, type, parentKey, dispatch(changeComponentRepresentation(parentKey, oldRepresentation, newRepresentation)); }; +const handleArrowNavigationAction = (action, isSelected, majorViewStage) => (dispatch, getState) => { + if (action) { + let isSelection = + action.object_type === actionObjectType.MOLECULE || action.object_type === actionObjectType.INSPIRATION; + + if (isSelection === true) { + dispatch(handleArrowNavigationActionOfMolecule(action, isSelected, majorViewStage)); + } else { + dispatch(handleArrowNavigationActionOfCompound(action, isSelected, majorViewStage)); + } + } +}; + +const handleArrowNavigationActionOfMolecule = (action, isSelected, majorViewStage) => (dispatch, getState) => { + const state = getState(); + if (action) { + let molecules = state.apiReducers.allMolecules; + let item = isSelected === true ? action.item : action.newItem; + let newItem = isSelected === true ? action.newItem : action.item; + let data = action.data; + + dispatch(removeAllSelectedMolTypes(majorViewStage, molecules, true)); + dispatch(moveSelectedMolSettings(majorViewStage, item, newItem, data, true)); + dispatch(setArrowUpDown(item, newItem, action.arrowType, data)); + } +}; + +const handleArrowNavigationActionOfCompound = (action, isSelected, majorViewStage) => (dispatch, getState) => { + const state = getState(); + if (action) { + const molecules = state.apiReducers.allMolecules; + const allInspirations = state.datasetsReducers.allInspirations; + + let data = action.data; + let item = isSelected === true ? action.item : action.newItem; + let newItem = isSelected === true ? action.newItem : action.item; + let datasetID = action.datasetID; + + const proteinListMolecule = data.proteinList; + const complexListMolecule = data.complexList; + const fragmentDisplayListMolecule = data.fragmentDisplayList; + const surfaceListMolecule = data.surfaceList; + const densityListMolecule = data.surfaceList; + const vectorOnListMolecule = data.vectorOnList; + + dispatch(hideAllSelectedMolecules(majorViewStage, molecules, false, true)); + dispatch(removeAllSelectedDatasetMolecules(majorViewStage, true)); + + const newDatasetID = (newItem.hasOwnProperty('datasetID') && newItem.datasetID) || datasetID; + const moleculeTitlePrev = newItem && newItem.name; + + const inspirations = getInspirationsForMol(allInspirations, datasetID, newItem.id); + dispatch(setInspirationMoleculeDataList(inspirations)); + dispatch(moveSelectedMoleculeSettings(majorViewStage, item, newItem, newDatasetID, datasetID, data, true)); + + if (isSelected === true) { + dispatch( + moveMoleculeInspirationsSettings( + item, + newItem, + majorViewStage, + data.objectsInView, + fragmentDisplayListMolecule, + proteinListMolecule, + complexListMolecule, + surfaceListMolecule, + densityListMolecule, + vectorOnListMolecule, + true + ) + ); + } else { + dispatch( + moveSelectedInspirations( + majorViewStage, + data.objectsInView, + fragmentDisplayListMolecule, + proteinListMolecule, + complexListMolecule, + surfaceListMolecule, + vectorOnListMolecule, + true + ) + ); + } + + dispatch(setCrossReferenceCompoundName(moleculeTitlePrev)); + dispatch(setArrowUpDownOfDataset(datasetID, item, newItem, action.arrowType, data)); + } +}; + const handleMoleculeGroupAction = (action, isSelected, stageSummaryView, majorViewStage) => (dispatch, getState) => { const state = getState(); if (action) { diff --git a/js/reducers/tracking/trackingActions.js b/js/reducers/tracking/trackingActions.js index e764fc3b0..bc7334478 100644 --- a/js/reducers/tracking/trackingActions.js +++ b/js/reducers/tracking/trackingActions.js @@ -5,17 +5,16 @@ import { constants as previewCompoundConstants } from '../../components/preview/ import { constants as selectionConstants } from '../selection/constants'; import { constants as customDatasetConstants } from '../../components/datasets/redux/constants'; import { DJANGO_CONTEXT } from '../../utils/djangoContext'; -import { NGL_PARAMS, BACKGROUND_COLOR } from '../../components/nglView/constants/index'; +import { BACKGROUND_COLOR } from '../../components/nglView/constants/index'; export const findTrackAction = (action, state) => { const username = DJANGO_CONTEXT['username']; const target_on_name = state.apiReducers.target_on_name; const isActionRestoring = state.trackingReducers.isActionRestoring; - const viewParams = state.nglReducers.viewParams; let trackAction = null; if (isActionRestoring === false && action.skipTracking !== true) { - if (action.type.includes(apiConstants.SET_TARGET_ON)) { + if (action.type === apiConstants.SET_TARGET_ON) { if (action.target_on) { let targetName = getTargetName(action.target_on, state); trackAction = { @@ -29,7 +28,7 @@ export const findTrackAction = (action, state) => { text: `${actionDescription.TARGET} ${targetName} ${actionDescription.LOADED}` }; } - } else if (action.type.includes(apiConstants.SET_MOL_GROUP_ON)) { + } else if (action.type === apiConstants.SET_MOL_GROUP_ON) { if (action.mol_group_on) { let molGroupSelection = state.selectionReducers.mol_group_selection; let currentMolGroup = molGroupSelection && molGroupSelection.find(o => o === action.mol_group_on); @@ -47,7 +46,7 @@ export const findTrackAction = (action, state) => { }; } } - } else if (action.type.includes(apiConstants.SET_MOL_GROUP_OFF)) { + } else if (action.type === apiConstants.SET_MOL_GROUP_OFF) { const { mol_group_off, selectionGroups } = action; let molGroupName = getMolGroupName(mol_group_off, state); trackAction = { @@ -60,7 +59,7 @@ export const findTrackAction = (action, state) => { selectionGroups, text: `${actionDescription.SITE} ${molGroupName} ${actionDescription.TURNED_OFF}` }; - } else if (action.type.includes(selectionConstants.SET_OBJECT_SELECTION)) { + } else if (action.type === selectionConstants.SET_OBJECT_SELECTION) { let objectId = action.payload && action.payload[0]; if (objectId) { let molGroupName = getMolGroupName(objectId, state); @@ -170,7 +169,7 @@ export const findTrackAction = (action, state) => { text: `${actionDescription.ALL} ${paylodTypeDescription} ${actionDescription.TURNED_OFF} ${objectType}` }; } - } else if (action.type.includes(selectionConstants.APPEND_FRAGMENT_DISPLAY_LIST)) { + } else if (action.type === selectionConstants.APPEND_FRAGMENT_DISPLAY_LIST) { if (action.item) { let objectType = action.item.isInspiration === true ? actionObjectType.INSPIRATION : actionObjectType.MOLECULE; let objectName = action.item.name || getMoleculeName(action.item.id, state); @@ -189,7 +188,7 @@ export const findTrackAction = (action, state) => { )}` }; } - } else if (action.type.includes(selectionConstants.REMOVE_FROM_FRAGMENT_DISPLAY_LIST)) { + } else if (action.type === selectionConstants.REMOVE_FROM_FRAGMENT_DISPLAY_LIST) { if (action.item) { let objectType = action.item.isInspiration === true ? actionObjectType.INSPIRATION : actionObjectType.MOLECULE; let objectName = action.item.name || getMoleculeName(action.item.id, state); @@ -208,7 +207,7 @@ export const findTrackAction = (action, state) => { )}` }; } - } else if (action.type.includes(selectionConstants.APPEND_PROTEIN_LIST)) { + } else if (action.type === selectionConstants.APPEND_PROTEIN_LIST) { if (action.item) { let objectType = action.item.isInspiration === true ? actionObjectType.INSPIRATION : actionObjectType.MOLECULE; let objectName = action.item.name || getMoleculeName(action.item.id, state); @@ -227,7 +226,7 @@ export const findTrackAction = (action, state) => { )}` }; } - } else if (action.type.includes(selectionConstants.REMOVE_FROM_PROTEIN_LIST)) { + } else if (action.type === selectionConstants.REMOVE_FROM_PROTEIN_LIST) { if (action.item) { let objectType = action.item.isInspiration === true ? actionObjectType.INSPIRATION : actionObjectType.MOLECULE; let objectName = action.item.name || getMoleculeName(action.item.id, state); @@ -246,7 +245,7 @@ export const findTrackAction = (action, state) => { )}` }; } - } else if (action.type.includes(selectionConstants.APPEND_COMPLEX_LIST)) { + } else if (action.type === selectionConstants.APPEND_COMPLEX_LIST) { if (action.item) { let objectType = action.item.isInspiration === true ? actionObjectType.INSPIRATION : actionObjectType.MOLECULE; let objectName = action.item.name || getMoleculeName(action.item.id, state); @@ -265,7 +264,7 @@ export const findTrackAction = (action, state) => { )}` }; } - } else if (action.type.includes(selectionConstants.REMOVE_FROM_COMPLEX_LIST)) { + } else if (action.type === selectionConstants.REMOVE_FROM_COMPLEX_LIST) { if (action.item) { let objectType = action.item.isInspiration === true ? actionObjectType.INSPIRATION : actionObjectType.MOLECULE; let objectName = action.item.name || getMoleculeName(action.item.id, state); @@ -284,7 +283,7 @@ export const findTrackAction = (action, state) => { )}` }; } - } else if (action.type.includes(selectionConstants.APPEND_SURFACE_LIST)) { + } else if (action.type === selectionConstants.APPEND_SURFACE_LIST) { if (action.item) { let objectType = action.item.isInspiration === true ? actionObjectType.INSPIRATION : actionObjectType.MOLECULE; let objectName = action.item.name || getMoleculeName(action.item.id, state); @@ -303,7 +302,7 @@ export const findTrackAction = (action, state) => { )}` }; } - } else if (action.type.includes(selectionConstants.REMOVE_FROM_SURFACE_LIST)) { + } else if (action.type === selectionConstants.REMOVE_FROM_SURFACE_LIST) { if (action.item) { let objectType = action.item.isInspiration === true ? actionObjectType.INSPIRATION : actionObjectType.MOLECULE; let objectName = action.item.name || getMoleculeName(action.item.id, state); @@ -322,7 +321,7 @@ export const findTrackAction = (action, state) => { )}` }; } - } else if (action.type.includes(selectionConstants.APPEND_VECTOR_ON_LIST)) { + } else if (action.type === selectionConstants.APPEND_VECTOR_ON_LIST) { if (action.item) { let objectType = action.item.isInspiration === true ? actionObjectType.INSPIRATION : actionObjectType.MOLECULE; let objectName = action.item.name || getMoleculeName(action.item.id, state); @@ -341,7 +340,7 @@ export const findTrackAction = (action, state) => { )}` }; } - } else if (action.type.includes(selectionConstants.REMOVE_FROM_VECTOR_ON_LIST)) { + } else if (action.type === selectionConstants.REMOVE_FROM_VECTOR_ON_LIST) { if (action.item) { let objectType = action.item.isInspiration === true ? actionObjectType.INSPIRATION : actionObjectType.MOLECULE; let objectName = action.item.name || getMoleculeName(action.item.id, state); @@ -360,6 +359,32 @@ export const findTrackAction = (action, state) => { )}` }; } + } else if (action.type === selectionConstants.SET_ARROW_UP_DOWN) { + let payload = action.payload; + if (payload) { + let item = payload.item; + let newItem = payload.newItem; + let objectType = item && item.isInspiration === true ? actionObjectType.INSPIRATION : actionObjectType.MOLECULE; + let objectTypeDescription = + item && item.isInspiration === true ? actionDescription.INSPIRATION : actionDescription.MOLECULE; + let itemName = item?.name || getMoleculeName(item?.id, state); + let newItemName = newItem?.name || getMoleculeName(newItem?.id, state); + + trackAction = { + type: actionType.ARROW_NAVIGATION, + annotation: actionAnnotation.CHECK, + timestamp: Date.now(), + username: username, + object_type: objectType, + object_name: itemName, + object_id: item?.id, + item: item, + newItem: newItem, + data: payload.data, + arrowType: payload.arrowType, + text: `${objectTypeDescription} ${actionDescription.MOVED} from: ${itemName} to ${newItemName}` + }; + } } else if (action.type === selectionConstants.APPEND_TO_BUY_LIST) { if (action.item) { let objectType = actionObjectType.MOLECULE; @@ -454,7 +479,7 @@ export const findTrackAction = (action, state) => { compoundId: action.payload, text: `${actionDescription.COMPOUND} ${objectName} ${actionDescription.REMOVED}` }; - } else if (action.type.includes(selectionConstants.SET_CURRENT_VECTOR)) { + } else if (action.type === selectionConstants.SET_CURRENT_VECTOR) { if (action.payload) { let objectType = actionObjectType.MOLECULE; let objectName = action.payload; @@ -506,7 +531,7 @@ export const findTrackAction = (action, state) => { text: `${actionDescription.CLASS} value ${actionDescription.UPDATED}: ${action.id}:${action.value}` }; } - } else if (action.type.includes(customDatasetConstants.APPEND_MOLECULE_TO_COMPOUNDS_TO_BUY_OF_DATASET)) { + } else if (action.type === customDatasetConstants.APPEND_MOLECULE_TO_COMPOUNDS_TO_BUY_OF_DATASET) { if (action.payload) { let objectType = actionObjectType.COMPOUND; let objectName = action.payload.moleculeTitle; @@ -523,7 +548,7 @@ export const findTrackAction = (action, state) => { text: `${objectType} ${objectName} ${actionDescription.SELECTED} of dataset: ${action.payload.datasetID}` }; } - } else if (action.type.includes(customDatasetConstants.REMOVE_MOLECULE_FROM_COMPOUNDS_TO_BUY_OF_DATASET)) { + } else if (action.type === customDatasetConstants.REMOVE_MOLECULE_FROM_COMPOUNDS_TO_BUY_OF_DATASET) { if (action.payload) { let objectType = actionObjectType.COMPOUND; let objectName = action.payload.moleculeTitle; @@ -622,7 +647,7 @@ export const findTrackAction = (action, state) => { text: `${actionDescription.ALL} ${paylodTypeDescription} ${actionDescription.TURNED_OFF} ${objectType} ${datasetDescription}` }; } - } else if (action.type.includes(customDatasetConstants.APPEND_LIGAND_LIST)) { + } else if (action.type === customDatasetConstants.APPEND_LIGAND_LIST) { if (action.payload && action.payload.item) { let objectType = action.payload.item.isCrossReference === true ? actionObjectType.CROSS_REFERENCE : actionObjectType.COMPOUND; @@ -640,7 +665,7 @@ export const findTrackAction = (action, state) => { text: `${actionDescription.LIGAND} ${actionDescription.TURNED_ON} ${objectType} ${objectName} of dataset: ${action.payload.datasetID}` }; } - } else if (action.type.includes(customDatasetConstants.REMOVE_FROM_LIGAND_LIST)) { + } else if (action.type === customDatasetConstants.REMOVE_FROM_LIGAND_LIST) { if (action.payload && action.payload.item) { let objectType = action.payload.item.isCrossReference === true ? actionObjectType.CROSS_REFERENCE : actionObjectType.COMPOUND; @@ -658,7 +683,7 @@ export const findTrackAction = (action, state) => { text: `${actionDescription.LIGAND} ${actionDescription.TURNED_OFF} ${objectType} ${objectName} of dataset: ${action.payload.datasetID}` }; } - } else if (action.type.includes(customDatasetConstants.APPEND_PROTEIN_LIST)) { + } else if (action.type === customDatasetConstants.APPEND_PROTEIN_LIST) { if (action.payload && action.payload.item) { let objectType = action.payload.item.isCrossReference === true ? actionObjectType.CROSS_REFERENCE : actionObjectType.COMPOUND; @@ -676,7 +701,7 @@ export const findTrackAction = (action, state) => { text: `${actionDescription.SIDECHAIN} ${actionDescription.TURNED_ON} ${objectType} ${objectName} of dataset: ${action.payload.datasetID}` }; } - } else if (action.type.includes(customDatasetConstants.REMOVE_FROM_PROTEIN_LIST)) { + } else if (action.type === customDatasetConstants.REMOVE_FROM_PROTEIN_LIST) { if (action.payload && action.payload.item) { let objectType = action.payload.item.isCrossReference === true ? actionObjectType.CROSS_REFERENCE : actionObjectType.COMPOUND; @@ -694,7 +719,7 @@ export const findTrackAction = (action, state) => { text: `${actionDescription.SIDECHAIN} ${actionDescription.TURNED_OFF} ${objectType} ${objectName} of dataset: ${action.payload.datasetID}` }; } - } else if (action.type.includes(customDatasetConstants.APPEND_COMPLEX_LIST)) { + } else if (action.type === customDatasetConstants.APPEND_COMPLEX_LIST) { if (action.payload && action.payload.item) { let objectType = action.payload.item.isCrossReference === true ? actionObjectType.CROSS_REFERENCE : actionObjectType.COMPOUND; @@ -712,7 +737,7 @@ export const findTrackAction = (action, state) => { text: `${actionDescription.INTERACTION} ${actionDescription.TURNED_ON} ${objectType} ${objectName} of dataset: ${action.payload.datasetID}` }; } - } else if (action.type.includes(customDatasetConstants.REMOVE_FROM_COMPLEX_LIST)) { + } else if (action.type === customDatasetConstants.REMOVE_FROM_COMPLEX_LIST) { if (action.payload && action.payload.item) { let objectType = action.payload.item.isCrossReference === true ? actionObjectType.CROSS_REFERENCE : actionObjectType.COMPOUND; @@ -730,7 +755,7 @@ export const findTrackAction = (action, state) => { text: `${actionDescription.INTERACTION} ${actionDescription.TURNED_OFF} ${objectType} ${objectName} of dataset: ${action.payload.datasetID}` }; } - } else if (action.type.includes(customDatasetConstants.APPEND_SURFACE_LIST)) { + } else if (action.type === customDatasetConstants.APPEND_SURFACE_LIST) { if (action.payload && action.payload.item) { let objectType = action.payload.item.isCrossReference === true ? actionObjectType.CROSS_REFERENCE : actionObjectType.COMPOUND; @@ -748,7 +773,7 @@ export const findTrackAction = (action, state) => { text: `${actionDescription.SURFACE} ${actionDescription.TURNED_ON} ${objectType} ${objectName} of dataset: ${action.payload.datasetID}` }; } - } else if (action.type.includes(customDatasetConstants.REMOVE_FROM_SURFACE_LIST)) { + } else if (action.type === customDatasetConstants.REMOVE_FROM_SURFACE_LIST) { if (action.payload && action.payload.item) { let objectType = action.payload.item.isCrossReference === true ? actionObjectType.CROSS_REFERENCE : actionObjectType.COMPOUND; @@ -766,6 +791,47 @@ export const findTrackAction = (action, state) => { text: `${actionDescription.SURFACE} ${actionDescription.TURNED_OFF} ${objectType} ${objectName} of dataset: ${action.payload.datasetID}` }; } + } else if (action.type === customDatasetConstants.SET_ARROW_UP_DOWN) { + let payload = action.payload; + if (payload) { + const proteinList = state.selectionReducers.proteinList; + const complexList = state.selectionReducers.complexList; + const fragmentDisplayList = state.selectionReducers.fragmentDisplayList; + const surfaceList = state.selectionReducers.surfaceList; + const densityList = state.selectionReducers.densityList; + const vectorOnList = state.selectionReducers.vectorOnList; + + let item = payload.item; + let newItem = payload.newItem; + let objectType = + item && item.isCrossReference === true ? actionObjectType.CROSS_REFERENCE : actionObjectType.COMPOUND; + let objectTypeDescription = + item && item.isCrossReference === true ? actionDescription.CROSS_REFERENCE : actionDescription.COMPOUND; + let itemId = item?.id; + let itemName = item?.name; + let newItemName = newItem?.name; + + let data = Object.assign( + { proteinList, complexList, fragmentDisplayList, surfaceList, densityList, vectorOnList }, + payload.data + ); + + trackAction = { + type: actionType.ARROW_NAVIGATION, + annotation: actionAnnotation.CHECK, + timestamp: Date.now(), + username: username, + object_type: objectType, + object_name: itemName, + object_id: itemId, + datasetID: payload.datasetID, + item: item, + newItem: newItem, + data: data, + arrowType: payload.arrowType, + text: `${objectTypeDescription} ${actionDescription.MOVED} from: ${itemName} to ${newItemName}` + }; + } } else if (action.type === nglConstants.UPDATE_COMPONENT_REPRESENTATION_VISIBILITY) { let objectType = actionObjectType.REPRESENTATION; let value = action.newVisibility; @@ -800,7 +866,7 @@ export const findTrackAction = (action, state) => { value: value, text: `${objectType} ${actionDescription.VISIBILITY} of ${action.objectInViewID} ${actionDescription.CHANGED} to: ${valueDescription}` }; - } else if (action.type.includes(nglConstants.UPDATE_COMPONENT_REPRESENTATION)) { + } else if (action.type === nglConstants.UPDATE_COMPONENT_REPRESENTATION) { let objectType = actionObjectType.REPRESENTATION; let key = action.change?.key; let oldValue = action.change?.oldValue; @@ -823,7 +889,7 @@ export const findTrackAction = (action, state) => { change: action.change, text: `${objectType} '${key}' of ${action.objectInViewID} ${actionDescription.UPDATED} ${valueDescription}` }; - } else if (action.type.includes(nglConstants.ADD_COMPONENT_REPRESENTATION)) { + } else if (action.type === nglConstants.ADD_COMPONENT_REPRESENTATION) { let objectType = actionObjectType.REPRESENTATION; let representationName = action.newRepresentation && action.newRepresentation.type; @@ -838,7 +904,7 @@ export const findTrackAction = (action, state) => { representation: action.newRepresentation, text: `${objectType} '${representationName}' of ${action.objectInViewID} ${actionDescription.ADDED}` }; - } else if (action.type.includes(nglConstants.REMOVE_COMPONENT_REPRESENTATION)) { + } else if (action.type === nglConstants.REMOVE_COMPONENT_REPRESENTATION) { let objectType = actionObjectType.REPRESENTATION; let representationName = action.representation && action.representation.type; @@ -853,7 +919,7 @@ export const findTrackAction = (action, state) => { representation: action.representation, text: `${objectType} '${representationName}' of ${action.objectInViewID} ${actionDescription.REMOVED}` }; - } else if (action.type.includes(nglConstants.CHANGE_COMPONENT_REPRESENTATION)) { + } else if (action.type === nglConstants.CHANGE_COMPONENT_REPRESENTATION) { let objectType = actionObjectType.REPRESENTATION; let oldRepresentationName = action.oldRepresentation && action.oldRepresentation.type; let newRepresentationName = action.newRepresentation && action.newRepresentation.type; @@ -870,7 +936,7 @@ export const findTrackAction = (action, state) => { newRepresentation: action.newRepresentation, text: `${objectType} of ${action.objectInViewID} ${actionDescription.CHANGED} from value: ${oldRepresentationName} to value: ${newRepresentationName}` }; - } else if (action.type.includes(nglConstants.SET_BACKGROUND_COLOR)) { + } else if (action.type === nglConstants.SET_BACKGROUND_COLOR) { let oldSetting = action.payload === BACKGROUND_COLOR.white ? BACKGROUND_COLOR.black : BACKGROUND_COLOR.white; let newSetting = action.payload; @@ -885,7 +951,7 @@ export const findTrackAction = (action, state) => { newSetting: newSetting, text: `Color of NGL ${actionDescription.CHANGED} from value: ${oldSetting} to value: ${newSetting}` }; - } else if (action.type.includes(nglConstants.SET_CLIP_NEAR)) { + } else if (action.type === nglConstants.SET_CLIP_NEAR) { let oldSetting = action.payload.oldValue; let newSetting = action.payload.newValue; @@ -911,7 +977,7 @@ export const findTrackAction = (action, state) => { }, text: `Clip near of NGL ${actionDescription.CHANGED} from value: ${oldSetting} to value: ${newSetting}` }; - } else if (action.type.includes(nglConstants.SET_CLIP_FAR)) { + } else if (action.type === nglConstants.SET_CLIP_FAR) { let oldSetting = action.payload.oldValue; let newSetting = action.payload.newValue; @@ -937,7 +1003,7 @@ export const findTrackAction = (action, state) => { }, text: `Clip far of NGL ${actionDescription.CHANGED} from value: ${oldSetting} to value: ${newSetting}` }; - } else if (action.type.includes(nglConstants.SET_CLIP_DIST)) { + } else if (action.type === nglConstants.SET_CLIP_DIST) { let oldSetting = action.payload.oldValue; let newSetting = action.payload.newValue; @@ -963,7 +1029,7 @@ export const findTrackAction = (action, state) => { }, text: `Clip dist of NGL ${actionDescription.CHANGED} from value: ${oldSetting} to value: ${newSetting}` }; - } else if (action.type.includes(nglConstants.SET_FOG_NEAR)) { + } else if (action.type === nglConstants.SET_FOG_NEAR) { let oldSetting = action.payload.oldValue; let newSetting = action.payload.newValue; @@ -989,7 +1055,7 @@ export const findTrackAction = (action, state) => { }, text: `For near of NGL ${actionDescription.CHANGED} from value: ${oldSetting} to value: ${newSetting}` }; - } else if (action.type.includes(nglConstants.SET_FOG_FAR)) { + } else if (action.type === nglConstants.SET_FOG_FAR) { let oldSetting = action.payload.oldValue; let newSetting = action.payload.newValue;