diff --git a/addons/web/static/src/core/dialog/dialog.js b/addons/web/static/src/core/dialog/dialog.js index f8790f5707f..50195e8fa23 100644 --- a/addons/web/static/src/core/dialog/dialog.js +++ b/addons/web/static/src/core/dialog/dialog.js @@ -14,7 +14,7 @@ export class Dialog extends Component { this.data.close(); }); this.id = `dialog_${this.data.id}`; - useChildSubEnv({ inDialog: true, dialogId: this.id }); + useChildSubEnv({ inDialog: true, dialogId: this.id, closeDialog: this.data.close }); owl.onWillDestroy(() => { if (this.env.isSmall) { diff --git a/addons/web/static/src/views/utils.js b/addons/web/static/src/views/utils.js index 34bebefcd01..d9f2927d2f5 100644 --- a/addons/web/static/src/views/utils.js +++ b/addons/web/static/src/views/utils.js @@ -196,6 +196,7 @@ export function processButton(node) { options: JSON.parse(node.getAttribute("options") || "{}"), modifiers: JSON.parse(node.getAttribute("modifiers") || "{}"), clickParams: { + close: archParseBoolean(node.getAttribute("close"), false), context: node.getAttribute("context") || "{}", name: node.getAttribute("name"), type: node.getAttribute("type"), 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 d47a88b960c..8d690bda19a 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 @@ -39,9 +39,7 @@ export function useViewButtons(model, ref, options = {}) { (() => { return true; }); - const afterExecuteAction = - options.afterExecuteAction || - (() => {}); + const afterExecuteAction = options.afterExecuteAction || (() => {}); useSubEnv({ async onClickViewButton({ clickParams, @@ -66,6 +64,7 @@ export function useViewButtons(model, ref, options = {}) { enableButtons(getEl(), manuallyDisabledButtons, enableAction); return; } + const closeDialog = clickParams.close && env.closeDialog; const params = getResParams(); const resId = params.resId; const resIds = params.resIds || model.resIds; @@ -88,9 +87,11 @@ export function useViewButtons(model, ref, options = {}) { context: params.context || {}, //LPE FIXME new Context(payload.env.context).eval(); buttonContext, onClose: async () => { - const reload = options.reload || (() => model.root.load()); - await reload(); - comp.render(true); // FIXME WOWL reactivity + if (!closeDialog) { + const reload = options.reload || (() => model.root.load()); + await reload(); + comp.render(true); // FIXME WOWL reactivity + } }, }); let error; @@ -101,6 +102,9 @@ export function useViewButtons(model, ref, options = {}) { await doActionParams.onClose(); } await afterExecuteAction(clickParams); + if (closeDialog) { + closeDialog(); + } enableButtons(getEl(), manuallyDisabledButtons, enableAction); if (error) { return Promise.reject(error); diff --git a/addons/web/static/tests/views/view_dialogs/form_view_dialog_tests.js b/addons/web/static/tests/views/view_dialogs/form_view_dialog_tests.js index e6cb2a48ec6..a840256c716 100644 --- a/addons/web/static/tests/views/view_dialogs/form_view_dialog_tests.js +++ b/addons/web/static/tests/views/view_dialogs/form_view_dialog_tests.js @@ -1,6 +1,12 @@ /** @odoo-module */ -import { click, getFixture, nextTick, triggerHotkey } from "@web/../tests/helpers/utils"; +import { + click, + getFixture, + nextTick, + patchWithCleanup, + triggerHotkey, +} from "@web/../tests/helpers/utils"; import { makeView } from "@web/../tests/views/helpers"; import { createWebClient } from "@web/../tests/webclient/helpers"; import { dialogService } from "@web/core/dialog/dialog_service"; @@ -245,6 +251,43 @@ QUnit.module("ViewDialogs", (hooks) => { await click(target, '.o_field_widget[name="instrument"] button.o_external_button'); }); + QUnit.test("click on view buttons in a FormViewDialog", async function (assert) { + serverData.views = { + "partner,false,form": ` +
`, + }; + + function mockRPC(route, args) { + assert.step(args.method || route); + } + const webClient = await createWebClient({ serverData, mockRPC }); + patchWithCleanup(webClient.env.services.action, { + doActionButton: (params) => { + assert.step(params.name); + params.onClose(); + }, + }); + webClient.env.services.dialog.add(FormViewDialog, { + resModel: "partner", + resId: 1, + }); + await nextTick(); + + assert.containsOnce(target, ".o_dialog .o_form_view"); + assert.containsN(target, ".o_dialog .o_form_view button", 2); + assert.verifySteps(["/web/webclient/load_menus", "get_views", "read"]); + await click(target.querySelector(".o_dialog .o_form_view .btn1")); + assert.containsOnce(target, ".o_dialog .o_form_view"); + assert.verifySteps(["method1", "read"]); // should re-read the record + await click(target.querySelector(".o_dialog .o_form_view .btn2")); + assert.containsNone(target, ".o_dialog .o_form_view"); + assert.verifySteps(["method2"]); // should not read as we closed + }); + QUnit.test( "formviewdialog is not closed when button handlers return a rejected promise", async function (assert) {