[FIX] web: form: no "oh snap" dialog after view button clicked

Have a form view with a view button. Make some changes in the form
s.t. the create/write rpc will return an error. Before this commit,
the "oh snap" dialog was displayed, providing 2 choices to the
user: stay here (basically, close the error dialog and do nothing
else) or discard (discard changes, and continue the flow). In this
case, the flow is to do the "call_button" as we clicked on a view
button. It means that if the user clicked on discard, we still
call the method/action, even though the record was invalid (and
maybe not even existing if it was a new record). This can cause
other issues afterwards.

The "oh snap" dialog was designed for navigation flows (e.g. menu,
breadcrumbs...), when the user tries to leave the form view. It
doesn't fit very well with flows involving the current record that
couldn't been saved.

This commit thus prevents the "oh snap" dialog from being displayed
if the save preceeding a call_button fails. The error returned by
the save is simply displayed in a basic dialog that can only be
closed.

opw~3395109

closes odoo/odoo#135050

X-original-commit: 50b2a24f22cb470bcc1a9befe677cf794211d7b2
Signed-off-by: Géry Debongnie <ged@odoo.com>
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
Aaron Bohy
2023-09-12 08:31:40 +00:00
parent c81e89adf7
commit 57da33a9ff
2 changed files with 38 additions and 3 deletions
@@ -480,9 +480,6 @@ export class FormController extends Component {
saved = await this.props.saveRecord(record, clickParams);
} else {
const params = { reload: !(this.env.inDialog && clickParams.close) };
if (!this.env.inDialog) {
params.onError = this.onSaveError.bind(this);
}
saved = await record.save(params);
}
if (saved !== false && this.props.onSave) {
@@ -12611,6 +12611,44 @@ QUnit.module("Views", (hooks) => {
assert.containsOnce(target, ".o_error_dialog");
});
QUnit.test("no 'oh snap' error when clicking on a view button", async (assert) => {
registry.category("services").add("error", errorService);
registry.category("error_dialogs").add("odoo.exceptions.UserError", WarningDialog);
// remove the override in qunit.js that swallows unhandledrejection errors
// s.t. we let the error service handle them
const originalOnUnhandledRejection = window.onunhandledrejection;
window.onunhandledrejection = () => {};
registerCleanup(() => {
window.onunhandledrejection = originalOnUnhandledRejection;
});
await makeView({
type: "form",
resModel: "partner",
serverData,
arch: `
<form>
<button name="do_it" type="object" string="Do it"/>
<field name="name"/>
</form>`,
mockRPC(route, { method }) {
assert.step(method);
if (method === "web_save") {
throw makeServerError({ message: "Some business message" });
}
},
});
await click(target, "button[name=do_it]");
assert.containsNone(target, ".o_form_error_dialog");
assert.containsOnce(target, ".modal");
assert.strictEqual(
target.querySelector(".modal .modal-body").textContent,
"Some business message"
);
assert.verifySteps(["get_views", "onchange", "web_save"]);
});
QUnit.test("no 'oh snap' error in form view in dialog", async (assert) => {
assert.expect(5);