From cbee4b0c06188419a65aef8953795c92f11d247b Mon Sep 17 00:00:00 2001 From: svs-odoo Date: Thu, 23 Jun 2022 12:57:45 +0000 Subject: [PATCH] [IMP] web: add onSave/onDiscard on form_controller Adds two new props in `form_controller` in order to call a function from the parent `Component` just after the form view is saved/discarded. closes odoo/odoo#97314 Related: odoo/enterprise#30045 Signed-off-by: Aaron Bohy (aab) --- .../static/src/views/form/form_controller.js | 22 ++++++++++++++++--- .../tests/views/form/form_view_tests.js | 18 +++++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/addons/web/static/src/views/form/form_controller.js b/addons/web/static/src/views/form/form_controller.js index 16e36da12e6..ef202a5a4f6 100644 --- a/addons/web/static/src/views/form/form_controller.js +++ b/addons/web/static/src/views/form/form_controller.js @@ -153,7 +153,14 @@ export class FormController extends Component { const beforeExecuteAction = (clickParams) => { if (clickParams.special !== "cancel") { - return this.model.root.save({ stayInEdition: true }); + return this.model.root.save({ stayInEdition: true }).then((saved) => { + if (saved && this.props.onSave) { + this.props.onSave(this.model.root); + } + return saved; + }); + } else if (this.props.onDiscard) { + this.props.onDiscard(this.model.root); } }; const rootRef = useRef("root"); @@ -333,6 +340,7 @@ export class FormController extends Component { async save(params = {}) { const disabledButtons = this.disableButtons(); const record = this.model.root; + let saved = false; // Before we save, we gather dirty translate fields data. It needs to be done before the // save as nothing will be dirty after. It is why there is a compute part and a show part. @@ -345,11 +353,14 @@ export class FormController extends Component { } if (this.props.saveRecord) { - await this.props.saveRecord(record, params); + saved = await this.props.saveRecord(record, params); } else { - await record.save(); + saved = await record.save(); } this.enableButtons(disabledButtons); + if (saved && this.props.onSave) { + this.props.onSave(record); + } // After we saved, we show the previously computed data in the alert (if there is any). // It needs to be done after the save because if we were in record creation, the resId @@ -366,6 +377,9 @@ export class FormController extends Component { return; } await this.model.root.discard(); + if (this.props.onDiscard) { + this.props.onDiscard(this.model.root); + } if (this.model.root.isVirtual) { this.env.config.historyBack(); } @@ -417,6 +431,8 @@ FormController.props = { buttonTemplate: String, preventCreate: { type: Boolean, optional: true }, preventEdit: { type: Boolean, optional: true }, + onDiscard: { type: Function, optional: true }, + onSave: { type: Function, optional: true }, }; FormController.defaultProps = { preventCreate: false, diff --git a/addons/web/static/tests/views/form/form_view_tests.js b/addons/web/static/tests/views/form/form_view_tests.js index 1fe2e0c0878..1d24a28cf6c 100644 --- a/addons/web/static/tests/views/form/form_view_tests.js +++ b/addons/web/static/tests/views/form/form_view_tests.js @@ -11986,4 +11986,22 @@ QUnit.module("Views", (hooks) => { "xmlHelp" ); }); + + QUnit.test("onSave/onDiscard props", async function (assert) { + await makeView({ + type: "form", + resModel: "partner", + serverData, + arch: `
`, + resId: 1, + onSave: () => assert.step("save"), + onDiscard: () => assert.step("discard"), + }); + + await click(target, ".o_form_button_edit"); + await click(target, ".o_form_button_save"); + await click(target, ".o_form_button_edit"); + await click(target, ".o_form_button_cancel"); + assert.verifySteps(["save", "discard"]); + }); });