Angular upgrade
[osm/NG-UI.git] / src / app / roles / roles-create-edit / RolesCreateEditComponent.ts
1 /*
2  Copyright 2020 TATA ELXSI
3
4  Licensed under the Apache License, Version 2.0 (the 'License');
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7
8   http://www.apache.org/licenses/LICENSE-2.0
9
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  Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.in), BARATH KUMAR R (barath.r@tataelxsi.co.in)
17 */
18 /**
19  * @file Roles Create and Edit Component
20  */
21 import { HttpClient, HttpHeaders } from '@angular/common/http';
22 import { Component, Injector, Input, OnInit } from '@angular/core';
23 import { FormBuilder, FormGroup, Validators } from '@angular/forms';
24 import { ActivatedRoute, Router } from '@angular/router';
25 import { TranslateService } from '@ngx-translate/core';
26 import { NotifierService } from 'angular-notifier';
27 import { APIURLHEADER, ERRORDATA } from 'CommonModel';
28 import { environment } from 'environment';
29 import * as jsonpath from 'jsonpath';
30 import { RestService } from 'RestService';
31 import { Permission, PermissionGroup, RoleConfig, RoleData } from 'RolesModel';
32 import { SharedService, isNullOrUndefined } from 'SharedService';
33
34 /**
35  * Creating component
36  * @Component takes RolesCreateEditComponent.html as template url
37  */
38 @Component({
39   selector: 'app-roles-create-edit',
40   templateUrl: './RolesCreateEditComponent.html',
41   styleUrls: ['./RolesCreateEditComponent.scss']
42 })
43 /** Exporting a class @exports RolesCreateEditComponent */
44 export class RolesCreateEditComponent implements OnInit {
45   /** To inject services @public */
46   public injector: Injector;
47
48   /** contains role permissions from config file @public */
49   public rolePermissions: {}[];
50
51   /** contains role form group information @public */
52   public roleForm: FormGroup;
53
54   /** Instance of the rest service @public */
55   public restService: RestService;
56
57   /** Check the loading results for loader status @public */
58   public isLoadingResults: boolean = false;
59
60   /** Give the message for the loading @public */
61   public message: string = 'PLEASEWAIT';
62
63   /** Instance to check role form submitted status @public */
64   public submitted: boolean = false;
65
66   /** Contains role create or edit value @public */
67   public getRoleType: string;
68
69   /** Contains view selection value either text or preview @public */
70   public viewMode: string = 'text';
71
72   /** Contains current permissions data @private */
73   private currentPermissions: string;
74
75   /** Contains current role name @private */
76   private currentRoleName: string;
77
78   /** Contains modified role name @private */
79   private modifiedRoleName: string;
80
81   /** Contains role id value @private */
82   private roleRef: string;
83
84   /** Notifier service to popup notification @private */
85   private notifierService: NotifierService;
86
87   /** Contains tranlsate instance @private */
88   private translateService: TranslateService;
89
90   /** contians form builder module @private */
91   private formBuilder: FormBuilder;
92
93   /** Contains all methods related to shared @private */
94   private sharedService: SharedService;
95
96   /** Controls the header form @private */
97   private headers: HttpHeaders;
98
99   /** Varaibles to hold http client @private */
100   private httpClient: HttpClient;
101
102   /** Holds the instance of activatedRoute of router service @private */
103   private activatedRoute: ActivatedRoute;
104
105   /** Holds the instance of roter service @private */
106   private router: Router;
107
108   constructor(injector: Injector) {
109     this.injector = injector;
110     this.restService = this.injector.get(RestService);
111     this.notifierService = this.injector.get(NotifierService);
112     this.translateService = this.injector.get(TranslateService);
113     this.formBuilder = this.injector.get(FormBuilder);
114     this.sharedService = this.injector.get(SharedService);
115     this.httpClient = this.injector.get(HttpClient);
116     this.activatedRoute = this.injector.get(ActivatedRoute);
117     this.router = this.injector.get(Router);
118   }
119
120   /** Lifecyle Hooks the trigger before component is instantiate @public */
121   public ngOnInit(): void {
122     this.headers = new HttpHeaders({
123       'Content-Type': 'application/json',
124       Accept: 'application/json',
125       'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0'
126     });
127     this.roleForm = this.formBuilder.group({
128       roleName: ['', [Validators.required]],
129       permissions: ['']
130     });
131     this.getRolePermissions();
132   }
133
134   /** Get role permission information based on action @public */
135   public getRolePermissions(): void {
136     this.isLoadingResults = true;
137     this.loadPermissions().then((response: RoleConfig) => {
138       this.rolePermissions = response.rolePermissions;
139       if (this.activatedRoute.snapshot.url[0].path === 'create') {
140         this.getRoleType = 'Add';
141         this.isLoadingResults = false;
142       } else {
143         this.getRoleType = 'Edit';
144         this.getRoleData();
145       }
146     }).catch(() => {
147       // Empty Block
148     });
149   }
150
151   /** Check Role Create or Edit and proceed action @public */
152   public roleCheck(): void {
153     this.submitted = true;
154     if (!this.roleForm.valid) {
155       const errorIp: Element = document.querySelector('.ng-invalid[formControlName]');
156       if (errorIp) {
157         errorIp.scrollIntoView({ behavior: 'smooth', block: 'center' });
158       }
159     } else {
160       if (this.getRoleType === 'Add') {
161         this.createRole();
162       } else {
163         this.editRole();
164       }
165     }
166   }
167
168   /** Convenience getter for easy access to form fields */
169   get f(): FormGroup['controls'] { return this.roleForm.controls; }
170
171   /** Create role @private  */
172   public createRole(): void {
173     const apiURLHeader: APIURLHEADER = {
174       url: environment.ROLES_URL,
175       httpOptions: { headers: this.headers }
176     };
177     let permissionData: Object = {};
178     this.sharedService.cleanForm(this.roleForm);
179     if (!this.roleForm.invalid) {
180       if (this.viewMode === 'preview') {
181         this.isLoadingResults = true;
182         permissionData = this.generatePermissions();
183         this.roleCreateAPI(apiURLHeader, permissionData);
184       } else {
185         if (this.checkPermission()) {
186           this.isLoadingResults = true;
187           permissionData = this.roleForm.value.permissions !== '' ? JSON.parse(this.roleForm.value.permissions) : {};
188           this.roleCreateAPI(apiURLHeader, permissionData);
189         }
190       }
191     }
192   }
193
194   /** Method to handle role create API call @public */
195   public roleCreateAPI(apiURLHeader: APIURLHEADER, permissionData: {}): void {
196     const postData: {} = {
197       name: this.roleForm.value.roleName,
198       permissions: !isNullOrUndefined(permissionData) ? permissionData : {}
199     };
200     this.restService.postResource(apiURLHeader, postData).subscribe(() => {
201       this.notifierService.notify('success', this.translateService.instant('PAGE.ROLES.CREATEDSUCCESSFULLY'));
202       this.router.navigate(['/roles/details']).catch((): void => {
203         // Catch Navigation Error
204       });
205     }, (error: ERRORDATA) => {
206       this.isLoadingResults = false;
207       this.restService.handleError(error, 'post');
208     });
209   }
210
211   /** Edit role  @private  */
212   public editRole(): void {
213     const apiURLHeader: APIURLHEADER = {
214       url: environment.ROLES_URL + '/' + this.roleRef,
215       httpOptions: { headers: this.headers }
216     };
217     this.modifiedRoleName = this.roleForm.value.roleName;
218     let permissionData: Object = {};
219     this.sharedService.cleanForm(this.roleForm);
220     if (!this.roleForm.invalid) {
221       if (this.viewMode === 'preview') {
222         permissionData = this.generatePermissions();
223         this.roleEditAPI(apiURLHeader, permissionData);
224       } else {
225         if (this.checkPermission()) {
226           permissionData = this.roleForm.value.permissions !== '' ? JSON.parse(this.roleForm.value.permissions) : {};
227           this.roleEditAPI(apiURLHeader, permissionData);
228         }
229       }
230     }
231   }
232
233   /** Method to handle role edit API call */
234   public roleEditAPI(apiURLHeader: APIURLHEADER, permissionData: {}): void {
235     if ((JSON.stringify(permissionData, null, '\t') === this.currentPermissions) && (this.modifiedRoleName === this.currentRoleName)) {
236       this.notifierService.notify('warning', this.translateService.instant('PAGE.TOPOLOGY.DATAEMPTY'));
237       return;
238     }
239     this.isLoadingResults = true;
240     const postData: {} = {
241       name: this.roleForm.value.roleName,
242       permissions: !isNullOrUndefined(permissionData) ? permissionData : {}
243     };
244     this.restService.patchResource(apiURLHeader, postData).subscribe(() => {
245       this.notifierService.notify('success', this.translateService.instant('PAGE.ROLES.UPDATEDSUCCESSFULLY'));
246       this.router.navigate(['/roles/details']).catch((): void => {
247         // Catch Navigation Error
248       });
249     }, (error: ERRORDATA) => {
250       this.isLoadingResults = false;
251       this.restService.handleError(error, 'patch');
252     });
253   }
254
255   /** Method to handle toggle role view selection @public */
256   public viewSelection(): void {
257     if (this.viewMode === 'text' && this.checkPermission()) {
258       this.loadPermissions().then((response: RoleConfig) => {
259         this.rolePermissions = response.rolePermissions;
260         const permissions: {} = this.roleForm.value.permissions !== '' ? JSON.parse(this.roleForm.value.permissions) : {};
261         this.filterRoleData(permissions);
262         this.viewMode = 'preview';
263       }).catch(() => {
264         // Empty Block
265       });
266     } else {
267       const rolePermission: {} = this.generatePermissions();
268       if (Object.keys(rolePermission).length !== 0) {
269         this.roleForm.patchValue({ permissions: JSON.stringify(rolePermission, null, '\t') });
270       }
271       this.viewMode = 'text';
272     }
273   }
274
275   /** Generate role permission post data @private */
276   private generatePermissions(): Object {
277     const permissions: Object = {};
278     this.rolePermissions.forEach((permissionGroup: PermissionGroup) => {
279       if (!isNullOrUndefined(permissionGroup)) {
280         permissionGroup.permissions.forEach((permission: Permission) => {
281           if (!isNullOrUndefined(permission.value) && permission.value !== 'NA') {
282             permissions[permission.operation] = permission.value;
283           }
284         });
285       }
286     });
287     return permissions;
288   }
289
290   /** Validation method for check permission json string @private */
291   private checkPermission(): boolean {
292     if (this.roleForm.value.permissions) {
293       if (!this.sharedService.checkJson(this.roleForm.value.permissions)) {
294         this.notifierService.notify('error', this.translateService.instant('PAGE.ROLES.ROLEJSONERROR'));
295         return false;
296       } else {
297         this.roleForm.value.permissions = this.roleForm.value.permissions.replace(/'/g, '"');
298         const rolePermission: {} = JSON.parse(this.roleForm.value.permissions);
299         for (const key of Object.keys(rolePermission)) {
300           // eslint-disable-next-line security/detect-object-injection
301           if (typeof rolePermission[key] !== 'boolean') {
302             this.notifierService.notify('error', this.translateService.instant('PAGE.ROLES.ROLEKEYERROR', { roleKey: key }));
303             return false;
304           }
305         }
306       }
307     }
308     return true;
309   }
310
311   /** Get role data from NBI based on ID and apply filter @private */
312   private getRoleData(): void {
313     this.roleRef = this.activatedRoute.snapshot.paramMap.get('id');
314     if (!isNullOrUndefined(this.roleRef)) {
315       this.restService.getResource(environment.ROLES_URL + '/' + this.roleRef).subscribe((data: RoleData) => {
316         this.roleForm.setValue({ roleName: data.name, permissions: JSON.stringify(data.permissions, null, '\t') });
317         this.filterRoleData(data.permissions);
318         this.isLoadingResults = false;
319         this.currentRoleName = data.name;
320         this.currentPermissions = JSON.stringify(data.permissions, null, '\t');
321       }, (error: ERRORDATA) => {
322         this.router.navigate(['/roles/details']).catch((): void => {
323           // Catch Navigation Error
324         });
325         this.restService.handleError(error, 'get');
326       });
327     }
328   }
329
330   /** Method to filter role data @private */
331   private filterRoleData(permissions: {}): void {
332     Object.keys(permissions).forEach((permission: string) => {
333       jsonpath.apply(this.rolePermissions, '$..permissions[?(@.operation == "' + permission + '")]', (response: Permission) => {
334         if (response.operation === permission) {
335           // eslint-disable-next-line security/detect-object-injection
336           response.value = permissions[permission];
337         }
338         return response;
339       });
340     });
341   }
342
343   /** Method to load the role permission Json file @private */
344   private async loadPermissions(): Promise<Object> {
345     const jsonFile: string = environment.PERMISSIONS_CONFIG_FILE + '?cb=' + new Date().getTime();
346     return new Promise<Object>((resolve: Function, reject: Function): void => {
347       this.httpClient.get(jsonFile).subscribe((response: Response) => {
348         resolve(response);
349       }, (error: {}) => {
350         reject();
351       });
352     });
353   }
354 }