Merge "RIFT-15032: launchpad UI - Viewport - icons for nsr"
diff --git a/skyquake/plugins/composer/src/src/components/EditDescriptorModelProperties.js b/skyquake/plugins/composer/src/src/components/EditDescriptorModelProperties.js
index 20c84da..4dc4b28 100644
--- a/skyquake/plugins/composer/src/src/components/EditDescriptorModelProperties.js
+++ b/skyquake/plugins/composer/src/src/components/EditDescriptorModelProperties.js
@@ -287,16 +287,16 @@
 				}
 				utils.assignPathValue(stateObject, [selected].join('.'), _.cloneDeep(choiceObject));
 
-				if(this.model.uiState.choice.hasOwnProperty(name)) {
-					delete this.model[selected];
-					utils.removePathValue(this.model, [name, selected].join('.'), isTopCase);
-				} else {
-					// remove the current choice value from the model
-				utils.removePathValue(this.model, [name, selected].join('.'), isTopCase);
+				if(selected) {
+					if(this.model.uiState.choice.hasOwnProperty(name)) {
+						delete this.model[selected];
+						utils.removePathValue(this.model, [name, selected].join('.'), isTopCase);
+					} else {
+						// remove the current choice value from the model
+						utils.removePathValue(this.model, [name, selected].join('.'), isTopCase);
+					}
 				}
 
-
-
 				// get any state for the new selected choice
 				const newChoiceObject = utils.resolvePath(stateObject, [value].join('.')) || {};
 
@@ -333,7 +333,7 @@
 			return {optionName: d.name};
 		});
 
-		const options = [{optionName: ''}].concat(cases).map((d, i) => {
+		const options = [{optionName: '', optionValue: false}].concat(cases).map((d, i) => {
 			return (
 				<option key={i} value={d.optionValue} title={d.optionTitle}>
 					{d.optionName}
@@ -353,7 +353,7 @@
 			if(fieldProperties) {
 				//Check each case statement in model and see if it is present in container model.
 				cases.map(function(c){
-					if(fieldProperties.hasOwnProperty(c.optionName)) {
+					if(fieldProperties.hasOwnProperty(c.optionValue.split('.')[1])) {
 						utils.assignPathValue(container.model, ['uiState.choice', selectName, 'selected'].join('.'), c.optionValue);
 					}
 				});
diff --git a/skyquake/plugins/composer/src/src/libraries/model/DescriptorModelSerializer.js b/skyquake/plugins/composer/src/src/libraries/model/DescriptorModelSerializer.js
index 014beb3..8ce90cf 100644
--- a/skyquake/plugins/composer/src/src/libraries/model/DescriptorModelSerializer.js
+++ b/skyquake/plugins/composer/src/src/libraries/model/DescriptorModelSerializer.js
@@ -129,7 +129,7 @@
 				return DescriptorModelSerializer.serialize(d);
 			});
 
-			return confd;
+			return cleanEmptyTopKeys(confd);
 
 		}
 	},
@@ -161,7 +161,7 @@
 			}
 			// fix-end
 			confd[property] = confd[property].map(d => DescriptorModelSerializer[property].serialize(d));
-			return confd;
+			return cleanEmptyTopKeys(confd);
 		}
 	},
 	'vnfd-connection-point-ref': {
@@ -185,7 +185,7 @@
 			if(!vnfdFields) vnfdFields = DescriptorModelMetaFactory.getModelFieldNamesForType('vnfd').concat('uiState');
 			const confd = _.pick(vnfdModel, vnfdFields);
 			confd.vdu = confd.vdu.map(d => DescriptorModelSerializer.serialize(d));
-			return confd;
+			return cleanEmptyTopKeys(confd);
 		}
 	},
 	vdu: {
@@ -195,26 +195,48 @@
 				checkForChoiceAndRemove(k, copy, vduModel)
 			}
 			const confd = _.omit(copy, ['uiState']);
-			return confd;
+			return cleanEmptyTopKeys(confd);
 		}
 	}
 };
 
 
 function checkForChoiceAndRemove(k, confd, model) {
-	let state = model.uiState;
-	if (state.choice) {
-		let choice = state.choice[k]
-		if(choice) {
-			for (let key in confd[k]) {
-				if(choice && (choice.selected.indexOf(key) > -1)) {
-					confd[key] = confd[k][key]
-				}
-			};
-			delete confd[k];
-		}
-	}
-	return confd;
+    let state = model.uiState;
+    if (state.choice) {
+        let choice = state.choice[k]
+        if(choice) {
+            if (choice.constructor.name == "Array") {
+                for(let i = 0; i < choice.length; i++) {
+                    for (let key in confd[k][i]) {
+                        if(choice[i] && (choice[i].selected.indexOf(key) > -1)) {
+                            confd[k][i][key] = confd[k][i][key]
+                        }
+                        confd[key];
+                    };
+                }
+            } else {
+                for (let key in confd[k]) {
+                    if(choice && (choice.selected.indexOf(key) > -1)) {
+                        confd[key] = confd[k][key]
+                    }
+                };
+                delete confd[k];
+            }
+
+        }
+    }
+    return confd;
+}
+
+function cleanEmptyTopKeys(m){
+    Object.keys(m).forEach(k => {
+        const isEmptyObject = typeof m[k] === 'object' && _.isEmpty(m[k]);
+        if (typeof m[k] === 'undefined' || isEmptyObject || m[k] === '') {
+            delete m[k];
+        }
+    });
+    return m;
 }
 
 export default DescriptorModelSerializer;