diff options
Diffstat (limited to 'FrontEnd/src/services/alert.ts')
-rw-r--r-- | FrontEnd/src/services/alert.ts | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/FrontEnd/src/services/alert.ts b/FrontEnd/src/services/alert.ts new file mode 100644 index 00000000..48d482ea --- /dev/null +++ b/FrontEnd/src/services/alert.ts @@ -0,0 +1,63 @@ +import React from "react"; +import pull from "lodash/pull"; + +import { BootstrapThemeColor, I18nText } from "@/common"; + +export interface AlertInfo { + type?: BootstrapThemeColor; + message: React.FC<unknown> | I18nText; + dismissTime?: number | "never"; +} + +export interface AlertInfoEx extends AlertInfo { + id: number; +} + +export type AlertConsumer = (alerts: AlertInfoEx) => void; + +export class AlertService { + private consumers: AlertConsumer[] = []; + private savedAlerts: AlertInfoEx[] = []; + private currentId = 1; + + private produce(alert: AlertInfoEx): void { + for (const consumer of this.consumers) { + consumer(alert); + } + } + + registerConsumer(consumer: AlertConsumer): void { + this.consumers.push(consumer); + if (this.savedAlerts.length !== 0) { + for (const alert of this.savedAlerts) { + this.produce(alert); + } + this.savedAlerts = []; + } + } + + unregisterConsumer(consumer: AlertConsumer): void { + pull(this.consumers, consumer); + } + + push(alert: AlertInfo): void { + const newAlert: AlertInfoEx = { ...alert, id: this.currentId++ }; + if (this.consumers.length === 0) { + this.savedAlerts.push(newAlert); + } else { + this.produce(newAlert); + } + } +} + +export const alertService = new AlertService(); + +export function pushAlert(alert: AlertInfo): void { + alertService.push(alert); +} + +export const kAlertHostId = "alert-host"; + +export function getAlertHost(): HTMLElement | null { + return document.getElementById(kAlertHostId); +} |