2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2021 Nordix Foundation. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 * SPDX-License-Identifier: Apache-2.0
19 * ============LICENSE_END=========================================================
21 import {Component, EventEmitter, Output, ViewChild} from '@angular/core';
22 import { FormControl } from '@angular/forms';
23 import {UIInterfaceModel} from "../interface-operations.component";
24 import {InputOperationParameter, InterfaceOperationModel, IOperationParamsList} from "../../../../../models/interfaceOperation";
25 import {TranslateService} from "../../../../shared/translator/translate.service";
26 import {DropdownValue} from "../../../../components/ui/form-components/dropdown/ui-element-dropdown.component";
27 import {ArtifactModel} from "../../../../../models/artifacts";
28 import {PropertyBEModel} from "../../../../../models/properties-inputs/property-be-model";
29 import {PropertyParamRowComponent} from "./property-param-row/property-param-row.component";
30 import {PropertyFEModel} from "../../../../../models/properties-inputs/property-fe-model";
31 import {IDropDownOption} from 'onap-ui-angular';
32 import {ComponentServiceNg2} from "../../../../services/component-services/component.service";
33 import {DropDownComponent} from "onap-ui-angular/dist/form-elements/dropdown/dropdown.component";
34 import {DataTypeService} from "../../../../services/data-type.service";
35 import {Observable} from "rxjs/Observable";
36 import {DataTypeModel} from "../../../../../models/data-types";
37 import {InstanceFeDetails} from "../../../../../models/instance-fe-details";
38 import {TopologyTemplateService} from "app/ng2/services/component-services/topology-template.service";
39 import {CustomToscaFunction} from "../../../../../models/default-custom-functions";
42 selector: 'operation-handler',
43 templateUrl: './interface-operation-handler.component.html',
44 styleUrls: ['./interface-operation-handler.component.less'],
45 providers: [TranslateService]
47 export class InterfaceOperationHandlerComponent {
49 @Output('propertyChanged') emitter: EventEmitter<PropertyFEModel> = new EventEmitter<PropertyFEModel>();
50 @ViewChild('interfaceOperationDropDown') interfaceOperationDropDown: DropDownComponent;
53 componentInstanceMap: Map<string, InstanceFeDetails>;
54 toscaArtifactTypes: Array<DropdownValue>;
55 selectedInterface: UIInterfaceModel;
56 selectedInterfaceOperation: InterfaceOperationModel;
57 validityChangedCallback: Function;
60 validImplementationProps:boolean;
64 dataTypeMap$: Observable<Map<string, DataTypeModel>>;
65 dataTypeMap: Map<string, DataTypeModel>;
66 interfaceType: string;
67 artifactVersion: string;
69 interfaceOperationName: string;
70 operationToUpdate: InterfaceOperationModel;
71 inputs: Array<InputOperationParameter> = [];
72 properties: Array<PropertyParamRowComponent> = [];
73 isLoading: boolean = false;
76 validImplementationProps:boolean;
77 interfaceTypes: Array<DropdownValue> = [];
78 interfaceTypeOptions: Array<DropDownOption> = [];
79 selectedInterfaceType: DropDownOption = undefined;
80 interfaceOperationMap: Map<string, Array<string>> = new Map<string, Array<string>>();
81 interfaceOperationOptions: Array<DropDownOption> = [];
82 selectedInterfaceOperation: DropDownOption = undefined;
84 toscaArtifactTypeSelected: string;
85 toscaArtifactTypeProperties: Array<PropertyBEModel> = [];
86 artifactTypeProperties: Array<InputOperationParameter> = [];
87 toscaArtifactTypes: Array<DropdownValue> = [];
88 componentInstanceMap: Map<string, InstanceFeDetails>;
89 customToscaFunctions: Array<CustomToscaFunction>;
90 enableAddArtifactImplementation: boolean;
91 propertyValueValid: boolean = true;
92 inputTypeOptions: any[];
93 timeoutValue = new FormControl('');
94 timeoutType = new FormControl('');
96 constructor(private dataTypeService: DataTypeService,
97 private componentServiceNg2: ComponentServiceNg2,
98 private topologyTemplateService: TopologyTemplateService) {
102 this.isViewOnly = this.input.isViewOnly;
103 this.isEdit = this.input.isEdit;
104 this.validImplementationProps = this.input.validImplementationProps;
105 this.componentInstanceMap = this.input.componentInstanceMap ? this.input.componentInstanceMap : null;
106 this.interfaceType = this.input.selectedInterface.type;
107 this.operationToUpdate = new InterfaceOperationModel(this.input.selectedInterfaceOperation);
108 this.operationToUpdate.interfaceId = this.input.selectedInterface.uniqueId;
109 this.operationToUpdate.interfaceType = this.input.selectedInterface.type;
110 this.modelName = this.input.modelName;
111 this.timeoutType.setValue('sec');
112 if (this.operationToUpdate.implementation && this.operationToUpdate.implementation.timeout != null) {
113 this.timeoutValue.setValue(this.operationToUpdate.implementation.timeout);
114 let timeout = this.timeoutValue.value / 3600;
115 if (Number.isInteger(timeout)) {
116 if (timeout > 23 && Number.isInteger(timeout / 24)) {
117 this.timeoutValue.setValue(timeout / 24);
118 this.timeoutType.setValue("day");
120 this.timeoutValue.setValue(timeout);
121 this.timeoutType.setValue("hour");
123 } else if (Number.isInteger(timeout / 24)) {
124 this.timeoutValue.setValue(timeout / 24);
125 this.timeoutType.setValue("day");
128 this.initCustomToscaFunctions();
130 this.removeImplementationQuote();
131 this.loadInterfaceOperationImplementation();
133 this.dataTypeMap$ = new Observable<Map<string, DataTypeModel>>(subscriber => {
134 this.dataTypeService.findAllDataTypesByModel(this.modelName)
135 .then((dataTypesMap: Map<string, DataTypeModel>) => {
136 subscriber.next(dataTypesMap);
139 this.dataTypeMap$.subscribe(value => {
140 this.dataTypeMap = value;
144 private initInputs() {
145 if (!this.operationToUpdate.inputs) {
146 this.operationToUpdate.inputs = new class implements IOperationParamsList {
147 listToscaDataDefinition: Array<InputOperationParameter> = [];
151 this.inputs = Array.from(this.operationToUpdate.inputs.listToscaDataDefinition);
152 this.removeImplementationQuote();
153 this.loadInterfaceOperationImplementation();
154 this.loadInterfaceType();
157 private initCustomToscaFunctions() {
158 this.customToscaFunctions = [];
159 this.topologyTemplateService.getDefaultCustomFunction().toPromise().then((data) => {
161 for (let customFunction of data) {
162 this.customToscaFunctions.push(new CustomToscaFunction(customFunction));
168 private loadInterfaceType() {
169 this.componentServiceNg2.getInterfaceTypesByModel(this.modelName)
170 .subscribe(response => {
172 this.interfaceOperationMap = new Map<string, Array<string>>();
173 for (const interfaceType of Object.keys(response).sort()) {
174 const operationList = response[interfaceType];
175 operationList.sort();
176 this.interfaceOperationMap.set(interfaceType, operationList);
177 const operationDropDownOption: DropDownOption = new DropDownOption(interfaceType);
178 this.interfaceTypeOptions.push(operationDropDownOption);
179 if (this.interfaceType == interfaceType) {
180 this.selectedInterfaceType = operationDropDownOption;
183 this.loadInterfaceTypeOperations();
188 loadInterfaceTypeOperations() {
189 this.interfaceOperationOptions = new Array<DropDownOption>();
190 const interfaceOperationList = this.interfaceOperationMap.get(this.interfaceType);
192 if (interfaceOperationList) {
193 interfaceOperationList.forEach(operationName => {
194 const operationOption = new DropDownOption(operationName, operationName);
195 this.interfaceOperationOptions.push(operationOption);
196 if (this.operationToUpdate.name == operationName) {
197 this.selectedInterfaceOperation = operationOption
202 this.interfaceOperationDropDown.allOptions = this.interfaceOperationOptions;
205 private loadInterfaceOperationImplementation() {
206 this.toscaArtifactTypes = this.input.toscaArtifactTypes;
207 if (this.operationToUpdate.implementation) {
208 this.artifactVersion = this.operationToUpdate.implementation.artifactVersion;
209 this.artifactName = this.operationToUpdate.implementation.artifactName;
210 this.toscaArtifactTypeProperties = this.operationToUpdate.implementation.properties;
212 this.artifactTypeProperties = this.convertArtifactsPropertiesToInput();
213 this.getArtifactTypesSelected();
216 onDescriptionChange = (value: any): void => {
217 this.operationToUpdate.description = value;
220 onURIChange(value: string | undefined) {
221 if(!this.operationToUpdate.implementation){
222 let artifact = new ArtifactModel();
223 this.operationToUpdate.implementation = artifact;
225 this.operationToUpdate.implementation.artifactName = value ? value : '';
228 onPropertyValueChange = (propertyValue) => {
229 this.emitter.emit(propertyValue);
232 onMarkToAddArtifactToImplementation(event: boolean) {
234 this.toscaArtifactTypeSelected = undefined;
235 this.artifactVersion = undefined;
236 if (this.operationToUpdate.implementation.artifactType) {
237 this.operationToUpdate.implementation.artifactVersion = '';
238 this.operationToUpdate.implementation.artifactType = '';
240 this.toscaArtifactTypeProperties = undefined;
241 this.artifactTypeProperties = undefined;
243 this.getArtifactTypesSelected();
245 this.enableAddArtifactImplementation = event;
248 onSelectToscaArtifactType(type: IDropDownOption) {
250 let toscaArtifactType = type.value;
251 let artifact = new ArtifactModel();
252 artifact.artifactName = this.operationToUpdate.implementation.artifactName;
253 artifact.artifactVersion = this.operationToUpdate.implementation.artifactVersion;
254 artifact.artifactType = toscaArtifactType.type;
255 artifact.properties = toscaArtifactType.properties;
256 this.toscaArtifactTypeProperties = artifact.properties;
257 this.artifactTypeProperties = this.convertArtifactsPropertiesToInput();
258 this.toscaArtifactTypeSelected = artifact.artifactType;
259 this.operationToUpdate.implementation = artifact;
260 this.getArtifactTypesSelected();
264 onArtifactVersionChange(value: string | undefined) {
265 this.operationToUpdate.implementation.artifactVersion = value ? value : '';
268 onAddInput(inputOperationParameter: InputOperationParameter) {
269 this.addInput(inputOperationParameter);
272 propertyValueValidation = (propertyValue): void => {
273 this.onPropertyValueChange(propertyValue);
274 this.propertyValueValid = propertyValue.isValid;
277 onRemoveInput = (inputParam: InputOperationParameter): void => {
278 let index = this.inputs.indexOf(inputParam);
279 this.inputs.splice(index, 1);
282 timeoutConversion = (): void => {
283 let timeout = this.timeoutValue.value;
284 if (timeout != null) {
285 if (this.timeoutType.value == null || this.timeoutType.value == 'sec') {
286 this.operationToUpdate.implementation.timeout = timeout;
289 if (this.timeoutType.value == 'hour') {
290 this.operationToUpdate.implementation.timeout = timeout * 3600;
291 } else if (this.timeoutType.value == 'day') {
292 this.operationToUpdate.implementation.timeout = (timeout * 24) * 3600;
297 private removeImplementationQuote(): void {
298 if (this.operationToUpdate.implementation) {
299 if (!this.operationToUpdate.implementation
300 || !this.operationToUpdate.implementation.artifactName) {
304 let implementation = this.operationToUpdate.implementation.artifactName.trim();
306 if (implementation.startsWith("'") && implementation.endsWith("'")) {
307 this.operationToUpdate.implementation.artifactName = implementation.slice(1, -1);
312 private getArtifactTypesSelected() {
313 if (this.operationToUpdate.implementation && this.operationToUpdate.implementation.artifactType) {
315 this.artifactName ? this.artifactName : this.operationToUpdate.implementation.artifactName;
316 this.toscaArtifactTypeSelected = this.operationToUpdate.implementation.artifactType;
317 this.artifactVersion =
318 this.artifactVersion ? this.artifactVersion : this.operationToUpdate.implementation.artifactVersion;
319 this.toscaArtifactTypeProperties = this.operationToUpdate.implementation.properties;
320 this.artifactTypeProperties = this.convertArtifactsPropertiesToInput();
321 this.enableAddArtifactImplementation = true;
325 toDropDownOption(val: string) {
326 return { value : val, label: val };
330 * Handles the input value change event.
331 * @param changedInput the changed input
333 onInputValueChange(changedInput: InputOperationParameter) {
334 if (changedInput.value instanceof Object) {
335 changedInput.value = JSON.stringify(changedInput.value);
337 const inputOperationParameter = this.inputs.find(value => value.name == changedInput.name);
338 inputOperationParameter.toscaFunction = null;
339 inputOperationParameter.value = changedInput.value;
340 inputOperationParameter.subPropertyToscaFunctions = changedInput.subPropertyToscaFunctions;
341 if (changedInput.isToscaFunction()) {
342 inputOperationParameter.toscaFunction = changedInput.toscaFunction;
343 inputOperationParameter.value = changedInput.toscaFunction.buildValueString();
347 onArtifactPropertyValueChange(changedProperty: InputOperationParameter) {
348 const property = this.toscaArtifactTypeProperties.find(artifactProperty => artifactProperty.name == changedProperty.name);
349 if (changedProperty.value instanceof Object) {
350 changedProperty.value = JSON.stringify(changedProperty.value);
352 property.toscaFunction = null;
353 property.value = changedProperty.value;
354 if (changedProperty.isToscaFunction()) {
355 property.toscaFunction = changedProperty.toscaFunction;
356 property.value = changedProperty.toscaFunction.buildValueString();
360 implementationPropsValidityChange(validImplementationProps: boolean) {
361 this.validImplementationProps = validImplementationProps;
365 * Handles the add input event.
366 * @param input the input to add
369 private addInput(input: InputOperationParameter) {
370 this.operationToUpdate.inputs.listToscaDataDefinition.push(input);
371 this.inputs = Array.from(this.operationToUpdate.inputs.listToscaDataDefinition);
375 * Return a list with current input names.
377 collectInputNames() {
378 return this.inputs.map((input) => input.name);
382 * Handles the delete input event.
383 * @param inputName the name of the input to be deleted
385 onInputDelete(inputName: string) {
386 const currentInputs = this.operationToUpdate.inputs.listToscaDataDefinition;
387 const input1 = currentInputs.find(value => value.name === inputName);
388 const indexOfInput = currentInputs.indexOf(input1);
389 if (indexOfInput === -1) {
390 console.error(`Could not delete input '${inputName}'. Input not found.`);
393 currentInputs.splice(currentInputs.indexOf(input1), 1);
394 this.inputs = Array.from(currentInputs);
397 private convertArtifactsPropertiesToInput(): Array<InputOperationParameter> {
398 if (!this.toscaArtifactTypeProperties) {
401 const inputList: Array<InputOperationParameter> = [];
402 this.toscaArtifactTypeProperties.forEach(property => {
403 const input = new InputOperationParameter();
404 input.name = property.name;
405 input.type = property.type;
406 input.schema = property.schema;
407 input.toscaDefaultValue = property.defaultValue;
408 input.value = property.value;
409 input.toscaFunction = property.toscaFunction;
410 inputList.push(input);
415 onSelectInterface(dropDownOption: DropDownOption) {
416 if (dropDownOption) {
417 this.setInterfaceType(dropDownOption);
419 this.setInterfaceType(undefined);
421 this.setInterfaceOperation(undefined);
422 this.interfaceOperationDropDown.selectOption({} as IDropDownOption);
423 this.loadInterfaceTypeOperations();
426 onSelectOperation(dropDownOption: DropDownOption) {
427 if (this.selectedInterfaceType && dropDownOption) {
428 this.setInterfaceOperation(dropDownOption);
432 private setInterfaceType(dropDownOption: DropDownOption) {
433 this.selectedInterfaceType = dropDownOption ? dropDownOption : undefined;
434 this.interfaceType = dropDownOption ? dropDownOption.value : undefined;
435 this.operationToUpdate.interfaceType = dropDownOption ? dropDownOption.value : undefined;
436 this.operationToUpdate.interfaceId = dropDownOption ? dropDownOption.value : undefined;
439 private setInterfaceOperation(dropDownOption: DropDownOption) {
440 this.operationToUpdate.name = dropDownOption ? dropDownOption.value : undefined;
441 this.operationToUpdate.operationType = dropDownOption ? dropDownOption.value : undefined;
442 this.selectedInterfaceOperation = dropDownOption ? dropDownOption : undefined;
446 class DropDownOption implements IDropDownOption {
450 constructor(value: string, label?: string) {
452 this.label = label || value;