diff --git a/addons/web/static/src/views/view_button/view_button_hook.js b/addons/web/static/src/views/view_button/view_button_hook.js index 5e3fb5cb9ed..330f760e008 100644 --- a/addons/web/static/src/views/view_button/view_button_hook.js +++ b/addons/web/static/src/views/view_button/view_button_hook.js @@ -22,6 +22,10 @@ function enableButtons(el, manuallyDisabledButtons) { } } } + +function undefinedAsTrue(val) { + return typeof val === "undefined" || val; +} export function useViewButtons(model, ref, options = {}) { const action = useService("action"); const dialog = useService("dialog"); @@ -33,12 +37,17 @@ export function useViewButtons(model, ref, options = {}) { return true; }); useSubEnv({ - async onClickViewButton({ clickParams, record }) { + async onClickViewButton({ clickParams, record, beforeExecute }) { const manuallyDisabledButtons = disableButtons(getEl()); async function execute() { - const _continue = await beforeExecuteAction(clickParams); - if (typeof _continue !== "undefined" && !_continue) { + let _continue = true; + if (beforeExecute) { + _continue = undefinedAsTrue(await beforeExecute()); + } + + _continue = _continue && undefinedAsTrue(await beforeExecuteAction(clickParams)); + if (!_continue) { enableButtons(getEl(), manuallyDisabledButtons); return; } diff --git a/addons/web/static/tests/views/view_button_hook_tests.js b/addons/web/static/tests/views/view_button_hook_tests.js new file mode 100644 index 00000000000..efd7d38926c --- /dev/null +++ b/addons/web/static/tests/views/view_button_hook_tests.js @@ -0,0 +1,79 @@ +/** @odoo-module */ +import { useViewButtons } from "@web/views/view_button/view_button_hook"; +import { setupViewRegistries } from "./helpers"; +import { click, getFixture } from "../helpers/utils"; +import { makeTestEnv } from "../helpers/mock_env"; +import { registry } from "@web/core/registry"; + +const { useRef, mount, Component, xml } = owl; + +QUnit.module("UseViewButton tests", (hooks) => { + let target; + hooks.beforeEach(() => { + target = getFixture(); + setupViewRegistries(); + }); + + QUnit.test("action can be prevented", async (assert) => { + registry.category("services").add( + "action", + { + start() { + return { + doActionButton() { + assert.step("doActionButton"); + }, + }; + }, + }, + { force: true } + ); + + let executeInHook; + let executeInHandler; + class MyComponent extends Component { + setup() { + const rootRef = useRef("root"); + useViewButtons({}, rootRef, { + beforeExecuteAction: () => { + assert.step("beforeExecuteAction in hook"); + return executeInHook; + }, + }); + } + + onClick() { + const record = { + resIds: [3], + resId: 3, + load: () => {}, + }; + const clickParams = {}; + const beforeExecute = () => { + assert.step("beforeExecuteAction on handler"); + return executeInHandler; + }; + this.env.onClickViewButton({ beforeExecute, record, clickParams }); + } + } + MyComponent.template = xml`
Some text
`; + + const env = await makeTestEnv(); + await mount(MyComponent, target, { env, props: {} }); + + await click(target, ".myComponent"); + assert.verifySteps([ + "beforeExecuteAction on handler", + "beforeExecuteAction in hook", + "doActionButton", + ]); + + executeInHook = false; + await click(target, ".myComponent"); + assert.verifySteps(["beforeExecuteAction on handler", "beforeExecuteAction in hook"]); + + executeInHandler = false; + await click(target, ".myComponent"); + assert.verifySteps(["beforeExecuteAction on handler"]); + }); +});