UNPKG

39.2 kBJavaScriptView Raw
1import { trigger, state, style, transition, animate } from '@angular/animations';
2import * as i0 from '@angular/core';
3import { EventEmitter, Injectable, Inject, TemplateRef, Component, ViewEncapsulation, ChangeDetectionStrategy, Input, Output, InjectionToken, NgModule } from '@angular/core';
4import { Subject } from 'rxjs';
5import * as i2 from '@angular/platform-browser';
6import * as i3 from '@angular/common';
7import { CommonModule } from '@angular/common';
8import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
9
10const DEFAULT_ICONS = {
11 alert: `
12 <svg class="simple-notification-svg" xmlns="http://www.w3.org/2000/svg" fill="#ffffff" height="24" viewBox="0 0 24 24" width="24">
13 <path d="M0 0h24v24H0z" fill="none"/>
14 <path d="M22 5.72l-4.6-3.86-1.29 1.53 4.6 3.86L22 5.72zM7.88 3.39L6.6 1.86 2 5.71l1.29 1.53 4.59-3.85zM12.5 8H11v6l4.75 2.85.75-1.23-4-2.37V8zM12 4c-4.97 0-9 4.03-9 9s4.02 9 9 9c4.97 0 9-4.03 9-9s-4.03-9-9-9zm0 16c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z"/>
15 </svg>
16 `,
17 error: `
18 <svg class="simple-notification-svg" xmlns="http://www.w3.org/2000/svg" fill="#ffffff" height="24" viewBox="0 0 24 24" width="24">
19 <path d="M0 0h24v24H0V0z" fill="none"/>
20 <path d="M11 15h2v2h-2zm0-8h2v6h-2zm.99-5C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"/>
21 </svg>
22 `,
23 info: `
24 <svg class="simple-notification-svg" xmlns="http://www.w3.org/2000/svg" fill="#ffffff" height="24" viewBox="0 0 24 24" width="24">
25 <path d="M0 0h24v24H0z" fill="none"/>
26 <path d="M11 17h2v-6h-2v6zm1-15C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zM11 9h2V7h-2v2z"/>
27 </svg>
28 `,
29 success: `
30 <svg class="simple-notification-svg" xmlns="http://www.w3.org/2000/svg" fill="#ffffff" height="24" viewBox="0 0 24 24" width="24">
31 <path d="M0 0h24v24H0z" fill="none"/>
32 <path d="M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z"/>
33 </svg>
34 `,
35 warn: `
36 <svg class="simple-notification-svg" xmlns="http://www.w3.org/2000/svg" fill="#ffffff" width="64" viewBox="0 0 64 64" height="64">
37 <circle cx="32.086" cy="50.142" r="2.256"/>
38 <path d="M30.08 25.012V42.32c0 1.107.897 2.005 2.006 2.005s2.006-.897 2.006-2.005V25.012c0-1.107-.897-2.006-2.006-2.006s-2.006.898-2.006 2.006z"/>
39 <path d="M63.766 59.234L33.856 3.082c-.697-1.308-2.844-1.308-3.54 0L.407 59.234c-.331.622-.312 1.372.051 1.975.362.605 1.015.975 1.72.975h59.816c.705 0 1.357-.369 1.721-.975.361-.603.381-1.353.051-1.975zM5.519 58.172L32.086 8.291l26.568 49.881H5.519z"/>
40 </svg>
41 `
42};
43
44var NotificationType;
45(function (NotificationType) {
46 NotificationType["Success"] = "success";
47 NotificationType["Error"] = "error";
48 NotificationType["Alert"] = "alert";
49 NotificationType["Info"] = "info";
50 NotificationType["Warn"] = "warn";
51 NotificationType["Bare"] = "bare";
52})(NotificationType || (NotificationType = {}));
53
54class NotificationsService {
55 constructor(globalOptions) {
56 this.globalOptions = globalOptions;
57 this.emitter = new Subject();
58 this.icons = DEFAULT_ICONS;
59 }
60 set(notification, to) {
61 notification.id = notification.override && notification.override.id ?
62 notification.override.id :
63 Math.random().toString(36).substring(3);
64 notification.click = new EventEmitter();
65 notification.clickIcon = new EventEmitter();
66 notification.timeoutEnd = new EventEmitter();
67 this.emitter.next({ command: 'set', notification, add: to });
68 return notification;
69 }
70 success(title = '', content = '', override, context) {
71 return this.set({ title, content: content || '', type: NotificationType.Success, icon: this.icons.success, override, context }, true);
72 }
73 error(title = '', content = '', override, context) {
74 return this.set({ title, content: content || '', type: NotificationType.Error, icon: this.icons.error, override, context }, true);
75 }
76 alert(title = '', content = '', override, context) {
77 return this.set({ title, content: content || '', type: NotificationType.Alert, icon: this.icons.alert, override, context }, true);
78 }
79 info(title = '', content = '', override, context) {
80 return this.set({ title, content: content || '', type: NotificationType.Info, icon: this.icons.info, override, context }, true);
81 }
82 warn(title = '', content = '', override, context) {
83 return this.set({ title, content: content || '', type: NotificationType.Warn, icon: this.icons.warn, override, context }, true);
84 }
85 bare(title = '', content = '', override, context) {
86 return this.set({ title, content: content || '', type: NotificationType.Bare, icon: 'bare', override, context }, true);
87 }
88 // With type method
89 create(title = '', content = '', type = NotificationType.Success, override, context) {
90 return this.set({ title, content, type, icon: this.icons[type], override, context }, true);
91 }
92 // HTML Notification method
93 html(html, type = NotificationType.Success, override, icon = 'bare', context) {
94 return this.set({ html, type, icon: this.icons[icon], override, context }, true);
95 }
96 // Remove all notifications method
97 remove(id) {
98 if (id) {
99 this.emitter.next({ command: 'clean', id });
100 }
101 else {
102 this.emitter.next({ command: 'cleanAll' });
103 }
104 }
105}
106NotificationsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0, type: NotificationsService, deps: [{ token: 'options' }], target: i0.ɵɵFactoryTarget.Injectable });
107NotificationsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0, type: NotificationsService });
108i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0, type: NotificationsService, decorators: [{
109 type: Injectable
110 }], ctorParameters: function () { return [{ type: undefined, decorators: [{
111 type: Inject,
112 args: ['options']
113 }] }]; } });
114
115class NotificationComponent {
116 constructor(notificationService, domSanitizer, cd, zone) {
117 this.notificationService = notificationService;
118 this.domSanitizer = domSanitizer;
119 this.cd = cd;
120 this.zone = zone;
121 this.titleIsTemplate = false;
122 this.contentIsTemplate = false;
123 this.htmlIsTemplate = false;
124 this.progressWidth = 0;
125 this.stopTime = false;
126 this.framesPerSecond = 40;
127 this.instance = () => {
128 const now = new Date().getTime();
129 if (this.endTime < now) {
130 this.remove();
131 this.item.timeoutEnd.emit();
132 }
133 else if (!this.stopTime) {
134 if (this.showProgressBar) {
135 // We add this.sleepTime just to have 100% before close
136 this.progressWidth = Math.min((now - this.startTime + this.sleepTime) * 100 / this.timeOut, 100);
137 }
138 this.timer = setTimeout(this.instance, this.sleepTime);
139 }
140 this.zone.run(() => {
141 if (!this.cd.destroyed) {
142 this.cd.detectChanges();
143 }
144 });
145 };
146 }
147 ngOnInit() {
148 if (this.item.override) {
149 this.attachOverrides();
150 }
151 if (this.animate) {
152 this.item.state = this.animate;
153 }
154 if (this.timeOut !== 0) {
155 this.startTimeOut();
156 }
157 this.contentType(this.item.title, 'title');
158 this.contentType(this.item.content, 'content');
159 this.contentType(this.item.html, 'html');
160 this.safeSvg = this.domSanitizer.bypassSecurityTrustHtml(this.icon || this.item.icon);
161 this.safeInputHtml = this.domSanitizer.bypassSecurityTrustHtml(this.item.html);
162 }
163 ngOnDestroy() {
164 clearTimeout(this.timer);
165 this.cd.detach();
166 }
167 startTimeOut() {
168 this.sleepTime = 1000 / this.framesPerSecond /* ms */;
169 this.startTime = new Date().getTime();
170 this.endTime = this.startTime + this.timeOut;
171 this.zone.runOutsideAngular(() => this.timer = setTimeout(this.instance, this.sleepTime));
172 }
173 onEnter() {
174 if (this.pauseOnHover) {
175 this.stopTime = true;
176 this.pauseStart = new Date().getTime();
177 }
178 }
179 onLeave() {
180 if (this.pauseOnHover) {
181 this.stopTime = false;
182 this.startTime += (new Date().getTime() - this.pauseStart);
183 this.endTime += (new Date().getTime() - this.pauseStart);
184 this.zone.runOutsideAngular(() => setTimeout(this.instance, this.sleepTime));
185 }
186 }
187 onClick(event) {
188 this.item.click.emit(event);
189 if (this.clickToClose) {
190 this.remove();
191 }
192 }
193 onClickIcon(event) {
194 this.item.clickIcon.emit(event);
195 if (this.clickIconToClose) {
196 this.remove();
197 }
198 }
199 // Attach all the overrides
200 attachOverrides() {
201 Object.keys(this.item.override).forEach(a => {
202 if (this.hasOwnProperty(a)) {
203 this[a] = this.item.override[a];
204 }
205 });
206 }
207 remove() {
208 if (this.animate) {
209 this.item.state = this.animate + 'Out';
210 setTimeout(() => {
211 this.notificationService.set(this.item, false);
212 }, 310);
213 }
214 else {
215 this.notificationService.set(this.item, false);
216 }
217 }
218 contentType(item, key) {
219 if (item instanceof TemplateRef) {
220 this[key] = item;
221 }
222 else {
223 this[key] = this.domSanitizer.bypassSecurityTrustHtml(item);
224 }
225 this[key + 'IsTemplate'] = item instanceof TemplateRef;
226 }
227}
228NotificationComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0, type: NotificationComponent, deps: [{ token: NotificationsService }, { token: i2.DomSanitizer }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
229NotificationComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.12", type: NotificationComponent, selector: "simple-notification", inputs: { timeOut: "timeOut", showProgressBar: "showProgressBar", pauseOnHover: "pauseOnHover", clickToClose: "clickToClose", clickIconToClose: "clickIconToClose", maxLength: "maxLength", theClass: "theClass", rtl: "rtl", animate: "animate", position: "position", item: "item" }, ngImport: i0, template: "<div class=\"simple-notification\"\r\n [@enterLeave]=\"item.state\"\r\n (click)=\"onClick($event)\"\r\n [class]=\"theClass\"\r\n [ngClass]=\"{\r\n 'alert': item.type === 'alert',\r\n 'error': item.type === 'error',\r\n 'warn': item.type === 'warn',\r\n 'success': item.type === 'success',\r\n 'info': item.type === 'info',\r\n 'bare': item.type === 'bare',\r\n 'rtl-mode': rtl,\r\n 'has-icon': item.icon !== 'bare'\r\n }\"\r\n (mouseenter)=\"onEnter()\"\r\n (mouseleave)=\"onLeave()\">\r\n\r\n <div *ngIf=\"!item.html\">\r\n\r\n <div class=\"sn-title\" *ngIf=\"titleIsTemplate; else regularTitle\">\r\n <ng-container *ngTemplateOutlet=\"title; context: item.context\"></ng-container>\r\n </div>\r\n\r\n <ng-template #regularTitle>\r\n <div class=\"sn-title\" [innerHTML]=\"title\"></div>\r\n </ng-template>\r\n\r\n <div class=\"sn-content\" *ngIf=\"contentIsTemplate else regularContent\">\r\n <ng-container *ngTemplateOutlet=\"content; context: item.context\"></ng-container>\r\n </div>\r\n\r\n <ng-template #regularContent>\r\n <div class=\"sn-content\" [innerHTML]=\"content\"></div>\r\n </ng-template>\r\n\r\n <div class=\"icon\" *ngIf=\"item.icon !== 'bare'\" [innerHTML]=\"safeSvg\"></div>\r\n </div>\r\n <div *ngIf=\"item.html\">\r\n <div class=\"sn-html\" *ngIf=\"htmlIsTemplate; else regularHtml\">\r\n <ng-container *ngTemplateOutlet=\"item.html; context: item.context\"></ng-container>\r\n </div>\r\n\r\n <ng-template #regularHtml>\r\n <div class=\"sn-content\" [innerHTML]=\"safeInputHtml\"></div>\r\n </ng-template>\r\n\r\n <div class=\"icon\" [class.icon-hover]=\"clickIconToClose\" *ngIf=\"item.icon\" [innerHTML]=\"safeSvg\" (click)=\"onClickIcon($event)\"></div>\r\n </div>\r\n\r\n <div class=\"sn-progress-loader\" *ngIf=\"showProgressBar\">\r\n <span [ngStyle]=\"{'width': progressWidth + '%'}\"></span>\r\n </div>\r\n\r\n</div>\r\n", styles: [".simple-notification{width:100%;padding:10px 20px;box-sizing:border-box;position:relative;float:left;margin-bottom:10px;color:#fff;cursor:pointer;transition:all .5s;min-height:70px}.simple-notification .sn-content,.simple-notification .sn-html,.simple-notification .sn-title{margin:0}.simple-notification .sn-title{line-height:30px;font-size:20px}.simple-notification .sn-content{font-size:16px;line-height:20px}.simple-notification.has-icon .sn-content,.simple-notification.has-icon .sn-html,.simple-notification.has-icon .sn-title{padding:0 50px 0 0}.simple-notification .icon{position:absolute;box-sizing:border-box;top:0;right:0;width:70px;height:70px;padding:10px}.simple-notification .icon.icon-hover:hover{opacity:.5}.simple-notification .icon svg{fill:#fff;width:100%;height:100%}.simple-notification .icon svg g{fill:#fff}.simple-notification.rtl-mode.has-icon .sn-content,.simple-notification.rtl-mode.has-icon .sn-html,.simple-notification.rtl-mode.has-icon .sn-title{padding:0 0 0 50px}.simple-notification.rtl-mode{direction:rtl}.simple-notification.rtl-mode .sn-content{padding:0 0 0 50px}.simple-notification.rtl-mode svg{left:0;right:auto}.simple-notification.error{background:#f44336}.simple-notification.success{background:#8bc34a}.simple-notification.alert{background:#ffdb5b}.simple-notification.info{background:#03a9f4}.simple-notification.warn{background:#ffdb5b}.simple-notification .sn-progress-loader{position:absolute;top:0;left:0;width:100%;height:5px}.simple-notification .sn-progress-loader span{float:left;height:100%}.simple-notification.success .sn-progress-loader span{background:#689f38}.simple-notification.error .sn-progress-loader span{background:#d32f2f}.simple-notification.alert .sn-progress-loader span{background:#edc242}.simple-notification.info .sn-progress-loader span{background:#0288d1}.simple-notification.warn .sn-progress-loader span{background:#edc242}.simple-notification.bare .sn-progress-loader span{background:#ccc}.simple-notification.warn div .sn-content,.simple-notification.warn div .sn-html,.simple-notification.warn div .sn-title{color:#444}"], directives: [{ type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], animations: [
230 trigger('enterLeave', [
231 // Fade
232 state('fade', style({ opacity: 1 })),
233 transition('* => fade', [
234 style({ opacity: 0 }),
235 animate('400ms ease-in-out')
236 ]),
237 state('fadeOut', style({ opacity: 0 })),
238 transition('fade => fadeOut', [
239 style({ opacity: 1 }),
240 animate('300ms ease-in-out')
241 ]),
242 // Enter from top
243 state('fromTop', style({ opacity: 1, transform: 'translateY(0)' })),
244 transition('* => fromTop', [
245 style({ opacity: 0, transform: 'translateY(-5%)' }),
246 animate('400ms ease-in-out')
247 ]),
248 state('fromTopOut', style({ opacity: 0, transform: 'translateY(5%)' })),
249 transition('fromTop => fromTopOut', [
250 style({ opacity: 1, transform: 'translateY(0)' }),
251 animate('300ms ease-in-out')
252 ]),
253 // Enter from right
254 state('fromRight', style({ opacity: 1, transform: 'translateX(0)' })),
255 transition('* => fromRight', [
256 style({ opacity: 0, transform: 'translateX(5%)' }),
257 animate('400ms ease-in-out')
258 ]),
259 state('fromRightOut', style({ opacity: 0, transform: 'translateX(-5%)' })),
260 transition('fromRight => fromRightOut', [
261 style({ opacity: 1, transform: 'translateX(0)' }),
262 animate('300ms ease-in-out')
263 ]),
264 // Enter from bottom
265 state('fromBottom', style({ opacity: 1, transform: 'translateY(0)' })),
266 transition('* => fromBottom', [
267 style({ opacity: 0, transform: 'translateY(5%)' }),
268 animate('400ms ease-in-out')
269 ]),
270 state('fromBottomOut', style({ opacity: 0, transform: 'translateY(-5%)' })),
271 transition('fromBottom => fromBottomOut', [
272 style({ opacity: 1, transform: 'translateY(0)' }),
273 animate('300ms ease-in-out')
274 ]),
275 // Enter from left
276 state('fromLeft', style({ opacity: 1, transform: 'translateX(0)' })),
277 transition('* => fromLeft', [
278 style({ opacity: 0, transform: 'translateX(-5%)' }),
279 animate('400ms ease-in-out')
280 ]),
281 state('fromLeftOut', style({ opacity: 0, transform: 'translateX(5%)' })),
282 transition('fromLeft => fromLeftOut', [
283 style({ opacity: 1, transform: 'translateX(0)' }),
284 animate('300ms ease-in-out')
285 ]),
286 // Rotate
287 state('scale', style({ opacity: 1, transform: 'scale(1)' })),
288 transition('* => scale', [
289 style({ opacity: 0, transform: 'scale(0)' }),
290 animate('400ms ease-in-out')
291 ]),
292 state('scaleOut', style({ opacity: 0, transform: 'scale(0)' })),
293 transition('scale => scaleOut', [
294 style({ opacity: 1, transform: 'scale(1)' }),
295 animate('400ms ease-in-out')
296 ]),
297 // Scale
298 state('rotate', style({ opacity: 1, transform: 'rotate(0deg)' })),
299 transition('* => rotate', [
300 style({ opacity: 0, transform: 'rotate(5deg)' }),
301 animate('400ms ease-in-out')
302 ]),
303 state('rotateOut', style({ opacity: 0, transform: 'rotate(-5deg)' })),
304 transition('rotate => rotateOut', [
305 style({ opacity: 1, transform: 'rotate(0deg)' }),
306 animate('400ms ease-in-out')
307 ])
308 ])
309 ], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
310i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0, type: NotificationComponent, decorators: [{
311 type: Component,
312 args: [{
313 selector: 'simple-notification',
314 encapsulation: ViewEncapsulation.None,
315 animations: [
316 trigger('enterLeave', [
317 // Fade
318 state('fade', style({ opacity: 1 })),
319 transition('* => fade', [
320 style({ opacity: 0 }),
321 animate('400ms ease-in-out')
322 ]),
323 state('fadeOut', style({ opacity: 0 })),
324 transition('fade => fadeOut', [
325 style({ opacity: 1 }),
326 animate('300ms ease-in-out')
327 ]),
328 // Enter from top
329 state('fromTop', style({ opacity: 1, transform: 'translateY(0)' })),
330 transition('* => fromTop', [
331 style({ opacity: 0, transform: 'translateY(-5%)' }),
332 animate('400ms ease-in-out')
333 ]),
334 state('fromTopOut', style({ opacity: 0, transform: 'translateY(5%)' })),
335 transition('fromTop => fromTopOut', [
336 style({ opacity: 1, transform: 'translateY(0)' }),
337 animate('300ms ease-in-out')
338 ]),
339 // Enter from right
340 state('fromRight', style({ opacity: 1, transform: 'translateX(0)' })),
341 transition('* => fromRight', [
342 style({ opacity: 0, transform: 'translateX(5%)' }),
343 animate('400ms ease-in-out')
344 ]),
345 state('fromRightOut', style({ opacity: 0, transform: 'translateX(-5%)' })),
346 transition('fromRight => fromRightOut', [
347 style({ opacity: 1, transform: 'translateX(0)' }),
348 animate('300ms ease-in-out')
349 ]),
350 // Enter from bottom
351 state('fromBottom', style({ opacity: 1, transform: 'translateY(0)' })),
352 transition('* => fromBottom', [
353 style({ opacity: 0, transform: 'translateY(5%)' }),
354 animate('400ms ease-in-out')
355 ]),
356 state('fromBottomOut', style({ opacity: 0, transform: 'translateY(-5%)' })),
357 transition('fromBottom => fromBottomOut', [
358 style({ opacity: 1, transform: 'translateY(0)' }),
359 animate('300ms ease-in-out')
360 ]),
361 // Enter from left
362 state('fromLeft', style({ opacity: 1, transform: 'translateX(0)' })),
363 transition('* => fromLeft', [
364 style({ opacity: 0, transform: 'translateX(-5%)' }),
365 animate('400ms ease-in-out')
366 ]),
367 state('fromLeftOut', style({ opacity: 0, transform: 'translateX(5%)' })),
368 transition('fromLeft => fromLeftOut', [
369 style({ opacity: 1, transform: 'translateX(0)' }),
370 animate('300ms ease-in-out')
371 ]),
372 // Rotate
373 state('scale', style({ opacity: 1, transform: 'scale(1)' })),
374 transition('* => scale', [
375 style({ opacity: 0, transform: 'scale(0)' }),
376 animate('400ms ease-in-out')
377 ]),
378 state('scaleOut', style({ opacity: 0, transform: 'scale(0)' })),
379 transition('scale => scaleOut', [
380 style({ opacity: 1, transform: 'scale(1)' }),
381 animate('400ms ease-in-out')
382 ]),
383 // Scale
384 state('rotate', style({ opacity: 1, transform: 'rotate(0deg)' })),
385 transition('* => rotate', [
386 style({ opacity: 0, transform: 'rotate(5deg)' }),
387 animate('400ms ease-in-out')
388 ]),
389 state('rotateOut', style({ opacity: 0, transform: 'rotate(-5deg)' })),
390 transition('rotate => rotateOut', [
391 style({ opacity: 1, transform: 'rotate(0deg)' }),
392 animate('400ms ease-in-out')
393 ])
394 ])
395 ],
396 templateUrl: './notification.component.html',
397 styleUrls: ['./notification.component.css'],
398 changeDetection: ChangeDetectionStrategy.OnPush
399 }]
400 }], ctorParameters: function () { return [{ type: NotificationsService }, { type: i2.DomSanitizer }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }]; }, propDecorators: { timeOut: [{
401 type: Input
402 }], showProgressBar: [{
403 type: Input
404 }], pauseOnHover: [{
405 type: Input
406 }], clickToClose: [{
407 type: Input
408 }], clickIconToClose: [{
409 type: Input
410 }], maxLength: [{
411 type: Input
412 }], theClass: [{
413 type: Input
414 }], rtl: [{
415 type: Input
416 }], animate: [{
417 type: Input
418 }], position: [{
419 type: Input
420 }], item: [{
421 type: Input
422 }] } });
423
424var NotificationAnimationType;
425(function (NotificationAnimationType) {
426 NotificationAnimationType["Fade"] = "fade";
427 NotificationAnimationType["FromTop"] = "fromTop";
428 NotificationAnimationType["FromRight"] = "fromRight";
429 NotificationAnimationType["FromBottom"] = "fromBottom";
430 NotificationAnimationType["FromLeft"] = "fromLeft";
431 NotificationAnimationType["Scale"] = "scale";
432 NotificationAnimationType["Rotate"] = "rotate";
433})(NotificationAnimationType || (NotificationAnimationType = {}));
434
435class SimpleNotificationsComponent {
436 constructor(service, cd) {
437 this.service = service;
438 this.cd = cd;
439 this.create = new EventEmitter();
440 this.destroy = new EventEmitter();
441 this.notifications = [];
442 this.position = ['bottom', 'right'];
443 // Received values
444 this.lastOnBottom = true;
445 this.maxStack = 8;
446 this.preventLastDuplicates = false;
447 this.preventDuplicates = false;
448 // Sent values
449 this.timeOut = 0;
450 this.maxLength = 0;
451 this.clickToClose = true;
452 this.clickIconToClose = false;
453 this.showProgressBar = true;
454 this.pauseOnHover = true;
455 this.theClass = '';
456 this.rtl = false;
457 this.animate = NotificationAnimationType.FromRight;
458 this.usingComponentOptions = false;
459 }
460 set options(opt) {
461 this.usingComponentOptions = true;
462 this.attachChanges(opt);
463 }
464 ngOnInit() {
465 /**
466 * Only attach global options if config
467 * options were never sent through input
468 */
469 if (!this.usingComponentOptions) {
470 this.attachChanges(this.service.globalOptions);
471 }
472 this.listener = this.service.emitter
473 .subscribe(item => {
474 switch (item.command) {
475 case 'cleanAll':
476 this.notifications = [];
477 break;
478 case 'clean':
479 this.cleanSingle(item.id);
480 break;
481 case 'set':
482 if (item.add) {
483 this.add(item.notification);
484 }
485 else {
486 this.defaultBehavior(item);
487 }
488 break;
489 default:
490 this.defaultBehavior(item);
491 break;
492 }
493 if (!this.cd.destroyed) {
494 this.cd.detectChanges();
495 }
496 });
497 }
498 ngOnDestroy() {
499 if (this.listener) {
500 this.listener.unsubscribe();
501 }
502 this.cd.detach();
503 }
504 // Default behavior on event
505 defaultBehavior(value) {
506 this.notifications.splice(this.notifications.indexOf(value.notification), 1);
507 this.destroy.emit(this.buildEmit(value.notification, false));
508 }
509 // Add the new notification to the notification array
510 add(item) {
511 item.createdOn = new Date();
512 const toBlock = this.preventLastDuplicates || this.preventDuplicates ? this.block(item) : false;
513 // Save this as the last created notification
514 this.lastNotificationCreated = item;
515 // Override icon if set
516 if (item.override && item.override.icons && item.override.icons[item.type]) {
517 item.icon = item.override.icons[item.type];
518 }
519 if (!toBlock) {
520 // Check if the notification should be added at the start or the end of the array
521 if (this.lastOnBottom) {
522 if (this.notifications.length >= this.maxStack) {
523 this.notifications.splice(0, 1);
524 }
525 this.notifications.push(item);
526 }
527 else {
528 if (this.notifications.length >= this.maxStack) {
529 this.notifications.splice(this.notifications.length - 1, 1);
530 }
531 this.notifications.splice(0, 0, item);
532 }
533 this.create.emit(this.buildEmit(item, true));
534 }
535 }
536 // Check if notifications should be prevented
537 block(item) {
538 const toCheck = item.html ? this.checkHtml : this.checkStandard;
539 if (this.preventDuplicates && this.notifications.length > 0) {
540 for (const notification of this.notifications) {
541 if (toCheck(notification, item)) {
542 return true;
543 }
544 }
545 }
546 if (this.preventLastDuplicates) {
547 let comp;
548 if (this.preventLastDuplicates === 'visible' && this.notifications.length > 0) {
549 if (this.lastOnBottom) {
550 comp = this.notifications[this.notifications.length - 1];
551 }
552 else {
553 comp = this.notifications[0];
554 }
555 }
556 else if (this.preventLastDuplicates === 'all' && this.lastNotificationCreated) {
557 comp = this.lastNotificationCreated;
558 }
559 else {
560 return false;
561 }
562 return toCheck(comp, item);
563 }
564 return false;
565 }
566 checkStandard(checker, item) {
567 return checker.type === item.type && checker.title === item.title && checker.content === item.content;
568 }
569 checkHtml(checker, item) {
570 return checker.html ?
571 checker.type === item.type && checker.title === item.title && checker.content === item.content && checker.html === item.html :
572 false;
573 }
574 // Attach all the changes received in the options object
575 attachChanges(options) {
576 for (const key in options) {
577 if (this.hasOwnProperty(key)) {
578 this[key] = options[key];
579 }
580 else if (key === 'icons') {
581 this.service.icons = options[key];
582 }
583 }
584 }
585 buildEmit(notification, to) {
586 const toEmit = {
587 createdOn: notification.createdOn,
588 type: notification.type,
589 icon: notification.icon,
590 id: notification.id
591 };
592 if (notification.html) {
593 toEmit.html = notification.html;
594 }
595 else {
596 toEmit.title = notification.title;
597 toEmit.content = notification.content;
598 }
599 if (!to) {
600 toEmit.destroyedOn = new Date();
601 }
602 return toEmit;
603 }
604 cleanSingle(id) {
605 let indexOfDelete = 0;
606 let doDelete = false;
607 let noti;
608 this.notifications.forEach((notification, idx) => {
609 if (notification.id === id) {
610 indexOfDelete = idx;
611 noti = notification;
612 doDelete = true;
613 }
614 });
615 if (doDelete) {
616 this.notifications.splice(indexOfDelete, 1);
617 this.destroy.emit(this.buildEmit(noti, false));
618 }
619 }
620}
621SimpleNotificationsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0, type: SimpleNotificationsComponent, deps: [{ token: NotificationsService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
622SimpleNotificationsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.12", type: SimpleNotificationsComponent, selector: "simple-notifications", inputs: { options: "options" }, outputs: { create: "create", destroy: "destroy" }, ngImport: i0, template: "<div class=\"simple-notification-wrapper\" [ngClass]=\"position\">\r\n <simple-notification\r\n *ngFor=\"let a of notifications; let i = index\"\r\n [item]=\"a\"\r\n [timeOut]=\"timeOut\"\r\n [clickToClose]=\"clickToClose\"\r\n [clickIconToClose]=\"clickIconToClose\"\r\n [maxLength]=\"maxLength\"\r\n [showProgressBar]=\"showProgressBar\"\r\n [pauseOnHover]=\"pauseOnHover\"\r\n [theClass]=\"theClass\"\r\n [rtl]=\"rtl\"\r\n [animate]=\"animate\"\r\n [position]=\"i\">\r\n </simple-notification>\r\n</div>", styles: [".simple-notification-wrapper{position:fixed;width:300px;z-index:1000}.simple-notification-wrapper.left{left:20px}.simple-notification-wrapper.top{top:20px}.simple-notification-wrapper.right{right:20px}.simple-notification-wrapper.bottom{bottom:20px}.simple-notification-wrapper.center{left:50%;transform:translateX(-50%)}.simple-notification-wrapper.middle{top:50%;transform:translateY(-50%)}.simple-notification-wrapper.middle.center{transform:translate(-50%,-50%)}@media (max-width:340px){.simple-notification-wrapper{width:auto;left:20px;right:20px}}"], components: [{ type: NotificationComponent, selector: "simple-notification", inputs: ["timeOut", "showProgressBar", "pauseOnHover", "clickToClose", "clickIconToClose", "maxLength", "theClass", "rtl", "animate", "position", "item"] }], directives: [{ type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
623i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0, type: SimpleNotificationsComponent, decorators: [{
624 type: Component,
625 args: [{
626 selector: 'simple-notifications',
627 encapsulation: ViewEncapsulation.None,
628 templateUrl: './simple-notifications.component.html',
629 styleUrls: ['./simple-notifications.component.css'],
630 changeDetection: ChangeDetectionStrategy.OnPush
631 }]
632 }], ctorParameters: function () { return [{ type: NotificationsService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { options: [{
633 type: Input
634 }], create: [{
635 type: Output
636 }], destroy: [{
637 type: Output
638 }] } });
639
640const DEFAULT_OPTIONS = {
641 position: ['bottom', 'right'],
642 timeOut: 0,
643 showProgressBar: true,
644 pauseOnHover: true,
645 lastOnBottom: true,
646 clickToClose: true,
647 clickIconToClose: false,
648 maxLength: 0,
649 maxStack: 8,
650 preventDuplicates: false,
651 preventLastDuplicates: false,
652 theClass: '',
653 rtl: false,
654 animate: NotificationAnimationType.FromRight,
655 icons: DEFAULT_ICONS
656};
657
658const OPTIONS = new InjectionToken('options');
659function optionsFactory(options) {
660 return Object.assign(Object.assign({}, DEFAULT_OPTIONS), options);
661}
662class SimpleNotificationsModule {
663 static forRoot(options = {}) {
664 return {
665 ngModule: SimpleNotificationsModule,
666 providers: [
667 NotificationsService,
668 {
669 provide: OPTIONS,
670 useValue: options
671 },
672 {
673 provide: 'options',
674 useFactory: optionsFactory,
675 deps: [OPTIONS]
676 }
677 ]
678 };
679 }
680}
681SimpleNotificationsModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0, type: SimpleNotificationsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
682SimpleNotificationsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0, type: SimpleNotificationsModule, declarations: [SimpleNotificationsComponent,
683 NotificationComponent], imports: [CommonModule,
684 BrowserAnimationsModule], exports: [SimpleNotificationsComponent] });
685SimpleNotificationsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0, type: SimpleNotificationsModule, imports: [[
686 CommonModule,
687 BrowserAnimationsModule,
688 ]] });
689i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0, type: SimpleNotificationsModule, decorators: [{
690 type: NgModule,
691 args: [{
692 imports: [
693 CommonModule,
694 BrowserAnimationsModule,
695 ],
696 declarations: [
697 SimpleNotificationsComponent,
698 NotificationComponent
699 ],
700 exports: [SimpleNotificationsComponent]
701 }]
702 }] });
703
704/**
705 * Generated bundle index. Do not edit.
706 */
707
708export { NotificationAnimationType, NotificationComponent, NotificationType, NotificationsService, OPTIONS, SimpleNotificationsComponent, SimpleNotificationsModule, optionsFactory };
709//# sourceMappingURL=angular2-notifications.js.map