Fix problem with top level choice elements not being saved correctly.
- 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>
diff --git a/skyquake/plugins/composer/src/src/components/EditDescriptorModelProperties.js b/skyquake/plugins/composer/src/src/components/EditDescriptorModelProperties.js
index 01cd5b2..0e1746d 100644
--- a/skyquake/plugins/composer/src/src/components/EditDescriptorModelProperties.js
+++ b/skyquake/plugins/composer/src/src/components/EditDescriptorModelProperties.js
@@ -388,21 +388,35 @@
 
 	}
 
-	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 @@
 		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 @@
 
 			if (isArray) {
 				valuePath.push(index);
-				fieldId = resolveReactKey(value);
+				fieldId = isLeafList ? fieldId + index + value : resolveReactKey(value);
 			}
 
 			if (isMetaField) {
@@ -772,11 +793,7 @@
 			<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 @@
 					<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>