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