From 4a1de1839bf94b2e827d1f0148ed771f20e9000e Mon Sep 17 00:00:00 2001 From: Lan Le Date: Mon, 7 Aug 2023 10:36:15 +0200 Subject: [PATCH] feat: show nmrium button for reaction and research plan --- .../apps/mydb/elements/details/ViewSpectra.js | 4 +- .../analysesTab/ReactionDetailsContainers.js | 127 +++++++++++------ .../ResearchPlanDetailsContainers.js | 129 ++++++++++++------ .../ReactionDetailsContainers.spec.js | 122 +++++++++++++++++ .../ResearchPlanDetailsContainers.spec.js | 123 +++++++++++++++++ .../packs/src/utilities/SpectraHelper.spec.js | 34 ++--- 6 files changed, 440 insertions(+), 99 deletions(-) create mode 100644 spec/javascripts/packs/src/apps/mydb/elements/details/reactions/analysesTab/ReactionDetailsContainers.spec.js create mode 100644 spec/javascripts/packs/src/apps/mydb/elements/details/researchPlans/analysesTab/ResearchPlanDetailsContainers.spec.js diff --git a/app/packs/src/apps/mydb/elements/details/ViewSpectra.js b/app/packs/src/apps/mydb/elements/details/ViewSpectra.js index 4b8a933583..8a43e4efa4 100644 --- a/app/packs/src/apps/mydb/elements/details/ViewSpectra.js +++ b/app/packs/src/apps/mydb/elements/details/ViewSpectra.js @@ -524,8 +524,8 @@ class ViewSpectra extends React.Component { buildOpsByLayout(et) { if (this.props.sample && this.props.sample instanceof ResearchPlan) { return [ - { name: 'write & save', value: this.writeOp }, - { name: 'write, save & close', value: this.writeCloseOp }, + { name: 'write & save', value: this.saveOp }, + { name: 'write, save & close', value: this.saveCloseOp }, ]; } const updatable = this.props.sample && this.props.sample.can_update; diff --git a/app/packs/src/apps/mydb/elements/details/reactions/analysesTab/ReactionDetailsContainers.js b/app/packs/src/apps/mydb/elements/details/reactions/analysesTab/ReactionDetailsContainers.js index fc2e53119c..a74d34cb04 100644 --- a/app/packs/src/apps/mydb/elements/details/reactions/analysesTab/ReactionDetailsContainers.js +++ b/app/packs/src/apps/mydb/elements/details/reactions/analysesTab/ReactionDetailsContainers.js @@ -15,11 +15,12 @@ import { hNmrCount, cNmrCount, instrumentText } from 'src/utilities/ElementUtils import { contentToText } from 'src/utilities/quillFormat'; import { chmoConversions } from 'src/components/OlsComponent'; import { previewContainerImage } from 'src/utilities/imageHelper'; -import { JcampIds, BuildSpcInfos } from 'src/utilities/SpectraHelper'; +import { JcampIds, BuildSpcInfos, BuildSpcInfosForNMRDisplayer, isNMRKind } from 'src/utilities/SpectraHelper'; import UIStore from 'src/stores/alt/stores/UIStore'; import SpectraActions from 'src/stores/alt/actions/SpectraActions'; import LoadingActions from 'src/stores/alt/actions/LoadingActions'; import ViewSpectra from 'src/apps/mydb/elements/details/ViewSpectra'; +import NMRiumDisplayer from 'src/components/nmriumWrapper/NMRiumDisplayer'; import TextTemplateActions from 'src/stores/alt/actions/TextTemplateActions'; @@ -42,48 +43,74 @@ const nmrMsg = (reaction, container) => { const SpectraEditorBtn = ({ element, spcInfo, hasJcamp, hasChemSpectra, toggleSpectraModal, confirmRegenerate, + toggleNMRDisplayerModal, hasNMRium, }) => ( - Spectra Editor {!spcInfo ? ': Reprocess' : ''}} - >{spcInfo ? ( - - + Spectra Editor {!spcInfo ? ': Reprocess' : ''}} + >{spcInfo ? ( + + } + onToggle={(open, event) => { if (event) { event.stopPropagation(); } }} + onClick={toggleSpectraModal} + disabled={!spcInfo || !hasChemSpectra} + > + { + event.stopPropagation(); + confirmRegenerate(event); + }} + disabled={!hasJcamp || !element.can_update} + > + Reprocess + + + + ) : ( + + )} + + { + hasNMRium ? ( + Process with NMRium} > - Reprocess - - - - ) : ( - - )} - + + + + + ) : null + } + ); SpectraEditorBtn.propTypes = { @@ -96,6 +123,8 @@ SpectraEditorBtn.propTypes = { hasChemSpectra: PropTypes.bool, toggleSpectraModal: PropTypes.func.isRequired, confirmRegenerate: PropTypes.func.isRequired, + toggleNMRDisplayerModal: PropTypes.func.isRequired, + hasNMRium: PropTypes.bool, }; SpectraEditorBtn.defaultProps = { @@ -103,6 +132,8 @@ SpectraEditorBtn.defaultProps = { spcInfo: false, element: {}, hasChemSpectra: false, + hasEditedJcamp: false, + hasNMRium: false, }; export default class ReactionDetailsContainers extends Component { @@ -192,13 +223,22 @@ export default class ReactionDetailsContainers extends Component { } }; const spcInfo = BuildSpcInfos(reaction, container); - const { hasChemSpectra } = UIStore.getState(); + const { hasChemSpectra, hasNmriumWrapper } = UIStore.getState(); const toggleSpectraModal = (e) => { e.stopPropagation(); SpectraActions.ToggleModal(); SpectraActions.LoadSpectra.defer(spcInfo); }; + //process open NMRium + const toggleNMRDisplayerModal = (e) => { + const spcInfosForNMRDisplayer = BuildSpcInfosForNMRDisplayer(reaction, container); + e.stopPropagation(); + SpectraActions.ToggleModalNMRDisplayer(); + SpectraActions.LoadSpectraForNMRDisplayer.defer(spcInfosForNMRDisplayer); // going to fetch files base on spcInfos + } + + const hasNMRium = isNMRKind(container) && hasNmriumWrapper; return (
@@ -219,6 +259,8 @@ export default class ReactionDetailsContainers extends Component { hasChemSpectra={hasChemSpectra} toggleSpectraModal={toggleSpectraModal} confirmRegenerate={confirmRegenerate} + toggleNMRDisplayerModal={toggleNMRDisplayerModal} + hasNMRium={hasNMRium} />
); @@ -388,6 +430,11 @@ export default class ReactionDetailsContainers extends Component { handleSampleChanged={this.handleSpChange} handleSubmit={this.props.handleSubmit} /> + ); diff --git a/app/packs/src/apps/mydb/elements/details/researchPlans/analysesTab/ResearchPlanDetailsContainers.js b/app/packs/src/apps/mydb/elements/details/researchPlans/analysesTab/ResearchPlanDetailsContainers.js index 6d5c4d33cc..6589b888c1 100644 --- a/app/packs/src/apps/mydb/elements/details/researchPlans/analysesTab/ResearchPlanDetailsContainers.js +++ b/app/packs/src/apps/mydb/elements/details/researchPlans/analysesTab/ResearchPlanDetailsContainers.js @@ -7,59 +7,87 @@ import QuillViewer from 'src/components/QuillViewer'; import ImageModal from 'src/components/common/ImageModal'; import { instrumentText } from 'src/utilities/ElementUtils'; import { previewContainerImage } from 'src/utilities/imageHelper'; -import { JcampIds, BuildSpcInfos } from 'src/utilities/SpectraHelper'; +import { JcampIds, BuildSpcInfos, BuildSpcInfosForNMRDisplayer, isNMRKind } from 'src/utilities/SpectraHelper'; import UIStore from 'src/stores/alt/stores/UIStore'; import SpectraActions from 'src/stores/alt/actions/SpectraActions'; import LoadingActions from 'src/stores/alt/actions/LoadingActions'; import ViewSpectra from 'src/apps/mydb/elements/details/ViewSpectra'; +import NMRiumDisplayer from 'src/components/nmriumWrapper/NMRiumDisplayer'; import TextTemplateActions from 'src/stores/alt/actions/TextTemplateActions'; const SpectraEditorBtn = ({ element, spcInfo, hasJcamp, hasChemSpectra, toggleSpectraModal, confirmRegenerate, + toggleNMRDisplayerModal, hasNMRium, }) => ( - Spectra Editor {!spcInfo ? ': Reprocess' : ''}} - >{spcInfo ? ( - - + Spectra Editor {!spcInfo ? ': Reprocess' : ''}} + >{spcInfo ? ( + + } + onToggle={(open, event) => { if (event) { event.stopPropagation(); } }} + onClick={toggleSpectraModal} + disabled={!spcInfo || !hasChemSpectra} + > + { + event.stopPropagation(); + confirmRegenerate(event); + }} + disabled={!hasJcamp || !element.can_update} + > + Reprocess + + + + ) : ( + + )} + + { + hasNMRium ? ( + Process with NMRium} > - Reprocess - - - - ) : ( - - )} - + + + + + ) : null + } + + ); @@ -73,6 +101,8 @@ SpectraEditorBtn.propTypes = { hasChemSpectra: PropTypes.bool, toggleSpectraModal: PropTypes.func.isRequired, confirmRegenerate: PropTypes.func.isRequired, + toggleNMRDisplayerModal: PropTypes.func.isRequired, + hasNMRium: PropTypes.bool, }; SpectraEditorBtn.defaultProps = { @@ -80,6 +110,7 @@ SpectraEditorBtn.defaultProps = { spcInfo: false, element: {}, hasChemSpectra: false, + hasNMRium: false, }; export default class ResearchPlanDetailsContainers extends Component { @@ -163,12 +194,23 @@ export default class ResearchPlanDetailsContainers extends Component { } }; const spcInfo = BuildSpcInfos(researchPlan, container); - const { hasChemSpectra } = UIStore.getState(); + const { hasChemSpectra, hasNmriumWrapper } = UIStore.getState(); const toggleSpectraModal = (e) => { e.stopPropagation(); SpectraActions.ToggleModal(); SpectraActions.LoadSpectra.defer(spcInfo); }; + + //process open NMRium + const toggleNMRDisplayerModal = (e) => { + const spcInfosForNMRDisplayer = BuildSpcInfosForNMRDisplayer(researchPlan, container); + e.stopPropagation(); + SpectraActions.ToggleModalNMRDisplayer(); + SpectraActions.LoadSpectraForNMRDisplayer.defer(spcInfosForNMRDisplayer); // going to fetch files base on spcInfos + } + + const hasNMRium = isNMRKind(container) && hasNmriumWrapper; + return (
); @@ -349,6 +393,11 @@ export default class ResearchPlanDetailsContainers extends Component { handleSampleChanged={this.handleSpChange} handleSubmit={this.props.handleSubmit} /> + ); diff --git a/spec/javascripts/packs/src/apps/mydb/elements/details/reactions/analysesTab/ReactionDetailsContainers.spec.js b/spec/javascripts/packs/src/apps/mydb/elements/details/reactions/analysesTab/ReactionDetailsContainers.spec.js new file mode 100644 index 0000000000..ded8806865 --- /dev/null +++ b/spec/javascripts/packs/src/apps/mydb/elements/details/reactions/analysesTab/ReactionDetailsContainers.spec.js @@ -0,0 +1,122 @@ +import React from 'react'; +import expect from 'expect'; +import Enzyme, { shallow } from 'enzyme'; +import Adapter from '@wojtekmaj/enzyme-adapter-react-17'; +import { + describe, it, beforeEach, afterEach +} from 'mocha'; + +import { + PanelGroup, + Panel, + Button, +} from 'react-bootstrap'; + +import ReactionDetailsContainers from 'src/apps/mydb/elements/details/reactions/analysesTab/ReactionDetailsContainers'; + +import Reaction from 'src/models/Reaction'; +import Container from 'src/models/Container'; +import { DndProvider } from 'react-dnd'; +import { HTML5Backend } from 'react-dnd-html5-backend'; + +Enzyme.configure({ adapter: new Adapter() }); + +describe('ReactionDetailsContainers', () => { + describe('when it does not have any analysis', () => { + const reaction = Reaction.buildEmpty(); + it('Render without any analysis and readonly', () => { + const wrapper = shallow(); + const expectedValue = shallow( +
+ There are currently no Analyses. + +
+ ); + expect(wrapper.html()).toEqual(expectedValue.html()); + }); + + it('Render without any analysis', () => { + const wrapper = shallow(); + const expectedValue = shallow( +
+ There are currently no Analyses. + +
+ ); + expect(wrapper.html()).toEqual(expectedValue.html()); + }); + }); + + describe('when it has analyses', () => { + let reaction = null; + + const btnAdd = ( +
+   +
+ ); + + beforeEach(() => { + reaction = Reaction.buildEmpty(); + }); + + afterEach(() => { + reaction = null; + }); + + it('Render with analysis is deleted', () => { + const analysis = Container.buildAnalysis(); + analysis.is_deleted = true; + reaction.container.children[0].children.push(analysis); + + const wrapper = shallow( + + + + ); + const expectedValue = shallow( +
+ {btnAdd} + + + +
+ + {analysis.name} + {` - Type: ${analysis.extended_metadata.kind}`} + + + +
+
+
+
+
+ ); + expect(wrapper.html()).toEqual(expectedValue.html()); + }); + }); +}); diff --git a/spec/javascripts/packs/src/apps/mydb/elements/details/researchPlans/analysesTab/ResearchPlanDetailsContainers.spec.js b/spec/javascripts/packs/src/apps/mydb/elements/details/researchPlans/analysesTab/ResearchPlanDetailsContainers.spec.js new file mode 100644 index 0000000000..044586dc05 --- /dev/null +++ b/spec/javascripts/packs/src/apps/mydb/elements/details/researchPlans/analysesTab/ResearchPlanDetailsContainers.spec.js @@ -0,0 +1,123 @@ +import React from 'react'; +import expect from 'expect'; +import Enzyme, { shallow } from 'enzyme'; +import Adapter from '@wojtekmaj/enzyme-adapter-react-17'; +import { + describe, it, beforeEach, afterEach +} from 'mocha'; + +import { + PanelGroup, + Panel, + Button, +} from 'react-bootstrap'; +import { DndProvider } from 'react-dnd'; +import { HTML5Backend } from 'react-dnd-html5-backend'; + +import Container from 'src/models/Container'; +import ResearchPlan from 'src/models/ResearchPlan'; + +import ResearchPlanDetailsContainers + from 'src/apps/mydb/elements/details/researchPlans/analysesTab/ResearchPlanDetailsContainers'; + +Enzyme.configure({ adapter: new Adapter() }); + +describe('ResearchPlanDetailsContainers', () => { + describe('when it does not have any analysis', () => { + const researchPlan = ResearchPlan.buildEmpty(); + it('Render without any analysis and readonly', () => { + const wrapper = shallow(); + const expectedValue = shallow( +
+ There are currently no Analyses. + +
+ ); + expect(wrapper.html()).toEqual(expectedValue.html()); + }); + + it('Render without any analysis', () => { + const wrapper = shallow(); + const expectedValue = shallow( +
+ There are currently no Analyses. + +
+ ); + expect(wrapper.html()).toEqual(expectedValue.html()); + }); + }); + + describe('when it has analyses', () => { + let researchPlan = null; + + const btnAdd = ( +
+   +
+ ); + + beforeEach(() => { + researchPlan = ResearchPlan.buildEmpty(); + }); + + afterEach(() => { + researchPlan = null; + }); + + it('Render with analysis is deleted', () => { + const analysis = Container.buildAnalysis(); + analysis.is_deleted = true; + researchPlan.container.children[0].children.push(analysis); + + const wrapper = shallow( + + + + ); + const expectedValue = shallow( +
+ {btnAdd} + + + +
+ + {analysis.name} + {` - Type: ${analysis.extended_metadata.kind}`} + + + +
+
+
+
+
+ ); + expect(wrapper.html()).toEqual(expectedValue.html()); + }); + }); +}); diff --git a/spec/javascripts/packs/src/utilities/SpectraHelper.spec.js b/spec/javascripts/packs/src/utilities/SpectraHelper.spec.js index 96cc18f756..0803ecc238 100644 --- a/spec/javascripts/packs/src/utilities/SpectraHelper.spec.js +++ b/spec/javascripts/packs/src/utilities/SpectraHelper.spec.js @@ -10,8 +10,8 @@ import Sample from 'src/models/Sample'; import Container from 'src/models/Container'; describe('SpectraHelper', () => { - describe('isNMRKind', () => { - describe('container is null or undefined', () => { + describe('.isNMRKind()', () => { + describe('when container is null or undefined:', () => { it('container is null', () => { expect(isNMRKind(null)).toEqual(false); }); @@ -21,13 +21,13 @@ describe('SpectraHelper', () => { }); }); - describe('container is neither not null nor undefined', () => { - it('container does not has extended_metadata', () => { + describe('when container is neither not null nor undefined:', () => { + it('when container does not has extended_metadata', () => { const container = 'Just a random value'; expect(isNMRKind(container)).toEqual(false); }); - describe('container has extended_metadata', () => { + describe('when container has extended_metadata', () => { it('metadata does not has kind value', () => { const container = { extended_metadata: {} }; expect(isNMRKind(container)).toEqual(false); @@ -46,8 +46,8 @@ describe('SpectraHelper', () => { }); }); - describe('BuildSpcInfosForNMRDisplayer', () => { - describe('sample or container is null or undefined', () => { + describe('.BuildSpcInfosForNMRDisplayer()', () => { + describe('when sample or container is null or undefined', () => { it('sample is null or undefined', () => { const specInfo1 = BuildSpcInfosForNMRDisplayer(null, 'just a random value'); expect(specInfo1).toEqual([]); @@ -65,7 +65,7 @@ describe('SpectraHelper', () => { }); }); - describe('it does not has any file to process', () => { + describe('when it does not has any file to process', () => { it('container does not has any attachment', () => { const container = { children: [{ attachments: [] }] }; const specInfo = BuildSpcInfosForNMRDisplayer('just a random value', container); @@ -88,7 +88,7 @@ describe('SpectraHelper', () => { }); }); - describe('it has file to be processed', () => { + describe('when it has file to be processed', () => { it('get spectra info', () => { const sample = Sample.buildEmpty(); const analyses = Container.buildEmpty(); @@ -125,8 +125,8 @@ describe('SpectraHelper', () => { }); }); - describe('JcampIds', () => { - describe('Container does not have any child', () => { + describe('.JcampIds()', () => { + describe('when container does not have any child', () => { it('children is empty', () => { const container = Container.buildEmpty(); const listJcampIds = JcampIds(container); @@ -135,7 +135,7 @@ describe('SpectraHelper', () => { }); }); - describe('Container does not have jcamp file', () => { + describe('when container does not have jcamp file', () => { const container = Container.buildEmpty(); const attachments = [{ filename: 'testfile.txt' }]; container.children.push({ attachments }); @@ -145,7 +145,7 @@ describe('SpectraHelper', () => { expect(listJcampIds).toEqual(expectedValue); }); - describe('Container has jcamp files', () => { + describe('when container has jcamp files', () => { let container; beforeEach(() => { @@ -184,8 +184,8 @@ describe('SpectraHelper', () => { }); }); - describe('BuildSpcInfos', () => { - describe('sample or container is null or undefined', () => { + describe('.BuildSpcInfos()', () => { + describe('when sample or container is null or undefined', () => { it('sample is null or undefined', () => { const specInfo1 = BuildSpcInfos(null, 'just a random value'); expect(specInfo1).toEqual([]); @@ -203,7 +203,7 @@ describe('SpectraHelper', () => { }); }); - describe('it does not has any file to process', () => { + describe('when it does not has any file to process', () => { it('container does not has any attachment', () => { const container = { children: [{ attachments: [] }] }; const specInfo = BuildSpcInfos('just a random value', container); @@ -226,7 +226,7 @@ describe('SpectraHelper', () => { }); }); - describe('it has file to be processed', () => { + describe('when it has file to be processed', () => { it('get spectra info', () => { const sample = Sample.buildEmpty(); const analyses = Container.buildEmpty();