diff options
| author | David Monjoie <dmo@odoo.com> | 2017-05-16 11:35:23 +0200 |
|---|---|---|
| committer | David Monjoie <dmo@odoo.com> | 2017-05-23 11:41:15 +0200 |
| commit | 3460bda5203ce365bdc56a79ef906217219acb6d (patch) | |
| tree | efa9cc5482db354743c2189ad082fe40d48b6c34 /addons/web/static/src/js | |
| parent | e783844f5b66acfc298a98f331bf432420fdbbf7 (diff) | |
[FIX] web: disable stat buttons until action resolution
Previously, it was possible to click multiple times on stat
buttons while still waiting for the result of a previous button
click. This could end up with the web client in strange states
or, worse, lead to tracebacks. Because of this, we decided to
disable the buttons once one of them is clicked and restore
them afterwards.
By doing this, we encovered a place in the code where a failed
deferred would not be properly forwarded back to the caller,
which meant, in our case, that the buttons would not be
enabled back in case the action failed. This is now fixed.
Initial methods to fix this issue used to break the test below.
Because the label of the assertion this used to break was
contradictory with the value it was actually expecting, we
decided to fix it as well.
Diffstat (limited to 'addons/web/static/src/js')
5 files changed, 49 insertions, 6 deletions
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 5a84f4fe4b3..155690f9663 100644 --- a/addons/web/static/src/js/chrome/abstract_web_client.js +++ b/addons/web/static/src/js/chrome/abstract_web_client.js @@ -75,6 +75,10 @@ var AbstractWebClient = Widget.extend(mixins.ServiceProvider, { if (event.data.on_success) { event.data.on_success(result); } + }).fail(function (result) { + if (event.data.on_fail) { + event.data.on_fail(result); + } }); }, }, diff --git a/addons/web/static/src/js/core/mixins.js b/addons/web/static/src/js/core/mixins.js index 9c643597f04..cc99cc1aaa4 100644 --- a/addons/web/static/src/js/core/mixins.js +++ b/addons/web/static/src/js/core/mixins.js @@ -511,6 +511,7 @@ var ServicesMixin = { action: action, options: options, on_success: function (result) { def.resolve(result); }, + on_fail: function (result) { def.reject(result); }, }); return def; }, diff --git a/addons/web/static/src/js/views/basic/basic_controller.js b/addons/web/static/src/js/views/basic/basic_controller.js index 3b24df19e3e..8d35e7f8fcd 100644 --- a/addons/web/static/src/js/views/basic/basic_controller.js +++ b/addons/web/static/src/js/views/basic/basic_controller.js @@ -248,9 +248,7 @@ var BasicController = AbstractController.extend(FieldManagerMixin, { var self = this; var def = $.Deferred(); var reload = function () { - if (!self.isDestroyed()) { - self.reload(); - } + return self.isDestroyed() ? $.when() : self.reload(); }; record = record || this.model.get(this.handle); var recordID = record.data.id; @@ -262,10 +260,14 @@ var BasicController = AbstractController.extend(FieldManagerMixin, { res_ids: [recordID], on_closed: function (reason) { if (!_.isObject(reason)) { - reload(); + reload(reason); } }, - on_fail: reload, + on_fail: function (reason) { + reload().always(function() { + def.reject(reason); + }) + }, on_success: def.resolve.bind(def), }); return this.alive(def); diff --git a/addons/web/static/src/js/views/form/form_controller.js b/addons/web/static/src/js/views/form/form_controller.js index 0ec959233e6..cc1a99faa61 100644 --- a/addons/web/static/src/js/views/form/form_controller.js +++ b/addons/web/static/src/js/views/form/form_controller.js @@ -70,6 +70,22 @@ var FormController = BasicController.extend({ }); }, /** + * Disable buttons so that they can't be clicked anymore + * + */ + disableButtons: function () { + this.$buttons.find('button').attr('disabled', true); + this.renderer.disableButtons(); + }, + /** + * Enable buttons so they can be clicked again + * + */ + enableButtons: function () { + this.$buttons.find('button').removeAttr('disabled'); + this.renderer.enableButtons(); + }, + /** * Returns the current res_id, wrapped in a list. This is only used by the * sidebar (and the debugmanager) * @@ -324,6 +340,8 @@ var FormController = BasicController.extend({ var self = this; var def; + this.disableButtons(); + var attrs = event.data.attrs; if (attrs.confirm) { var d = $.Deferred(); @@ -348,7 +366,7 @@ var FormController = BasicController.extend({ return self._callButtonAction(attrs, record); }); } - def.then(function () { + def = def.then(function () { self.reload(); }); @@ -357,6 +375,10 @@ var FormController = BasicController.extend({ self.show_wow(); }); } + + def.always(function() { + self.enableButtons(); + }); }, /** * Called when the user wants to create a new record -> @see createRecord diff --git a/addons/web/static/src/js/views/form/form_renderer.js b/addons/web/static/src/js/views/form/form_renderer.js index 3747699f45c..ddd77ee5dc6 100644 --- a/addons/web/static/src/js/views/form/form_renderer.js +++ b/addons/web/static/src/js/views/form/form_renderer.js @@ -91,6 +91,20 @@ var FormRenderer = BasicRenderer.extend({ }); }, /** + * Disable stat buttons so that they can't be clicked anymore + * + */ + disableButtons: function() { + this.$('.oe_button_box button').attr('disabled', true); + }, + /** + * Enable stat buttons so they can be clicked again + * + */ + enableButtons: function() { + this.$('.oe_button_box button').removeAttr('disabled'); + }, + /** * returns the active tab pages for each notebook * * @todo currently, this method is unused... |
