216dc3284e90428fae81b33271fc5a44f30e026f
[sdc.git] /
1 /*
2 * ============LICENSE_START=======================================================
3 * SDC
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
10 *
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.
17 *
18 *  SPDX-License-Identifier: Apache-2.0
19 *  ============LICENSE_END=========================================================
20 */
21 import {Component, EventEmitter, Output, ViewChild} from '@angular/core';
22 import {UIInterfaceModel} from "../interface-operations.component";
23 import {InputOperationParameter, InterfaceOperationModel, IOperationParamsList} from "../../../../../models/interfaceOperation";
24 import {TranslateService} from "../../../../shared/translator/translate.service";
25 import {DropdownValue} from "../../../../components/ui/form-components/dropdown/ui-element-dropdown.component";
26 import {ArtifactModel} from "../../../../../models/artifacts";
27 import {PropertyBEModel} from "../../../../../models/properties-inputs/property-be-model";
28 import {PropertyParamRowComponent} from "./property-param-row/property-param-row.component";
29 import {PropertyFEModel} from "../../../../../models/properties-inputs/property-fe-model";
30 import {IDropDownOption} from 'onap-ui-angular';
31 import {ComponentServiceNg2} from "../../../../services/component-services/component.service";
32 import {DropDownComponent} from "onap-ui-angular/dist/form-elements/dropdown/dropdown.component";
33 import {DataTypeService} from "../../../../services/data-type.service";
34 import {Observable} from "rxjs/Observable";
35 import {DataTypeModel} from "../../../../../models/data-types";
36
37 @Component({
38     selector: 'operation-handler',
39     templateUrl: './interface-operation-handler.component.html',
40     styleUrls: ['./interface-operation-handler.component.less'],
41     providers: [TranslateService]
42 })
43 export class InterfaceOperationHandlerComponent {
44
45     @Output('propertyChanged') emitter: EventEmitter<PropertyFEModel> = new EventEmitter<PropertyFEModel>();
46     @ViewChild('interfaceOperationDropDown') interfaceOperationDropDown: DropDownComponent;
47
48     input: {
49         toscaArtifactTypes: Array<DropdownValue>;
50         selectedInterface: UIInterfaceModel;
51         selectedInterfaceOperation: InterfaceOperationModel;
52         validityChangedCallback: Function;
53         isViewOnly: boolean;
54         isEdit: boolean;
55         modelName: string;
56     };
57
58     dataTypeMap$: Observable<Map<string, DataTypeModel>>;
59     dataTypeMap: Map<string, DataTypeModel>;
60     interfaceType: string;
61     artifactVersion: string;
62     artifactName: string;
63     interfaceOperationName: string;
64     operationToUpdate: InterfaceOperationModel;
65     inputs: Array<InputOperationParameter> = [];
66     properties: Array<PropertyParamRowComponent> = [];
67     isLoading: boolean = false;
68     isViewOnly: boolean;
69     isEdit: boolean;
70     interfaceTypes: Array<DropdownValue> = [];
71     interfaceTypeOptions: Array<DropDownOption> = [];
72     selectedInterfaceType: DropDownOption = undefined;
73     interfaceOperationMap: Map<string, Array<string>> = new Map<string, Array<string>>();
74     interfaceOperationOptions: Array<DropDownOption> = [];
75     selectedInterfaceOperation: DropDownOption = undefined;
76     modelName: string;
77     toscaArtifactTypeSelected: string;
78     toscaArtifactTypeProperties: Array<PropertyBEModel> = [];
79     artifactTypeProperties: Array<InputOperationParameter> = [];
80     toscaArtifactTypes: Array<DropdownValue> = [];
81     enableAddArtifactImplementation: boolean;
82     propertyValueValid: boolean = true;
83     inputTypeOptions: any[];
84
85     constructor(private dataTypeService: DataTypeService, private componentServiceNg2: ComponentServiceNg2) {
86     }
87
88     ngOnInit() {
89         this.isViewOnly = this.input.isViewOnly;
90         this.isEdit = this.input.isEdit;
91         this.interfaceType = this.input.selectedInterface.type;
92         this.operationToUpdate = new InterfaceOperationModel(this.input.selectedInterfaceOperation);
93         this.operationToUpdate.interfaceId = this.input.selectedInterface.uniqueId;
94         this.operationToUpdate.interfaceType = this.input.selectedInterface.type;
95         this.modelName = this.input.modelName;
96         this.initInputs();
97         this.removeImplementationQuote();
98         this.loadInterfaceOperationImplementation();
99
100         this.dataTypeMap$ = new Observable<Map<string, DataTypeModel>>(subscriber => {
101             this.dataTypeService.findAllDataTypesByModel(this.modelName)
102             .then((dataTypesMap: Map<string, DataTypeModel>) => {
103                 subscriber.next(dataTypesMap);
104             });
105         });
106         this.dataTypeMap$.subscribe(value => {
107             this.dataTypeMap = value;
108         });
109     }
110
111     private initInputs() {
112         if (!this.operationToUpdate.inputs) {
113             this.operationToUpdate.inputs = new class implements IOperationParamsList {
114                 listToscaDataDefinition: Array<InputOperationParameter> = [];
115             }
116         }
117
118         this.inputs = Array.from(this.operationToUpdate.inputs.listToscaDataDefinition);
119         this.removeImplementationQuote();
120         this.loadInterfaceOperationImplementation();
121         this.loadInterfaceType();
122     }
123
124     private loadInterfaceType() {
125         this.componentServiceNg2.getInterfaceTypesByModel(this.modelName)
126         .subscribe(response => {
127             if (response) {
128                 this.interfaceOperationMap = new Map<string, Array<string>>();
129                 for (const interfaceType of Object.keys(response).sort()) {
130                     const operationList = response[interfaceType];
131                     operationList.sort();
132                     this.interfaceOperationMap.set(interfaceType, operationList);
133                     const operationDropDownOption: DropDownOption = new DropDownOption(interfaceType);
134                     this.interfaceTypeOptions.push(operationDropDownOption);
135                     if (this.interfaceType == interfaceType) {
136                         this.selectedInterfaceType = operationDropDownOption;
137                     }
138                 }
139                 this.loadInterfaceTypeOperations();
140             }
141         });
142     }
143
144     loadInterfaceTypeOperations() {
145         this.interfaceOperationOptions = new Array<DropDownOption>();
146         const interfaceOperationList = this.interfaceOperationMap.get(this.interfaceType);
147
148         if (interfaceOperationList) {
149             interfaceOperationList.forEach(operationName => {
150                 const operationOption = new DropDownOption(operationName, operationName);
151                 this.interfaceOperationOptions.push(operationOption);
152                 if (this.operationToUpdate.name == operationName) {
153                     this.selectedInterfaceOperation = operationOption
154                 }
155             });
156         }
157
158         this.interfaceOperationDropDown.allOptions = this.interfaceOperationOptions;
159     }
160
161     private loadInterfaceOperationImplementation() {
162         this.toscaArtifactTypes = this.input.toscaArtifactTypes;
163         if (this.operationToUpdate.implementation) {
164             this.artifactVersion = this.operationToUpdate.implementation.artifactVersion;
165             this.artifactName = this.operationToUpdate.implementation.artifactName;
166             this.toscaArtifactTypeProperties = this.operationToUpdate.implementation.properties;
167         }
168         this.artifactTypeProperties = this.convertArtifactsPropertiesToInput();
169         this.getArtifactTypesSelected();
170     }
171
172     onDescriptionChange = (value: any): void => {
173         this.operationToUpdate.description = value;
174     }
175
176     onURIChange(value: string | undefined) {
177         if(!this.operationToUpdate.implementation){
178             let artifact = new ArtifactModel();
179             this.operationToUpdate.implementation = artifact;
180         }
181         this.operationToUpdate.implementation.artifactName = value ? value : '';
182     }
183
184     onPropertyValueChange = (propertyValue) => {
185         this.emitter.emit(propertyValue);
186     }
187
188     onMarkToAddArtifactToImplementation(event: boolean) {
189         if (!event) {
190             this.toscaArtifactTypeSelected = undefined;
191             this.artifactVersion = undefined;
192             if (this.operationToUpdate.implementation.artifactType) {
193                 this.operationToUpdate.implementation.artifactName = '';
194                 this.operationToUpdate.implementation.artifactVersion = '';
195             }
196             this.toscaArtifactTypeProperties = undefined;
197             this.artifactTypeProperties = undefined;
198         } else {
199             this.getArtifactTypesSelected();
200         }
201         this.enableAddArtifactImplementation = event;
202     }
203
204     onSelectToscaArtifactType(type: IDropDownOption) {
205         if (type) {
206             let toscaArtifactType = type.value;
207             let artifact = new ArtifactModel();
208             artifact.artifactName = this.operationToUpdate.implementation.artifactName;
209             artifact.artifactVersion = this.operationToUpdate.implementation.artifactVersion;
210             artifact.artifactType = toscaArtifactType.type;
211             artifact.properties = toscaArtifactType.properties;
212             this.toscaArtifactTypeProperties = artifact.properties;
213             this.artifactTypeProperties = this.convertArtifactsPropertiesToInput();
214             this.toscaArtifactTypeSelected = artifact.artifactType;
215             this.operationToUpdate.implementation = artifact;
216             this.getArtifactTypesSelected();
217         }
218     }
219
220     onArtifactVersionChange(value: string | undefined) {
221             this.operationToUpdate.implementation.artifactVersion = value ? value : '';
222     }
223
224     onAddInput(inputOperationParameter: InputOperationParameter) {
225         this.addInput(inputOperationParameter);
226     }
227
228     propertyValueValidation = (propertyValue): void => {
229         this.onPropertyValueChange(propertyValue);
230         this.propertyValueValid = propertyValue.isValid;
231     }
232
233     onRemoveInput = (inputParam: InputOperationParameter): void => {
234         let index = this.inputs.indexOf(inputParam);
235         this.inputs.splice(index, 1);
236     }
237
238     private removeImplementationQuote(): void {
239         if (this.operationToUpdate.implementation) {
240             if (!this.operationToUpdate.implementation
241                 || !this.operationToUpdate.implementation.artifactName) {
242                 return;
243             }
244
245             let implementation = this.operationToUpdate.implementation.artifactName.trim();
246
247             if (implementation.startsWith("'") && implementation.endsWith("'")) {
248                 this.operationToUpdate.implementation.artifactName = implementation.slice(1, -1);
249             }
250         }
251     }
252
253     private getArtifactTypesSelected() {
254         if (this.operationToUpdate.implementation && this.operationToUpdate.implementation.artifactType) {
255             this.artifactName =
256                 this.artifactName ? this.artifactName : this.operationToUpdate.implementation.artifactName;
257             this.toscaArtifactTypeSelected = this.operationToUpdate.implementation.artifactType;
258             this.artifactVersion =
259                 this.artifactVersion ? this.artifactVersion : this.operationToUpdate.implementation.artifactVersion;
260             this.toscaArtifactTypeProperties = this.operationToUpdate.implementation.properties;
261             this.artifactTypeProperties = this.convertArtifactsPropertiesToInput();
262             this.enableAddArtifactImplementation = true;
263         }
264     }
265
266     toDropDownOption(val: string) {
267         return { value : val, label: val };
268     }
269
270     /**
271      * Handles the input value change event.
272      * @param changedInput the changed input
273      */
274     onInputValueChange(changedInput: InputOperationParameter) {
275         if (changedInput.value instanceof Object) {
276             changedInput.value = JSON.stringify(changedInput.value);
277         }
278         const inputOperationParameter = this.inputs.find(value => value.name == changedInput.name);
279         inputOperationParameter.value = changedInput.value;
280     }
281
282     onArtifactPropertyValueChange(changedProperty: InputOperationParameter) {
283         if (changedProperty.value instanceof Object) {
284             changedProperty.value = JSON.stringify(changedProperty.value);
285         }
286         const property = this.toscaArtifactTypeProperties.find(artifactProperty => artifactProperty.name == changedProperty.name);
287         property.value = changedProperty.value;
288     }
289
290     /**
291      * Handles the add input event.
292      * @param input the input to add
293      * @private
294      */
295     private addInput(input: InputOperationParameter) {
296         this.operationToUpdate.inputs.listToscaDataDefinition.push(input);
297         this.inputs = Array.from(this.operationToUpdate.inputs.listToscaDataDefinition);
298     }
299
300     /**
301      * Return a list with current input names.
302      */
303     collectInputNames() {
304         return this.inputs.map((input) => input.name);
305     }
306
307     /**
308      * Handles the delete input event.
309      * @param inputName the name of the input to be deleted
310      */
311     onInputDelete(inputName: string) {
312         const currentInputs = this.operationToUpdate.inputs.listToscaDataDefinition;
313         const input1 = currentInputs.find(value => value.name === inputName);
314         const indexOfInput = currentInputs.indexOf(input1);
315         if (indexOfInput === -1) {
316             console.error(`Could delete input '${inputName}'. Input not found.`);
317             return;
318         }
319         currentInputs.splice(currentInputs.indexOf(input1), 1);
320         this.inputs = Array.from(currentInputs);
321     }
322
323     private convertArtifactsPropertiesToInput(): Array<InputOperationParameter> {
324         if (!this.toscaArtifactTypeProperties) {
325             return [];
326         }
327         const inputList: Array<InputOperationParameter> = [];
328         this.toscaArtifactTypeProperties.forEach(property => {
329             const input = new InputOperationParameter();
330             input.name = property.name;
331             input.type = property.type;
332             input.schema = property.schema;
333             input.toscaDefaultValue = property.defaultValue;
334             input.value = property.value;
335             inputList.push(input);
336         });
337         return inputList;
338     }
339
340     onSelectInterface(dropDownOption: DropDownOption) {
341         if (dropDownOption) {
342             this.setInterfaceType(dropDownOption);
343         } else {
344             this.setInterfaceType(undefined);
345         }
346         this.setInterfaceOperation(undefined);
347         this.interfaceOperationDropDown.selectOption({} as IDropDownOption);
348         this.loadInterfaceTypeOperations();
349     }
350
351     onSelectOperation(dropDownOption: DropDownOption) {
352         if (this.selectedInterfaceType && dropDownOption) {
353             this.setInterfaceOperation(dropDownOption);
354         }
355     }
356
357     private setInterfaceType(dropDownOption: DropDownOption) {
358         this.selectedInterfaceType = dropDownOption ? dropDownOption : undefined;
359         this.interfaceType = dropDownOption ? dropDownOption.value : undefined;
360         this.operationToUpdate.interfaceType = dropDownOption ? dropDownOption.value : undefined;
361         this.operationToUpdate.interfaceId = dropDownOption ? dropDownOption.value : undefined;
362     }
363
364     private setInterfaceOperation(dropDownOption: DropDownOption) {
365         this.operationToUpdate.name = dropDownOption ? dropDownOption.value : undefined;
366         this.operationToUpdate.operationType = dropDownOption ? dropDownOption.value : undefined;
367         this.selectedInterfaceOperation = dropDownOption ? dropDownOption : undefined;
368     }
369 }
370
371 class DropDownOption implements IDropDownOption {
372     value: string;
373     label: string;
374
375     constructor(value: string, label?: string) {
376         this.value = value;
377         this.label = label || value;
378     }
379 }