From afa4ac684d3da90ff80cc59847cdb67ff8fb2997 Mon Sep 17 00:00:00 2001 From: Mohammed Shekha Date: Thu, 4 Mar 2021 13:44:54 +0000 Subject: [PATCH] [FIX] web: reset renderer local state when switching view before this commit: when switching to form view from listview using Create button and then activate some other tab and Discard that record which will move back user to list view now again clicking Create button opens form view but active tab is last activated form tab instead of first one, this is because of local state is not cleared. after this commit: when form view is switched back to list view using Discard button, local state will be cleared, here we are explicitly removing 'active' class from all tab and pages of all notebooks. task-2466057 X-original-commit: ff0e5694e28a46287dc54ab440364e11e8e9c832 --- .../src/legacy/js/views/abstract_renderer.js | 9 ++++ .../legacy/js/views/basic/basic_controller.js | 1 + .../src/legacy/js/views/form/form_renderer.js | 15 ++++++ .../static/tests/legacy/views/form_tests.js | 51 +++++++++++++++++++ 4 files changed, 76 insertions(+) diff --git a/addons/web/static/src/legacy/js/views/abstract_renderer.js b/addons/web/static/src/legacy/js/views/abstract_renderer.js index 27dd35aa7a7..f30541c2010 100644 --- a/addons/web/static/src/legacy/js/views/abstract_renderer.js +++ b/addons/web/static/src/legacy/js/views/abstract_renderer.js @@ -88,6 +88,15 @@ export default mvc.Renderer.extend({ */ giveFocus: function () { }, + /** + * Resets state that renderer keeps, state may contains scroll position, + * the currently active tab page, ... + * + * @see getLocalState + * @see setLocalState + */ + resetLocalState() { + }, /** * This is the reverse operation from getLocalState. With this method, we * expect the renderer to restore all DOM state, if it is relevant. diff --git a/addons/web/static/src/legacy/js/views/basic/basic_controller.js b/addons/web/static/src/legacy/js/views/basic/basic_controller.js index 22ca19992ac..24daed9bcf7 100644 --- a/addons/web/static/src/legacy/js/views/basic/basic_controller.js +++ b/addons/web/static/src/legacy/js/views/basic/basic_controller.js @@ -91,6 +91,7 @@ var BasicController = AbstractController.extend(FieldManagerMixin, { if (this._boundOnBeforeUnload) { window.removeEventListener("beforeunload", this._boundOnBeforeUnload); } + this.renderer.resetLocalState(); }, //-------------------------------------------------------------------------- diff --git a/addons/web/static/src/legacy/js/views/form/form_renderer.js b/addons/web/static/src/legacy/js/views/form/form_renderer.js index db6adb77d38..512b39dfe07 100644 --- a/addons/web/static/src/legacy/js/views/form/form_renderer.js +++ b/addons/web/static/src/legacy/js/views/form/form_renderer.js @@ -256,6 +256,21 @@ var FormRenderer = BasicRenderer.extend({ resetLastActivatedField: function () { this.lastActivatedFieldIndex = -1; }, + /** + * Resets state which stores information like scroll position, curently + * active page, ... + * + * @override + */ + resetLocalState() { + for (const notebook of this.el.querySelectorAll(':scope div.o_notebook')) { + [...notebook.querySelectorAll(':scope .o_notebook_headers .nav-item .nav-link')] + .map(nav => nav.classList.remove('active')); + [...notebook.querySelectorAll(':scope .tab-content > .tab-pane')] + .map(tab => tab.classList.remove('active')); + } + + }, /** * Restore active tab pages for each notebook. It relies on the implicit fact * that each nav header corresponds to a tab page. diff --git a/addons/web/static/tests/legacy/views/form_tests.js b/addons/web/static/tests/legacy/views/form_tests.js index e2ee4864c79..442065b76ce 100644 --- a/addons/web/static/tests/legacy/views/form_tests.js +++ b/addons/web/static/tests/legacy/views/form_tests.js @@ -1062,6 +1062,57 @@ QUnit.module('Views', { form.destroy(); }); + QUnit.test('reset local state when switching to another view', async function (assert) { + assert.expect(3); + + serverData.views = { + 'partner,false,form': `
+ + + + + + + + + + + +
`, + 'partner,false,list': '', + 'partner,false,search': '', + }; + + serverData.actions = { + 1: { + id: 1, + name: 'Partner', + res_model: 'partner', + type: 'ir.actions.act_window', + views: [[false, 'list'], [false, 'form']], + } + }; + + const webClient = await createWebClient({ serverData }); + await doAction(webClient, 1); + + await testUtils.dom.click(webClient.el.querySelector('.o_list_button_add')); + assert.containsOnce(webClient, '.o_form_view'); + + // click on second page tab + await testUtils.dom.click($(webClient.el).find('.o_notebook .nav-link:eq(1)')); + + await testUtils.dom.click('.o_control_panel .o_form_button_cancel'); + await legacyExtraNextTick(); + assert.containsNone(webClient, '.o_form_view'); + + await testUtils.dom.click(webClient.el.querySelector('.o_list_button_add')); + await legacyExtraNextTick(); + // check notebook active page is 0th page + assert.hasClass($(webClient.el).find('.o_notebook .nav-link:eq(0)'), 'active'); + + }); + QUnit.test('rendering stat buttons', async function (assert) { assert.expect(3);