1 import { Injectable } from '@angular/core';
3 import * as _ from 'lodash';
4 import { ToastOptions, ToastsManager } from 'ng2-toastr';
5 import { BehaviorSubject } from 'rxjs';
7 import { NotificationType } from '../enum/notification-type.enum';
8 import { CdNotification, CdNotificationConfig } from '../models/cd-notification';
9 import { FinishedTask } from '../models/finished-task';
10 import { CdDatePipe } from '../pipes/cd-date.pipe';
11 import { ServicesModule } from './services.module';
12 import { TaskMessageService } from './task-message.service';
15 providedIn: ServicesModule
17 export class NotificationService {
18 private hideToasties = false;
21 private dataSource = new BehaviorSubject<CdNotification[]>([]);
22 private queuedNotifications: CdNotificationConfig[] = [];
25 data$ = this.dataSource.asObservable();
27 private queueTimeoutId: number;
28 KEY = 'cdNotifications';
31 public toastr: ToastsManager,
32 private taskMessageService: TaskMessageService,
33 private cdDatePipe: CdDatePipe
35 const stringNotifications = localStorage.getItem(this.KEY);
36 let notifications: CdNotification[] = [];
38 if (_.isString(stringNotifications)) {
39 notifications = JSON.parse(stringNotifications, (_key, value) => {
40 if (_.isPlainObject(value)) {
41 return _.assign(new CdNotification(), value);
47 this.dataSource.next(notifications);
51 * Removes all current saved notifications
54 localStorage.removeItem(this.KEY);
55 this.dataSource.next([]);
59 * Method used for saving a shown notification (check show() method).
61 save(notification: CdNotification) {
62 const recent = this.dataSource.getValue();
63 recent.push(notification);
64 while (recent.length > 10) {
67 this.dataSource.next(recent);
68 localStorage.setItem(this.KEY, JSON.stringify(recent));
71 queueNotifications(notifications: CdNotificationConfig[]) {
72 this.queuedNotifications = this.queuedNotifications.concat(notifications);
73 this.cancel(this.queueTimeoutId);
74 this.queueTimeoutId = window.setTimeout(() => {
75 this.sendQueuedNotifications();
79 private sendQueuedNotifications() {
80 _.uniqWith(this.queuedNotifications, _.isEqual).forEach((notification) => {
81 this.show(notification);
83 this.queuedNotifications = [];
87 * Method for showing a notification.
88 * @param {NotificationType} type toastr type
89 * @param {string} title
90 * @param {string} [message] The message to be displayed. Note, use this field
91 * for error notifications only.
92 * @param {*} [options] toastr compatible options, used when creating a toastr
93 * @param {string} [application] Only needed if notification comes from an external application
94 * @returns The timeout ID that is set to be able to cancel the notification.
97 type: NotificationType,
100 options?: any | ToastOptions,
103 show(config: CdNotificationConfig | (() => CdNotificationConfig)): number;
105 arg: NotificationType | CdNotificationConfig | (() => CdNotificationConfig),
108 options?: any | ToastOptions,
111 return window.setTimeout(() => {
112 let config: CdNotificationConfig;
113 if (_.isFunction(arg)) {
114 config = arg() as CdNotificationConfig;
115 } else if (_.isObject(arg)) {
116 config = arg as CdNotificationConfig;
118 config = new CdNotificationConfig(
119 arg as NotificationType,
126 const notification = new CdNotification(config);
127 this.save(notification);
128 this.showToasty(notification);
132 private showToasty(notification: CdNotification) {
133 // Exit immediately if no toasty should be displayed.
134 if (this.hideToasties) {
137 this.toastr[['error', 'info', 'success'][notification.type]](
138 (notification.message ? notification.message + '<br>' : '') +
139 this.renderTimeAndApplicationHtml(notification),
145 renderTimeAndApplicationHtml(notification: CdNotification): string {
146 return `<small class="date">${this.cdDatePipe.transform(
147 notification.timestamp
148 )}</small><i class="pull-right custom-icon ${notification.applicationClass}" title="${
149 notification.application
153 notifyTask(finishedTask: FinishedTask, success: boolean = true): number {
154 let notification: CdNotificationConfig;
155 if (finishedTask.success && success) {
156 notification = new CdNotificationConfig(
157 NotificationType.success,
158 this.taskMessageService.getSuccessTitle(finishedTask)
161 notification = new CdNotificationConfig(
162 NotificationType.error,
163 this.taskMessageService.getErrorTitle(finishedTask),
164 this.taskMessageService.getErrorMessage(finishedTask)
167 return this.show(notification);
171 * Prevent the notification from being shown.
172 * @param {number} timeoutId A number representing the ID of the timeout to be canceled.
175 window.clearTimeout(timeoutId);
179 * Suspend showing the notification toasties.
180 * @param {boolean} suspend Set to ``true`` to disable/hide toasties.
182 suspendToasties(suspend: boolean) {
183 this.hideToasties = suspend;