[FIX] web: FormViewDialog: handle close attr on buttons

Before this commit, clicking on view buttons with attribute
`close="1"` in FormViewDialog didn't close the dialog once the
button action was performed. This commit fixes that issue, and
ensures we do not reload the record if we're about to close the
dialog.

X-original-commit: 32d211a6fd5c121fa5f556f1d78b79421edc6f68
Part-of: odoo/odoo#102149
This commit is contained in:
Aaron Bohy
2022-10-04 22:00:43 +02:00
parent 9d455d830b
commit 78c6c70ee4
4 changed files with 56 additions and 8 deletions
+1 -1
View File
@@ -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) {
+1
View File
@@ -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"),
@@ -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);
@@ -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": `
<form>
<field name="foo"/>
<button name="method1" type="object" string="Button 1" class="btn1"/>
<button name="method2" type="object" string="Button 2" class="btn2" close="1"/>
</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) {