From b601ec66caa5bebdd97fc196af294c488dd78100 Mon Sep 17 00:00:00 2001 From: Aaron Bohy Date: Tue, 30 Jun 2015 14:37:14 +0200 Subject: [PATCH] [IMP] web,mail: use of Modals to confirm changes discard instead of the browser confirm dialogs, for the sake of uniformity. --- addons/mail/static/src/js/mail.js | 28 +++++-- addons/web/static/src/js/action_manager.js | 41 +++++----- addons/web/static/src/js/views/form_view.js | 74 ++++++++++++------- addons/web/static/src/js/web_client.js | 26 ++++--- addons/web/static/src/js/widgets/user_menu.js | 8 +- 5 files changed, 107 insertions(+), 70 deletions(-) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 1c9549f3b36..fb78f11b7cc 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -4,6 +4,7 @@ odoo.define('mail.mail', function (require) { var mail_utils = require('mail.utils'); var core = require('web.core'); var data = require('web.data'); +var Dialog = require('web.Dialog'); var form_common = require('web.form_common'); var session = require('web.session'); var SystrayMenu = require('web.SystrayMenu'); @@ -1047,14 +1048,25 @@ var ComposeMessage = Attachment.extend ({ this.view = parent.view; this.session = session; - core.bus.on('clear_uncommitted_changes', this, function (e) { - if (this.show_composer && !e.isDefaultPrevented()) { - if (!confirm(_t("You are currently composing a message, your message will be discarded.\n\nAre you sure you want to leave this page ?"))) { - e.preventDefault(); - } - else { - this.on_cancel(); - } + core.bus.on('clear_uncommitted_changes', this, function (chain_callbacks) { + if (this.show_composer) { + chain_callbacks(function() { + var def = $.Deferred(); + var message = _t("You are currently composing a message, your message will be discarded. Are you sure you want to leave this page ?"); + var options = { + title: _t("Warning"), + confirm_callback: function() { + def.resolve(); + }, + cancel_callback: function() { + def.reject(); + }, + }; + Dialog.confirm(this, message, options); + return def; + }); + } else { + this.on_cancel(); } }); }, diff --git a/addons/web/static/src/js/action_manager.js b/addons/web/static/src/js/action_manager.js index b5415bf25c3..9b4fd97753c 100644 --- a/addons/web/static/src/js/action_manager.js +++ b/addons/web/static/src/js/action_manager.js @@ -267,21 +267,22 @@ var ActionManager = Widget.extend({ return $.Deferred().reject(); }, select_action: function(action, index) { - if (this.webclient.has_uncommitted_changes()) { + var self = this; + return this.webclient.clear_uncommitted_changes().then(function() { + // Set the new inner_widget and clear the action_stack + self.inner_widget = action.widget; + var action_index = self.action_stack.indexOf(action); + self.clear_action_stack(self.action_stack.splice(action_index + 1)); + + // Hide the ControlPanel if the widget doesn't use it + if (!self.inner_widget.need_control_panel) { + self.main_control_panel.do_hide(); + } + + return action.restore(index); + }).fail(function() { return $.Deferred().reject(); - } - - // Set the new inner_widget and clear the action_stack - this.inner_widget = action.widget; - var action_index = this.action_stack.indexOf(action); - this.clear_action_stack(this.action_stack.splice(action_index + 1)); - - // Hide the ControlPanel if the widget doesn't use it - if (!this.inner_widget.need_control_panel) { - this.main_control_panel.do_hide(); - } - - return action.restore(index); + }); }, clear_action_stack: function(action_stack) { _.map(action_stack || this.action_stack, function(action) { @@ -580,11 +581,15 @@ var ActionManager = Widget.extend({ return this.dialog_widget.appendTo(this.dialog.$el); } - if (this.inner_widget && this.webclient.has_uncommitted_changes()) { + // Clear uncommitted changes on the current inner widget if there is one + var self = this; + var def = (this.inner_widget && this.webclient.clear_uncommitted_changes()) || $.when(); + return def.then(function() { + self.dialog_stop(executor.action); + return self.push_action(executor.widget(), executor.action, options); + }).fail(function() { return $.Deferred().reject(); - } - this.dialog_stop(executor.action); - return this.push_action(executor.widget(), executor.action, options); + }); }, ir_actions_act_window: function (action, options) { var self = this; diff --git a/addons/web/static/src/js/views/form_view.js b/addons/web/static/src/js/views/form_view.js index 35aa0223a13..488ddae9e61 100644 --- a/addons/web/static/src/js/views/form_view.js +++ b/addons/web/static/src/js/views/form_view.js @@ -89,10 +89,17 @@ var FormView = View.extend(common.FieldManagerMixin, { self.on("change:actual_mode", self, self.do_update_pager); }); self.on("load_record", self, self.load_record); - core.bus.on('clear_uncommitted_changes', this, function(e) { - if (!this.can_be_discarded()) { - e.preventDefault(); - } + core.bus.on('clear_uncommitted_changes', this, function(chain_callbacks) { + var self = this; + chain_callbacks(function() { + var def = $.Deferred(); + self.can_be_discarded().then(function() { + def.resolve(); + }).fail(function() { + def.reject(); + }); + return def; + }); }); }, view_loading: function(r) { @@ -402,26 +409,25 @@ var FormView = View.extend(common.FieldManagerMixin, { this.$el.addClass('oe_form_dirty'); }, execute_pager_action: function(action) { - if (this.can_be_discarded()) { + var self = this; + return this.can_be_discarded().then(function() { switch (action) { case 'first': - this.dataset.index = 0; + self.dataset.index = 0; break; case 'previous': - this.dataset.previous(); + self.dataset.previous(); break; case 'next': - this.dataset.next(); + self.dataset.next(); break; case 'last': - this.dataset.index = this.dataset.ids.length - 1; + self.dataset.index = self.dataset.ids.length - 1; break; } - var def = this.reload(); - this.trigger('pager_action_executed'); - return def; - } - return $.when(); + self.trigger('pager_action_executed'); + return self.reload(); + }); }, do_update_pager: function(hide_index) { if (this.$pager) { @@ -727,16 +733,16 @@ var FormView = View.extend(common.FieldManagerMixin, { }, on_button_cancel: function(event) { var self = this; - if (this.can_be_discarded()) { - if (this.get('actual_mode') === 'create') { - this.trigger('history_back'); + this.can_be_discarded().then(function() { + if (self.get('actual_mode') === 'create') { + self.trigger('history_back'); } else { - this.to_view_mode(); - $.when.apply(null, this.render_value_defs).then(function(){ + self.to_view_mode(); + $.when.apply(null, self.render_value_defs).then(function(){ self.trigger('load_record', self.datarecord); }); } - } + }); this.trigger('on_button_cancel'); return false; }, @@ -744,9 +750,9 @@ var FormView = View.extend(common.FieldManagerMixin, { var self = this; this.to_edit_mode(); return $.when(this.has_been_loaded).then(function() { - if (self.can_be_discarded()) { + return self.can_be_discarded().then(function() { return self.load_defaults(); - } + }); }); }, on_button_edit: function() { @@ -787,13 +793,25 @@ var FormView = View.extend(common.FieldManagerMixin, { return def.promise(); }, can_be_discarded: function() { - if (this.$el.is('.oe_form_dirty')) { - if (!confirm(_t("Warning, the record has been modified, your changes will be discarded.\n\nAre you sure you want to leave this page ?"))) { - return false; - } - this.$el.removeClass('oe_form_dirty'); + if (!this.$el.is('.oe_form_dirty')) { + return $.Deferred().resolve(); } - return true; + + var self = this; + var def = $.Deferred(); + var message = _t("The record has been modified, your changes will be discarded. Are you sure you want to leave this page ?"); + var options = { + title: _t("Warning"), + confirm_callback: function() { + self.$el.removeClass('oe_form_dirty'); + def.resolve(); + }, + cancel_callback: function() { + def.reject(); + }, + }; + Dialog.confirm(this, message, options); + return def; }, /** * Triggers saving the form's record. Chooses between creating a new diff --git a/addons/web/static/src/js/web_client.js b/addons/web/static/src/js/web_client.js index c6fd30d6c13..496f83c7d3a 100644 --- a/addons/web/static/src/js/web_client.js +++ b/addons/web/static/src/js/web_client.js @@ -5,6 +5,7 @@ var ActionManager = require('web.ActionManager'); var core = require('web.core'); var crash_manager = require('web.crash_manager'); var data = require('web.data'); +var framework = require('web.framework'); var Loading = require('web.Loading'); var Menu = require('web.Menu'); var Model = require('web.Model'); @@ -100,12 +101,11 @@ var WebClient = Widget.extend({ this.set_content_full_screen(full_screen); }); }, - on_logo_click: function(ev){ - if (!this.has_uncommitted_changes()) { - return; - } else { - ev.preventDefault(); - } + on_logo_click: function(ev) { + ev.preventDefault(); + return this.clear_uncommitted_changes().then(function() { + framework.redirect("/web" + (core.debug ? "?debug" : "")); + }); }, show_common: function() { var self = this; @@ -133,10 +133,12 @@ var WebClient = Widget.extend({ toggle_bars: function(value) { this.$('tr:has(td.navbar),.oe_leftbar').toggle(value); }, - has_uncommitted_changes: function() { - var $e = $.Event('clear_uncommitted_changes'); - core.bus.trigger('clear_uncommitted_changes', $e); - return $e.isDefaultPrevented(); + clear_uncommitted_changes: function() { + var def = $.Deferred().resolve(); + core.bus.trigger('clear_uncommitted_changes', function chain_callbacks(callback) { + def = def.then(callback); + }); + return def; }, /** Sets the first part of the title of the window, dedicated to the current action. @@ -258,9 +260,9 @@ var WebClient = Widget.extend({ }, on_logout: function() { var self = this; - if (!this.has_uncommitted_changes()) { + this.clear_uncommitted_changes().then(function() { self.action_manager.do_action('logout'); - } + }); }, bind_hashchange: function() { var self = this; diff --git a/addons/web/static/src/js/widgets/user_menu.js b/addons/web/static/src/js/widgets/user_menu.js index 3d360c1eae6..ef2927d668f 100644 --- a/addons/web/static/src/js/widgets/user_menu.js +++ b/addons/web/static/src/js/widgets/user_menu.js @@ -63,15 +63,15 @@ var SystrayMenu = Widget.extend({ }, on_menu_settings: function() { var self = this; - if (!this.getParent().has_uncommitted_changes()) { + this.getParent().clear_uncommitted_changes().then(function() { self.rpc("/web/action/load", { action_id: "base.action_res_users_my" }).done(function(result) { result.res_id = session.uid; self.getParent().action_manager.do_action(result); }); - } + }); }, on_menu_account: function() { - if (!this.getParent().has_uncommitted_changes()) { + this.getParent().clear_uncommitted_changes().then(function() { var P = new Model('ir.config_parameter'); P.call('get_param', ['database.uuid']).then(function(dbuuid) { var state = { @@ -89,7 +89,7 @@ var SystrayMenu = Widget.extend({ ev.preventDefault(); framework.redirect('https://accounts.odoo.com/account'); }); - } + }); }, on_menu_about: function() { var self = this;