[REF] web: refactor notification system

This commit aims to bring the code closer to an ideal state.  We want
notifications to be a simple service, easy to use, and well documented.
This commit is contained in:
Géry Debongnie
2017-10-18 13:31:17 +02:00
parent 1503ec8883
commit 1dda323359
5 changed files with 169 additions and 58 deletions
+10 -5
View File
@@ -4,7 +4,7 @@ odoo.define('base_calendar.base_calendar', function (require) {
var bus = require('bus.bus').bus;
var BasicModel = require('web.BasicModel');
var field_registry = require('web.field_registry');
var Notification = require('web.notification').Notification;
var Notification = require('web.Notification');
var relational_fields = require('web.relational_fields');
var session = require('web.session');
var WebClient = require('web.WebClient');
@@ -15,9 +15,10 @@ var FieldMany2ManyTags = relational_fields.FieldMany2ManyTags;
var CalendarNotification = Notification.extend({
template: "CalendarNotification",
init: function(parent, title, text, eid) {
this._super(parent, title, text, true);
this.eid = eid;
init: function(parent, params) {
this._super(parent, params);
this.eid = params.eventID;
this.sticky = true;
this.events = _.extend(this.events || {}, {
'click .link2event': function() {
@@ -66,7 +67,11 @@ WebClient.include({
// For each notification, set a timeout to display it
_.each(notifications, function(notif) {
self.calendar_notif_timeouts[notif.event_id] = setTimeout(function() {
var notification = new CalendarNotification(self.notification_manager, notif.title, notif.message, notif.event_id);
var notification = new CalendarNotification(self.notification_manager, {
title: notif.title,
text: notif.message,
eventID: notif.event_id,
});
self.notification_manager.display(notification);
self.calendar_notif[notif.event_id] = notification;
}, notif.timer * 1000);
@@ -20,7 +20,7 @@ var data_manager = require('web.data_manager');
var Dialog = require('web.Dialog');
var Loading = require('web.Loading');
var mixins = require('web.mixins');
var NotificationManager = require('web.notification').NotificationManager;
var NotificationManager = require('web.NotificationManager');
var RainbowMan = require('web.RainbowMan');
var session = require('web.session');
var Widget = require('web.Widget');
@@ -0,0 +1,90 @@
odoo.define('web.NotificationManager', function (require) {
"use strict";
/**
* NotificationManager
*
* The NotificationManager is simply a widget that will be instantiated by the
* web client to display notifications in the top/right part of the screen.
*
* If you want to display such a notification, you probably do not want to do it
* by using this file. The proper way is to use the do_warn or do_notify
* methods on the Widget class.
*
* @todo This class should be converted into a proper service. Need the right
* service API to do it.
*/
var Notification = require('web.Notification');
var Widget = require('web.Widget');
var NotificationManager = Widget.extend({
className: 'o_notification_manager',
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
/**
* Display a notification at the appropriate location, and returns the
* reference to the same widget (useful to get back a reference).
*
* Note that this method does not wait for the appendTo method to complete.
*
* @param {Notification} notification
* @returns {Notification}
*/
display: function (notification) {
notification.appendTo(this.$el);
return notification;
},
/**
* Will display a notification of type 'notification'
*
* @param {string} title
* @param {string} text
* @param {boolean} sticky
* @returns {Notification}
*/
notify: function (title, text, sticky) {
return this._display(title, text, sticky, 'notification');
},
/**
* Will display a notification of type 'warning'
*
* @param {string} title
* @param {string} text
* @param {boolean} sticky
* @returns {Notification}
*/
warn: function (title, text, sticky) {
return this._display(title, text, sticky, 'warning');
},
//--------------------------------------------------------------------------
// Private
//--------------------------------------------------------------------------
/**
* Display a notification
*
* @private
* @param {string} title
* @param {string} text
* @param {boolean} sticky
* @param {string} type either 'notification' or 'warning'
* @returns {Notification}
*/
_display: function (title, text, sticky, type) {
return this.display(new Notification(this, {
title: title,
text: text,
sticky: sticky,
type: type,
}));
}
});
return NotificationManager;
});
@@ -1,73 +1,88 @@
odoo.define('web.notification', function (require) {
odoo.define('web.Notification', function (require) {
"use strict";
var core = require('web.core');
/**
* Notification
*
* This file contains the widget which is used to display a warning/information
* message in the top right of the screen.
*
* If you want to display such a notification, you probably do not want to do it
* by importing this file. The proper way is to use the do_warn or do_notify
* methods on the Widget class.
*/
var Widget = require('web.Widget');
var Notification = Widget.extend({
template: 'Notification',
events: {
'click .o_close': function(e) {
e.preventDefault();
this.destroy(true);
'click .o_close': '_onClose',
},
/**
* @override
* @param {Widget} parent
* @param {Object} params
* @param {string} params.title notification title
* @param {string} params.text notification main text
* @param {string} params.type 'notification' or 'warning'
* @param {boolean} [params.sticky=false] if true, the notification will stay
* visible until the user clicks on it.
*/
init: function (parent, params) {
this._super.apply(this, arguments);
this.title = params.title;
this.text = params.text;
this.sticky = !!params.sticky;
if (params.type === 'warning') {
this.template = 'Warning';
}
},
init: function(parent, title, text, sticky) {
this._super.apply(this, arguments);
this.title = title;
this.text = text;
this.sticky = !!sticky;
},
start: function() {
this._super.apply(this, arguments);
/**
* @override
*/
start: function () {
var self = this;
this.$el.animate({opacity: 1.0}, 400, "swing", function() {
if(!self.sticky) {
setTimeout(function() {
self.destroy(true);
}, 2500);
}
});
},
destroy: function(animate) {
if(!animate) {
return this._super.apply(this, arguments);
}
var self = this,
superDestroy = this._super;
this.$el.animate({opacity: 0.0}, 400, "swing", function() {
self.$el.animate({height: 0}, 400, "swing", function() {
superDestroy.call(self);
return this._super.apply(this, arguments).then(function () {
self.$el.animate({opacity: 1.0}, 400, "swing", function () {
if(!self.sticky) {
setTimeout(self._destroy.bind(self), 2500);
}
});
});
},
});
var Warning = Notification.extend({
template: 'Warning',
});
//--------------------------------------------------------------------------
// Private
//--------------------------------------------------------------------------
var NotificationManager = Widget.extend({
className: 'o_notification_manager',
display: function(notification) {
notification.appendTo(this.$el);
return notification;
/**
* This method is used to destroy the widget with a nice animation. We
* first perform an animation, then call the real destroy method.
*
* @private
*/
_destroy: function () {
var self = this;
this.$el.animate({opacity: 0.0}, 400, "swing", function() {
self.$el.animate({height: 0}, 400, "swing", self.destroy.bind(self));
});
},
notify: function(title, text, sticky) {
return this.display(new Notification(this, title, text, sticky));
},
warn: function(title, text, sticky) {
return this.display(new Warning(this, title, text, sticky));
//--------------------------------------------------------------------------
// Handlers
//--------------------------------------------------------------------------
/**
* @private
* @param {MouseEvent} ev
*/
_onClose: function (ev) {
ev.preventDefault();
this._destroy();
},
});
return {
Notification: Notification,
Warning: Warning,
NotificationManager: NotificationManager,
};
return Notification;
});
+1
View File
@@ -157,6 +157,7 @@
<script type="text/javascript" src="/web/static/src/js/services/crash_manager.js"></script>
<script type="text/javascript" src="/web/static/src/js/services/data_manager.js"></script>
<script type="text/javascript" src="/web/static/src/js/services/session.js"></script>
<script type="text/javascript" src="/web/static/src/js/services/notification_manager.js"></script>
<script type="text/javascript" src="/web/static/src/js/widgets/auto_complete.js"></script>
<script type="text/javascript" src="/web/static/src/js/widgets/change_password.js"></script>
<script type="text/javascript" src="/web/static/src/js/widgets/debug_manager.js"></script>