From a3845ae3f058772d4b548c703f5ddf94b571d903 Mon Sep 17 00:00:00 2001 From: Mitali Patel Date: Wed, 10 Jul 2019 13:52:42 +0000 Subject: [PATCH] [FIX] base: ask to discard before leaving settings In a settings form view, do some changes, then click on a button or link in the form (e.g. 'Manage Users' in General Settings). We now ask if the user wants to discard the changes before leaving the page. Task 1921574 closes odoo/odoo#34799 Signed-off-by: Aaron Bohy (aab) Co-authored-by: Mohammed Shekha --- .../base/static/src/js/res_config_settings.js | 25 +++++ .../base/static/tests/base_settings_tests.js | 97 +++++++++++++++++++ 2 files changed, 122 insertions(+) diff --git a/odoo/addons/base/static/src/js/res_config_settings.js b/odoo/addons/base/static/src/js/res_config_settings.js index 9ad0a2c9196..802fdaced6f 100644 --- a/odoo/addons/base/static/src/js/res_config_settings.js +++ b/odoo/addons/base/static/src/js/res_config_settings.js @@ -353,6 +353,9 @@ var BaseSettingRenderer = FormRenderer.extend({ }); var BaseSettingController = FormController.extend({ + custom_events: _.extend({}, FormController.prototype.custom_events, { + button_clicked: '_onButtonClicked', + }), init: function () { this._super.apply(this, arguments); this.disableAutofocus = true; @@ -367,6 +370,28 @@ var BaseSettingController = FormController.extend({ willRestore: function () { this.mode = 'edit'; }, + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * @private + */ + _onButtonClicked: function (ev) { + var self = this; + if (ev.data.attrs.name !== 'execute' && ev.data.attrs.name !== 'cancel') { + var recordID = ev.data.recordID; + var _super = this._super; + var args = arguments; + this._discardChanges(recordID).then(function () { + _super.apply(self, args); + }); + } else { + this._super.apply(this, arguments); + } + }, + }); var BaseSettingsModel = BasicModel.extend({ diff --git a/odoo/addons/base/static/tests/base_settings_tests.js b/odoo/addons/base/static/tests/base_settings_tests.js index 98d68b1281e..fa9b92c49e2 100644 --- a/odoo/addons/base/static/tests/base_settings_tests.js +++ b/odoo/addons/base/static/tests/base_settings_tests.js @@ -143,6 +143,103 @@ QUnit.module('base_settings_tests', { actionManager.destroy(); }); + QUnit.test('clicking on any button in setting should show discard warning if setting form is dirty', async function (assert) { + assert.expect(11); + + var actions = [{ + id: 1, + name: 'Settings view', + res_model: 'project', + type: 'ir.actions.act_window', + views: [[1, 'form']], + }, { + id: 4, + name: 'Other action', + res_model: 'project', + type: 'ir.actions.act_window', + views: [[2, 'list']], + }]; + var archs = { + 'project,1,form': '
' + + '
' + + '
' + + '
' + + '
'+ + '
'+ + '
' + + ''+ + '
'+ + '
'+ + 'Foo'+ + '
'+ + 'this is foo'+ + '
'+ + '
' + + '
'+ + '
'+ + '
' + + '
', + 'project,2,list': '', + 'project,false,search': '', + }; + + var actionManager = await createActionManager({ + actions: actions, + archs: archs, + data: this.data, + mockRPC: function (route, args) { + if (route === '/web/dataset/call_button') { + if (args.method === "execute") { + assert.ok("execute method called"); + return Promise.resolve(true); + } + if (args.method === "cancel") { + assert.ok("cancel method called"); + return Promise.resolve(true); + } + } + return this._super.apply(this, arguments); + }, + }); + + await actionManager.doAction(1); + assert.containsNone(actionManager, '.o_field_boolean input:checked', + "checkbox should not be checked"); + + await testUtils.dom.click(actionManager.$("input[type='checkbox']")); + assert.containsOnce(actionManager, '.o_field_boolean input:checked', + "checkbox should be checked"); + + await testUtils.dom.click(actionManager.$('button[name="4"]')); + assert.containsOnce(document.body, '.modal', "should open a warning dialog"); + + await testUtils.dom.click($('.modal button:contains(Ok)')); + assert.containsOnce(actionManager, '.o_list_view', "should be open list view"); + + await testUtils.dom.click($('.o_control_panel .breadcrumb-item a')); + assert.containsNone(actionManager, '.o_field_boolean input:checked', + "checkbox should not be checked"); + + await testUtils.dom.click(actionManager.$("input[type='checkbox']")); + await testUtils.dom.click(actionManager.$('button[name="4"]')); + assert.containsOnce(document.body, '.modal', "should open a warning dialog"); + + await testUtils.dom.click($('.modal button:contains(Cancel)')); + assert.containsOnce(actionManager, '.o_form_view' ,"should be remain on form view"); + + await testUtils.dom.click(actionManager.$("button[name='execute']")); + assert.containsNone(document.body, '.modal', "should not open a warning dialog"); + + await testUtils.dom.click(actionManager.$("input[type='checkbox']")); + await testUtils.dom.click(actionManager.$("button[name='cancel']")); + assert.containsNone(document.body, '.modal', "should not open a warning dialog"); + + actionManager.destroy(); + }); + QUnit.test('settings view does not display other settings after reload', async function (assert) { assert.expect(2);