[FIX] web: Dropping record in folded kanban column loads it

Before this commit, when dropping a record on a folded column in a
kanban view, the column would not load its records and display a "load
more" button instead.

Now, dropping a record on a folded column loads it entirely before
unfolding it, displaying its records normally (including the newly
dropped one).

closes odoo/odoo#98922

Signed-off-by: Mathieu Duckerts-Antoine <dam@odoo.com>
This commit is contained in:
Julien Mougenot
2022-08-30 20:22:58 +02:00
parent b3b672a66b
commit 8f8f6a52ac
3 changed files with 113 additions and 9 deletions
@@ -349,6 +349,7 @@ export class KanbanDynamicGroupList extends DynamicGroupList {
this.model.addEventListener("group-updated", ({ detail }) => {
if (this.groups.some((g) => g.id === detail.group.id)) {
this.updateGroupProgressData([detail.group], detail.withProgressBars);
this.model.notify();
}
});
}
@@ -417,8 +418,6 @@ export class KanbanDynamicGroupList extends DynamicGroupList {
const result = await promises.readProgressBar;
await Promise.all(groups.map((group) => group.updateProgressData(result)));
}
this.model.notify();
}
/**
@@ -447,6 +446,7 @@ export class KanbanDynamicGroupList extends DynamicGroupList {
}
// Move from one group to another
const fullyLoadGroup = targetGroup.isFolded;
if (dataGroupId !== targetGroupId) {
const refIndex = targetGroup.list.records.findIndex((r) => r.id === refId);
// Quick update: moves the record at the right position and notifies components
@@ -470,14 +470,24 @@ export class KanbanDynamicGroupList extends DynamicGroupList {
throw err;
}
// Record can be loaded along with the group metadata
await Promise.all([
this.updateGroupProgressData([sourceGroup, targetGroup], true),
record.load(),
]);
const promises = [this.updateGroupProgressData([sourceGroup, targetGroup], true)];
if (fullyLoadGroup) {
// The group is folded: we need to load it
// In this case since we load after saving the record there is no
// need to reload the record nor to resequence the list.
promises.push(targetGroup.toggle());
} else {
// Record can be loaded along with the group metadata
promises.push(record.load());
}
await Promise.all(promises);
}
await targetGroup.list.resequence(dataRecordId, refId);
if (!fullyLoadGroup) {
// Only trigger resequence if the group hasn't been fully loaded
await targetGroup.list.resequence(dataRecordId, refId);
}
this.model.transaction.commit(dataRecordId);
}
@@ -2423,7 +2423,6 @@ export class Group extends DataPoint {
*/
addRecord(record, index) {
this.count++;
this.isFolded = false;
return this.list.addRecord(record, index);
}
@@ -11053,4 +11053,99 @@ QUnit.module("Views", (hooks) => {
productFieldName + "..."
);
});
QUnit.test("fold a column and drag record on it should unfold it", async (assert) => {
let searchReadProm;
await makeView({
type: "kanban",
resModel: "partner",
serverData,
arch: /* xml */ `
<kanban>
<templates>
<div t-name="kanban-box">
<field name="id"/>
</div>
</templates>
</kanban>`,
groupBy: ["product_id"],
async mockRPC(_route, { method }) {
if (method === "web_search_read") {
await searchReadProm;
}
},
});
assert.containsN(target, ".o_kanban_group", 2);
assert.containsN(getColumn(0), ".o_kanban_record", 2);
assert.containsN(getColumn(1), ".o_kanban_record", 2);
const clickColumnAction = await toggleColumnActions(1);
await clickColumnAction("Fold");
assert.containsN(getColumn(0), ".o_kanban_record", 2);
assert.hasClass(getColumn(1), "o_column_folded");
assert.strictEqual(getColumn(1).innerText, "xmo (2)");
searchReadProm = makeDeferred();
await dragAndDrop(".o_kanban_group:first-child .o_kanban_record", ".o_column_folded");
assert.containsN(getColumn(0), ".o_kanban_record", 1);
assert.hasClass(getColumn(1), "o_column_folded");
assert.strictEqual(getColumn(1).innerText, "xmo (3)");
searchReadProm.resolve();
await nextTick();
assert.containsN(getColumn(0), ".o_kanban_record", 1);
assert.doesNotHaveClass(getColumn(1), "o_column_folded");
assert.containsN(getColumn(1), ".o_kanban_record", 3);
});
QUnit.test("drag record on initially folded column should load it", async (assert) => {
let searchReadProm;
await makeView({
type: "kanban",
resModel: "partner",
serverData,
arch: /* xml */ `
<kanban>
<templates>
<div t-name="kanban-box">
<field name="id"/>
</div>
</templates>
</kanban>`,
groupBy: ["product_id"],
async mockRPC(route, args, performRPC) {
if (args.method === "web_read_group") {
const result = await performRPC(route, args);
result.groups[1].__fold = true;
return result;
} else if (args.method === "web_search_read") {
await searchReadProm;
}
},
});
assert.containsN(getColumn(0), ".o_kanban_record", 2);
assert.hasClass(getColumn(1), "o_column_folded");
assert.strictEqual(getColumn(1).innerText, "xmo (2)");
searchReadProm = makeDeferred();
await dragAndDrop(".o_kanban_group:first-child .o_kanban_record", ".o_column_folded");
assert.containsN(getColumn(0), ".o_kanban_record", 1);
assert.hasClass(getColumn(1), "o_column_folded");
assert.strictEqual(getColumn(1).innerText, "xmo (3)");
searchReadProm.resolve();
await nextTick();
assert.containsN(getColumn(0), ".o_kanban_record", 1);
assert.doesNotHaveClass(getColumn(1), "o_column_folded");
assert.containsN(getColumn(1), ".o_kanban_record", 3);
});
});