From afb4959c3ebf6122e2b009b97da0d6ed7c9a7c80 Mon Sep 17 00:00:00 2001 From: Mathieu Duckerts-Antoine Date: Tue, 28 Dec 2021 14:06:16 +0000 Subject: [PATCH] [REF] web: action service: historyBack OWL-2 is in preparation and will be soon merged. One of the changes it will bring is that it will be no longer possible to use the directive t-on on a tag component. Here we refactor the code in order to remove one use of it in the action service. Part-of: odoo/odoo#81984 --- .../web/static/src/legacy/action_adapters.js | 2 + addons/web/static/src/views/view.js | 1 + .../src/webclient/actions/action_service.js | 18 ++--- .../webclient/actions/close_action_tests.js | 79 +++++++++++++++++-- .../tests/webclient/actions/misc_tests.js | 12 ++- 5 files changed, 93 insertions(+), 19 deletions(-) diff --git a/addons/web/static/src/legacy/action_adapters.js b/addons/web/static/src/legacy/action_adapters.js index e210f4abfb4..b8b7ad46a79 100644 --- a/addons/web/static/src/legacy/action_adapters.js +++ b/addons/web/static/src/legacy/action_adapters.js @@ -120,6 +120,8 @@ class ActionAdapter extends ComponentAdapter { type: "warning", }); } + } else if (ev.name === "history_back") { + this.wowlEnv.config.historyBack(); } else { super._trigger_up(ev); } diff --git a/addons/web/static/src/views/view.js b/addons/web/static/src/views/view.js index ee4f4282fb4..5f411d49b45 100644 --- a/addons/web/static/src/views/view.js +++ b/addons/web/static/src/views/view.js @@ -44,6 +44,7 @@ export function getDefaultConfig() { ], getDisplayName: () => displayName, getPagerProps: () => {}, + historyBack: () => {}, setDisplayName: (newDisplayName) => { displayName = newDisplayName; }, diff --git a/addons/web/static/src/webclient/actions/action_service.js b/addons/web/static/src/webclient/actions/action_service.js index 4edb86640b1..ed519c31427 100644 --- a/addons/web/static/src/webclient/actions/action_service.js +++ b/addons/web/static/src/webclient/actions/action_service.js @@ -75,7 +75,7 @@ const CTX_KEY_REGEX = /^(?:(?:default_|search_default_|show_).+|.+_view_ref|grou // only register this template once for all dynamic classes ControllerComponent const ControllerComponentTemplate = xml``; +/>`; function makeActionManager(env) { const keepLast = new KeepLast(); @@ -539,6 +539,14 @@ function makeActionManager(env) { env.services.title.setParts({ action: controller.displayName }); } }; + controller.config.historyBack = () => { + const previousController = controllerStack[controllerStack.length - 2]; + if (previousController && !dialog) { + restore(previousController.jsId); + } else { + _executeCloseAction(); + } + }; class ControllerComponent extends Component { setup() { @@ -652,14 +660,6 @@ function makeActionManager(env) { dialogCloseResolve(); } } - onHistoryBack() { - const previousController = controllerStack[controllerStack.length - 2]; - if (previousController && !dialog) { - restore(previousController.jsId); - } else { - _executeCloseAction(); - } - } } ControllerComponent.template = ControllerComponentTemplate; ControllerComponent.Component = controller.Component; diff --git a/addons/web/static/tests/webclient/actions/close_action_tests.js b/addons/web/static/tests/webclient/actions/close_action_tests.js index 6e4b0540117..0437384464e 100644 --- a/addons/web/static/tests/webclient/actions/close_action_tests.js +++ b/addons/web/static/tests/webclient/actions/close_action_tests.js @@ -1,8 +1,15 @@ /** @odoo-module **/ import testUtils from "web.test_utils"; -import { click, legacyExtraNextTick, nextTick } from "../../helpers/utils"; +import { click, legacyExtraNextTick, nextTick, patchWithCleanup } from "../../helpers/utils"; import { createWebClient, doAction, getActionManagerServerData } from "./../helpers"; +import FormController from "web.FormController"; +import { makeFakeUserService } from "@web/../tests/helpers/mock_services"; +import ListController from "web.ListController"; +import { PivotView } from "@web/views/pivot/pivot_view"; +import { registry } from "@web/core/registry"; + +const serviceRegistry = registry.category("services"); let serverData; @@ -94,6 +101,13 @@ QUnit.module("ActionManager", (hooks) => { QUnit.test("history back calls on_close handler of dialog action", async function (assert) { assert.expect(4); + let controller; + patchWithCleanup(FormController.prototype, { + init() { + this._super(...arguments); + controller = this; + }, + }); const webClient = await createWebClient({ serverData }); function onClose() { assert.step("on_close"); @@ -101,8 +115,7 @@ QUnit.module("ActionManager", (hooks) => { // open a new dialog form await doAction(webClient, 5, { onClose }); assert.containsOnce(webClient.el, ".modal"); - const ev = new Event("history-back", { bubbles: true, cancelable: true }); - webClient.el.querySelector(".o_view_controller").dispatchEvent(ev); + controller.trigger_up("history_back"); assert.verifySteps(["on_close"], "should have called the on_close handler"); await nextTick(); assert.containsNone(webClient.el, ".modal"); @@ -110,6 +123,13 @@ QUnit.module("ActionManager", (hooks) => { QUnit.test("history back called within on_close", async function (assert) { assert.expect(7); + let controller; + patchWithCleanup(ListController.prototype, { + init() { + this._super(...arguments); + controller = this; + }, + }); const webClient = await createWebClient({ serverData }); await doAction(webClient, 1); @@ -118,8 +138,7 @@ QUnit.module("ActionManager", (hooks) => { assert.containsOnce(webClient, ".o_list_view"); function onClose() { - const ev = new Event("history-back", { bubbles: true, cancelable: true }); - webClient.el.querySelector(".o_view_controller").dispatchEvent(ev); + controller.trigger_up("history_back"); assert.step("on_close"); } // open a new dialog form @@ -138,6 +157,13 @@ QUnit.module("ActionManager", (hooks) => { "history back calls on_close handler of dialog action with 2 breadcrumbs", async function (assert) { assert.expect(7); + let controller; + patchWithCleanup(ListController.prototype, { + init() { + this._super(...arguments); + controller = this; + }, + }); const webClient = await createWebClient({ serverData }); await doAction(webClient, 1); // kanban await doAction(webClient, 3); // list @@ -149,8 +175,7 @@ QUnit.module("ActionManager", (hooks) => { await doAction(webClient, 5, { onClose }); assert.containsOnce(webClient.el, ".modal"); assert.containsOnce(webClient.el, ".o_list_view"); - const ev = new Event("history-back", { bubbles: true, cancelable: true }); - webClient.el.querySelector(".o_view_controller").dispatchEvent(ev); + controller.trigger_up("history_back"); assert.verifySteps(["on_close"], "should have called the on_close handler"); await nextTick(); await legacyExtraNextTick(); @@ -159,6 +184,46 @@ QUnit.module("ActionManager", (hooks) => { } ); + QUnit.test( + "history back calls on_close handler of dialog action with 2 breadcrumbs (2)", + async function (assert) { + assert.expect(7); + let pivot; + patchWithCleanup(PivotView.prototype, { + setup() { + this._super(...arguments); + pivot = this; + }, + }); + serverData.views["partner,false,pivot"] = ""; + serviceRegistry.add("user", makeFakeUserService()); + const webClient = await createWebClient({ serverData }); + await doAction(webClient, 1); // kanban + await doAction(webClient, { + id: 3, + xml_id: "action_3", + name: "Partners", + res_model: "partner", + type: "ir.actions.act_window", + views: [[false, "pivot"]], + }); // pivot + assert.containsOnce(webClient.el, ".o_pivot_view"); + function onClose() { + assert.step("on_close"); + } + // open a new dialog form + await doAction(webClient, 5, { onClose }); + assert.containsOnce(webClient.el, ".modal"); + assert.containsOnce(webClient.el, ".o_pivot_view"); + pivot.env.config.historyBack(); + assert.verifySteps(["on_close"], "should have called the on_close handler"); + await nextTick(); + await legacyExtraNextTick(); + assert.containsOnce(webClient.el, ".o_pivot_view"); + assert.containsNone(webClient.el, ".modal"); + } + ); + QUnit.test("web client is not deadlocked when a view crashes", async function (assert) { assert.expect(3); const readOnFirstRecordDef = testUtils.makeTestPromise(); diff --git a/addons/web/static/tests/webclient/actions/misc_tests.js b/addons/web/static/tests/webclient/actions/misc_tests.js index 03b8eb5ea0b..bb74b579762 100644 --- a/addons/web/static/tests/webclient/actions/misc_tests.js +++ b/addons/web/static/tests/webclient/actions/misc_tests.js @@ -21,6 +21,7 @@ import { setupWebClientRegistries, } from "./../helpers"; import * as cpHelpers from "@web/../tests/search/helpers"; +import ListController from "web.ListController"; let serverData; // legacy stuff @@ -456,13 +457,18 @@ QUnit.module("ActionManager", (hooks) => { QUnit.test('handles "history_back" event', async function (assert) { assert.expect(3); + let controller; + patchWithCleanup(ListController.prototype, { + init() { + this._super(...arguments); + controller = this; + }, + }); const webClient = await createWebClient({ serverData }); await doAction(webClient, 4); await doAction(webClient, 3); assert.containsN(webClient, ".o_control_panel .breadcrumb-item", 2); - // simulate an "history-back" event - const ev = new Event("history-back", { bubbles: true, cancelable: true }); - webClient.el.querySelector(".o_view_controller").dispatchEvent(ev); + controller.trigger_up("history_back"); await testUtils.nextTick(); await legacyExtraNextTick(); assert.containsOnce(webClient, ".o_control_panel .breadcrumb-item");