summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js/widgets/notification.js
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/web/static/src/js/widgets/notification.js
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/web/static/src/js/widgets/notification.js')
-rw-r--r--addons/web/static/src/js/widgets/notification.js176
1 files changed, 176 insertions, 0 deletions
diff --git a/addons/web/static/src/js/widgets/notification.js b/addons/web/static/src/js/widgets/notification.js
new file mode 100644
index 00000000..0e9cdabe
--- /dev/null
+++ b/addons/web/static/src/js/widgets/notification.js
@@ -0,0 +1,176 @@
+odoo.define('web.Notification', function (require) {
+'use strict';
+
+var Widget = require('web.Widget');
+
+/**
+ * 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 Notification = Widget.extend({
+ template: 'Notification',
+ events: {
+ 'hidden.bs.toast': '_onClose',
+ 'click .o_notification_buttons button': '_onClickButton',
+ 'mouseenter': '_onMouseEnter',
+ 'mouseleave': '_onMouseLeave',
+ },
+ _autoCloseDelay: 4000,
+ _animation: true,
+
+ /**
+ * @override
+ * @param {Widget} parent
+ * @param {Object} params
+ * @param {string} params.title
+ * @param {string} params.subtitle
+ * @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)
+ * @param {Object[]} params.buttons
+ * @param {function} params.buttons[0].click callback on click
+ * @param {boolean} [params.buttons[0].primary] display the button as primary
+ * @param {string} [params.buttons[0].text] button label
+ * @param {string} [params.buttons[0].icon] font-awsome className or image src
+ */
+ init: function (parent, params) {
+ this._super.apply(this, arguments);
+ this.title = params.title;
+ this.subtitle = params.subtitle;
+ this.message = params.message;
+ this.buttons = params.buttons || [];
+ this.sticky = !!this.buttons.length || !!params.sticky;
+ this.type = params.type === undefined ? 'warning' : params.type;
+ this.className = params.className || '';
+ this._closeCallback = params.onClose;
+
+ 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';
+ }
+ },
+ /**
+ * @override
+ */
+ start: function () {
+ this.$el.toast({
+ animation: this._animation,
+ autohide: false,
+ });
+ void this.$el[0].offsetWidth; // Force a paint refresh before showing the toast
+ if (!this.sticky) {
+ this.autohide = _.cancellableThrottleRemoveMeSoon(this.close, this._autoCloseDelay, {leading: false});
+ this.$el.on('shown.bs.toast', () => {
+ this.autohide();
+ });
+ }
+ this.$el.toast('show');
+ return this._super.apply(this, arguments);
+ },
+ /**
+ * @override
+ */
+ destroy: function () {
+ this.$el.toast('dispose');
+ this._super.apply(this, arguments);
+ },
+
+ //--------------------------------------------------------------------------
+ // Public
+ //--------------------------------------------------------------------------
+
+ /**
+ * 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.$el.one('shown.bs.toast', function () {
+ self.$el.toast('hide');
+ });
+ },
+
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * @param {MouseEvent} ev
+ */
+ _onClickButton: function (ev) {
+ ev.preventDefault();
+ if (this._buttonClicked) {
+ return;
+ }
+ this._buttonClicked = true;
+ var index = $(ev.currentTarget).index();
+ var button = this.buttons[index];
+ if (button.click) {
+ button.click();
+ }
+ this.close(true);
+ },
+ /**
+ * @private
+ * @param {Event} ev
+ */
+ _onClose: function (ev) {
+ this.trigger_up('close');
+ if (!this.silent && !this._buttonClicked) {
+ if (this._closeCallback) {
+ this._closeCallback();
+ }
+ }
+ this.destroy();
+ },
+ /**
+ * @private
+ */
+ _onMouseEnter: function () {
+ if (!this.sticky) {
+ this.autohide.cancel();
+ }
+ },
+ /**
+ * @private
+ */
+ _onMouseLeave: function () {
+ if (!this.sticky) {
+ this.autohide();
+ }
+ },
+});
+
+return Notification;
+});