X-Git-Url: https://osm.etsi.org/gitweb/?p=osm%2FUI.git;a=blobdiff_plain;f=skyquake%2Fplugins%2Fcomposer%2Fsrc%2Fsrc%2Fcomponents%2FEditDescriptorModelProperties.js;h=c923ede7f8b7e85278c9fef63fe3d9c45421006c;hp=b3d8afb2bd5003cee44d154dec373365c625fa9f;hb=e7e6cea47fc7334220eeec6197d49601dddbc45f;hpb=4acb70df4b726b59822ea1c9296fce9a717f0b7c diff --git a/skyquake/plugins/composer/src/src/components/EditDescriptorModelProperties.js b/skyquake/plugins/composer/src/src/components/EditDescriptorModelProperties.js index b3d8afb2b..c923ede7f 100644 --- a/skyquake/plugins/composer/src/src/components/EditDescriptorModelProperties.js +++ b/skyquake/plugins/composer/src/src/components/EditDescriptorModelProperties.js @@ -20,9 +20,15 @@ * * This class generates the form fields used to edit the CONFD JSON model. */ -'use strict'; -import _ from 'lodash' +import _includes from 'lodash/includes' +import _isArray from 'lodash/isArray' +import _cloneDeep from 'lodash/cloneDeep' +import _debounce from 'lodash/debounce'; +import _uniqueId from 'lodash/uniqueId'; +import _set from 'lodash/set'; +import _get from 'lodash/get'; +import _has from 'lodash/has'; import utils from '../libraries/utils' import React from 'react' import ClassNames from 'classnames' @@ -46,13 +52,23 @@ import imgRemove from '../../../node_modules/open-iconic/svg/trash.svg' import '../styles/EditDescriptorModelProperties.scss' +const EMPTY_LEAF_PRESENT = '--empty-leaf-set--'; + +function resolveReactKey(value) { + const keyPath = ['uiState', 'fieldKey']; + if (!_has(value, keyPath)) { + _set(value, keyPath, _uniqueId()); + } + return _get(value, keyPath); +} + function getDescriptorMetaBasicForType(type) { - const basicPropertiesFilter = d => _.includes(DESCRIPTOR_MODEL_FIELDS[type], d.name); + const basicPropertiesFilter = d => _includes(DESCRIPTOR_MODEL_FIELDS[type], d.name); return DescriptorModelMetaFactory.getModelMetaForType(type, basicPropertiesFilter) || {properties: []}; } function getDescriptorMetaAdvancedForType(type) { - const advPropertiesFilter = d => !_.includes(DESCRIPTOR_MODEL_FIELDS[type], d.name); + const advPropertiesFilter = d => !_includes(DESCRIPTOR_MODEL_FIELDS[type], d.name); return DescriptorModelMetaFactory.getModelMetaForType(type, advPropertiesFilter) || {properties: []}; } @@ -136,7 +152,10 @@ export default function EditDescriptorModelProperties(props) { create(model, path, property); } else { const name = path.join('.'); - const value = Property.createModelInstance(property); + // get a unique name for the new list item based on the current list content + // some lists, based on the key, may not get a uniqueName generated here + const uniqueName = DescriptorModelMetaFactory.generateItemUniqueName(container.model[property.name], property); + const value = Property.createModelInstance(property, uniqueName); utils.assignPathValue(this.model, name, value); } CatalogItemsActions.catalogItemDescriptorChanged(this.getRoot()); @@ -163,31 +182,43 @@ export default function EditDescriptorModelProperties(props) { ); } - function onFormFieldValueChanged(event) { - if (DescriptorModelFactory.isContainer(this)) { - event.preventDefault(); - const name = event.target.name; - const value = event.target.value; - utils.assignPathValue(this.model, name, value); - CatalogItemsActions.catalogItemDescriptorChanged(this.getRoot()); - } - } - function buildField(container, property, path, value, fieldKey) { let cds = CatalogDataStore; let catalogs = cds.getTransientCatalogs(); - const name = path.join('.'); + const pathToProperty = path.join('.'); const isEditable = true; const isGuid = Property.isGuid(property); const isBoolean = Property.isBoolean(property); - const onChange = onFormFieldValueChanged.bind(container); const isEnumeration = Property.isEnumeration(property); const isLeafRef = Property.isLeafRef(property); const onFocus = onFocusPropertyFormInputElement.bind(container, property, path, value); const placeholder = changeCase.title(property.name); const className = ClassNames(property.name + '-input', {'-is-guid': isGuid}); const fieldValue = value ? (value.constructor.name != "Object") ? value : '' : (isNaN(value) ? undefined : value); + + // process the named field value change + function processFieldValueChange(name, value) { + console.debug('processed change for -- ' + name + ' -- with value -- ' + value); + // this = the container being edited + if (DescriptorModelFactory.isContainer(this)) { + utils.assignPathValue(this.model, name, value); + CatalogItemsActions.catalogItemDescriptorChanged(this.getRoot()); + } + } + + // change handler used for onChange event + const changeHandler = (handleValueChange, event) => { + event.preventDefault(); + console.debug(event.target.value); + handleValueChange(event.target.value); + }; + // create an onChange event handler for a text field for the specified field path (debounced to accumulate chars) + const onTextChange = changeHandler.bind(null, _debounce( + processFieldValueChange.bind(container, pathToProperty), 2000, {maxWait: 5000})); // max wait for short-name + // create an onChange event handler for a select field for the specified field path + const onSelectChange = changeHandler.bind(null, processFieldValueChange.bind(container, pathToProperty)); + if (isEnumeration) { const enumeration = Property.getEnumeration(property, value); const options = enumeration.map((d, i) => { @@ -195,110 +226,202 @@ export default function EditDescriptorModelProperties(props) { // so we categorically ignore them // https://trello.com/c/uzEwVx6W/230-bug-enum-should-not-use-index-only-name //return ; - return ; + return ; }); const isValueSet = enumeration.filter(d => d.isSelected).length > 0; if (!isValueSet || property.cardinality === '0..1') { const noValueDisplayText = changeCase.title(property.name); - options.unshift(); + options.unshift(); } - return ; + return ( + + ); } if (isLeafRef) { - let fullFieldKey = _.isArray(fieldKey) ? fieldKey.join(':') : fieldKey; + let fullPathString = container.key + ':' + path.join(':'); let containerRef = container; while (containerRef.parent) { - fullFieldKey = containerRef.parent.key + ':' + fullFieldKey; + fullPathString = containerRef.parent.key + ':' + fullPathString; containerRef = containerRef.parent; } - const leafRefPathValues = Property.getLeafRef(property, path, value, fullFieldKey, catalogs, container); + const leafRefPathValues = Property.getLeafRef(property, path, value, fullPathString, catalogs, container); const options = leafRefPathValues && leafRefPathValues.map((d, i) => { - return ; + return ; }); const isValueSet = leafRefPathValues.filter(d => d.isSelected).length > 0; if (!isValueSet || property.cardinality === '0..1') { const noValueDisplayText = changeCase.title(property.name); - options.unshift(); + options.unshift(); } - return ; + return ( + + ); } if (isBoolean) { - let fullFieldKey = _.isArray(fieldKey) ? fieldKey.join(':') : fieldKey; - let containerRef = container; - while (containerRef.parent) { - fullFieldKey = containerRef.parent.key + ':' + fullFieldKey; - containerRef = containerRef.parent; - } - const options = [ - , - + , + ] // if (!isValueSet) { const noValueDisplayText = changeCase.title(property.name); - options.unshift(); + options.unshift(); // } let val = value; if(typeof(val) == 'number') { val = value ? "TRUE" : "FALSE" } const isValueSet = (val != '' && val) - return ; + return ( + + ); + } + + if (Property.isLeafEmpty(property)) { + // A null value indicates the leaf exists (as opposed to undefined). + // We stick in a string when the user actually sets it to simplify things + // but the correct thing happens when we serialize to user data + let isEmptyLeafPresent = (value === EMPTY_LEAF_PRESENT || value === null); + let present = isEmptyLeafPresent ? EMPTY_LEAF_PRESENT : ""; + const options = [ + , + + ] + + return ( + + ); } if (property['preserve-line-breaks']) { - return