Skip to content

Commit

Permalink
[12.0] web_notify: improve popup UI (OCA#1231)
Browse files Browse the repository at this point in the history
* [ADD]: all available bootstrap notifications (success/danger/warning/info/default)
* [IMP] use black color for text for default notification.
* [FIX] reverted require string for `bus.Longpolling` and rename `on_message_received` to `on_message` to prevent collisions.
  • Loading branch information
shepilov-vladislav authored and aswanth-pits committed Oct 15, 2022
1 parent ec3d46b commit d599b95
Show file tree
Hide file tree
Showing 15 changed files with 310 additions and 107 deletions.
10 changes: 5 additions & 5 deletions web_notify/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ Web Notify
:target: https://runbot.odoo-community.org/runbot/162/12.0
:alt: Try me on Runbot

|badge1| |badge2| |badge3| |badge4| |badge5|
|badge1| |badge2| |badge3| |badge4| |badge5|

Send instant notification messages to the user in live.

This technical module allows you to send instant notification messages from the server to the user in live.
This technical module allows you to send instant notification messages from the server to the user in live.
Two kinds of notification are supported.

* Warning: Displayed in a red flying popup div
Expand All @@ -50,13 +50,13 @@ Usage
To send a notification to the user you just need to call one of the new methods defined on res.users:

.. code-block:: python
self.env.user.notify_info(message='My information message')
or
or

.. code-block:: python
self.env.user.notify_warning(message='My marning message')
.. figure:: https://raw.githubusercontent.com/OCA/web/12.0/web_notify/static/description/notifications_screenshot.png
Expand Down
1 change: 1 addition & 0 deletions web_notify/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# pylint: disable=missing-docstring
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from . import models
2 changes: 1 addition & 1 deletion web_notify/__manifest__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# pylint: disable=missing-docstring
# Copyright 2016 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

Expand All @@ -6,7 +7,6 @@
'summary': """
Send notification messages to user""",
'version': '12.0.1.0.0',
'description': 'Web Notify',
'license': 'AGPL-3',
'author': 'ACSONE SA/NV,'
'AdaptiveCity,'
Expand Down
1 change: 1 addition & 0 deletions web_notify/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# pylint: disable=missing-docstring
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from . import res_users
99 changes: 70 additions & 29 deletions web_notify/models/res_users.py
Original file line number Diff line number Diff line change
@@ -1,46 +1,87 @@
# pylint: disable=missing-docstring
# Copyright 2016 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import api, exceptions, fields, models, _
from odoo import _, api, exceptions, fields, models

DEFAULT_MESSAGE = "Default message"

SUCCESS = "success"
DANGER = "danger"
WARNING = "warning"
INFO = "info"
DEFAULT = "default"


class ResUsers(models.Model):
_inherit = 'res.users'
_inherit = "res.users"

@api.depends('create_date')
@api.depends("create_date")
def _compute_channel_names(self):
for record in self:
res_id = record.id
record.notify_info_channel_name = 'notify_info_%s' % res_id
record.notify_warning_channel_name = 'notify_warning_%s' % res_id
record.notify_success_channel_name = "notify_success_%s" % res_id
record.notify_danger_channel_name = "notify_danger_%s" % res_id
record.notify_warning_channel_name = "notify_warning_%s" % res_id
record.notify_info_channel_name = "notify_info_%s" % res_id
record.notify_default_channel_name = "notify_default_%s" % res_id

notify_success_channel_name = fields.Char(compute="_compute_channel_names")
notify_danger_channel_name = fields.Char(compute="_compute_channel_names")
notify_warning_channel_name = fields.Char(compute="_compute_channel_names")
notify_info_channel_name = fields.Char(compute="_compute_channel_names")
notify_default_channel_name = fields.Char(compute="_compute_channel_names")

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

notify_info_channel_name = fields.Char(
compute='_compute_channel_names')
notify_warning_channel_name = fields.Char(
compute='_compute_channel_names')
def notify_danger(
self, message="Default message", title=None, sticky=False
):
title = title or _("Danger")
self._notify_channel(DANGER, message, title, sticky)

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

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

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

def _notify_channel(self, channel_name_field, message, title, sticky):
if (not self.env.user._is_admin()
and any(user.id != self.env.uid for user in self)):
title = title or _("Information")
self._notify_channel(INFO, message, title, sticky)

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

def _notify_channel(
self,
type_message=DEFAULT,
message=DEFAULT_MESSAGE,
title=None,
sticky=False,
):
# pylint: disable=protected-access
if not self.env.user._is_admin() and any(
user.id != self.env.uid for user in self
):
raise exceptions.UserError(
_('Sending a notification to another user is forbidden.')
_("Sending a notification to another user is forbidden.")
)
channel_name_field = "notify_{}_channel_name".format(type_message)
bus_message = {
'message': message,
'title': title,
'sticky': sticky
"type": type_message,
"message": message,
"title": title,
"sticky": sticky,
}
notifications = [(record[channel_name_field], bus_message)
for record in self]
self.env['bus.bus'].sendmany(notifications)
notifications = [
(record[channel_name_field], bus_message) for record in self
]
self.env["bus.bus"].sendmany(notifications)
3 changes: 2 additions & 1 deletion web_notify/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
* Laurent Mignon <[email protected]>
* Serpent Consulting Services Pvt. Ltd.<[email protected]>
* Aitor Bouzas <[email protected]>
* Aitor Bouzas <[email protected]>
* Shepilov Vladislav <[email protected]>
9 changes: 6 additions & 3 deletions web_notify/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
Send instant notification messages to the user in live.

This technical module allows you to send instant notification messages from the server to the user in live.
This technical module allows you to send instant notification messages from the server to the user in live.
Two kinds of notification are supported.

* Warning: Displayed in a red flying popup div
* Information: Displayed in a light yellow flying popup div
* Success: Displayed in a `success` theme color flying popup div
* Danger: Displayed in a `danger` theme color flying popup div
* Warning: Displayed in a `warning` theme color flying popup div
* Information: Displayed in a `info` theme color flying popup div
* Default: Displayed in a `default` theme color flying popup div
2 changes: 1 addition & 1 deletion web_notify/readme/INSTALL.rst
Original file line number Diff line number Diff line change
@@ -1 +1 @@
This module is based on the Instant Messaging Bus. To work properly, the server must be launched in gevent mode.
This module is based on the Instant Messaging Bus. To work properly, the server must be launched in gevent mode.
26 changes: 22 additions & 4 deletions web_notify/readme/USAGE.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,32 @@
To send a notification to the user you just need to call one of the new methods defined on res.users:

.. code-block:: python
self.env.user.notify_success(message='My success message')
or

.. code-block:: python
self.env.user.notify_danger(message='My danger message')
or

.. code-block:: python
self.env.user.notify_warning(message='My warning message')
or

.. code-block:: python
self.env.user.notify_info(message='My information message')
or
or

.. code-block:: python
self.env.user.notify_warning(message='My marning message')
self.env.user.notify_default(message='My default message')
.. figure:: static/description/notifications_screenshot.png
:scale: 80 %
Expand Down
85 changes: 47 additions & 38 deletions web_notify/static/src/js/web_client.js
Original file line number Diff line number Diff line change
@@ -1,44 +1,53 @@
odoo.define('web_notify.WebClient', function (require) {
"use strict";
"use strict";

var WebClient = require('web.WebClient');
var base_bus = require('bus.Longpolling');
var session = require('web.session');
require('bus.BusService');
var WebClient = require('web.WebClient');
var base_bus = require('bus.Longpolling');
var session = require('web.session');
require('bus.BusService');


WebClient.include({
show_application: function() {
var res = this._super();
this.start_polling();
return res
},
start_polling: function() {
this.channel_warning = 'notify_warning_' + session.uid;
this.channel_info = 'notify_info_' + session.uid;
this.call('bus_service', 'addChannel', this.channel_warning);
this.call('bus_service', 'addChannel', this.channel_info);
this.call('bus_service', 'on', 'notification', this, this.bus_notification);
this.call('bus_service', 'startPolling');
},
bus_notification: function(notifications) {
var self = this;
_.each(notifications, function (notification) {
var channel = notification[0];
var message = notification[1];
if (channel === self.channel_warning) {
self.on_message_warning(message);
} else if (channel === self.channel_info) {
self.on_message_info(message);
}
});
},
on_message_warning: function(message){
this.do_warn(message.title, message.message, message.sticky);
},
on_message_info: function(message){
this.do_notify(message.title, message.message, message.sticky);
}
});
WebClient.include({
show_application: function () {
var res = this._super();
this.start_polling();
return res;
},
start_polling: function () {
this.channel_success = 'notify_success_' + session.uid;
this.channel_danger = 'notify_danger_' + session.uid;
this.channel_warning = 'notify_warning_' + session.uid;
this.channel_info = 'notify_info_' + session.uid;
this.channel_default = 'notify_default_' + session.uid;
this.call('bus_service', 'addChannel', this.channel_success);
this.call('bus_service', 'addChannel', this.channel_danger);
this.call('bus_service', 'addChannel', this.channel_warning);
this.call('bus_service', 'addChannel', this.channel_info);
this.call('bus_service', 'addChannel', this.channel_default);
this.call(
'bus_service', 'on', 'notification',
this, this.bus_notification);
this.call('bus_service', 'startPolling');
},
bus_notification: function (notifications) {
var self = this;
_.each(notifications, function (notification) {
// Not used: var channel = notification[0];
var message = notification[1];
self.on_message(message);
});
},
on_message: function (message) {
return this.call(
'notification', 'notify', {
type: message.type,
title: message.title,
message: message.message,
sticky: message.sticky,
className: message.className,
}
);
},
});

});
26 changes: 26 additions & 0 deletions web_notify/static/src/js/widgets/notification.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
odoo.define('web_notify.Notification', function (require) {
"use strict";

var Notification = require('web.Notification');

Notification.include({
icon_mapping: {
'success': 'fa-thumbs-up',
'danger': 'fa-exclamation-triangle',
'warning': 'fa-exclamation',
'info': 'fa-info',
'default': 'fa-lightbulb-o',
},
init: function () {
this._super.apply(this, arguments);
// Delete default classes
this.className = this.className.replace(' o_error', '');
// Add custom icon and custom class
this.icon = (this.type in this.icon_mapping) ?
this.icon_mapping[this.type] :
this.icon_mapping['default'];
this.className += ' o_' + this.type;
},
});

});
24 changes: 24 additions & 0 deletions web_notify/static/src/scss/webclient.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
.o_notification_manager {
.o_notification {
&.o_success {
color: white;
background-color: theme-color('success');
}
&.o_danger {
color: white;
background-color: theme-color('danger');
}
&.o_warning {
color: white;
background-color: theme-color('warning');
}
&.o_info {
color: white;
background-color: theme-color('info');
}
&.o_default {
color: black;
background-color: theme-color('default');
}
}
}
Loading

0 comments on commit d599b95

Please sign in to comment.