From 0b3dc0301ec31c6c4980afc55f01c91927ad2431 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Tue, 29 Jan 2019 20:42:05 +0100 Subject: [PATCH] allow closing notifications on click --- web/static/src/ts/core/qweb_vdom.ts | 2 +- web/static/src/ts/widgets/notification.ts | 6 +- .../tests/services/notifications.test.ts | 39 +++-------- web/static/tests/widgets/notification.test.ts | 66 +++++++++++++++++++ 4 files changed, 80 insertions(+), 33 deletions(-) create mode 100644 web/static/tests/widgets/notification.test.ts diff --git a/web/static/src/ts/core/qweb_vdom.ts b/web/static/src/ts/core/qweb_vdom.ts index 1d45729b..2fb683e2 100644 --- a/web/static/src/ts/core/qweb_vdom.ts +++ b/web/static/src/ts/core/qweb_vdom.ts @@ -721,7 +721,7 @@ const widgetDirective: Directive = { ctx.addLine(`let _${dummyID}_index = c${ctx.parentNode}.length;`); ctx.addLine(`c${ctx.parentNode}.push(_${dummyID});`); ctx.addLine(`let def${defID};`); - let templateID = ctx.inLoop ? `(${widgetID} + i)` : String(widgetID); + let templateID = ctx.inLoop ? `(-${widgetID} - i)` : String(widgetID); ctx.addLine( `let w${widgetID} = ${templateID} in context.__widget__.cmap ? context.__widget__.children[context.__widget__.cmap[${templateID}]] : false;` ); diff --git a/web/static/src/ts/widgets/notification.ts b/web/static/src/ts/widgets/notification.ts index 3d1d3870..b3a8e15f 100644 --- a/web/static/src/ts/widgets/notification.ts +++ b/web/static/src/ts/widgets/notification.ts @@ -4,7 +4,7 @@ import { INotification } from "../services/notifications"; const template = `
- +
@@ -17,4 +17,8 @@ const template = ` export class Notification extends Widget { name = "notification"; template = template; + + close() { + this.env.notifications.close(this.props!.id); + } } diff --git a/web/static/tests/services/notifications.test.ts b/web/static/tests/services/notifications.test.ts index bab35b60..45353fd4 100644 --- a/web/static/tests/services/notifications.test.ts +++ b/web/static/tests/services/notifications.test.ts @@ -1,44 +1,21 @@ -import { - NotificationManager, - INotification, - INotificationManager -} from "../../src/ts/services/notifications"; - -//------------------------------------------------------------------------------ -// Setup and helpers -//------------------------------------------------------------------------------ - -function makeNotification(notif: Partial = {}): INotification { - const defaultNotif = { - id: 1, - title: "title", - message: "message", - type: "notification", - sticky: false - }; - return Object.assign(defaultNotif, notif); -} - -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ +import { NotificationManager } from "../../src/ts/services/notifications"; 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()); + const id = notifications.add({ title: "test", message: "message" }); expect(notified).toBe(true); expect(id).toBeDefined(); }); test("can close a notification", () => { - const notifications: INotificationManager = new NotificationManager(); + const notifications = new NotificationManager(); let notified = false; notifications.on("notification_removed", {}, () => (notified = true)); - const id = notifications.add(makeNotification()); + const id = notifications.add({ title: "test", message: "message" }); expect(notified).toBe(false); notifications.close(id); @@ -47,11 +24,11 @@ test("can close a notification", () => { test("notifications closes themselves after a while", () => { jest.useFakeTimers(); - const notifications: INotificationManager = new NotificationManager(); + const notifications = new NotificationManager(); let removed = false; notifications.on("notification_removed", {}, () => (removed = true)); - notifications.add(makeNotification()); + notifications.add({ title: "test", message: "message" }); expect(setTimeout).toHaveBeenCalledTimes(1); expect(removed).toBe(false); @@ -61,11 +38,11 @@ test("notifications closes themselves after a while", () => { test("sticky notifications do not close themselves after a while", () => { jest.useFakeTimers(); - const notifications: INotificationManager = new NotificationManager(); + const notifications = new NotificationManager(); let removed = false; notifications.on("notification_removed", {}, () => (removed = true)); - notifications.add(makeNotification({ sticky: true })); + notifications.add({ title: "test", message: "message", sticky: true }); expect(setTimeout).toHaveBeenCalledTimes(0); expect(removed).toBe(false); diff --git a/web/static/tests/widgets/notification.test.ts b/web/static/tests/widgets/notification.test.ts new file mode 100644 index 00000000..bea56515 --- /dev/null +++ b/web/static/tests/widgets/notification.test.ts @@ -0,0 +1,66 @@ +import { Env } from "../../src/ts/env"; +import { makeTestEnv, makeTestFixture, normalize } from "../helpers"; +import { Notification } from "../../src/ts/widgets/notification"; +import { INotification } from "../../src/ts/services/notifications"; + +//------------------------------------------------------------------------------ +// Setup and helpers +//------------------------------------------------------------------------------ + +let fixture: HTMLElement; +let env: Env; + +beforeEach(() => { + fixture = makeTestFixture(); + env = makeTestEnv(); +}); + +afterEach(() => { + fixture.remove(); +}); + +function makeNotification(notif: Partial = {}): INotification { + const defaultNotif = { + id: 1, + title: "title", + message: "message", + type: "notification", + sticky: false + }; + return Object.assign(defaultNotif, notif); +} + +//------------------------------------------------------------------------------ +// Tests +//------------------------------------------------------------------------------ + +test("can be rendered", async () => { + const notif = makeNotification({ title: "title", message: "message" }); + const navbar = new Notification(env, notif); + await navbar.mount(fixture); + expect(normalize(fixture.innerHTML)).toBe( + normalize(` +
+
title
+
message
+
`) + ); +}); + +test("can be closed by clicking on it (if sticky)", async () => { + let notif: INotification; + let removed = false; + env.notifications.on("notification_added", null, _notif => (notif = _notif)); + env.notifications.add({ + title: "title", + message: "message", + sticky: true + }); + env.notifications.on("notification_removed", null, () => (removed = true)); + + const navbar = new Notification(env, notif!); + await navbar.mount(fixture); + expect(removed).toBe(false); + (fixture.getElementsByClassName("o_close")[0]).click(); + expect(removed).toBe(true); +});