]> git.apps.os.sepia.ceph.com Git - ceph.git/blob
5a0f9b603e9e82044a03a436bd4bf0be84d9e350
[ceph.git] /
1 import {
2   ChangeDetectionStrategy,
3   ChangeDetectorRef,
4   Component,
5   HostBinding,
6   NgZone,
7   OnDestroy,
8   OnInit
9 } from '@angular/core';
10
11 import { Mutex } from 'async-mutex';
12 import * as _ from 'lodash';
13 import * as moment from 'moment';
14 import { Subscription } from 'rxjs';
15
16 import { Icons } from '../../enum/icons.enum';
17 import { CdNotification } from '../../models/cd-notification';
18 import { ExecutingTask } from '../../models/executing-task';
19 import { FinishedTask } from '../../models/finished-task';
20 import { AuthStorageService } from '../../services/auth-storage.service';
21 import { NotificationService } from '../../services/notification.service';
22 import { PrometheusAlertService } from '../../services/prometheus-alert.service';
23 import { PrometheusNotificationService } from '../../services/prometheus-notification.service';
24 import { SummaryService } from '../../services/summary.service';
25 import { TaskMessageService } from '../../services/task-message.service';
26
27 @Component({
28   selector: 'cd-notifications-sidebar',
29   templateUrl: './notifications-sidebar.component.html',
30   styleUrls: ['./notifications-sidebar.component.scss'],
31   changeDetection: ChangeDetectionStrategy.OnPush
32 })
33 export class NotificationsSidebarComponent implements OnInit, OnDestroy {
34   @HostBinding('class.active') isSidebarOpened = false;
35
36   notifications: CdNotification[];
37   private interval: number;
38   private timeout: number;
39
40   executingTasks: ExecutingTask[] = [];
41
42   private subs = new Subscription();
43
44   icons = Icons;
45
46   // Tasks
47   last_task = '';
48   mutex = new Mutex();
49
50   simplebar = {
51     autoHide: false
52   };
53
54   constructor(
55     public notificationService: NotificationService,
56     private summaryService: SummaryService,
57     private taskMessageService: TaskMessageService,
58     private prometheusNotificationService: PrometheusNotificationService,
59     private authStorageService: AuthStorageService,
60     private prometheusAlertService: PrometheusAlertService,
61     private ngZone: NgZone,
62     private cdRef: ChangeDetectorRef
63   ) {
64     this.notifications = [];
65   }
66
67   ngOnDestroy() {
68     window.clearInterval(this.interval);
69     window.clearTimeout(this.timeout);
70     this.subs.unsubscribe();
71   }
72
73   ngOnInit() {
74     this.last_task = window.localStorage.getItem('last_task');
75
76     const permissions = this.authStorageService.getPermissions();
77     if (permissions.prometheus.read && permissions.configOpt.read) {
78       this.triggerPrometheusAlerts();
79       this.ngZone.runOutsideAngular(() => {
80         this.interval = window.setInterval(() => {
81           this.ngZone.run(() => {
82             this.triggerPrometheusAlerts();
83           });
84         }, 5000);
85       });
86     }
87
88     this.subs.add(
89       this.notificationService.data$.subscribe((notifications: CdNotification[]) => {
90         this.notifications = _.orderBy(notifications, ['timestamp'], ['desc']);
91         this.cdRef.detectChanges();
92       })
93     );
94
95     this.subs.add(
96       this.notificationService.sidebarSubject.subscribe((forceClose) => {
97         if (forceClose) {
98           this.isSidebarOpened = false;
99         } else {
100           this.isSidebarOpened = !this.isSidebarOpened;
101         }
102
103         window.clearTimeout(this.timeout);
104         this.timeout = window.setTimeout(() => {
105           this.cdRef.detectChanges();
106         }, 0);
107       })
108     );
109
110     this.subs.add(
111       this.summaryService.subscribe((summary) => {
112         this._handleTasks(summary.executing_tasks);
113
114         this.mutex.acquire().then((release) => {
115           _.filter(
116             summary.finished_tasks,
117             (task: FinishedTask) => !this.last_task || moment(task.end_time).isAfter(this.last_task)
118           ).forEach((task) => {
119             const config = this.notificationService.finishedTaskToNotification(task, task.success);
120             const notification = new CdNotification(config);
121             notification.timestamp = task.end_time;
122             notification.duration = task.duration;
123
124             if (!this.last_task || moment(task.end_time).isAfter(this.last_task)) {
125               this.last_task = task.end_time;
126               window.localStorage.setItem('last_task', this.last_task);
127             }
128
129             this.notificationService.save(notification);
130           });
131
132           this.cdRef.detectChanges();
133
134           release();
135         });
136       })
137     );
138   }
139
140   _handleTasks(executingTasks: ExecutingTask[]) {
141     for (const excutingTask of executingTasks) {
142       excutingTask.description = this.taskMessageService.getRunningTitle(excutingTask);
143     }
144     this.executingTasks = executingTasks;
145   }
146
147   private triggerPrometheusAlerts() {
148     this.prometheusAlertService.refresh();
149     this.prometheusNotificationService.refresh();
150   }
151
152   removeAll() {
153     this.notificationService.removeAll();
154   }
155
156   remove(index: number) {
157     this.notificationService.remove(index);
158   }
159
160   closeSidebar() {
161     this.isSidebarOpened = false;
162   }
163
164   trackByFn(index: number) {
165     return index;
166   }
167 }