import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, HostBinding, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges, ViewEncapsulation, } from '@angular/core'; import { filter, Subject, takeUntil } from 'rxjs'; import { BooleanInput, coerceBooleanProperty } from '@angular/cdk/coercion'; import { fuseAnimations } from '@fuse/animations'; import { FuseAlertAppearance, FuseAlertType, } from '@fuse/components/alert/alert.types'; import { FuseAlertService } from '@fuse/components/alert/alert.service'; import { FuseUtilsService } from '@fuse/services/utils/utils.service'; @Component({ selector: 'fuse-alert', templateUrl: './alert.component.html', styleUrls: ['./alert.component.scss'], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, animations: fuseAnimations, exportAs: 'fuseAlert', }) export class FuseAlertComponent implements OnChanges, OnInit, OnDestroy { /* eslint-disable @typescript-eslint/naming-convention */ static ngAcceptInputType_dismissible: BooleanInput; static ngAcceptInputType_dismissed: BooleanInput; static ngAcceptInputType_showIcon: BooleanInput; /* eslint-enable @typescript-eslint/naming-convention */ @Input() appearance: FuseAlertAppearance = 'soft'; @Input() dismissed: boolean = false; @Input() dismissible: boolean = false; @Input() name: string = this._fuseUtilsService.randomId(); @Input() showIcon: boolean = true; @Input() type: FuseAlertType = 'primary'; @Output() readonly dismissedChanged: EventEmitter = new EventEmitter(); private _unsubscribeAll: Subject = new Subject(); /** * Constructor */ constructor( private _changeDetectorRef: ChangeDetectorRef, private _fuseAlertService: FuseAlertService, private _fuseUtilsService: FuseUtilsService ) {} // ----------------------------------------------------------------------------------------------------- // @ Accessors // ----------------------------------------------------------------------------------------------------- /** * Host binding for component classes */ @HostBinding('class') get classList(): any { return { 'fuse-alert-appearance-border': this.appearance === 'border', 'fuse-alert-appearance-fill': this.appearance === 'fill', 'fuse-alert-appearance-outline': this.appearance === 'outline', 'fuse-alert-appearance-soft': this.appearance === 'soft', 'fuse-alert-dismissed': this.dismissed, 'fuse-alert-dismissible': this.dismissible, 'fuse-alert-show-icon': this.showIcon, 'fuse-alert-type-primary': this.type === 'primary', 'fuse-alert-type-accent': this.type === 'accent', 'fuse-alert-type-warn': this.type === 'warn', 'fuse-alert-type-basic': this.type === 'basic', 'fuse-alert-type-info': this.type === 'info', 'fuse-alert-type-success': this.type === 'success', 'fuse-alert-type-warning': this.type === 'warning', 'fuse-alert-type-error': this.type === 'error', }; } // ----------------------------------------------------------------------------------------------------- // @ Lifecycle hooks // ----------------------------------------------------------------------------------------------------- /** * On changes * * @param changes */ ngOnChanges(changes: SimpleChanges): void { // Dismissed if ('dismissed' in changes) { // Coerce the value to a boolean this.dismissed = coerceBooleanProperty(changes['dismissed'].currentValue); // Dismiss/show the alert this._toggleDismiss(this.dismissed); } // Dismissible if ('dismissible' in changes) { // Coerce the value to a boolean this.dismissible = coerceBooleanProperty( changes['dismissed'].currentValue ); } // Show icon if ('showIcon' in changes) { // Coerce the value to a boolean this.showIcon = coerceBooleanProperty(changes['showIcon'].currentValue); } } /** * On init */ ngOnInit(): void { // Subscribe to the dismiss calls this._fuseAlertService.onDismiss .pipe( filter((name: any) => this.name === name), takeUntil(this._unsubscribeAll) ) .subscribe(() => { // Dismiss the alert this.dismiss(); }); // Subscribe to the show calls this._fuseAlertService.onShow .pipe( filter((name: any) => this.name === name), takeUntil(this._unsubscribeAll) ) .subscribe(() => { // Show the alert this.show(); }); } /** * On destroy */ ngOnDestroy(): void { // Unsubscribe from all subscriptions this._unsubscribeAll.next(null); this._unsubscribeAll.complete(); } // ----------------------------------------------------------------------------------------------------- // @ Public methods // ----------------------------------------------------------------------------------------------------- /** * Dismiss the alert */ dismiss(): void { // Return if the alert is already dismissed if (this.dismissed) { return; } // Dismiss the alert this._toggleDismiss(true); } /** * Show the dismissed alert */ show(): void { // Return if the alert is already showing if (!this.dismissed) { return; } // Show the alert this._toggleDismiss(false); } // ----------------------------------------------------------------------------------------------------- // @ Private methods // ----------------------------------------------------------------------------------------------------- /** * Dismiss/show the alert * * @param dismissed * @private */ private _toggleDismiss(dismissed: boolean): void { // Return if the alert is not dismissible if (!this.dismissible) { return; } // Set the dismissed this.dismissed = dismissed; // Execute the observable this.dismissedChanged.next(this.dismissed); // Notify the change detector this._changeDetectorRef.markForCheck(); } }