Fix complex list/map entries in composition view
[sdc.git] / catalog-ui / src / app / directives / property-types / type-list / type-list-directive.ts
index 857c62c..b2d322b 100644 (file)
  * Created by rcohen on 9/15/2016.
  */
 'use strict';
-import {SchemaProperty} from "app/models";
-import {ValidationUtils, PROPERTY_TYPES} from "app/utils";
+import {SchemaProperty, PropertyModel, DataTypesMap} from "app/models";
+import {ValidationUtils, PROPERTY_TYPES, PROPERTY_DATA} from "app/utils";
 import {DataTypesService} from "app/services";
+import {InstanceFeDetails} from "app/models/instance-fe-details";
+import {ToscaGetFunction} from "app/models/tosca-get-function";
+import {SubPropertyToscaFunction} from "app/models/sub-property-tosca-function";
 
 export interface ITypeListScope extends ng.IScope {
     parentFormObj:ng.IFormController;
     schemaProperty:SchemaProperty;
+    parentProperty:PropertyModel;
+    componentInstanceMap: Map<string, InstanceFeDetails>;
     isSchemaTypeDataType:boolean;
     valueObjRef:any;
     propertyNameValidationPattern:RegExp;
@@ -38,14 +43,20 @@ export interface ITypeListScope extends ng.IScope {
     listNewItem:any;
     maxLength:number;
     stringSchema: SchemaProperty;
-
+    showToscaFunction: Array<boolean>;
     constraints:string[];
+    types:DataTypesMap;
+    isService:boolean;
 
     getValidationPattern(type:string):RegExp;
     validateIntRange(value:string):boolean;
     addListItem():void;
+    addValueToList(value:string,index:number);
     deleteListItem(listItemIndex:number):void;
     getStringSchemaProperty():SchemaProperty;
+    getNumber(num:number):Array<any>;
+    onEnableTosca(toscaFlag:boolean,index:number);
+    onGetToscaFunction(toscaGetFunction: ToscaGetFunction, index:number);
 }
 
 
@@ -65,12 +76,16 @@ export class TypeListDirective implements ng.IDirective {
     scope = {
         valueObjRef: '=',//ref to list object in the parent value object
         schemaProperty: '=',//get the schema.property object
+        componentInstanceMap: '=',
+        parentProperty: '=',
         parentFormObj: '=',//ref to parent form (get angular form object)
         fieldsPrefixName: '=',//prefix for form fields names
         readOnly: '=',//is form read only
         defaultValue: '@',//this list default value
         maxLength: '=',
-        constraints: '='
+        constraints: '=',
+        types: '=',
+        isService: '='
     };
 
     restrict = 'E';
@@ -78,11 +93,51 @@ export class TypeListDirective implements ng.IDirective {
     template = ():string => {
         return require('./type-list-directive.html');
     };
+    
+    private isDataTypeForSchemaType = (property:SchemaProperty, types:DataTypesMap):boolean=> {
+        property.simpleType = "";
+        if (property.type && PROPERTY_DATA.TYPES.indexOf(property.type) > -1) {
+            return false;
+        }
+        let simpleType = this.getTypeForDataTypeDerivedFromSimple(property.type, types);
+        if (simpleType) {
+            property.simpleType = simpleType;
+            return false;
+        }
+        return true;
+    };
+    
+    private getTypeForDataTypeDerivedFromSimple = (dataTypeName:string, types:DataTypesMap):string => {
+        if (!types[dataTypeName]) {
+            return 'string';
+        }
+        if (types[dataTypeName].derivedFromName == "tosca.datatypes.Root" || types[dataTypeName].properties) {
+            return null;
+        }
+        if (PROPERTY_DATA.SIMPLE_TYPES.indexOf(types[dataTypeName].derivedFromName) > -1) {
+            return types[dataTypeName].derivedFromName
+        }
+        return this.getTypeForDataTypeDerivedFromSimple(types[dataTypeName].derivedFromName, types);
+    };
 
     link = (scope:ITypeListScope, element:any, $attr:any) => {
         scope.propertyNameValidationPattern = this.PropertyNameValidationPattern;
         scope.stringSchema = this.stringSchema;
-
+        if (scope.valueObjRef.length == 0) {
+            scope.valueObjRef.push("");
+        }
+        scope.showToscaFunction = new Array(scope.valueObjRef.length);
+        scope.valueObjRef.forEach((value, index) => {
+            scope.showToscaFunction[index] = false;
+            let key : string = index.toString();
+            if (scope.parentProperty.subPropertyToscaFunctions != null) {
+                scope.parentProperty.subPropertyToscaFunctions.forEach(SubPropertyToscaFunction => {
+                    if (SubPropertyToscaFunction.subPropertyPath.indexOf(key) != -1) {
+                        scope.showToscaFunction[index] = true;
+                    }
+                });
+            }
+        });
         //reset valueObjRef when schema type is changed
         scope.$watchCollection('schemaProperty.type', (newData:any):void => {
             scope.isSchemaTypeDataType = this.DataTypesService.isDataTypeForSchemaType(scope.schemaProperty);
@@ -113,18 +168,80 @@ export class TypeListDirective implements ng.IDirective {
             } else if ((scope.schemaProperty.simpleType || scope.schemaProperty.type) == PROPERTY_TYPES.STRING) {
                 newVal = scope.listNewItem.value;
             } else {
-                newVal = JSON.parse(scope.listNewItem.value);
+                if (scope.listNewItem.value != "") {
+                    newVal = JSON.parse(scope.listNewItem.value);
+                }
             }
             scope.valueObjRef.push(newVal);
+            scope.showToscaFunction.push(false);
             scope.listNewItem.value = "";
         };
 
+        //return dummy array in order to prevent rendering map-keys ng-repeat again when a map key is changed
+        scope.getNumber = (num:number):Array<any> => {
+            return new Array(num);
+        };
+
+        scope.addValueToList = (value:string,index:number):void => {
+            console.log("value : "+value+" , index : "+index);
+            scope.valueObjRef[index] = value;
+            scope.parentProperty.value = scope.valueObjRef;
+        }
+
         scope.deleteListItem = (listItemIndex: number): void => {
             scope.valueObjRef.splice(listItemIndex, 1);
+            let key : string = listItemIndex.toString();
+            if (scope.parentProperty.subPropertyToscaFunctions != null) {
+                let subToscaFunctionList : Array<SubPropertyToscaFunction> = [];
+                scope.parentProperty.subPropertyToscaFunctions.forEach((SubPropertyToscaFunction, index) => {
+                    if (SubPropertyToscaFunction.subPropertyPath.indexOf(key) == -1) {
+                        subToscaFunctionList.push(SubPropertyToscaFunction);
+                    }
+                });
+                scope.parentProperty.subPropertyToscaFunctions = subToscaFunctionList;
+            }
             if (!scope.valueObjRef.length && scope.listDefaultValue) {
                 angular.copy(scope.listDefaultValue, scope.valueObjRef);
             }
         };
+
+        scope.onEnableTosca = (toscaFlag:boolean,flagIndex:number):void => {
+            scope.showToscaFunction[flagIndex] = toscaFlag;
+            scope.valueObjRef[flagIndex] = "";
+            let key:string = flagIndex.toString();
+            if (!toscaFlag) {
+                if (scope.parentProperty.subPropertyToscaFunctions != null) {
+                    let subToscaFunctionList : Array<SubPropertyToscaFunction> = [];
+                    scope.parentProperty.subPropertyToscaFunctions.forEach((SubPropertyToscaFunction, index) => {
+                        if (SubPropertyToscaFunction.subPropertyPath.indexOf(key) == -1) {
+                            subToscaFunctionList.push(SubPropertyToscaFunction);
+                        }
+                    });
+                    scope.parentProperty.subPropertyToscaFunctions = subToscaFunctionList;
+                }
+            }
+        };
+
+        scope.onGetToscaFunction = (toscaGetFunction: ToscaGetFunction, index:number): void => {
+            let key:string = index.toString();
+            if (scope.parentProperty.subPropertyToscaFunctions != null) {
+                scope.parentProperty.subPropertyToscaFunctions.forEach(SubPropertyToscaFunction => {
+                    if (SubPropertyToscaFunction.subPropertyPath.indexOf(key) != -1) {
+                        SubPropertyToscaFunction.toscaFunction = toscaGetFunction;
+                        return;
+                    }
+                });
+
+            }
+            if (scope.parentProperty.subPropertyToscaFunctions == null){
+                scope.parentProperty.subPropertyToscaFunctions = [];
+            }
+            let subPropertyToscaFunction = new SubPropertyToscaFunction();
+            subPropertyToscaFunction.toscaFunction = toscaGetFunction;
+            subPropertyToscaFunction.subPropertyPath = [key];
+            scope.parentProperty.subPropertyToscaFunctions.push(subPropertyToscaFunction);
+        }
+
     };
 
     public static factory = (DataTypesService:DataTypesService,