]> BookStack Code Mirror - bookstack/blob - resources/js/services/events.ts
Comments: Split out page comment reference logic to own component
[bookstack] / resources / js / services / events.ts
1 import {HttpError} from "./http";
2
3 export class EventManager {
4     protected listeners: Record<string, ((data: any) => void)[]> = {};
5     protected stack: {name: string, data: {}}[] = [];
6
7     /**
8      * Emit a custom event for any handlers to pick-up.
9      */
10     emit(eventName: string, eventData: {} = {}): void {
11         this.stack.push({name: eventName, data: eventData});
12
13         const listenersToRun = this.listeners[eventName] || [];
14         for (const listener of listenersToRun) {
15             listener(eventData);
16         }
17     }
18
19     /**
20      * Listen to a custom event and run the given callback when that event occurs.
21      */
22     listen<T>(eventName: string, callback: (data: T) => void): void {
23         if (typeof this.listeners[eventName] === 'undefined') this.listeners[eventName] = [];
24         this.listeners[eventName].push(callback);
25     }
26
27     /**
28      * Remove an event listener which is using the given callback for the given event name.
29      */
30     remove(eventName: string, callback: Function): void {
31         const listeners = this.listeners[eventName] || [];
32         const index = listeners.indexOf(callback);
33         if (index !== -1) {
34             listeners.splice(index, 1);
35         }
36     }
37
38     /**
39      * Emit an event for public use.
40      * Sends the event via the native DOM event handling system.
41      */
42     emitPublic(targetElement: Element, eventName: string, eventData: {}): void {
43         const event = new CustomEvent(eventName, {
44             detail: eventData,
45             bubbles: true,
46         });
47         targetElement.dispatchEvent(event);
48     }
49
50     /**
51      * Emit a success event with the provided message.
52      */
53     success(message: string): void {
54         this.emit('success', message);
55     }
56
57     /**
58      * Emit an error event with the provided message.
59      */
60     error(message: string): void {
61         this.emit('error', message);
62     }
63
64     /**
65      * Notify of standard server-provided validation errors.
66      */
67     showValidationErrors(responseErr: {status?: number, data?: object}): void {
68         if (!responseErr.status) return;
69         if (responseErr.status === 422 && responseErr.data) {
70             const message = Object.values(responseErr.data).flat().join('\n');
71             this.error(message);
72         }
73     }
74
75     /**
76      * Notify standard server-provided error messages.
77      */
78     showResponseError(responseErr: {status?: number, data?: Record<any, any>}|HttpError): void {
79         if (!responseErr.status) return;
80         if (responseErr.status >= 400 && typeof responseErr.data === 'object' && responseErr.data.message) {
81             this.error(responseErr.data.message);
82         }
83     }
84 }