File
Metadata
encapsulation |
ViewEncapsulation.None |
selector |
simple-notifications |
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; }
@media (max-width: 340px) {
.simple-notification-wrapper {
width: auto;
left: 20px;
right: 20px;
}
}
|
template |
<div class="simple-notification-wrapper" [ngClass]="position"> <simple-notification *ngFor="let a of notifications; let i = index" [item]="a" [timeOut]="timeOut" [clickToClose]="clickToClose" [maxLength]="maxLength" [showProgressBar]="showProgressBar" [pauseOnHover]="pauseOnHover" [theClass]="theClass" [rtl]="rtl" [animate]="animate" [position]="i" > </simple-notification> </div>
|
Methods
defaultBehavior
|
defaultBehavior(value: any)
|
Returns: void
|
add
|
add(item: Notification)
|
Returns: void
|
block
|
block(item: Notification)
|
Returns: boolean
|
checkStandard
|
checkStandard(checker: Notification, item: Notification)
|
Returns: boolean
|
checkHtml
|
checkHtml(checker: Notification, item: Notification)
|
Returns: boolean
|
attachChanges
|
attachChanges(options: any)
|
Returns: void
|
buildEmit
|
buildEmit(notification: Notification, to: boolean)
|
Returns: void
|
cleanSingle
|
cleanSingle(id: string)
|
Returns: void
|
Public animate
|
animate: "fromRight" | "fromLeft" | "rotate" | "scale"
|
Default value: fromRight
|
Public clickToClose
|
clickToClose: boolean
|
Default value: true
|
Private lastNotificationCreated
|
lastNotificationCreated: Notification
|
Private lastOnBottom
|
lastOnBottom: boolean
|
Default value: true
|
Private listener
|
listener: Subscription
|
Public maxLength
|
maxLength: number
|
Default value: 0
|
Private maxStack
|
maxStack: number
|
Default value: 8
|
Public notifications
|
notifications: Notification[]
|
Public pauseOnHover
|
pauseOnHover: boolean
|
Default value: true
|
Public position
|
position: ["top" | "bottom", "right" | "left"]
|
Private preventDuplicates
|
preventDuplicates: boolean
|
Default value: false
|
Private preventLastDuplicates
|
preventLastDuplicates: any
|
Default value: false
|
Public rtl
|
rtl: boolean
|
Default value: false
|
Public showProgressBar
|
showProgressBar: boolean
|
Default value: true
|
Public theClass
|
theClass: string
|
Public timeOut
|
timeOut: number
|
Default value: 0
|
import { Component, EventEmitter, OnInit, OnDestroy, ViewEncapsulation, Input, Output } from '@angular/core';
import { Subscription } from 'rxjs';
import { Options } from '../interfaces/options.type';
import { Notification } from '../interfaces/notification.type';
import { NotificationsService } from '../services/notifications.service';
@Component({
// tslint:disable-next-line:component-selector
selector: 'simple-notifications',
encapsulation: ViewEncapsulation.None,
template: `
<div class="simple-notification-wrapper" [ngClass]="position">
<simple-notification
*ngFor="let a of notifications; let i = index"
[item]="a"
[timeOut]="timeOut"
[clickToClose]="clickToClose"
[maxLength]="maxLength"
[showProgressBar]="showProgressBar"
[pauseOnHover]="pauseOnHover"
[theClass]="theClass"
[rtl]="rtl"
[animate]="animate"
[position]="i"
>
</simple-notification>
</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; }
@media (max-width: 340px) {
.simple-notification-wrapper {
width: auto;
left: 20px;
right: 20px;
}
}
`]
})
export class SimpleNotificationsComponent implements OnInit, OnDestroy {
@Input() set options(opt: Options) {
this.attachChanges(opt);
}
@Output() onCreate = new EventEmitter();
@Output() onDestroy = new EventEmitter();
public notifications: Notification[] = [];
public position: ['top' | 'bottom', 'right' | 'left'] = ['bottom', 'right'];
private lastNotificationCreated: Notification;
private listener: Subscription;
// Received values
private lastOnBottom = true;
private maxStack = 8;
private preventLastDuplicates: any = false;
private preventDuplicates = false;
// Sent values
public timeOut = 0;
public maxLength = 0;
public clickToClose = true;
public showProgressBar = true;
public pauseOnHover = true;
public theClass = '';
public rtl = false;
public animate: 'fromRight' | 'fromLeft' | 'rotate' | 'scale' = 'fromRight';
constructor(private _service: NotificationsService) { }
ngOnInit(): void {
// Listen for changes in the service
this.listener = this._service.getChangeEmitter()
.subscribe(item => {
switch (item.command) {
case 'cleanAll':
this.notifications = [];
break;
case 'clean':
this.cleanSingle(item.id!);
break;
case 'set':
if (item.add) {
this.add(item.notification!);
} else {
this.defaultBehavior(item);
}
break;
default:
this.defaultBehavior(item);
break;
}
});
}
// Default behavior on event
defaultBehavior(value: any): void {
this.notifications.splice(this.notifications.indexOf(value.notification), 1);
this.onDestroy.emit(this.buildEmit(value.notification, false));
}
// Add the new notification to the notification array
add(item: Notification): void {
item.createdOn = new Date();
const toBlock: boolean = this.preventLastDuplicates || this.preventDuplicates ? this.block(item) : false;
// Save this as the last created notification
this.lastNotificationCreated = item;
if (!toBlock) {
// Check if the notification should be added at the start or the end of the array
if (this.lastOnBottom) {
if (this.notifications.length >= this.maxStack) {
this.notifications.splice(0, 1);
}
this.notifications.push(item);
} else {
if (this.notifications.length >= this.maxStack) {
this.notifications.splice(this.notifications.length - 1, 1);
}
this.notifications.splice(0, 0, item);
}
this.onCreate.emit(this.buildEmit(item, true));
}
}
// Check if notifications should be prevented
block(item: Notification): boolean {
const toCheck = item.html ? this.checkHtml : this.checkStandard;
if (this.preventDuplicates && this.notifications.length > 0) {
for (let i = 0; i < this.notifications.length; i++) {
if (toCheck(this.notifications[i], item)) {
return true;
}
}
}
if (this.preventLastDuplicates) {
let comp: Notification;
if (this.preventLastDuplicates === 'visible' && this.notifications.length > 0) {
if (this.lastOnBottom) {
comp = this.notifications[this.notifications.length - 1];
} else {
comp = this.notifications[0];
}
} else if (this.preventLastDuplicates === 'all' && this.lastNotificationCreated) {
comp = this.lastNotificationCreated;
} else {
return false;
}
return toCheck(comp, item);
}
return false;
}
checkStandard(checker: Notification, item: Notification): boolean {
return checker.type === item.type && checker.title === item.title && checker.content === item.content;
}
checkHtml(checker: Notification, item: Notification): boolean {
return checker.html ? checker.type === item.type && checker.title === item.title && checker.content === item.content && checker.html === item.html : false;
}
// Attach all the changes received in the options object
attachChanges(options: any): void {
Object.keys(options).forEach(a => {
if (this.hasOwnProperty(a)) {
(<any>this)[a] = options[a];
}
});
}
buildEmit(notification: Notification, to: boolean) {
const toEmit: Notification = {
createdOn: notification.createdOn,
type: notification.type,
icon: notification.icon,
id: notification.id
};
if (notification.html) {
toEmit.html = notification.html;
} else {
toEmit.title = notification.title;
toEmit.content = notification.content;
}
if (!to) {
toEmit.destroyedOn = new Date();
}
return toEmit;
}
cleanSingle(id: string): void {
let indexOfDelete = 0;
let doDelete = false;
this.notifications.forEach((notification, idx) => {
if (notification.id === id) {
indexOfDelete = idx;
doDelete = true;
}
});
if (doDelete) {
this.notifications.splice(indexOfDelete, 1);
}
}
ngOnDestroy(): void {
if (this.listener) {
this.listener.unsubscribe();
}
}
}