From 84dd803c7bfbde96b67e7f57e109f6a675ce0d45 Mon Sep 17 00:00:00 2001 From: Johannes Haubold Date: Wed, 25 Sep 2024 15:14:58 +0200 Subject: [PATCH 01/17] Fix proptype of NumeralInput.value The value is internally converted to a numeral anyway, so we can be lenient in accepting data. Additionally, the component was called with a no longer existing property, which I removed as well. --- app/packs/src/apps/mydb/elements/details/NumeralInput.js | 2 +- .../details/samples/propertiesTab/ElementalCompositionCustom.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/packs/src/apps/mydb/elements/details/NumeralInput.js b/app/packs/src/apps/mydb/elements/details/NumeralInput.js index d789bce3b5..714e4c1d7c 100644 --- a/app/packs/src/apps/mydb/elements/details/NumeralInput.js +++ b/app/packs/src/apps/mydb/elements/details/NumeralInput.js @@ -72,7 +72,7 @@ NumeralInput.defaultProps = { NumeralInput.propTypes = { onChange: PropTypes.func.isRequired, - value: PropTypes.number.isRequired, + value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), numeralFormat: PropTypes.string.isRequired, disabled: PropTypes.bool, variant: PropTypes.string, diff --git a/app/packs/src/apps/mydb/elements/details/samples/propertiesTab/ElementalCompositionCustom.js b/app/packs/src/apps/mydb/elements/details/samples/propertiesTab/ElementalCompositionCustom.js index 62a239f528..e088f58217 100644 --- a/app/packs/src/apps/mydb/elements/details/samples/propertiesTab/ElementalCompositionCustom.js +++ b/app/packs/src/apps/mydb/elements/details/samples/propertiesTab/ElementalCompositionCustom.js @@ -50,7 +50,6 @@ export default class ElementalCompositionCustom extends React.Component { numeralFormat="0,0.00" label={key} value={newData[key]} - defaultValue={newData[key]} onChange={(v) => this.handleElementsListChanged(v, key, el_composition)} /> From 82b916bbe135a4c5e66b8a6829eb511791eeaf5b Mon Sep 17 00:00:00 2001 From: Johannes Haubold Date: Wed, 25 Sep 2024 16:24:24 +0200 Subject: [PATCH 02/17] Remove obsolete .isNew check --- .../src/apps/mydb/elements/details/reactions/ReactionDetails.js | 1 - 1 file changed, 1 deletion(-) diff --git a/app/packs/src/apps/mydb/elements/details/reactions/ReactionDetails.js b/app/packs/src/apps/mydb/elements/details/reactions/ReactionDetails.js index 98f039469b..76f0f7dc56 100644 --- a/app/packs/src/apps/mydb/elements/details/reactions/ReactionDetails.js +++ b/app/packs/src/apps/mydb/elements/details/reactions/ReactionDetails.js @@ -565,7 +565,6 @@ export default class ReactionDetails extends Component { { !reaction.isNew && } - this.handleReactionChange(r)} From 0014cef47795588c6edd6a4d9c37499f531ce04d Mon Sep 17 00:00:00 2001 From: Johannes Haubold Date: Wed, 25 Sep 2024 16:25:39 +0200 Subject: [PATCH 03/17] Make fetchDOIMetadata and fetchISBNMetadata return a proper Literature object, not a JS Object This caused Proptype Errors in AddButton and Citation --- .../literature/DetailsTabLiteratures.js | 45 +++++++++---------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/app/packs/src/apps/mydb/elements/details/literature/DetailsTabLiteratures.js b/app/packs/src/apps/mydb/elements/details/literature/DetailsTabLiteratures.js index 4b79ba8692..d504b7ccbd 100644 --- a/app/packs/src/apps/mydb/elements/details/literature/DetailsTabLiteratures.js +++ b/app/packs/src/apps/mydb/elements/details/literature/DetailsTabLiteratures.js @@ -222,16 +222,16 @@ export default class DetailsTabLiteratures extends Component { if (json.data && json.data.length > 0) { const data = json.data[0]; const citation = new Cite(data); - this.setState((prevState) => ({ - ...prevState, - literature: { - ...prevState.literature, - doi, - title: data.title || '', - year: (data && data.issued && data.issued['date-parts'][0]) || '', - refs: { citation, bibtex: citation.format('bibtex'), bibliography: json.format('bibliography') } - } - })); + + this.setState((prevState) => { + let updatedLiterature = prevState.literature; + updatedLiterature.doi = doi; + updatedLiterature.title = data.title || ''; + updatedLiterature.year = (data && data.issued && data.issued['date-parts'][0]) || ''; + updatedLiterature.refs = { citation, bibtex: citation.format('bibtex'), bibliography: json.format('bibliography') }; + + return ({ literature: updatedLiterature }); + }); const { literature } = this.state; this.handleLiteratureAdd(literature); } @@ -248,17 +248,16 @@ export default class DetailsTabLiteratures extends Component { Cite.async(isbn).then((json) => { if (json.data && json.data.length > 0) { const data = json.data[0]; - this.setState((prevState) => ({ - ...prevState, - literature: { - ...prevState.literature, - isbn, - title: data.title || '', - year: (data && data.issued && data.issued['date-parts'][0]) || '', - url: (data && data.URL) || '', - refs: { citation: json, bibtex: json.format('bibtex'), bibliography: json.format('bibliography') } - } - })); + this.setState((prevState) => { + let updatedLiterature = prevState.literature; + updatedLiterature.isbn = isbn; + updatedLiterature.title = data.title || ''; + updatedLiterature.year = (data && data.issued && data.issued['date-parts'][0]) || ''; + updatedLiterature.url = (data && data.URL) || ''; + updatedLiterature.refs = { citation: json, bibtex: json.format('bibtex'), bibliography: json.format('bibliography') } + + return ({ literature: updatedLiterature }); + }); const { literature } = this.state; this.handleLiteratureAdd(literature); } @@ -369,11 +368,11 @@ DetailsTabLiteratures.propTypes = { PropTypes.instanceOf(CellLine), PropTypes.instanceOf(Sample) ]).isRequired, - literatures: PropTypes.array, + literatures: PropTypes.object, readOnly: PropTypes.bool }; DetailsTabLiteratures.defaultProps = { readOnly: false, - literatures: [] + literatures: {} }; From d11eab6744182a3c0415bc34d1c6a4e56dbfd644 Mon Sep 17 00:00:00 2001 From: Johannes Haubold Date: Wed, 25 Sep 2024 17:16:14 +0200 Subject: [PATCH 04/17] Move ToggleButton to tab body and replace it by proper bootstrap component The original issue was just that the ToggleButton was situated in the Tab Button, which throws an error, because you are not allowed to nest a - - ); -} - -ToggleButton.propTypes = { - isToggledInitial: PropTypes.bool.isRequired, - onToggle: PropTypes.func, - onChange: PropTypes.func, - onLabel: PropTypes.string, - offLabel: PropTypes.string, - onColor: PropTypes.string, - offColor: PropTypes.string, - tooltipOn: PropTypes.string, - tooltipOff: PropTypes.string, -}; - -ToggleButton.defaultProps = { - onToggle: null, - onChange: null, - onLabel: 'On', - offLabel: 'Off', - onColor: '#afcfee', - offColor: '#d3d3d3', - tooltipOn: 'Click to switch off', - tooltipOff: 'Click to switch on', -}; diff --git a/spec/javascripts/packs/src/components/common/ToggleButton.spec.js b/spec/javascripts/packs/src/components/common/ToggleButton.spec.js deleted file mode 100644 index 5e2ffefc27..0000000000 --- a/spec/javascripts/packs/src/components/common/ToggleButton.spec.js +++ /dev/null @@ -1,64 +0,0 @@ -import React from 'react'; -import { shallow } from 'enzyme'; -import expect from 'expect'; -import sinon from 'sinon'; -import { - describe, it, beforeEach, afterEach -} from 'mocha'; -import ToggleButton from 'src/components/common/ToggleButton'; - -describe('', () => { - let wrapper; - let onToggleSpy; - let onChangeSpy; - - beforeEach(() => { - onToggleSpy = sinon.spy(); - onChangeSpy = sinon.spy(); - - wrapper = shallow( - - ); - }); - - afterEach(() => { - sinon.restore(); - }); - - it('should render with the initial state', () => { - expect(wrapper.find('span').text()).toEqual('Default Scheme'); - }); - - it('should toggle state and update label when clicked', () => { - wrapper.find('Button').simulate('click'); - expect(wrapper.find('span').text()).toEqual('Gas Scheme'); - }); - - it('should call the onToggle and onChange callbacks when clicked', () => { - wrapper.find('Button').simulate('click'); - expect(onToggleSpy.calledOnce).toBe(true); - expect(onToggleSpy.calledWith(true)).toBe(true); - expect(onChangeSpy.calledOnce).toBe(true); - expect(onChangeSpy.calledWith(true)).toBe(true); - }); - - it('should apply the correct background color based on the state', () => { - const buttonStyleBefore = wrapper.find('Button').prop('style'); - expect(buttonStyleBefore.backgroundColor).toEqual('#d3d3d3'); - - wrapper.find('Button').simulate('click'); - - const buttonStyleAfter = wrapper.find('Button').prop('style'); - expect(buttonStyleAfter.backgroundColor).toEqual('#afcfee'); - }); -}); From a29be55a41ef3ba23e339539f6d3b2264f81d8db Mon Sep 17 00:00:00 2001 From: Johannes Haubold Date: Wed, 25 Sep 2024 17:30:42 +0200 Subject: [PATCH 05/17] Make disabled property of PrivateNoteElement optional The render function sets a default, so the prop is definitely not required --- app/packs/src/apps/mydb/elements/details/PrivateNoteElement.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/packs/src/apps/mydb/elements/details/PrivateNoteElement.js b/app/packs/src/apps/mydb/elements/details/PrivateNoteElement.js index 9c7eaa2ddd..85c4e3bf47 100644 --- a/app/packs/src/apps/mydb/elements/details/PrivateNoteElement.js +++ b/app/packs/src/apps/mydb/elements/details/PrivateNoteElement.js @@ -112,5 +112,5 @@ export default class PrivateNoteElement extends React.Component { PrivateNoteElement.propTypes = { element: PropTypes.object.isRequired, - disabled: PropTypes.bool.isRequired, + disabled: PropTypes.bool, }; From bd3ec01dd04723bd6fa6c6fb83106b253c1e9437 Mon Sep 17 00:00:00 2001 From: Johannes Haubold Date: Wed, 25 Sep 2024 18:18:14 +0200 Subject: [PATCH 06/17] Make WellplateDetailsAttachments use instances of Wellplate and Attachment for PropType checking --- .../WellplateDetailsAttachments.js | 50 ++----------------- 1 file changed, 4 insertions(+), 46 deletions(-) diff --git a/app/packs/src/apps/mydb/elements/details/wellplates/attachmentsTab/WellplateDetailsAttachments.js b/app/packs/src/apps/mydb/elements/details/wellplates/attachmentsTab/WellplateDetailsAttachments.js index 283017e2b3..7d4a03e22d 100644 --- a/app/packs/src/apps/mydb/elements/details/wellplates/attachmentsTab/WellplateDetailsAttachments.js +++ b/app/packs/src/apps/mydb/elements/details/wellplates/attachmentsTab/WellplateDetailsAttachments.js @@ -27,6 +27,8 @@ import { import { formatDate, parseDate } from 'src/utilities/timezoneHelper'; import { StoreContext } from 'src/stores/mobx/RootStore'; import { observer } from 'mobx-react'; +import Wellplate from 'src/models/Wellplate'; +import Attachment from 'src/models/Attachment'; const templateInfo = ( @@ -384,52 +386,8 @@ export class WellplateDetailsAttachments extends Component { } WellplateDetailsAttachments.propTypes = { - wellplate: PropTypes.shape({ - id: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.number - ]).isRequired, - changed: PropTypes.bool.isRequired, - body: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.string.isRequired, - title: PropTypes.string.isRequired, - type: PropTypes.string.isRequired, - }) - ).isRequired, - attachments: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.number - ]).isRequired, - aasm_state: PropTypes.string.isRequired, - content_type: PropTypes.string.isRequired, - filename: PropTypes.string.isRequired, - filesize: PropTypes.number.isRequired, - identifier: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.number - ]).isRequired, - thumb: PropTypes.bool.isRequired - }) - ) - }).isRequired, - attachments: PropTypes.arrayOf(PropTypes.shape({ - id: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.number - ]).isRequired, - aasm_state: PropTypes.string.isRequired, - content_type: PropTypes.string.isRequired, - filename: PropTypes.string.isRequired, - filesize: PropTypes.number.isRequired, - identifier: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.number - ]).isRequired, - thumb: PropTypes.bool.isRequired - })), + wellplate: PropTypes.instanceOf(Wellplate).isRequired, + attachments: PropTypes.arrayOf(PropTypes.instanceOf(Attachment)).isRequired, onDrop: PropTypes.func.isRequired, onDelete: PropTypes.func.isRequired, onUndoDelete: PropTypes.func.isRequired, From 08efa4dd1151d21a546166728862adc9a6cc82bd Mon Sep 17 00:00:00 2001 From: Johannes Haubold Date: Wed, 25 Sep 2024 18:25:03 +0200 Subject: [PATCH 07/17] Fix PropType definitions of CustomSizeModal --- .../details/wellplates/propertiesTab/CustomSizeModal.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/packs/src/apps/mydb/elements/details/wellplates/propertiesTab/CustomSizeModal.js b/app/packs/src/apps/mydb/elements/details/wellplates/propertiesTab/CustomSizeModal.js index 7bc8078729..7e3ae93147 100644 --- a/app/packs/src/apps/mydb/elements/details/wellplates/propertiesTab/CustomSizeModal.js +++ b/app/packs/src/apps/mydb/elements/details/wellplates/propertiesTab/CustomSizeModal.js @@ -93,9 +93,9 @@ const CustomSizeModal = ({show, wellplate, updateWellplate, handleClose}) => { CustomSizeModal.propTypes = { wellplate: PropTypes.instanceOf(Wellplate).isRequired, - showCustomSizeModal: PropTypes.bool.isRequired, + show: PropTypes.bool.isRequired, handleClose: PropTypes.func.isRequired, - triggerUIUpdate: PropTypes.func.isRequired, + updateWellplate: PropTypes.func.isRequired, } export default CustomSizeModal From 7bd272afe951bba00764f4e9a5cd39fc70558640 Mon Sep 17 00:00:00 2001 From: Johannes Haubold Date: Wed, 25 Sep 2024 18:25:18 +0200 Subject: [PATCH 08/17] Add keys to options in WellplateSizeDropdown --- .../details/wellplates/propertiesTab/WellplateSizeDropdown.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/packs/src/apps/mydb/elements/details/wellplates/propertiesTab/WellplateSizeDropdown.js b/app/packs/src/apps/mydb/elements/details/wellplates/propertiesTab/WellplateSizeDropdown.js index a492b490a4..a8e152bedf 100644 --- a/app/packs/src/apps/mydb/elements/details/wellplates/propertiesTab/WellplateSizeDropdown.js +++ b/app/packs/src/apps/mydb/elements/details/wellplates/propertiesTab/WellplateSizeDropdown.js @@ -8,8 +8,9 @@ import CustomSizeModal from 'src/apps/mydb/elements/details/wellplates/propertie const Option = (width, height) => { const label = `${height * width} (${width}x${height})` const value = `${width} ${height}` + const key = `${width}x${height}` - return (