diff --git a/client/src/lib/namespace.js b/client/src/lib/namespace.js new file mode 100644 index 00000000..aeaddc7e --- /dev/null +++ b/client/src/lib/namespace.js @@ -0,0 +1,30 @@ +'use strict'; + +import React, { Component } from 'react'; +import { translate } from 'react-i18next'; +import { TreeTableSelect } from './form'; + + +@translate() +class NamespaceSelect extends Component { + render() { + const t = this.props.t; + + return ( + + ); + } +} + +function validateNamespace(t, state) { + if (!state.getIn(['namespace', 'value'])) { + state.setIn(['namespace', 'error'], t('Namespace must be selected')); + } else { + state.setIn(['namespace', 'error'], null); + } +} + +export { + NamespaceSelect, + validateNamespace +}; \ No newline at end of file diff --git a/client/src/lib/tree.js b/client/src/lib/tree.js index edfbe497..bf68d921 100644 --- a/client/src/lib/tree.js +++ b/client/src/lib/tree.js @@ -149,14 +149,14 @@ class TreeTable extends Component { updateSelection() { const tree = this.tree; if (this.selectMode === TreeSelectMode.MULTI) { - const selectSet = new Set(this.props.selection); + const selectSet = new Set(this.props.selection.map(key => this.stringifyKey(key))); tree.enableUpdate(false); tree.visit(node => node.setSelected(selectSet.has(node.key))); tree.enableUpdate(true); } else if (this.selectMode === TreeSelectMode.SINGLE) { - this.tree.activateKey(this.props.selection); + this.tree.activateKey(this.stringifyKey(this.props.selection)); } } @@ -167,9 +167,26 @@ class TreeTable extends Component { } } + stringifyKey(key) { + if (key !== null && key !== undefined) { + return key.toString(); + } else { + return key; + } + } + + destringifyKey(key) { + if (/^(\-|\+)?([0-9]+|Infinity)$/.test(key)) { + return Number(key); + } else { + return key; + } + } + // Single-select onActivate(event, data) { - const selection = this.tree.getActiveNode().key; + const selection = this.destringifyKey(this.tree.getActiveNode().key); + if (selection !== this.props.selection) { this.onSelectionChanged(selection); } @@ -177,7 +194,7 @@ class TreeTable extends Component { // Multi-select onSelect(event, data) { - const newSel = this.tree.getSelectedNodes().map(node => node.key).sort(); + const newSel = this.tree.getSelectedNodes().map(node => this.destringifyKey(node.key)).sort(); const oldSel = this.props.selection; let updated = false; diff --git a/client/src/namespaces/CUD.js b/client/src/namespaces/CUD.js index bd7277a4..00802dba 100644 --- a/client/src/namespaces/CUD.js +++ b/client/src/namespaces/CUD.js @@ -81,9 +81,7 @@ export default class CUD extends Component { @withAsyncErrorHandler async loadFormValues() { - await this.getFormValuesFromURL(`/rest/namespaces/${this.state.entityId}`, data => { - if (data.parent) data.parent = data.parent.toString(); - }); + await this.getFormValuesFromURL(`/rest/namespaces/${this.state.entityId}`); } componentDidMount() { @@ -93,7 +91,7 @@ export default class CUD extends Component { this.populateFormValues({ name: '', description: '', - parent: null + namespace: null }); } @@ -112,10 +110,10 @@ export default class CUD extends Component { } if (!this.isEditGlobal()) { - if (!state.getIn(['parent', 'value'])) { - state.setIn(['parent', 'error'], t('Parent Namespace must be selected')); + if (!state.getIn(['namespace', 'value'])) { + state.setIn(['namespace', 'error'], t('Parent Namespace must be selected')); } else { - state.setIn(['parent', 'error'], null); + state.setIn(['namespace', 'error'], null); } } } @@ -137,9 +135,7 @@ export default class CUD extends Component { this.disableForm(); this.setFormStatusMessage('info', t('Saving namespace ...')); - const submitSuccessful = await this.validateAndSendFormValuesToURL(sendMethod, url, data => { - if (data.parent) data.parent = parseInt(data.parent); - }); + const submitSuccessful = await this.validateAndSendFormValuesToURL(sendMethod, url); if (submitSuccessful) { this.navigateToWithFlashMessage('/namespaces', 'success', t('Namespace saved')); @@ -232,7 +228,7 @@ export default class CUD extends Component {