diff --git a/app/packs/src/apps/admin/textTemplates/TextTemplate.js b/app/packs/src/apps/admin/textTemplates/TextTemplate.js
deleted file mode 100644
index bedf98c426..0000000000
--- a/app/packs/src/apps/admin/textTemplates/TextTemplate.js
+++ /dev/null
@@ -1,303 +0,0 @@
-import { AgGridReact } from 'ag-grid-react';
-import { cloneDeep } from 'lodash';
-import PropTypes from 'prop-types';
-import Delta from 'quill-delta';
-import React from 'react';
-import { Button, Form, Container, Col, InputGroup, Row } from 'react-bootstrap';
-
-import QuillEditor from 'src/components/QuillEditor';
-import TextTemplateIcon from 'src/apps/admin/textTemplates/TextTemplateIcon';
-
-function RemoveRowBtn({ removeRow, node }) {
- const { data } = node;
-
- const btnClick = () => {
- removeRow(data.name);
- };
-
- return (
-
- );
-}
-
-RemoveRowBtn.propTypes = {
- removeRow: PropTypes.func.isRequired,
- // eslint-disable-next-line react/forbid-prop-types
- node: PropTypes.object.isRequired,
-};
-
-function AddRowBtn({ addRow }) {
- return (
-
- );
-}
-
-AddRowBtn.propTypes = {
- addRow: PropTypes.func.isRequired,
-};
-
-export default class TextTemplate extends React.Component {
- constructor(props) {
- super(props);
-
- this.state = {
- selectedTemplate: null,
- text: '',
- icon: ''
- };
-
- this.reactQuillRef = React.createRef();
-
- this.onSelectionChanged = this.onSelectionChanged.bind(this);
- this.onGridReady = this.onGridReady.bind(this);
- this.onCellValueChanged = this.onCellValueChanged.bind(this);
- this.onChangeText = this.onChangeText.bind(this);
- this.onChangeIcon = this.onChangeIcon.bind(this);
-
- this.saveTemplate = this.saveTemplate.bind(this);
- this.removeRow = this.removeRow.bind(this);
- this.addRow = this.addRow.bind(this);
-
- this.columnDefs = [
- {
- field: 'name',
- editable: true,
- minWidth: 150,
- onCellValueChanged: this.onCellValueChanged
- },
- {
- headerName: '',
- colId: 'actions',
- headerComponent: AddRowBtn,
- headerComponentParams: {
- addRow: this.addRow
- },
- cellRenderer: RemoveRowBtn,
- cellRendererParams: {
- removeRow: this.removeRow,
- },
- editable: false,
- filter: false,
- width: 35,
- },
- ];
- }
-
- // eslint-disable-next-line camelcase
- UNSAFE_componentWillReceiveProps(newProps) {
- const { fetchedTemplates } = newProps;
- const selectedRows = this.gridApi.getSelectedRows();
- if (selectedRows.length === 0) return;
-
- const selectedNameIdx = fetchedTemplates.findIndex(t => (
- t.name === selectedRows[0].name
- ));
- if (selectedNameIdx < 0) return;
-
- const newSelectedTemplate = cloneDeep(fetchedTemplates[selectedNameIdx]);
- this.setState({
- selectedTemplate: cloneDeep(newSelectedTemplate),
- text: newSelectedTemplate.data.text || '',
- icon: newSelectedTemplate.data.icon || ''
- });
- }
-
- componentDidUpdate() {
- if (this.gridApi) {
- this.gridApi.sizeColumnsToFit();
- }
- }
-
- // eslint-disable-next-line class-methods-use-this
- onGridReady(e) {
- if (!e.api) return;
- this.gridApi = e.api;
- this.gridApi.sizeColumnsToFit();
- }
-
- onSelectionChanged() {
- if (!this.gridApi) return;
-
- const selectedRows = this.gridApi.getSelectedRows();
- if (selectedRows.length === 0) return;
-
- const templateName = selectedRows[0].name;
- const { fetchedTemplates } = this.props;
- const selectedNameIdx = fetchedTemplates.findIndex(t => (
- t.name === templateName
- ));
-
- if (selectedNameIdx >= 0) {
- const selectedTemplate = cloneDeep(fetchedTemplates[selectedNameIdx]);
- this.setState({
- selectedTemplate,
- text: selectedTemplate.data.text || '',
- icon: selectedTemplate.data.icon || ''
- });
- } else {
- const { fetchTemplate } = this.props;
- fetchTemplate(templateName);
- }
- }
-
- onCellValueChanged(params) {
- const { oldValue, newValue } = params;
- const { fetchedTemplates, updateTemplate } = this.props;
- const selectedNameIdx = fetchedTemplates.findIndex(t => (
- t.name === oldValue
- ));
- if (selectedNameIdx < 0) return;
-
- const selectedTemplate = cloneDeep(fetchedTemplates[selectedNameIdx]);
- selectedTemplate.name = newValue;
- updateTemplate(selectedTemplate);
- }
-
- onChangeText(e) {
- const { selectedTemplate } = this.state;
- const { value } = e.target;
- selectedTemplate.data.text = value;
-
- this.setState({
- text: value,
- selectedTemplate
- });
- }
-
- onChangeIcon(e) {
- const { selectedTemplate } = this.state;
- const { value } = e.target;
- selectedTemplate.data.icon = value;
-
- this.setState({ icon: value, selectedTemplate });
- }
-
- saveTemplate() {
- if (this.reactQuillRef.current == null) {
- return;
- }
-
- const quill = this.reactQuillRef.current;
- const delta = quill.getContents();
-
- // Quill automatically append a trailing newline, we don't want that
- // Remove it !!!
- const deltaLength = delta.length();
- const removeTrailingNewline = new Delta().retain(deltaLength - 1).delete(1);
- const content = delta.compose(removeTrailingNewline);
-
- const selectedTemplate = cloneDeep(this.state.selectedTemplate);
- selectedTemplate.data.ops = content.ops;
- this.props.updateTemplate(selectedTemplate);
- }
-
- removeRow(name) {
- const { removeTemplate } = this.props;
- removeTemplate(name);
- this.setState({ selectedTemplate: null });
- }
-
- addRow() {
- const { addTemplate } = this.props;
- addTemplate(this.gridApi);
- }
-
- handleInputChange = () => {}
-
- render() {
- const { predefinedTemplateNames } = this.props;
- const { selectedTemplate, text, icon } = this.state;
-
- return (
-
-
-
-
-
-
-
-
- Preview
-
-
-
- Text
- {}}
- className='py-3'
- />
-
-
- Icon
- {}}
- className='py-3'
- />
-
-
- this.handleInputChange(event)}
- />
-
-
-
-
-
-
-
- );
- }
-}
-
-TextTemplate.propTypes = {
- predefinedTemplateNames: PropTypes.arrayOf(PropTypes.object),
- // eslint-disable-next-line react/forbid-prop-types
- fetchedTemplates: PropTypes.arrayOf(PropTypes.object),
- fetchTemplate: PropTypes.func.isRequired,
- addTemplate: PropTypes.func.isRequired,
- updateTemplate: PropTypes.func.isRequired,
- removeTemplate: PropTypes.func.isRequired,
-};
-
-TextTemplate.defaultProps = {
- predefinedTemplateNames: [],
- fetchedTemplates: [],
-};
diff --git a/app/packs/src/apps/admin/textTemplates/TextTemplateContainer.js b/app/packs/src/apps/admin/textTemplates/TextTemplateContainer.js
index 1cf6aabbb1..4a56e1ed06 100644
--- a/app/packs/src/apps/admin/textTemplates/TextTemplateContainer.js
+++ b/app/packs/src/apps/admin/textTemplates/TextTemplateContainer.js
@@ -1,103 +1,158 @@
import React from 'react';
+import { Container, Col, Row } from 'react-bootstrap';
+
import TextTemplatesFetcher from 'src/fetchers/TextTemplatesFetcher';
-import TextTemplate from 'src/apps/admin/textTemplates/TextTemplate';
+import TextTemplateForm from 'src/apps/admin/textTemplates/TextTemplateForm';
+import TextTemplateSelector from 'src/apps/admin/textTemplates/TextTemplateSelector';
+
export default class TextTemplateContainer extends React.Component {
constructor(props) {
super(props);
this.state = {
- predefinedTemplateNames: [],
- fetchedTemplates: [],
+ templateNames: [],
+ fetchedTemplates: {},
+ selectedTemplateName: null,
};
this.addTemplate = this.addTemplate.bind(this);
- this.fetchTemplate = this.fetchTemplate.bind(this);
+ this.renameTemplate = this.renameTemplate.bind(this);
this.removeTemplate = this.removeTemplate.bind(this);
this.updateTemplate = this.updateTemplate.bind(this);
+ this.selectTemplate = this.selectTemplate.bind(this);
}
componentDidMount() {
TextTemplatesFetcher.fetchPredefinedTemplateNames().then((res) => {
- const templateNames = res.map(n => ({ name: n }));
- this.setState({ predefinedTemplateNames: templateNames });
+ this.setState({ templateNames: res });
});
}
addTemplate(gridApi) {
- const { predefinedTemplateNames, fetchedTemplates } = this.state;
+ const { templateNames, fetchedTemplates } = this.state;
this.setState({
- predefinedTemplateNames: [{ name: '' }, ...predefinedTemplateNames],
- fetchedTemplates: [
- { name: '', data: {} },
- ...fetchedTemplates
- ]
+ templateNames: ['', ...templateNames],
+ fetchedTemplates: {
+ ...fetchedTemplates,
+ '': { name: '', data: {} },
+ },
+ selectedTemplateName: '',
}, () => {
- if (!gridApi) return;
-
- gridApi.startEditingCell({ rowIndex: 0, colKey: 'name' });
+ if (gridApi) {
+ gridApi.startEditingCell({ rowIndex: 0, colKey: 'name' });
+ }
});
}
- fetchTemplate(name) {
- TextTemplatesFetcher.fetchPredefinedTemplateByNames([name]).then((res) => {
+ selectTemplate(name) {
+ const { fetchedTemplates, selectedTemplateName } = this.state;
+ if (name === selectedTemplateName && fetchedTemplates[name]) return;
+
+ if (fetchedTemplates[name]) {
+ this.setState({ selectedTemplateName: name });
+ } else {
+ TextTemplatesFetcher.fetchPredefinedTemplateByNames([name]).then((res) => {
+ if (!res) return;
+
+ const newTemplates = {};
+ res.forEach((r) => newTemplates[r.name] = r);
+
+ this.setState({
+ fetchedTemplates: {
+ ...fetchedTemplates,
+ ...newTemplates,
+ },
+ selectedTemplateName: name,
+ });
+ });
+ }
+ }
+
+ removeTemplate(name) {
+ TextTemplatesFetcher.deletePredefinedTemplateByName(name).then((res) => {
if (!res) return;
- const { fetchedTemplates } = this.state;
+ const { templateNames, fetchedTemplates, selectedTemplateName } = this.state;
+ const newFetchedTemplates = { ...fetchedTemplates };
+ delete newFetchedTemplates[name];
+
this.setState({
- fetchedTemplates: [...fetchedTemplates].concat(res),
+ templateNames: templateNames.filter((n) => n !== name),
+ fetchedTemplates: newFetchedTemplates,
+ selectedTemplateName: selectedTemplateName === name ? null : selectedTemplateName,
});
});
}
- removeTemplate(name) {
- TextTemplatesFetcher.deletePredefinedTemplateByName(name).then((res) => {
+ renameTemplate(oldName, newName) {
+ const { templateNames, fetchedTemplates, selectedTemplateName } = this.state;
+ const template = fetchedTemplates[oldName];
+
+ const newTemplate = {...template, name: newName};
+ const newFetchedTemplates = { ...fetchedTemplates, [newName]: newTemplate };
+ delete newFetchedTemplates[oldName];
+
+ TextTemplatesFetcher.updatePredefinedTemplates(newTemplate).then((res) => {
if (!res) return;
- const { fetchedTemplates, predefinedTemplateNames } = this.state;
this.setState({
- fetchedTemplates: fetchedTemplates.filter(t => t.name !== name),
- predefinedTemplateNames: predefinedTemplateNames.filter(t => (
- t.name !== name
- ))
+ templateNames: templateNames.with(templateNames.indexOf(oldName), newName),
+ fetchedTemplates: newFetchedTemplates,
+ selectedTemplateName: selectedTemplateName === oldName ? newName : selectedTemplateName,
});
});
}
updateTemplate(template) {
const { fetchedTemplates } = this.state;
- const selectedNameIdx = fetchedTemplates.findIndex(t => (
- t.id === template.id
- ));
- if (selectedNameIdx < 0) return;
-
TextTemplatesFetcher.updatePredefinedTemplates(template).then((res) => {
if (!res) return;
- const newTemplates = fetchedTemplates.map((t, idx) => (
- (idx === selectedNameIdx) ? res : t
- ));
- this.setState({ fetchedTemplates: newTemplates });
+ this.setState({
+ fetchedTemplates: {
+ ...fetchedTemplates,
+ [template.name]: template
+ }
+ });
});
}
render() {
const {
- predefinedTemplateNames,
+ templateNames,
fetchedTemplates,
+ selectedTemplateName,
} = this.state;
+ const selectedTemplate = fetchedTemplates[selectedTemplateName];
+
return (
-
+
+
+
+
+
+
+ {selectedTemplate ? (
+
+ ) : (
+ Select a template to edit
+ )}
+
+
+
);
}
}
diff --git a/app/packs/src/apps/admin/textTemplates/TextTemplateForm.js b/app/packs/src/apps/admin/textTemplates/TextTemplateForm.js
new file mode 100644
index 0000000000..a94e23966d
--- /dev/null
+++ b/app/packs/src/apps/admin/textTemplates/TextTemplateForm.js
@@ -0,0 +1,129 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import Delta from 'quill-delta';
+import { Button, Form, InputGroup } from 'react-bootstrap';
+
+import QuillEditor from 'src/components/QuillEditor';
+import TextTemplateIcon from 'src/apps/admin/textTemplates/TextTemplateIcon';
+
+
+export default class TextTemplateForm extends React.Component {
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ text: props.selectedTemplate?.data?.text ?? '',
+ icon: props.selectedTemplate?.data?.icon ?? '',
+ };
+
+ this.reactQuillRef = React.createRef();
+
+ this.onChangeText = this.onChangeText.bind(this);
+ this.onChangeIcon = this.onChangeIcon.bind(this);
+ this.saveTemplate = this.saveTemplate.bind(this);
+
+ }
+
+ componentDidUpdate(prevProps) {
+ const { selectedTemplate } = this.props;
+ if (selectedTemplate !== prevProps.selectedTemplate) {
+ this.setState({
+ text: selectedTemplate?.data?.text ?? '',
+ icon: selectedTemplate?.data?.icon ?? '',
+ });
+ }
+ }
+
+ onChangeText(e) {
+ const { value } = e.target;
+ this.setState({ text: value });
+ }
+
+ onChangeIcon(e) {
+ const { value } = e.target;
+ this.setState({ icon: value });
+ }
+
+ saveTemplate() {
+ if (this.reactQuillRef.current == null) {
+ return;
+ }
+
+ const quill = this.reactQuillRef.current;
+ const delta = quill.getContents();
+
+ // Quill automatically append a trailing newline, we don't want that
+ // Remove it !!!
+ const deltaLength = delta.length();
+ const removeTrailingNewline = new Delta().retain(deltaLength - 1).delete(1);
+ const { ops } = delta.compose(removeTrailingNewline);
+
+ const { selectedTemplate, updateTemplate } = this.props;
+ const { text, icon } = this.state;
+ updateTemplate({
+ ...selectedTemplate,
+ data: {
+ ops,
+ text: text.trim() == '' ? null : text.trim(),
+ icon: icon.trim() == '' ? null : icon.trim(),
+ }
+ });
+ }
+
+ render() {
+ const { selectedTemplate } = this.props;
+ const { text, icon } = this.state;
+
+ return (
+
+
Editing '{selectedTemplate.name}'
+
+ Preview
+
+
+
+ Text
+
+
+
+ Icon
+
+
+
+ {}}
+ />
+
+
+
+
+ );
+ }
+}
+
+TextTemplateForm.propTypes = {
+ selectedTemplate: PropTypes.object,
+ updateTemplate: PropTypes.func.isRequired,
+};
+
+TextTemplateForm.defaultProps = {
+ selectedTemplate: null,
+};
diff --git a/app/packs/src/apps/admin/textTemplates/TextTemplateIcon.js b/app/packs/src/apps/admin/textTemplates/TextTemplateIcon.js
index 6766e368e7..3f3736a947 100644
--- a/app/packs/src/apps/admin/textTemplates/TextTemplateIcon.js
+++ b/app/packs/src/apps/admin/textTemplates/TextTemplateIcon.js
@@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
const TextTemplateIcon = ({ template, iconClass }) => {
- if (!template) return ;
+ if (!template) return null;
const { data, name } = template;
@@ -12,7 +12,7 @@ const TextTemplateIcon = ({ template, iconClass }) => {
);
}
- const text = (data || {}).text || name;
+ const text = data?.text ?? name ?? '';
return (
{text.toUpperCase()}
diff --git a/app/packs/src/apps/admin/textTemplates/TextTemplateSelector.js b/app/packs/src/apps/admin/textTemplates/TextTemplateSelector.js
new file mode 100644
index 0000000000..2863a21868
--- /dev/null
+++ b/app/packs/src/apps/admin/textTemplates/TextTemplateSelector.js
@@ -0,0 +1,128 @@
+import React, { Component } from 'react'
+import PropTypes from 'prop-types';
+import { Button } from 'react-bootstrap';
+import { AgGridReact } from 'ag-grid-react';
+
+function RemoveRowBtn({ removeRow, node }) {
+ const { data } = node;
+
+ const btnClick = () => {
+ removeRow(data.name);
+ };
+
+ return (
+
+ );
+}
+
+RemoveRowBtn.propTypes = {
+ removeRow: PropTypes.func.isRequired,
+ // eslint-disable-next-line react/forbid-prop-types
+ node: PropTypes.object.isRequired,
+};
+
+function AddRowBtn({ addRow }) {
+ return (
+
+ );
+}
+
+AddRowBtn.propTypes = {
+ addRow: PropTypes.func.isRequired,
+};
+
+class TextTemplateSelector extends Component {
+ constructor(props) {
+ super(props);
+ }
+
+ componentDidMount() {
+ this.gridApi?.sizeColumnsToFit()
+ }
+
+ componentDidUpdate() {
+ this.gridApi?.sizeColumnsToFit()
+ }
+
+ onSelectionChanged = ({api}) => {
+ const selectedRows = api.getSelectedRows();
+ if (selectedRows.length === 0) return;
+
+ const { selectTemplate } = this.props;
+ selectTemplate(selectedRows[0].name);
+ }
+
+ onGridReady = ({api}) => {
+ this.gridApi = api;
+ }
+
+ render() {
+ const {
+ templateNames,
+ addTemplate,
+ renameTemplate,
+ removeTemplate
+ } = this.props;
+
+ const columnDefs = [
+ {
+ field: 'name',
+ editable: true,
+ minWidth: 150,
+ onCellValueChanged: ({ oldValue, newValue }) => {
+ renameTemplate(oldValue, newValue);
+ }
+ },
+ {
+ headerName: '',
+ colId: 'actions',
+ headerComponent: AddRowBtn,
+ headerComponentParams: {
+ addRow: addTemplate,
+ },
+ cellRenderer: RemoveRowBtn,
+ cellRendererParams: {
+ removeRow: removeTemplate,
+ },
+ editable: false,
+ filter: false,
+ width: 35,
+ },
+ ];
+
+ return (
+
+
+
({ name: n }))}
+ className='fs-6'
+ rowHeight={35}
+ />
+
+
+ );
+ }
+};
+
+export default TextTemplateSelector;
diff --git a/app/packs/src/apps/mydb/collections/CollectionSubtree.js b/app/packs/src/apps/mydb/collections/CollectionSubtree.js
index 17b6486487..90588b3187 100644
--- a/app/packs/src/apps/mydb/collections/CollectionSubtree.js
+++ b/app/packs/src/apps/mydb/collections/CollectionSubtree.js
@@ -15,11 +15,7 @@ export default class CollectionSubtree extends React.Component {
super(props);
this.state = {
- isRemote: props.isRemote,
- label: props.root.label,
- inventoryPrefix: props.root.inventory_prefix,
selected: false,
- root: props.root,
visible: false
}
@@ -29,48 +25,31 @@ export default class CollectionSubtree extends React.Component {
this.handleTakeOwnership = this.handleTakeOwnership.bind(this)
}
-
componentDidMount() {
UIStore.listen(this.onChange);
}
- // eslint-disable-next-line camelcase
- UNSAFE_componentWillReceiveProps(nextProps) {
- this.setState({
- root: nextProps.root,
- label: nextProps.root.label,
- inventoryPrefix: nextProps.root.inventory_prefix
- });
- }
-
componentWillUnmount() {
UIStore.unlisten(this.onChange);
}
onChange(state) {
- if (state.currentCollection) {
- const visible = this.isVisible(this.state.root, state)
- const { root } = this.state;
+ const { root } = this.props;
+ if (state.currentCollection) {
+ const visible = this.isVisible(root, state)
const selectedCol = (
- state.currentCollection.id == root.id &&
- state.currentCollection.is_synchronized == root.is_synchronized
- ) || (
- state.currentCollection.id == root.id &&
- state.currentCollection.isRemote == root.isRemote
+ state.currentCollection.id == root.id
+ && (
+ state.currentCollection.is_synchronized == root.is_synchronized
+ || state.currentCollection.isRemote == root.isRemote
)
+ );
- if (selectedCol) {
- this.setState({
- selected: true,
- visible
- });
- } else {
- this.setState({
- selected: false,
+ this.setState({
+ selected: selectedCol,
visible
- });
- }
+ });
}
}
@@ -85,68 +64,58 @@ export default class CollectionSubtree extends React.Component {
}
children() {
- return this.state.root.children || [];
- }
-
- hasChildren() {
- return this.children().length > 0;
+ const { root } = this.props;
+ return root.children || [];
}
canTakeOwnership() {
- const { root, isRemote } = this.state;
+ const { root, isRemote } = this.props;
const isTakeOwnershipAllowed = root.permission_level === 5;
const isSync = !!((root.sharer && root.user && root.user.type !== 'Group'));
return (isRemote || isSync) && isTakeOwnershipAllowed;
}
handleTakeOwnership() {
- const { root: { sharer, id } } = this.state;
+ const { root: { sharer, id } } = this.props;
const isSync = !!sharer;
CollectionActions.takeOwnership({ id, isSync });
}
handleClick(e) {
- const { fakeRoot } = this.props;
- if (fakeRoot) {
- e.stopPropagation();
- return;
- }
-
- const { root } = this.state;
- let { visible } = this.state;
+ const { root } = this.props;
+ const { visible } = this.state;
const uiState = UIStore.getState();
+ this.setState({ visible: visible || this.isVisible(root, uiState) });
- visible = visible || this.isVisible(root, uiState);
- this.setState({ visible });
- let collectionID = 'all';
if (root.label === 'All' && root.is_locked) {
Aviator.navigate(`/collection/all/${this.urlForCurrentElement()}`, { silent: true });
- collectionShow({ params: { collectionID } });
+ collectionShow({ params: { collectionID: 'all' } });
return;
}
- const url = (this.props.root.sharer)
+
+ const url = (root.sharer)
? `/scollection/${root.id}/${this.urlForCurrentElement()}`
: `/collection/${root.id}/${this.urlForCurrentElement()}`;
Aviator.navigate(url, { silent: true });
- collectionID = this.state.root.id;
- const collShow = this.props.root.sharer ? scollectionShow : collectionShow;
- collShow({ params: { collectionID } });
+
+ const collShow = root.sharer ? scollectionShow : collectionShow;
+ collShow({ params: { collectionID: root.id } });
}
urlForCurrentElement() {
const { currentElement } = ElementStore.getState();
if (currentElement) {
- if (currentElement.isNew) {
- return `${currentElement.type}/new`;
- }
- return `${currentElement.type}/${currentElement.id}`;
+ return currentElement.isNew
+ ? `${currentElement.type}/new`
+ : `${currentElement.type}/${currentElement.id}`;
}
return '';
}
toggleExpansion(e) {
e.stopPropagation()
- let { visible, root } = this.state
+ const { root } = this.props;
+ let { visible } = this.state
visible = !visible
this.setState({ visible: visible })
@@ -156,7 +125,7 @@ export default class CollectionSubtree extends React.Component {
} else {
let descendantIds = root.descendant_ids
? root.descendant_ids
- : root.children.map(function (s) { return s.id })
+ : root.children.map((s) => s.id);
descendantIds.push(root.id)
visibleRootsIds = visibleRootsIds.filter(x => descendantIds.indexOf(x) == -1)
}
@@ -167,11 +136,12 @@ export default class CollectionSubtree extends React.Component {
}
render() {
- const { label, root, inventoryPrefix, visible, selected } = this.state;
+ const { root, isRemote } = this.props;
+ const { visible, selected } = this.state;
const sharedUsers = root.sync_collections_users;
const children = this.children();
- const showGatePushButton = root && root.is_locked && label === 'chemotion-repository.net';
+ const showGatePushButton = root && root.is_locked && root.label === 'chemotion-repository.net';
return (
@@ -181,13 +151,13 @@ export default class CollectionSubtree extends React.Component {
onClick={this.handleClick}
>
{showGatePushButton && (
)}
-
{label}
- {inventoryPrefix && (
+
{root.label}
+ {root.inventory_prefix && (
Inventory Label}
>
- {inventoryPrefix}
+ {root.inventory_prefix}
)}
{this.canTakeOwnership() && (
@@ -201,7 +171,7 @@ export default class CollectionSubtree extends React.Component {
)}
- {this.hasChildren() && (
+ {children.length > 0 && (
{children.map((child) => (
-
+
))}
diff --git a/app/packs/src/apps/mydb/elements/details/NumeralInput.js b/app/packs/src/apps/mydb/elements/details/NumeralInput.js
index d789bce3b5..30a007dd86 100644
--- a/app/packs/src/apps/mydb/elements/details/NumeralInput.js
+++ b/app/packs/src/apps/mydb/elements/details/NumeralInput.js
@@ -13,12 +13,13 @@ export default class NumeralInput extends Component {
};
}
- // eslint-disable-next-line camelcase
- UNSAFE_componentWillReceiveProps(nextProps) {
- const { value } = nextProps;
- this.setState({
- numeralValue: this._convertValueToNumeralValue(value)
- });
+ componentDidUpdate(prevProps) {
+ const { value } = this.props;
+ if (value !== prevProps.value) {
+ this.setState({
+ numeralValue: this._convertValueToNumeralValue(value)
+ });
+ }
}
_convertValueToNumeralValue(value) {
diff --git a/app/packs/src/apps/mydb/elements/details/NumeralInputWithUnitsCompo.js b/app/packs/src/apps/mydb/elements/details/NumeralInputWithUnitsCompo.js
index 5f29f7edb7..e1bc89da43 100644
--- a/app/packs/src/apps/mydb/elements/details/NumeralInputWithUnitsCompo.js
+++ b/app/packs/src/apps/mydb/elements/details/NumeralInputWithUnitsCompo.js
@@ -1,5 +1,6 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
+import { isEqual } from 'lodash';
import { Form, InputGroup, Button } from 'react-bootstrap';
import { metPreConv, metPrefSymbols } from 'src/utilities/metricPrefix';
@@ -22,9 +23,12 @@ export default class NumeralInputWithUnitsCompo extends Component {
this.forceUpdate();
}
- UNSAFE_componentWillReceiveProps(nextProps) {
- const { value, block } = nextProps;
- this.setState({ value, block });
+ componentDidUpdate(prevProps) {
+ const { value, block } = this.props;
+ // isEqual considers NaN to be equal to NaN
+ if (!isEqual(value, prevProps.value) || block !== prevProps.block) {
+ this.setState({ value, block });
+ }
}
shouldComponentUpdate(nextProps, nextState) {
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..165ea1f7cc 100644
--- a/app/packs/src/apps/mydb/elements/details/reactions/ReactionDetails.js
+++ b/app/packs/src/apps/mydb/elements/details/reactions/ReactionDetails.js
@@ -96,20 +96,13 @@ export default class ReactionDetails extends Component {
}
}
- // eslint-disable-next-line camelcase
- UNSAFE_componentWillReceiveProps(nextProps) {
- const { reaction } = this.state;
- const nextReaction = nextProps.reaction;
-
- if (nextReaction.id !== reaction.id ||
- nextReaction.updated_at !== reaction.updated_at ||
- nextReaction.reaction_svg_file !== reaction.reaction_svg_file ||
- nextReaction.changed || nextReaction.editedSample) {
- this.setState(prevState => ({ ...prevState, reaction: nextReaction }));
+ componentDidUpdate(prevProps) {
+ const { reaction } = this.props;
+ if (reaction.id !== prevProps.reaction.id) {
+ this.setState({ reaction });
}
}
-
shouldComponentUpdate(nextProps, nextState) {
const reactionFromNextProps = nextProps.reaction;
const reactionFromNextState = nextState.reaction;
diff --git a/app/packs/src/apps/mydb/elements/details/reactions/ReactionDetailsMainProperties.js b/app/packs/src/apps/mydb/elements/details/reactions/ReactionDetailsMainProperties.js
index 404c8beb84..150cc39938 100644
--- a/app/packs/src/apps/mydb/elements/details/reactions/ReactionDetailsMainProperties.js
+++ b/app/packs/src/apps/mydb/elements/details/reactions/ReactionDetailsMainProperties.js
@@ -20,30 +20,18 @@ import { permitOn } from 'src/components/common/uis';
export default class ReactionDetailsMainProperties extends Component {
constructor(props) {
super(props);
- const { temperature } = props && props.reaction;
+
this.state = {
showTemperatureChart: false,
- temperature,
};
+
this.toggleTemperatureChart = this.toggleTemperatureChart.bind(this);
this.updateTemperature = this.updateTemperature.bind(this);
- this.temperatureUnit = props.reaction.temperature.valueUnit;
- }
-
- // eslint-disable-next-line camelcase
- UNSAFE_componentWillReceiveProps(nextProps) {
- this.setState({
- temperature: nextProps.reaction.temperature,
- });
-
- this.temperatureUnit = nextProps.reaction.temperature.valueUnit;
}
updateTemperature(newData) {
- const { temperature } = this.state;
- temperature.data = newData;
- this.setState({ temperature });
- this.props.onInputChange('temperatureData', temperature);
+ const { reaction: { temperature } } = this.props;
+ this.props.onInputChange('temperatureData', { ...temperature, data: newData });
}
toggleTemperatureChart() {
@@ -52,42 +40,18 @@ export default class ReactionDetailsMainProperties extends Component {
}
changeUnit() {
- const index = Reaction.temperature_unit.indexOf(this.temperatureUnit);
- const unit = Reaction.temperature_unit[(index + 1) % 3];
+ const { reaction: { temperature } } = this.props;
+
+ const units = Reaction.temperature_unit;
+ const index = units.indexOf(temperature.valueUnit);
+ const unit = units[(index + 1) % units.length];
this.props.onInputChange('temperatureUnit', unit);
}
-
render() {
const { reaction, onInputChange } = this.props;
- const temperatureTooltip = (
- Show temperature chart
- );
-
- const temperatureDisplay = reaction.temperature_display;
- const { showTemperatureChart, temperature } = this.state;
- const tempUnitLabel = `Temperature (${this.temperatureUnit})`;
-
- let TempChartRow = ;
- if (showTemperatureChart) {
- TempChartRow = (
-
-
-
-
-
-
-
-
- );
- }
+ const { temperature } = reaction;
+ const { showTemperatureChart } = this.state;
return (
<>
@@ -126,7 +90,9 @@ export default class ReactionDetailsMainProperties extends Component {
Temperature
-
+ Show temperature chart
+ )}>
-
- {TempChartRow}
-
+
+ {showTemperatureChart && (
+
+
+
+
+
+
+
+
+ )}
>
);
}
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 d6814949dd..02af5d1b52 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
@@ -60,15 +60,13 @@ const nmrMsg = (reaction, container) => {
export default class ReactionDetailsContainers extends Component {
constructor(props) {
- super();
- const { reaction } = props;
+ super(props);
+
this.state = {
- reaction,
activeContainer: UIStore.getState().reaction.activeAnalysis
};
this.containerRefs = {};
- this.handleChange = this.handleChange.bind(this);
this.handleAdd = this.handleAdd.bind(this);
this.handleRemove = this.handleRemove.bind(this);
this.handleUndo = this.handleUndo.bind(this);
@@ -100,16 +98,8 @@ export default class ReactionDetailsContainers extends Component {
}
}
- // eslint-disable-next-line camelcase
- UNSAFE_componentWillReceiveProps(nextProps) {
- this.setState({
- reaction: nextProps.reaction,
- });
- }
-
handleChange = () => {
- const { handleReactionChange } = this.props;
- const { reaction } = this.state;
+ const { reaction, handleReactionChange } = this.props;
handleReactionChange(reaction);
};
@@ -120,15 +110,13 @@ export default class ReactionDetailsContainers extends Component {
}
handleUndo(container) {
- const { handleReactionChange } = this.props;
- const { reaction } = this.state;
+ const { reaction, handleReactionChange } = this.props;
container.is_deleted = false;
handleReactionChange(reaction, { schemaChanged: false });
}
handleAdd() {
- const { handleReactionChange } = this.props;
- const { reaction } = this.state;
+ const { reaction, handleReactionChange } = this.props;
const container = Container.buildEmpty();
container.container_type = 'analysis';
container.extended_metadata.content = { ops: [{ insert: '' }] };
@@ -218,9 +206,7 @@ export default class ReactionDetailsContainers extends Component {
handleRemove(container) {
- const { handleReactionChange } = this.props;
- const { reaction } = this.state;
-
+ const { reaction, handleReactionChange } = this.props;
container.is_deleted = true;
handleReactionChange(reaction, { schemaChanged: false });
}
@@ -249,8 +235,8 @@ export default class ReactionDetailsContainers extends Component {
}
render() {
- const { reaction, activeContainer } = this.state;
- const { readOnly } = this.props;
+ const { activeContainer } = this.state;
+ const { reaction, readOnly } = this.props;
const containerHeader = (container) => {
let kind = container.extended_metadata.kind || '';
@@ -371,7 +357,9 @@ export default class ReactionDetailsContainers extends Component {
>
- {container.is_deleted ? containerHeaderDeleted(container) : containerHeader(container)}
+ {container.is_deleted
+ ? containerHeaderDeleted(container)
+ : containerHeader(container)}
diff --git a/app/packs/src/apps/mydb/elements/details/reactions/propertiesTab/ReactionDetailsProperties.js b/app/packs/src/apps/mydb/elements/details/reactions/propertiesTab/ReactionDetailsProperties.js
index 5895b61eea..c763996dec 100644
--- a/app/packs/src/apps/mydb/elements/details/reactions/propertiesTab/ReactionDetailsProperties.js
+++ b/app/packs/src/apps/mydb/elements/details/reactions/propertiesTab/ReactionDetailsProperties.js
@@ -16,18 +16,11 @@ import { EditUserLabels } from 'src/components/UserLabels';
export default class ReactionDetailsProperties extends Component {
constructor(props) {
super(props);
- props.reaction.convertDurationDisplay();
this.handleOnReactionChange = this.handleOnReactionChange.bind(this);
this.handleOnSolventSelect = this.handleOnSolventSelect.bind(this);
}
- // eslint-disable-next-line camelcase
- UNSAFE_componentWillReceiveProps(nextProps) {
- if (!nextProps.reaction) { return; }
- nextProps.reaction.convertDurationDisplay();
- }
-
handleOnReactionChange(reaction) {
this.props.onReactionChange(reaction);
}
diff --git a/app/packs/src/apps/mydb/elements/details/reactions/schemeTab/ReactionDetailsDuration.js b/app/packs/src/apps/mydb/elements/details/reactions/schemeTab/ReactionDetailsDuration.js
index 38177dde7d..f4dab39dd6 100644
--- a/app/packs/src/apps/mydb/elements/details/reactions/schemeTab/ReactionDetailsDuration.js
+++ b/app/packs/src/apps/mydb/elements/details/reactions/schemeTab/ReactionDetailsDuration.js
@@ -8,18 +8,11 @@ import { copyToClipboard } from 'src/utilities/clipboard';
export default class ReactionDetailsDuration extends Component {
constructor(props) {
super(props);
- props.reaction.convertDurationDisplay();
this.setCurrentTime = this.setCurrentTime.bind(this);
this.copyToDuration = this.copyToDuration.bind(this);
this.handleDurationChange = this.handleDurationChange.bind(this);
}
- // eslint-disable-next-line camelcase
- UNSAFE_componentWillReceiveProps(nextProps) {
- if (!nextProps.reaction) { return; }
- nextProps.reaction.convertDurationDisplay();
- }
-
setCurrentTime(type) {
const currentTime = new Date().toLocaleString('en-GB').split(', ').join(' ');
const { reaction } = this.props;
diff --git a/app/packs/src/apps/mydb/elements/details/reactions/schemeTab/ReactionDetailsScheme.js b/app/packs/src/apps/mydb/elements/details/reactions/schemeTab/ReactionDetailsScheme.js
index c10c2b3d89..61a3c780a4 100644
--- a/app/packs/src/apps/mydb/elements/details/reactions/schemeTab/ReactionDetailsScheme.js
+++ b/app/packs/src/apps/mydb/elements/details/reactions/schemeTab/ReactionDetailsScheme.js
@@ -40,11 +40,8 @@ export default class ReactionDetailsScheme extends Component {
constructor(props) {
super(props);
- const { reaction } = props;
-
const textTemplate = TextTemplateStore.getState().reactionDescription;
this.state = {
- reaction,
lockEquivColumn: false,
reactionDescTemplate: textTemplate.toJS(),
};
@@ -76,12 +73,6 @@ export default class ReactionDetailsScheme extends Component {
TextTemplateActions.fetchTextTemplates('reactionDescription');
}
- // eslint-disable-next-line camelcase
- UNSAFE_componentWillReceiveProps(nextProps) {
- const { reaction } = nextProps;
- this.setState({ reaction });
- }
-
componentWillUnmount() {
TextTemplateStore.unlisten(this.handleTemplateChange);
this.resetGasPhaseStore();
@@ -93,7 +84,7 @@ export default class ReactionDetailsScheme extends Component {
}
dropSample(srcSample, tagMaterial, tagGroup, extLabel, isNewSample = false) {
- const { reaction } = this.state;
+ const { reaction } = this.props;
let splitSample;
if (srcSample instanceof Molecule || isNewSample) {
@@ -165,11 +156,12 @@ export default class ReactionDetailsScheme extends Component {
}
renderRoleSelect() {
- const { role } = this.props.reaction;
+ const { reaction } = this.props;
+ const { role } = reaction;
return (