diff --git a/addons/calendar/static/src/js/base_calendar.js b/addons/calendar/static/src/js/base_calendar.js
index f906958605f..892ab05a064 100644
--- a/addons/calendar/static/src/js/base_calendar.js
+++ b/addons/calendar/static/src/js/base_calendar.js
@@ -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);
diff --git a/addons/web/static/src/js/chrome/abstract_web_client.js b/addons/web/static/src/js/chrome/abstract_web_client.js
index dbf6937937d..45a2b0b1e8c 100644
--- a/addons/web/static/src/js/chrome/abstract_web_client.js
+++ b/addons/web/static/src/js/chrome/abstract_web_client.js
@@ -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');
diff --git a/addons/web/static/src/js/services/notification_manager.js b/addons/web/static/src/js/services/notification_manager.js
new file mode 100644
index 00000000000..b9b128be78d
--- /dev/null
+++ b/addons/web/static/src/js/services/notification_manager.js
@@ -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;
+
+});
diff --git a/addons/web/static/src/js/widgets/notification.js b/addons/web/static/src/js/widgets/notification.js
index 6e11b4c8647..21c24c99e1b 100644
--- a/addons/web/static/src/js/widgets/notification.js
+++ b/addons/web/static/src/js/widgets/notification.js
@@ -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;
});
diff --git a/addons/web/views/webclient_templates.xml b/addons/web/views/webclient_templates.xml
index 4f69ed286b3..cdc29635cd1 100644
--- a/addons/web/views/webclient_templates.xml
+++ b/addons/web/views/webclient_templates.xml
@@ -157,6 +157,7 @@
+