From 85bd6269daa97e543952f500ddfe42d5b33af7d6 Mon Sep 17 00:00:00 2001 From: Brianna Major Date: Fri, 25 Oct 2019 09:10:01 -0400 Subject: [PATCH 01/11] Remember previous location for Calculations When navigating Calculations or My Calculations remember previous location to allow navigating back to a previous page. Signed-off-by: Brianna Major --- src/containers/calculations.js | 68 +++++++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 5 deletions(-) diff --git a/src/containers/calculations.js b/src/containers/calculations.js index f14b164..7f491b3 100644 --- a/src/containers/calculations.js +++ b/src/containers/calculations.js @@ -44,22 +44,68 @@ class CalculationsContainer extends Component { constructor(props) { super(props); + const params = new URLSearchParams(props.location.search); this.state = { - sortIndex: 0, - paginationOptions: { limit: 16, offset: 0, sort: '_id', sortdir: -1 }, - searchOptions: {} + sortIndex: params.get('sortIndex') || 0, + paginationOptions: { + limit: params.get('limit') || 16, + offset: params.get('offset') || 0, + sort: params.get('sort') ? params.get('sort').toString() : '_id', + sortdir: params.get('sortdir') || -1 + }, + searchOptions: { + formula: params.get('formula') || '', + name: params.get('name') || '', + inchi: params.get('inchi') || '', + inchikey: params.get('inchikey') || '', + smiles: params.get('smiles') || '' + } } } componentDidMount() { - const { paginationOptions } = this.state; + const { paginationOptions, searchOptions } = this.state; var creatorId = null; if (this.props.match.params.id) { creatorId = this.props.match.params.id; } - this.props.dispatch(calculations.loadCalculations({options: paginationOptions, loadMolecules: true, creatorId: creatorId})); + const options = {...paginationOptions, ...searchOptions} + this.props.dispatch(calculations.loadCalculations({options, loadMolecules: true, creatorId: creatorId})); } + componentDidUpdate(prevProps) { + const currSearch = this.props.location.search; + const prevSearch = prevProps.location.search; + const params = new URLSearchParams(currSearch); + const reload = ( + this.props.history.action === 'POP' || params.get('offset') == 0); + if (currSearch !== prevSearch && reload) { + var offset = params.get('offset') + this.setState({ + sortIndex: params.get('sortIndex') || 0, + paginationOptions: { + limit: params.get('limit') || 16, + offset: params.get('offset') || 0, + sort: params.get('sort') ? params.get('sort').toString() : '_id', + sortdir: params.get('sortdir') || -1 + }, + searchOptions: { + formula: params.get('formula') || '', + name: params.get('name') || '', + inchi: params.get('inchi') || '', + inchikey: params.get('inchikey') || '', + smiles: params.get('smiles') || '' + } + }, () => { + const options = {...this.state.paginationOptions, ...this.state.searchOptions}; + var creatorId = null; + if (this.props.match.params.id) { + creatorId = this.props.match.params.id; + } + this.props.dispatch(calculations.loadCalculations({options, loadMolecules: true, creatorId})); + }); + } + } onOpen = (id) => { this.props.dispatch(push(`/calculations/${id}?mo=homo`)); } @@ -113,7 +159,19 @@ class CalculationsContainer extends Component { if (this.props.match.params.id) { creatorId = this.props.match.params.id; } + + const {sortIndex} = this.state; + const {sortdir, sort, limit, offset} = pagination; + for (let val in search) { + if (search[val] === undefined) { + search[val] = ''; + } + } + const params = {sortIndex, sortdir, sort, limit, offset, ...search}; + const query = new URLSearchParams(params).toString(); + this.props.dispatch(calculations.loadCalculations({options, loadMolecules: true, creatorId})); + this.props.dispatch(push({pathname:'/calculations', search:query})); } render() { From c66f51c5dfabe147f04d33215025705284103622 Mon Sep 17 00:00:00 2001 From: Brianna Major Date: Fri, 25 Oct 2019 09:14:19 -0400 Subject: [PATCH 02/11] Update Molecules to handle back navigation from search Previously, search params were not being taken into account in page navigation, so going back from a molecule that had been selected from search results would send you back to the first page of results, not matter where you were previously. Search params are now taken into account and users are returned to the correct previous page. Signed-off-by: Brianna Major --- src/containers/molecules.js | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/src/containers/molecules.js b/src/containers/molecules.js index b075f13..8e1be7e 100644 --- a/src/containers/molecules.js +++ b/src/containers/molecules.js @@ -109,16 +109,25 @@ class MoleculesContainer extends Component { sort: params.get('sort').toString(), sortdir: params.get('sortdir') }, - searchOptions: params.get('searchOptions') + searchOptions: { + formula: params.get('formula') || '', + name: params.get('name') || '', + inchi: params.get('inchi') || '', + inchikey: params.get('inchikey') || '', + smiles: params.get('smiles') || '' + } } } componentDidMount() { - const options = this.state.paginationOptions; + const { paginationOptions, searchOptions } = this.state; var creatorId = null; if (this.props.match.params.id) { creatorId = this.props.match.params.id; } + const options = {...paginationOptions, ...searchOptions} + Object.keys(options).forEach( + (key) => (options[key] == '') && delete options[key]); this.props.dispatch(molecules.loadMolecules({options, creatorId})); } @@ -138,9 +147,17 @@ class MoleculesContainer extends Component { sort: params.get('sort').toString(), sortdir: params.get('sortdir') }, - searchOptions: params.get('searchOptions') + searchOptions: { + formula: params.get('formula') || '', + name: params.get('name') || '', + inchi: params.get('inchi') || '', + inchikey: params.get('inchikey') || '', + smiles: params.get('smiles') || '' + } }, () => { - const options = this.state.paginationOptions; + const options = {...this.state.paginationOptions, ...this.state.searchOptions}; + Object.keys(options).forEach( + (key) => (options[key] == '') && delete options[key]); var creatorId = null; if (this.props.match.params.id) { creatorId = this.props.match.params.id; @@ -208,12 +225,19 @@ class MoleculesContainer extends Component { if (this.props.match.params.id) { creatorId = this.props.match.params.id; } - + const {sortIndex} = this.state; const {sortdir, sort, limit, offset} = pagination; - const params = {sortIndex, sortdir, sort, limit, offset}; + for (let val in search) { + if (search[val] === undefined) { + search[val] = ''; + } + } + const params = {sortIndex, sortdir, sort, limit, offset, ...search}; const query = new URLSearchParams(params).toString(); + Object.keys(options).forEach( + (key) => (options[key] == '') && delete options[key]); this.props.dispatch(molecules.loadMolecules({options, creatorId})); this.props.dispatch(push({pathname:'/molecules', search:query})); } From ccd69a02c7d5300681bcf34c9d5ec00cd68e66c3 Mon Sep 17 00:00:00 2001 From: Brianna Major Date: Fri, 25 Oct 2019 09:19:02 -0400 Subject: [PATCH 03/11] Clean up the molecule route Signed-off-by: Brianna Major --- src/components/sidebar/index.js | 4 ++-- src/containers/molecules.js | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/components/sidebar/index.js b/src/components/sidebar/index.js index 4bd4ad4..2e59da9 100644 --- a/src/components/sidebar/index.js +++ b/src/components/sidebar/index.js @@ -71,7 +71,7 @@ class SideBar extends Component { pushRoute('/molecules?limit=16&offset=0&sort=_id&sortdir=-1&sortIndex=0') } + onClick={() => pushRoute('/molecules') } >   Molecules @@ -80,7 +80,7 @@ class SideBar extends Component { {userId ? pushRoute('/user/' + userId + '/molecules?limit=16&offset=0&sort=_id&sortdir=-1&sortIndex=0') } + onClick={() => pushRoute('/user/' + userId + '/molecules') } >   My Molecules diff --git a/src/containers/molecules.js b/src/containers/molecules.js index 8e1be7e..66044a7 100644 --- a/src/containers/molecules.js +++ b/src/containers/molecules.js @@ -102,12 +102,12 @@ class MoleculesContainer extends Component { super(props); const params = new URLSearchParams(props.location.search); this.state = { - sortIndex: params.get('sortIndex'), + sortIndex: params.get('sortIndex') || 0, paginationOptions: { - limit: params.get('limit'), - offset: params.get('offset'), - sort: params.get('sort').toString(), - sortdir: params.get('sortdir') + limit: params.get('limit') || 16, + offset: params.get('offset') || 0, + sort: params.get('sort') ? params.get('sort').toString() : '_id', + sortdir: params.get('sortdir') || -1 }, searchOptions: { formula: params.get('formula') || '', @@ -140,12 +140,12 @@ class MoleculesContainer extends Component { if (currSearch !== prevSearch && reload) { var offset = params.get('offset') this.setState({ - sortIndex: params.get('sortIndex'), + sortIndex: params.get('sortIndex') || 0, paginationOptions: { - limit: params.get('limit'), - offset: offset, - sort: params.get('sort').toString(), - sortdir: params.get('sortdir') + limit: params.get('limit') || 16, + offset: params.get('offset') || 0, + sort: params.get('sort') ? params.get('sort').toString() : '_id', + sortdir: params.get('sortdir') || -1 }, searchOptions: { formula: params.get('formula') || '', From 1fbb753f47383e9ffa422b8c1f47078370c4b9d0 Mon Sep 17 00:00:00 2001 From: Brianna Major Date: Mon, 28 Oct 2019 10:54:13 -0400 Subject: [PATCH 04/11] Use loadash to check for undefined values Signed-off-by: Brianna Major --- src/containers/calculations.js | 4 ++-- src/containers/molecules.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/containers/calculations.js b/src/containers/calculations.js index 7f491b3..21f5034 100644 --- a/src/containers/calculations.js +++ b/src/containers/calculations.js @@ -5,7 +5,7 @@ import { push } from 'connected-react-router'; import { selectors } from '@openchemistry/redux' import { calculations, molecules } from '@openchemistry/redux' -import { isNil } from 'lodash-es'; +import { isNil, isUndefined } from 'lodash-es'; import PaginationSort from '../components/pagination-sort'; import Calculations from '../components/calculations'; @@ -163,7 +163,7 @@ class CalculationsContainer extends Component { const {sortIndex} = this.state; const {sortdir, sort, limit, offset} = pagination; for (let val in search) { - if (search[val] === undefined) { + if (isUndefined(search[val])) { search[val] = ''; } } diff --git a/src/containers/molecules.js b/src/containers/molecules.js index 66044a7..fb6aa53 100644 --- a/src/containers/molecules.js +++ b/src/containers/molecules.js @@ -5,7 +5,7 @@ import { push } from 'connected-react-router'; import { selectors } from '@openchemistry/redux' import { molecules } from '@openchemistry/redux' -import { has, isNil, isEqual } from 'lodash-es'; +import { has, isNil, isUndefined } from 'lodash-es'; import PaginationSort from '../components/pagination-sort'; import Molecules from '../components/molecules'; @@ -229,7 +229,7 @@ class MoleculesContainer extends Component { const {sortIndex} = this.state; const {sortdir, sort, limit, offset} = pagination; for (let val in search) { - if (search[val] === undefined) { + if (isUndefined(search[val])) { search[val] = ''; } } From e88d299608751a22a142f8ec40e82b8c320e657e Mon Sep 17 00:00:00 2001 From: Brianna Major Date: Tue, 29 Oct 2019 11:54:25 -0400 Subject: [PATCH 05/11] If a calculation has a version number, display it In the Calculations card on a molecule page and in the Input card on a calculation page, display the calculation's version number if it has one. Do not display the version number when browsing all calculations. Signed-off-by: Brianna Major --- src/components/calculations.js | 7 +++++-- src/utils/calculations.js | 3 +++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/components/calculations.js b/src/components/calculations.js index efcfcb3..315f701 100644 --- a/src/components/calculations.js +++ b/src/components/calculations.js @@ -1,7 +1,7 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { has } from 'lodash-es'; +import { has, filter, eq } from 'lodash-es'; import { withStyles } from '@material-ui/core'; import Grid from '@material-ui/core/Grid'; import Typography from '@material-ui/core/Typography'; @@ -52,7 +52,10 @@ class Calculations extends Component { const title = this.getName(calculation); const image = `${window.location.origin}/api/v1/molecules/${calculation.moleculeId}/svg`; const pending = has(calculation, 'properties.pending'); - const properties = getCalculationProperties(calculation); + let properties = getCalculationProperties(calculation); + properties = filter(properties, function(obj) { + return !eq(obj.label, 'Version'); + }); return ( diff --git a/src/utils/calculations.js b/src/utils/calculations.js index c6cee32..64c4938 100644 --- a/src/utils/calculations.js +++ b/src/utils/calculations.js @@ -38,6 +38,9 @@ export const getCalculationProperties = (calculation) => { if (has(calculation, 'image.repository')) { properties.push({label: 'Code', value: formatCode(calculation.image.repository)}); } + if (has(calculation, 'code.version')) { + properties.push({label: 'Version', value: calculation.code.version}); + } if (has(calculation, 'input.parameters.task')) { properties.push({label: 'Type', value: formatTask(calculation.input.parameters.task)}); } From a6ab3c045e72191ab36d3d3aff51af66d2ba21f6 Mon Sep 17 00:00:00 2001 From: Brianna Major Date: Tue, 29 Oct 2019 13:45:27 -0400 Subject: [PATCH 06/11] Fix the calculation notebook view The view was previously limited to a height of 60px. The notebook height is now determined by the available space. Signed-off-by: Brianna Major --- src/components/notebook.js | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/components/notebook.js b/src/components/notebook.js index 7c91644..915416c 100644 --- a/src/components/notebook.js +++ b/src/components/notebook.js @@ -3,14 +3,22 @@ import PropTypes from 'prop-types'; import Iframe from 'react-iframe' import Typography from '@material-ui/core/Typography'; +import { withStyles } from '@material-ui/core/styles'; import PageHead from './page-head'; import PageBody from './page-body'; -export default class Notebook extends Component { +const appStyles = theme => ({ + iframe: { + width: '100%', + height: '-webkit-fill-available' + } +}) + +class Notebook extends Component { render = () => { - const {fileId} = this.props; + const {classes, fileId} = this.props; const baseUrl = `${window.location.origin}/api/v1`; return (
@@ -20,10 +28,7 @@ export default class Notebook extends Component { -