b265464f86ea24a41187875075d6bd733aae1062
[sdc.git] / catalog-ui / src / app / ng2 / pages / composition / interface-operatons / operation-creator / activities-list / activities-list.component.ts
1 /*
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2023 Nordix Foundation
4  *  ================================================================================
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  *
16  *  SPDX-License-Identifier: Apache-2.0
17  *  ============LICENSE_END=========================================================
18  */
19
20 import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
21 import {
22   ActivityParameter,
23   IActivityParameterList,
24   InputOperationParameter,
25   IOperationParamsList,
26   ActivityTypesEnum
27 } from "../../../../../../models/interfaceOperation";
28 import { DataTypeModel } from "../../../../../../models/data-types";
29 import { Observable } from "rxjs/Observable";
30 import { InstanceFeDetails } from "../../../../../../models/instance-fe-details";
31 import {
32   AbstractControl,
33   FormArray,
34   FormControl,
35   FormGroup, 
36   ValidationErrors,
37   ValidatorFn,
38   Validators
39 } from '@angular/forms';
40
41 @Component({
42   selector: 'activities-list',
43   templateUrl: './activities-list.component.html',
44   styleUrls: ['./activities-list.component.less']
45 })
46 export class ActivitiesListComponent implements OnInit {
47
48   @Input() componentInstanceMap: Map<string, InstanceFeDetails> = new Map();
49   @Input() dataTypeMap: Map<string, DataTypeModel>;;
50   @Input() dataTypeMap$: Observable<Map<string, DataTypeModel>>;
51   @Input() existingActivities: IActivityParameterList;
52   @Input() isViewOnly: boolean;
53   @Output('activitiesChangeEvent') activitiesChangeEvent: EventEmitter<any> = new EventEmitter<any>();
54
55   readonly DEFAULT_INPUT_TYPE: string = "tosca.dataTypes.tmf.milestoneJeopardyData";
56   readonly DEFAULT_INPUT_NAME: string = "TMFMilestoneJeopardyData";
57   activityTypes: string[] = [];
58   activities: ActivityParameter[] = [];
59   activityFormArray: FormArray = new FormArray([]);
60   activityForm: FormGroup = new FormGroup (
61     {
62       'activityFormList': this.activityFormArray
63     }
64   );
65   validationMessages = {
66     activity: [
67       { type: 'required', message: 'Activity type and value is required'}
68     ]
69   };
70
71   ngOnInit() {
72     Object.keys(ActivityTypesEnum).forEach(key => {
73       this.activityTypes.push(ActivityTypesEnum[key])
74     });
75     this.activityForm.valueChanges.subscribe(() => {
76       this.emitOnActivityChange();
77     });
78     if (this.existingActivities && this.existingActivities.listToscaDataDefinition && this.existingActivities.listToscaDataDefinition.length > 0) {
79       this.existingActivities.listToscaDataDefinition.forEach(val => {
80         this.activities.push(val);
81         this.activityFormArray.push(
82           new FormControl(val, [Validators.required, this.formControlValidator()])
83         );
84       })
85     }
86   }
87
88   private emitOnActivityChange(): void {
89     this.activitiesChangeEvent.emit({
90       activities: this.activities,
91       valid: this.activityForm.valid
92     });
93   }
94
95   addActivity() {
96     let input = new class implements IOperationParamsList {
97       listToscaDataDefinition: Array<InputOperationParameter> = [];
98     }
99     let activityParameter: ActivityParameter = {
100       type: null,
101       workflow: null,
102       inputs: input
103     }
104     this.activities.push(activityParameter);
105     this.activityFormArray.push(
106       new FormControl(activityParameter, [Validators.required, this.formControlValidator()])
107     );
108
109     let index = this.activities.indexOf(activityParameter);
110     let inputOperationParameter: InputOperationParameter = new InputOperationParameter();
111     inputOperationParameter.name = this.DEFAULT_INPUT_NAME;
112     inputOperationParameter.type = this.DEFAULT_INPUT_TYPE;
113     inputOperationParameter.valid = true;
114     this.activities[index].inputs.listToscaDataDefinition.push(inputOperationParameter);
115     this.activities[index].inputs.listToscaDataDefinition = Array.from(this.activities[index].inputs.listToscaDataDefinition);
116   }
117
118   private formControlValidator(): ValidatorFn {
119     return (control: AbstractControl): ValidationErrors | null => {
120       const activity = control.value;
121       if (!activity || !activity.type || !activity.workflow) {
122         return {required:true};
123       }
124       return null;
125     }
126   }
127
128   removeFromActivities (index: number) {
129     this.activities.splice(index, 1);
130     this.activityFormArray.removeAt(index);
131   }
132
133   onActivityTypeChange(type: string, index: number) {
134     let activity = this.activityFormArray.controls[index].value;
135     activity.type = type;
136     this.activityFormArray.controls[index].setValue(activity);
137   }
138
139   onActivityValueChange (value: any, index: number) {
140     let activity = this.activityFormArray.controls[index].value;
141     activity.workflow = value;
142     this.activityFormArray.controls[index].setValue(activity);
143   }
144
145   collectInputNames(index: number) {
146     return this.activities[index].inputs.listToscaDataDefinition.map((input) => input.name);
147 }
148
149   onAddInput(inputOperationParameter: InputOperationParameter, index: number) {
150     this.activities[index].inputs.listToscaDataDefinition.push(inputOperationParameter);
151     this.activities[index].inputs.listToscaDataDefinition = Array.from(this.activities[index].inputs.listToscaDataDefinition);
152   }
153
154   getInputs(index: number) {
155     if (this.activities[index].inputs.listToscaDataDefinition) {
156       let test: InputOperationParameter[] = this.activities[index].inputs.listToscaDataDefinition;
157       return test;
158     }
159     return {};
160   }
161
162   onInputValueChange(changedInput: InputOperationParameter, index: number) {
163     if (changedInput.value instanceof Object) {
164         changedInput.value = JSON.stringify(changedInput.value);
165     }
166     const inputOperationParameter = this.activities[index].inputs.listToscaDataDefinition.find(value => value.name == changedInput.name);
167     inputOperationParameter.toscaFunction = null;
168     inputOperationParameter.value = changedInput.value;
169     inputOperationParameter.subPropertyToscaFunctions = changedInput.subPropertyToscaFunctions;
170     if (changedInput.isToscaFunction()) {
171         inputOperationParameter.toscaFunction = changedInput.toscaFunction;
172         inputOperationParameter.value = changedInput.toscaFunction.buildValueString();
173     }
174 }
175
176   onInputDelete(inputName: string, index: number) {
177     const currentInputs = this.activities[index].inputs.listToscaDataDefinition;
178     const input1 = currentInputs.find(value => value.name === inputName);
179     const indexOfInput = currentInputs.indexOf(input1);
180     if (indexOfInput === -1) {
181         console.error(`Could not delete input '${inputName}'. Input not found.`);
182         return;
183     }
184     currentInputs.splice(currentInputs.indexOf(input1), 1);
185     this.activities[index].inputs.listToscaDataDefinition = Array.from(currentInputs);
186   }
187 }