From 552d8a0809f65920827b9b31b364fcf6edf870d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Tue, 29 Jan 2019 14:15:36 +0100 Subject: [PATCH] add notification service --- web/static/src/ts/services/ajax.ts | 6 +-- web/static/src/ts/services/notifications.ts | 52 +++++++++++++++++++ .../tests/services/notifications.test.ts | 46 ++++++++++++++++ 3 files changed, 101 insertions(+), 3 deletions(-) create mode 100644 web/static/src/ts/services/notifications.ts create mode 100644 web/static/tests/services/notifications.test.ts diff --git a/web/static/src/ts/services/ajax.ts b/web/static/src/ts/services/ajax.ts index 8d49a435..db888e42 100644 --- a/web/static/src/ts/services/ajax.ts +++ b/web/static/src/ts/services/ajax.ts @@ -1,14 +1,14 @@ -export interface RPC { +export interface RPCQuery { model: string; method: string; args: any; } export interface IAjax { - rpc(rpc: RPC): Promise; + rpc(rpc: RPCQuery): Promise; } export class Ajax implements IAjax { - rpc(rpc: RPC): Promise { + rpc(rpc: RPCQuery): Promise { return Promise.resolve(1); } } diff --git a/web/static/src/ts/services/notifications.ts b/web/static/src/ts/services/notifications.ts new file mode 100644 index 00000000..ec8bfab2 --- /dev/null +++ b/web/static/src/ts/services/notifications.ts @@ -0,0 +1,52 @@ +import { EventBus as Bus } from "../core/event_bus"; + +//------------------------------------------------------------------------------ +// Types +//------------------------------------------------------------------------------ + +export interface Notification { + id: number; + title: string; + message: string; + type: "notification" | "warning"; + sticky: boolean; +} + +export type NotificationEvent = "notification_added" | "notification_closed"; + +export type Callback = (notif: Notification) => void; + +export interface INotificationManager { + add(notif: Partial): number; + close(id: number): void; + on(event: NotificationEvent, owner: any, callback: Callback): void; +} + +//------------------------------------------------------------------------------ +// Notification Manager +//------------------------------------------------------------------------------ +export class NotificationManager extends Bus implements INotificationManager { + nextID = 0; + notifications: { [key: number]: Notification } = {}; + + add(notif: Partial): number { + const id = this.nextID++; + const defaultVals = { + title: "", + message: "", + type: "notification", + sticky: false + }; + const notification = Object.assign(defaultVals, notif, { id }); + this.notifications[id] = notification; + this.trigger("notification_added", notification); + return id; + } + close(id: number) { + let notification = this.notifications[id]; + if (notification) { + delete this.notifications[id]; + this.trigger("notification_closed", notification); + } + } +} diff --git a/web/static/tests/services/notifications.test.ts b/web/static/tests/services/notifications.test.ts new file mode 100644 index 00000000..75f91d07 --- /dev/null +++ b/web/static/tests/services/notifications.test.ts @@ -0,0 +1,46 @@ +import { + NotificationManager, + Notification, + INotificationManager +} from "../../src/ts/services/notifications"; + +//------------------------------------------------------------------------------ +// Setup and helpers +//------------------------------------------------------------------------------ + +function makeNotification(notif: Partial = {}): Notification { + const defaultNotif = { + id: 1, + title: "title", + message: "message", + type: "notification", + sticky: false + }; + return Object.assign(defaultNotif, notif); +} + +//------------------------------------------------------------------------------ +// Tests +//------------------------------------------------------------------------------ + +test("can subscribe and add notification", () => { + let notified = false; + const notifications = new NotificationManager(); + notifications.on("notification_added", {}, () => (notified = true)); + expect(notified).toBe(false); + const id = notifications.add(makeNotification()); + expect(notified).toBe(true); + expect(id).toBeDefined(); +}); + +test("can close a notification", () => { + const notifications: INotificationManager = new NotificationManager(); + let notified = false; + notifications.on("notification_closed", {}, () => (notified = true)); + + const id = notifications.add(makeNotification()); + expect(notified).toBe(false); + + notifications.close(id); + expect(notified).toBe(true); +});