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

Promote f/e changes to production #462

Merged
merged 27 commits into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
d651036
Squashed commit of the following:
boriskovar-m2ms Jul 31, 2024
8817d77
#1482 added TagName and CentroidRes columns for expanded view of obse…
matej-vavrek Aug 22, 2024
6af83d0
#1489 show warning toast message if is defined on target load
matej-vavrek Aug 27, 2024
5db8ab0
#1322 added longcode column
matej-vavrek Sep 4, 2024
c7c010d
updated general function for tag comparison
matej-vavrek Sep 5, 2024
63d44d6
Merge branch 'staging' into stagingcandidate
boriskovar-m2ms Sep 5, 2024
1b24e2a
#1505 adjusted getting of centroid_res
matej-vavrek Sep 5, 2024
fc9cd3e
#1458 allow to tag XCA sites, temp commit
matej-vavrek Jul 10, 2024
449eaa6
#1458 adjusted functionality and styling to proper change tag
matej-vavrek Sep 4, 2024
7193616
#1508 removed TagName column in expanded observation dialog, changed …
matej-vavrek Sep 12, 2024
da9ea84
Merge branch 'staging' into stagingcandidate
matej-vavrek Sep 12, 2024
12f8391
#1508 adjusted column order and width calculation
matej-vavrek Sep 13, 2024
f812106
Merge branch 'staging' into stagingcandidate
matej-vavrek Sep 13, 2024
e6b563b
#1501 added upload links to menu
matej-vavrek Sep 17, 2024
c9dfbf4
#1501 (#451)
matej-vavrek Sep 17, 2024
b24340d
#1520 show tag alias instead of upload_name on hit navigator CanonSit…
matej-vavrek Sep 25, 2024
dedd836
#1519 keep tag in edit window after save
matej-vavrek Sep 25, 2024
c68655e
#1519 and #1520 (#453)
matej-vavrek Sep 26, 2024
238b5c2
#1497 added Path column for extended view of observations
matej-vavrek Sep 30, 2024
c244d20
#1497 (#454)
matej-vavrek Oct 1, 2024
cdbb897
#1518 properly remove tag from list after updating its object
matej-vavrek Oct 10, 2024
37b885d
#1522 allow to change XCA tags for selections but not for CanonSite
matej-vavrek Oct 10, 2024
4d8ea0c
#1463 initial implementation of new sort options for hit navigator
matej-vavrek Oct 14, 2024
63fa397
Merge pull request #455 from m2ms/stagingcandidate
mwinokan Oct 14, 2024
9916d56
#1514 (#456)
matej-vavrek Oct 16, 2024
b8b61be
#1523 #1463 (#457)
matej-vavrek Oct 16, 2024
f155db1
#1551 (#459)
matej-vavrek Nov 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions js/components/datasets/inspirationDialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ import GroupNglControlButtonsContext from '../preview/molecule/groupNglControlBu

const useStyles = makeStyles(theme => ({
paper: {
width: 472,
height: 294,
width: 505,
// height: 294,
overflowY: 'hidden'
},
molHeader: {
Expand Down Expand Up @@ -382,11 +382,11 @@ export const InspirationDialog = memo(
<>
<Grid container justifyContent="flex-start" direction="row" className={classes.molHeader} wrap="nowrap">
<Grid item container justifyContent="flex-start" direction="row">
{Object.keys(moleculeProperty).map(key => (
{/* {Object.keys(moleculeProperty).map(key => (
<Grid item key={key} className={classes.rightBorder}>
{moleculeProperty[key]}
</Grid>
))}
))} */}
{allSelectedMolecules.length > 0 && (
<Grid item>
<Grid
Expand Down
28 changes: 26 additions & 2 deletions js/components/header/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ import { AddProjectDetail } from '../projects/addProjectDetail';
import { ServicesStatusWrapper } from '../services';
import { COMPANIES, get_logo } from '../funders/constants';
import { setEditTargetDialogOpen } from '../target/redux/actions';
import { Upload } from '@mui/icons-material';

const useStyles = makeStyles(theme => ({
padding: {
Expand Down Expand Up @@ -272,8 +273,8 @@ export default memo(
targetName !== undefined ? (
<>
{currentProject.authorID === null ||
currentProject.projectID === null ||
currentProject.authorID === userId ? (
currentProject.projectID === null ||
currentProject.authorID === userId ? (
<Button
onClick={() => {
isProjectModalLoading === false
Expand Down Expand Up @@ -574,6 +575,29 @@ export default memo(
</ListItemIcon>
<ListItemText primary="Contributors" />
</ListItem>
{DJANGO_CONTEXT.pk &&
<>
<Divider />
<ListItem button onClick={() => openLink(URLS.lhsUpload)}>
<ListItemIcon>
<Upload />
</ListItemIcon>
<ListItemText primary="LHS upload" />
</ListItem>
<ListItem button onClick={() => openLink(URLS.rhsUpload)}>
<ListItemIcon>
<Upload />
</ListItemIcon>
<ListItemText primary="RHS upload" />
</ListItem>
<ListItem button onClick={() => openLink(URLS.metadataUpload)}>
<ListItemIcon>
<Upload />
</ListItemIcon>
<ListItemText primary="Metadata upload" />
</ListItem>
</>
}
<Divider />
{authListItem}
</Grid>
Expand Down
40 changes: 38 additions & 2 deletions js/components/preview/molecule/moleculeView/moleculeView.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ import { DJANGO_CONTEXT } from '../../../../utils/djangoContext';
import { getFontColorByBackgroundColor } from '../../../../utils/colors';
import { api, METHOD } from '../../../../utils/api';
import { base_url } from '../../../routes/constants';
import { ContentCopyRounded } from '@mui/icons-material';
import { ToastContext } from '../../../toast';

const useStyles = makeStyles(theme => ({
container: {
Expand Down Expand Up @@ -145,7 +147,7 @@ const useStyles = makeStyles(theme => ({
image: {
border: 'solid 1px',
borderColor: theme.palette.background.divider,
borderStyle: 'solid solid solid none',
borderStyle: 'none none none solid',
position: 'relative'
},
imageMargin: {
Expand Down Expand Up @@ -411,6 +413,7 @@ const MoleculeView = memo(
const [tagEditModalOpenNew, setTagEditModalOpenNew] = useState(tagEditorOpenObs);

const { getNglView } = useContext(NglContext);
const { toastInfo } = useContext(ToastContext);
const stage = getNglView(VIEWS.MAJOR_VIEW) && getNglView(VIEWS.MAJOR_VIEW).stage;

const isLigandOn = L;
Expand Down Expand Up @@ -465,6 +468,7 @@ const MoleculeView = memo(
const [moleculeTooltipOpen, setMoleculeTooltipOpen] = useState(false);
const [tagPopoverOpen, setTagPopoverOpen] = useState(null);
const [centroidRes, setCentroidRes] = useState('');
const [experimentalPath, setExperimentalPath] = useState('');

const moleculeImgRef = useRef(null);

Expand Down Expand Up @@ -514,6 +518,26 @@ const MoleculeView = memo(
});
}, [data.canon_site_conf]);

useEffect(() => {
api({
url: `${base_url}/api/experiments/`,
method: METHOD.GET
})
.then(resp => {
const experiment = resp.data.results.find(experiment => experiment.id === data.experiment);
if (experiment) {
setExperimentalPath(experiment.pdb_info_source_file ?? '');
} else {
console.log('there is not any matching canonSiteConf object with ' + data.experiment + ' id');
setExperimentalPath('');
}
})
.catch(err => {
console.log('error fetching experiment from experiments api', err);
setExperimentalPath('');
});
}, [data.experiment]);

useEffect(() => {
if (showExpandedView) {
setHeaderWidthsHandler(centroidRes, 'CentroidRes');
Expand Down Expand Up @@ -1134,6 +1158,11 @@ const MoleculeView = memo(
return tagTooltip;
}, [getTagType]);

const copyExperimentalPaths = async () => {
await navigator.clipboard.writeText(experimentalPath);
toastInfo('Link was copied to the clipboard', { autoHideDuration: 5000 });
};

return (
<>
<Grid
Expand Down Expand Up @@ -1174,7 +1203,7 @@ const MoleculeView = memo(
</Grid>
<Grid item container className={classes.detailsCol} justifyContent="space-between" direction="row">
<Grid item container direction="column" alignItems="center" xs>
<Grid item container justifyContent="flex-start" alignItems="center" direction="row">
<Grid item container justifyContent="flex-start" alignItems="center" direction="row" xs>
<Grid item container justifyContent="space-between" direction="column" xs={3}>
{/* Title label */}
<Tooltip title={data.prefix_tooltip ?? '-' + (data.id === pose?.main_site_observation ? " - main observation" : "")} placement="bottom-start">
Expand Down Expand Up @@ -1503,6 +1532,13 @@ const MoleculeView = memo(
{data.longcode}
</Grid>
</Tooltip>
<Tooltip title={experimentalPath.length > 0 ? experimentalPath : 'empty path'}>
<Grid item align="center" style={{ minWidth: headerWidths.Path }}>
<IconButton color="inherit" onClick={copyExperimentalPaths} size="small">
<ContentCopyRounded fontSize="small" />
</IconButton>
</Grid>
</Tooltip>
</Grid>}
</Grid >
<SvgTooltip
Expand Down
149 changes: 142 additions & 7 deletions js/components/preview/molecule/observationCmpList.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ import {
Divider,
Typography,
IconButton,
ButtonGroup
ButtonGroup,
Select,
MenuItem,
Checkbox
} from '@material-ui/core';
import React, { useState, useEffect, useCallback, memo, useRef, useContext, useMemo } from 'react';
import { useDispatch, useSelector } from 'react-redux';
Expand Down Expand Up @@ -222,6 +225,9 @@ const useStyles = makeStyles(theme => ({
//color: theme.palette.black
}
},
selectButton: {
padding: '4px 2px !important'
},
formControl: {
color: 'inherit',
margin: theme.spacing(1),
Expand Down Expand Up @@ -321,6 +327,89 @@ export const ObservationCmpList = memo(({ hideProjects }) => {

const [predefinedFilter, setPredefinedFilter] = useState(filter !== undefined ? filter.predefined : DEFAULT_FILTER);

const [ascending, setAscending] = useState(true);
const handleAscendingChecked = (event) => setAscending(event.target.checked);
const SORT_OPTIONS = [
'POSE_NAME',
'COMPOUND_CODE',
'CANONSITE_NUMBER',
'CONFORMERSITE_NUMBER',
'OBSERVATION_COUNT'
];
const sortOptions = {
POSE_NAME: {
title: 'Pose name',
handler: (a, b, asc) => compareByPoseName(a, b, asc)
},
COMPOUND_CODE: {
title: 'Compound code',
handler: (a, b, asc) => compareByCompoundCode(a, b, asc)
},
CANONSITE_NUMBER: {
title: 'CanonSite number',
handler: (a, b, asc) => compareByCanonSiteNumber(a, b, asc)
},
CONFORMERSITE_NUMBER: {
title: 'ConformerSite number',
handler: (a, b, asc) => compareByConformerSiteNumber(a, b, asc)
},
OBSERVATION_COUNT: {
title: 'Observation count',
handler: (a, b, asc) => compareByObservationCount(a, b, asc)
}
};
const [sortOption, setSortOption] = useState(SORT_OPTIONS[0]);

const compareByPoseName = (a, b, asc) => {
const aName = a.code;
const bName = b.code;
return asc ? aName.localeCompare(bName, undefined, { numeric: true, sensitivity: 'base' })
: bName.localeCompare(aName, undefined, { numeric: true, sensitivity: 'base' });
};
const compareByCompoundCode = (a, b, asc) => {
const aName = a.main_site_observation_cmpd_code;
const bName = b.main_site_observation_cmpd_code;
return asc ? aName.localeCompare(bName, undefined, { numeric: true, sensitivity: 'base' })
: bName.localeCompare(aName, undefined, { numeric: true, sensitivity: 'base' });
};
const compareByCanonSiteNumber = (a, b, asc) => {
const aName = getCanonSiteTagPrefix(a);
const bName = getCanonSiteTagPrefix(b);
return asc ? aName.localeCompare(bName, undefined, { numeric: true, sensitivity: 'base' })
: bName.localeCompare(aName, undefined, { numeric: true, sensitivity: 'base' });
};
const compareByConformerSiteNumber = (a, b, asc) => {
const aName = getConformerSiteTagPrefix(a);
const bName = getConformerSiteTagPrefix(b);
return asc ? aName.localeCompare(bName, undefined, { numeric: true, sensitivity: 'base' })
: bName.localeCompare(aName, undefined, { numeric: true, sensitivity: 'base' });
};
const compareByObservationCount = (a, b, asc) => {
const aCount = a.site_observations.length;
const bCount = b.site_observations.length;
return asc ? aCount - bCount : bCount - aCount;
};

/**
* Get CanonSites tag for sorting
*/
const getCanonSiteTagPrefix = useCallback(pose => {
const mainObservation = pose.associatedObs.find(observation => observation.id === pose.main_site_observation);
const canonSitesTag = categories.find(tagCategory => tagCategory.category === 'CanonSites');
const canonSite = tags.find(tag => tag.category === canonSitesTag.id && tag.site_observations.includes(mainObservation.id));
return canonSite !== undefined ? canonSite.tag_prefix : '';
}, [categories, tags]);

/**
* Get ConformerSites tag for sorting
*/
const getConformerSiteTagPrefix = useCallback(pose => {
const mainObservation = pose.associatedObs.find(observation => observation.id === pose.main_site_observation);
const conformerSitesTag = categories.find(tagCategory => tagCategory.category === 'ConformerSites');
const conformerSite = tags.find(tag => tag.category === conformerSitesTag.id && tag.site_observations.includes(mainObservation.id));
return conformerSite !== undefined ? conformerSite.tag_prefix : '';
}, [categories, tags]);

const isActiveFilter = !!(filter || {}).active;

const { getNglView } = useContext(NglContext);
Expand All @@ -330,10 +419,29 @@ export const ObservationCmpList = memo(({ hideProjects }) => {
const filterRef = useRef();
const tagEditorRef = useRef();
const scrollBarRef = useRef();
const hitNavigatorRef = useRef();
const [tagEditorAnchorEl, setTagEditorAnchorEl] = useState(null);
const [hitNavigatorWidth, setHitNavigatorWidth] = useState(0);

const areLSHCompoundsInitialized = useSelector(state => state.selectionReducers.areLSHCompoundsInitialized);

useEffect(() => {
if (hitNavigatorRef && hitNavigatorRef.current) {

const resizeObserver = new ResizeObserver(() => {
if (hitNavigatorRef.current.offsetWidth !== hitNavigatorWidth) {
setHitNavigatorWidth(hitNavigatorRef.current.offsetWidth);
}
});

resizeObserver.observe(hitNavigatorRef.current);

return function cleanup() {
resizeObserver.disconnect();
}
}
}, [hitNavigatorRef, hitNavigatorWidth]);

if (directDisplay && directDisplay.target) {
target = directDisplay.target;
}
Expand Down Expand Up @@ -718,8 +826,9 @@ export const ObservationCmpList = memo(({ hideProjects }) => {
compounds.push(compound);
}
});
compounds.sort((a, b) => sortOptions[sortOption].handler(a, b, ascending));
return compounds;
}, [joinedMoleculeLists, lhsCompoundsList]);
}, [joinedMoleculeLists, lhsCompoundsList, sortOptions, sortOption, ascending]);

useEffect(() => {
if (isObservationDialogOpen && observationsForLHSCmp?.length > 0) {
Expand Down Expand Up @@ -973,7 +1082,7 @@ export const ObservationCmpList = memo(({ hideProjects }) => {
};

return (
<Panel hasHeader title="Hit navigator" headerActions={actions}>
<Panel hasHeader title="Hit navigator" headerActions={actions} ref={hitNavigatorRef}>
<AlertModal
title="Are you sure?"
description={`Loading of ${joinedMoleculeLists?.length} may take a long time`}
Expand Down Expand Up @@ -1113,7 +1222,7 @@ export const ObservationCmpList = memo(({ hideProjects }) => {

{
<Tooltip title={selectAllHitsPressed ? 'Unselect all hits' : 'Select all hits'}>
<Grid item style={{ marginLeft: '20px' }}>
<Grid item style={{ marginLeft: '2px' }} className={classes.selectButton}>
<Button
variant="outlined"
className={classNames(classes.contColButton, {
Expand All @@ -1133,7 +1242,7 @@ export const ObservationCmpList = memo(({ hideProjects }) => {
}
{selectedDisplayHits === true ? (
<Tooltip title={'Unselect displayed hits'}>
<Grid item style={{ marginLeft: '20px' }}>
<Grid item className={classes.selectButton}>
<Button
variant="outlined"
className={classNames(classes.contColButton, {
Expand All @@ -1152,7 +1261,7 @@ export const ObservationCmpList = memo(({ hideProjects }) => {
</Tooltip>
) : (
<Tooltip title={'Select displayed hits'}>
<Grid item style={{ marginLeft: '20px' }}>
<Grid item className={classes.selectButton}>
<Button
variant="outlined"
className={classNames(classes.contColButton, {
Expand All @@ -1171,9 +1280,35 @@ export const ObservationCmpList = memo(({ hideProjects }) => {
</Tooltip>
)}
<Grid style={{ marginTop: '4px' }}>
<Typography variant="caption" className={classes.noOfSelectedHits}>{`Selected: ${allSelectedMolecules ? allSelectedMolecules.length : 0
<Typography variant="caption">{`Selected: ${allSelectedMolecules ? allSelectedMolecules.length : 0
}`}</Typography>
</Grid>
<Grid style={{ marginTop: '4px' }}>
<Typography variant="caption" style={{ paddingLeft: 3 }}>Sort by</Typography>
</Grid>
<Grid style={{ marginTop: '4px', marginLeft: '4px' }}>
<Tooltip title={sortOption ? sortOptions[sortOption].title : "Sort by"}>
<Select
value={sortOption}
onChange={(event) => setSortOption(event.target.value)}
// fullWidth
size="small"
style={{ fontSize: 10, width: 75 }}
>
{SORT_OPTIONS.map((option, index) => (
<MenuItem key={`${index}-${option}`} value={option} style={{ fontSize: 12, padding: '3px 7px' }}>
{sortOptions[option].title}
</MenuItem>
))}
</Select>
</Tooltip>
</Grid>
<Tooltip title={ascending ? "Ascending" : "Descending"}>
<Grid style={{ marginTop: '4px' }}>
<Checkbox checked={ascending} onChange={handleAscendingChecked} size="small" style={{ padding: 0 }} />
<Typography variant="caption">{(selectAllHitsPressed && hitNavigatorWidth > 508) || (!selectAllHitsPressed && hitNavigatorWidth > 491) ? 'Ascending' : 'ASC'}</Typography>
</Grid>
</Tooltip>
</Grid>
<Grid container spacing={1} direction="column" justifyContent="flex-start" className={classes.container}>
<Grid item>
Expand Down
Loading