diff --git a/addons/web/static/src/views/form/form_controller.js b/addons/web/static/src/views/form/form_controller.js index d467b75741f..423b922b951 100644 --- a/addons/web/static/src/views/form/form_controller.js +++ b/addons/web/static/src/views/form/form_controller.js @@ -194,15 +194,7 @@ export class FormController extends Component { useSetupView({ rootRef, - beforeLeave: () => { - if (this.model.root.isDirty) { - return this.model.root.save({ - noReload: true, - stayInEdition: true, - useSaveErrorDialog: true, - }); - } - }, + beforeLeave: () => this.beforeLeave(), beforeUnload: (ev) => this.beforeUnload(ev), getLocalState: () => { // TODO: export the whole model? @@ -299,6 +291,16 @@ export class FormController extends Component { } } + async beforeLeave() { + if (this.model.root.isDirty) { + return this.model.root.save({ + noReload: true, + stayInEdition: true, + useSaveErrorDialog: true, + }); + } + } + async beforeUnload(ev) { const isValid = await this.model.root.urgentSave(); if (!isValid) { diff --git a/addons/web/static/src/webclient/settings_form_view/settings_form_controller.js b/addons/web/static/src/webclient/settings_form_view/settings_form_controller.js index 11534bed480..7481545fe67 100644 --- a/addons/web/static/src/webclient/settings_form_view/settings_form_controller.js +++ b/addons/web/static/src/webclient/settings_form_view/settings_form_controller.js @@ -32,9 +32,6 @@ export class SettingsFormController extends formView.Controller { () => [this.searchState.value] ); useEffect(() => { - if (this.env.__beforeLeave__) { - this.env.__beforeLeave__.remove(this); - } if (this.env.__getLocalState__) { this.env.__getLocalState__.remove(this); } @@ -50,45 +47,27 @@ export class SettingsFormController extends formView.Controller { if (clickParams.name === "cancel") { return true; } - let _continue = true; if ( this.model.root.isDirty && !["execute"].includes(clickParams.name) && !clickParams.noSaveDialog ) { - const message = this.env._t("Would you like to save your changes?"); - await new Promise((resolve) => { - this.dialogService.add(SettingsConfirmationDialog, { - body: message, - confirm: async () => { - await this._save(); - // It doesn't make sense to do the action of the button - // as the res.config.settings `execute` method will trigger a reload. - _continue = false; - resolve(); - }, - cancel: async () => { - await this.model.root.discard(); - await this.model.root.save({ stayInEdition: true }); - _continue = true; - resolve(); - }, - stayHere: () => { - _continue = false; - resolve(); - }, - }); - }); + return this._confirmSave(); } else { - _continue = await this.model.root.save({ stayInEdition: true }); + return this.model.root.save({ stayInEdition: true }); } - return _continue; } displayName() { return this.env._t("Settings"); } + beforeLeave() { + if (this.model.root.isDirty) { + return this._confirmSave(); + } + } + //This is needed to avoid the auto save when unload beforeUnload() {} @@ -121,6 +100,33 @@ export class SettingsFormController extends formView.Controller { pick(this.model.root, "context", "evalContext", "resModel", "resId", "resIds"), }); } + + async _confirmSave() { + let _continue = true; + await new Promise((resolve) => { + this.dialogService.add(SettingsConfirmationDialog, { + body: this.env._t("Would you like to save your changes?"), + confirm: async () => { + await this._save(); + // It doesn't make sense to do the action of the button + // as the res.config.settings `execute` method will trigger a reload. + _continue = false; + resolve(); + }, + cancel: async () => { + await this.model.root.discard(); + await this.model.root.save({ stayInEdition: true }); + _continue = true; + resolve(); + }, + stayHere: () => { + _continue = false; + resolve(); + }, + }); + }); + return _continue; + } } SettingsFormController.components = { diff --git a/addons/web/static/tests/webclient/settings_form_view/settings_form_view_tests.js b/addons/web/static/tests/webclient/settings_form_view/settings_form_view_tests.js index 0975815ea6d..d634175dbb8 100644 --- a/addons/web/static/tests/webclient/settings_form_view/settings_form_view_tests.js +++ b/addons/web/static/tests/webclient/settings_form_view/settings_form_view_tests.js @@ -517,6 +517,62 @@ QUnit.module("SettingsFormView", (hooks) => { ]); }); + QUnit.test( + "settings views ask for confirmation when leaving if dirty", + async function (assert) { + serverData.actions = { + 1: { + id: 1, + name: "Settings view", + res_model: "res.config.settings", + type: "ir.actions.act_window", + views: [[1, "form"]], + }, + 4: { + id: 4, + name: "Other action", + res_model: "task", + type: "ir.actions.act_window", + views: [["view_ref", "form"]], + }, + }; + + serverData.views = { + "res.config.settings,1,form": ` +
`, + "res.config.settings,false,search": `