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