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