diff --git a/addons/web/static/src/core/pager/pager.js b/addons/web/static/src/core/pager/pager.js index 25f83d903ba..c311574fc1f 100644 --- a/addons/web/static/src/core/pager/pager.js +++ b/addons/web/static/src/core/pager/pager.js @@ -64,6 +64,10 @@ export class Pager extends Component { async navigate(direction) { let minimum = this.props.offset + this.props.limit * direction; let total = this.props.total; + if (this.props.updateTotal && minimum < 0) { + // we must know the real total to be able to loop by doing "previous" + total = await this.props.updateTotal(); + } if (minimum >= total) { if (!this.props.updateTotal) { // only loop forward if we know the real total, otherwise let the minimum diff --git a/addons/web/static/tests/core/pager_tests.js b/addons/web/static/tests/core/pager_tests.js index 154f57729c4..1e327678ac9 100644 --- a/addons/web/static/tests/core/pager_tests.js +++ b/addons/web/static/tests/core/pager_tests.js @@ -382,4 +382,30 @@ QUnit.module("Components", ({ beforeEach }) => { assert.strictEqual(target.querySelector(".o_pager_limit").innerText, "10+"); assert.hasClass(target.querySelector(".o_pager_limit"), "o_pager_limit_fetch"); }); + + QUnit.test("updateTotal props: click previous", async function (assert) { + const pager = await makePager({ + offset: 0, + limit: 5, + total: 10, + onUpdate(data) { + pager.updateProps(data); + }, + async updateTotal() { + const total = 23; + pager.updateProps({ total, updateTotal: undefined }); + return total; + }, + }); + + assert.strictEqual(target.querySelector(".o_pager_value").innerText, "1-5"); + assert.strictEqual(target.querySelector(".o_pager_limit").innerText, "10+"); + assert.hasClass(target.querySelector(".o_pager_limit"), "o_pager_limit_fetch"); + + await click(target, ".o_pager_previous"); + + assert.strictEqual(target.querySelector(".o_pager_value").innerText, "21-23"); + assert.strictEqual(target.querySelector(".o_pager_limit").innerText, "23"); + assert.doesNotHaveClass(target.querySelector(".o_pager_limit"), "o_pager_limit_fetch"); + }); }); diff --git a/addons/web/static/tests/views/kanban_view_tests.js b/addons/web/static/tests/views/kanban_view_tests.js index 125d9506d70..2c43614b27d 100644 --- a/addons/web/static/tests/views/kanban_view_tests.js +++ b/addons/web/static/tests/views/kanban_view_tests.js @@ -1342,6 +1342,47 @@ QUnit.module("Views", (hooks) => { assert.verifySteps(["search_count"]); }); + QUnit.test( + "pager, ungrouped, deleting all records from last page should move to previous page", + async (assert) => { + patchDialog((_cls, props) => { + assert.step("open-dialog"); + props.confirm(); + }); + + await makeView({ + type: "kanban", + resModel: "partner", + serverData, + arch: ` + + +
+
Delete
+ +
+
+
+
`, + }); + + assert.deepEqual(getPagerValue(target), [1, 3]); + assert.strictEqual(getPagerLimit(target), 4); + + // move to next page + await pagerNext(target); + + assert.deepEqual(getPagerValue(target), [4, 4]); + + // delete a record + await click(target, ".o_kanban_record a"); + + assert.verifySteps(["open-dialog"]); + assert.deepEqual(getPagerValue(target), [1, 3]); + assert.strictEqual(getPagerLimit(target), 3); + } + ); + QUnit.test("pager, update calls onUpdatedPager before the render", async (assert) => { assert.expect(8); diff --git a/addons/web/static/tests/views/list_view_tests.js b/addons/web/static/tests/views/list_view_tests.js index b6aba0e2cb6..1768dcef3df 100644 --- a/addons/web/static/tests/views/list_view_tests.js +++ b/addons/web/static/tests/views/list_view_tests.js @@ -5752,6 +5752,37 @@ QUnit.module("Views", (hooks) => { assert.verifySteps(["web_search_read"]); }); + QUnit.test("pager, ungrouped, with count limit reached, click previous", async (assert) => { + patchWithCleanup(DynamicRecordList, { WEB_SEARCH_READ_COUNT_LIMIT: 3 }); + serverData.models.foo.records.push({ id: 5, bar: true, foo: "xxx" }); + + let expectedCountLimit = 4; + await makeView({ + type: "list", + resModel: "foo", + serverData, + arch: '', + mockRPC(route, args) { + assert.step(args.method); + if (args.method === "web_search_read") { + assert.strictEqual(args.kwargs.count_limit, expectedCountLimit); + } + }, + }); + + assert.containsN(target, ".o_data_row", 2); + assert.strictEqual(target.querySelector(".o_pager_value").innerText, "1-2"); + assert.strictEqual(target.querySelector(".o_pager_limit").innerText, "3+"); + assert.verifySteps(["get_views", "web_search_read"]); + + expectedCountLimit = undefined; + await click(target.querySelector(".o_pager_previous")); + assert.containsOnce(target, ".o_data_row"); + assert.strictEqual(target.querySelector(".o_pager_value").innerText, "5-5"); + assert.strictEqual(target.querySelector(".o_pager_limit").innerText, "5"); + assert.verifySteps(["search_count", "web_search_read"]); + }); + QUnit.test("pager, ungrouped, with count limit reached, edit pager", async (assert) => { patchWithCleanup(DynamicRecordList, { WEB_SEARCH_READ_COUNT_LIMIT: 3 }); serverData.models.foo.records.push({ id: 5, bar: true, foo: "xxx" });