Provide add/edit constraints capability to inputs in properties page
[sdc.git] / catalog-ui / src / app / ng2 / pages / properties-assignment / properties-assignment.page.component.ts
index 6474b15..e66de41 100644 (file)
@@ -38,14 +38,16 @@ import {
     PropertyBEModel,
     PropertyFEModel,
     Service,
-    SimpleFlatProperty
+    SimpleFlatProperty,
+    PropertyDeclareAPIModel,
+    PropertiesGroup
 } from "app/models";
 import {ResourceType} from "app/utils";
 import {ComponentServiceNg2} from "../../services/component-services/component.service";
 import {TopologyTemplateService} from "../../services/component-services/topology-template.service";
 import {ComponentInstanceServiceNg2} from "../../services/component-instance-services/component-instance.service"
 import {KeysPipe} from 'app/ng2/pipes/keys.pipe';
-import {EVENTS, PROPERTY_TYPES, WorkspaceMode} from "../../../utils/constants";
+import {EVENTS, PROPERTY_TYPES, WorkspaceMode, PROPERTY_DATA} from "../../../utils/constants";
 import {EventListenerService} from "app/services/event-listener-service"
 import {HierarchyDisplayOptions} from "../../components/logic/hierarchy-navigtion/hierarchy-display-options";
 import {FilterPropertiesAssignmentComponent} from "../../components/logic/filter-properties-assignment/filter-properties-assignment.component";
@@ -67,6 +69,7 @@ import {ToscaPresentationData} from "../../../models/tosca-presentation";
 import {Observable} from "rxjs";
 import {TranslateService} from "../../shared/translator/translate.service";
 import {ToscaFunction} from "../../../models/tosca-function";
+import {SubPropertyToscaFunction} from "../../../models/sub-property-tosca-function";
 
 const SERVICE_SELF_TITLE = "SELF";
 @Component({
@@ -94,6 +97,8 @@ export class PropertiesAssignmentComponent {
     selectedInstanceData: ComponentInstance | GroupInstance | PolicyInstance = null;
     checkedPropertiesCount: number = 0;
     checkedChildPropertiesCount: number = 0;
+    enableToscaFunction: boolean = false;
+    checkedToscaCount: number = 0;
 
     hierarchyPropertiesDisplayOptions: HierarchyDisplayOptions = new HierarchyDisplayOptions('path', 'name', 'childrens');
     hierarchyInstancesDisplayOptions: HierarchyDisplayOptions = new HierarchyDisplayOptions('uniqueId', 'name', 'archived', null, 'iconClass');
@@ -117,6 +122,7 @@ export class PropertiesAssignmentComponent {
     serviceBePropertiesMap: InstanceBePropertiesMap;
     serviceBeCapabilitiesPropertiesMap: InstanceBePropertiesMap;
     selectedInstance_FlattenCapabilitiesList: Capability[];
+    componentInstancePropertyMap : PropertiesGroup;
 
     @ViewChild('hierarchyNavTabs') hierarchyNavTabs: Tabs;
     @ViewChild('propertyInputTabs') propertyInputTabs: Tabs;
@@ -166,6 +172,7 @@ export class PropertiesAssignmentComponent {
                 this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
                 this.inputs.push(newInput); //only push items that were declared via SDC
             });
+            this.componentInstancePropertyMap = response.componentInstancesProperties;
             this.loadingInputs = false;
 
         }, error => {
@@ -511,17 +518,18 @@ export class PropertiesAssignmentComponent {
      * Select Tosca function value from defined values
      */
     selectToscaFunctionAndValues = (): void => {
-        const selectedInstanceData: ComponentInstance | GroupInstance = this.getSelectedInstance();
+        const selectedInstanceData: ComponentInstance | GroupInstance | PolicyInstance = this.getSelectedInstance();
         if (!selectedInstanceData) {
             return;
         }
         this.openToscaGetFunctionModal();
     }
 
-    private getSelectedInstance(): ComponentInstance | GroupInstance {
+    private getSelectedInstance(): ComponentInstance | GroupInstance | PolicyInstance {
         const instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
         const instanceId: string = instancesIds[0];
-        return <ComponentInstance | GroupInstance> this.instances.find(instance => instance.uniqueId == instanceId && instance instanceof ComponentInstance || instance instanceof GroupInstance);
+        return <ComponentInstance | GroupInstance | PolicyInstance> this.instances.find(instance => 
+            instance.uniqueId == instanceId && (instance instanceof ComponentInstance || instance instanceof GroupInstance || instance instanceof PolicyInstance));
     }
 
     private buildCheckedInstanceProperty(): PropertyBEModel {
@@ -575,28 +583,104 @@ export class PropertiesAssignmentComponent {
 
     private clearCheckedInstancePropertyValue() {
         const checkedInstanceProperty: PropertyBEModel = this.buildCheckedInstanceProperty();
+        const currentValue : any = checkedInstanceProperty.value;
         checkedInstanceProperty.getInputValues = null;
         checkedInstanceProperty.value = null;
         checkedInstanceProperty.toscaFunction = null;
+        if (checkedInstanceProperty instanceof PropertyDeclareAPIModel && (<PropertyDeclareAPIModel>checkedInstanceProperty).propertiesName){
+            const propertiesNameArray = (<PropertyDeclareAPIModel>checkedInstanceProperty).propertiesName;
+            const parts = propertiesNameArray.split("#");
+            let currentKey = [];
+            if (this.isListOrMap(checkedInstanceProperty.type)) {
+                currentKey.push((<DerivedFEProperty>checkedInstanceProperty.input).mapKey);
+                if (this.isComplexSchemaType(checkedInstanceProperty.schemaType)) {
+                    currentKey.push(parts.reverse()[0]);
+                }
+            }
+            if (propertiesNameArray.length > 1){
+                const index = checkedInstanceProperty.subPropertyToscaFunctions.findIndex(existingSubPropertyToscaFunction => this.areEqual(existingSubPropertyToscaFunction.subPropertyPath, currentKey.length > 0 ? currentKey : parts.slice(1)));
+                checkedInstanceProperty.subPropertyToscaFunctions.splice(index, 1);
+            }
+            if(currentValue !== null && currentKey.length > 0){
+                let valueJson = JSON.parse(currentValue);
+                if(currentKey.length >1){
+                    let innerObj = valueJson[currentKey[0]];
+                    delete innerObj[currentKey[1]];
+                    valueJson[currentKey[0]] = innerObj;
+                }else{
+                    delete valueJson[currentKey[0]];
+                }
+                if (checkedInstanceProperty.type == PROPERTY_TYPES.LIST && currentKey.length == 1) {
+                    let listValue = valueJson.filter(function (item) {
+                        return item != null && item != '';
+                    });
+                    checkedInstanceProperty.value = JSON.stringify(listValue);
+                } else {
+                    checkedInstanceProperty.value = JSON.stringify(valueJson);
+                }
+            }
+        }
         if (this.selectedInstanceData instanceof ComponentInstance) {
             this.updateInstanceProperty(checkedInstanceProperty);
         } else if (this.selectedInstanceData instanceof GroupInstance) {
             this.updateGroupInstanceProperty(checkedInstanceProperty);
+        } else if (this.selectedInstanceData instanceof PolicyInstance) {
+            this.updatePolicyInstanceProperty(checkedInstanceProperty);
         }
     }
 
     private updateCheckedInstancePropertyFunctionValue(toscaFunction: ToscaFunction) {
         const checkedProperty: PropertyBEModel = this.buildCheckedInstanceProperty();
-        checkedProperty.toscaFunction = toscaFunction;
+        if (checkedProperty instanceof PropertyDeclareAPIModel && (<PropertyDeclareAPIModel>checkedProperty).propertiesName){
+            const propertiesName = (<PropertyDeclareAPIModel>checkedProperty).propertiesName;
+            const parts = propertiesName.split("#");
+            let currentKey = [];
+            if (this.isListOrMap(checkedProperty.type)) {
+                currentKey.push((<DerivedFEProperty>checkedProperty.input).mapKey);
+                if (this.isComplexSchemaType(checkedProperty.schemaType)) {
+                    currentKey.push(parts.reverse()[0]);
+                }
+            }
+            if (checkedProperty.subPropertyToscaFunctions == null){
+                checkedProperty.subPropertyToscaFunctions = [];
+            }
+            let subPropertyToscaFunction = checkedProperty.subPropertyToscaFunctions.find(existingSubPropertyToscaFunction => this.areEqual(existingSubPropertyToscaFunction.subPropertyPath, currentKey.length > 0 ? currentKey : parts.slice(1)));
+            if (!subPropertyToscaFunction){
+                 subPropertyToscaFunction = new SubPropertyToscaFunction();
+                 checkedProperty.subPropertyToscaFunctions.push(subPropertyToscaFunction);
+            }
+            subPropertyToscaFunction.toscaFunction = toscaFunction;
+            subPropertyToscaFunction.subPropertyPath = currentKey.length > 0 ? currentKey : parts.slice(1);
+   
+        } else {
+            checkedProperty.subPropertyToscaFunctions = null;
+            checkedProperty.toscaFunction = toscaFunction;
+        }
         if (this.selectedInstanceData instanceof ComponentInstance) {
             this.updateInstanceProperty(checkedProperty);
         } else if (this.selectedInstanceData instanceof GroupInstance) {
             this.updateGroupInstanceProperty(checkedProperty);
+        } else if (this.selectedInstanceData instanceof PolicyInstance) {
+            this.updatePolicyInstanceProperty(checkedProperty);
         }
     }
 
+    private isComplexSchemaType(propertyType: string): boolean {
+        return PROPERTY_DATA.SIMPLE_TYPES.indexOf(propertyType) === -1;
+    }
+
+    private isListOrMap(propertyType: string): boolean {
+        return PROPERTY_TYPES.MAP === propertyType || PROPERTY_TYPES.LIST === propertyType;
+    }
+
+    private areEqual(array1: string[], array2: string[]): boolean {
+        return array1.length === array2.length && array1.every(function(value, index) { return value === array2[index]})
+    }
+
     updateInstanceProperty(instanceProperty: PropertyBEModel) {
         this.loadingProperties = true;
+        this.enableToscaFunction = false;
+        this.checkedToscaCount = 0;
         this.componentInstanceServiceNg2.updateInstanceProperties(this.component.componentType, this.component.uniqueId,
             this.selectedInstanceData.uniqueId, [instanceProperty])
         .subscribe(() => {
@@ -623,6 +707,20 @@ export class PropertiesAssignmentComponent {
         });
     }
 
+    updatePolicyInstanceProperty(instanceProperty: PropertyBEModel) {
+        this.loadingProperties = true;
+        this.componentInstanceServiceNg2.updateComponentPolicyInstanceProperties(this.component.componentType, this.component.uniqueId,
+            this.selectedInstanceData.uniqueId, [instanceProperty])
+        .subscribe(() => {
+            this.changeSelectedInstance(this.getSelectedInstance());
+        }, (error) => {
+            this.loadingProperties = false;
+            console.error(error);
+        }, () => {
+            this.loadingProperties = false;
+        });
+    }
+
     /*** DECLARE PROPERTIES/INPUTS ***/
     declareProperties = (): void => {
         console.debug("==>" + this.constructor.name + ": declareProperties");
@@ -1103,6 +1201,15 @@ export class PropertiesAssignmentComponent {
         this.checkedChildPropertiesCount += (increment) ? 1 : -1;
     };
 
+    togggleToscaBtn = (toscaFlag: boolean) : void => {
+        this.checkedToscaCount += toscaFlag ? 1 : -1;
+        if(this.checkedToscaCount == 1){
+            this.enableToscaFunction = true;
+        }else{
+            this.enableToscaFunction = false;
+        }
+    };
+
     setInputTabIndication = (numInputs: number): void => {
         this.propertyInputTabs.setTabIndication('Inputs', numInputs);
     };