Feature 10941: User Management Enhancements
[osm/NG-UI.git] / src / app / users / user-details / UserDetailsComponent.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 /* eslint-disable security/detect-object-injection */
19 /**
20  * @file users details Component.
21  */
22 import { isNullOrUndefined } from 'util';
23 import { Component, Injector, OnDestroy, OnInit } from '@angular/core';
24 import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
25 import { TranslateService } from '@ngx-translate/core';
26 import { AddEditUserComponent } from 'AddEditUserComponent';
27 import { CONFIGCONSTANT, ERRORDATA, MODALCLOSERESPONSEDATA } from 'CommonModel';
28 import { DataService } from 'DataService';
29 import { environment } from 'environment';
30 import { LocalDataSource } from 'ng2-smart-table';
31 import { ProjectService } from 'ProjectService';
32 import { RestService } from 'RestService';
33 import { Subscription } from 'rxjs';
34 import { SharedService } from 'SharedService';
35 import { UserData, UserDetail } from 'UserModel';
36 import { UsersActionComponent } from 'UsersActionComponent';
37
38 /**
39  * Creating component
40  * @Component takes UserDetailsComponent.html as template url
41  */
42 @Component({
43   templateUrl: './UserDetailsComponent.html',
44   styleUrls: ['./UserDetailsComponent.scss']
45 })
46 /** Exporting a class @exports UserDetailsComponent */
47 export class UserDetailsComponent implements OnInit, OnDestroy {
48   /** Data of smarttable populate through LocalDataSource @public */
49   public dataSource: LocalDataSource = new LocalDataSource();
50
51   /** handle translate @public */
52   public translateService: TranslateService;
53
54   /** To inject services @public */
55   public injector: Injector;
56
57   /** Settings for smarttable to populate the table with columns @public */
58   public settings: object = {};
59
60   /** Check the loading results @public */
61   public isLoadingResults: boolean = true;
62
63   /** Give the message for the loading @public */
64   public message: string = 'PLEASEWAIT';
65
66   /** Class for empty and present data @public */
67   public checkDataClass: string;
68
69   /** user active data @public */
70   public userActive: string = CONFIGCONSTANT.userActive;
71
72   /** user locked data @public */
73   public userLocked: string = CONFIGCONSTANT.userLocked;
74
75   /** user expired data @public */
76   public userExpired: string = CONFIGCONSTANT.userExpired;
77
78   /** user always-active data @public */
79   public userAlwaysActive: string = CONFIGCONSTANT.userAlwaysActive;
80
81   /** Admin Visibility Check  @public */
82   public isAdminShow: boolean;
83
84   /** Instance of the rest service @private */
85   private restService: RestService;
86
87   /** dataService to pass the data from one component to another @private */
88   private dataService: DataService;
89
90   /** Instance of the modal service @private */
91   private modalService: NgbModal;
92
93   /** Formation of appropriate Data for LocalDatasource @private */
94   private userData: {}[] = [];
95
96   /** Contains all methods related to shared @private */
97   private sharedService: SharedService;
98
99   /** Holds all project details */
100   private projectService: ProjectService;
101
102   /** holds the project information @private */
103   private projectList: {}[] = [];
104
105   /** Columns list of the smart table @public */
106   private columnLists: object = {};
107
108   /** Instance of subscriptions @private */
109   private generateDataSub: Subscription;
110
111   constructor(injector: Injector) {
112     this.injector = injector;
113     this.restService = this.injector.get(RestService);
114     this.dataService = this.injector.get(DataService);
115     this.sharedService = this.injector.get(SharedService);
116     this.modalService = this.injector.get(NgbModal);
117     this.projectService = this.injector.get(ProjectService);
118     this.translateService = this.injector.get(TranslateService);
119   }
120
121   /**
122    * Lifecyle Hooks the trigger before component is instantiate
123    */
124   public ngOnInit(): void {
125     this.projectService.getAllProjects().subscribe((projects: {}[]) => {
126       this.projectList = projects;
127     });
128     this.isAdminShow = localStorage.getItem('admin_show') === 'true' ? true : false;
129     this.generateColumns();
130     this.generateSettings();
131     this.generateData();
132     this.hideColumnForUser();
133     this.generateDataSub = this.sharedService.dataEvent.subscribe(() => { this.generateData(); });
134   }
135
136   /** smart table Header Colums @public */
137   public generateColumns(): void {
138     this.columnLists = {
139       username: { title: this.translateService.instant('NAME'), width: '10%', sortDirection: 'asc' },
140       projects: { title: this.translateService.instant('PAGE.DASHBOARD.PROJECTS'), width: '15%' },
141       identifier: { title: this.translateService.instant('IDENTIFIER'), width: '10%' },
142       user_status: {
143         type: 'html',
144         title: this.translateService.instant('STATUS'),
145         width: '15%',
146         filter: {
147           type: 'list',
148           config: {
149             selectText: 'Select',
150             list: [
151               { value: this.userActive, title: this.userActive },
152               { value: this.userLocked, title: this.userLocked },
153               { value: this.userExpired, title: this.userExpired },
154               { value: this.userAlwaysActive, title: this.userAlwaysActive }
155             ]
156           }
157         },
158         valuePrepareFunction: (cell: UserData, row: UserData): string => {
159           if (row.user_status === this.userActive) {
160             return `<span class="icon-label" title="${row.user_status}">
161                  <i class="fas fa-user-check text-success"></i>
162                  </span>`;
163           } else if (row.user_status === this.userLocked) {
164             return `<span class="icon-label" title="${row.user_status}">
165                  <i class="fas fa-user-lock text-danger"></i>
166                  </span>`;
167           } else if (row.user_status === this.userExpired) {
168             return `<span class="icon-label" title="${row.user_status}">
169                  <i class="fas fa-user-times text-warning"></i>
170                  </span>`;
171           } else if (row.user_status === this.userAlwaysActive) {
172             return `<span class="icon-label" title="${row.user_status}">
173                  <i class="fas fa-user-shield text-info"></i>
174                  </span>`;
175           } else {
176             return `<span>${row.user_status}</span>`;
177           }
178         }
179       },
180       account_expire_time: { title: this.translateService.instant('Expires in'), width: '10%' },
181       modified: { title: this.translateService.instant('MODIFIED'), width: '10%' },
182       created: { title: this.translateService.instant('CREATED'), width: '10%' },
183       Actions: {
184         name: 'Action', width: '5%', filter: false, sort: false, title: this.translateService.instant('ACTIONS'), type: 'custom',
185         valuePrepareFunction: (cell: UserData, row: UserData): UserData => row,
186         renderComponent: UsersActionComponent
187       }
188     };
189   }
190
191   /** smart table Data Settings @public */
192   public generateSettings(): void {
193     this.settings = {
194       edit: { editButtonContent: '<i class="fa fa-edit" title="Edit"></i>', confirmSave: true },
195       delete: { deleteButtonContent: '<i class="far fa-trash-alt" title="delete"></i>', confirmDelete: true },
196       columns: this.columnLists,
197       actions: { add: false, edit: false, delete: false, position: 'right' },
198       attr: this.sharedService.tableClassConfig(),
199       pager: this.sharedService.paginationPagerConfig(),
200       noDataMessage: this.translateService.instant('NODATAMSG')
201     };
202   }
203
204   /** To hide coulmns in smart table @public */
205   public hideColumnForUser(): void {
206     if (!this.isAdminShow) {
207       const userStatus: string = 'user_status';
208       const expire: string = 'account_expire_time';
209       // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
210       delete this.columnLists[userStatus];
211       // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
212       delete this.columnLists[expire];
213     } else {
214       const modified: string = 'modified';
215       // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
216       delete this.columnLists[modified];
217     }
218   }
219
220   /** on Navigate to Composer Page @public */
221   public composeUser(): void {
222     // eslint-disable-next-line security/detect-non-literal-fs-filename
223     const modalRef: NgbModalRef = this.modalService.open(AddEditUserComponent, { backdrop: 'static' });
224     modalRef.componentInstance.userTitle = this.translateService.instant('PAGE.USERS.NEWUSER');
225     modalRef.componentInstance.userType = 'add';
226     modalRef.result.then((result: MODALCLOSERESPONSEDATA) => {
227       if (result) {
228         this.sharedService.callData();
229       }
230     }).catch((): void => {
231       // Catch Navigation Error
232     });
233   }
234
235   /** smart table listing manipulation @private */
236   public onChange(perPageValue: number): void {
237     this.dataSource.setPaging(1, perPageValue, true);
238   }
239
240   /** OnUserRowSelect function @private */
241   public onUserRowSelect(event: MessageEvent): void {
242     Object.assign(event.data, { page: 'users' });
243     this.dataService.changeMessage(event.data);
244   }
245
246   /** Set up user details @public */
247   public setUserDetails(userData: UserDetail): void {
248     const userDataObj: UserData = {
249       username: userData.username,
250       modified: this.sharedService.convertEpochTime(!isNullOrUndefined(userData._admin) ? userData._admin.modified : null),
251       created: this.sharedService.convertEpochTime(!isNullOrUndefined(userData._admin) ? userData._admin.created : null),
252       projects: userData.projectListName,
253       identifier: userData._id,
254       user_status: userData._admin.user_status,
255       account_expire_time: this.sharedService.convertEpochTime(!isNullOrUndefined(userData._admin) ?
256         userData._admin.account_expire_time : null)
257     };
258     this.userData.push(userDataObj);
259   }
260
261   /**
262    * Lifecyle hook which get trigger on component destruction
263    */
264   public ngOnDestroy(): void {
265     this.generateDataSub.unsubscribe();
266   }
267
268   /** Fetching the data from server to Load in the smarttable @protected */
269   protected generateData(): void {
270     this.isLoadingResults = true;
271     this.restService.getResource(environment.USERS_URL).subscribe((usersData: UserDetail[]) => {
272       this.userData = [];
273       usersData.forEach((userData: UserDetail) => {
274         if (userData.projects.length > 0) {
275           userData.projectListName = userData.projects.join(', ');
276         } else {
277           userData.projectListName = '';
278         }
279         this.setUserDetails(userData);
280       });
281       if (this.userData.length > 0) {
282         this.checkDataClass = 'dataTables_present';
283       } else {
284         this.checkDataClass = 'dataTables_empty';
285       }
286       this.dataSource.load(this.userData).then((data: {}) => {
287         this.isLoadingResults = false;
288       }).catch((): void => {
289         // Catch Navigation Error
290       });
291     }, (error: ERRORDATA) => {
292       this.restService.handleError(error, 'get');
293       this.isLoadingResults = false;
294     });
295   }
296 }