[FIX] web: do not save untouched fields on F5
Have a char field with trim option set to True (this is the default). Open a form view where the value of this field has leading or trailing spaces. Press F5 (or close the tab/browser). Before this commit, a write was done before leaving, with the trimmed value of the char field. This isn't the expected behavior: as the field hasn't been manually edited, we don't want to write on it. This could be reproduced on project.task form views, on tasks with a name with leading/trailing spaces (e.g. tasks created by mails sent to feedback@odoo.com). The issue occurred when we saved a record "urgently" (before unload) because we parsed the value of each input field, and we sent it if it was different from the initial (or last set) value. In our case, parsing the value trimmed it, and it was thus different from the initial value. Bug reported after the migration of odoo.com to 16.0. closes odoo/odoo#110528 X-original-commit: 43b7ae39e633ced6008b067bb4e63ed9be7eda01 Signed-off-by: Michaël Mattiello <mcm@odoo.com>
This commit is contained in:
@@ -33,6 +33,14 @@ export function useInputField(params) {
|
||||
*/
|
||||
let lastSetValue = null;
|
||||
|
||||
/**
|
||||
* Track the fact that there is a change sent to the model that hasn't been acknowledged yet
|
||||
* (e.g. because the onchange is still pending). This is necessary if we must do an urgent save,
|
||||
* as we have to re-send that change for the write that will be done directly.
|
||||
* FIXME: this could/should be handled by the model itself, when it will be rewritten
|
||||
*/
|
||||
let pendingUpdate = false;
|
||||
|
||||
/**
|
||||
* When a user types, we need to set the field as dirty.
|
||||
*/
|
||||
@@ -64,7 +72,10 @@ export function useInputField(params) {
|
||||
}
|
||||
|
||||
if (!isInvalid) {
|
||||
component.props.update(val);
|
||||
pendingUpdate = true;
|
||||
Promise.resolve(component.props.update(val)).then(() => {
|
||||
pendingUpdate = false;
|
||||
});
|
||||
lastSetValue = ev.target.value;
|
||||
}
|
||||
|
||||
@@ -126,7 +137,7 @@ export function useInputField(params) {
|
||||
}
|
||||
|
||||
isDirty = inputRef.el.value !== lastSetValue;
|
||||
if (isDirty || urgent) {
|
||||
if (isDirty || (urgent && pendingUpdate)) {
|
||||
let isInvalid = false;
|
||||
isDirty = false;
|
||||
let val = inputRef.el.value;
|
||||
|
||||
@@ -11868,6 +11868,35 @@ QUnit.module("Views", (hooks) => {
|
||||
assert.verifySteps([], "should not save because we do not change anything");
|
||||
});
|
||||
|
||||
QUnit.test(
|
||||
"Auto save: save on closing tab/browser (not dirty but trailing spaces)",
|
||||
async function (assert) {
|
||||
serverData.models.partner.fields.foo.trim = true;
|
||||
serverData.models.partner.records[0].foo = "name with trailing spaces ";
|
||||
|
||||
await makeView({
|
||||
type: "form",
|
||||
resModel: "partner",
|
||||
serverData,
|
||||
arch: `<form><field name="foo"/></form>`,
|
||||
resId: 1,
|
||||
mockRPC(route, { args, method, model }) {
|
||||
if (method === "write" && model === "partner") {
|
||||
throw new Error("no write should be done");
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
assert.strictEqual(
|
||||
target.querySelector(".o_field_widget[name=foo] input").value,
|
||||
"name with trailing spaces "
|
||||
);
|
||||
|
||||
window.dispatchEvent(new Event("beforeunload"));
|
||||
await nextTick();
|
||||
}
|
||||
);
|
||||
|
||||
QUnit.test(
|
||||
"Auto save: save on closing tab/browser (not dirty) with text field",
|
||||
async function (assert) {
|
||||
|
||||
Reference in New Issue
Block a user