[FIX] web: unselect row inside x2many dialog
Have an x2many with an x2many editable list inside the form view containing at least a row. Open a record, click discard. Open it again, and click on a row of the x2many to switch it to edit mode. Before this commit, the row could never be switched back to readonly. This was the list renderer didn't correctly compute its active element (it must wait for a micro tick for the mounted hook of the dialog, its ancestor, to be called). After fixing this issue, a second one arise: the row can now be unselected, but it disappears if it is a new record. This is because we lost the dirty flag when clicking on discard. This is fixed by storing the dirty state alongside changes in the savepoint. Part-of: odoo/odoo#114024
This commit is contained in:
@@ -37,7 +37,6 @@ export class Record extends DataPoint {
|
||||
this._unsetRequiredFields = markRaw(new Set());
|
||||
this._closeInvalidFieldsNotification = () => {};
|
||||
|
||||
let savePoint;
|
||||
const missingFields = this.fieldNames.filter((fieldName) => !(fieldName in data));
|
||||
const vals = this._parseServerValues({
|
||||
...this._getDefaultValues(missingFields),
|
||||
@@ -46,13 +45,14 @@ export class Record extends DataPoint {
|
||||
if (this.resId) {
|
||||
this._values = markRaw(vals);
|
||||
this._changes = markRaw({});
|
||||
savePoint = {};
|
||||
} else {
|
||||
this._values = markRaw({});
|
||||
this._changes = markRaw(vals);
|
||||
savePoint = { ...this._changes };
|
||||
}
|
||||
this._savePoint = markRaw(savePoint);
|
||||
this._savePoint = markRaw({
|
||||
dirty: false,
|
||||
changes: { ...this._changes },
|
||||
});
|
||||
this.data = { ...this._values, ...this._changes };
|
||||
|
||||
const parentRecord = this._parentRecord;
|
||||
@@ -258,7 +258,8 @@ export class Record extends DataPoint {
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
_addSavePoint() {
|
||||
Object.assign(this._savePoint, this._changes);
|
||||
this._savePoint.dirty = this.dirty;
|
||||
Object.assign(this._savePoint.changes, this._changes);
|
||||
for (const fieldName in this._changes) {
|
||||
if (["one2many", "many2many"].includes(this.fields[fieldName].type)) {
|
||||
this._changes[fieldName]._addSavePoint();
|
||||
@@ -400,13 +401,13 @@ export class Record extends DataPoint {
|
||||
}
|
||||
|
||||
_discard() {
|
||||
this.dirty = false;
|
||||
for (const fieldName in this._changes) {
|
||||
if (["one2many", "many2many"].includes(this.fields[fieldName].type)) {
|
||||
this._changes[fieldName]._discard();
|
||||
}
|
||||
}
|
||||
this._changes = { ...this._savePoint };
|
||||
this.dirty = this._savePoint.dirty;
|
||||
this._changes = { ...this._savePoint.changes };
|
||||
this.data = { ...this._values, ...this._changes };
|
||||
this._setEvalContext();
|
||||
this._invalidFields.clear();
|
||||
|
||||
@@ -110,7 +110,10 @@ export class ListRenderer extends Component {
|
||||
|
||||
this.cellToFocus = null;
|
||||
this.activeRowId = null;
|
||||
onMounted(() => {
|
||||
onMounted(async () => {
|
||||
// Due to the way elements are mounted in the DOM by Owl (bottom-to-top),
|
||||
// we need to wait the next micro task tick to set the activeElement.
|
||||
await Promise.resolve();
|
||||
this.activeElement = this.uiService.activeElement;
|
||||
});
|
||||
onWillPatch(() => {
|
||||
|
||||
@@ -11323,6 +11323,14 @@ QUnit.module("Fields", (hooks) => {
|
||||
"second partner turtle is Michelangelo"
|
||||
);
|
||||
await clickDiscard(target.querySelector(".modal"));
|
||||
|
||||
// re-open, edit michelangelo row, click out -> row still there, in readonly
|
||||
await click(target.querySelectorAll(".o_data_row")[1].querySelector(".o_data_cell"));
|
||||
await click(target.querySelector(".modal .o_data_row .o_data_cell"));
|
||||
assert.containsOnce(target, ".modal .o_selected_row");
|
||||
await click(target.querySelector(".modal"));
|
||||
assert.containsOnce(target, ".modal .o_data_row");
|
||||
assert.strictEqual(target.querySelector(".modal .o_data_cell").innerText, "Michelangelo");
|
||||
});
|
||||
|
||||
QUnit.test("quickly switch between pages in one2many list", async function (assert) {
|
||||
|
||||
Reference in New Issue
Block a user