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