Fix Bug 2121: NG-UI uses unmaintained Chokidar version
[osm/NG-UI.git] / src / app / dashboard / DashboardComponent.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 Dashboard Component
20  */
21 import { isNullOrUndefined } from 'util';
22 import { Component, Injector, OnInit } from '@angular/core';
23 import { TranslateService } from '@ngx-translate/core';
24 import { NotifierService } from 'angular-notifier';
25 import { AuthenticationService } from 'AuthenticationService';
26 import { Chart, ChartType, LineController, LineElement, PointElement, LinearScale, Title, ChartEvent, ActiveElement } from 'chart.js';
27 import ChartDataLabels from 'chartjs-plugin-datalabels';
28 Chart.register(LineController, LineElement, PointElement, LinearScale, Title, ChartDataLabels);
29 import { ERRORDATA, TYPESECTION, VIM_TYPES } from 'CommonModel';
30 import { environment } from 'environment';
31 import { NSDDetails } from 'NSDModel';
32 import { NSInstanceDetails } from 'NSInstanceModel';
33 import { ProjectData, ProjectDetails } from 'ProjectModel';
34 import { ProjectService } from 'ProjectService';
35 import { RestService } from 'RestService';
36 import { Observable, Subscription } from 'rxjs';
37 import { SDNControllerModel } from 'SDNControllerModel';
38 import { SharedService } from 'SharedService';
39 import { ProjectRoleMappings, UserDetail } from 'UserModel';
40 import { VimAccountDetails } from 'VimAccountModel';
41 import { VNFInstanceDetails } from 'VNFInstanceModel';
42
43 /**
44  * Creating component
45  * @Component takes DashboardComponent.html as template url
46  */
47 @Component({
48     styleUrls: ['./DashboardComponent.scss'],
49     templateUrl: './DashboardComponent.html'
50 })
51
52 /**
53  * This file created during the angular project creation
54  */
55
56 /** Exporting a class @exports DashboardComponent */
57 export class DashboardComponent implements OnInit {
58     /** Invoke service injectors @public */
59     public injector: Injector;
60
61     /** Handle translate @public */
62     public translateService: TranslateService;
63
64     /** Observable holds logined value  @public */
65     public username$: Observable<string>;
66
67     /** Variables holds admin is logged or not @public */
68     public isAdmin: boolean;
69
70     /** List of NS failed Instances @public */
71     public nsFailedInstances: {}[] = [];
72
73     /** Setting up count for vnfdPackages @public */
74     public vnfdPackageCount: number;
75
76     /** Setting up count for nsdPackage @public */
77     public nsdPackageCount: number;
78
79     /** Setting up count for nsInstance @public */
80     public nsInstanceCount: number;
81
82     /** Setting up count for vnfInstance @public */
83     public vnfInstanceCount: number;
84
85     /** Setting up count for vimAccount @public */
86     public vimAccountCount: number;
87
88     /** Setting up count for sdnController @public */
89     public sdnControllerCount: number;
90
91     /** Variables holds current project details @public */
92     public currentProjectDetails: {};
93
94     /** Array holds all the projects @public */
95     public projectList: {}[] = [];
96
97     /** Array holds all the projects @public */
98     public allProjectList: {}[] = [];
99
100     /** Variables holds the selected project @public */
101     public selectedProject: Observable<string>;
102
103     /** Check the Instances loading results @public */
104     public isCanvasLoadingResults: boolean = true;
105
106     /** Check the Projects loading results @public */
107     public isProjectsLoadingResults: boolean = true;
108
109     /** Give the message for the loading @public */
110     public message: string = 'PLEASEWAIT';
111
112     /** List of NS Success Instances @public */
113     public nsRunningInstance: string[] = [];
114
115     /** Contains VIM Account details @public */
116     public vimData: VimAccountDetails[] = [];
117
118     /** Contains Selected VIM Details @public */
119     public selectedVIMDetails: VimAccountDetails = null;
120
121     /** List of VIM_TYPES @public */
122     public vimTypes: TYPESECTION[] = VIM_TYPES;
123
124     /** Array holds Vim data filtered with selected vimtype  */
125     public vimList: VimAccountDetails[] = [];
126
127     /** Model value used to hold selected vimtype Data @public */
128     public vimListData: string;
129
130     /** List of color for Instances @private */
131     private backgroundColor: string[] = [];
132
133     /** Utilizes rest service for any CRUD operations @private */
134     private restService: RestService;
135
136     /** Utilizes auth service for any auth operations @private */
137     private authService: AuthenticationService;
138
139     /** Used to subscribe vnfdPackage @private */
140     private vnfdPackageCountSub: Subscription;
141
142     /** Used to subscribe nsdPackage @private */
143     private nsdPackageCountSub: Subscription;
144
145     /** Used to subscribe nsInstance @private */
146     private nsInstanceCountSub: Subscription;
147
148     /** Used to subscribe vnfInstance @private */
149     private vnfInstanceCountSub: Subscription;
150
151     /** Used to subscribe vimAccount @private */
152     private vimAccountCountSub: Subscription;
153
154     /** Used to subscribe sdnController @private */
155     private sdnControllerCountSub: Subscription;
156
157     /** No of Hours of NS Success Instances @private */
158     private noOfHours: number[] = [];
159
160     /** collects charts objects @private */
161     private charts: object = [];
162
163     /** Contains all methods related to projects @private */
164     private projectService: ProjectService;
165
166     /** Contains all methods related to shared @private */
167     private sharedService: SharedService;
168
169     /** Contains NS Instance Details */
170     private nsInstancesDataArr: {}[];
171
172     /** Container created time array @private */
173     private createdTimes: string[] = [];
174
175     /** Contains slice limit const @private */
176     // eslint-disable-next-line @typescript-eslint/no-magic-numbers
177     private sliceLimit: number = 10;
178
179     /** Contians hour converter @private */
180     // eslint-disable-next-line @typescript-eslint/no-magic-numbers
181     private hourConverter: number = 3600;
182
183     /** Converter used to round off time to one decimal point @private */
184     // eslint-disable-next-line @typescript-eslint/no-magic-numbers
185     private converter: number = 10;
186
187     /** Notifier service to popup notification @private */
188     private notifierService: NotifierService;
189
190     constructor(injector: Injector) {
191         this.injector = injector;
192         this.restService = this.injector.get(RestService);
193         this.authService = this.injector.get(AuthenticationService);
194         this.projectService = this.injector.get(ProjectService);
195         this.sharedService = this.injector.get(SharedService);
196         this.translateService = this.injector.get(TranslateService);
197         this.notifierService = this.injector.get(NotifierService);
198     }
199
200     /**
201      * Lifecyle Hooks the trigger before component is instantiate
202      */
203     public ngOnInit(): void {
204         this.username$ = this.authService.username;
205         this.isAdmin = (localStorage.getItem('isAdmin') === 'true') ? true : false;
206         this.selectedProject = this.authService.ProjectName;
207         this.checkAdminPrivilege();
208         this.getUserAccessedProjects();
209         this.getAllProjects();
210         this.getVnfdPackageCount();
211         this.getNsdPackageCount();
212         this.getNsInstanceCount();
213         this.getVnfInstanceCount();
214         this.getVimAccountCount();
215         this.getSDNControllerCount();
216     }
217
218     /** Get all the projects @public */
219     public getUserAccessedProjects(): void {
220         this.projectService.getUserProjects().subscribe((projects: UserDetail): void => {
221             const projectList: {}[] = projects.project_role_mappings;
222             this.projectList = projectList.filter(
223                 (thing: ProjectRoleMappings, i: number, arr: []): boolean => arr
224                     .findIndex((t: ProjectRoleMappings): boolean => t.project_name === thing.project_name) === i
225             );
226         }, (error: Error): void => {
227             // TODO: Handle failure
228         });
229     }
230
231     /** Fetching all the Project in dashboard @public */
232     public getAllProjects(): void {
233         this.isProjectsLoadingResults = true;
234         this.restService.getResource(environment.PROJECTS_URL).subscribe((projectsData: ProjectDetails[]): void => {
235             this.allProjectList = [];
236             projectsData.forEach((projectData: ProjectDetails): void => {
237                 const projectDataObj: ProjectData = this.generateProjectData(projectData);
238                 this.allProjectList.push(projectDataObj);
239             });
240             this.isProjectsLoadingResults = false;
241         }, (error: ERRORDATA): void => {
242             this.restService.handleError(error, 'get');
243             this.isProjectsLoadingResults = false;
244         });
245     }
246
247     /** Generate Projects object from loop and return for the datasource @public */
248     public generateProjectData(projectData: ProjectDetails): ProjectData {
249         return {
250             projectName: projectData.name,
251             modificationDate: this.sharedService.convertEpochTime(projectData._admin.modified),
252             creationDate: this.sharedService.convertEpochTime(projectData._admin.created),
253             id: projectData._id,
254             project: projectData._id
255         };
256     }
257
258     /** Function to check admin privilege @public */
259     public checkAdminPrivilege(): void {
260         if (!this.isAdmin) {
261             this.projectService.getCurrentProjectDetails().subscribe((projectDetails: {}): void => {
262                 this.currentProjectDetails = projectDetails;
263             }, (error: Error): void => {
264                 // TODO: Handle failure
265             });
266         }
267     }
268
269     /** Get VNFD Package details @public */
270     public getVnfdPackageCount(): void {
271         this.vnfdPackageCountSub = this.restService.getResource(environment.VNFPACKAGESCONTENT_URL)
272             .subscribe((vnfdPackageData: []): void => {
273                 this.vnfdPackageCount = vnfdPackageData.length;
274             }, (error: ERRORDATA): void => {
275                 this.restService.handleError(error, 'get');
276             });
277     }
278
279     /** Get NSD Package details @public */
280     public getNsdPackageCount(): void {
281         this.nsdPackageCountSub = this.restService.getResource(environment.NSDESCRIPTORSCONTENT_URL)
282             .subscribe((nsdPackageData: NSDDetails[]): void => {
283                 this.nsdPackageCount = nsdPackageData.length;
284             }, (error: ERRORDATA): void => {
285                 this.restService.handleError(error, 'get');
286             });
287     }
288
289     /** Get NS Instance details @public */
290     public getNsInstanceCount(): void {
291         this.isCanvasLoadingResults = true;
292         this.nsInstanceCountSub = this.restService.getResource(environment.NSDINSTANCES_URL)
293             .subscribe((nsInstancesData: NSInstanceDetails[]): void => {
294                 this.nsInstancesDataArr = nsInstancesData;
295                 this.nsInstanceCount = nsInstancesData.length;
296                 this.nsInstanceChart();
297                 this.isCanvasLoadingResults = false;
298             }, (error: ERRORDATA): void => {
299                 this.restService.handleError(error, 'get');
300                 this.isCanvasLoadingResults = false;
301             });
302     }
303
304     /** Get NS Instance chart details @public */
305     public nsInstanceChart(): void {
306         this.nsInstancesDataArr.forEach((nsdInstanceData: NSDDetails): void => {
307             const operationalStatus: string = nsdInstanceData['operational-status'];
308             const configStatus: string = nsdInstanceData['config-status'];
309             if (operationalStatus === 'failed' || configStatus === 'failed') {
310                 this.nsFailedInstances.push(nsdInstanceData);
311             } else if (operationalStatus === 'running' && configStatus === 'configured') {
312                 this.nsRunningInstance.push(nsdInstanceData.name);
313                 this.backgroundColor.push(this.sharedService.generateColor());
314                 this.createdTimes.push(((nsdInstanceData._admin.created).toString()).slice(0, this.sliceLimit));
315             }
316         });
317         const now: Date = new Date();
318         const currentTime: number = Number((now.getTime().toString().slice(0, this.sliceLimit)));
319         this.createdTimes.forEach((createdTime: string): void => {
320             this.noOfHours.push(Math.floor(((currentTime - Number(createdTime)) / this.hourConverter) * (this.converter)) / this.converter);
321         });
322         this.drawNsChart();
323     }
324
325     /** Prepare and sketch NS instance chart */
326     public drawNsChart(): void {
327         this.charts = new Chart('canvas', {
328             type: 'bar' as ChartType,
329             data: {
330                 labels: this.nsRunningInstance,
331                 datasets: [{
332                     data: this.noOfHours,
333                     label: this.translateService.instant('NOOFHOURS'),
334                     borderColor: this.backgroundColor,
335                     fill: false,
336                     backgroundColor: this.backgroundColor,
337                     hoverBackgroundColor: this.backgroundColor
338                 }]
339             },
340             options: {
341                 layout: {
342                     padding: {
343                         top: 25
344                     }
345                 },
346                 animation: false,
347                 // eslint-disable-next-line prefer-arrow/prefer-arrow-functions
348                 onHover(event: ChartEvent, item: ActiveElement[], chart: Chart): void {
349                     const el: HTMLElement = document.getElementById('canvas');
350                     el.style.cursor = item[0] ? 'pointer' : 'default';
351                 },
352                 plugins: {
353                     legend: { display: false },
354                     datalabels: {
355                         anchor: 'end',
356                         align: 'top',
357                         font: {
358                             weight: 'bold'
359                         }
360                     }
361                 },
362                 scales: {
363                     x: {
364                         display: true,
365                         title: {
366                             display: true,
367                             text: this.translateService.instant('NSINSTANCES')
368                         }
369                     },
370                     y: {
371                         beginAtZero: true,
372                         display: true,
373                         title: {
374                             display: true,
375                             text: this.translateService.instant('NOOFHOURS')
376                         }
377                     }
378                 }
379             }
380         });
381     }
382
383     /** Get VNFD instance details @public */
384     public getVnfInstanceCount(): void {
385         this.vnfInstanceCountSub = this.restService.getResource(environment.VNFINSTANCES_URL)
386             .subscribe((vnfInstanceData: VNFInstanceDetails[]): void => {
387                 this.vnfInstanceCount = vnfInstanceData.length;
388             }, (error: ERRORDATA): void => {
389                 this.restService.handleError(error, 'get');
390             });
391     }
392
393     /** Get VIM account details @public */
394     public getVimAccountCount(): void {
395         this.vimAccountCountSub = this.restService.getResource(environment.VIMACCOUNTS_URL)
396             .subscribe((vimAccountData: VimAccountDetails[]): void => {
397                 this.vimAccountCount = vimAccountData.length;
398                 this.vimData = vimAccountData;
399             }, (error: ERRORDATA): void => {
400                 this.restService.handleError(error, 'get');
401             });
402     }
403
404     /** Get SDN Controller Count  @public */
405     public getSDNControllerCount(): void {
406         this.sdnControllerCountSub = this.restService.getResource(environment.SDNCONTROLLER_URL)
407             .subscribe((sdnControllerData: SDNControllerModel[]): void => {
408                 this.sdnControllerCount = sdnControllerData.length;
409             }, (error: ERRORDATA): void => {
410                 this.restService.handleError(error, 'get');
411             });
412     }
413
414     /** Get Vim data filtered by the selected Vim Type @public */
415     public getSelectedVimTypeList(selectedVIMType: string): void {
416         this.vimList = this.vimData.filter((vimData: VimAccountDetails): boolean =>
417             vimData.vim_type === selectedVIMType);
418         if (this.vimList.length === 0) {
419             this.vimListData = null;
420         }
421     }
422
423     /** Get Selected VIM details @public */
424     public getSelectedVIMDetails(vimDetails: VimAccountDetails): void {
425         if (!isNullOrUndefined(vimDetails.resources)) {
426             this.selectedVIMDetails = vimDetails;
427         } else {
428             this.notifierService.notify('error', this.translateService.instant('RESOURCESNOTFOUND'));
429         }
430     }
431
432     /**
433      * Lifecyle Hooks the trigger before component is deleted
434      */
435     public ngOnDestroy(): void {
436         this.vnfdPackageCountSub.unsubscribe();
437         this.nsdPackageCountSub.unsubscribe();
438         this.nsInstanceCountSub.unsubscribe();
439         this.vnfInstanceCountSub.unsubscribe();
440         this.vimAccountCountSub.unsubscribe();
441         this.sdnControllerCountSub.unsubscribe();
442     }
443 }