Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implements #1373 and f/e part of the #1393 #421

Merged
merged 11 commits into from
Apr 12, 2024
Binary file added M2MS_Fragalysis_front-end_requirements_v0.5.docx
Binary file not shown.
175 changes: 135 additions & 40 deletions js/components/datasets/compoundSetList.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/
import React, { useEffect, memo, useState, useCallback } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { clearDatasetSettings, initializeDatasetFilter } from './redux/dispatchActions';
import { clearDatasetSettings, getInspirationsForMol, initializeDatasetFilter } from './redux/dispatchActions';
import { setExpandCompoundSets, setDataset, setSelectedDatasetIndex, setUpdatedDatasets } from './redux/actions';
import DatasetMoleculeList from './datasetMoleculeList';
import { makeStyles, Table, TableBody, TableCell, TableHead, TableRow, Tooltip } from '@material-ui/core';
Expand All @@ -13,6 +13,7 @@ import CloudDownloadOutlinedIcon from '@mui/icons-material/CloudDownloadOutlined
import SearchField from '../common/Components/SearchField';
import { base_url } from '../routes/constants';
import { METHOD, api } from '../../utils/api';
import { compoundsColors } from '../preview/compounds/redux/constants';

const useStyles = makeStyles(theme => ({
table: {
Expand Down Expand Up @@ -63,6 +64,23 @@ export const CompoundSetList = () => {
const scoreDatasetMap = useSelector(state => state.datasetsReducers.scoreDatasetMap);
const moleculeLists = useSelector(state => state.datasetsReducers.moleculeLists);

const allInspirations = useSelector(state => state.datasetsReducers.allInspirations);
const compoundColors = useSelector(state => state.datasetsReducers.compoundColorByDataset);

const blueInput = useSelector(state => state.previewReducers.compounds[compoundsColors.blue.key]);
const redInput = useSelector(state => state.previewReducers.compounds[compoundsColors.red.key]);
const greenInput = useSelector(state => state.previewReducers.compounds[compoundsColors.green.key]);
const purpleInput = useSelector(state => state.previewReducers.compounds[compoundsColors.purple.key]);
const apricotInput = useSelector(state => state.previewReducers.compounds[compoundsColors.apricot.key]);

const inputs = {
[compoundsColors.blue.key]: blueInput,
[compoundsColors.red.key]: redInput,
[compoundsColors.green.key]: greenInput,
[compoundsColors.purple.key]: purpleInput,
[compoundsColors.apricot.key]: apricotInput
};

const [isExpanded, setIsExpanded] = useState(false);
const [searchString, setSearchString] = useState(null);
const [defaultSelectedValue, setDefaultSelectedValue] = useState();
Expand All @@ -74,13 +92,20 @@ export const CompoundSetList = () => {
* @param {*} scoreName
* @returns {string}
*/
const getCommonScore = useCallback((datasetID, scoreName) => {
let value = '';
if (datasetID && scoreDatasetMap.hasOwnProperty(datasetID) && scoreDatasetMap[datasetID].hasOwnProperty(scoreName)) {
value = scoreDatasetMap[datasetID][scoreName].description;
}
return value;
}, [scoreDatasetMap]);
const getCommonScore = useCallback(
(datasetID, scoreName) => {
let value = '';
if (
datasetID &&
scoreDatasetMap.hasOwnProperty(datasetID) &&
scoreDatasetMap[datasetID].hasOwnProperty(scoreName)
) {
value = scoreDatasetMap[datasetID][scoreName].description;
}
return value;
},
[scoreDatasetMap]
);

/**
* Download molecule list of given dataset as CSV file
Expand All @@ -91,12 +116,81 @@ export const CompoundSetList = () => {
const listOfMols = [];
const moleculeList = moleculeLists[datasetID] || [];

let maxNumOfInspirations = 0;
moleculeList.forEach(cmp => {
const inspirations = getInspirationsForMol(allInspirations, datasetID, cmp.id);
if (inspirations?.length > maxNumOfInspirations) {
maxNumOfInspirations = inspirations.length;
}
});

let colorsTemplate = {};
moleculeList.forEach(compound => {
let shoppingCartColors = [];
const cmpColorsForDataset = compoundColors[datasetID];
if (cmpColorsForDataset) {
shoppingCartColors = cmpColorsForDataset[compound.id];
shoppingCartColors.forEach(color => {
if (!colorsTemplate.hasOwnProperty(color)) {
colorsTemplate[color] = '';
if (inputs.hasOwnProperty(color) && inputs[color]) {
colorsTemplate[`${color}-text`] = inputs[color];
}
}
});
}
});

moleculeList.forEach(molecule => {
let molObj = {};

molObj['smiles'] = molecule.smiles;
molObj['name'] = molecule.name;

if (molecule.hasOwnProperty('numerical_scores')) {
Object.keys(molecule.numerical_scores).forEach(key => {
molObj[key] = molecule.numerical_scores[key];
});
}
if (molecule.hasOwnProperty('text_scores')) {
Object.keys(molecule.text_scores).forEach(key => {
molObj[key] = molecule.text_scores[key];
});
}

if (maxNumOfInspirations) {
const inspirations = getInspirationsForMol(allInspirations, datasetID, molecule.id);
for (let i = 0; i < maxNumOfInspirations; i++) {
if (inspirations?.[i]) {
molObj[`inspiration_${i + 1}`] = inspirations[i].code;
} else {
molObj[`inspiration_${i + 1}`] = '';
}
}
}

let shoppingCartColors = [];

const cmpColorsForDataset = compoundColors[datasetID];
if (cmpColorsForDataset) {
shoppingCartColors = cmpColorsForDataset[molecule.id];
let colorsTemplateCopy = { ...colorsTemplate };
shoppingCartColors.forEach(color => {
colorsTemplateCopy[color] = true;
});

Object.keys(colorsTemplateCopy)
.filter(key => key.includes('-text'))
.forEach(key => {
const color = key.split('-')[0];
if (colorsTemplateCopy.hasOwnProperty(color) && !colorsTemplateCopy[color]) {
colorsTemplateCopy[key] = '';
}
});

molObj = { ...molObj, ...colorsTemplateCopy };
}

listOfMols.push(molObj);
});

Expand All @@ -118,7 +212,9 @@ export const CompoundSetList = () => {

useEffect(() => {
if (selectedDatasetIndex === 0) {
const filteredDataset = searchString ? customDatasets.filter(dataset => dataset.title.toLowerCase().includes(searchString.toLowerCase())) : customDatasets;
const filteredDataset = searchString
? customDatasets.filter(dataset => dataset.title.toLowerCase().includes(searchString.toLowerCase()))
: customDatasets;
const newDataset = filteredDataset.map((dataSet, index) =>
index === 0 ? { ...dataSet, visibility: true } : { ...dataSet, visibility: false }
);
Expand All @@ -138,7 +234,9 @@ export const CompoundSetList = () => {
};

const handleChangeVisibility = index => {
const filteredDataset = searchString ? customDatasets.filter(dataset => dataset.title.toLowerCase().includes(searchString.toLowerCase())) : customDatasets;
const filteredDataset = searchString
? customDatasets.filter(dataset => dataset.title.toLowerCase().includes(searchString.toLowerCase()))
: customDatasets;
const newDataset = filteredDataset.map((dataSetValue, i) =>
i === index ? { ...dataSetValue, visibility: true } : { ...dataSetValue, visibility: false }
);
Expand Down Expand Up @@ -171,30 +269,14 @@ export const CompoundSetList = () => {
<Table className={classes.table}>
<TableHead>
<TableRow style={{ padding: 0 }}>
<TableCell style={{ width: 25, padding: 0 }}>
{/* Select */}
</TableCell>
<TableCell style={{ width: 60, padding: 0 }}>
Name
</TableCell>
<TableCell style={{ width: 15, padding: 0 }}>
#
</TableCell>
<TableCell style={{ width: 70, padding: 0 }}>
Submitter
</TableCell>
<TableCell style={{ width: 55, padding: 0 }}>
Institution
</TableCell>
<TableCell style={{ width: 60, padding: 0 }}>
Date
</TableCell>
<TableCell style={{ width: 70, padding: 0 }}>
Method
</TableCell>
<TableCell style={{ width: 30, padding: 0 }}>
CSV
</TableCell>
<TableCell style={{ width: 25, padding: 0 }}>{/* Select */}</TableCell>
<TableCell style={{ width: 60, padding: 0 }}>Name</TableCell>
<TableCell style={{ width: 15, padding: 0 }}>#</TableCell>
<TableCell style={{ width: 70, padding: 0 }}>Submitter</TableCell>
<TableCell style={{ width: 55, padding: 0 }}>Institution</TableCell>
<TableCell style={{ width: 60, padding: 0 }}>Date</TableCell>
<TableCell style={{ width: 70, padding: 0 }}>Method</TableCell>
<TableCell style={{ width: 30, padding: 0 }}>CSV</TableCell>
</TableRow>
</TableHead>
<TableBody>
Expand All @@ -220,23 +302,36 @@ export const CompoundSetList = () => {
</TableCell>
</Tooltip>
<Tooltip title="Number of compounds">
<TableCell className={classes.tableCell} style={{ maxWidth: 15 }}>{moleculeList.length}</TableCell>
<TableCell className={classes.tableCell} style={{ maxWidth: 15 }}>
{moleculeList.length}
</TableCell>
</Tooltip>
<Tooltip title={getCommonScore(dataset.id, 'submitter_name')}>
<TableCell className={classes.tableCell} style={{ maxWidth: 100 }}>{getCommonScore(dataset.id, 'submitter_name')}</TableCell>
<TableCell className={classes.tableCell} style={{ maxWidth: 100 }}>
{getCommonScore(dataset.id, 'submitter_name')}
</TableCell>
</Tooltip>
<Tooltip title={getCommonScore(dataset.id, 'submitter_institution')}>
<TableCell className={classes.tableCell} style={{ maxWidth: 70 }}>{getCommonScore(dataset.id, 'submitter_institution')}</TableCell>
<TableCell className={classes.tableCell} style={{ maxWidth: 70 }}>
{getCommonScore(dataset.id, 'submitter_institution')}
</TableCell>
</Tooltip>
<Tooltip title={getCommonScore(dataset.id, 'generation_date')}>
<TableCell className={classes.tableCell} style={{ maxWidth: 60 }}>{getCommonScore(dataset.id, 'generation_date')}</TableCell>
<TableCell className={classes.tableCell} style={{ maxWidth: 60 }}>
{getCommonScore(dataset.id, 'generation_date')}
</TableCell>
</Tooltip>
<Tooltip title={getCommonScore(dataset.id, 'method')}>
<TableCell className={classes.tableCell} style={{ maxWidth: 150 }}>{getCommonScore(dataset.id, 'method')}</TableCell>
<TableCell className={classes.tableCell} style={{ maxWidth: 150 }}>
{getCommonScore(dataset.id, 'method')}
</TableCell>
</Tooltip>
<TableCell style={{ padding: 0 }}>
<Tooltip title="Download as CSV">
<CloudDownloadOutlinedIcon className={classes.downloadIcon} onClick={() => downloadCSV(dataset.id)} />
<CloudDownloadOutlinedIcon
className={classes.downloadIcon}
onClick={() => downloadCSV(dataset.id)}
/>
</Tooltip>
</TableCell>
</TableRow>
Expand Down
36 changes: 16 additions & 20 deletions js/components/datasets/datasetMoleculeView/datasetMoleculeView.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,15 @@ import { centerOnLigandByMoleculeID } from '../../../reducers/ngl/dispatchAction
import { ArrowDownward, ArrowUpward, MyLocation } from '@material-ui/icons';
import { isString } from 'lodash';
import { SvgTooltip } from '../../common';
import { addComplex, addHitProtein, addSurface, getMolImage, removeComplex, removeHitProtein, removeSurface } from '../../preview/molecule/redux/dispatchActions';
import {
addComplex,
addHitProtein,
addSurface,
getMolImage,
removeComplex,
removeHitProtein,
removeSurface
} from '../../preview/molecule/redux/dispatchActions';
import { MOL_TYPE } from '../../preview/molecule/redux/constants';
import {
deselectVectorCompound,
Expand Down Expand Up @@ -1236,13 +1244,7 @@ const DatasetMoleculeView = memo(
wrap="nowrap"
className={classes.fullHeight}
>
<Grid
item
container
justifyContent="flex-start"
direction="row"
wrap="nowrap"
>
<Grid item container justifyContent="flex-start" direction="row" wrap="nowrap">
{filteredScoreProperties &&
datasetID &&
filteredScoreProperties[datasetID] &&
Expand Down Expand Up @@ -1270,21 +1272,15 @@ const DatasetMoleculeView = memo(
null}
</Grid>
)) || (
<Grid item className={classes.rightBorder}>
-
</Grid>
)}
<Grid item className={classes.rightBorder}>
-
</Grid>
)}
</Tooltip>
);
})}
</Grid>
<Grid
item
container
justifyContent="flex-end"
direction="row"
wrap="nowrap"
>
<Grid item container justifyContent="flex-end" direction="row" wrap="nowrap">
{Object.keys(compoundsColors).map(color => {
const colorIncluded = shoppingCartColors?.includes(color);
return (
Expand Down Expand Up @@ -1363,7 +1359,7 @@ const DatasetMoleculeView = memo(
</Tooltip>
)}
{moleculeTooltipOpen && !inSelectedCompoundsList && (
<Tooltip title={"Missing tooltip!"}>
<Tooltip title={'Missing tooltip!'}>
<IconButton className={classes.addToShoppingCartIcon} onClick={handleShoppingCartClick}>
<AddShoppingCartIcon />
</IconButton>
Expand Down
Loading