diff --git a/addons/web/static/src/legacy/action_adapters.js b/addons/web/static/src/legacy/action_adapters.js index 71071df58f9..b841ede875d 100644 --- a/addons/web/static/src/legacy/action_adapters.js +++ b/addons/web/static/src/legacy/action_adapters.js @@ -9,21 +9,10 @@ import { Dialog } from "../core/dialog/dialog"; import { useEffect } from "../core/effect_hook"; import { useService } from "../core/service_hook"; import { ViewNotFoundError } from "../webclient/actions/action_service"; -import { cleanDomFromBootstrap, mapDoActionOptionAPI } from "./utils"; +import { cleanDomFromBootstrap, wrapSuccessOrFail, mapDoActionOptionAPI } from "./utils"; const { Component, tags } = owl; -function wrapSuccessOrFail(promise, { on_success, on_fail } = {}) { - return promise.then(on_success || (() => {})).catch((reason) => { - if (on_fail) { - on_fail(reason); - } - if (reason instanceof Error) { - throw reason; - } - }); -} - class ActionAdapter extends ComponentAdapter { setup() { super.setup(); @@ -88,8 +77,8 @@ class ActionAdapter extends ComponentAdapter { if (payload.action.context) { payload.action.context = new Context(payload.action.context).eval(); } - this.onReverseBreadcrumb = ev.data.options && ev.data.options.on_reverse_breadcrumb; - const legacyOptions = mapDoActionOptionAPI(ev.data.options); + this.onReverseBreadcrumb = payload.options && payload.options.on_reverse_breadcrumb; + const legacyOptions = mapDoActionOptionAPI(payload.options); wrapSuccessOrFail(this.actionService.doAction(payload.action, legacyOptions), payload); } else if (ev.name === "breadcrumb_clicked") { this.actionService.restore(payload.controllerID); diff --git a/addons/web/static/src/legacy/legacy_service_provider.js b/addons/web/static/src/legacy/legacy_service_provider.js index e458ea39766..ce4e291f1c3 100644 --- a/addons/web/static/src/legacy/legacy_service_provider.js +++ b/addons/web/static/src/legacy/legacy_service_provider.js @@ -1,11 +1,14 @@ /** @odoo-module **/ import { bus } from "web.core"; +import Context from "web.Context"; + import { browser } from "../core/browser/browser"; import { registry } from "../core/registry"; +import { mapDoActionOptionAPI } from "./utils"; export const legacyServiceProvider = { - dependencies: ["effect"], + dependencies: ["effect", "action"], start({ services }) { browser.addEventListener("show-effect", (ev) => { services.effect.add(ev.detail.type, ev.detail); @@ -13,6 +16,15 @@ export const legacyServiceProvider = { bus.on("show-effect", this, (payload) => { services.effect.add(payload.type, payload); }); + + browser.addEventListener("do-action", (ev) => { + const payload = ev.detail; + if (payload.action.context) { + payload.action.context = new Context(payload.action.context).eval(); + } + const legacyOptions = mapDoActionOptionAPI(payload.options); + services.action.doAction(payload.action, legacyOptions); + }); }, }; diff --git a/addons/web/static/src/legacy/utils.js b/addons/web/static/src/legacy/utils.js index 216c9664477..0d4c0748465 100644 --- a/addons/web/static/src/legacy/utils.js +++ b/addons/web/static/src/legacy/utils.js @@ -279,3 +279,14 @@ export function makeLegacyCrashManagerService(legacyEnv) { }, }; } + +export function wrapSuccessOrFail(promise, { on_success, on_fail } = {}) { + return promise.then(on_success || (() => {})).catch((reason) => { + if (on_fail) { + on_fail(reason); + } + if (reason instanceof Error) { + throw reason; + } + }); +} diff --git a/addons/web/static/tests/webclient/actions/legacy_tests.js b/addons/web/static/tests/webclient/actions/legacy_tests.js index d1bb90250ef..ca160410ab3 100644 --- a/addons/web/static/tests/webclient/actions/legacy_tests.js +++ b/addons/web/static/tests/webclient/actions/legacy_tests.js @@ -15,6 +15,8 @@ import { debugService } from "@web/core/debug/debug_service"; import ControlPanel from "web.ControlPanel"; import core from "web.core"; import AbstractAction from "web.AbstractAction"; +import Widget from "web.Widget"; +import SystrayMenu from "web.SystrayMenu"; let serverData; @@ -352,4 +354,32 @@ QUnit.module("ActionManager", (hooks) => { doctor: "quackson", }); }); + + QUnit.test("Systray item triggers do action on legacy service provider", async (assert) => { + assert.expect(3); + function createMockActionService(assert) { + return { + dependencies: [], + start() { + return { + doAction(params) { + assert.step("do action"); + assert.strictEqual(params, 128, "The doAction parameters are invalid."); + }, + loadState() {}, + }; + }, + }; + } + registry.category("services").add("action", createMockActionService(assert)); + const FakeSystrayItemWidget = Widget.extend({ + on_attach_callback() { + this.do_action(128); + }, + }); + SystrayMenu.Items.push(FakeSystrayItemWidget); + await createWebClient({ serverData }); + assert.verifySteps(["do action"]); + delete SystrayMenu.Items.FakeSystrayItemWidget; + }); });