UI support for custom functions 11/134011/6
authorJvD_Ericsson <jeff.van.dam@est.tech>
Fri, 31 Mar 2023 13:42:07 +0000 (14:42 +0100)
committerJEFF VAN DAM <jeff.van.dam@est.tech>
Thu, 13 Apr 2023 15:35:54 +0000 (15:35 +0000)
Issue-ID: SDC-4466
Signed-off-by: JvD_Ericsson <jeff.van.dam@est.tech>
Change-Id: I8ff794be8783dc31efecbd1f6abe2efefec6b819

12 files changed:
catalog-ui/src/app/models/tosca-custom-function.ts [new file with mode: 0644]
catalog-ui/src/app/models/tosca-function-type.enum.ts
catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-concat-function/tosca-concat-function.component.spec.ts
catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-custom-function/tosca-custom-function.component.html [new file with mode: 0644]
catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-custom-function/tosca-custom-function.component.less [new file with mode: 0644]
catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-custom-function/tosca-custom-function.component.spec.ts [new file with mode: 0644]
catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-custom-function/tosca-custom-function.component.ts [new file with mode: 0644]
catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.html
catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.ts
catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.module.ts
catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.ts
catalog-ui/src/app/utils/constants.ts

diff --git a/catalog-ui/src/app/models/tosca-custom-function.ts b/catalog-ui/src/app/models/tosca-custom-function.ts
new file mode 100644 (file)
index 0000000..e13be50
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * -
+ *  ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 Nordix Foundation.
+ *  ================================================================================
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *  SPDX-License-Identifier: Apache-2.0
+ *  ============LICENSE_END=========================================================
+ */
+
+import {ToscaFunction} from "./tosca-function";
+import {ToscaFunctionType} from "./tosca-function-type.enum";
+import {ToscaFunctionParameter} from "./tosca-function-parameter";
+import {ToscaGetFunction} from "./tosca-get-function";
+import {YamlFunction} from "./yaml-function";
+import {ToscaStringParameter} from "./tosca-string-parameter";
+
+export class ToscaCustomFunction implements ToscaFunction, ToscaFunctionParameter {
+    name: string;
+    type = ToscaFunctionType.CUSTOM;
+    value: any;
+    parameters: Array<ToscaFunctionParameter> = [];
+
+    constructor(toscaCustomFunction?: ToscaCustomFunction) {
+        if (!toscaCustomFunction) {
+            return;
+        }
+        this.value = toscaCustomFunction.value;
+        this.name = toscaCustomFunction.name;
+        if (toscaCustomFunction.parameters) {
+            toscaCustomFunction.parameters.forEach(parameter => {
+                switch (parameter.type) {
+                    case ToscaFunctionType.GET_INPUT:
+                    case ToscaFunctionType.GET_ATTRIBUTE:
+                    case ToscaFunctionType.GET_PROPERTY:
+                        this.parameters.push(new ToscaGetFunction(<ToscaGetFunction>parameter));
+                        break;
+                    case ToscaFunctionType.CONCAT:
+                        this.parameters.push(new ToscaCustomFunction(<ToscaCustomFunction>parameter));
+                        break;
+                    case ToscaFunctionType.CUSTOM:
+                        this.parameters.push(new ToscaCustomFunction(<ToscaCustomFunction>parameter));
+                        break;
+                    case ToscaFunctionType.YAML:
+                        this.parameters.push(new YamlFunction(<YamlFunction>parameter));
+                        break;
+                    case ToscaFunctionType.STRING:
+                        this.parameters.push(new ToscaStringParameter(<ToscaStringParameter>parameter));
+                        break;
+                    default:
+                        console.error(`Unsupported parameter type "${parameter.type}"`);
+                        this.parameters.push(parameter);
+                }
+            });
+        }
+    }
+
+    public buildValueString(): string {
+        return JSON.stringify(this.buildValueObject());
+    }
+
+    public buildValueObject(): Object {
+        return {
+            [this.name]: this.parameters.map(parameter => parameter.buildValueObject())
+        }
+    }
+
+}
\ No newline at end of file
index 116c881..0394048 100644 (file)
@@ -3,6 +3,7 @@ export enum ToscaFunctionType {
     GET_ATTRIBUTE = 'GET_ATTRIBUTE',
     GET_PROPERTY = 'GET_PROPERTY',
     CONCAT = 'CONCAT',
+    CUSTOM = 'CUSTOM',
     YAML = 'YAML',
     STRING = 'STRING'
 }
index 199f733..65e6339 100644 (file)
@@ -22,6 +22,7 @@
 import {async, ComponentFixture, TestBed} from '@angular/core/testing';
 
 import {ToscaConcatFunctionComponent} from './tosca-concat-function.component';
+import {ToscaCustomFunctionComponent} from '../tosca-custom-function/tosca-custom-function.component';
 import {FormsModule, ReactiveFormsModule} from "@angular/forms";
 import {ToscaFunctionComponent} from "../tosca-function.component";
 import {TranslateModule} from "../../../../shared/translator/translate.module";
@@ -35,7 +36,7 @@ describe('ToscaConcatFunctionComponent', () => {
 
     beforeEach(async(() => {
         TestBed.configureTestingModule({
-            declarations: [ToscaConcatFunctionComponent, ToscaFunctionComponent, ToscaGetFunctionComponent, YamlFunctionComponent],
+            declarations: [ToscaConcatFunctionComponent, ToscaFunctionComponent, ToscaGetFunctionComponent, YamlFunctionComponent, ToscaCustomFunctionComponent],
             imports: [
                 FormsModule,
                 ReactiveFormsModule,
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-custom-function/tosca-custom-function.component.html b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-custom-function/tosca-custom-function.component.html
new file mode 100644 (file)
index 0000000..a67364c
--- /dev/null
@@ -0,0 +1,50 @@
+<!--
+  ~ -
+  ~  ============LICENSE_START=======================================================
+  ~  Copyright (C) 2023 Nordix Foundation.
+  ~  ================================================================================
+  ~  Licensed under the Apache License, Version 2.0 (the "License");
+  ~  you may not use this file except in compliance with the License.
+  ~  You may obtain a copy of the License at
+  ~
+  ~       http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~  Unless required by applicable law or agreed to in writing, software
+  ~  distributed under the License is distributed on an "AS IS" BASIS,
+  ~  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~  See the License for the specific language governing permissions and
+  ~  limitations under the License.
+  ~
+  ~  SPDX-License-Identifier: Apache-2.0
+  ~  ============LICENSE_END=========================================================
+  -->
+
+<div class="component-container">
+  <ng-container [formGroup]="formGroup">
+    <label>Custom function name: </label>
+    <input type="text" formControlName="customName" [value]="name" required/><br/><br/>
+    <div formArrayName="customParameterList">
+      <div *ngFor="let parameter of parameters; let idx = index">
+        <div *ngIf="idx > 0" class="text-center"><span class="custom-plus-icon"></span></div>
+        <div class="parameter-card">
+          <div class="card-content">
+            <ng-container *ngIf="parameter.type === STRING_FUNCTION_TYPE">
+              <input type="text" [formControlName]="idx" [value]="parameter.value"/><br/>
+            </ng-container>
+            <ng-container *ngIf="parameter.type !== STRING_FUNCTION_TYPE">
+              <tosca-function [property]="propertyInputList[idx]" [componentInstanceMap]="componentInstanceMap" [allowClear]="false"
+                              (onValidityChange)="onFunctionValidityChange($event, idx)">
+              </tosca-function>
+            </ng-container>
+            <div class="buttons-container">
+              <span class="delete-icon" (click)="removeParameter(idx)"></span>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </ng-container>
+  <div class="buttons-container">
+    <a class="add-link" (click)="addStringParameter()">String Value</a> <a class="add-link" (click)="addFunction()">TOSCA Function Expression</a>
+  </div>
+</div>
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-custom-function/tosca-custom-function.component.less b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-custom-function/tosca-custom-function.component.less
new file mode 100644 (file)
index 0000000..f37e7be
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * -
+ *  ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 Nordix Foundation.
+ *  ================================================================================
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *  SPDX-License-Identifier: Apache-2.0
+ *  ============LICENSE_END=========================================================
+ */
+
+@import "../../../../../../assets/styles/mixins.less";
+@import "../../../../../../assets/styles/sprite.less";
+
+.component-container {
+    max-height: 500px;
+    overflow: scroll;
+    padding: 0 5px;
+    &::-webkit-scrollbar-track {
+        border: 0;
+    }
+}
+
+.buttons-container {
+    display: flex;
+    flex-direction: row;
+    justify-content: flex-end;
+    gap: 10px;
+    margin-bottom: 10px;
+
+    .add-link {
+        .f-color.a();
+        .f-type._14_m();
+        cursor: pointer;
+
+        &:before {
+            .sprite-new();
+            .plus-icon();
+            margin-right: 5px;
+            content: "";
+        }
+
+        &:hover {
+            .f-color.b();
+            &:before {
+                .sprite-new();
+                .plus-icon-hover();
+            }
+        }
+    }
+
+    .delete-icon {
+        .sprite-new();
+        .delete-btn();
+        cursor: pointer;
+    }
+}
+
+.parameter-card {
+    border: 2px solid @main_color_o;
+    box-shadow: 0 0 0 0 rgba(0,0,0,0.2);
+    //padding: 10px;
+    border-radius: 2px;
+    transition: 0.3s;
+    margin-bottom: 5px;
+    &:hover {
+        box-shadow: 0 1px 8px 2px rgba(0,0,0,0.2);
+    }
+
+    .card-content {
+        padding: 5px 10px;
+    }
+
+    .text-center {
+        text-align: center;
+    }
+
+    input {
+        border: solid 1px @main_color_o;
+    }
+}
+
+.custom-plus-icon {
+    .sprite-new();
+    background-position: -216px -1388px;
+    width: 14px;
+    height: 14px;
+}
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-custom-function/tosca-custom-function.component.spec.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-custom-function/tosca-custom-function.component.spec.ts
new file mode 100644 (file)
index 0000000..9c3c188
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * -
+ *  ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 Nordix Foundation.
+ *  ================================================================================
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *  SPDX-License-Identifier: Apache-2.0
+ *  ============LICENSE_END=========================================================
+ */
+
+import {async, ComponentFixture, TestBed} from '@angular/core/testing';
+
+import {ToscaConcatFunctionComponent} from '../tosca-concat-function/tosca-concat-function.component';
+import {ToscaCustomFunctionComponent} from './tosca-custom-function.component';
+import {FormsModule, ReactiveFormsModule} from "@angular/forms";
+import {ToscaFunctionComponent} from "../tosca-function.component";
+import {TranslateModule} from "../../../../shared/translator/translate.module";
+import {ToscaGetFunctionComponent} from "../tosca-get-function/tosca-get-function.component";
+import {UiElementsModule} from "../../../../components/ui/ui-elements.module";
+import {YamlFunctionComponent} from "../yaml-function/yaml-function.component";
+
+describe('ToscaCustomFunctionComponent', () => {
+    let component: ToscaCustomFunctionComponent;
+    let fixture: ComponentFixture<ToscaCustomFunctionComponent>;
+
+    beforeEach(async(() => {
+        TestBed.configureTestingModule({
+            declarations: [
+                ToscaCustomFunctionComponent,
+                ToscaConcatFunctionComponent,
+                ToscaFunctionComponent,
+                ToscaGetFunctionComponent,
+                YamlFunctionComponent],
+            imports: [
+                FormsModule,
+                ReactiveFormsModule,
+                TranslateModule,
+                UiElementsModule
+            ]
+        })
+        .compileComponents();
+    }));
+
+    beforeEach(() => {
+        fixture = TestBed.createComponent(ToscaCustomFunctionComponent);
+        component = fixture.componentInstance;
+        fixture.detectChanges();
+    });
+
+    it('should create', () => {
+        expect(component).toBeTruthy();
+    });
+});
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-custom-function/tosca-custom-function.component.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-custom-function/tosca-custom-function.component.ts
new file mode 100644 (file)
index 0000000..f368788
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * -
+ *  ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 Nordix Foundation.
+ *  ================================================================================
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *  SPDX-License-Identifier: Apache-2.0
+ *  ============LICENSE_END=========================================================
+ */
+
+import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
+import {FormArray, FormControl, FormGroup, Validators} from "@angular/forms";
+import {ToscaCustomFunction} from "../../../../../models/tosca-custom-function";
+import {ToscaFunctionParameter} from "../../../../../models/tosca-function-parameter";
+import {ToscaStringParameter} from "../../../../../models/tosca-string-parameter";
+import {ToscaFunctionType} from "../../../../../models/tosca-function-type.enum";
+import {PropertyBEModel} from "../../../../../models/properties-inputs/property-be-model";
+import {PROPERTY_TYPES} from "../../../../../utils/constants";
+import {InstanceFeDetails} from "../../../../../models/instance-fe-details";
+import {ToscaFunctionValidationEvent} from "../tosca-function.component";
+import {ToscaFunction} from "../../../../../models/tosca-function";
+
+@Component({
+    selector: 'app-tosca-custom-function',
+    templateUrl: './tosca-custom-function.component.html',
+    styleUrls: ['./tosca-custom-function.component.less']
+})
+export class ToscaCustomFunctionComponent implements OnInit {
+
+    @Input() toscaCustomFunction: ToscaCustomFunction;
+    @Input() componentInstanceMap: Map<string, InstanceFeDetails> = new Map<string, InstanceFeDetails>();
+    @Output() onValidFunction: EventEmitter<ToscaCustomFunction> = new EventEmitter<ToscaCustomFunction>();
+    @Output() onValidityChange: EventEmitter<ToscaCustomFunctionValidationEvent> = new EventEmitter<ToscaCustomFunctionValidationEvent>();
+
+    name: string = '';
+    customFunctionFormName: FormControl = new FormControl('', [Validators.required, Validators.minLength(1)]);
+    customParameterFormArray: FormArray = new FormArray([], Validators.minLength(1));
+    formGroup: FormGroup = new FormGroup(
+        {
+            'customParameterList': this.customParameterFormArray,
+            'customName': this.customFunctionFormName
+        }
+    );
+
+    parameters: ToscaFunctionParameter[] = [];
+    propertyInputList: Array<PropertyBEModel> = [];
+
+    STRING_FUNCTION_TYPE = ToscaFunctionType.STRING
+
+    ngOnInit() {
+        this.initForm();
+    }
+
+    private initForm(): void {
+        this.formGroup.valueChanges.subscribe(() => {
+            this.onValidityChange.emit({
+                isValid: this.formGroup.valid,
+                toscaCustomFunction: this.formGroup.valid ? this.buildCustomFunctionFromForm() : undefined
+            })
+            if (this.formGroup.valid) {
+                this.onValidFunction.emit(this.buildCustomFunctionFromForm());
+            }
+        });
+        if (!this.toscaCustomFunction) {
+            return;
+        }
+        if (this.toscaCustomFunction.parameters) {
+            this.name = this.toscaCustomFunction.name;
+            this.customFunctionFormName.setValue(this.name)
+            this.parameters = Array.from(this.toscaCustomFunction.parameters);
+            for (const parameter of this.parameters) {
+                if (parameter.type !== PROPERTY_TYPES.STRING) {
+                    const propertyBEModel = this.createProperty(parameter.value);
+                    propertyBEModel.toscaFunction = <ToscaFunction> parameter;
+                    this.propertyInputList.push(propertyBEModel);
+                    this.customParameterFormArray.push(
+                        new FormControl(parameter, [Validators.required, Validators.minLength(1)])
+                    );
+                } else {
+                    this.propertyInputList.push(undefined);
+                    this.customParameterFormArray.push(
+                        new FormControl(parameter.value, [Validators.required, Validators.minLength(1)])
+                    );
+                }
+            }
+        }
+    }
+
+    private buildCustomFunctionFromForm(): ToscaCustomFunction {
+        const toscaCustomFunction1 = new ToscaCustomFunction();
+        toscaCustomFunction1.name = this.customFunctionFormName.value;
+        this.customParameterFormArray.controls.forEach(control => {
+            const value = control.value;
+            if (typeof value === 'string') {
+                const stringParameter = new ToscaStringParameter();
+                stringParameter.value = value;
+                toscaCustomFunction1.parameters.push(stringParameter);
+            } else {
+                toscaCustomFunction1.parameters.push(control.value);
+            }
+        });
+
+        return toscaCustomFunction1;
+    }
+
+    addFunction(): void {
+        this.propertyInputList.push(this.createProperty());
+        this.parameters.push({} as ToscaFunctionParameter);
+        this.customParameterFormArray.push(
+            new FormControl(undefined, [Validators.required, Validators.minLength(1)])
+        );
+    }
+
+    addStringParameter(): void {
+        const toscaStringParameter = new ToscaStringParameter();
+        toscaStringParameter.value = ''
+        this.parameters.push(toscaStringParameter);
+        this.propertyInputList.push(undefined);
+        this.customParameterFormArray.push(
+            new FormControl('', [Validators.required, Validators.minLength(1)])
+        );
+    }
+
+    removeParameter(position): void {
+        this.propertyInputList.splice(position, 1);
+        this.parameters.splice(position, 1);
+        this.customParameterFormArray.removeAt(position);
+    }
+
+    createProperty(value?: any): PropertyBEModel {
+        const property = new PropertyBEModel();
+        property.type = PROPERTY_TYPES.ANY;
+        property.value = value ? value : undefined;
+        return property;
+    }
+
+    onFunctionValidityChange(event: ToscaFunctionValidationEvent, index: number): void {
+        if (event.isValid && event.toscaFunction) {
+            this.customParameterFormArray.controls[index].setValue(event.toscaFunction)
+        } else {
+            this.customParameterFormArray.controls[index].setValue(undefined);
+        }
+    }
+}
+
+export interface ToscaCustomFunctionValidationEvent {
+    isValid: boolean,
+    toscaCustomFunction: ToscaCustomFunction,
+}
index 74a06ba..3ec3fa4 100644 (file)
       <app-tosca-concat-function [toscaConcatFunction]="toscaFunction" [componentInstanceMap]="componentInstanceMap"
                                  (onValidityChange)="onConcatFunctionValidityChange($event)"></app-tosca-concat-function>
     </div>
+    <div *ngIf="isCustomSelected()">
+      <app-tosca-custom-function [toscaCustomFunction]="toscaFunction" [componentInstanceMap]="componentInstanceMap"
+                                 (onValidityChange)="onCustomFunctionValidityChange($event)"></app-tosca-custom-function>
+    </div>
     <div *ngIf="isGetFunctionSelected()">
       <app-tosca-get-function [property]="property" [toscaGetFunction]="toscaFunction"
                               [componentInstanceMap]="componentInstanceMap"
index d46ac2e..6783f5b 100644 (file)
@@ -29,9 +29,11 @@ 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, PROPERTY_DATA} 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";
 
 @Component({
@@ -142,7 +144,8 @@ export class ToscaFunctionComponent implements OnInit, OnChanges {
         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) {
+        this.toscaFunctions.push(ToscaFunctionType.CUSTOM);
+        if (this.property.type === PROPERTY_TYPES.STRING || this.property.type === PROPERTY_TYPES.ANY) {
             this.toscaFunctions.push(ToscaFunctionType.CONCAT);
         }
         this.toscaFunctions.push(ToscaFunctionType.YAML);
@@ -169,6 +172,10 @@ export class ToscaFunctionComponent implements OnInit, OnChanges {
         return this.formGroup.get('toscaFunctionType').value === ToscaFunctionType.CONCAT;
     }
 
+    isCustomSelected(): boolean {
+        return this.formGroup.get('toscaFunctionType').value === ToscaFunctionType.CUSTOM;
+    }
+
     isGetFunctionSelected(): boolean {
         return this.isGetInputSelected() || this.isGetPropertySelected() || this.isGetAttributeSelected();
     }
@@ -193,6 +200,14 @@ export class ToscaFunctionComponent implements OnInit, OnChanges {
         }
     }
 
+    onCustomFunctionValidityChange(validationEvent: ToscaCustomFunctionValidationEvent): void {
+        if (validationEvent.isValid) {
+            this.toscaFunctionForm.setValue(validationEvent.toscaCustomFunction);
+        } else {
+            this.toscaFunctionForm.setValue(undefined);
+        }
+    }
+
     onGetFunctionValidityChange(validationEvent: ToscaGetFunctionValidationEvent): void {
         if (validationEvent.isValid) {
             this.toscaFunctionForm.setValue(validationEvent.toscaGetFunction);
@@ -229,6 +244,9 @@ export class ToscaFunctionComponent implements OnInit, OnChanges {
         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);
         }
index bcf1072..1452ed6 100644 (file)
@@ -27,6 +27,7 @@ import { ToscaFunctionComponent } from './tosca-function.component';
 import { SdcUiComponentsModule } from 'onap-ui-angular';
 import { ToscaGetFunctionComponent } from './tosca-get-function/tosca-get-function.component';
 import { ToscaConcatFunctionComponent } from './tosca-concat-function/tosca-concat-function.component';
+import { ToscaCustomFunctionComponent } from './tosca-custom-function/tosca-custom-function.component';
 import { YamlFunctionComponent } from './yaml-function/yaml-function.component';
 
 @NgModule({
@@ -34,6 +35,7 @@ import { YamlFunctionComponent } from './yaml-function/yaml-function.component';
         ToscaFunctionComponent,
         ToscaGetFunctionComponent,
         ToscaConcatFunctionComponent,
+        ToscaCustomFunctionComponent,
         YamlFunctionComponent,
     ],
     imports: [
index 656d7d6..36ead13 100644 (file)
@@ -387,6 +387,9 @@ export class ToscaGetFunctionComponent implements OnInit, OnChanges {
     }
 
     private hasSameType(property: PropertyBEModel | AttributeBEModel): boolean {
+        if (this.property.type === PROPERTY_TYPES.ANY) {
+            return true;
+        }
         if (this.typeHasSchema(this.property.type)) {
             if ((this.property instanceof PropertyDeclareAPIModel && (<PropertyDeclareAPIModel> this.property).input instanceof DerivedFEProperty) || this.compositionMap) {
                 let childObject : DerivedFEProperty = (<DerivedFEProperty>(<PropertyDeclareAPIModel> this.property).input);
index 087ecaf..927c778 100644 (file)
@@ -150,6 +150,7 @@ export class SEVERITY {
 }
 
 export class PROPERTY_TYPES {
+    public static ANY = 'any';
     public static STRING = 'string';
     public static INTEGER = 'integer';
     public static TIMESTAMP = 'timestamp';