[FIX] web: multi level grouped list: correct pager inside groups

Have a list view with multiple groupbys and a lot of records to
have pagers displayed. Open a group (first level). The pager of the
group uses the number of records instead of number of (inner)
groups as total.

This commit fixes the issue. The pager now correctly allows to
navigate through inner groups.

closes odoo/odoo#157995

Signed-off-by: Francois Georis (fge) <fge@odoo.com>
This commit is contained in:
Aaron Bohy
2024-03-19 09:24:20 +00:00
parent 9d2b18f047
commit 2176cadebd
2 changed files with 64 additions and 36 deletions
@@ -1029,7 +1029,7 @@ export class ListRenderer extends Component {
if (this.props.onOpenFormView) {
colspan++;
}
return colspan
return colspan;
}
getGroupPagerProps(group) {
@@ -1037,7 +1037,7 @@ export class ListRenderer extends Component {
return {
offset: list.offset,
limit: list.limit,
total: group.count,
total: list.isGrouped ? list.count : group.count,
onUpdate: async ({ offset, limit }) => {
await list.load({ limit, offset });
this.render(true);
@@ -1778,7 +1778,10 @@ export class ListRenderer extends Component {
}
showGroupPager(group) {
return !group.isFolded && group.list.limit < group.count;
return (
!group.isFolded &&
group.list.limit < (group.list.isGrouped ? group.list.count : group.count)
);
}
/**
@@ -2159,11 +2159,12 @@ QUnit.module("Views", (hooks) => {
});
assert.strictEqual(
target.querySelector(".o_group_header th").getAttribute("colspan"), "2"
target.querySelector(".o_group_header th").getAttribute("colspan"),
"2"
);
assert.strictEqual(
target.querySelector(".o_group_header th:last-child").getAttribute("colspan"),
"2",
"2"
);
}
);
@@ -2186,11 +2187,12 @@ QUnit.module("Views", (hooks) => {
});
assert.strictEqual(
target.querySelector(".o_group_header th").getAttribute("colspan"), "2"
target.querySelector(".o_group_header th").getAttribute("colspan"),
"2"
);
assert.strictEqual(
target.querySelector(".o_group_header th:last-child").getAttribute("colspan"),
"1",
"1"
);
}
);
@@ -6808,6 +6810,23 @@ QUnit.module("Views", (hooks) => {
);
});
QUnit.test("multi-level grouped list, pager inside a group", async function (assert) {
serverData.models.foo.records.forEach((r) => (r.bar = true));
await makeView({
type: "list",
resModel: "foo",
serverData,
arch: '<tree limit="2" groups_limit="3"><field name="foo"/><field name="bar"/></tree>',
groupBy: ["bar", "foo"],
});
assert.containsOnce(target, ".o_group_header");
await click(target.querySelector(".o_group_header"));
assert.containsN(target, ".o_group_header", 4);
assert.containsNone(target, ".o_group_header:first-of-type .o_group_name .o_pager");
});
QUnit.test("count_limit attrs set in arch", async function (assert) {
let expectedCountLimit = 4;
await makeView({
@@ -11563,7 +11582,10 @@ QUnit.module("Views", (hooks) => {
</tree>`,
mockRPC(route, args) {
if (args.method === "write") {
assert.deepEqual(args.args, [[1, 2], { date_start: "2021-04-01", date_end: "2017-01-26"}]);
assert.deepEqual(args.args, [
[1, 2],
{ date_start: "2021-04-01", date_end: "2017-01-26" },
]);
}
},
});
@@ -20025,36 +20047,39 @@ QUnit.module("Views", (hooks) => {
}
);
QUnit.test("onchange should only be called once after pressing enter on a field", async function (assert) {
serverData.models.foo.onchanges = {
foo(record) {
if (record.foo) {
record.int_field = 1;
}
},
};
await makeView({
type: "list",
resModel: "foo",
serverData,
arch: `
QUnit.test(
"onchange should only be called once after pressing enter on a field",
async function (assert) {
serverData.models.foo.onchanges = {
foo(record) {
if (record.foo) {
record.int_field = 1;
}
},
};
await makeView({
type: "list",
resModel: "foo",
serverData,
arch: `
<tree editable="top">
<field name="foo"/>
<field name="int_field"/>
</tree>`,
async mockRPC(_, { method }) {
if (method === "onchange") {
assert.step(method);
}
},
});
await click(target.querySelector(".o_data_cell"));
target.querySelector(".o_field_widget[name=foo] input").value = "1";
await triggerEvents(target, ".o_field_widget[name=foo] input", [
["keydown", { key: "Enter" }],
["change"],
]);
await nextTick();
assert.verifySteps(["onchange"], "There should only be one onchange call");
});
async mockRPC(_, { method }) {
if (method === "onchange") {
assert.step(method);
}
},
});
await click(target.querySelector(".o_data_cell"));
target.querySelector(".o_field_widget[name=foo] input").value = "1";
await triggerEvents(target, ".o_field_widget[name=foo] input", [
["keydown", { key: "Enter" }],
["change"],
]);
await nextTick();
assert.verifySteps(["onchange"], "There should only be one onchange call");
}
);
});