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