diff --git a/addons/web/static/src/core/dialog/dialog_service.js b/addons/web/static/src/core/dialog/dialog_service.js index 2f841bd4f14..f984c615757 100644 --- a/addons/web/static/src/core/dialog/dialog_service.js +++ b/addons/web/static/src/core/dialog/dialog_service.js @@ -88,7 +88,13 @@ export const dialogService = { return remove; }; - return { add }; + function closeAll() { + for (const dialog of [...stack].reverse()) { + dialog.close(); + } + } + + return { add, closeAll }; }, }; diff --git a/addons/web/static/src/webclient/menus/menu_providers.js b/addons/web/static/src/webclient/menus/menu_providers.js index e7bfc3bbffa..60c5bcb78c3 100644 --- a/addons/web/static/src/webclient/menus/menu_providers.js +++ b/addons/web/static/src/webclient/menus/menu_providers.js @@ -33,6 +33,7 @@ commandProviderRegistry.add("menu", { async provide(env, options) { const result = []; const menuService = env.services.menu; + const dialogService = env.services.dialog; let { apps, menuItems } = computeAppsAndMenuItems(menuService.getMenuAsTree("root")); if (options.searchValue !== "") { apps = fuzzyLookup(options.searchValue, apps, (menu) => menu.label); @@ -42,6 +43,7 @@ commandProviderRegistry.add("menu", { ).forEach((menu) => { result.push({ action() { + dialogService.closeAll(); menuService.selectMenu(menu); }, category: "menu_items", @@ -66,6 +68,7 @@ commandProviderRegistry.add("menu", { result.push({ Component: AppIconCommand, action() { + dialogService.closeAll(); menuService.selectMenu(menu); }, category: "apps", diff --git a/addons/web/static/tests/core/commands/menu_provider_tests.js b/addons/web/static/tests/core/commands/menu_provider_tests.js index a5dd7f6b6a6..b31b0e6ad27 100644 --- a/addons/web/static/tests/core/commands/menu_provider_tests.js +++ b/addons/web/static/tests/core/commands/menu_provider_tests.js @@ -1,7 +1,9 @@ /** @odoo-module **/ +import { Component, xml } from "@odoo/owl"; import { createWebClient, getActionManagerServerData } from "@web/../tests/webclient/helpers"; import { browser } from "@web/core/browser/browser"; +import { Dialog } from "@web/core/dialog/dialog"; import { registry } from "@web/core/registry"; import { click, getFixture, nextTick, patchWithCleanup, triggerHotkey } from "../../helpers/utils"; import { editSearchBar } from "./command_service_tests"; @@ -141,3 +143,28 @@ QUnit.test("opens a menu items", async (assert) => { " ClientAction_Report" ); }); + +QUnit.test("open a menu item when a dialog is displayed", async (assert) => { + class CustomDialog extends Component {} + CustomDialog.components = { Dialog }; + CustomDialog.template = xml`content`; + + const webclient = await createWebClient({ serverData }); + assert.containsNone(target, ".o_menu_brand"); + assert.containsNone(target, ".modal .test"); + + webclient.env.services.dialog.add(CustomDialog); + await nextTick(); + assert.containsOnce(target, ".modal .test"); + + triggerHotkey("control+k"); + await nextTick(); + await editSearchBar("/sal"); + assert.containsOnce(target, ".o_command_palette"); + assert.containsOnce(target, ".modal .test"); + + await click(target, "#o_command_2"); + await nextTick(); + assert.strictEqual(target.querySelector(".o_menu_brand").textContent, "Sales"); + assert.containsNone(target, ".modal .test"); +});