From 3fa70eed13552fb35d3710c375a86f44cc32fa92 Mon Sep 17 00:00:00 2001 From: Aaron Bohy Date: Wed, 8 Dec 2021 14:09:15 +0000 Subject: [PATCH] [FIX] web: correctly set window title in wowl views The name of the action is supposed to be displayed in the second part of the window title (e.g. "Odoo - Partners"). Before this commit, this wasn't the case for views that were converted to wowl (only legacy views correctly updated the window title). Part-of: odoo/odoo#81031 --- .../web/static/src/legacy/action_adapters.js | 8 ++------ .../src/webclient/actions/action_service.js | 13 +++++++++++-- .../webclient/actions/window_action_tests.js | 19 ++++++++++++++++--- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/addons/web/static/src/legacy/action_adapters.js b/addons/web/static/src/legacy/action_adapters.js index b94e00d8df5..b3626805703 100644 --- a/addons/web/static/src/legacy/action_adapters.js +++ b/addons/web/static/src/legacy/action_adapters.js @@ -28,7 +28,6 @@ class ActionAdapter extends ComponentAdapter { // In Wowl, we want to have all states pushed during the same setTimeout. // This is protected in legacy (backward compatibility) but should not e supported in Wowl this.tempQuery = {}; - this.waitTitle = true; let originalUpdateControlPanel; useEffect( () => { @@ -38,8 +37,6 @@ class ActionAdapter extends ComponentAdapter { this.__widget = this.widget; if (!this.wowlEnv.inDialog) { this.pushState(query); - this.title.setParts({ action: this.widget.getTitle() }); - this.waitTitle = false; } this.wowlEnv.bus.on("ACTION_MANAGER:UPDATE", this, () => { this.env.bus.trigger("close_dialogs"); @@ -50,7 +47,6 @@ class ActionAdapter extends ComponentAdapter { this.trigger("controller-title-updated", this.__widget.getTitle()); return originalUpdateControlPanel(newProps); }; - this.trigger("controller-title-updated", this.__widget.getTitle()); core.bus.trigger("DOM_updated"); return () => { @@ -78,10 +74,10 @@ class ActionAdapter extends ComponentAdapter { Object.assign(this.tempQuery, query); return; } - if (!this.waitTitle && this.widget) { + if (this.widget) { const actionTitle = this.widget.getTitle(); if (actionTitle) { - this.title.setParts({ action: actionTitle }); + this.trigger("controller-title-updated", actionTitle); } } this.router.pushState(query); diff --git a/addons/web/static/src/webclient/actions/action_service.js b/addons/web/static/src/webclient/actions/action_service.js index 20662574854..68f48c5430c 100644 --- a/addons/web/static/src/webclient/actions/action_service.js +++ b/addons/web/static/src/webclient/actions/action_service.js @@ -7,7 +7,7 @@ import { download } from "@web/core/network/download"; import { evaluateExpr } from "@web/core/py_js/py"; import { registry } from "@web/core/registry"; import { KeepLast } from "@web/core/utils/concurrency"; -import { useBus } from "@web/core/utils/hooks"; +import { useBus, useService } from "@web/core/utils/hooks"; import { sprintf } from "@web/core/utils/strings"; import { cleanDomFromBootstrap } from "@web/legacy/utils"; import { View } from "@web/views/view"; @@ -536,6 +536,7 @@ function makeActionManager(env) { setup() { this.Component = controller.Component; this.componentRef = useRef("component"); + this.titleService = useService("title"); useDebugCategory("action", { action }); useSubEnv({ config: controller.config }); if (action.target !== "new") { @@ -552,6 +553,7 @@ function makeActionManager(env) { __getLocalState__: this.__getLocalState__, }); } + this.isMounted = false; } catchError(error) { reject(error); @@ -629,12 +631,15 @@ function makeActionManager(env) { } // END LEGACY CODE COMPATIBILITY controllerStack = nextStack; // the controller is mounted, commit the new stack - // wait Promise callbacks to be executed pushState(controller); + this.titleService.setParts({ + action: controller.title || this.env.config.displayName, + }); browser.sessionStorage.setItem("current_action", action._originalAction); } resolve(); env.bus.trigger("ACTION_MANAGER:UI-UPDATED", _getActionMode(action)); + this.isMounted = true; } willUnmount() { if (action.target === "new" && dialogCloseResolve) { @@ -651,6 +656,10 @@ function makeActionManager(env) { } onTitleUpdated(ev) { controller.title = ev.detail; + if (this.isMounted) { + // if not mounted yet, will be done in "mounted" + this.titleService.setParts({ action: controller.title }); + } } } ControllerComponent.template = ControllerComponentTemplate; diff --git a/addons/web/static/tests/webclient/actions/window_action_tests.js b/addons/web/static/tests/webclient/actions/window_action_tests.js index d5beea23f92..e367bcf152c 100644 --- a/addons/web/static/tests/webclient/actions/window_action_tests.js +++ b/addons/web/static/tests/webclient/actions/window_action_tests.js @@ -2410,11 +2410,24 @@ QUnit.module("ActionManager", (hooks) => { const webClient = await createWebClient({ serverData }); await doAction(webClient, 3); // list view const titleService = webClient.env.services.title; - assert.strictEqual(titleService.current, "{\"zopenerp\":\"Odoo\",\"action\":\"Partners\"}"); + assert.strictEqual(titleService.current, '{"zopenerp":"Odoo","action":"Partners"}'); await click(webClient.el.querySelector(".o_data_row")); await legacyExtraNextTick(); - assert.strictEqual(titleService.current, "{\"zopenerp\":\"Odoo\",\"action\":\"First record\"}"); + assert.strictEqual(titleService.current, '{"zopenerp":"Odoo","action":"First record"}'); await click(webClient.el.querySelector(".o_pager_next")); - assert.strictEqual(titleService.current, "{\"zopenerp\":\"Odoo\",\"action\":\"Second record\"}"); + assert.strictEqual(titleService.current, '{"zopenerp":"Odoo","action":"Second record"}'); + }); + + QUnit.test("action part of title is updated when an action is mounted", async (assert) => { + // use a PivotView because we need a view converted to wowl + // those two lines can be removed once the list view is converted to wowl + serverData.actions[3].views.unshift([false, "pivot"]); + serverData.views["partner,false,pivot"] = ""; + serviceRegistry.add("user", makeFakeUserService()); + + const webClient = await createWebClient({ serverData }); + await doAction(webClient, 3); + const titleService = webClient.env.services.title; + assert.strictEqual(titleService.current, '{"zopenerp":"Odoo","action":"Partners"}'); }); });