From 67200eb799727baa5eea7ae52c378d84f098bf21 Mon Sep 17 00:00:00 2001 From: boriskovar-m2ms Date: Tue, 23 Apr 2024 09:10:05 +0200 Subject: [PATCH] Implements #1348, small part of #1404 and last part of #1389 (#423) * #1403 fixed timer when services are not available * #1389 applied tag.hidden logic, reduced autohide time for tags toasts to 5 seconds * Squashed commit of the following: commit 7511b573482d4a1097286cfdc354b374ec5900e6 Author: Boris Kovar Date: Tue Apr 23 08:27:24 2024 +0200 - finished #1348 commit 6074d79ca46cdd141d166789af1e7268c0e7bf33 Author: Boris Kovar Date: Wed Apr 17 09:50:06 2024 +0200 - #1348 - fixed cases when all pdbs are missing commit 49f0ae8750ac9056dbc6d545a1a151e73f0d3b81 Author: Boris Kovar Date: Wed Apr 10 13:41:50 2024 +0200 - checkpoint commit 13a315ef93d0d5f411b3cb3091696a6bc166ce1d Author: Boris Kovar Date: Wed Apr 3 12:30:06 2024 +0200 - checkpoint commit a5b8cca53af12a5a2f5d20ca74f3c91d9104e4f2 Merge: 34b75f78 756a25be Author: Boris Kovar Date: Mon Mar 25 12:24:01 2024 +0100 Merge branch '#1348' of https://github.com/m2ms/fragalysis-frontend into #1348 commit 34b75f78782360ac20c5c6b5e0f650558ae0e401 Author: Boris Kovar Date: Tue Mar 12 12:35:21 2024 +0100 - latest backend commit 1308cb28c79ea746d2ac6847baa1ee489089d94d Author: Boris Kovar Date: Tue Feb 27 09:23:04 2024 +0100 - checkpoint commit 1ee15e78086164142fb79eb8102df2827b28a2c1 Author: Boris Kovar Date: Mon Feb 26 08:42:49 2024 +0100 - checkpoint commit a033b68c5f093743c8fd1deb6eb3e2d1e3aac314 Author: Boris Kovar Date: Tue Feb 27 09:23:04 2024 +0100 - checkpoint commit 7149081d50a30191434605dedde5b112539d0141 Author: Boris Kovar Date: Mon Feb 26 08:42:49 2024 +0100 - checkpoint commit 623de4fa1750e4d1acf013ae266b1b68fadd8449 Author: Boris Kovar Date: Tue Mar 12 09:48:51 2024 +0100 - using official backend version commit eec204c5771885f95b05a1beb036e483302b987e Author: Boris Kovar Date: Tue Feb 27 12:16:45 2024 +0100 - checkpoint commit dbc93a71846312f0c40c96b7fac207a3380b3c01 Author: Boris Kovar Date: Tue Feb 27 10:27:08 2024 +0100 - checkpoint commit b933243938573b4a2bb23b6d92a0e5eeaf396b10 Author: Boris Kovar Date: Tue Feb 27 09:23:04 2024 +0100 - checkpoint commit 4a0e17154d2e947d23668e851ef19c5eaf4d412a Author: Boris Kovar Date: Mon Feb 26 08:42:49 2024 +0100 - checkpoint commit 634ed03beb909e1e69c748ddb33a09ada83bd609 Author: Boris Kovar Date: Tue Feb 27 09:23:04 2024 +0100 - checkpoint commit 6e65faecf8a1cb880363d5374f9777403b2cf6c1 Author: Boris Kovar Date: Mon Feb 26 08:42:49 2024 +0100 - checkpoint commit 1bff7bf46ac041d3d480a9978c340868e98a7e08 Author: Boris Kovar Date: Tue Feb 27 09:23:04 2024 +0100 - checkpoint commit 07f21b61bd1204e14db02f424590decfeb527f51 Author: Boris Kovar Date: Mon Feb 26 08:42:49 2024 +0100 - checkpoint commit 021366ef147e36a14567b22a1d97628987d13c8e Author: Boris Kovar Date: Tue Feb 27 09:23:04 2024 +0100 - checkpoint commit 36f87b4daf9d385b558d4a0663abed13d5e3d13e Author: Boris Kovar Date: Mon Feb 26 08:42:49 2024 +0100 - checkpoint commit 87e765a7594fcada946ad65082dd854bc0092328 Author: Boris Kovar Date: Tue Mar 12 12:35:21 2024 +0100 - latest backend commit 72c94f05cbd60bb33f477de4aef471920f1c29bf Author: Boris Kovar Date: Tue Feb 27 09:23:04 2024 +0100 - checkpoint commit 224ca2345f734a8819d88125fcabc72aedffb8b2 Author: Boris Kovar Date: Mon Feb 26 08:42:49 2024 +0100 - checkpoint commit 36f03f843dce0b603a5f38a246f1cded8ebd9c71 Author: Boris Kovar Date: Tue Feb 27 09:23:04 2024 +0100 - checkpoint commit 807292042c5063582f61b642f32762cc013b2323 Author: Boris Kovar Date: Mon Feb 26 08:42:49 2024 +0100 - checkpoint commit e3190563cbd25a4860bb45317fcd18e149214942 Author: Boris Kovar Date: Tue Mar 12 09:48:51 2024 +0100 - using official backend version commit 187e7f39614be2a60857f843bfc8398bb94874f5 Author: Boris Kovar Date: Tue Feb 27 12:16:45 2024 +0100 - checkpoint commit b6aa0a4dbe30d1a1e57092cc2e253b078f49825b Author: Boris Kovar Date: Tue Feb 27 10:27:08 2024 +0100 - checkpoint commit fccf97682fa65b6f86226e85713f3bda283726b4 Author: Boris Kovar Date: Tue Feb 27 09:23:04 2024 +0100 - checkpoint commit 965be5ecc97b316a5605ccc3acfbf3646e04e524 Author: Boris Kovar Date: Mon Feb 26 08:42:49 2024 +0100 - checkpoint commit b01cdbf01d85855bfca6f60a3981888334f64d7b Author: Boris Kovar Date: Tue Feb 27 09:23:04 2024 +0100 - checkpoint commit e04fbf2a8b54cb3bad30889e6cd64144fdd74c9c Author: Boris Kovar Date: Mon Feb 26 08:42:49 2024 +0100 - checkpoint commit 5d64c26ca47113b78d1680c9381c389260d330f9 Author: Boris Kovar Date: Tue Feb 27 09:23:04 2024 +0100 - checkpoint commit dbb155c0ea79aa6295e6ed18498a4d0b121f0133 Author: Boris Kovar Date: Mon Feb 26 08:42:49 2024 +0100 - checkpoint commit b1c0f3c0c3547eb71d0b756da6b2f11d090df2ad Author: Boris Kovar Date: Thu Feb 29 10:32:27 2024 +0100 - checkpoint commit abc8cc993165970d1827898dbb4cc7795b23835d Author: Boris Kovar Date: Tue Feb 27 09:23:04 2024 +0100 - checkpoint commit 2ef004ad1324989890dc2460cb4d991a4d0e3a9d Author: Boris Kovar Date: Mon Feb 26 08:42:49 2024 +0100 - checkpoint commit 756a25be46950e2762e3c8c399583132a1d37d57 Merge: f686ef4a f474ff6c Author: Boris Kovar Date: Thu Mar 14 10:00:02 2024 +0100 Merge branch '#1348' of https://github.com/m2ms/fragalysis-frontend into #1348 commit f686ef4a96e57571ab53ce1901927676a85a7eb1 Author: Boris Kovar Date: Tue Mar 12 12:35:21 2024 +0100 - latest backend commit df6209c149d048ff8cc6f5faef40fb4657a51578 Author: Boris Kovar Date: Tue Feb 27 09:23:04 2024 +0100 - checkpoint commit f5a842f250d2706e1fdaba819876fef766b754a1 Author: Boris Kovar Date: Mon Feb 26 08:42:49 2024 +0100 - checkpoint commit 83ffcccc99d813815496d1b97443e23bd3e72ae3 Author: Boris Kovar Date: Tue Feb 27 09:23:04 2024 +0100 - checkpoint commit 0ecff35ab72e0f679211fd6266a86b9bda3814e0 Author: Boris Kovar Date: Mon Feb 26 08:42:49 2024 +0100 - checkpoint commit d3a90c7e6c5538b46f8c1ed0aa5fa48fd718e951 Author: Boris Kovar Date: Tue Mar 12 09:48:51 2024 +0100 - using official backend version commit 50800b9c05cc94fc783b63e918c419a8f1c95d7b Author: Boris Kovar Date: Tue Feb 27 12:16:45 2024 +0100 - checkpoint commit 2af18fdc661a84342af49b1eaab7e3e09a5f702b Author: Boris Kovar Date: Tue Feb 27 10:27:08 2024 +0100 - checkpoint commit cd75a275c858acfd77eea28c1833175a25ba1776 Author: Boris Kovar Date: Tue Feb 27 09:23:04 2024 +0100 - checkpoint commit c485389796dce1817d14d923e8d41e26875533eb Author: Boris Kovar Date: Mon Feb 26 08:42:49 2024 +0100 - checkpoint commit 96296e919e3b15d0bbc0ee66f63c0ee4f7564942 Author: Boris Kovar Date: Tue Feb 27 09:23:04 2024 +0100 - checkpoint commit 760152bdc448a9f91c22de292fd4e41b7aa0b626 Author: Boris Kovar Date: Mon Feb 26 08:42:49 2024 +0100 - checkpoint commit 8a30204864a5858c94bc0ee6341c9337c1deeff4 Author: Boris Kovar Date: Tue Feb 27 09:23:04 2024 +0100 - checkpoint commit 6235e9c320920bb57928af515c7c003eba06d80e Author: Boris Kovar Date: Mon Feb 26 08:42:49 2024 +0100 - checkpoint commit e2e46cb4c68a8c2a2a92a720de978a8935813815 Author: Boris Kovar Date: Thu Feb 29 10:32:27 2024 +0100 - checkpoint commit 8176514e81f7e67a1be034207d7d33ac96a41259 Author: Boris Kovar Date: Tue Feb 27 09:23:04 2024 +0100 - checkpoint commit 6aa51082e3832f0a678c270b5cd5d8958de88a96 Author: Boris Kovar Date: Mon Feb 26 08:42:49 2024 +0100 - checkpoint commit f474ff6c01b12c9b1775323bae5eab18b5717d95 Merge: 56c0b85c e728f49c Author: Boris Kovar Date: Thu Mar 14 08:30:00 2024 +0100 Merge branch '#1348' of https://github.com/m2ms/fragalysis-frontend into #1348 # Conflicts: # js/components/preview/tags/details/tagDetails.js commit 56c0b85cc08afe9f56bbf2f78297a3d1251dbc62 Author: Boris Kovar Date: Tue Feb 27 09:23:04 2024 +0100 - checkpoint commit a185933a1639d78238f6f2145f1eae2a0ac4d3c6 Author: Boris Kovar Date: Mon Feb 26 08:42:49 2024 +0100 - checkpoint commit 09c97b53e59d30576859a13d5e443fdd6e827e98 Author: Boris Kovar Date: Tue Feb 27 09:23:04 2024 +0100 - checkpoint commit c6d0738d3e376de9082192de4f6d6b91808bafac Author: Boris Kovar Date: Mon Feb 26 08:42:49 2024 +0100 - checkpoint commit 72f36b0de20159bb8bbbc2217b073f302c41315e Author: Boris Kovar Date: Thu Feb 29 10:32:27 2024 +0100 - checkpoint commit 971799dffdcfd51601943e981786fc19aa0d672c Author: Boris Kovar Date: Tue Feb 27 09:23:04 2024 +0100 - checkpoint commit 1bb53263961016ce3d7a2e3f977a5cbaf2e8e9fb Author: Boris Kovar Date: Mon Feb 26 08:42:49 2024 +0100 - checkpoint commit e728f49cb7e08238afb349039b7cf15d4290555f Author: Boris Kovar Date: Tue Mar 12 12:35:21 2024 +0100 - latest backend commit 125b8d48589d0180d261e781fc18f3b88787cc05 Author: Boris Kovar Date: Tue Feb 27 09:23:04 2024 +0100 - checkpoint commit 0e4155177fde3500404a15cd514bc774f3836b43 Author: Boris Kovar Date: Mon Feb 26 08:42:49 2024 +0100 - checkpoint commit 8cf43e054416ed1a54565604859a411530ba1837 Author: Boris Kovar Date: Tue Feb 27 09:23:04 2024 +0100 - checkpoint commit d336352f1856fa02722eb27f19511e29f26781c0 Author: Boris Kovar Date: Mon Feb 26 08:42:49 2024 +0100 - checkpoint commit 2fb59dcd5c2c14941fd8c74282473822af87b0fb Author: Boris Kovar Date: Tue Mar 12 09:48:51 2024 +0100 - using official backend version commit 9439f5d40bb696f2247f412901b65db8d1ea5ea6 Author: Boris Kovar Date: Thu Mar 7 13:59:03 2024 +0100 - partial fix for purple release for #1370 commit 4ff5f945954ea6533f9c3728c0565b20c79b2b0d Author: Boris Kovar Date: Thu Mar 7 10:10:41 2024 +0100 - implemented #1376 - also fixed bug in download structures dialog where only first download got added to the dropdown menu commit 66a98f3c617d0d110e73cf4df09048c572b3edee Author: Boris Kovar Date: Wed Mar 6 09:47:12 2024 +0100 - implemented #1361 - improvements for #1354 commit 8a193a551faa91e4441783429b980608c116665c Author: Boris Kovar Date: Tue Mar 5 13:24:11 2024 +0100 - cleanup for #1354 commit bb3bf3b6ceafdd40b0778157ff95d01ecceb6f8e Author: Boris Kovar Date: Tue Mar 5 13:21:32 2024 +0100 - updated message for #1354 commit a3dc8191aadd627f4de6f7425c9dfb72c34c1d23 Author: Boris Kovar Date: Tue Mar 5 13:05:12 2024 +0100 - first implementation of #1354 commit 4121519dad01feb107c1a4b2751caefb620f5471 Author: Boris Kovar Date: Tue Mar 5 08:17:49 2024 +0100 - implemented #1357 commit 4d96ff464b940f7aca3340819496e1d6fa03d1cf Author: Boris Kovar Date: Mon Mar 4 10:07:06 2024 +0100 - implemented changes requested in #1326 commit 03158bec02a2a6a8ded44bae99bfccd0f1df49ca Author: Boris Kovar Date: Mon Mar 4 08:45:22 2024 +0100 - fixed problem with tags not visually updating on observations commit 8765a3c69ef662a8c34ce73806bedfa306ab12f7 Author: matej Date: Mon Feb 26 21:36:12 2024 +0100 #1341 "pin" edit tag row outside of tag list commit 6db8b22ca6133eddeb7322cc0bd0ab52a5272fd6 Author: Boris Kovar Date: Thu Feb 29 10:32:27 2024 +0100 - checkpoint commit 027eaf0eacd1ea929eb00bfca4aef9e34ba1deab Author: Boris Kovar Date: Tue Feb 27 12:16:45 2024 +0100 - checkpoint commit 7407dbd02fe0cf50dcb069740475e914010e9016 Author: Boris Kovar Date: Tue Feb 27 10:27:08 2024 +0100 - checkpoint commit c13628b494bb5bfcd3b889b7a040568b683549a8 Author: Boris Kovar Date: Tue Feb 27 09:23:04 2024 +0100 - checkpoint commit e39721c2353fe40249ea7cac6d7d01bc58186fe2 Author: Boris Kovar Date: Mon Feb 26 08:42:49 2024 +0100 - checkpoint --------- Co-authored-by: matej --- js/components/datasets/datasetMoleculeList.js | 323 +++++++++++----- .../datasetMoleculeView.js | 73 +++- .../datasets/lockVisibleCompoundsDialog.js | 12 +- js/components/datasets/redux/actions.js | 11 +- js/components/datasets/redux/constants.js | 5 +- .../datasets/redux/dispatchActions.js | 362 +++++++++++++----- js/components/datasets/redux/reducer.js | 28 +- js/components/datasets/redux/selectors.js | 40 ++ .../datasets/selectedCompoundsList.js | 119 ++++-- .../preview/tags/details/tagDetails.js | 6 +- .../preview/tags/modal/editTagsModal.js | 6 +- js/components/preview/tags/tagCategory.js | 2 +- js/components/preview/tags/utils/tagUtils.js | 2 +- .../services/ServicesStatusWrapper.js | 4 +- js/reducers/tracking/dispatchActions.js | 2 +- 15 files changed, 747 insertions(+), 248 deletions(-) diff --git a/js/components/datasets/datasetMoleculeList.js b/js/components/datasets/datasetMoleculeList.js index e8f0144d2..99847c459 100644 --- a/js/components/datasets/datasetMoleculeList.js +++ b/js/components/datasets/datasetMoleculeList.js @@ -43,7 +43,10 @@ import { deleteDataset, getTrackingActions, moveDatasetMoleculeUpDown, - getAllVisibleButNotLockedCompounds + getAllVisibleButNotLockedCompounds, + getObservationForLHSReference, + getCurrentDatasetIterator, + resetDatasetIterator } from './redux/dispatchActions'; import { setAskLockCompoundsQuestion, @@ -57,11 +60,12 @@ import { appendCompoundColorOfDataset, appendColorToAllCompoundsOfDataset, removeCompoundColorOfDataset, - removeColorFromAllCompoundsOfDataset + removeColorFromAllCompoundsOfDataset, + setDatasetIterator } from './redux/actions'; import { DatasetFilter } from './datasetFilter'; import { FilterList, Link, DeleteForever, ArrowUpward, ArrowDownward, Edit } from '@material-ui/icons'; -import { getJoinedMoleculeLists } from './redux/selectors'; +import { getJoinedMoleculeLists, getLHSVisibleListsForRHS } from './redux/selectors'; import { InspirationDialog } from './inspirationDialog'; import { CrossReferenceDialog } from './crossReferenceDialog'; import { AlertModal } from '../common/Modal/AlertModal'; @@ -86,6 +90,14 @@ import { import { LockVisibleCompoundsDialog } from './lockVisibleCompoundsDialog'; import { size } from 'lodash'; import { Circle } from '@mui/icons-material'; +import { + addComplex, + addHitProtein, + addSurface, + removeComplex, + removeHitProtein, + removeSurface +} from '../preview/molecule/redux/dispatchActions'; const useStyles = makeStyles(theme => ({ container: { @@ -428,10 +440,12 @@ const DatasetMoleculeList = ({ title, datasetID, url }) => { ); const ligandList = useSelector(state => state.datasetsReducers.ligandLists[datasetID]); - // const proteinList = useSelector(state => state.datasetsReducers.proteinLists[datasetID]); - // const complexList = useSelector(state => state.datasetsReducers.complexLists[datasetID]); - // const surfaceList = useSelector(state => state.datasetsReducers.surfaceLists[datasetID]); + const proteinListDataset = useSelector(state => state.datasetsReducers.proteinLists[datasetID]); + const complexListDataset = useSelector(state => state.datasetsReducers.complexLists[datasetID]); + const surfaceListDataset = useSelector(state => state.datasetsReducers.surfaceLists[datasetID]); // #1249 dataset molecules currently could use side observation molecule for some renders + + // const { proteinList, complexList, surfaceList } = useSelector(state => getLHSVisibleListsForRHS(state, datasetID)); const proteinList = useSelector(state => state.selectionReducers.proteinList); const complexList = useSelector(state => state.selectionReducers.complexList); const surfaceList = useSelector(state => state.selectionReducers.surfaceList); @@ -473,9 +487,18 @@ const DatasetMoleculeList = ({ title, datasetID, url }) => { const compoundColors = useSelector(state => state.datasetsReducers.compoundColorByDataset[datasetID]) ?? {}; - const isSelectedTypeOn = typeList => { + const isSelectedTypeOn = (typeList, isLHSReference) => { if (typeList) { - return typeList.some(molId => allMolecules.some(mol => mol.id === molId)); + if (!isLHSReference) { + return typeList.some(molId => allMolecules.some(mol => mol.id === molId)); + } else { + const molsWithLHSReference = allMolecules.filter(mol => mol.site_observation_code); + return typeList.some(molId => + molsWithLHSReference.some( + mol => mol.site_observation_code === allMoleculesList.find(m => m.id === molId)?.code + ) + ); + } } return false; }; @@ -484,12 +507,12 @@ const DatasetMoleculeList = ({ title, datasetID, url }) => { return typeList && typeList.length > 0; }; - let isLigandOn = isSelectedTypeOn(ligandList); - let isProteinOn = isSelectedTypeOn(proteinList); - let isComplexOn = isSelectedTypeOn(complexList); + let isLigandOn = isSelectedTypeOn(ligandList, false); + let isProteinOn = isSelectedTypeOn(proteinList, true) || isSelectedTypeOn(proteinListDataset, false); + let isComplexOn = isSelectedTypeOn(complexList, true) || isSelectedTypeOn(complexListDataset, false); + let isSurfaceOn = isSelectedTypeOn(surfaceList, true) || isSelectedTypeOn(surfaceListDataset, false); - let areArrowsVisible = - isTypeOn(ligandList) || isTypeOn(proteinList) || isTypeOn(complexList) || isTypeOn(surfaceList); + let areArrowsVisible = isLigandOn || isProteinOn || isComplexOn || isSurfaceOn; const addType = { ligand: addDatasetLigand, @@ -505,6 +528,20 @@ const DatasetMoleculeList = ({ title, datasetID, url }) => { surface: removeDatasetSurface }; + const addLHSType = { + ligand: addDatasetLigand, + protein: addHitProtein, + complex: addComplex, + surface: addSurface + }; + + const removeLHSType = { + ligand: removeDatasetLigand, + protein: removeHitProtein, + complex: removeComplex, + surface: removeSurface + }; + // TODO: "currentMolecules" do not need to correspondent to selections in {type}List // TODO: so this could lead to inconsistend behaviour while scrolling // TODO: maybe change "currentMolecules.forEach" to "{type}List.forEach" @@ -516,12 +553,24 @@ const DatasetMoleculeList = ({ title, datasetID, url }) => { if ((type === 'protein' || type === 'complex') && !molecule.pdb_info) { continue; } - dispatch(removeType[type](stage, molecule, colourList[molecule.id % colourList.length], datasetID, skipTracking)); + if (type === 'ligand') { + dispatch( + removeType[type](stage, molecule, colourList[molecule.id % colourList.length], datasetID, skipTracking) + ); + } else { + if (molecule.site_observation_code) { + const lhsMol = allMoleculesList.find(mol => mol.code === molecule.site_observation_code); + if (lhsMol) { + dispatch(removeLHSType[type](stage, lhsMol, colourList[molecule.id % colourList.length], skipTracking)); + } + } else if (molecule.isCustomPdb) { + dispatch( + removeType[type](stage, molecule, colourList[molecule.id % colourList.length], datasetID, skipTracking) + ); + } + } } - // lockedMolecules.forEach(cid => { - // let molecule = getCompoundForId(cid); - // dispatch(removeType[type](stage, molecule, colourList[molecule.id % colourList.length], datasetID, skipTracking)); - // }); + selectedAll.current = false; }; @@ -536,20 +585,54 @@ const DatasetMoleculeList = ({ title, datasetID, url }) => { if ((type === 'protein' || type === 'complex') && !molecule.pdb_info) { continue; } - promises.push( - dispatch( - addType[type](stage, molecule, colourList[molecule.id % colourList.length], datasetID, skipTracking) - ) - ); + if (type === 'ligand') { + promises.push( + dispatch( + addType[type](stage, molecule, colourList[molecule.id % colourList.length], datasetID, skipTracking) + ) + ); + } else { + if (molecule.site_observation_code) { + const lhsMol = allMoleculesList.find(mol => mol.code === molecule.site_observation_code); + if (lhsMol) { + if (type === 'protein') { + promises.push( + dispatch( + addLHSType[type]( + stage, + lhsMol, + colourList[molecule.id % colourList.length], + true, + skipTracking, + undefined, + true + ) + ) + ); + } else if (type === 'complex') { + promises.push( + dispatch( + addLHSType[type]( + stage, + lhsMol, + colourList[molecule.id % colourList.length], + skipTracking, + undefined, + true + ) + ) + ); + } + } + } else if (molecule.isCustomPdb) { + promises.push( + dispatch( + addType[type](stage, molecule, colourList[molecule.id % colourList.length], datasetID, skipTracking) + ) + ); + } + } } - // lockedMolecules.forEach(cid => { - // let molecule = getCompoundForId(cid); - // promises.push( - // dispatch( - // addType[type](stage, molecule, colourList[molecule.id % colourList.length], datasetID, skipTracking) - // ) - // ); - // }); await Promise.all(promises); }) @@ -561,6 +644,7 @@ const DatasetMoleculeList = ({ title, datasetID, url }) => { }; const onButtonToggle = (type, calledFromSelectAll = false) => { + resetIterator(); if (calledFromSelectAll === true && selectedAll.current === true) { // REDO if (eval('is' + ucfirst(type) + 'On') === false) { @@ -656,7 +740,7 @@ const DatasetMoleculeList = ({ title, datasetID, url }) => { <> {/* fontSize does not change font here, but it disqualifies default font size so we do not need to !important */} - {isActiveFilter && } + {isActiveFilter && } @@ -708,6 +792,10 @@ const DatasetMoleculeList = ({ title, datasetID, url }) => { lockedMolecules.map(cid => ({ datasetID, molecule: getCompoundForId(cid) })) ); + const resetIterator = () => { + dispatch(resetDatasetIterator(datasetID)); + }; + // useEffectDebugger( // () => {}, // [setSortDialogAnchorEl, loadNextMolecules, addMoleculeViewRef, setSelectedMoleculeRef, moveMolecule], @@ -775,14 +863,36 @@ const DatasetMoleculeList = ({ title, datasetID, url }) => { // ); const getFirstItemForIterationStart = () => { - const firstItem = joinedMoleculeLists.find( - mol => - (ligandList.includes(mol.id) || - proteinList.includes(mol.id) || - complexList.includes(mol.id) || - surfaceList.includes(mol.id)) && - !lockedMolecules.includes(mol.id) - ); + let firstItem = dispatch(getCurrentDatasetIterator(datasetID)); + if (!firstItem) { + firstItem = joinedMoleculeLists.find(mol => { + if (!mol.isCustomPdb) { + const obs = dispatch(getObservationForLHSReference(mol)); + if (obs) { + return ( + (ligandList.includes(mol.id) || + proteinList.includes(obs.id) || + complexList.includes(obs.id) || + surfaceList.includes(obs.id)) && + !lockedMolecules.includes(mol.id) + ); + } else { + return false; + } + } else { + return ( + (ligandList.includes(mol.id) || + proteinListDataset.includes(mol.id) || + complexListDataset.includes(mol.id) || + surfaceListDataset.includes(mol.id)) && + !lockedMolecules.includes(mol.id) + ); + } + }); + // if (firstItem) { + // dispatch(setDatasetIterator(datasetID, firstItem)); + // } + } return firstItem; }; @@ -816,12 +926,28 @@ const DatasetMoleculeList = ({ title, datasetID, url }) => { const node = getNode(nextItem.id); setScrollToMoleculeId(nextItem.id); + let firstItemIdToUse = firstItem.id; + let isCustomPdb = true; + if (!firstItem.isCustomPdb) { + isCustomPdb = false; + const obs = dispatch(getObservationForLHSReference(firstItem)); + if (obs) { + firstItemIdToUse = obs.id; + } + } + let dataValue = { colourToggle: getRandomColor(firstItem), isLigandOn: ligandList.includes(firstItem.id), - isProteinOn: proteinList.includes(firstItem.id), - isComplexOn: complexList.includes(firstItem.id), - isSurfaceOn: surfaceList.includes(firstItem.id) + isProteinOn: isCustomPdb + ? proteinListDataset.includes(firstItemIdToUse) + : proteinList.includes(firstItemIdToUse), + isComplexOn: isCustomPdb + ? complexListDataset.includes(firstItemIdToUse) + : complexList.includes(firstItemIdToUse), + isSurfaceOn: isCustomPdb + ? surfaceListDataset.includes(firstItemIdToUse) + : surfaceList.includes(firstItemIdToUse) }; dispatch(setCrossReferenceCompoundName(moleculeTitleNext)); @@ -851,12 +977,28 @@ const DatasetMoleculeList = ({ title, datasetID, url }) => { const node = getNode(prevItem.id); setScrollToMoleculeId(prevItem.id); + let firstItemIdToUse = firstItem.id; + let isCustomPdb = true; + if (!firstItem.isCustomPdb) { + isCustomPdb = false; + const obs = dispatch(getObservationForLHSReference(firstItem)); + if (obs) { + firstItemIdToUse = obs.id; + } + } + let dataValue = { colourToggle: getRandomColor(firstItem), isLigandOn: ligandList.includes(firstItem.id), - isProteinOn: proteinList.includes(firstItem.id), - isComplexOn: complexList.includes(firstItem.id), - isSurfaceOn: surfaceList.includes(firstItem.id) + isProteinOn: isCustomPdb + ? proteinListDataset.includes(firstItemIdToUse) + : proteinList.includes(firstItemIdToUse), + isComplexOn: isCustomPdb + ? complexListDataset.includes(firstItemIdToUse) + : complexList.includes(firstItemIdToUse), + isSurfaceOn: isCustomPdb + ? surfaceListDataset.includes(firstItemIdToUse) + : surfaceList.includes(firstItemIdToUse) }; dispatch(setCrossReferenceCompoundName(moleculeTitlePrev)); @@ -917,7 +1059,7 @@ const DatasetMoleculeList = ({ title, datasetID, url }) => { }; return ( - + { setIsDeleteDatasetAlertOpen(false); }} /> - { - sortDialogOpen && ( - - ) - } - { - isOpenInspirationDialog && ( - - ) - } - { - askLockCompoundsQuestion && isLockVisibleCompoundsDialogOpenGlobal && ( - - ) - } - { - isOpenCrossReferenceDialog && ( - - ) - } + {sortDialogOpen && ( + + )} + {isOpenInspirationDialog && ( + + )} + {askLockCompoundsQuestion && isLockVisibleCompoundsDialogOpenGlobal && ( + + )} + {isOpenCrossReferenceDialog && ( + + )}
{/* TODO disable showing of filter tags for now */} {false && isActiveFilter && ( @@ -992,8 +1126,9 @@ const DatasetMoleculeList = ({ title, datasetID, url }) => { {filterSettings.priorityOrder.map(attr => ( @@ -1336,9 +1471,21 @@ const DatasetMoleculeList = ({ title, datasetID, url }) => { previousItemData={index > 0 && array[index - 1]} nextItemData={index < array?.length && array[index + 1]} L={ligandList?.includes(data.id)} - P={proteinList?.includes(idToFind)} - C={complexList?.includes(idToFind)} - S={surfaceList?.includes(idToFind)} + P={ + data.isCustomPdb + ? proteinListDataset?.includes(idToFind) + : proteinList?.includes(idToFind) + } + C={ + data.isCustomPdb + ? complexListDataset?.includes(idToFind) + : complexList?.includes(idToFind) + } + S={ + data.isCustomPdb + ? surfaceListDataset?.includes(idToFind) + : surfaceList?.includes(idToFind) + } V={false} moveMolecule={moveMolecule} isLocked={locked} @@ -1347,7 +1494,7 @@ const DatasetMoleculeList = ({ title, datasetID, url }) => { disableL={locked && groupDatasetsNglControlButtonsDisabledState.ligand} disableP={locked && groupDatasetsNglControlButtonsDisabledState.protein} disableC={locked && groupDatasetsNglControlButtonsDisabledState.complex} - dragDropEnabled + dragDropEnabled={false} getNode={getNode} /> ); @@ -1396,7 +1543,7 @@ const DatasetMoleculeList = ({ title, datasetID, url }) => { )} - + ); }; diff --git a/js/components/datasets/datasetMoleculeView/datasetMoleculeView.js b/js/components/datasets/datasetMoleculeView/datasetMoleculeView.js index 4182e0364..84cde57e6 100644 --- a/js/components/datasets/datasetMoleculeView/datasetMoleculeView.js +++ b/js/components/datasets/datasetMoleculeView/datasetMoleculeView.js @@ -32,14 +32,15 @@ import { moveDatasetMoleculeUpDown, getFirstUnlockedCompoundAfter, getFirstUnlockedCompoundBefore, - isDatasetCompoundIterrable, isDatasetCompoundLocked, getAllVisibleButNotLockedCompounds, getAllVisibleButNotLockedSelectedCompounds, isCompoundLocked, getFirstUnlockedSelectedCompoundAfter, moveSelectedDatasetMoleculeUpDown, - getFirstUnlockedSelectedCompoundBefore + getFirstUnlockedSelectedCompoundBefore, + resetSelectedCompoundIterator, + resetDatasetIterator } from '../redux/dispatchActions'; import { isAnyInspirationTurnedOn, getFilteredDatasetMoleculeList } from '../redux/selectors'; @@ -87,6 +88,7 @@ import RemoveShoppingCartIcon from '@mui/icons-material/RemoveShoppingCart'; import { compoundsColors } from '../../preview/compounds/redux/constants'; import { LockVisibleCompoundsDialog } from '../lockVisibleCompoundsDialog'; import { fabClasses } from '@mui/material'; +import useClipboard from 'react-use-clipboard'; const useStyles = makeStyles(theme => ({ container: { @@ -461,7 +463,7 @@ const DatasetMoleculeView = memo( // #1249 dataset molecules currently could use side observation molecule for some renders const allMolecules = useSelector(state => state.apiReducers.all_mol_lists); const [pdbData, setPdbData] = useState(null); - const isPdbAvailable = !!(data && (data.pdb_info || pdbData)); + const isPdbAvailable = !!(data && (data.pdb_info || data.site_observation_code)); useEffect(() => { if (data.site_observation_code) { @@ -470,7 +472,7 @@ const DatasetMoleculeView = memo( setPdbData(molecule); } } else { - setPdbData(data.pdb_info); + setPdbData(data); } }, [data, allMolecules]); @@ -504,6 +506,14 @@ const DatasetMoleculeView = memo( const current_style = isLigandOn || isProteinOn || isComplexOn || isSurfaceOn ? selected_style : not_selected_style; + const resetIterator = () => { + if (inSelectedCompoundsList) { + dispatch(resetSelectedCompoundIterator()); + } else { + dispatch(resetDatasetIterator(datasetID)); + } + }; + const addNewLigand = (skipTracking = false) => { dispatch( withDisabledDatasetMoleculeNglControlButton(datasetID, currentID, 'ligand', () => { @@ -522,6 +532,7 @@ const DatasetMoleculeView = memo( const [loadingAll, setLoadingAll] = useState(false); const [loadingLigand, setLoadingLigand] = useState(false); const onLigand = calledFromSelectAll => { + resetIterator(); setLoadingLigand(true); if (calledFromSelectAll === true && selectedAll.current === true) { if (isLigandOn === false) { @@ -544,22 +555,29 @@ const DatasetMoleculeView = memo( }; const removeSelectedProtein = (skipTracking = false) => { - // dispatch(removeDatasetHitProtein(stage, data, colourToggle, datasetID, skipTracking)); - dispatch(removeHitProtein(stage, pdbData, colourToggle, skipTracking)); + if (data.isCustomPdb) { + dispatch(removeDatasetHitProtein(stage, data, colourToggle, datasetID, skipTracking)); + } else { + dispatch(removeHitProtein(stage, pdbData, colourToggle, skipTracking)); + } selectedAll.current = false; }; const addNewProtein = (skipTracking = false) => { dispatch( withDisabledDatasetMoleculeNglControlButton(datasetID, currentID, 'protein', () => { - dispatch(addHitProtein(stage, pdbData, colourToggle, true, skipTracking, undefined, true)); - // dispatch(addDatasetHitProtein(stage, data, colourToggle, datasetID, skipTracking)); + if (data.isCustomPdb) { + dispatch(addDatasetHitProtein(stage, data, colourToggle, datasetID, skipTracking)); + } else { + dispatch(addHitProtein(stage, pdbData, colourToggle, true, skipTracking, undefined, true)); + } }) ); }; const [loadingProtein, setLoadingProtein] = useState(false); const onProtein = calledFromSelectAll => { + resetIterator(); setLoadingProtein(true); if (calledFromSelectAll === true && selectedAll.current === true) { if (isProteinOn === false) { @@ -578,22 +596,29 @@ const DatasetMoleculeView = memo( }; const removeSelectedComplex = (skipTracking = false) => { - // dispatch(removeDatasetComplex(stage, data, colourToggle, datasetID, skipTracking)); - dispatch(removeComplex(stage, pdbData, colourToggle, skipTracking)); + if (data.isCustomPdb) { + dispatch(removeDatasetComplex(stage, data, colourToggle, datasetID, skipTracking)); + } else { + dispatch(removeComplex(stage, pdbData, colourToggle, skipTracking)); + } selectedAll.current = false; }; const addNewComplex = (skipTracking = false) => { dispatch( withDisabledDatasetMoleculeNglControlButton(datasetID, currentID, 'complex', () => { - // dispatch(addDatasetComplex(stage, data, colourToggle, datasetID, skipTracking)); - dispatch(addComplex(stage, pdbData, colourToggle, skipTracking, undefined, true)); + if (data.isCustomPdb) { + dispatch(addDatasetComplex(stage, data, colourToggle, datasetID, skipTracking)); + } else { + dispatch(addComplex(stage, pdbData, colourToggle, skipTracking, undefined, true)); + } }) ); }; const [loadingComplex, setLoadingComplex] = useState(false); const onComplex = calledFromSelectAll => { + resetIterator(); setLoadingComplex(true); if (calledFromSelectAll === true && selectedAll.current === true) { if (isComplexOn === false) { @@ -612,22 +637,29 @@ const DatasetMoleculeView = memo( }; const removeSelectedSurface = () => { - // dispatch(removeDatasetSurface(stage, data, colourToggle, datasetID)); - dispatch(removeSurface(stage, pdbData, colourToggle)); + if (data.isCustomPdb) { + dispatch(removeDatasetSurface(stage, data, colourToggle, datasetID)); + } else { + dispatch(removeSurface(stage, pdbData, colourToggle)); + } selectedAll.current = false; }; const addNewSurface = async () => { dispatch( withDisabledDatasetMoleculeNglControlButton(datasetID, currentID, 'surface', () => { - dispatch(addSurface(stage, pdbData, colourToggle, false, undefined, true)); - // dispatch(addDatasetSurface(stage, data, colourToggle, datasetID)); + if (data.isCustomPdb) { + dispatch(addDatasetSurface(stage, data, colourToggle, datasetID)); + } else { + dispatch(addSurface(stage, pdbData, colourToggle, false, undefined, true)); + } }) ); }; const [loadingSurface, setLoadingSurface] = useState(false); const onSurface = calledFromSelectAll => { + resetIterator(); setLoadingSurface(true); if (calledFromSelectAll === true && selectedAll.current === true) { if (isSurfaceOn === false) { @@ -896,6 +928,7 @@ const DatasetMoleculeView = memo( }; const moleculeTitle = data && data.name; + const [isNameCopied, setNameCopied] = useClipboard(moleculeTitle, { successDuration: 5000 }); const datasetTitle = datasets?.find(item => `${item.id}` === `${datasetID}`)?.title; const allScores = { ...data?.numerical_scores, ...data?.text_scores }; @@ -974,7 +1007,13 @@ const DatasetMoleculeView = memo( > -
+
{ + e.preventDefault(); + setNameCopied(moleculeTitle); + }} + > {moleculeTitle}
diff --git a/js/components/datasets/lockVisibleCompoundsDialog.js b/js/components/datasets/lockVisibleCompoundsDialog.js index af986d62e..d13f50724 100644 --- a/js/components/datasets/lockVisibleCompoundsDialog.js +++ b/js/components/datasets/lockVisibleCompoundsDialog.js @@ -44,27 +44,27 @@ export const LockVisibleCompoundsDialog = forwardRef( if (currentCmp) { let cmpsToLock = dispatch(getAllVisibleButNotLockedCompounds(datasetId)); if (cmpsToLock && cmpsToLock.length > 0) { - dispatch(lockCompounds(datasetId, cmpsToLock, currentCmp.id)); + dispatch(lockCompounds(datasetId, cmpsToLock, currentCmp)); } } else { let cmpsToLock = dispatch(getAllVisibleButNotLockedCompounds(datasetId)); //we need to skip first element if we came here from global arrows if (cmpsToLock && cmpsToLock.length > 0) { - const firstCmpId = cmpsToLock[0]; - dispatch(lockCompounds(datasetId, cmpsToLock, firstCmpId)); + const firstCmp = cmpsToLock[0]; + dispatch(lockCompounds(datasetId, cmpsToLock, firstCmp)); } } } else { if (currentCmp) { let cmpsToLock = dispatch(getAllVisibleButNotLockedSelectedCompounds()); if (cmpsToLock && cmpsToLock.length > 0) { - dispatch(lockSelectedCompounds(cmpsToLock, currentCmp.id)); + dispatch(lockSelectedCompounds(cmpsToLock, { datasetID: currentCmp.computed_set, molecule: currentCmp })); } } else { let cmpsToLock = dispatch(getAllVisibleButNotLockedSelectedCompounds()); if (cmpsToLock && cmpsToLock.length > 0) { - const firstCmpId = cmpsToLock[0]; - dispatch(lockSelectedCompounds(cmpsToLock, firstCmpId)); + const firstCmp = cmpsToLock[0]; + dispatch(lockSelectedCompounds(cmpsToLock, firstCmp)); } } } diff --git a/js/components/datasets/redux/actions.js b/js/components/datasets/redux/actions.js index c172a9860..715bde06f 100644 --- a/js/components/datasets/redux/actions.js +++ b/js/components/datasets/redux/actions.js @@ -62,6 +62,16 @@ export const setFilterDialogOpen = filterDialogOpen => ({ payload: filterDialogOpen }); +export const setDatasetIterator = (datasetID, currentCmp) => ({ + type: constants.SET_DATASET_ITERATOR, + payload: { datasetID, currentCmp } +}); + +export const setSelectedCompoundsIterator = (datasetID, molecule) => ({ + type: constants.SET_SELECTED_COMPOUNDS_ITERATOR, + payload: { datasetID, molecule } +}); + export const setLigandList = function(datsetID, ligandList) { return { type: constants.SET_LIGAND_LIST, @@ -579,4 +589,3 @@ export const setUpdatedDatasets = updatedDataset => ({ type: constants.SET_UPDATED_DATASETS, payload: { updatedDataset } }); - diff --git a/js/components/datasets/redux/constants.js b/js/components/datasets/redux/constants.js index 99e1aab10..1fdfcbd64 100644 --- a/js/components/datasets/redux/constants.js +++ b/js/components/datasets/redux/constants.js @@ -115,7 +115,10 @@ export const constants = { SET_SELECT_ALL_BUTTON_FOR_DATASET: prefix + 'SET_SELECT_ALL_BUTTON_FOR_DATASET', SET_COMPOUND_SET: prefix + 'SET_COMPOUND_SET', - SET_UPDATED_DATASETS: prefix + 'SET_UPDATED_DATASETS' + SET_UPDATED_DATASETS: prefix + 'SET_UPDATED_DATASETS', + + SET_DATASET_ITERATOR: prefix + 'SET_DATASET_ITERATOR', + SET_SELECTED_COMPOUNDS_ITERATOR: prefix + 'SET_SELECTED_COMPOUNDS_ITERATOR' }; export const COUNT_OF_VISIBLE_SCORES = 7; diff --git a/js/components/datasets/redux/dispatchActions.js b/js/components/datasets/redux/dispatchActions.js index fa9135242..6e6aaf515 100644 --- a/js/components/datasets/redux/dispatchActions.js +++ b/js/components/datasets/redux/dispatchActions.js @@ -35,7 +35,9 @@ import { enableDatasetMoleculeNglControlButton, setArrowUpDown, removeDataset, - appendCompoundToSelectedCompoundsByDataset + appendCompoundToSelectedCompoundsByDataset, + setDatasetIterator, + setSelectedCompoundsIterator } from './actions'; import { base_url } from '../../routes/constants'; import { @@ -66,7 +68,10 @@ import { addLigand, addDensity, addDensityCustomView, - hideAllSelectedMolecules + hideAllSelectedMolecules, + removeHitProtein, + removeComplex, + removeSurface } from '../../preview/molecule/redux/dispatchActions'; import { OBJECT_TYPE } from '../../nglView/constants'; import { getRepresentationsByType } from '../../nglView/generatingObjects'; @@ -299,10 +304,18 @@ export const loadDatasetCompoundsWithScores = (datasetsToLoad = null) => (dispat // -----> add 'site_observation_code' to molecules whereas '/compound-molecules' has more molecule info so far, can be removed later const compondMolecules = await api({ url: `${base_url}/api/compound-molecules/?compound_set=${dataset.id}` }); const compondMoleculesMap = {}; - compondMolecules.data.results.forEach(molecule => compondMoleculesMap[molecule.name] = molecule.site_observation_code); + compondMolecules.data.results.forEach( + molecule => + (compondMoleculesMap[molecule.name] = { + site_observation_code: molecule.site_observation_code, + pdb_info: molecule.pdb_info + }) + ); response.data.results.forEach(molecule => { if (compondMoleculesMap.hasOwnProperty(molecule.name)) { - molecule['site_observation_code'] = compondMoleculesMap[molecule.name]; + molecule['site_observation_code'] = compondMoleculesMap[molecule.name].site_observation_code; + molecule['pdb_info'] = compondMoleculesMap[molecule.name].pdb_info; + molecule['isCustomPdb'] = !!!compondMoleculesMap[molecule.name].site_observation_code; } }); // <----- @@ -578,42 +591,112 @@ export const autoHideDatasetDialogsOnScroll = ({ inspirationDialogRef, crossRefe } }; +export const getObservationForLHSReference = rhsCompound => (dispatch, getState) => { + let result = null; + + if (!rhsCompound?.isCustomPdb && rhsCompound.site_observation_code) { + const state = getState(); + const allLHSMols = state.apiReducers.all_mol_lists; + result = allLHSMols.find(mol => mol.code === rhsCompound.site_observation_code); + } + + return result; +}; + +export const getRHSCmpReferencingLHSObservation = (obsId, obsReferenceToSkip = null) => (dispatch, getState) => { + let result = { obs: null, cmp: null }; + + const state = getState(); + const lhsObservations = state.apiReducers.all_mol_lists; + const obs = lhsObservations.find(mol => mol.id === obsId); + + if (obs?.code !== obsReferenceToSkip) { + const currentMolecules = state.datasetsReducers.moleculeLists; + const datasetIds = Object.keys(currentMolecules); + for (let i = 0; i < datasetIds.length; i++) { + const datasetID = datasetIds[i]; + const molecules = currentMolecules[datasetID]; + const found = molecules.find(mol => mol.site_observation_code === obs.code); + if (found) { + result = { obs: obs, cmp: found }; + break; + } + } + } + + return result; +}; + export const clearCompoundView = (cmp, datasetID, stage, skipTracking) => (dispatch, getState) => { const state = getState(); - const ligandList = state.datasetsReducers.ligandLists[datasetID]; - const proteinList = state.datasetsReducers.proteinLists[datasetID]; - const complexList = state.datasetsReducers.complexLists[datasetID]; - const surfaceList = state.datasetsReducers.surfaceLists[datasetID]; + let dataToUse = null; + + let ligandList = state.datasetsReducers.ligandLists[datasetID]; + let proteinList = []; + let complexList = []; + let surfaceList = []; + + if (cmp.isCustomPdb) { + dataToUse = cmp; + + proteinList = state.datasetsReducers.proteinLists[datasetID]; + complexList = state.datasetsReducers.complexLists[datasetID]; + surfaceList = state.datasetsReducers.surfaceLists[datasetID]; + } else { + dataToUse = dispatch(getObservationForLHSReference(cmp)); + + proteinList = state.selectionReducers.proteinList; + complexList = state.selectionReducers.complexList; + surfaceList = state.selectionReducers.surfaceList; + } - if (ligandList?.includes(cmp.id)) { + if (ligandList?.includes(dataToUse.id)) { dispatch(removeDatasetLigand(stage, cmp, getRandomColor(cmp), datasetID, skipTracking)); } - if (proteinList?.includes(cmp.id)) { - dispatch(removeDatasetHitProtein(stage, cmp, getRandomColor(cmp), datasetID, skipTracking)); + if (proteinList?.includes(dataToUse.id)) { + if (dataToUse.isCustomPdb) { + dispatch(removeDatasetHitProtein(stage, cmp, getRandomColor(cmp), datasetID, skipTracking)); + } else { + dispatch(removeHitProtein(stage, dataToUse, getRandomColor(cmp), skipTracking)); + } } - if (complexList?.includes(cmp.id)) { - dispatch(removeDatasetComplex(stage, cmp, getRandomColor(cmp), datasetID, skipTracking)); + if (complexList?.includes(dataToUse.id)) { + if (dataToUse.isCustomPdb) { + dispatch(removeDatasetComplex(stage, cmp, getRandomColor(cmp), datasetID, skipTracking)); + } else { + dispatch(removeComplex(stage, dataToUse, getRandomColor(cmp), skipTracking)); + } } - if (surfaceList?.includes(cmp.id)) { - dispatch(removeDatasetSurface(stage, cmp, getRandomColor(cmp), datasetID, skipTracking)); + if (surfaceList?.includes(dataToUse.id)) { + if (dataToUse.isCustomPdb) { + dispatch(removeDatasetSurface(stage, cmp, getRandomColor(cmp), datasetID, skipTracking)); + } else { + dispatch(removeSurface(stage, dataToUse, getRandomColor(cmp))); + } } }; -export const removeSelectedDatasetMolecules = (stage, skipTracking, skipMolecules = {}) => (dispatch, getState) => { +export const removeSelectedDatasetMolecules = (stage, skipTracking, currentCmp = null, skipMolecules = {}) => ( + dispatch, + getState +) => { const state = getState(); const datasets = state.datasetsReducers.datasets; const currentMolecules = state.datasetsReducers.moleculeLists; if (datasets) { + let proteinList = []; + let complexList = []; + let surfaceList = []; datasets.forEach(dataset => { const datasetID = dataset.id; const ligandList = state.datasetsReducers.ligandLists[datasetID]; - const proteinList = state.datasetsReducers.proteinLists[datasetID]; - const complexList = state.datasetsReducers.complexLists[datasetID]; - const surfaceList = state.datasetsReducers.surfaceLists[datasetID]; + proteinList = state.datasetsReducers.proteinLists[datasetID]; + complexList = state.datasetsReducers.complexLists[datasetID]; + surfaceList = state.datasetsReducers.surfaceLists[datasetID]; const molecules = currentMolecules[datasetID].filter(molecule => { return !skipMolecules[datasetID]?.includes(molecule.id); @@ -652,6 +735,33 @@ export const removeSelectedDatasetMolecules = (stage, skipTracking, skipMolecule } }); }); + + proteinList = state.selectionReducers.proteinList; + complexList = state.selectionReducers.complexList; + surfaceList = state.selectionReducers.surfaceList; + + const obsReferenceToSkip = currentCmp ? currentCmp.site_observation_code : ''; + + proteinList.forEach(obsId => { + const { obs, cmp } = dispatch(getRHSCmpReferencingLHSObservation(obsId, obsReferenceToSkip)); + if (obs) { + dispatch(removeHitProtein(stage, obs, getRandomColor(cmp), skipTracking)); + } + }); + + complexList.forEach(obsId => { + const { obs, cmp } = dispatch(getRHSCmpReferencingLHSObservation(obsId, obsReferenceToSkip)); + if (obs) { + dispatch(removeComplex(stage, obs, getRandomColor(cmp), skipTracking)); + } + }); + + surfaceList.forEach(obsId => { + const { obs, cmp } = dispatch(getRHSCmpReferencingLHSObservation(obsId, obsReferenceToSkip)); + if (obs) { + dispatch(removeSurface(stage, obs, getRandomColor(cmp))); + } + }); } }; @@ -666,11 +776,6 @@ const flattenInspirationsList = (inspirations, skipMolecules) => { } }); }); - // skipMolecules.forEach(molecule => { - // if (!inspirationsToSkip.hasOwnProperty(molecule.id)) { - // inspirationsToSkip[molecule.id] = molecule; - // } - // }); Object.keys(inspirations).forEach(molId => { const molecules = inspirations[molId]; @@ -744,10 +849,16 @@ const moveSelectedDatasetMoleculeInspirationsSettings = (data, newItemData, stag ); }; -export const lockSelectedCompounds = (selectedCompounds, skipCmpId = 0) => (dispatch, getState) => { +export const lockSelectedCompounds = (selectedCompounds, skipCmp = null) => (dispatch, getState) => { let filteredCompounds = [...selectedCompounds]; - if (skipCmpId) { - filteredCompounds = selectedCompounds.filter(item => item.molecule.id !== skipCmpId); + if (skipCmp) { + filteredCompounds = selectedCompounds.filter(item => { + let result = true; + if (item.molecule.id === skipCmp.molecule.id && item.datasetID === skipCmp.datasetID) { + result = false; + } + return result; + }); } filteredCompounds?.forEach(item => { @@ -759,22 +870,22 @@ export const lockSelectedCompounds = (selectedCompounds, skipCmpId = 0) => (disp }); }; -export const lockCompounds = (datasetID, compoundIds, skipCmpId = 0) => (dispatch, getState) => { +export const lockCompounds = (datasetID, compoundsToLock, skipCmp = null) => (dispatch, getState) => { const state = getState(); const compounds = state.datasetsReducers.moleculeLists[datasetID]; - let filteredCompounds = [...compoundIds]; - if (skipCmpId) { - filteredCompounds = compoundIds.filter(item => item !== skipCmpId); + let filteredCompounds = [...compoundsToLock]; + if (skipCmp) { + filteredCompounds = compoundsToLock.filter(item => item.id !== skipCmp.id); } - filteredCompounds?.forEach(compoundID => { - const filteredCIds = compounds.filter(cmp => cmp.id === compoundID); + filteredCompounds?.forEach(compound => { + const filteredCmps = compounds.filter(cmp => cmp.id === compound.id); let molName = ''; - if (filteredCIds && filteredCIds.length > 0) { - molName = filteredCIds[0].name; + if (filteredCmps && filteredCmps.length > 0) { + molName = filteredCmps[0].name; } - dispatch(appendCompoundToSelectedCompoundsByDataset(datasetID, compoundID, molName)); + dispatch(appendCompoundToSelectedCompoundsByDataset(datasetID, compound.id, molName)); }); }; @@ -809,11 +920,7 @@ export const getAllVisibleButNotLockedSelectedCompounds = (skipDatasetID = '', s if (datasetID !== skipDatasetID || skipCmpId !== molecule.id) { const isLocked = dispatch(isCompoundLocked(datasetID, molecule)); if (!isLocked) { - let isVisible = dispatch(isCompoundVisible(datasetID, molecule.id)); - // isVisible |= state.datasetsReducers.ligandLists[datasetID].includes(molecule.id); - // isVisible |= state.datasetsReducers.proteinLists[datasetID].includes(molecule.id); - // isVisible |= state.datasetsReducers.complexLists[datasetID].includes(molecule.id); - // isVisible |= state.datasetsReducers.surfaceLists[datasetID].includes(molecule.id); + let isVisible = dispatch(isCompoundVisible(item)); if (isVisible) { result.push(item); @@ -825,15 +932,27 @@ export const getAllVisibleButNotLockedSelectedCompounds = (skipDatasetID = '', s return result; }; -export const isCompoundVisible = (datasetID, compoundId) => (dispatch, getState) => { +export const isCompoundVisible = cmp => (dispatch, getState) => { let isVisible = false; const state = getState(); + const datasetID = cmp.datasetID; + const compoundId = cmp.molecule.id; + const isCustomPdb = cmp.molecule.isCustomPdb; + + let itemIdToUse = isCustomPdb ? cmp.molecule.id : dispatch(getObservationForLHSReference(cmp.molecule))?.id; + isVisible |= state.datasetsReducers.ligandLists[datasetID]?.includes(compoundId); - isVisible |= state.datasetsReducers.proteinLists[datasetID]?.includes(compoundId); - isVisible |= state.datasetsReducers.complexLists[datasetID]?.includes(compoundId); - isVisible |= state.datasetsReducers.surfaceLists[datasetID]?.includes(compoundId); + isVisible |= isCustomPdb + ? state.datasetsReducers.proteinLists[datasetID]?.includes(itemIdToUse) + : state.selectionReducers.proteinList.includes(itemIdToUse); + isVisible |= isCustomPdb + ? state.datasetsReducers.complexLists[datasetID]?.includes(itemIdToUse) + : state.selectionReducers.complexList.includes(itemIdToUse); + isVisible |= isCustomPdb + ? state.datasetsReducers.surfaceLists[datasetID]?.includes(itemIdToUse) + : state.selectionReducers.surfaceList.includes(itemIdToUse); return isVisible; }; @@ -842,36 +961,31 @@ export const getAllVisibleButNotLockedCompounds = (datasetID, skipCmpId = 0) => let result = []; const state = getState(); - const lockedCmps = state.datasetsReducers.selectedCompoundsByDataset[datasetID] || []; - - result = mergeCompoundIdsList(result, state.datasetsReducers.ligandLists[datasetID]); - result = mergeCompoundIdsList(result, state.datasetsReducers.proteinLists[datasetID]); - result = mergeCompoundIdsList(result, state.datasetsReducers.complexLists[datasetID]); - result = mergeCompoundIdsList(result, state.datasetsReducers.surfaceLists[datasetID]); - - result = result.filter(item => !lockedCmps.includes(item)); - if (skipCmpId) { - result = result.filter(item => item !== skipCmpId); - } + // const lockedCmps = state.datasetsReducers.selectedCompoundsByDataset[datasetID] || []; + const datasetCmps = state.datasetsReducers.moleculeLists[datasetID]; - return result; -}; - -export const isDatasetCompoundIterrable = (datasetID, compoundID) => (dispatch, getState) => { - let result = false; + datasetCmps.forEach(cmp => { + if (skipCmpId !== cmp.id) { + const isLocked = dispatch(isCompoundLocked(datasetID, cmp)); + if (!isLocked) { + let isVisible = dispatch(isCompoundVisible({ datasetID, molecule: cmp })); - if (dispatch(isDatasetCompoundLocked(datasetID, compoundID))) { - const state = getState(); + if (isVisible) { + result.push(cmp); + } + } + } + }); - const L = state.datasetsReducers.ligandLists[datasetID].includes(compoundID); - const P = state.datasetsReducers.proteinLists[datasetID].includes(compoundID); - const C = state.datasetsReducers.complexLists[datasetID].includes(compoundID); - const S = state.datasetsReducers.surfaceLists[datasetID].includes(compoundID); + // result = mergeCompoundIdsList(result, state.datasetsReducers.ligandLists[datasetID]); + // result = mergeCompoundIdsList(result, state.datasetsReducers.proteinLists[datasetID]); + // result = mergeCompoundIdsList(result, state.datasetsReducers.complexLists[datasetID]); + // result = mergeCompoundIdsList(result, state.datasetsReducers.surfaceLists[datasetID]); - result = !(L || P || C || S); - } else { - result = true; - } + // result = result.filter(item => !lockedCmps.includes(item)); + // if (skipCmpId) { + // result = result.filter(item => item !== skipCmpId); + // } return result; }; @@ -1002,8 +1116,10 @@ export const moveSelectedDatasetMoleculeUpDown = ( dispatch(moveSelectedDatasetMoleculeInspirationsSettings(item, newItem, stage, true)) ]); - dispatch(removeSelectedDatasetMolecules(stage, true, { ...lockedCompounds })); + dispatch(removeSelectedDatasetMolecules(stage, true, newItem, { ...lockedCompounds })); dispatch(removeSelectedTypesOfDatasetInspirations([newItem], stage, true, datasetID)); + + dispatch(setSelectedCompoundsIterator(newItemDatasetID, newItem)); }; /** @@ -1028,13 +1144,18 @@ export const moveDatasetMoleculeUpDown = (stage, datasetID, item, newItemDataset const inspirations = getInspirationsForMol(allInspirations, datasetID, newItem.id); dispatch(setInspirationMoleculeDataList(inspirations)); dispatch(clearCompoundView(newItem, datasetID, stage, true)); + console.log('moveDatasetMoleculeUpDown - compounds cleared'); await Promise.all([ dispatch(moveSelectedMoleculeSettings(stage, item, newItem, newItemDatasetID, datasetID, dataValue, true)), dispatch(moveSelectedDatasetMoleculeInspirationsSettings(item, newItem, stage, true)) ]); - dispatch(removeSelectedDatasetMolecules(stage, true, { [newItemDatasetID]: [newItem.id, ...lockedCompounds] })); + dispatch( + removeSelectedDatasetMolecules(stage, true, newItem, { [newItemDatasetID]: [newItem.id, ...lockedCompounds] }) + ); dispatch(removeSelectedTypesOfDatasetInspirations([newItem], stage, true, datasetID)); + + dispatch(setDatasetIterator(newItemDatasetID, newItem)); }; export const getInspirationsForMol = (allInspirations, datasetId, molId) => { @@ -1319,6 +1440,10 @@ export const moveSelectedMoleculeSettings = ( ) => (dispatch, getState) => { const promises = []; if (newItem && data) { + let customPdbData = null; + if (!newItem.isCustomPdb) { + customPdbData = dispatch(getObservationForLHSReference(newItem)); + } if (data.isLigandOn) { let representations = getRepresentationsByType(data.objectsInView, newItem, OBJECT_TYPE.LIGAND, datasetID); promises.push( @@ -1329,27 +1454,59 @@ export const moveSelectedMoleculeSettings = ( } if (data.isProteinOn) { let representations = getRepresentationsByType(data.objectsInView, newItem, OBJECT_TYPE.PROTEIN, datasetID); - promises.push( - dispatch( - addDatasetHitProtein(stage, newItem, getRandomColor(newItem), datasetIdOfMolecule, skipTracking, representations) - ) - ); + if (newItem.isCustomPdb) { + promises.push( + dispatch( + addDatasetHitProtein( + stage, + newItem, + getRandomColor(newItem), + datasetIdOfMolecule, + skipTracking, + representations + ) + ) + ); + } else { + promises.push( + dispatch( + addHitProtein(stage, customPdbData, getRandomColor(newItem), true, skipTracking, representations, true) + ) + ); + } } if (data.isComplexOn) { let representations = getRepresentationsByType(data.objectsInView, newItem, OBJECT_TYPE.COMPLEX, datasetID); - promises.push( - dispatch( - addDatasetComplex(stage, newItem, getRandomColor(newItem), datasetIdOfMolecule, skipTracking, representations) - ) - ); + if (newItem.isCustomPdb) { + promises.push( + dispatch( + addDatasetComplex( + stage, + newItem, + getRandomColor(newItem), + datasetIdOfMolecule, + skipTracking, + representations + ) + ) + ); + } else { + promises.push( + dispatch(addComplex(stage, customPdbData, getRandomColor(newItem), skipTracking, representations, true)) + ); + } } if (data.isSurfaceOn) { let representations = getRepresentationsByType(data.objectsInView, newItem, OBJECT_TYPE.SURFACE, datasetID); - promises.push( - dispatch( - addDatasetSurface(stage, newItem, getRandomColor(newItem), datasetIdOfMolecule, skipTracking, representations) - ) - ); + if (newItem.isCustomPdb) { + promises.push( + dispatch(addDatasetSurface(stage, newItem, getRandomColor(newItem), datasetIdOfMolecule, representations)) + ); + } else { + promises.push( + dispatch(addSurface(stage, customPdbData, getRandomColor(newItem), false, representations, true)) + ); + } } } return Promise.all(promises); @@ -1478,3 +1635,32 @@ export const deleteDataset = (datasetID, stage) => async (dispatch, getState) => dispatch(removeDataset(datasetID)); console.log('dataset removed from redux store'); }; + +export const getCurrentDatasetIterator = datasetID => (dispatch, getState) => { + let result = null; + + const state = getState(); + const datasetIterators = state.datasetsReducers.iteratorDatasets; + if (datasetIterators.hasOwnProperty(datasetID)) { + result = datasetIterators[datasetID]; + } + + return result; +}; + +export const getCurrentSelectedCompoundIterator = () => (dispatch, getState) => { + let result = null; + + const state = getState(); + result = state.datasetsReducers.iteratorSelectedCompounds; + + return result; +}; + +export const resetDatasetIterator = datasetID => (dispatch, getState) => { + dispatch(setDatasetIterator(datasetID, null)); +}; + +export const resetSelectedCompoundIterator = () => (dispatch, getState) => { + dispatch(setSelectedCompoundsIterator(null, null)); +}; diff --git a/js/components/datasets/redux/reducer.js b/js/components/datasets/redux/reducer.js index 17d8b52ea..af94f6198 100644 --- a/js/components/datasets/redux/reducer.js +++ b/js/components/datasets/redux/reducer.js @@ -79,7 +79,11 @@ export const INITIAL_STATE = { cmpForLocalLockVisibleCompoundsDialog: null, askLockCompoundsQuestion: true, editedColorGroup: null, - askLockSelectedCompoundsQuestion: true + askLockSelectedCompoundsQuestion: true, + + //iterator functionality for dataset tabs and also selected compounds tab + iteratorDatasets: {}, + iteratorSelectedCompounds: null }; /** @@ -283,6 +287,28 @@ export const datasetsReducers = (state = INITIAL_STATE, action = {}) => { case constants.REMOVE_FROM_INSPIRATION_LIST: return removeFromList(state, 'inspirationLists', action.payload.datasetID, action.payload.itemID); + case constants.SET_DATASET_ITERATOR: { + if (action.payload.currentCmp) { + return { + ...state, + iteratorDatasets: { ...state.iteratorDatasets, [action.payload.datasetID]: { ...action.payload.currentCmp } } + }; + } else { + return { + ...state, + iteratorDatasets: { ...state.iteratorDatasets, [action.payload.datasetID]: null } + }; + } + } + + case constants.SET_SELECTED_COMPOUNDS_ITERATOR: { + if (action.payload) { + return { ...state, iteratorSelectedCompounds: { ...action.payload } }; + } else { + return { ...state, iteratorSelectedCompounds: null }; + } + } + case constants.APPEND_TO_SCORE_DATASET_MAP: return Object.assign({}, state, { scoreDatasetMap: { diff --git a/js/components/datasets/redux/selectors.js b/js/components/datasets/redux/selectors.js index 4c33776eb..323839bf0 100644 --- a/js/components/datasets/redux/selectors.js +++ b/js/components/datasets/redux/selectors.js @@ -478,3 +478,43 @@ export const getJoinedMoleculeLists = (datasetID, state) => { return moleculeList; }; + +export const getLHSVisibleListsForRHS = createSelector( + (_, datasetID) => datasetID, + moleculeLists, + proteinList, + complexList, + surfaceList, + (datasetID, molecules, proteins, complexes, surfaces) => { + const result = { proteinList: [], complexList: [], surfaceList: [] }; + + const rhsCompoundsWithLHSReference = {}; + const moleculesOfDataset = molecules[datasetID] || []; + + moleculesOfDataset.forEach(molecule => { + if (molecule.site_observation_code) { + rhsCompoundsWithLHSReference[molecule.id] = molecule; + } + }); + + proteins.forEach(id => { + if (rhsCompoundsWithLHSReference[id]) { + result.proteinList.push(rhsCompoundsWithLHSReference[id].id); + } + }); + + complexes.forEach(id => { + if (rhsCompoundsWithLHSReference[id]) { + result.complexList.push(rhsCompoundsWithLHSReference[id].id); + } + }); + + surfaces.forEach(id => { + if (rhsCompoundsWithLHSReference[id]) { + result.surfaceList.push(rhsCompoundsWithLHSReference[id].id); + } + }); + + return result; + } +); diff --git a/js/components/datasets/selectedCompoundsList.js b/js/components/datasets/selectedCompoundsList.js index c14cc225c..77cacdfdd 100644 --- a/js/components/datasets/selectedCompoundsList.js +++ b/js/components/datasets/selectedCompoundsList.js @@ -33,7 +33,9 @@ import { CrossReferenceDialog } from './crossReferenceDialog'; import { autoHideDatasetDialogsOnScroll, getAllVisibleButNotLockedSelectedCompounds, + getCurrentSelectedCompoundIterator, getInspirationsForMol, + getObservationForLHSReference, isCompoundLocked, isCompoundVisible, moveDatasetMoleculeUpDown, @@ -192,15 +194,22 @@ export const SelectedCompoundList = memo(() => { const canLoadMore = listItemOffset < moleculesObjectIDListOfCompoundsToBuy.length; const ligandList = useSelector(state => getListOfSelectedLigandOfAllDatasets(state)); - const proteinList = useSelector(state => getListOfSelectedProteinOfAllDatasets(state)); - const complexList = useSelector(state => getListOfSelectedComplexOfAllDatasets(state)); - const surfaceList = useSelector(state => getListOfSelectedSurfaceOfAllDatasets(state)); + const proteinList = useSelector(state => state.selectionReducers.proteinList); + const complexList = useSelector(state => state.selectionReducers.complexList); + const surfaceList = useSelector(state => state.selectionReducers.surfaceList); + + const proteinListDataset = useSelector(state => getListOfSelectedProteinOfAllDatasets(state)); + const complexListDataset = useSelector(state => getListOfSelectedComplexOfAllDatasets(state)); + const surfaceListDataset = useSelector(state => getListOfSelectedSurfaceOfAllDatasets(state)); const showedCompoundList = useSelector(state => state.previewReducers.compounds.showedCompoundList); const filteredScoreProperties = useSelector(state => state.datasetsReducers.filteredScoreProperties); const moleculeLists = useSelector(state => state.datasetsReducers.moleculeLists); + const allMoleculesList = useSelector(state => state.apiReducers.all_mol_lists); + const compoundsToBuyList = useSelector(state => state.datasetsReducers.compoundsToBuyDatasetMap); + let selectedMolecules = []; Object.keys(compoundsToBuyList).forEach(datasetId => { const datasetCmpsToBuy = compoundsToBuyList[datasetId] || []; @@ -266,9 +275,7 @@ export const SelectedCompoundList = memo(() => { if (moleculesObjectIDListOfCompoundsToBuy) { for (let i = 0; i < moleculesObjectIDListOfCompoundsToBuy.length; i++) { const cmp = moleculesObjectIDListOfCompoundsToBuy[i]; - const dataset = cmp.datasetID; - const molecule = cmp.molecule; - const isVisible = dispatch(isCompoundVisible(dataset, molecule.id)); + const isVisible = dispatch(isCompoundVisible(cmp)); if (isVisible) { result = true; break; @@ -276,19 +283,17 @@ export const SelectedCompoundList = memo(() => { } } return result; - }, [dispatch, moleculesObjectIDListOfCompoundsToBuy]); - // if (!moleculesObjectIDListOfCompoundsToBuy) { - // for (let i = 0; i < moleculesObjectIDListOfCompoundsToBuy.length; i++) { - // const cmp = moleculesObjectIDListOfCompoundsToBuy[i]; - // const dataset = cmp.datasetID; - // const molecule = cmp.molecule; - // const isVisible = dispatch(isCompoundVisible(dataset, molecule.id)); - // if (isVisible) { - // areArrowsVisible = true; - // break; - // } - // } - // } + }, [ + dispatch, + moleculesObjectIDListOfCompoundsToBuy, + ligandList, + proteinList, + complexList, + surfaceList, + proteinListDataset, + complexListDataset, + surfaceListDataset + ]); useEffect(() => { return () => { @@ -601,13 +606,18 @@ export const SelectedCompoundList = memo(() => { const getFirstItemForIterationStart = () => { let result = null; - for (let i = 0; i < moleculesObjectIDListOfCompoundsToBuy.length; i++) { - const cmp = moleculesObjectIDListOfCompoundsToBuy[i]; - if (!dispatch(isCompoundLocked(cmp.datasetID, cmp.molecule)) && !isCompoundFromVectorSelector(cmp.molecule)) { - const isVisible = dispatch(isCompoundVisible(cmp.datasetID, cmp.molecule.id)); - if (isVisible) { - result = cmp; - break; + + result = dispatch(getCurrentSelectedCompoundIterator()); + + if (!(result.datasetID && result.molecule)) { + for (let i = 0; i < moleculesObjectIDListOfCompoundsToBuy.length; i++) { + const cmp = moleculesObjectIDListOfCompoundsToBuy[i]; + if (!dispatch(isCompoundLocked(cmp.datasetID, cmp.molecule)) && !isCompoundFromVectorSelector(cmp.molecule)) { + const isVisible = dispatch(isCompoundVisible(cmp)); + if (isVisible) { + result = cmp; + break; + } } } } @@ -664,12 +674,28 @@ export const SelectedCompoundList = memo(() => { const node = getNode(nextItem.molecule?.id); setScrollToMoleculeId(nextItem.molecule?.id); + let firstItemIdToUse = firstItem.molecule?.id; + let isCustomPdb = true; + if (!firstItem.molecule?.isCustomPdb) { + isCustomPdb = false; + const obs = dispatch(getObservationForLHSReference(firstItem.molecule)); + if (obs) { + firstItemIdToUse = obs.id; + } + } + let dataValue = { colourToggle: getRandomColor(firstItem.molecule), isLigandOn: ligandList.includes(firstItem.molecule?.id), - isProteinOn: proteinList.includes(firstItem.molecule?.id), - isComplexOn: complexList.includes(firstItem.molecule?.id), - isSurfaceOn: surfaceList.includes(firstItem.molecule?.id) + isProteinOn: isCustomPdb + ? proteinListDataset.includes(firstItemIdToUse) + : proteinList.includes(firstItemIdToUse), + isComplexOn: isCustomPdb + ? complexListDataset.includes(firstItemIdToUse) + : complexList.includes(firstItemIdToUse), + isSurfaceOn: isCustomPdb + ? surfaceListDataset.includes(firstItemIdToUse) + : surfaceList.includes(firstItemIdToUse) }; dispatch(setCrossReferenceCompoundName(moleculeTitleNext)); @@ -707,12 +733,28 @@ export const SelectedCompoundList = memo(() => { const node = getNode(prevItem.molecule?.id); setScrollToMoleculeId(prevItem.molecule?.id); + let firstItemIdToUse = firstItem.molecule?.id; + let isCustomPdb = true; + if (!firstItem.molecule?.isCustomPdb) { + isCustomPdb = false; + const obs = dispatch(getObservationForLHSReference(firstItem?.molecule)); + if (obs) { + firstItemIdToUse = obs.id; + } + } + let dataValue = { colourToggle: getRandomColor(firstItem.molecule), isLigandOn: ligandList.includes(firstItem.molecule?.id), - isProteinOn: proteinList.includes(firstItem.molecule?.id), - isComplexOn: complexList.includes(firstItem.molecule?.id), - isSurfaceOn: surfaceList.includes(firstItem.molecule?.id) + isProteinOn: isCustomPdb + ? proteinListDataset.includes(firstItemIdToUse) + : proteinList.includes(firstItemIdToUse), + isComplexOn: isCustomPdb + ? complexListDataset.includes(firstItemIdToUse) + : complexList.includes(firstItemIdToUse), + isSurfaceOn: isCustomPdb + ? surfaceListDataset.includes(firstItemIdToUse) + : surfaceList.includes(firstItemIdToUse) }; dispatch(setCrossReferenceCompoundName(moleculeTitleNext)); @@ -936,6 +978,11 @@ export const SelectedCompoundList = memo(() => { } const isLocked = dispatch(isCompoundLocked(data.datasetID, data.molecule)); + const isCustomPdb = data.molecule.isCustomPdb; + + const itemIdToUse = isCustomPdb + ? data.molecule.id + : dispatch(getObservationForLHSReference(data.molecule))?.id; // } return ( isVisible && ( @@ -952,12 +999,12 @@ export const SelectedCompoundList = memo(() => { previousItemData={index > 0 && array[index - 1]} nextItemData={index < array?.length && array[index + 1]} L={isLigandOn} - P={proteinList.includes(data.molecule.id)} - C={complexList.includes(data.molecule.id)} - S={surfaceList.includes(data.molecule.id)} + P={isCustomPdb ? proteinListDataset.includes(itemIdToUse) : proteinList.includes(itemIdToUse)} + C={isCustomPdb ? complexListDataset.includes(itemIdToUse) : complexList.includes(itemIdToUse)} + S={isCustomPdb ? surfaceListDataset.includes(itemIdToUse) : surfaceList.includes(itemIdToUse)} V={false} arrowsHidden={false} - dragDropEnabled + dragDropEnabled={false} shoppingCartColors={shoppingCartColors} isAddedToShoppingCart={isAddedToShoppingCart} inSelectedCompoundsList diff --git a/js/components/preview/tags/details/tagDetails.js b/js/components/preview/tags/details/tagDetails.js index 2f814f0b8..b4895c148 100644 --- a/js/components/preview/tags/details/tagDetails.js +++ b/js/components/preview/tags/details/tagDetails.js @@ -186,7 +186,7 @@ const TagDetails = memo(() => { useEffect(() => { const categoriesToRemove = getCategoriesToBeRemovedFromTagDetails(tagCategories); const newTagList = preTagList.filter(t => { - if (t.additional_info?.downloadName || categoriesToRemove.some(c => c.id === t.category)) { + if (t.hidden === true || t.additional_info?.downloadName || categoriesToRemove.some(c => c.id === t.category)) { return false; } else { return true; @@ -201,8 +201,8 @@ const TagDetails = memo(() => { const moleculesToEditIds = useSelector(state => state.selectionReducers.moleculesToEdit); const moleculesToEdit = moleculesToEditIds && - moleculesToEditIds.length > 0 && - !(moleculesToEditIds.length === 1 && moleculesToEditIds[0] === null) + moleculesToEditIds.length > 0 && + !(moleculesToEditIds.length === 1 && moleculesToEditIds[0] === null) ? moleculesToEditIds.map(id => dispatch(getMoleculeForId(id))) : []; diff --git a/js/components/preview/tags/modal/editTagsModal.js b/js/components/preview/tags/modal/editTagsModal.js index 9a9c703e9..7c07c4ded 100644 --- a/js/components/preview/tags/modal/editTagsModal.js +++ b/js/components/preview/tags/modal/editTagsModal.js @@ -184,7 +184,7 @@ export const EditTagsModal = ({ open, anchorEl, setOpenDialog }) => { dispatch(appendTagList(augMolTagObject)); dispatch(appendMoleculeTag(molTag)); dispatch(setNoTagsReceived(false)); - toastInfo('Tag was created'); + toastInfo('Tag was created', { autoHideDuration: 5000 }); }); // reset tag/fields after creating new one resetTagToEditState(); @@ -222,7 +222,7 @@ export const EditTagsModal = ({ open, anchorEl, setOpenDialog }) => { ) ); } - toastInfo('Tag was updated'); + toastInfo('Tag was updated', { autoHideDuration: 5000 }); // reset tag/fields after updating selected one resetTagToEditState(); } @@ -245,7 +245,7 @@ export const EditTagsModal = ({ open, anchorEl, setOpenDialog }) => { }); } deleteExistingTag(tag, tag.id); - toastInfo('Tag was deleted'); + toastInfo('Tag was deleted', { autoHideDuration: 5000 }); // reset tag/fields after removing selected tag resetTagToEditState(); } diff --git a/js/components/preview/tags/tagCategory.js b/js/components/preview/tags/tagCategory.js index 25465e6b2..27f16b0aa 100644 --- a/js/components/preview/tags/tagCategory.js +++ b/js/components/preview/tags/tagCategory.js @@ -20,7 +20,7 @@ const TagCategory = memo(({ tagClickCallback, disabled = false }) => { let tagList = useSelector(state => state.apiReducers.tagList); tagList = tagList .filter(t => { - if (t.additional_info?.downloadName || listOfProhibitedCategories.some(cid => cid === t.category)) { + if (t.hidden || t.additional_info?.downloadName || listOfProhibitedCategories.some(cid => cid === t.category)) { return false; } else { return true; diff --git a/js/components/preview/tags/utils/tagUtils.js b/js/components/preview/tags/utils/tagUtils.js index 8d2876ec9..0862137c3 100644 --- a/js/components/preview/tags/utils/tagUtils.js +++ b/js/components/preview/tags/utils/tagUtils.js @@ -236,7 +236,7 @@ export const getAllTagsForLHSCmp = (observations, tagList, tagCategoryList) => { obs?.tags_set.forEach(tagId => { let tag = tagList.find(t => t.id === tagId); if ( - tag && + tag && !tag.hidden && !restOfTheTags.some(t => t.id === tag.id) && !prioTags.some(t => t.id === tag.id) && !obsPrioTags.some(t => t.id === tag.id) diff --git a/js/components/services/ServicesStatusWrapper.js b/js/components/services/ServicesStatusWrapper.js index 52fad2f6d..f84b7e599 100644 --- a/js/components/services/ServicesStatusWrapper.js +++ b/js/components/services/ServicesStatusWrapper.js @@ -45,7 +45,9 @@ export const ServicesStatusWrapper = memo(() => { if (!(prevState.length === 1 && prevState[0]?.id === 'services')) { toastError('Status of services is not available'); } - return [{ id: 'services', name: 'Status of services', state: 'NOT_AVAILABLE', timestamp: Date.now() }]; + const newTemp = [{ id: 'services', name: 'Status of services', state: 'NOT_AVAILABLE', timestamp: Date.now() }]; + checkServices(prevState, newTemp); + return newTemp; }); } else { setServices((prevState) => { diff --git a/js/reducers/tracking/dispatchActions.js b/js/reducers/tracking/dispatchActions.js index 2e5d5ca88..1ababf4f5 100644 --- a/js/reducers/tracking/dispatchActions.js +++ b/js/reducers/tracking/dispatchActions.js @@ -3485,7 +3485,7 @@ const handleArrowNavigationActionOfCompound = (action, isSelected, majorViewStag const qualityListMolecule = data.qualityList; dispatch(hideAllSelectedMolecules(majorViewStage, molecules, false, true)); - dispatch(removeSelectedDatasetMolecules(majorViewStage, true)); + dispatch(removeSelectedDatasetMolecules(majorViewStage, true, newItem)); const newDatasetID = (newItem.hasOwnProperty('datasetID') && newItem.datasetID) || datasetID; const moleculeTitlePrev = newItem && newItem.name;