Fix problem with top level choice elements not being saved correctly.
authorBob Gallagher <bob.gallagher@riftio.com>
Tue, 2 May 2017 12:34:39 +0000 (08:34 -0400)
committerBob Gallagher <bob.gallagher@riftio.com>
Wed, 3 May 2017 22:08:51 +0000 (18:08 -0400)
- create common function to process a list of properties and to handle choice correctly
- also fixed issued with leaf-list elements and array handling
- rift-16326

Change-Id: I67f10318c47d2efcdc5dc1a81d48bf0d6841a221
Signed-off-by: Bob Gallagher <bob.gallagher@riftio.com>
skyquake/plugins/composer/src/src/components/EditDescriptorModelProperties.js

index 01cd5b2..0e1746d 100644 (file)
@@ -388,21 +388,35 @@ export default function EditDescriptorModelProperties(props) {
 
        }
 
-       function buildElement(container, property, valuePath, value) {
-               return property.properties.map((property, index) => {
-                       let childValue;
-                       const childPath = valuePath.slice();
-                       if (typeof value === 'object') {
-                               childValue = value[property.name];
+       /**
+        * buiid and return an array of components representing an editor for each property.
+        * 
+        * @param {any} container the master document being edited
+        * @param {[property]} properties 
+        * @param {string} pathToProperties path within the container to the properties
+        * @param {Object} data source for each property
+        * @param {any} props object containing main data panel information, e.g. panel width {width: 375}
+        * which may be useful/necessary to a components rendering.
+        * @returns an array of react components
+        */
+       function buildComponentsForProperties(container, properties, pathToProperties, data, props) {
+               return properties.map((property) => {
+                       let value;
+                       let propertyPath = pathToProperties.slice();
+                       if (data && typeof data === 'object') {
+                               value = data[property.name];
                        }
                        if(property.type != 'choice'){
-                                               childPath.push(property.name);
+                               propertyPath.push(property.name);
                        }
-                       return build(container, property, childPath, childValue);
-
+                       return build(container, property, propertyPath, value, props);
                });
        }
 
+       function buildElement(container, property, valuePath, value) {
+               return buildComponentsForProperties(container, property.properties, valuePath, value);
+       }
+
        function buildChoice(container, property, path, value, key) {
 
                function processChoiceChange(name, value) {
@@ -538,8 +552,15 @@ export default function EditDescriptorModelProperties(props) {
                const hasProperties = _isArray(valueProperty.properties) && valueProperty.properties.length;
                const isMissingDescriptorMeta = !hasProperties && !Property.isLeaf(valueProperty);
                //Some magic that prevents errors for arising
-               const valueResponse = valueProperty.properties && valueProperty.properties.length ? valueProperty.properties.map(valuePropertyFn) : (!isMissingDescriptorMeta) ? build(container, valueProperty, path.concat(valueProperty.name), utils.resolvePath(container.model, path.concat(valueProperty.name).join('.')) || container.model[valueProperty.name]) :
-               valueProperty.map && valueProperty.map(valuePropertyFn);
+               let valueResponse = null;
+               if (valueProperty.properties && valueProperty.properties.length) { 
+                       valueResponse = valueProperty.properties.map(valuePropertyFn);
+               } else if (!isMissingDescriptorMeta) {
+                       let value = utils.resolvePath(container.model, path.concat(valueProperty.name).join('.')) || container.model[valueProperty.name];
+                       valueResponse = build(container, valueProperty, path.concat(valueProperty.name), value)
+               } else {
+                       valueResponse = valueProperty.map && valueProperty.map(valuePropertyFn);
+               }
                function valuePropertyFn(d, i) {
                        const childPath = path.concat(valueProperty.name, d.name);
                        const childValue = utils.resolvePath(container.model, childPath.join('.'));
@@ -668,7 +689,7 @@ export default function EditDescriptorModelProperties(props) {
 
                        if (isArray) {
                                valuePath.push(index);
-                               fieldId = resolveReactKey(value);
+                               fieldId = isLeafList ? fieldId + index + value : resolveReactKey(value);
                        }
 
                        if (isMetaField) {
@@ -772,11 +793,7 @@ export default function EditDescriptorModelProperties(props) {
                        <div className="basic-properties-group">
                                <h2>Basic</h2>
                                <div>
-                                       {basicProperties.map(property => {
-                                               const path = [property.name];
-                                               const value = container.model[property.name];
-                                               return build(container, property, path, value);
-                                       })}
+                                       {buildComponentsForProperties(container, basicProperties, [], container.model)}
                                </div>
                        </div>
                );
@@ -796,11 +813,7 @@ export default function EditDescriptorModelProperties(props) {
                                        <a className="toggle-show-less" href="#show-more-properties">less&hellip;</a>
                                </h1>
                                <div className="toggleable">
-                                       {properties.map(property => {
-                                               const path = [property.name];
-                                               const value = container.model[property.name];
-                                               return build(container, property, path, value, {toggle: true, width: props.width});
-                                       })}
+                                       {buildComponentsForProperties(container, properties, [], container.model, {toggle: true, width: props.width})}
                                </div>
                                <div className="toggle-bottom-spacer" style={{visibility: 'hidden', 'height': '50%', position: 'absolute'}}>We need this so when the user closes the panel it won't shift away and scare the bj out of them!</div>
                        </div>