summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js
diff options
context:
space:
mode:
Diffstat (limited to 'addons/web/static/src/js')
-rw-r--r--addons/web/static/src/js/core/service_mixins.js30
-rw-r--r--addons/web/static/src/js/services/notification_service.js11
-rw-r--r--addons/web/static/src/js/widgets/notification.js111
3 files changed, 97 insertions, 55 deletions
diff --git a/addons/web/static/src/js/core/service_mixins.js b/addons/web/static/src/js/core/service_mixins.js
index 4f296b6bb90..209f6ccabb3 100644
--- a/addons/web/static/src/js/core/service_mixins.js
+++ b/addons/web/static/src/js/core/service_mixins.js
@@ -222,11 +222,37 @@ var ServicesMixin = {
});
});
},
+ /**
+ * Displays a notification.
+ *
+ * @param {string} title
+ * @param {string} [message]
+ * @param {string} [type='warning'] 'info', 'success', 'warning', 'danger' or ''
+ * @param {boolean} [sticky=false]
+ * @param {string} [className]
+ */
+ displayNotification: function (title, message, type, sticky, className) {
+ return this.call('notification', 'notify', {
+ type: type,
+ title: title,
+ message: message,
+ sticky: sticky,
+ className: className,
+ });
+ },
+ /**
+ * @deprecated will be removed as soon as the notification system is reviewed
+ * @see displayNotification
+ */
do_notify: function (title, message, sticky, className) {
- return this.call('notification', 'notify', {title: title, message: message, sticky: sticky, className: className});
+ return this.displayNotification(title, message, 'warning', sticky, className);
},
+ /**
+ * @deprecated will be removed as soon as the notification system is reviewed
+ * @see displayNotification
+ */
do_warn: function (title, message, sticky, className) {
- return this.call('notification', 'notify', {type: 'warning', title: title, message: message, sticky: sticky, className: className});
+ return this.displayNotification(title, message, 'danger', sticky, className);
},
};
diff --git a/addons/web/static/src/js/services/notification_service.js b/addons/web/static/src/js/services/notification_service.js
index a0d2720604b..ea16d9ef66f 100644
--- a/addons/web/static/src/js/services/notification_service.js
+++ b/addons/web/static/src/js/services/notification_service.js
@@ -1,9 +1,10 @@
odoo.define('web.NotificationService', function (require) {
-"use strict";
+'use strict';
var AbstractService = require('web.AbstractService');
var Notification = require('web.Notification');
var core = require('web.core');
+
var id = 0;
/**
@@ -16,9 +17,7 @@ var id = 0;
* by using this file. The proper way is to use the do_warn or do_notify
* methods on the Widget class.
*/
-
var NotificationService = AbstractService.extend({
-
custom_events: {
close: '_onCloseNotification',
},
@@ -37,8 +36,8 @@ var NotificationService = AbstractService.extend({
/**
* It may sometimes be useful to close programmatically a notification. For
- * example, when there is a sticky notification that warns the user about
- * some condition (connection lost), but the condition do not apply anymore.
+ * example, when there is a sticky notification warning the user about some
+ * condition (connection lost), but the condition does not apply anymore.
*
* @param {number} notificationId
* @param {boolean} [silent=false] if true, the notification does not call
@@ -105,9 +104,7 @@ var NotificationService = AbstractService.extend({
},
});
-
core.serviceRegistry.add('notification', NotificationService);
-
return NotificationService;
});
diff --git a/addons/web/static/src/js/widgets/notification.js b/addons/web/static/src/js/widgets/notification.js
index e9425144085..31caf5b3e91 100644
--- a/addons/web/static/src/js/widgets/notification.js
+++ b/addons/web/static/src/js/widgets/notification.js
@@ -1,39 +1,38 @@
odoo.define('web.Notification', function (require) {
-"use strict";
+'use strict';
+
+var Widget = require('web.Widget');
/**
- * Notification
- *
- * This file contains the widget which is used to display a warning/information
- * message in the top right of the screen.
+ * Widget which is used to display a warning/information message on 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',
+ xmlDependencies: ['/web/static/src/xml/notification.xml'],
events: {
- 'click > .o_close': '_onClose',
- 'click .o_buttons button': '_onClickButton'
+ 'hidden.bs.toast': '_onClose',
+ 'click .o_notification_buttons button': '_onClickButton'
},
_autoCloseDelay: 2500,
- _animationDelay: 400,
+ _animation: true,
+
/**
* @override
* @param {Widget} parent
* @param {Object} params
- * @param {string} params.title notification title
- * @param {string} params.message notification main message
- * @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.
- * @param {string} [params.className] className to add on the dom
+ * @param {string} params.title
+ * @param {string} [params.message]
+ * @param {string} [params.type='warning'] 'info', 'success', 'warning', 'danger' or ''
+ * @param {boolean} [params.sticky=false] if true, the notification will
+ * stay visible until the user clicks on it.
+ * @param {string} [params.className]
* @param {function} [params.onClose] callback when the user click on the x
- * or when the notification is auto close (no sticky)
+ * or when the notification is auto close (no sticky)
* @param {Object[]} params.buttons
* @param {function} params.buttons[0].click callback on click
* @param {boolean} [params.buttons[0].primary] display the button as primary
@@ -46,32 +45,47 @@ var Notification = Widget.extend({
this.message = params.message;
this.buttons = params.buttons || [];
this.sticky = !!this.buttons.length || !!params.sticky;
- this.type = params.type || 'notification';
+ this.type = params.type === undefined ? 'warning' : params.type;
this.className = params.className || '';
this._closeCallback = params.onClose;
- this.icon = 'fa-lightbulb-o';
+
+ if (this.type === 'danger') {
+ this.icon = 'fa-exclamation';
+ this.className += ' bg-danger';
+ } else if (this.type === 'warning') {
+ this.icon = 'fa-lightbulb-o';
+ this.className += ' bg-warning';
+ } else if (this.type === 'success') {
+ this.icon = 'fa-check';
+ this.className += ' bg-success';
+ } else if (this.type === 'info') {
+ this.icon = 'fa-info';
+ this.className += ' bg-info';
+ }
+
if (this.buttons && this.buttons.length) {
this.icon = 'fa-question-circle-o';
}
- if (this.type === 'warning') {
- this.icon = 'fa-exclamation';
- this.className += ' o_error';
- }
},
/**
* @override
*/
start: function () {
- var self = this;
- return this._super.apply(this, arguments).then(function () {
- self.$el.animate({opacity: 1.0}, self._animationDelay, "swing", function () {
- if(!self.sticky) {
- setTimeout(function () {
- self.close();
- }, self._autoCloseDelay);
- }
- });
+ this.$el.toast({
+ animation: this._animation,
+ autohide: !this.sticky,
+ delay: this._autoCloseDelay,
});
+ void this.$el[0].offsetWidth; // Force a paint refresh before showing the toast
+ this.$el.toast('show');
+ return this._super.apply(this, arguments);
+ },
+ /**
+ * @override
+ */
+ destroy: function () {
+ this.$el.toast('dispose');
+ this._super.apply(this, arguments);
},
//--------------------------------------------------------------------------
@@ -79,22 +93,23 @@ var Notification = Widget.extend({
//--------------------------------------------------------------------------
/**
- * This method is used to destroy the widget with a nice animation. We
- * first perform an animation, then call the real destroy method.
+ * Destroys the widget with a nice animation.
*
* @private
* @param {boolean} [silent=false] if true, the notification does not call
* _closeCallback method
*/
close: function (silent) {
+ this.silent = silent;
+ this.$el.toast('hide');
+
+ // Make 'close' work if the notification is not shown yet but will be.
+ // Should not be needed but the calendar notification system is an
+ // example of feature that does not work without this yet.
var self = this;
- this.trigger_up('close');
- if (!silent && !this._buttonClicked) {
- if (this._closeCallback) {
- this._closeCallback();
- }
- }
- this.$el.animate({opacity: 0.0, height: 0}, this._animationDelay, "swing", self.destroy.bind(self));
+ this.$el.one('shown.bs.toast', function () {
+ self.$el.toast('hide');
+ });
},
//--------------------------------------------------------------------------
@@ -120,14 +135,18 @@ var Notification = Widget.extend({
},
/**
* @private
- * @param {MouseEvent} ev
+ * @param {Event} ev
*/
_onClose: function (ev) {
- ev.preventDefault();
- this.close();
+ this.trigger_up('close');
+ if (!this.silent && !this._buttonClicked) {
+ if (this._closeCallback) {
+ this._closeCallback();
+ }
+ }
+ this.destroy();
},
});
return Notification;
-
});