[FIX] web: update records of the current page when deleting

**Issue:**

When at the first page of the list, and the user deleted all/or some
of the records, the next page is not automatically displayed.

**Solution:**

This is because the first page (offset=0) is exempted from offset
adjustment (_adjustOffset) which is responsible in reloading the
records in the list.

In this commit, we propose to reload the list if the call to
`_adjustOffset` didn't call `load` and there are actually deleted
records.

closes odoo/odoo#106317

X-original-commit: 2863978041d2856644da938ced9eedc640b8f198
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
Signed-off-by: Joseph Caburnay (jcb) <jcb@odoo.com>
This commit is contained in:
Joseph Caburnay
2022-11-23 13:25:03 +01:00
parent d9fafdd08e
commit ac2074bd1a
2 changed files with 70 additions and 3 deletions
@@ -1921,7 +1921,15 @@ export class DynamicRecordList extends DynamicList {
for (const record of records) {
this.removeRecord(record);
}
await this._adjustOffset();
const hasReloaded = await this._adjustOffset();
if (resIds.length > 0 && !hasReloaded) {
// If the list hasn't been reloaded, force a reload if there are
// deleted records.
// NOTE that we don't rely on the reload logic of the _adjustOffset
// because we don't want the offset to be adjusted. Offset adjustment
// should only be done when at the last page.
await this.load();
}
return resIds;
}
@@ -2015,13 +2023,15 @@ export class DynamicRecordList extends DynamicList {
/**
* Reload the model if more records should appear on the current page.
*
* @returns {Promise<void>}
* @returns {Promise<boolean>} Resolves to true if the model reloaded.
*/
async _adjustOffset() {
if (this.offset && !this.records.length) {
this.offset = Math.max(this.offset - this.limit, 0);
await this.load();
return true;
}
return false;
}
/**
@@ -11553,7 +11553,7 @@ QUnit.module("Views", (hooks) => {
QUnit.test(
"grouped list view move to previous page of group when all records from last page deleted",
async function (assert) {
assert.expect(9);
assert.expect(10);
let checkSearchRead = false;
await makeView({
@@ -11610,6 +11610,63 @@ QUnit.module("Views", (hooks) => {
"",
"should be on first page now"
);
assert.containsN(target, ".o_data_row", 2);
}
);
QUnit.test(
"grouped list view move to next page when all records from the current page deleted",
async function (assert) {
serverData.models.foo.records = [1, 2, 3, 4, 5, 6]
.map((i) => ({
id: i,
foo: `yop${i}`,
m2o: 1,
}))
.concat([{ id: 7, foo: "blip", m2o: 2 }]);
await makeView({
type: "list",
resModel: "foo",
serverData,
arch: '<tree limit="2"><field name="foo"/></tree>',
actionMenus: {},
groupBy: ["m2o"],
});
assert.strictEqual(
target.querySelector("tr.o_group_header:first-child th").textContent.trim(),
"Value 1 (6)"
);
assert.strictEqual(
target.querySelector("tr.o_group_header:nth-child(2) th").textContent.trim(),
"Value 2 (1)"
);
const firstGroup = target.querySelector("tr.o_group_header:first-child");
await click(firstGroup);
assert.deepEqual(getPagerValue(firstGroup), [1, 2]);
assert.strictEqual(getPagerLimit(firstGroup), 6);
// delete all records from current page
await click(target.querySelector("thead .o_list_record_selector input"));
await click(target, ".o_cp_action_menus .dropdown-toggle");
await click(
[...target.querySelectorAll(".dropdown-item")].filter(
(el) => el.innerText === "Delete"
)[0]
);
await click(target, ".modal .btn-primary");
const groupLabel = "Value 1 (4)";
const pagerText = "1-2 / 4";
assert.strictEqual(
target.querySelector(".o_group_header:nth-child(1) .o_group_name").textContent,
`${groupLabel} ${pagerText}`
);
assert.deepEqual(
[...target.querySelectorAll(".o_data_row")].map((row) => row.textContent),
["yop3", "yop4"]
);
}
);