You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

96 lines
3.0 KiB

  1. import { Component, OnInit, OnDestroy, Input } from '@angular/core';
  2. import { Router, NavigationStart } from '@angular/router';
  3. import { Subscription } from 'rxjs';
  4. import { Alert, AlertType } from '@app/_models';
  5. import { AlertService } from '@app/_services';
  6. @Component({ selector: 'alert', templateUrl: 'alert.component.html' })
  7. export class AlertComponent implements OnInit, OnDestroy {
  8. @Input() id = 'default-alert';
  9. @Input() fade = true;
  10. alerts: Alert[] = [];
  11. alertSubscription!: Subscription;
  12. routeSubscription!: Subscription;
  13. constructor(private router: Router, private alertService: AlertService) { }
  14. ngOnInit() {
  15. // subscribe to new alert notifications
  16. this.alertSubscription = this.alertService.onAlert(this.id)
  17. .subscribe(alert => {
  18. // clear alerts when an empty alert is received
  19. if (!alert.message) {
  20. // filter out alerts without 'keepAfterRouteChange' flag
  21. this.alerts = this.alerts.filter(x => x.keepAfterRouteChange);
  22. // remove 'keepAfterRouteChange' flag on the rest
  23. this.alerts.forEach(x => delete x.keepAfterRouteChange);
  24. return;
  25. }
  26. // add alert to array
  27. this.alerts.push(alert);
  28. // auto close alert if required
  29. if (alert.autoClose) {
  30. setTimeout(() => this.removeAlert(alert), 3000);
  31. }
  32. });
  33. // clear alerts on location change
  34. this.routeSubscription = this.router.events.subscribe(event => {
  35. if (event instanceof NavigationStart) {
  36. this.alertService.clear(this.id);
  37. }
  38. });
  39. }
  40. ngOnDestroy() {
  41. // unsubscribe to avoid memory leaks
  42. this.alertSubscription.unsubscribe();
  43. this.routeSubscription.unsubscribe();
  44. }
  45. removeAlert(alert: Alert) {
  46. // check if already removed to prevent error on auto close
  47. if (!this.alerts.includes(alert)) return;
  48. if (this.fade) {
  49. // fade out alert
  50. alert.fade = true;
  51. // remove alert after faded out
  52. setTimeout(() => {
  53. this.alerts = this.alerts.filter(x => x !== alert);
  54. }, 250);
  55. } else {
  56. // remove alert
  57. this.alerts = this.alerts.filter(x => x !== alert);
  58. }
  59. }
  60. cssClass(alert: Alert) {
  61. if (!alert) return;
  62. const classes = ['alert', 'alert-dismissible', 'mt-4', 'container'];
  63. const alertTypeClass = {
  64. [AlertType.Success]: 'alert-success',
  65. [AlertType.Error]: 'alert-danger',
  66. [AlertType.Info]: 'alert-info',
  67. [AlertType.Warning]: 'alert-warning'
  68. }
  69. if (alert.type !== undefined) {
  70. classes.push(alertTypeClass[alert.type]);
  71. }
  72. if (alert.fade) {
  73. classes.push('fade');
  74. }
  75. return classes.join(' ');
  76. }
  77. }