From e7e409baad42256ecd4fde43296e0f17112b4b01 Mon Sep 17 00:00:00 2001 From: "Simon Genin (ges)" Date: Fri, 18 Jun 2021 12:07:05 +0000 Subject: [PATCH] [FIX] web: make activities systray item work The activities systray item didn't work anymore. Nothing happened on click. It was because the do action event was never caught. The systray item logic had a different flow and didn't go through the ViewAdapter code. We fix this by adding a listener on window (through legacy service provider) to execute this code when the do_action bubbles up. Instead of using the legacy service provided, we could have done this in the SystrayItemAdapter, but we then have the legacy environment and would need more work for the same result. closes odoo/odoo#72406 Signed-off-by: Aaron Bohy (aab) --- .../web/static/src/legacy/action_adapters.js | 17 ++--------- .../src/legacy/legacy_service_provider.js | 14 ++++++++- addons/web/static/src/legacy/utils.js | 11 +++++++ .../tests/webclient/actions/legacy_tests.js | 30 +++++++++++++++++++ 4 files changed, 57 insertions(+), 15 deletions(-) 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; + }); });