From d1b260b4242ce168ae539bcdea2ce575570620c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Sat, 12 Jun 2021 09:15:04 +0000 Subject: [PATCH] [REF] web: refactor notification system This commit does some improvements on notification system: - move notification handling logic in service - remove use of __destroy - simplify types closes odoo-dev/odoo#955 Signed-off-by: Aaron Bohy (aab) --- .../notifications/notification_container.js | 53 ++---------- .../notifications/notification_service.js | 85 +++++++++++-------- 2 files changed, 58 insertions(+), 80 deletions(-) diff --git a/addons/web/static/src/core/notifications/notification_container.js b/addons/web/static/src/core/notifications/notification_container.js index 9bc2d2e7a78..5fbccdfa28e 100644 --- a/addons/web/static/src/core/notifications/notification_container.js +++ b/addons/web/static/src/core/notifications/notification_container.js @@ -1,62 +1,25 @@ /** @odoo-module **/ -import { Notification as NotificationComponent } from "./notification"; +import { Notification } from "./notification"; const { Component, tags } = owl; export class NotificationContainer extends Component { setup() { - this.notifications = []; - this.props.bus.on("ADD", this, this.add); - this.props.bus.on("REMOVE", this, this.remove); - } - __destroy() { - this.props.bus.off("ADD", this, this.add); - this.props.bus.off("REMOVE", this, this.remove); - super.__destroy(); - } - - /** - * @param {Object} params - * @param {number} params.id - * @param {{ - * name: string; - * icon?: string; - * primary?: boolean; - * onClick: () => void - * }[]} params.buttons - * @param {string} params.className - * @param {string} params.message - * @param {boolean} params.messageIsHtml - * @param {() => void} params.onClose - * @param {string} params.title - * @param {"warning" | "danger" | "success" | "info"} params.type - */ - add(params) { - const { id, ...props } = params; - this.notifications.push({ id, props }); - this.render(); - } - /** - * @param {number} id - */ - remove(id) { - const index = this.notifications.findIndex((n) => n.id === id); - if (index > -1) { - this.notifications.splice(index, 1); - this.render(); - } + // this works, but then this component cannot be unmounted, then + // remounted. would need a destroyed hook different from willunmount + this.props.bus.on("UPDATE", this, this.render); } } NotificationContainer.template = tags.xml`
- - +
`; -NotificationContainer.components = { NotificationComponent }; +NotificationContainer.components = { Notification }; diff --git a/addons/web/static/src/core/notifications/notification_service.js b/addons/web/static/src/core/notifications/notification_service.js index 7e5a1921fc3..3669eb971f6 100644 --- a/addons/web/static/src/core/notifications/notification_service.js +++ b/addons/web/static/src/core/notifications/notification_service.js @@ -8,50 +8,65 @@ const { EventBus } = owl.core; const AUTOCLOSE_DELAY = 4000; +/** + * @typedef {Object} NotificationButton + * @property {string} name + * @property {string} [icon] + * @property {boolean} [primary] + * @property {() => void} onClick + * + * @typedef {Object} NotificationOptions + * @property {string} [title] + * @property {"warning" | "danger" | "success" | "info"} [type] + * @property {boolean} [sticky] + * @property {string} [className] + * @property {() => void} [onClose] + * @property {NotificationButton} [buttons] + */ + export const notificationService = { start() { let notifId = 0; + let notifications = []; const bus = new EventBus(); registry.category("main_components").add("NotificationContainer", { Component: NotificationContainer, - props: { bus }, + props: { bus, notifications }, }); - return { - bus, - /** - * @param {string} message - * @param {Object} [options] - * @param {{ - * name: string; - * icon?: string; - * primary?: boolean; - * onClick: () => void - * }[]} [options.buttons] - * @param {string} [options.className] - * @param {boolean} [options.messageIsHtml] - * @param {() => void} [options.onClose] - * @param {boolean} [options.sticky] - * @param {string} [options.title] - * @param {"warning" | "danger" | "success" | "info"} [options.type] - */ - add(message, options = {}) { - const notif = Object.assign({}, options, { - id: ++notifId, - message, - }); - const sticky = notif.sticky; - delete notif.sticky; - bus.trigger("ADD", notif); - if (!sticky) { - browser.setTimeout(() => bus.trigger("REMOVE", notif.id), AUTOCLOSE_DELAY); - } - return () => { - bus.trigger("REMOVE", notif.id); - }; - }, - }; + /** + * @param {string} message + * @param {NotificationOptions} [options] + */ + function add(message, options = {}) { + const id = ++notifId; + const props = Object.assign({}, options, { message }); + const sticky = props.sticky; + delete props.sticky; + const closeFn = () => close(id); + const notification = { + id, + props, + close: closeFn, + }; + notifications.push(notification); + bus.trigger("UPDATE"); + if (!sticky) { + browser.setTimeout(closeFn, AUTOCLOSE_DELAY); + } + return closeFn; + } + + function close(id) { + const index = notifications.findIndex((n) => n.id === id); + if (index > -1) { + notifications.splice(index, 1); + bus.trigger("UPDATE"); + } + } + + return { add }; }, };