Custom tosca functions with valid_values and in_range operators not showing properly
[sdc.git] / catalog-ui / src / app / ng2 / pages / properties-assignment / tosca-function / tosca-function.component.ts
index 70df4ea..412e29a 100644 (file)
@@ -17,8 +17,8 @@
  *  ============LICENSE_END=========================================================
  */
 
-import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
-import {ComponentMetadata, PropertyBEModel, PropertyDeclareAPIModel} from 'app/models';
+import {Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges} from '@angular/core';
+import {ComponentMetadata, PropertyBEModel, PropertyDeclareAPIModel, DerivedFEProperty} from 'app/models';
 import {TopologyTemplateService} from "../../../services/component-services/topology-template.service";
 import {WorkspaceService} from "../../workspace/workspace.service";
 import {ToscaGetFunctionType} from "../../../../models/tosca-get-function-type";
@@ -29,19 +29,30 @@ import {ToscaFunctionType} from "../../../../models/tosca-function-type.enum";
 import {ToscaGetFunctionValidationEvent} from "./tosca-get-function/tosca-get-function.component";
 import {ToscaFunction} from "../../../../models/tosca-function";
 import {ToscaConcatFunctionValidationEvent} from "./tosca-concat-function/tosca-concat-function.component";
+import {ToscaCustomFunctionValidationEvent} from "./tosca-custom-function/tosca-custom-function.component";
 import {PROPERTY_TYPES} from "../../../../utils/constants";
 import {YamlFunctionValidationEvent} from "./yaml-function/yaml-function.component";
+import {ToscaConcatFunction} from "../../../../models/tosca-concat-function";
+import {ToscaCustomFunction} from "../../../../models/tosca-custom-function";
+import {YamlFunction} from "../../../../models/yaml-function";
+import {CustomToscaFunction} from "../../../../models/default-custom-functions";
 
 @Component({
     selector: 'tosca-function',
     templateUrl: './tosca-function.component.html',
     styleUrls: ['./tosca-function.component.less'],
 })
-export class ToscaFunctionComponent implements OnInit {
+export class ToscaFunctionComponent implements OnInit, OnChanges {
 
     @Input() property: PropertyBEModel;
+    @Input() overridingType: PROPERTY_TYPES;
+    @Input() inToscaFunction: ToscaFunction;
     @Input() componentInstanceMap: Map<string, InstanceFeDetails> = new Map<string, InstanceFeDetails>();
+    @Input() customToscaFunctions: Array<CustomToscaFunction> = [];
     @Input() allowClear: boolean = true;
+    @Input() compositionMap: boolean = false;
+    @Input() compositionMapKey: string = "";
+    @Input() complexListKey: string = null;
     @Output() onValidFunction: EventEmitter<ToscaGetFunction> = new EventEmitter<ToscaGetFunction>();
     @Output() onValidityChange: EventEmitter<ToscaFunctionValidationEvent> = new EventEmitter<ToscaFunctionValidationEvent>();
 
@@ -55,6 +66,7 @@ export class ToscaFunctionComponent implements OnInit {
     isLoading: boolean = false;
     toscaFunction: ToscaFunction;
     toscaFunctions: Array<string> = [];
+    toscaCustomFunctions: Array<String> = [];
 
     private isInitialized: boolean = false;
     private componentMetadata: ComponentMetadata;
@@ -65,13 +77,12 @@ export class ToscaFunctionComponent implements OnInit {
 
     ngOnInit(): void {
         this.componentMetadata = this.workspaceService.metadata;
-        this.toscaFunction = this.property.toscaFunction ? this.property.toscaFunction : undefined;
+        this.toscaFunction = this.inToscaFunction ? this.inToscaFunction : this.property.toscaFunction ? this.property.toscaFunction : undefined;
         this.loadToscaFunctions();
         this.formGroup.valueChanges.subscribe(() => {
             if (!this.isInitialized) {
                 return;
             }
-            this.emitValidityChange();
             if (this.formGroup.valid) {
                 this.onValidFunction.emit(this.toscaFunctionForm.value);
             }
@@ -81,31 +92,93 @@ export class ToscaFunctionComponent implements OnInit {
         this.isInitialized = true;
     }
 
-    private validate() {
+    ngOnChanges(changes: SimpleChanges): void {
+        if (changes.property) {
+            this.resetForm();
+            this.toscaFunction = this.inToscaFunction ? this.inToscaFunction : this.property.toscaFunction ? this.property.toscaFunction : undefined;
+            this.initToscaFunction();
+            this.loadToscaFunctions();
+            this.emitValidityChange();
+        }
+    }
+
+    private validate(): boolean {
         return (!this.toscaFunctionForm.value && !this.toscaFunctionTypeForm.value) || this.formGroup.valid;
     }
 
-    private initToscaFunction() {
+    private initToscaFunction(): void {
+        if (this.compositionMap && this.property.subPropertyToscaFunctions) {
+            let keyToFind = [this.compositionMapKey];
+            if (this.complexListKey != null) {
+                keyToFind = [this.complexListKey,this.compositionMapKey];
+            }       
+            let subPropertyToscaFunction;
+            this.property.subPropertyToscaFunctions.forEach(subToscaFunction => {
+                if (subToscaFunction.subPropertyPath.toString() == keyToFind.toString()) {
+                    subPropertyToscaFunction = subToscaFunction;
+                }
+            });
+
+            if (subPropertyToscaFunction){
+                this.toscaFunction = subPropertyToscaFunction.toscaFunction;
+                this.toscaFunctionForm.setValue(this.toscaFunction);
+                let type = this.toscaFunction.type;
+                if (type == ToscaFunctionType.CUSTOM) {
+                    let name = (subPropertyToscaFunction.toscaFunction as ToscaCustomFunction).name;
+                    let customToscaFunc = this.customToscaFunctions.find(custToscFunc => _.isEqual(custToscFunc.name, name))
+                    if (customToscaFunc) {
+                        this.toscaFunctionTypeForm.setValue(name);
+                    } else {
+                        this.toscaFunctionTypeForm.setValue("other");
+                    }
+                } else {
+                    this.toscaFunctionTypeForm.setValue(type);
+                }
+            }
+            return;
+        }
            if (this.property instanceof PropertyDeclareAPIModel && this.property.subPropertyToscaFunctions && (<PropertyDeclareAPIModel> this.property).propertiesName){
                let propertiesPath = (<PropertyDeclareAPIModel> this.property).propertiesName.split("#");
             if (propertiesPath.length > 1){
-                   propertiesPath = propertiesPath.slice(1);
-                let subPropertyToscaFunction = this.property.subPropertyToscaFunctions.find(subPropertyToscaFunction => this.areEqual(subPropertyToscaFunction.subPropertyPath, propertiesPath));
+                let keyToFind = (<DerivedFEProperty>this.property.input).toscaPath;
+                let subPropertyToscaFunction = this.property.subPropertyToscaFunctions.find(subPropertyToscaFunction => this.areEqual(subPropertyToscaFunction.subPropertyPath, keyToFind.length > 0 ? keyToFind : propertiesPath.slice(1)));
 
                 if (subPropertyToscaFunction){
                        this.toscaFunction = subPropertyToscaFunction.toscaFunction;
                     this.toscaFunctionForm.setValue(this.toscaFunction);
-                    this.toscaFunctionTypeForm.setValue(this.toscaFunction.type);
+                    let type = this.toscaFunction.type;
+                    if (type == ToscaFunctionType.CUSTOM) {
+                        let name = (subPropertyToscaFunction.toscaFunction as ToscaCustomFunction).name;
+                        let customToscaFunc = this.customToscaFunctions.find(custToscFunc => _.isEqual(custToscFunc.name, name))
+                        if (customToscaFunc) {
+                            this.toscaFunctionTypeForm.setValue(name);
+                        } else {
+                            this.toscaFunctionTypeForm.setValue("other");
+                        }
+                    } else {
+                        this.toscaFunctionTypeForm.setValue(type);
+                    }
                 }
                 return;
             }
         }
-       
         if (!this.property.isToscaFunction()) {
             return;
         }
-        this.toscaFunctionForm.setValue(this.property.toscaFunction);
-        this.toscaFunctionTypeForm.setValue(this.property.toscaFunction.type);
+
+        this.toscaFunctionForm.setValue(this.inToscaFunction ? this.inToscaFunction : this.property.toscaFunction);
+        let type = this.property.toscaFunction.type ? this.property.toscaFunction.type : this.toscaFunctionForm.value.type;
+        if (type == ToscaFunctionType.CUSTOM) {
+            let name = (this.toscaFunctionForm.value as ToscaCustomFunction).name;
+            let customToscaFunc = this.customToscaFunctions.find(custToscFunc => _.isEqual(custToscFunc.name, name))
+            if (customToscaFunc) {
+                this.toscaFunctionTypeForm.setValue(name);
+            } else {
+                this.toscaFunctionTypeForm.setValue("other");
+            }
+        } else {
+            this.toscaFunctionTypeForm.setValue(this.inToscaFunction ? this.inToscaFunction.type : type);
+        }
     }
 
     private areEqual(array1: string[], array2: string[]): boolean {
@@ -113,13 +186,51 @@ export class ToscaFunctionComponent implements OnInit {
     }
 
     private loadToscaFunctions(): void {
+        this.toscaFunctions = [];
         this.toscaFunctions.push(ToscaFunctionType.GET_ATTRIBUTE);
         this.toscaFunctions.push(ToscaFunctionType.GET_INPUT);
         this.toscaFunctions.push(ToscaFunctionType.GET_PROPERTY);
-        if (this.property.type === PROPERTY_TYPES.STRING) {
+        if ((this.property.type === PROPERTY_TYPES.STRING || this.property.type === PROPERTY_TYPES.ANY) && this.overridingType === undefined) {
             this.toscaFunctions.push(ToscaFunctionType.CONCAT);
         }
-        this.toscaFunctions.push(ToscaFunctionType.YAML);
+        this.loadCustomToscaFunctions();
+    }
+
+    private loadCustomToscaFunctions(): void {
+        if (!this.customToscaFunctions.find(custToscFunc => _.isEqual(custToscFunc.name, "other"))) {
+            let other = new CustomToscaFunction();
+            other.name = "other";
+            other.type = ToscaFunctionType.CUSTOM;
+            this.customToscaFunctions.push(other);
+        }
+        this.toscaCustomFunctions = [];
+        for (let func of this.customToscaFunctions) {
+            this.toscaCustomFunctions.push(func.name);
+        }
+    }
+
+    getCustomToscaFunction(): CustomToscaFunction {
+        let funcName = this.formGroup.get('toscaFunctionType').value;
+        return this.customToscaFunctions.find(custToscFunc => _.isEqual(custToscFunc.name, funcName));
+    }
+
+    getCustomFunctionName():string {
+        let toscaFunctionType: CustomToscaFunction = this.getCustomToscaFunction();
+        let name = toscaFunctionType.name;
+        return name == 'other' ? '' : name;
+    }
+
+    getCustomFunctionType():string {
+        let toscaFunctionType: CustomToscaFunction = this.getCustomToscaFunction();
+        return toscaFunctionType.type;
+    }
+
+    isDefaultCustomFunction(): boolean {
+        let toscaFunctionType: CustomToscaFunction = this.getCustomToscaFunction();
+        if (toscaFunctionType.name === "other") {
+            return false;
+        }
+        return this.customToscaFunctions.filter(e => e.name === toscaFunctionType.name).length > 0;
     }
 
     private resetForm(): void {
@@ -143,6 +254,11 @@ export class ToscaFunctionComponent implements OnInit {
         return this.formGroup.get('toscaFunctionType').value === ToscaFunctionType.CONCAT;
     }
 
+    isCustomSelected(): boolean {
+        let toscaFunctionType: CustomToscaFunction = this.getCustomToscaFunction();
+        return toscaFunctionType && (toscaFunctionType.type === ToscaFunctionType.CUSTOM || toscaFunctionType.type === ToscaFunctionType.GET_INPUT);
+    }
+
     isGetFunctionSelected(): boolean {
         return this.isGetInputSelected() || this.isGetPropertySelected() || this.isGetAttributeSelected();
     }
@@ -151,7 +267,7 @@ export class ToscaFunctionComponent implements OnInit {
         return this.formGroup.get('toscaFunctionType').value === ToscaFunctionType.YAML;
     }
 
-    onClearValues() {
+    onClearValues(): void {
         this.resetForm();
     }
 
@@ -159,38 +275,74 @@ export class ToscaFunctionComponent implements OnInit {
         return this.allowClear && this.toscaFunctionTypeForm.value;
     }
 
-    onConcatFunctionValidityChange(validationEvent: ToscaConcatFunctionValidationEvent) {
+    onConcatFunctionValidityChange(validationEvent: ToscaConcatFunctionValidationEvent): void {
         if (validationEvent.isValid) {
             this.toscaFunctionForm.setValue(validationEvent.toscaConcatFunction);
         } else {
             this.toscaFunctionForm.setValue(undefined);
         }
+        this.emitValidityChange();
+    }
+
+    onCustomFunctionValidityChange(validationEvent: ToscaCustomFunctionValidationEvent): void {
+        if (validationEvent.isValid) {
+            this.toscaFunctionForm.setValue(validationEvent.toscaCustomFunction);
+        } else {
+            this.toscaFunctionForm.setValue(undefined);
+        }
+        this.emitValidityChange();
     }
 
-    onGetFunctionValidityChange(validationEvent: ToscaGetFunctionValidationEvent) {
+    onGetFunctionValidityChange(validationEvent: ToscaGetFunctionValidationEvent): void {
         if (validationEvent.isValid) {
             this.toscaFunctionForm.setValue(validationEvent.toscaGetFunction);
         } else {
             this.toscaFunctionForm.setValue(undefined);
         }
+        this.emitValidityChange();
     }
 
-    onYamlFunctionValidityChange(validationEvent: YamlFunctionValidationEvent) {
+    onYamlFunctionValidityChange(validationEvent: YamlFunctionValidationEvent): void {
         if (validationEvent.isValid) {
             this.toscaFunctionForm.setValue(validationEvent.value);
         } else {
             this.toscaFunctionForm.setValue(undefined);
         }
+        this.emitValidityChange();
+    }
+
+    onFunctionTypeChange(): void {
+        this.toscaFunction = undefined;
+        this.toscaFunctionForm.reset();
     }
 
-    private emitValidityChange() {
-        const isValid = this.validate();
+    private emitValidityChange(): void {
+        const isValid: boolean = this.validate();
         this.onValidityChange.emit({
             isValid: isValid,
-            toscaFunction: isValid ? this.toscaFunctionForm.value : undefined
+            toscaFunction: isValid ? this.buildFunctionFromForm() : undefined
         });
     }
 
+    private buildFunctionFromForm(): ToscaFunction {
+        if (!this.toscaFunctionTypeForm.value) {
+            return undefined;
+        }
+        if (this.isConcatSelected()) {
+            return new ToscaConcatFunction(this.toscaFunctionForm.value);
+        }
+        if (this.isCustomSelected()) {
+            return new ToscaCustomFunction(this.toscaFunctionForm.value);
+        }
+        if (this.isGetFunctionSelected()) {
+            return new ToscaGetFunction(this.toscaFunctionForm.value);
+        }
+        if (this.isYamlFunctionSelected()) {
+            return new YamlFunction(this.toscaFunctionForm.value);
+        }
+
+        console.error(`Function ${this.toscaFunctionTypeForm.value} not supported`);
+    }
 }
 
 export class ToscaFunctionValidationEvent {