packages/ui/src/lib/notifications/notifications.component.ts
Displays any kind of Notification inside the DOM.
It listens on the notificationService.$emitter for notifications.
selector | ec-notifications |
templateUrl | ./notifications.component.html |
Properties |
Inputs |
constructor(notificationService: NotificationsService)
|
||||||
Listens on the NotificationService and shows each notification that has this component set as host, or none at all.
Parameters :
|
time | |
Type : number
|
|
The default time for a notification to be visible. Will be ignored if the notification itself has a time set. |
notifications |
Type : Collection<Notification>
|
Default value : new Collection([])
|
The current stack of notifications that are visible. |
The Notifications Module is a combination of the NotificationsService and the NotificationsComponent.
<ec-notifications></ec-notifications>
export class MyComponent {
constructor(private notifications: NotificationsService) {}
showNotification() {
this.notifications.emit({
type: 'success',
title: 'Das ist der Notification Titel',
message: 'Das ist die Beschreibung'
});
}
doSomethingRisky() {
return Promise.reject('Fehler')
.catch((err) => {
this.notifications.emit({
error: err, // passing the error Object
title: 'Fehler!'
})
})
}
}
The given type will be added as class. The classes that are available by default can be looked up here.
You can also use multiple ec-notifications at different places:
<ec-notifications #a></ec-notifications>
<ec-notifications #b></ec-notifications>
<button (click)="emit(a)">A</button>
<button (click)="emit(b)">B</button>
All you have to do, is pass the instance of the component that should display the notification via the host property:
export class MyComponent {
constructor(private notifications: NotificationsService) {}
emit(host) {
this.notifications.emit({
type: 'success',
title: 'Das ist der Notification Titel',
host: host
});
}
}
Here is an example usage of a typical success/error handling. It features hiding previous notifications. We recommended you to use the WithNotifications interface for that case.
export class MuffinComponent implements WithNotifications {
/** Recent Error notification */
notifications: Notification[] = [];
constructor(
public bakery:BakeryService,
public notificationService: NotificationsService,
)
bake() {
this.bakery.bake().then(()=> {
this.notificationService.emit({
title: 'Muffin was baken!',
hide: this.notifications // this will hide all preceding notifications
})
}).catch(error=>{
this.notificationService.emit({
title: 'Error while baking',
sticky: true,
hide: this.notifications, // this will hide all preceding notifications
replace: this.notifications // this will replace the given array with the new notification
})
});
}
}
The hide option is useful to hide obsolete errors. E.g. If you successfully log in after one failiure, the sticky error notification of the first attempt will be hidden. This enables you to keep errors messages as long as they are needed. Instead of replace, you could also use append (see notification.component.ts for implementation).
import { Component, Input } from '@angular/core';
import { Collection } from '@ec.components/core';
import { Notification } from './notification';
import { NotificationsService } from './notifications.service';
/** Displays any kind of Notification inside the DOM.
* It listens on the notificationService.$emitter for notifications.
* <example-url>https://components.entrecode.de/ui/notifications?e=1</example-url>
* */
@Component({
selector: 'ec-notifications',
templateUrl: './notifications.component.html',
})
export class NotificationsComponent {
/** The current stack of notifications that are visible. */
notifications: Collection<Notification> = new Collection([]);
/** The default time for a notification to be visible. Will be ignored if the notification itself has a time set. */
@Input() time: number;
/** Listens on the NotificationService and shows each notification that has this component set as host, or none at all. */
constructor(private notificationService: NotificationsService) {
this.time = this.time || this.notificationService.defaultTime;
this.notificationService.emitter$.subscribe((notification: Notification) => {
if (notification.hide) {
this.notifications.removeAll(notification.hide);
}
if (!notification.title && !notification.message) {
// console.warn('tried to emit notification without message and title', notification);
return;
}
if (notification.append) {
notification.append.push(notification);
}
if (notification.replace) {
notification.replace.length = 0;
notification.replace.push(notification);
}
if (!notification.host || notification.host === this) {
this.notifications.add(notification);
if (notification.sticky) {
if (notification.time) {
console.warn('notification.time is ignored because it was set sticky');
}
return;
}
setTimeout(() => this.notifications.remove(notification), notification.time || this.time);
}
});
}
}
<div class="ec-notifications">
<ec-pop *ngFor="let notification of notifications?.items" [active]="true" class="ec-notification" [ngClass]="'is-' + notification.type">
<h6 class="ec-notification__title">{{notification.title}}</h6>
<p class="ec-notification__message">{{notification.message}}</p>
<ec-error *ngIf="notification.error" [error]="notification.error"></ec-error>
<ul *ngIf="notification.error?.errors" class="ec-notification-errors-list">
<li *ngFor="let error of notification.error?.errors">
<ec-error [error]="error"></ec-error>
</li>
</ul>
<a class="ec-notification__dismiss" (click)="notifications.remove(notification)">
<ec-icon name="close"></ec-icon>
</a>
</ec-pop>
</div>