From 7d1957da8f563d096514b587ec96aede5b204007 Mon Sep 17 00:00:00 2001 From: Vincent Schippefilt Date: Tue, 5 Feb 2019 12:54:29 +0000 Subject: [PATCH] [FIX] web: hang when saving then discarding When editing a record, if it cannot be saved (b.e. due to required fields) and the user clicks on save, then on discard Before this fix, the window did nothing (seems like it is unresponsive) After this fix, the user is able to discard the form. task-id: 1937142 closes odoo/odoo#30871 --- .../src/js/views/basic/basic_controller.js | 16 +++++--- addons/web/static/tests/views/form_tests.js | 40 ++++++++++++++++++- 2 files changed, 50 insertions(+), 6 deletions(-) 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 01bbd9cd2fe..16204c83163 100644 --- a/addons/web/static/src/js/views/basic/basic_controller.js +++ b/addons/web/static/src/js/views/basic/basic_controller.js @@ -188,12 +188,18 @@ var BasicController = AbstractController.extend(FieldManagerMixin, { // mutex-protected as commitChanges function of x2m has to be aware of // all final changes made to a row. var self = this; - this.savingDef = this.mutex.getUnlockedDef().then(function () { - return self.renderer.commitChanges(recordID || self.handle).then(function () { + var savingDef = $.Deferred(); + this.savingDef = savingDef; + + return this.mutex.getUnlockedDef() + .then(function () { + return self.renderer.commitChanges(recordID || self.handle); + }) + .then(function () { return self.mutex.exec(self._saveRecord.bind(self, recordID, options)); - }); - }); - return this.savingDef; + }) + .then(savingDef.resolve.bind(savingDef)) + .fail(savingDef.resolve.bind(savingDef)); }, /** * @override diff --git a/addons/web/static/tests/views/form_tests.js b/addons/web/static/tests/views/form_tests.js index 01042f9b63c..ebb579edd00 100644 --- a/addons/web/static/tests/views/form_tests.js +++ b/addons/web/static/tests/views/form_tests.js @@ -16,7 +16,6 @@ var Widget = require('web.Widget'); var _t = core._t; var createView = testUtils.createView; -var createActionManager = testUtils.createActionManager; var createAsyncView = testUtils.createAsyncView; var createActionManager = testUtils.createActionManager; @@ -106,6 +105,14 @@ QUnit.module('Views', { ] }, }; + + this.actions = [{ + id: 1, + name: 'Partners Action 1', + res_model: 'partner', + type: 'ir.actions.act_window', + views: [[false, 'kanban'], [false, 'form']], + }]; } }, function () { @@ -7518,6 +7525,37 @@ QUnit.module('Views', { form.destroy(); }); + QUnit.test('discard after a failed save', function (assert) { + assert.expect(2); + + var actionManager = createActionManager({ + data: this.data, + archs: { + 'partner,false,form': '
' + + '' + + '' + + '', + 'partner,false,kanban': '' + + '', + 'partner,false,search': '', + }, + actions: this.actions, + }); + + actionManager.doAction(1); + + testUtils.dom.click('.o_control_panel .o-kanban-button-new'); + + //cannot save because there is a required field + testUtils.dom.click('.o_control_panel .o_form_button_save'); + testUtils.dom.click('.o_control_panel .o_form_button_cancel'); + + assert.containsNone(actionManager, '.o_form_view'); + assert.containsOnce(actionManager, '.o_kanban_view'); + + actionManager.destroy(); + }); + QUnit.module('FormViewTABMainButtons'); QUnit.test('using tab in an empty required string field should not move to the next field',function(assert) {