Fix generated tosca and Required fields validation
[sdc.git] / catalog-ui / src / app / ng2 / pages / composition / interface-operatons / operation-creator / interface-operation-handler.component.ts
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
22 import {Component, EventEmitter, Output} from '@angular/core';
23 import {UIInterfaceModel} from "../interface-operations.component";
24 import {
25     InputOperationParameter,
26     InterfaceOperationModel,
27     IOperationParamsList
28 } from "../../../../../models/interfaceOperation";
29 import {TranslateService} from "../../../../shared/translator/translate.service";
30 import {IDropDownOption} from "onap-ui-angular/dist/form-elements/dropdown/dropdown-models";
31 import {DropdownValue} from "../../../../components/ui/form-components/dropdown/ui-element-dropdown.component";
32 import {ArtifactModel} from "../../../../../models/artifacts";
33 import {PropertyBEModel} from "../../../../../models/properties-inputs/property-be-model";
34 import {PropertyParamRowComponent} from "./property-param-row/property-param-row.component";
35 import {PropertyFEModel} from "../../../../../models/properties-inputs/property-fe-model";
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
44 export class InterfaceOperationHandlerComponent {
45     @Output('propertyChanged') emitter: EventEmitter<PropertyFEModel> = new EventEmitter<PropertyFEModel>();
46
47     input: {
48         toscaArtifactTypes: Array<DropdownValue>;
49         selectedInterface: UIInterfaceModel;
50         selectedInterfaceOperation: InterfaceOperationModel;
51         validityChangedCallback: Function;
52     };
53
54     interfaceType: string;
55     artifactVersion: string;
56     artifactName: string;
57     interfaceOperationName: string;
58     operationToUpdate: InterfaceOperationModel;
59     inputs: Array<InputOperationParameter> = [];
60     properties: Array<PropertyParamRowComponent> = [];
61     isLoading: boolean = false;
62     readonly: boolean;
63
64     toscaArtifactTypeSelected: string;
65     toscaArtifactTypeProperties: Array<PropertyBEModel> = [];
66
67     toscaArtifactTypes: Array<DropdownValue> = [];
68
69     enableAddArtifactImplementation: boolean;
70     propertyValueValid: boolean = true;
71
72     ngOnInit() {
73         this.interfaceType = this.input.selectedInterface.displayType();
74         this.operationToUpdate = new InterfaceOperationModel(this.input.selectedInterfaceOperation);
75         this.operationToUpdate.interfaceId = this.input.selectedInterface.uniqueId;
76         this.operationToUpdate.interfaceType = this.input.selectedInterface.type;
77         if (!this.operationToUpdate.inputs) {
78             this.operationToUpdate.inputs = new class implements IOperationParamsList {
79                 listToscaDataDefinition: Array<InputOperationParameter> = [];
80             }
81         }
82
83         this.inputs = this.operationToUpdate.inputs.listToscaDataDefinition;
84         this.removeImplementationQuote();
85         this.validityChanged();
86         this.loadInterfaceOperationImplementation();
87     }
88
89     private loadInterfaceOperationImplementation() {
90         this.toscaArtifactTypes = this.input.toscaArtifactTypes;
91         this.artifactVersion = this.operationToUpdate.implementation.artifactVersion;
92         this.artifactName = this.operationToUpdate.implementation.artifactName;
93         this.toscaArtifactTypeProperties = this.operationToUpdate.implementation.properties;
94         this.getArtifactTypesSelected();
95     }
96
97     onDescriptionChange= (value: any): void => {
98         this.operationToUpdate.description = value;
99     }
100
101     onImplementationNameChange(value: any) {
102         this.readonly = true
103         if (value) {
104             let artifact = new ArtifactModel();
105             artifact.artifactName = value;
106             this.operationToUpdate.implementation = artifact;
107             this.enableAddArtifactImplementation = false;
108             this.readonly = false;
109         }
110     }
111
112     onPropertyValueChange = (propertyValue) => {
113         this.emitter.emit(propertyValue);
114     }
115
116     onMarkToAddArtifactToImplementation(event: any) {
117         if (!event) {
118             this.toscaArtifactTypeSelected = undefined;
119             this.artifactVersion = undefined;
120             if (this.operationToUpdate.implementation.artifactType) {
121                 this.artifactName = undefined;
122             }
123             this.toscaArtifactTypeProperties = undefined;
124         } else {
125             this.getArtifactTypesSelected();
126         }
127         this.enableAddArtifactImplementation = event;
128         this.validateRequiredField();
129     }
130
131     onSelectToscaArtifactType(type: IDropDownOption) {
132         if (type) {
133             let toscaArtifactType = type.value;
134             let artifact = new ArtifactModel();
135             this.artifactName = undefined;
136             this.artifactVersion = undefined;
137             artifact.artifactType = toscaArtifactType.type;
138             artifact.properties = toscaArtifactType.properties;
139             this.toscaArtifactTypeProperties = artifact.properties;
140             this.toscaArtifactTypeSelected = artifact.artifactType;
141             this.operationToUpdate.implementation = artifact;
142             this.getArtifactTypesSelected();
143         }
144         this.validateRequiredField();
145     }
146
147     onArtifactFileChange(value: any) {
148         if (value) {
149             this.operationToUpdate.implementation.artifactName = value;
150         }
151         this.validateRequiredField();
152     }
153
154     onArtifactVersionChange(value: any) {
155         if (value) {
156             this.operationToUpdate.implementation.artifactVersion = value;
157         }
158     }
159
160     onAddInput(inputOperationParameter?: InputOperationParameter): void {
161         let newInput = new InputOperationParameter(inputOperationParameter)
162         newInput.type = "string";
163         newInput.inputId = this.generateUniqueId();
164         this.inputs.push(newInput);
165         this.validityChanged();
166     }
167
168     propertyValueValidation = (propertyValue): void => {
169         this.onPropertyValueChange(propertyValue);
170         this.propertyValueValid = propertyValue.isValid;
171         this.readonly = !this.propertyValueValid;
172         this.validateRequiredField();
173     }
174
175     onRemoveInput = (inputParam: InputOperationParameter): void => {
176         let index = this.inputs.indexOf(inputParam);
177         this.inputs.splice(index, 1);
178         this.validityChanged();
179     }
180
181     private removeImplementationQuote(): void {
182         if (this.operationToUpdate.implementation) {
183             if (!this.operationToUpdate.implementation
184                 || !this.operationToUpdate.implementation.artifactName) {
185                 return;
186             }
187
188             let implementation = this.operationToUpdate.implementation.artifactName.trim();
189
190             if (implementation.startsWith("'") && implementation.endsWith("'")) {
191                 this.operationToUpdate.implementation.artifactName = implementation.slice(1, -1);
192             }
193         }
194     }
195
196     private generateUniqueId = (): string => {
197         let result = '';
198         const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
199         const charactersLength = characters.length;
200         for (let i = 0; i < 36; i++ ) {
201             result += characters.charAt(Math.floor(Math.random() * charactersLength));
202         }
203         return result;
204     }
205
206     validityChanged = () => {
207         let validState = this.checkFormValidForSubmit();
208         this.input.validityChangedCallback(validState);
209         if (validState) {
210             this.readonly = false;
211         }
212     }
213
214     private getArtifactTypesSelected() {
215         if (this.operationToUpdate.implementation && this.operationToUpdate.implementation.artifactType) {
216             this.artifactName = this.operationToUpdate.implementation.artifactName;
217             this.toscaArtifactTypeSelected = this.operationToUpdate.implementation.artifactType;
218             this.artifactVersion = this.operationToUpdate.implementation.artifactVersion;
219             this.toscaArtifactTypeProperties = this.operationToUpdate.implementation.properties;
220             this.enableAddArtifactImplementation = true;
221         }
222         this.validateRequiredField();
223     }
224
225     validateRequiredField = () => {
226         this.readonly = true;
227         const isRequiredFieldSelected = this.isRequiredFieldsSelected();
228         this.input.validityChangedCallback(isRequiredFieldSelected);
229         if (isRequiredFieldSelected && this.propertyValueValid) {
230             this.readonly = false;
231         }
232     }
233
234     private isRequiredFieldsSelected() {
235         return this.toscaArtifactTypeSelected && this.artifactName;
236     }
237
238     private checkFormValidForSubmit = (): boolean => {
239         return this.operationToUpdate.name && this.artifactName && this.isParamsValid();
240     }
241
242     private isParamsValid = (): boolean => {
243         const isInputValid = (input) => input.name && input.inputId;
244         const isValid = this.inputs.every(isInputValid);
245         if (!isValid) {
246             this.readonly = true;
247         }
248         return isValid;
249     }
250
251     toDropDownOption(val: string) {
252         return { value : val, label: val };
253     }
254
255 }