Browse Source

Merge branch 'guewen-web-notify-add-actions' into 10.0

pull/1029/head
Yannick Vaucher 6 years ago
parent
commit
b4ba0eeb4a
  1. 29
      web_notify/README.rst
  2. 5
      web_notify/__manifest__.py
  3. 26
      web_notify/models/res_users.py
  4. 5
      web_notify/static/src/css/notification.less
  5. 57
      web_notify/static/src/js/notification.js
  6. 59
      web_notify/static/src/js/web_client.js
  7. 38
      web_notify/static/src/xml/notification.xml
  8. 57
      web_notify/tests/test_res_users.py
  9. 2
      web_notify/views/web_notify.xml

29
web_notify/README.rst

@ -30,6 +30,34 @@ or
:scale: 80 %
:alt: Sample notifications
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:
.. code-block:: python
self.env.user.notify_info('My information message', show_reload=True)
The action can be used using the ``action`` keyword:
.. code-block:: python
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,
# optional
action_link_name=_('Open Sale'),
)
Installation
============
@ -64,6 +92,7 @@ Contributors
* Laurent Mignon <laurent.mignon@acsone.eu>
* Serpent Consulting Services Pvt. Ltd.<jay.vora@serpentcs.com>
* Guewen Baconnier <guewen.baconnier@camptocamp.com>
Maintainer
----------

5
web_notify/__manifest__.py

@ -6,7 +6,7 @@
'name': 'Web Notify',
'summary': """
Send notification messages to user""",
'version': '10.0.1.0.0',
'version': '10.0.1.1.0',
'description': 'Web Notify',
'license': 'AGPL-3',
'author': 'ACSONE SA/NV,Odoo Community Association (OCA)',
@ -18,7 +18,8 @@
'data': [
'views/web_notify.xml'
],
'demo': [
'qweb': [
'static/src/xml/*.xml',
],
'installable': True,
}

26
web_notify/models/res_users.py

@ -1,8 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright 2016 ACSONE SA/NV
# Copyright 2018 Camptocamp
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models, _
from odoo.addons.web.controllers.main import clean_action
class ResUsers(models.Model):
@ -23,24 +25,36 @@ class ResUsers(models.Model):
compute='_compute_channel_names')
@api.multi
def notify_info(self, message, title=None, sticky=False):
def notify_info(self, message, title=None, sticky=False,
show_reload=False, action=None,
action_link_name=None, **options):
title = title or _('Information')
self._notify_channel(
'notify_info_channel_name', message, title, sticky)
'notify_info_channel_name', message, title,
sticky=sticky, show_reload=show_reload, action=action,
action_link_name=action_link_name, **options
)
@api.multi
def notify_warning(self, message, title=None, sticky=False):
def notify_warning(self, message, title=None, sticky=False,
show_reload=False, action=None,
action_link_name=None, **options):
title = title or _('Warning')
self._notify_channel(
'notify_warning_channel_name', message, title, sticky)
'notify_warning_channel_name', message, title,
sticky=sticky, show_reload=show_reload, action=action,
action_link_name=action_link_name, **options
)
@api.multi
def _notify_channel(self, channel_name_field, message, title, sticky):
def _notify_channel(self, channel_name_field, message, title, **options):
if options.get('action'):
options['action'] = clean_action(options['action'])
bus_message = {
'message': message,
'title': title,
'sticky': sticky
}
bus_message.update(options)
notifications = [(getattr(record, channel_name_field), bus_message)
for record in self]
self.env['bus.bus'].sendmany(notifications)

5
web_notify/static/src/css/notification.less

@ -0,0 +1,5 @@
.o_notification {
.o_notification_action {
padding: 10px;
}
}

57
web_notify/static/src/js/notification.js

@ -0,0 +1,57 @@
/* Copyright 2018 Camptocamp
* License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). */
odoo.define('web_notify.notification', function (require) {
"use strict";
var base_notification = require('web.notification'),
WebClient = require('web.WebClient'),
Notification = base_notification.Notification;
var InteractiveNotification = Notification.extend({
template: 'InteractiveNotification',
events: _.extend(
{},
Notification.prototype.events,
{'click .o_notification_reload_view': function(e){
e.preventDefault();
this.reload_active_view();
},
'click .o_notification_do_action': function(e){
e.preventDefault();
this.button_do_action();
}
}
),
init: function(parent, title, text, options) {
this.options = options || {};
var sticky = this.options.sticky;
this._super.apply(this, [parent, title, text, sticky]);
},
reload_active_view: function() {
this.trigger_up('reload_active_view');
},
button_do_action: function() {
this.getParent().do_action(this.options.action);
}
});
var InteractiveWarning = InteractiveNotification.extend({
template: 'InteractiveWarning',
});
base_notification.NotificationManager.include({
interactive_notify(title, text, options) {
return this.display(new InteractiveNotification(this, title, text, options));
},
interactive_warn(title, text, options) {
return this.display(new InteractiveWarning(this, title, text, options));
}
});
return {
InteractiveNotification: InteractiveNotification,
InteractiveWarning: InteractiveWarning
};
});

59
web_notify/static/src/js/web_client.js

@ -1,13 +1,60 @@
odoo.define('web_notify.WebClient', function (require) {
"use strict";
var WebClient = require('web.WebClient');
var base_bus = require('bus.bus');
var core = require('web.core'),
WebClient = require('web.WebClient'),
base_bus = require('bus.bus'),
Widget = require('web.Widget');
Widget.include({
do_interactive_notify: function(title, message, options) {
this.trigger_up(
'interactive_notification',
{title: title, message: message, options: options});
},
do_interactive_warn: function(title, message, options) {
this.trigger_up(
'interactive_warning',
{title: title, message: message, options: options});
},
});
WebClient.include({
custom_events: _.extend(
{},
WebClient.prototype.custom_events,
{reload_active_view: 'reload_active_view',
interactive_notification: function (e) {
if(this.notification_manager) {
this.notification_manager.interactive_notify(
e.data.title, e.data.message, e.data.options
);
}
},
interactive_warning: function (e) {
if(this.notification_manager) {
this.notification_manager.interactive_warn(
e.data.title, e.data.message, e.data.options
);
}
}
}
),
init: function(parent, client_options){
this._super(parent, client_options);
},
reload_active_view: function(){
var action_manager = this.action_manager;
if(!action_manager){
return;
}
var active_view = action_manager.inner_widget.active_view;
if(active_view) {
active_view.controller.reload();
}
},
show_application: function() {
var res = this._super();
this.start_polling();
@ -40,12 +87,16 @@ WebClient.include({
},
on_message_warning: function(message){
if(this.notification_manager) {
this.notification_manager.do_warn(message.title, message.message, message.sticky);
this.notification_manager.do_interactive_warn(
message.title, message.message, message
);
}
},
on_message_info: function(message){
if(this.notification_manager) {
this.notification_manager.do_notify(message.title, message.message, message.sticky);
this.notification_manager.do_interactive_notify(
message.title, message.message, message
);
}
}
});

38
web_notify/static/src/xml/notification.xml

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<t t-name="Notification.reload">
<div class="o_notification_action" t-if="widget.options.show_reload">
<a href="#" class="o_notification_reload_view">
<span class="fa fa-refresh"/> Reload current view
</a>
</div>
</t>
<t t-name="Notification.do_action">
<div class="o_notification_action" t-if="widget.options.action">
<a href="#" class="o_notification_do_action">
<span t-att-class="'fa ' + (widget.options.action_fa_icon ? widget.options.action_fa_icon : 'fa-arrow-circle-left')"/>
<t t-if="widget.options.action_link_name">
<t t-esc="widget.options.action_link_name"/>
</t>
<t t-else="">Open</t>
</a>
</div>
</t>
<t t-name="InteractiveNotification" t-extend="Notification">
<t t-jquery=".o_notification_content" t-operation="after">
<t t-call="Notification.reload"/>
<t t-call="Notification.do_action"/>
</t>
</t>
<t t-name="InteractiveWarning" t-extend="Warning">
<t t-jquery=".o_notification_content" t-operation="after">
<t t-call="Notification.reload"/>
<t t-call="Notification.do_action"/>
</t>
</t>
</templates>

57
web_notify/tests/test_res_users.py

@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
# Copyright 2016 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import json
from odoo.tests import common
from odoo.addons.bus.models.bus import json_dump
@ -17,12 +18,18 @@ class TestResUsers(common.TransactionCase):
]
existing = bus_bus.search(domain)
self.env.user.notify_info(
message='message', title='title', sticky=True)
message='message', title='title', sticky=True,
show_reload=True, foo="bar"
)
news = bus_bus.search(domain) - existing
self.assertEqual(1, len(news))
self.assertEqual(
'{"message":"message","sticky":true,"title":"title"}',
news.message)
expected = ('{"message":"message","sticky":true,"title":"title",'
'"show_reload":true,"action":null,'
'"action_link_name":null,"foo":"bar"}')
self.assertDictEqual(
json.loads(expected),
json.loads(news.message)
)
def test_notify_warning(self):
bus_bus = self.env['bus.bus']
@ -32,12 +39,46 @@ class TestResUsers(common.TransactionCase):
]
existing = bus_bus.search(domain)
self.env.user.notify_warning(
message='message', title='title', sticky=True)
message='message', title='title', sticky=True,
show_reload=True, foo="bar"
)
news = bus_bus.search(domain) - existing
self.assertEqual(1, len(news))
self.assertEqual(
'{"message":"message","sticky":true,"title":"title"}',
news.message)
expected = ('{"message":"message","sticky":true,"title":"title",'
'"show_reload":true,"action":null,'
'"action_link_name":null,"foo":"bar"}')
self.assertDictEqual(
json.loads(expected),
json.loads(news.message)
)
def test_notify_with_action(self):
bus_bus = self.env['bus.bus']
domain = [
('channel', '=',
json_dump(self.env.user.notify_info_channel_name))
]
existing = bus_bus.search(domain)
self.env.user.notify_info(
message='message', title='title', sticky=True,
action={
"type": "ir.actions.act_window",
"view_mode": "form",
},
action_link_name="Open"
)
news = bus_bus.search(domain) - existing
self.assertEqual(1, len(news))
# the action should be transformed by Odoo (clean_action)
expected = ('{"message":"message","sticky":true,"title":"title",'
'"show_reload":false,"action":'
'{"type": "ir.actions.act_window", "view_mode":"form",'
'"flags":{},"views":[[false, "form"]]},'
'"action_link_name":"Open"}')
self.assertDictEqual(
json.loads(expected),
json.loads(news.message)
)
def test_notify_many(self):
# check that the notification of a list of users is done with

2
web_notify/views/web_notify.xml

@ -3,7 +3,9 @@
<data>
<template id="assets_backend" name="web_noify assets" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<link rel="stylesheet" href="/web_notify/static/src/css/notification.less"/>
<script type="text/javascript" src="/web_notify/static/src/js/web_client.js"/>
<script type="text/javascript" src="/web_notify/static/src/js/notification.js"/>
</xpath>
</template>
</data>

Loading…
Cancel
Save