08575bcad2967e796fcb30ec72adebab1e012d83
[vid.git] /
1 import {Injectable} from "@angular/core";
2 import {DropdownFormControl} from "../../../models/formControlModels/dropdownFormControl.model";
3 import {FormGroup} from "@angular/forms";
4 import {
5   CustomValidatorOptions,
6   FormControlModel,
7   ValidatorModel,
8   ValidatorOptions
9 } from "../../../models/formControlModels/formControl.model";
10 import {InputFormControl} from "../../../models/formControlModels/inputFormControl.model";
11 import {AppState} from "../../../store/reducers";
12 import {NgRedux} from "@angular-redux/store";
13 import {NumberFormControl} from "../../../models/formControlModels/numberFormControl.model";
14 import {FormControlType} from "../../../models/formControlModels/formControlTypes.enum";
15 import {FileFormControl} from "../../../models/formControlModels/fileFormControl.model";
16 import {SelectOption} from "../../../models/selectOption";
17 import {DynamicInputLabelPipe} from "../../../pipes/dynamicInputLabel/dynamic-input-label.pipe";
18 import {FormGeneralErrorsService} from "../../formGeneralErrors/formGeneralErrors.service";
19 import {Observable, of} from "rxjs";
20 import {NodeModel} from "../../../models/nodeModel";
21 import {Constants} from "../../../utils/constants";
22 import {FileUnit} from "../../formControls/component/file/fileUnit.enum";
23 import * as _ from 'lodash';
24
25 export const SUPPLEMENTARY_FILE = 'supplementaryFile';
26 export const SDN_C_PRE_LOAD = 'sdncPreLoad';
27
28 @Injectable()
29 export class ControlGeneratorUtil {
30
31   public static readonly INSTANCE_NAME_REG_EX: RegExp = /^[a-zA-Z0-9._-]*$/;
32   public static readonly GENERATED_NAME_REG_EX: RegExp = /[^a-zA-Z0-9._-]/g;
33
34   constructor(private _store: NgRedux<AppState>) {
35   }
36
37   getSubscribeResult(subscribeFunction: Function, control: DropdownFormControl): Observable<any> {
38     return subscribeFunction(this).subscribe((res) => {
39       control.options$ = res;
40       control.hasEmptyOptions = res.length === 0;
41       FormGeneralErrorsService.checkForErrorTrigger.next();
42       return of(res);
43     });
44   }
45
46   getSubscribeInitResult(subscribeFunction: Function, control: DropdownFormControl, form: FormGroup): Observable<any> {
47     return subscribeFunction(this).subscribe((res) => {
48       if (!_.isNil(control['onInitSelectedField'])) {
49         let result = res;
50         for (let key of control['onInitSelectedField']) {
51           result = !_.isNil(result[key]) ? result[key] : [];
52         }
53         control.options$ = result;
54         control.hasEmptyOptions = _.isNil(result) || result.length === 0;
55       } else {
56         control.options$ = !_.isNil(res) ? res : [];
57         control.hasEmptyOptions = _.isNil(res) || res.length === 0;
58       }
59
60       FormGeneralErrorsService.checkForErrorTrigger.next();
61       return of(res);
62     });
63   }
64
65   isLegacyRegionShouldBeVisible(instance: any): boolean {
66     if (!_.isNil(instance) && !_.isNil(instance.lcpCloudRegionId)) {
67       return Constants.LegacyRegion.MEGA_REGION.indexOf(instance.lcpCloudRegionId) !== -1;
68     }
69     return false;
70   }
71
72   createValidationsForInstanceName(instance: any, serviceId: string, isEcompGeneratedNaming: boolean): ValidatorModel[] {
73     let validations: ValidatorModel[] = [
74       new ValidatorModel(ValidatorOptions.pattern, 'Instance name may include only alphanumeric characters and underscore.', ControlGeneratorUtil.INSTANCE_NAME_REG_EX),
75       new ValidatorModel(CustomValidatorOptions.uniqueInstanceNameValidator, 'some error', [this._store, serviceId, instance && instance.instanceName])
76     ];
77     if (!isEcompGeneratedNaming) {
78       validations.push(new ValidatorModel(ValidatorOptions.required, 'is required'));
79     }
80     return validations;
81   }
82
83   getInputsOptions = (options: any[]): Observable<SelectOption[]> => {
84     let optionList: SelectOption[] = [];
85     options.forEach((option) => {
86       optionList.push(new SelectOption({
87         id: option.id || option.name,
88         name: option.name
89       }));
90     });
91     return of(optionList);
92   };
93
94   getDynamicInputsByType(dynamicInputs: any, serviceModelId: string, storeKey: string, type: string): FormControlModel[] {
95     let result: FormControlModel[] = [];
96     if (dynamicInputs) {
97       let nodeInstance = null;
98       if (_.has(this._store.getState().service.serviceInstance[serviceModelId][type], storeKey)) {
99         nodeInstance = Object.assign({}, this._store.getState().service.serviceInstance[serviceModelId][type][storeKey]);
100       }
101       result = this.getDynamicInputs(dynamicInputs, nodeInstance);
102     }
103     return result;
104   }
105
106   getServiceDynamicInputs(dynamicInputs: any, serviceModelId: string): FormControlModel[] {
107     let result: FormControlModel[] = [];
108     if (dynamicInputs) {
109       let serviceInstance = null;
110       if (_.has(this._store.getState().service.serviceInstance, serviceModelId)) {
111         serviceInstance = Object.assign({}, this._store.getState().service.serviceInstance[serviceModelId]);
112       }
113       result = this.getDynamicInputs(dynamicInputs, serviceInstance);
114     }
115     return result;
116   }
117
118   getDynamicInputs(dynamicInputs: any, instance: any): FormControlModel[] {
119     let result: FormControlModel[] = [];
120     if (dynamicInputs) {
121       dynamicInputs.forEach((input) => {
122         let validations: ValidatorModel[] = [];
123         if (input.isRequired) {
124           validations.push(new ValidatorModel(ValidatorOptions.required, 'is required'))
125         }
126         if (input.minLength) {
127           validations.push(new ValidatorModel(ValidatorOptions.minLength, '', input.minLength))
128         }
129         if (input.maxLength) {
130           validations.push(new ValidatorModel(ValidatorOptions.maxLength, '', input.maxLength))
131         }
132
133         let dynamicInputLabelPipe: DynamicInputLabelPipe = new DynamicInputLabelPipe();
134         let data: any = {
135           controlName: input.name,
136           displayName: dynamicInputLabelPipe.transform(input.name).slice(0, -1),
137           dataTestId: input.id,
138           placeHolder: input.prompt,
139           tooltip: input.description,
140           validations: validations,
141           isVisible: input.isVisible,
142           value: !_.isNil(instance) && !_.isNil(instance.instanceParams) && instance.instanceParams.length > 0 ? instance.instanceParams[0][input.name] : input.value
143         };
144
145         switch (input.type) {
146           case 'select' :
147           case 'boolean' : {
148             data.value = data.value || input.optionList.filter((option) => option.isDefault ? option.id || option.name : null);
149             data.onInit = this.getSubscribeInitResult.bind(null, this.getInputsOptions.bind(this, input.optionList));
150             result.push(new DropdownFormControl(data));
151             break;
152           }
153           case 'checkbox': {
154             data.type = FormControlType.CHECKBOX;
155             result.push(new FormControlModel(data));
156             break;
157           }
158           case 'number': {
159             data.min = input.min;
160             data.max = input.max;
161             result.push(new NumberFormControl(data));
162             break;
163           }
164           case 'file': {
165             result.push(new FileFormControl(data));
166             break;
167           }
168           default: {
169             result.push(new InputFormControl(data));
170           }
171         }
172       })
173     }
174
175     return result;
176   }
177
178   getDefaultInstanceName(instance: any, model: NodeModel): string {
179     const initialInstanceName = (!_.isNil(instance) && instance.instanceName) || (!_.isNil(model.name) ? model.name.replace(ControlGeneratorUtil.GENERATED_NAME_REG_EX, "") : model.name);
180     return initialInstanceName;
181   }
182
183   concatSupplementaryFile(originalArray: FormControlModel[], vfModuleInstance): FormControlModel[] {
184     let suppFileInput: FileFormControl = <FileFormControl>(this.getSupplementaryFile(vfModuleInstance));
185     return originalArray.concat([suppFileInput], suppFileInput.hiddenFile);
186   }
187
188   getSupplementaryFile(instance: any): FileFormControl {
189     return new FileFormControl({
190       controlName: SUPPLEMENTARY_FILE,
191       displayName: 'Supplementary Data File (JSON format)',
192       dataTestId: 'SupplementaryFile',
193       placeHolder: 'Choose file',
194       selectedFile: !_.isNil(instance) ? instance.supplementaryFileName : null,
195       isVisible: true,
196       acceptedExtentions: "application/json",
197       hiddenFile: [new InputFormControl({
198         controlName: SUPPLEMENTARY_FILE + "_hidden",
199         isVisible: false,
200         validations: [new ValidatorModel(CustomValidatorOptions.isFileTooBig, "File size exceeds 5MB.", [FileUnit.MB, 5])]
201       }),
202         new InputFormControl({
203           controlName: SUPPLEMENTARY_FILE + "_hidden_content",
204           isVisible: false,
205           validations: [new ValidatorModel(CustomValidatorOptions.isValidJson,
206             "File is invalid, please make sure a legal JSON file is uploaded using name:value pairs.", []),
207             new ValidatorModel(CustomValidatorOptions.isStringContainTags,
208               "File is invalid, please remove tags <>.", [])],
209           value: !_.isNil(instance) ? (instance.supplementaryFile_hidden_content) : null,
210         })
211       ],
212       onDelete: this.getOnDeleteForSupplementaryFile(),
213       onChange: this.getOnChangeForSupplementaryFile()
214     })
215   };
216
217   retrieveInstanceIfUpdateMode(store: NgRedux<AppState>, instance: any): any {
218     return store.getState().global.isUpdateModalMode ? instance : null;
219   }
220
221   private getOnDeleteForSupplementaryFile() {
222     return (form: FormGroup) => {
223       form.controls[SUPPLEMENTARY_FILE + "_hidden"].setValue(null);
224       form.controls[SUPPLEMENTARY_FILE + "_hidden_content"].setValue(null);
225     };
226   }
227
228   private getOnChangeForSupplementaryFile() {
229     return (files: FileList, form: FormGroup) => {
230       if (files.length > 0) {
231         const file = files.item(0);
232         let reader = new FileReader();
233         reader.onload = function (event) {
234           form.controls[SUPPLEMENTARY_FILE + "_hidden_content"].setValue(reader.result);
235           form.controls[SUPPLEMENTARY_FILE + "_hidden"].setValue(file);
236         };
237         reader.readAsText(file);
238       } else {
239         form.controls[SUPPLEMENTARY_FILE + "_hidden"].setValue(null);
240         form.controls[SUPPLEMENTARY_FILE + "_hidden_content"].setValue(null);
241       }
242     };
243   }
244
245   getRollBackOnFailureOptions = (): Observable<SelectOption[]> => {
246     return of([
247       new SelectOption({id: 'true', name: 'Rollback'}),
248       new SelectOption({id: 'false', name: 'Don\'t Rollback'})
249     ]);
250   };
251
252 }