Sync Integ to Master
[sdc.git] / catalog-ui / src / app / ng2 / pages / properties-assignment / services / properties.utils.ts
index 8f46c6f..e7b59b9 100644 (file)
@@ -18,6 +18,7 @@
  * ============LICENSE_END=========================================================
  */
 
+import * as _ from "lodash";
 import { Injectable } from '@angular/core';
 import { DataTypeModel, PropertyFEModel, PropertyBEModel, InstanceBePropertiesMap, InstanceFePropertiesMap, DerivedFEProperty,  DerivedPropertyType, InputFEModel} from "app/models";
 import { DataTypeService } from "app/ng2/services/data-type.service";
@@ -47,10 +48,13 @@ export class PropertiesUtils {
 
                     let newFEProp: PropertyFEModel = new PropertyFEModel(property); //Convert property to FE
 
-                    if (newFEProp.derivedDataType == DerivedPropertyType.COMPLEX) { //Create children if prop is not simple, list, or map.
-                        newFEProp.flattenedChildren = this.createFlattenedChildren(newFEProp.type, newFEProp.name);
-                    }
-                    if (newFEProp.getInputValues && newFEProp.getInputValues.length) { //if this prop (or any children) are declared, set isDeclared and disable checkbox on parents/children
+                    this.initValueObjectRef(newFEProp); //initialize valueObj.
+                    propertyFeArray.push(newFEProp);
+                    newFEProp.updateExpandedChildPropertyId(newFEProp.name); //display only the first level of children
+                    this.dataTypeService.checkForCustomBehavior(newFEProp);
+
+                    //if this prop (or any children) are declared, set isDeclared and disable checkbox on parents/children
+                    if (newFEProp.getInputValues && newFEProp.getInputValues.length) {
                         newFEProp.getInputValues.forEach(propInputDetail => {
                             let inputPath = propInputDetail.inputPath;
                             if (!inputPath) { //TODO: this is a workaround until Marina adds inputPath
@@ -63,10 +67,6 @@ export class PropertiesUtils {
                             this.propertiesService.disableRelatedProperties(newFEProp, inputPath);
                         });
                     }
-                    this.initValueObjectRef(newFEProp); //initialize valueObj.
-                    propertyFeArray.push(newFEProp);
-                    newFEProp.updateExpandedChildPropertyId(newFEProp.name); //display only the first level of children
-                    this.dataTypeService.checkForCustomBehavior(newFEProp);
                 }
             });
             instanceFePropertiesMap[instanceId] = propertyFeArray;
@@ -103,33 +103,29 @@ export class PropertiesUtils {
     * Note: This logic is different than assignflattenedchildrenvalues - here we merge values, there we pick either the parents value, props value, or default value - without merging.
     */
     public initValueObjectRef = (property: PropertyFEModel): void => {
-        if (property.derivedDataType == DerivedPropertyType.SIMPLE || property.isDeclared) { //if property is declared, it gets a simple input instead. List and map values and pseudo-children will be handled in property component
-            property.valueObj = property.value || property.defaultValue;
-            if (property.isDeclared) {
-                if(typeof property.valueObj == 'object'){
-                    property.valueObj = JSON.stringify(property.valueObj);
-                }
-            }else if(property.valueObj &&
-                property.type !== PROPERTY_TYPES.STRING &&
-                property.type !== PROPERTY_TYPES.JSON &&
-                PROPERTY_DATA.SCALAR_TYPES.indexOf(property.type) == -1){
-                    property.valueObj = JSON.parse(property.valueObj);//The valueObj contains the real value ans not the value as string
+        property.resetValueObjValidation();
+        if (property.isDeclared) { //if property is declared, it gets a simple input instead. List and map values and pseudo-children will be handled in property component
+            property.valueObj = property.value || property.defaultValue || null;  // use null for empty value object
+            if (property.valueObj && typeof property.valueObj == 'object') {
+                property.valueObj = JSON.stringify(property.valueObj);
             }
         } else {
-            if (property.derivedDataType == DerivedPropertyType.LIST) {
-                property.valueObj = _.merge([], JSON.parse(property.defaultValue || '[]'), JSON.parse(property.value || '[]')); //value object should be merged value and default value. Value takes higher precendence. Set valueObj to empty obj if undefined.
-            } else {
-                property.valueObj = _.merge({}, JSON.parse(property.defaultValue || '{}'), JSON.parse(property.value || '{}')); //value object should be merged value and default value. Value takes higher precendence. Set valueObj to empty obj if undefined.
-            }
-            if ((property.derivedDataType == DerivedPropertyType.LIST || property.derivedDataType == DerivedPropertyType.MAP) && Object.keys(property.valueObj).length) {
+            property.valueObj = property.getValueObj();
+            if (property.derivedDataType == DerivedPropertyType.LIST || property.derivedDataType == DerivedPropertyType.MAP) {
+                property.flattenedChildren = [];
                 Object.keys(property.valueObj).forEach((key) => {
                     property.flattenedChildren.push(...this.createListOrMapChildren(property, key, property.valueObj[key]))
                 });
-            } else {
+            } else if (property.derivedDataType === DerivedPropertyType.COMPLEX) {
+                property.flattenedChildren = this.createFlattenedChildren(property.type, property.name);
                 this.assignFlattenedChildrenValues(property.valueObj, property.flattenedChildren, property.name);
+                property.flattenedChildren.forEach((childProp) => {
+                    property.childPropUpdated(childProp);
+                });
             }
         }
-    }
+        property.updateValueObjOrig();
+    };
 
     /*
     * Loops through flattened properties array and to assign values
@@ -142,22 +138,24 @@ export class PropertiesUtils {
         derivedPropArray.forEach((prop, index) => {
 
             let propNameInObj = prop.propertiesName.substring(prop.propertiesName.indexOf(parentName) + parentName.length + 1).split('#').join('.'); //extract everything after parent name
-            prop.valueObj = _.get(parentValueJSON, propNameInObj, prop.value || prop.defaultValue); //assign value -first value of parent if exists. If not, prop.value if not, prop.defaultvalue
+            prop.valueObj = _.get(parentValueJSON, propNameInObj, prop.value || prop.defaultValue || null); //assign value -first value of parent if exists. If not, prop.value if not, prop.defaultvalue
+            prop.value = (prop.valueObj !== null && (typeof prop.valueObj) != 'string') ? JSON.stringify(prop.valueObj) : prop.valueObj;
 
-            if ( prop.isDeclared && typeof prop.valueObj == 'object') { //Stringify objects of items that are declared
-                prop.valueObj = JSON.stringify(prop.valueObj);
-            } else if(typeof prop.valueObj == PROPERTY_TYPES.STRING
-                && (prop.type == PROPERTY_TYPES.INTEGER || prop.type == PROPERTY_TYPES.FLOAT || prop.type == PROPERTY_TYPES.BOOLEAN)){ //parse ints and non-string simple types
-                prop.valueObj = JSON.parse(prop.valueObj);
+            if ((prop.isDeclared || prop.type == PROPERTY_TYPES.STRING || prop.type == PROPERTY_TYPES.JSON)) { //Stringify objects of items that are declared or from type string/json
+                prop.valueObj = (prop.valueObj !== null && typeof prop.valueObj == 'object') ? JSON.stringify(prop.valueObj) : prop.valueObj;
+            } else if(prop.type == PROPERTY_TYPES.INTEGER || prop.type == PROPERTY_TYPES.FLOAT || prop.type == PROPERTY_TYPES.BOOLEAN){ //parse ints and non-string simple types
+                prop.valueObj = (prop.valueObj !== null && typeof prop.valueObj == PROPERTY_TYPES.STRING) ? JSON.parse(prop.valueObj) : prop.valueObj;
             } else { //parse strings that should be objects
-                if (prop.derivedDataType == DerivedPropertyType.COMPLEX && typeof prop.valueObj != 'object') {
-                    prop.valueObj = JSON.parse(prop.valueObj || '{}');
-                } else if (prop.derivedDataType == DerivedPropertyType.LIST && typeof prop.valueObj != 'object') {
-                    prop.valueObj = JSON.parse(prop.valueObj || '[]');
-                } else if (prop.derivedDataType == DerivedPropertyType.MAP && typeof prop.valueObj != 'object' && (!prop.isChildOfListOrMap || !prop.schema.property.isSimpleType)) { //dont parse values for children of map of simple
-                    prop.valueObj = JSON.parse(prop.valueObj || '{}');
+                if (prop.derivedDataType == DerivedPropertyType.COMPLEX) {
+                    prop.valueObj = (prop.valueObj === null || typeof prop.valueObj != 'object') ? JSON.parse(prop.valueObj || '{}') : prop.valueObj;
+                } else if (prop.derivedDataType == DerivedPropertyType.LIST) {
+                    prop.valueObj = (prop.valueObj === null || typeof prop.valueObj != 'object') ? JSON.parse(prop.valueObj || '[]') : prop.valueObj;
+                } else if (prop.derivedDataType == DerivedPropertyType.MAP) {
+                    if (!prop.isChildOfListOrMap || !prop.schema.property.isSimpleType) {
+                        prop.valueObj = (prop.valueObj === null || typeof prop.valueObj != 'object') ? JSON.parse(prop.valueObj || '{}') : prop.valueObj;
+                    }
                 }
-                if ((prop.derivedDataType == DerivedPropertyType.LIST || prop.derivedDataType == DerivedPropertyType.MAP) && typeof prop.valueObj == 'object' && Object.keys(prop.valueObj).length) {
+                if ((prop.derivedDataType == DerivedPropertyType.LIST || prop.derivedDataType == DerivedPropertyType.MAP) && typeof prop.valueObj == 'object' && prop.valueObj !== null && Object.keys(prop.valueObj).length) {
                     let newProps: Array<DerivedFEProperty> = [];
                     Object.keys(prop.valueObj).forEach((key) => {
                         newProps.push(...this.createListOrMapChildren(prop, key, prop.valueObj[key]));//create new children, assign their values, and then add to array
@@ -165,6 +163,8 @@ export class PropertiesUtils {
                     propsToPushMap[index + 1] = newProps;
                 }
             }
+
+            prop.valueObj = PropertyFEModel.cleanValueObj(prop.valueObj);
         });
 
         //add props after we're done looping (otherwise our loop gets messed up). Push in reverse order, so we dont mess up indexes.
@@ -178,11 +178,10 @@ export class PropertiesUtils {
         if (nestedPath) {
             let newProp = property.flattenedChildren.find(prop => prop.propertiesName == nestedPath);
             newProp && this.assignFlattenedChildrenValues(JSON.parse(newValue), [newProp], property.name);
+            property.updateValueObjOrig();
         } else {
             this.initValueObjectRef(property);
         }
     }
 
-
-
 }