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";
22 export const SUPPLEMENTARY_FILE = 'supplementaryFile';
23 export const SDN_C_PRE_LOAD = 'sdncPreLoad';
26 export class BasicControlGenerator {
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;
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();
42 getSubscribeInitResult(subscribeFunction : Function, control : DropdownFormControl, form : FormGroup) : Observable<any>{
43 return subscribeFunction(this).subscribe((res) => {
44 if(!_.isNil(control['onInitSelectedField'])){
46 for(let key of control['onInitSelectedField']){
47 result = !_.isNil(result[key]) ? result[key] : [];
49 control.options$ = result;
50 control.hasEmptyOptions = _.isNil(result) || result.length === 0;
52 control.options$ = !_.isNil(res) ? res : [];
53 control.hasEmptyOptions = _.isNil(res) || res.length === 0;
56 FormGeneralErrorsService.checkForErrorTrigger.next();
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,
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;
75 if(!pattern.test(event['key'])){
76 event.preventDefault();
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;
90 isLegacyRegionShouldBeVisible(instance : any) : boolean {
91 if(!_.isNil(instance) && !_.isNil(instance.lcpCloudRegionId)) {
92 return Constants.LegacyRegion.MEGA_REGION.indexOf(instance.lcpCloudRegionId) !== -1;
97 getLegacyRegion(instance: any): FormControlModel {
98 return new InputFormControl({
99 controlName: 'legacyRegion',
100 displayName: 'Legacy Region',
101 dataTestId: 'lcpRegionText',
102 placeHolder: 'Type Legacy Region',
104 isVisible: this.isLegacyRegionShouldBeVisible(instance),
105 isDisabled : _.isNil(instance) ? true : Constants.LegacyRegion.MEGA_REGION.indexOf(instance.lcpCloudRegionId),
106 value: instance ? instance.legacyRegion : null
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])
115 if (!isEcompGeneratedNaming) {
116 validations.push(new ValidatorModel(ValidatorOptions.required, 'is required'));
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,
129 return of(optionList);
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',
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),
149 getDynamicInputsByType(dynamicInputs : any, serviceModelId : string, storeKey : string, type: string ) : FormControlModel[] {
150 let result : FormControlModel[] = [];
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]);
156 result = this.getDynamicInputs(dynamicInputs, nodeInstance);
162 getServiceDynamicInputs(dynamicInputs : any, serviceModelId : string) : FormControlModel[] {
163 let result: FormControlModel[] = [];
165 let serviceInstance = null;
166 if (_.has(this._store.getState().service.serviceInstance, serviceModelId)) {
167 serviceInstance = Object.assign({}, this._store.getState().service.serviceInstance[serviceModelId]);
169 result = this.getDynamicInputs(dynamicInputs, serviceInstance);
174 getDynamicInputs(dynamicInputs : any, instance :any) : FormControlModel[]{
175 let result : FormControlModel[] = [];
177 dynamicInputs.forEach((input)=> {
178 let validations: ValidatorModel[] = [];
179 if(input.isRequired) {
180 validations.push(new ValidatorModel(ValidatorOptions.required, 'is required'))
182 if(input.minLength) {
183 validations.push(new ValidatorModel(ValidatorOptions.minLength, '', input.minLength))
185 if(input.maxLength) {
186 validations.push(new ValidatorModel(ValidatorOptions.maxLength, '', input.maxLength))
189 let dynamicInputLabelPipe: DynamicInputLabelPipe = new DynamicInputLabelPipe();
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
201 switch (input.type) {
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));
210 data.type = FormControlType.CHECKBOX;
211 result.push(new FormControlModel(data));
215 data.min = input.min;
216 data.max = input.max;
217 result.push(new NumberFormControl(data));
221 result.push(new FileFormControl(data));
225 result.push(new InputFormControl(data));
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;
239 concatSupplementaryFile(originalArray: FormControlModel[], vfModuleInstance): FormControlModel[] {
240 let suppFileInput: FileFormControl = <FileFormControl>(this.getSupplementaryFile(vfModuleInstance));
241 return originalArray.concat([suppFileInput], suppFileInput.hiddenFile);
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')]
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,
262 acceptedExtentions: "application/json",
263 hiddenFile : [new InputFormControl({
264 controlName: SUPPLEMENTARY_FILE + "_hidden",
266 validations: [new ValidatorModel(CustomValidatorOptions.isFileTooBig, "File size exceeds 5MB.", [FileUnit.MB, 5])]
268 new InputFormControl({
269 controlName: SUPPLEMENTARY_FILE + "_hidden_content",
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,
278 onDelete : this.getOnDeleteForSupplementaryFile(),
279 onChange : this.getOnChangeForSupplementaryFile()
283 private getOnDeleteForSupplementaryFile() {
284 return (form: FormGroup) => {
285 form.controls[SUPPLEMENTARY_FILE + "_hidden"].setValue(null);
286 form.controls[SUPPLEMENTARY_FILE + "_hidden_content"].setValue(null);
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);
299 reader.readAsText(file);
301 form.controls[SUPPLEMENTARY_FILE + "_hidden"].setValue(null);
302 form.controls[SUPPLEMENTARY_FILE + "_hidden_content"].setValue(null);