Skip to content

Commit 6460457

Browse files
authored
Merge pull request #493 from xchem/staging
Push to production
2 parents 0324344 + e203721 commit 6460457

35 files changed

Lines changed: 1984 additions & 677 deletions

docker-compose.dev.vector.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ services:
6262
- ../data/logs:/code/logs/
6363
- ../data/media:/code/media/
6464
- ../fragalysis-frontend:/code/frontend
65+
- ../data/target:/code/target
6566
ports:
6667
- '8080:80'
6768
environment:

js/components/datasets/datasetMoleculeView/datasetMoleculeView.js

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ import {
7171
addComplex,
7272
addHitProtein,
7373
addSurface,
74+
generateAndStoreMolImage,
7475
getMolImage,
7576
removeComplex,
7677
removeHitProtein,
@@ -92,6 +93,7 @@ import { compoundsColors } from '../../preview/compounds/redux/constants';
9293
import { LockVisibleCompoundsDialog } from '../lockVisibleCompoundsDialog';
9394
import { fabClasses } from '@mui/material';
9495
import useClipboard from 'react-use-clipboard';
96+
import { useRDKit } from '../../rdkit/RDKitContext';
9597

9698
const useStyles = makeStyles(theme => ({
9799
container: {
@@ -402,6 +404,8 @@ const DatasetMoleculeView = memo(
402404
const { handlerId, isDragging } = useDragDropMoleculeView(ref, datasetID, data, index, moveMolecule);
403405
const opacity = isDragging ? 0 : 1;
404406

407+
const { RDKitModule, loading } = useRDKit();
408+
405409
const selectedAll = useRef(false);
406410
const currentID = (data && data.id) || (data && data.smiles) || undefined;
407411
const isFromVectorSelector = isCompoundFromVectorSelector(data);
@@ -514,10 +518,22 @@ const DatasetMoleculeView = memo(
514518

515519
// componentDidMount
516520
useEffect(() => {
517-
dispatch(getMolImage(data.smiles, MOL_TYPE.DATASET, imageWidth, imageHeight)).then(i => {
518-
setImage(i);
521+
dispatch(generateAndStoreMolImage(data, MOL_TYPE.DATASET, imageWidth, imageHeight, RDKitModule)).then(i => {
522+
i && setImage(i.toString());
519523
});
520-
}, [C, currentID, data, L, imageHeight, imageWidth, data.smiles, data.id, filteredDatasetMoleculeList, dispatch]);
524+
}, [
525+
C,
526+
currentID,
527+
data,
528+
L,
529+
imageHeight,
530+
imageWidth,
531+
data.smiles,
532+
data.id,
533+
filteredDatasetMoleculeList,
534+
dispatch,
535+
RDKitModule
536+
]);
521537

522538
const svg_image = (
523539
<SVGInline
@@ -1397,10 +1413,10 @@ const DatasetMoleculeView = memo(
13971413
null}
13981414
</Grid>
13991415
)) || (
1400-
<Grid item className={classes.rightBorder}>
1401-
-
1402-
</Grid>
1403-
)}
1416+
<Grid item className={classes.rightBorder}>
1417+
-
1418+
</Grid>
1419+
)}
14041420
</Tooltip>
14051421
);
14061422
})}

js/components/header/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ import { VIEWS } from '../../constants/constants';
8181
import moment from 'moment';
8282
import { ToastContext } from '../toast';
8383
import { api, METHOD } from '../../utils/api';
84+
import { QualityStatusService } from '../preview/molecule/moleculeView/qualityStatus/QualityStatusService';
8485

8586
const useStyles = makeStyles(theme => ({
8687
padding: {
@@ -496,6 +497,7 @@ export default memo(
496497
)}
497498
</Grid>
498499
<ServicesStatusWrapper />
500+
<QualityStatusService />
499501
<Grid item>
500502
<Tooltip title={'Introduction to the Fragalysis application'}>
501503
<Button onClick={() => openLink(URLS.helpPage)} startIcon={<HelpOutline />} variant="text" size="small">
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { Dialog, DialogContent, DialogTitle, LinearProgress, Typography } from '@material-ui/core';
2+
import React, { useState, useEffect, useContext } from 'react';
3+
import { useSelector } from 'react-redux';
4+
5+
export const DataDownloadProgressDialog = () => {
6+
const dataAreDownloading = useSelector(state => state.apiReducers.dataAreDownloading);
7+
const lhsIsFullyRendered = useSelector(state => state.selectionReducers.lhsIsFullyRendered);
8+
9+
return (
10+
<Dialog open={dataAreDownloading || !lhsIsFullyRendered} aria-labelledby="data-download-progress-dialog-title">
11+
<DialogTitle id="data-download-progress-dialog-title">
12+
{dataAreDownloading ? 'Data download progress' : 'Rendering of UI in progress'}
13+
</DialogTitle>
14+
<DialogContent>
15+
<Typography variant="body1">
16+
{dataAreDownloading ? 'Downloading of data is in progress...' : 'Rendering of UI is in progress...'}
17+
</Typography>
18+
{dataAreDownloading && <LinearProgress variant="indeterminate" />}
19+
</DialogContent>
20+
</Dialog>
21+
);
22+
};

js/components/preview/Preview.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ import { useDisplaySurfaceRHS } from '../../reducers/ngl/useDisplaySurfaceRHS';
6666
import { loadTargetList } from '../target/redux/dispatchActions';
6767
import { EditSnapshotDialog } from './projectHistoryPanel/editSnapshotDialog';
6868
import { RenderingProgressDialog } from '../loading/RenderingProgressDialog';
69+
import { DataDownloadProgressDialog } from '../loading/DataDownloadProgressDialog';
6970

7071
const ReactGridLayout = WidthProvider(ResponsiveGridLayout);
7172

@@ -350,6 +351,7 @@ const Preview = memo(({ isStateLoaded, hideProjects, isSnapshot = false }) => {
350351
<PickProjectModal />
351352
<EditSnapshotDialog />
352353
<RenderingProgressDialog />
354+
<DataDownloadProgressDialog />
353355
{!hideProjects && <ProjectDetailDrawer showHistory={showHistory} setShowHistory={setShowHistory} />}
354356
</>
355357
);

js/components/preview/molecule/moleculeView/moleculeView.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ import {
3333
getDensityMapData,
3434
getProteinData,
3535
withDisabledMoleculeNglControlButton,
36-
getCategoryById
36+
getCategoryById,
37+
generateAndStoreMolImage
3738
} from '../redux/dispatchActions';
3839
import {
3940
setSelectedAll,
@@ -67,6 +68,7 @@ import { api, METHOD } from '../../../../utils/api';
6768
import { base_url } from '../../../routes/constants';
6869
import { ContentCopyRounded } from '@mui/icons-material';
6970
import { ToastContext } from '../../../toast';
71+
import { useRDKit } from '../../../rdkit/RDKitContext';
7072

7173
const useStyles = makeStyles(theme => ({
7274
container: {
@@ -418,6 +420,8 @@ const MoleculeView = memo(
418420
const filter = useSelector(state => state.selectionReducers.filter);
419421
const [img_data, setImg_data] = useState(img_data_init);
420422

423+
const { RDKitModule, loading } = useRDKit();
424+
421425
const viewParams = useSelector(state => state.nglReducers.viewParams);
422426
const tagList = useSelector(state => state.apiReducers.tagList);
423427
const tagEditorOpenObs = useSelector(state => state.selectionReducers.tagEditorOpenedObs);
@@ -846,11 +850,11 @@ const MoleculeView = memo(
846850
// componentDidMount
847851
useEffect(() => {
848852
if (data) {
849-
dispatch(getMolImage(data?.id, MOL_TYPE.HIT, imageWidth, imageHeight)).then(i => {
850-
setImg_data(i);
853+
dispatch(generateAndStoreMolImage(data, MOL_TYPE.HIT, imageWidth, imageHeight, RDKitModule)).then(i => {
854+
i && setImg_data(i.toString());
851855
});
852856
}
853-
}, [data, imageHeight, imageWidth, dispatch]);
857+
}, [data, imageHeight, imageWidth, dispatch, RDKitModule]);
854858

855859
useEffect(() => {
856860
dispatch(getQualityInformation(data));
@@ -859,7 +863,7 @@ const MoleculeView = memo(
859863
const svg_image = (
860864
<SVGInline
861865
component="div"
862-
svg={img_data}
866+
svg={img_data.toString()}
863867
// className={classes.imageMargin}
864868
style={{
865869
height: `${imageHeight}px`,
@@ -1608,7 +1612,7 @@ const MoleculeView = memo(
16081612
<SvgTooltip
16091613
open={moleculeTooltipOpen}
16101614
anchorEl={moleculeImgRef.current}
1611-
imgData={img_data}
1615+
imgData={img_data.toString()}
16121616
width={imageWidth}
16131617
height={imageHeight}
16141618
/>
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/**
2+
* This is a modal window for quality status overview
3+
*/
4+
5+
import React, { memo, useCallback, useContext, useState } from 'react';
6+
import { Dialog, DialogContent, Divider, Grid, IconButton, makeStyles, Popover, Table, TableBody, TableCell, TableRow, TextField, Tooltip, Typography } from '@material-ui/core';
7+
import { QualityStatusLight } from './QualityStatusLight';
8+
import { QUALITY_STATUSES } from './constants';
9+
import { Add, Check } from '@material-ui/icons';
10+
import classNames from 'classnames';
11+
import { addPeerReviewStatus } from './api/apiActions';
12+
import { useDispatch } from 'react-redux';
13+
import { ToastContext } from '../../../../toast';
14+
15+
const useStyles = makeStyles(theme => ({
16+
root: {
17+
padding: 16,
18+
minWidth: 260,
19+
'& $gridItem': {
20+
padding: 4
21+
}
22+
},
23+
gridItem: {
24+
// padding: 4
25+
},
26+
paper: {
27+
overflow: 'hidden'
28+
},
29+
highlight: {
30+
boxShadow: '0px 0px 0px 2px #ccc',
31+
borderRadius: 5
32+
},
33+
statusLight: {
34+
cursor: 'pointer'
35+
}
36+
}));
37+
38+
export const PeerReviewModal = memo(({ openDialog, onDialogClose, anchorEl, site_observation }) => {
39+
40+
const dispatch = useDispatch();
41+
const classes = useStyles();
42+
const [comment, setComment] = useState('');
43+
const [selectedStatus, setSelectedStatus] = useState(QUALITY_STATUSES.NONE);
44+
45+
const { toastInfo } = useContext(ToastContext);
46+
47+
const addPeerReviewStatusHandler = () => {
48+
dispatch(addPeerReviewStatus({ status: selectedStatus, comment: comment, site_observation: site_observation }));
49+
toastInfo('Peer review was added', { autoHideDuration: 5000 });
50+
onDialogClose();
51+
};
52+
53+
return (
54+
<Popover
55+
// id={id}
56+
open={openDialog}
57+
anchorEl={anchorEl}
58+
onClose={onDialogClose}
59+
anchorOrigin={{
60+
vertical: 'center',
61+
horizontal: 'right'
62+
}}
63+
classes={{ paper: classes.paper }}
64+
>
65+
<Grid container justifyContent="flex-start" direction="column" spacing={2} className={classes.root}>
66+
<Grid item container direction="row" justifyContent="space-between" alignItems="center" spacing={2}>
67+
<Grid className={classes.gridItem} item xs={4}>
68+
<Typography variant="body1">Set status:</Typography>
69+
</Grid>
70+
{Object.values(QUALITY_STATUSES).map((status, index) => (
71+
<Grid key={index} item xs
72+
className={classNames(classes.gridItem, classes.statusLight)}
73+
onClick={() => setSelectedStatus(status)}
74+
>
75+
<QualityStatusLight size={16} status={status} props={{ className: classNames({ [classes.highlight]: status === selectedStatus }) }} />
76+
</Grid>
77+
))}
78+
<Tooltip title={'Add peer review'}>
79+
<Grid className={classes.gridItem} item xs>
80+
<IconButton size="small" onClick={addPeerReviewStatusHandler} disabled={!comment}>
81+
<Check />
82+
</IconButton>
83+
</Grid>
84+
</Tooltip>
85+
</Grid>
86+
<Grid item container direction="row" justifyContent="space-between" alignItems="center" spacing={2}>
87+
<Grid className={classes.gridItem} item xs={5}>
88+
<Typography variant="body1">Add comment:</Typography>
89+
</Grid>
90+
<Grid className={classes.gridItem} item xs>
91+
<TextField value={comment} onChange={event => setComment(event.target.value)} placeholder='write a comment' />
92+
</Grid>
93+
</Grid>
94+
</Grid>
95+
</Popover>
96+
);
97+
});
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import React, { memo } from "react";
2+
import { QUALITY_STATUSES, QUALITY_STATUS_COLORS } from "./constants";
3+
import { LightCircle } from "../../../../services";
4+
5+
export const QualityStatusLight = memo(({ status, size = 15, props = {} }) => {
6+
const getColor = (status) => {
7+
switch (status) {
8+
case QUALITY_STATUSES.GOOD:
9+
return QUALITY_STATUS_COLORS.GOOD;
10+
case QUALITY_STATUSES.MEDIOCRE:
11+
return QUALITY_STATUS_COLORS.MEDIOCRE;
12+
case QUALITY_STATUSES.BAD:
13+
return QUALITY_STATUS_COLORS.BAD;
14+
default:
15+
return QUALITY_STATUS_COLORS.NONE;
16+
}
17+
}
18+
return <LightCircle color={getColor(status)} size={size} props={props} />;
19+
});

0 commit comments

Comments
 (0)