Skip to content

Commit

Permalink
Add possibility to return an action in a notification
Browse files Browse the repository at this point in the history
  • Loading branch information
guewen authored and rousseldenis committed Aug 29, 2023
1 parent 8b258c8 commit d8d9e0e
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 22 deletions.
22 changes: 19 additions & 3 deletions web_notify/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,28 @@ or

.. code-block:: python
self.env.user.notify_info(message='My information message')
self.env.user.notify_default(message='My default message')
or
The notifications can bring interactivity with some buttons.

* One allowing to refresh the active view
* Another allowing to send a window / client action

The reload button is activated when sending the notification with:


The action can be used using the ``action`` keyword:

.. code-block:: python
self.env.user.notify_default(message='My default message')
action = self.env.ref('sale.action_orders').read()[0]
action.update({
'res_id': self.id,
'views': [(False, 'form')],
})
self.env.user.notify_info('My information message', action=action)
.. figure:: https://raw.githubusercontent.com/OCA/web/16.0/web_notify/static/description/notifications_screenshot.gif
:scale: 80 %
Expand Down Expand Up @@ -118,6 +133,7 @@ Contributors
* Aitor Bouzas <[email protected]>
* Shepilov Vladislav <[email protected]>
* Kevin Khao <[email protected]>
* Guewen Baconnier <[email protected]>
* `Tecnativa <https://www.tecnativa.com>`_:

* David Vidal
Expand Down
50 changes: 40 additions & 10 deletions web_notify/models/res_users.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from odoo import _, api, exceptions, fields, models

from odoo.addons.bus.models.bus import channel_with_db, json_dump
from odoo.addons.web.controllers.main import clean_action

DEFAULT_MESSAGE = "Default message"

Expand Down Expand Up @@ -42,34 +43,59 @@ def _compute_channel_names(self):
notify_default_channel_name = fields.Char(compute="_compute_channel_names")

def notify_success(
self, message="Default message", title=None, sticky=False, target=None
self,
message="Default message",
title=None,
sticky=False,
target=None,
action=None,
):
title = title or _("Success")
self._notify_channel(SUCCESS, message, title, sticky, target)
self._notify_channel(SUCCESS, message, title, sticky, target, action)

def notify_danger(
self, message="Default message", title=None, sticky=False, target=None
self,
message="Default message",
title=None,
sticky=False,
target=None,
action=None,
):
title = title or _("Danger")
self._notify_channel(DANGER, message, title, sticky, target)
self._notify_channel(DANGER, message, title, sticky, target, action)

def notify_warning(
self, message="Default message", title=None, sticky=False, target=None
self,
message="Default message",
title=None,
sticky=False,
target=None,
action=None,
):
title = title or _("Warning")
self._notify_channel(WARNING, message, title, sticky, target)
self._notify_channel(WARNING, message, title, sticky, target, action)

def notify_info(
self, message="Default message", title=None, sticky=False, target=None
self,
message="Default message",
title=None,
sticky=False,
target=None,
action=None,
):
title = title or _("Information")
self._notify_channel(INFO, message, title, sticky, target)
self._notify_channel(INFO, message, title, sticky, target, action)

def notify_default(
self, message="Default message", title=None, sticky=False, target=None
self,
message="Default message",
title=None,
sticky=False,
target=None,
action=None,
):
title = title or _("Default")
self._notify_channel(DEFAULT, message, title, sticky, target)
self._notify_channel(DEFAULT, message, title, sticky, target, action)

def _notify_channel(
self,
Expand All @@ -78,6 +104,7 @@ def _notify_channel(
title=None,
sticky=False,
target=None,
action=None,
):
if not self.env.user._is_admin() and any(
user.id != self.env.uid for user in self
Expand All @@ -87,11 +114,14 @@ def _notify_channel(
)
if not target:
target = self.partner_id
if action:
action = clean_action(action, self.env)

Check warning on line 118 in web_notify/models/res_users.py

View check run for this annotation

Codecov / codecov/patch

web_notify/models/res_users.py#L118

Added line #L118 was not covered by tests
bus_message = {
"type": type_message,
"message": message,
"title": title,
"sticky": sticky,
"action": action,
}

notifications = [[partner, "web.notify", [bus_message]] for partner in target]
Expand Down
21 changes: 21 additions & 0 deletions web_notify/readme/USAGE.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,27 @@ or
self.env.user.notify_default(message='My default message')
The notifications can bring interactivity with some buttons.

* One allowing to refresh the active view
* Another allowing to send a window / client action

The reload button is activated when sending the notification with:


The action can be used using the ``action`` keyword:

.. code-block:: python
action = self.env["ir.actions.act_window"]._for_xml_id('sale.action_orders')
action.update({
'res_id': self.id,
'views': [(False, 'form')],
})
self.env.user.notify_info('My information message', action=action)
.. figure:: static/description/notifications_screenshot.gif
:scale: 80 %
:alt: Sample notifications
Expand Down
20 changes: 16 additions & 4 deletions web_notify/static/src/js/services/notification_services.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,39 @@ import {browser} from "@web/core/browser/browser";
import {registry} from "@web/core/registry";

export const webNotificationService = {
dependencies: ["bus_service", "notification"],
dependencies: ["bus_service", "notification", "action"],

start(env, {bus_service, notification}) {
start(env, {bus_service, notification, action}) {
let webNotifTimeouts = {};
/**
* Displays the web notification on user's screen
*/

function displaywebNotification(notifications) {
Object.values(webNotifTimeouts).forEach((notif) =>
browser.clearTimeout(notif)
);
webNotifTimeouts = {};

notifications.forEach(function (notif) {
browser.setTimeout(function () {
let buttons = [];

if (notif.action) {
buttons = [
{
name: env._t("Open"),
primary: true,
onClick: async () => {
await action.doAction(notif.action);
},
},
];
}
notification.add(Markup(notif.message), {
title: notif.title,
type: notif.type,
sticky: notif.sticky,
className: notif.className,
buttons: buttons,
});
});
});
Expand Down
35 changes: 30 additions & 5 deletions web_notify/tests/test_res_users.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ def test_notify_success(self):
bus_bus = self.env["bus.bus"]
domain = [("channel", "=", self.env.user.notify_success_channel_name)]
existing = bus_bus.search(domain)
test_msg = {"message": "message", "title": "title", "sticky": True}
test_msg = {
"message": "message",
"title": "title",
"sticky": True,
"action": None,
}
self.env.user.notify_success(**test_msg)
news = bus_bus.search(domain) - existing
self.assertEqual(1, len(news))
Expand All @@ -26,7 +31,12 @@ def test_notify_danger(self):
bus_bus = self.env["bus.bus"]
domain = [("channel", "=", self.env.user.notify_danger_channel_name)]
existing = bus_bus.search(domain)
test_msg = {"message": "message", "title": "title", "sticky": True}
test_msg = {
"message": "message",
"title": "title",
"sticky": True,
"action": None,
}
self.env.user.notify_danger(**test_msg)
news = bus_bus.search(domain) - existing
self.assertEqual(1, len(news))
Expand All @@ -38,7 +48,12 @@ def test_notify_warning(self):
bus_bus = self.env["bus.bus"]
domain = [("channel", "=", self.env.user.notify_warning_channel_name)]
existing = bus_bus.search(domain)
test_msg = {"message": "message", "title": "title", "sticky": True}
test_msg = {
"message": "message",
"title": "title",
"sticky": True,
"action": None,
}
self.env.user.notify_warning(**test_msg)
news = bus_bus.search(domain) - existing
self.assertEqual(1, len(news))
Expand All @@ -50,7 +65,12 @@ def test_notify_info(self):
bus_bus = self.env["bus.bus"]
domain = [("channel", "=", self.env.user.notify_info_channel_name)]
existing = bus_bus.search(domain)
test_msg = {"message": "message", "title": "title", "sticky": True}
test_msg = {
"message": "message",
"title": "title",
"sticky": True,
"action": None,
}
self.env.user.notify_info(**test_msg)
news = bus_bus.search(domain) - existing
self.assertEqual(1, len(news))
Expand All @@ -62,7 +82,12 @@ def test_notify_default(self):
bus_bus = self.env["bus.bus"]
domain = [("channel", "=", self.env.user.notify_default_channel_name)]
existing = bus_bus.search(domain)
test_msg = {"message": "message", "title": "title", "sticky": True}
test_msg = {
"message": "message",
"title": "title",
"sticky": True,
"action": None,
}
self.env.user.notify_default(**test_msg)
news = bus_bus.search(domain) - existing
self.assertEqual(1, len(news))
Expand Down

0 comments on commit d8d9e0e

Please sign in to comment.