pull/2971/merge
Carlos Jimeno Cordero 2025-04-23 10:20:29 +01:00 committed by GitHub
commit 107c453cba
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 62 additions and 2 deletions

View File

@ -143,6 +143,7 @@ Contributors
* Aitor Bouzas <aitor.bouzas@adaptivecity.com>
* Shepilov Vladislav <shepilov.v@protonmail.com>
* Kevin Khao <kevin.khao@akretion.com>
* Carlos Jimeno <carlos.jimeno@braintec.com>
* `Tecnativa <https://www.tecnativa.com>`_:
* David Vidal

View File

@ -1,5 +1,7 @@
# Copyright 2016 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import uuid
from odoo import _, api, exceptions, fields, models
from odoo.addons.bus.models.bus import channel_with_db, json_dump
@ -122,7 +124,11 @@ class ResUsers(models.Model):
target = self.partner_id
if action:
action = clean_action(action, self.env)
unique_id = str(uuid.uuid4())
bus_message = {
"id": unique_id,
"type": type_message,
"message": message,
"title": title,
@ -133,3 +139,18 @@ class ResUsers(models.Model):
notifications = [[partner, "web.notify", [bus_message]] for partner in target]
self.env["bus.bus"]._sendmany(notifications)
@api.model
def notify_dismiss(self, notif_id):
partner_id = self.env.user.partner_id.id
bus_message = {
"id": notif_id,
}
notifications = [
[
(self.env.cr.dbname, "res.partner", partner_id),
"web.notify.dismiss",
[bus_message],
]
]
self.env["bus.bus"]._sendmany(notifications)

View File

@ -3,6 +3,7 @@
* Aitor Bouzas <aitor.bouzas@adaptivecity.com>
* Shepilov Vladislav <shepilov.v@protonmail.com>
* Kevin Khao <kevin.khao@akretion.com>
* Carlos Jimeno <carlos.jimeno@braintec.com>
* `Tecnativa <https://www.tecnativa.com>`_:
* David Vidal

View File

@ -473,6 +473,7 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
<li>Aitor Bouzas &lt;<a class="reference external" href="mailto:aitor.bouzas&#64;adaptivecity.com">aitor.bouzas&#64;adaptivecity.com</a>&gt;</li>
<li>Shepilov Vladislav &lt;<a class="reference external" href="mailto:shepilov.v&#64;protonmail.com">shepilov.v&#64;protonmail.com</a>&gt;</li>
<li>Kevin Khao &lt;<a class="reference external" href="mailto:kevin.khao&#64;akretion.com">kevin.khao&#64;akretion.com</a>&gt;</li>
<li>Carlos Jimeno &lt;<a class="reference external" href="mailto:carlos.jimeno&#64;braintec.com">carlos.jimeno&#64;braintec.com</a>&gt;</li>
<li><a class="reference external" href="https://www.tecnativa.com">Tecnativa</a>:<ul>
<li>David Vidal</li>
</ul>

View File

@ -4,10 +4,11 @@ import {browser} from "@web/core/browser/browser";
import {registry} from "@web/core/registry";
export const webNotificationService = {
dependencies: ["bus_service", "notification", "action"],
dependencies: ["bus_service", "notification", "action", "orm"],
start(env, {bus_service, notification, action}) {
start(env, {bus_service, notification, action, orm}) {
let webNotifTimeouts = {};
const displayedNotifications = {};
/**
* Displays the web notification on user's screen
* @param {*} notifications
@ -44,10 +45,17 @@ export const webNotificationService = {
button.onClick = async () => {
await onClick();
notificationRemove();
await orm.call("res.users", "notify_dismiss", [
notif.id,
]);
};
return button;
}),
onClose: async () => {
await orm.call("res.users", "notify_dismiss", [notif.id]);
},
});
displayedNotifications[notif.id] = notificationRemove;
});
});
}
@ -56,9 +64,16 @@ export const webNotificationService = {
for (const {payload, type} of notifications) {
if (type === "web.notify") {
displaywebNotification(payload);
} else if (type === "web.notify.dismiss") {
const notifId = payload[0].id;
if (displayedNotifications[notifId]) {
displayedNotifications[notifId]();
delete displayedNotifications[notifId];
}
}
}
});
bus_service.start();
},
};

View File

@ -26,6 +26,8 @@ class TestResUsers(common.TransactionCase):
self.assertEqual(1, len(news))
test_msg.update({"type": SUCCESS})
payload = json.loads(news.message)["payload"][0]
self.assertIn("id", payload)
payload.pop("id", None)
self.assertDictEqual(test_msg, payload)
def test_notify_danger(self):
@ -44,6 +46,8 @@ class TestResUsers(common.TransactionCase):
self.assertEqual(1, len(news))
test_msg.update({"type": DANGER})
payload = json.loads(news.message)["payload"][0]
self.assertIn("id", payload)
payload.pop("id", None)
self.assertDictEqual(test_msg, payload)
def test_notify_warning(self):
@ -62,6 +66,8 @@ class TestResUsers(common.TransactionCase):
self.assertEqual(1, len(news))
test_msg.update({"type": WARNING})
payload = json.loads(news.message)["payload"][0]
self.assertIn("id", payload)
payload.pop("id", None)
self.assertDictEqual(test_msg, payload)
def test_notify_info(self):
@ -80,6 +86,8 @@ class TestResUsers(common.TransactionCase):
self.assertEqual(1, len(news))
test_msg.update({"type": INFO})
payload = json.loads(news.message)["payload"][0]
self.assertIn("id", payload)
payload.pop("id", None)
self.assertDictEqual(test_msg, payload)
def test_notify_default(self):
@ -98,6 +106,8 @@ class TestResUsers(common.TransactionCase):
self.assertEqual(1, len(news))
test_msg.update({"type": DEFAULT})
payload = json.loads(news.message)["payload"][0]
self.assertIn("id", payload)
payload.pop("id", None)
self.assertDictEqual(test_msg, payload)
def test_notify_many(self):
@ -117,3 +127,14 @@ class TestResUsers(common.TransactionCase):
def test_notify_admin_allowed_other_user(self):
other_user = self.env.ref("base.user_demo")
other_user.notify_info(message="hello")
def test_notify_dismiss(self):
bus_bus = self.env["bus.bus"]
domain = [("channel", "=", self.env.user.notify_default_channel_name)]
existing = bus_bus.search(domain)
notif_id = "test-notif-id"
self.env.user.notify_dismiss(notif_id)
news = bus_bus.search(domain) - existing
self.assertEqual(1, len(news))
payload = json.loads(news.message)["payload"][0]
self.assertEqual(payload["id"], notif_id)