File

src/notification/notification.service.ts

Description

Provides a way to use the notification component.

Notifications are displayed toward the top of the UI and do not interrupt the user’s work.

Example

Index

Properties
Methods

Constructor

constructor(injector: Injector, componentFactoryResolver: ComponentFactoryResolver, applicationRef: ApplicationRef)

Constructs NotificationService.

Parameters :
Name Type Optional Description
injector Injector
componentFactoryResolver ComponentFactoryResolver
applicationRef ApplicationRef

Methods

close
close(notificationRef: any)

Programatically closes notification based on notificationRef.

Parameters :
Name Type Optional Description
notificationRef any

ComponentRef of a notification or Notification component you wish to close

Returns : void
getSmartTimeout
getSmartTimeout(notificationObj: )

Calculates the amount of time user needs to read the message in the notification.

Parameters :
Name Type Optional Description
notificationObj

Same object used to instantiate notification.

In addition to type and message members, use duration member to add some extra time (in ms) to timeout if you need to.

Returns : number

calculated timeout (in ms) for smart notification

ngOnDestroy
ngOnDestroy()

OnDestroy hook.

Destroys all living notifications it is responsible for.

Returns : void
showNotification
showNotification(notificationObj: NotificationContent | ToastContent, notificationComp: )

Shows the notification based on the notificationObj.

Parameters :
Name Type Optional Description
notificationObj NotificationContent | ToastContent

Can have type, message, target, duration and smart members.

Members:

  • type can be one of "info", "warning", "danger", "success"
  • message is message for notification to display
  • target is css selector defining an element to append notification to. If not provided, showNotification() creates a place for the notification in body
  • duration is number of ms to close the notification after. If used in combination with smart, it's added to the calculated timeout
  • smart, set to true if you want to use smart notification.

Example:

// Info notification, saying "Sample message." added to the element with id notification-container
            // uses smart timeout with added duration of 1 second.
            {
            type: "info",
            message: "Sample message.",
            target: "#notification-container",
            duration: 1000,
            smart: true
            }
notificationComp

If provided, used to resolve component factory

Returns : any
showToast
showToast(notificationObj: NotificationContent | ToastContent, notificationComp: )
Parameters :
Name Type Optional Description
notificationObj NotificationContent | ToastContent
notificationComp
Returns : any

Properties

Public notificationRefs
notificationRefs:

An array containing ComponentRefs to all the notifications this service instance is responsible for.

Public onClose
onClose: EventEmitter<any>
Type : EventEmitter<any>
import {
	ApplicationRef,
	ComponentFactory,
	ComponentFactoryResolver,
	ComponentRef,
	EventEmitter,
	Injectable,
	Injector,
	OnDestroy
} from "@angular/core";

import { NotificationContent, ToastContent } from "./notification-content.interface";
import { Notification, Toast } from "./notification.module";

/**
 * Provides a way to use the notification component.
 *
 * Notifications are displayed toward the top of the UI and do not interrupt the user’s work.
 *
 * @export
 * @class NotificationService
 */
@Injectable()
export class NotificationService implements OnDestroy {
	/**
	 * An array containing `ComponentRef`s to all the notifications this service instance
	 * is responsible for.
	 *
	 * @memberof NotificationService
	 */
	public notificationRefs = new Array<ComponentRef<any>>();
	public onClose: EventEmitter<any> = new EventEmitter();

	/**
	 * Constructs NotificationService.
	 *
	 * @param {Injector} injector
	 * @param {ComponentFactoryResolver} componentFactoryResolver
	 * @param {ApplicationRef} applicationRef
	 * @memberof NotificationService
	 */
	constructor(
		private injector: Injector,
		private componentFactoryResolver: ComponentFactoryResolver,
		private applicationRef: ApplicationRef) {
	}

	/**
	 * Shows the notification based on the `notificationObj`.
	 *
	 * @param {any} notificationObj Can have `type`, `message`, `target`, `duration` and `smart` members.
	 *
	 * **Members:**
	 *
	 * * `type` can be one of `"info"`, `"warning"`, `"danger"`, `"success"`
	 * * `message` is message for notification to display
	 * * `target` is css selector defining an element to append notification to. If not provided,
	 * `showNotification()` creates a place for the notification in `body`
	 * * `duration` is number of ms to close the notification after. If used in combination with `smart`,
	 * it's added to the calculated timeout
	 * * `smart`, set to `true` if you want to use smart notification.
	 *
	 * **Example:**
	 * ```typescript
	 * // Info notification, saying "Sample message." added to the element with id notification-container
	 * // uses smart timeout with added duration of 1 second.
	 * {
	 *	type: "info",
	 *	message: "Sample message.",
	 *	target: "#notification-container",
	 *	duration: 1000,
	 *	smart: true
	 * }
	 * ```
	 *
	 * @param {any} [notificationComp=Notification] If provided, used to resolve component factory
	 * @memberof NotificationService
	 */
	showNotification(notificationObj: NotificationContent | ToastContent, notificationComp = Notification) {
		const componentFactory = this.componentFactoryResolver.resolveComponentFactory(notificationComp);

		let notificationRef = componentFactory.create(this.injector);
		notificationRef.instance.notificationObj = notificationObj as any; // typescript isn't being very smart here, so we type to any
		this.notificationRefs.push(notificationRef);

		this.onClose = notificationRef.instance.close;
		this.applicationRef.attachView(notificationRef.hostView);

		if (notificationObj.target) {
			document.querySelector(notificationObj.target).appendChild(notificationRef.location.nativeElement);
		} else {
			let body = document.querySelector("body");

			// get or create a container for alert list
			let notificationClassName = "notification-overlay";
			let notificationList = body.querySelector(`.${notificationClassName}`);
			if (!notificationList) {
				notificationList = document.createElement("div");
				notificationList.className = notificationClassName;
				body.appendChild(notificationList);
			}

			// add the notification to the top of the list
			if (notificationList.firstChild) {
				notificationList.insertBefore(notificationRef.location.nativeElement, notificationList.firstChild);
			} else {
				notificationList.appendChild(notificationRef.location.nativeElement);
			}
		}

		if (notificationObj.duration && notificationObj.duration > 0) {
			setTimeout(() => {
				this.close(notificationRef);
			}, notificationObj.duration);
		}

		if (notificationObj.smart) {
			// let it disappear after calculated timeout
			setTimeout(() => {
				this.close(notificationRef);
			}, this.getSmartTimeout(notificationObj));
		}

		this.onClose.subscribe(() => {
			this.close(notificationRef);
		});

		notificationRef.instance.componentRef = notificationRef;
		return notificationRef.instance;
	}

	showToast(notificationObj: NotificationContent | ToastContent, notificationComp = Toast) {
		return this.showNotification(notificationObj, notificationComp);
	}

	/**
	 * Programatically closes notification based on `notificationRef`.
	 *
	 * @param notificationRef `ComponentRef` of a notification or `Notification` component you wish to close
	 * @memberof NotificationService
	 */
	close(notificationRef: any) {
		if (notificationRef) {
			if (notificationRef instanceof Notification) {
				this.close(notificationRef.componentRef);
			} else {
				setTimeout( () => {
					this.applicationRef.detachView(notificationRef.hostView);
					notificationRef.destroy();
				}, 200);
			}
		}
	}

	/**
	 * Calculates the amount of time user needs to read the message in the notification.
	 *
	 * @param {any} notificationObj Same object used to instantiate notification.
	 *
	 * In addition to `type` and `message` members, use `duration` member to add
	 * some extra time (in ms) to timeout if you need to.
	 * @returns {number} calculated timeout (in ms) for smart notification
	 * @memberof NotificationService
	 */
	getSmartTimeout(notificationObj): number {
		// calculate timeout
		let timeout = 600; // start with reaction time

		// custom duration
		timeout += notificationObj.duration || 0;

		// message type
		switch (notificationObj.type) {
			case "info":
			case "success":
			default: {
				break;
			}
			case "danger": {
				timeout += 3000;
				break;
			}
			case "warning": {
				timeout += 1500;
				break;
			}
		}

		// message length
		// average reader reads around 200 words per minute, or it takes them ~0.3s per word
		// let's use 1.5 factor for below average speed readers and have 0.45s per word
		let wordCount = notificationObj.message.trim().split(/\s+/).length;
		timeout += wordCount * 450;

		return timeout;
	}

	/**
	 * OnDestroy hook.
	 *
	 * Destroys all living notifications it is responsible for.
	 *
	 * @memberof NotificationService
	 */
	ngOnDestroy() {
		if (this.notificationRefs.length > 0) {
			for (let i = 0; i < this.notificationRefs.length; i++) {
				let notificationRef = this.notificationRefs[i];
				this.applicationRef.detachView(notificationRef.hostView);
				notificationRef.destroy();
			}
			this.notificationRefs.length = 0;
		}
	}
}

results matching ""

    No results matching ""