[FIX] web: pager: do not fetch count on page next
Since commit [1], we can have list or kanban view with same limit and count_limit (to save a costly search_count), i.e. have a pager like "1-80/80+". Before this commit, when reaching the count limit on page next, we performed the search_count. This was fine before as the count_limit was hardcoded to 10k, so you basically never did page next until the limit. However, it's a issue now that the count_limit can be specified, as in the above example, we don't want to slow down the loading of the second page records because of the search_count. With this commit, we slightly increase the count limit when we reach it, so for instance doing next when the pager shows 1-80/80+ fetches the records with args offset=80, limit=80, count_limit=160 and the pager then shows 81-160/160+. If the total number of records is reached, we know the count and display it, for instance, after another pager next: 161-190/190. The same logic applies when the pager is manually edited, e.g. when you write 1-150 in a pager showing 1-80/80+, you'll get 1-150/150+ if there are more than 150 records. [1] 699215ec9a71b8c9b6a53fe96e924a400d216729 Task 3162026 X-original-commit: d39559274e6de6cdba6972775f9bda8bd2de8fa6 Part-of: odoo/odoo#113134
This commit is contained in:
@@ -51,6 +51,8 @@ export class Pager extends Component {
|
||||
return parts.join("-");
|
||||
}
|
||||
/**
|
||||
* Note: returns false if we received the props "updateTotal", as in this case we don't know
|
||||
* the real total so we can't assert that there's a single page.
|
||||
* @returns {boolean} true if there is only one page
|
||||
*/
|
||||
get isSinglePage() {
|
||||
@@ -62,11 +64,12 @@ 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 + this.props.limit > total) {
|
||||
total = await this.props.updateTotal();
|
||||
}
|
||||
if (minimum >= total) {
|
||||
minimum = 0;
|
||||
if (!this.props.updateTotal) {
|
||||
// only loop forward if we know the real total, otherwise let the minimum
|
||||
// go out of range
|
||||
minimum = 0;
|
||||
}
|
||||
} else if (minimum < 0 && this.props.limit === 1) {
|
||||
minimum = total - 1;
|
||||
} else if (minimum < 0 && this.props.limit > 1) {
|
||||
@@ -82,13 +85,13 @@ export class Pager extends Component {
|
||||
let [minimum, maximum] = value.trim().split(/\s*[-\s,;]\s*/);
|
||||
minimum = parseInt(minimum, 10);
|
||||
maximum = maximum ? parseInt(maximum, 10) : minimum;
|
||||
let total = this.props.total;
|
||||
if (this.props.updateTotal && maximum > total) {
|
||||
total = await this.props.updateTotal();
|
||||
if (this.props.updateTotal) {
|
||||
// we don't know the real total, so we can't clamp
|
||||
return { minimum: minimum - 1, maximum };
|
||||
}
|
||||
return {
|
||||
minimum: clamp(minimum, 1, total) - 1,
|
||||
maximum: clamp(maximum, 1, total),
|
||||
minimum: clamp(minimum, 1, this.props.total) - 1,
|
||||
maximum: clamp(maximum, 1, this.props.total),
|
||||
};
|
||||
}
|
||||
/**
|
||||
|
||||
@@ -1795,13 +1795,14 @@ class DynamicList extends DataPoint {
|
||||
DynamicList.DEFAULT_LIMIT = 80;
|
||||
|
||||
export class DynamicRecordList extends DynamicList {
|
||||
setup(params) {
|
||||
setup(params, state) {
|
||||
super.setup(...arguments);
|
||||
|
||||
/** @type {Record[]} */
|
||||
this.records = [];
|
||||
this.data = params.data;
|
||||
this.countLimit = params.countLimit || this.constructor.WEB_SEARCH_READ_COUNT_LIMIT;
|
||||
this.countLimit =
|
||||
state.countLimit || params.countLimit || this.constructor.WEB_SEARCH_READ_COUNT_LIMIT;
|
||||
this.hasLimitedCount = false;
|
||||
}
|
||||
|
||||
@@ -1936,6 +1937,7 @@ export class DynamicRecordList extends DynamicList {
|
||||
return {
|
||||
...super.exportState(),
|
||||
offset: this.offset,
|
||||
countLimit: this.countLimit,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1952,6 +1954,7 @@ export class DynamicRecordList extends DynamicList {
|
||||
this.countLimit = Number.MAX_SAFE_INTEGER;
|
||||
this.hasLimitedCount = false;
|
||||
this.model.notify();
|
||||
return this.count;
|
||||
}
|
||||
|
||||
async load(params = {}) {
|
||||
@@ -2026,6 +2029,9 @@ export class DynamicRecordList extends DynamicList {
|
||||
* @returns {Promise<Record[]>}
|
||||
*/
|
||||
async _loadRecords() {
|
||||
if (this.countLimit < this.offset + this.limit) {
|
||||
this.countLimit = this.offset + this.limit;
|
||||
}
|
||||
const kwargs = {
|
||||
limit: this.limit,
|
||||
offset: this.offset,
|
||||
@@ -2065,6 +2071,7 @@ export class DynamicRecordList extends DynamicList {
|
||||
this.hasLimitedCount = true;
|
||||
this.count = length - 1;
|
||||
} else {
|
||||
this.hasLimitedCount = false;
|
||||
this.count = length;
|
||||
}
|
||||
|
||||
|
||||
@@ -284,18 +284,21 @@ QUnit.module("Components", ({ beforeEach }) => {
|
||||
});
|
||||
|
||||
QUnit.test("updateTotal props: click next", async function (assert) {
|
||||
let tempTotal = 10;
|
||||
const realTotal = 18;
|
||||
const pager = await makePager({
|
||||
offset: 0,
|
||||
limit: 5,
|
||||
total: 10,
|
||||
total: tempTotal,
|
||||
onUpdate(data) {
|
||||
pager.updateProps(Object.assign({}, data));
|
||||
},
|
||||
async updateTotal() {
|
||||
const total = 25;
|
||||
pager.updateProps({ total, updateTotal: undefined });
|
||||
return total;
|
||||
tempTotal = Math.min(realTotal, Math.max(tempTotal, data.offset + data.limit));
|
||||
const nextProps = { ...data, total: tempTotal };
|
||||
if (tempTotal === realTotal) {
|
||||
nextProps.updateTotal = undefined;
|
||||
}
|
||||
pager.updateProps(nextProps);
|
||||
},
|
||||
async updateTotal() {},
|
||||
});
|
||||
|
||||
assert.strictEqual(target.querySelector(".o_pager_value").innerText, "1-5");
|
||||
@@ -309,23 +312,31 @@ QUnit.module("Components", ({ beforeEach }) => {
|
||||
|
||||
await click(target, ".o_pager_next");
|
||||
assert.strictEqual(target.querySelector(".o_pager_value").innerText, "11-15");
|
||||
assert.strictEqual(target.querySelector(".o_pager_limit").innerText, "25");
|
||||
assert.strictEqual(target.querySelector(".o_pager_limit").innerText, "15+");
|
||||
assert.hasClass(target.querySelector(".o_pager_limit"), "o_pager_limit_fetch");
|
||||
|
||||
await click(target, ".o_pager_next");
|
||||
assert.strictEqual(target.querySelector(".o_pager_value").innerText, "16-18");
|
||||
assert.strictEqual(target.querySelector(".o_pager_limit").innerText, "18");
|
||||
assert.doesNotHaveClass(target.querySelector(".o_pager_limit"), "o_pager_limit_fetch");
|
||||
});
|
||||
|
||||
QUnit.test("updateTotal props: edit input", async function (assert) {
|
||||
let tempTotal = 10;
|
||||
const realTotal = 18;
|
||||
const pager = await makePager({
|
||||
offset: 0,
|
||||
limit: 5,
|
||||
total: 10,
|
||||
total: tempTotal,
|
||||
onUpdate(data) {
|
||||
pager.updateProps(Object.assign({}, data));
|
||||
},
|
||||
async updateTotal() {
|
||||
const total = 25;
|
||||
pager.updateProps({ total, updateTotal: undefined });
|
||||
return total;
|
||||
tempTotal = Math.min(realTotal, Math.max(tempTotal, data.offset + data.limit));
|
||||
const nextProps = { ...data, total: tempTotal };
|
||||
if (tempTotal === realTotal) {
|
||||
nextProps.updateTotal = undefined;
|
||||
}
|
||||
pager.updateProps(nextProps);
|
||||
},
|
||||
async updateTotal() {},
|
||||
});
|
||||
|
||||
assert.strictEqual(target.querySelector(".o_pager_value").innerText, "1-5");
|
||||
@@ -345,24 +356,20 @@ QUnit.module("Components", ({ beforeEach }) => {
|
||||
input = target.querySelector(".o_pager_counter input.o_pager_value");
|
||||
input.value = "3-20";
|
||||
await triggerEvents(input, null, ["change", "blur"]);
|
||||
assert.strictEqual(target.querySelector(".o_pager_value").innerText, "3-20");
|
||||
assert.strictEqual(target.querySelector(".o_pager_limit").innerText, "25");
|
||||
assert.strictEqual(target.querySelector(".o_pager_value").innerText, "3-18");
|
||||
assert.strictEqual(target.querySelector(".o_pager_limit").innerText, "18");
|
||||
assert.doesNotHaveClass(target.querySelector(".o_pager_limit"), "o_pager_limit_fetch");
|
||||
});
|
||||
|
||||
QUnit.test("updateTotal props: can use buttons even if single page", async function (assert) {
|
||||
QUnit.test("updateTotal props: can use next even if single page", async function (assert) {
|
||||
const pager = await makePager({
|
||||
offset: 0,
|
||||
limit: 5,
|
||||
total: 5,
|
||||
onUpdate(data) {
|
||||
pager.updateProps(Object.assign({}, data));
|
||||
},
|
||||
async updateTotal() {
|
||||
const total = 25;
|
||||
pager.updateProps({ total, updateTotal: undefined });
|
||||
return total;
|
||||
pager.updateProps({ ...data, total: 10 });
|
||||
},
|
||||
async updateTotal() {},
|
||||
});
|
||||
|
||||
assert.strictEqual(target.querySelector(".o_pager_value").innerText, "1-5");
|
||||
@@ -372,7 +379,7 @@ QUnit.module("Components", ({ beforeEach }) => {
|
||||
await click(target, ".o_pager_next");
|
||||
|
||||
assert.strictEqual(target.querySelector(".o_pager_value").innerText, "6-10");
|
||||
assert.strictEqual(target.querySelector(".o_pager_limit").innerText, "25");
|
||||
assert.doesNotHaveClass(target.querySelector(".o_pager_limit"), "o_pager_limit_fetch");
|
||||
assert.strictEqual(target.querySelector(".o_pager_limit").innerText, "10+");
|
||||
assert.hasClass(target.querySelector(".o_pager_limit"), "o_pager_limit_fetch");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1167,6 +1167,151 @@ QUnit.module("Views", (hooks) => {
|
||||
assert.verifySteps(["search_count"]);
|
||||
});
|
||||
|
||||
QUnit.test("pager, ungrouped, with count limit reached, click next", async (assert) => {
|
||||
patchWithCleanup(DynamicRecordList, { WEB_SEARCH_READ_COUNT_LIMIT: 3 });
|
||||
|
||||
await makeView({
|
||||
type: "kanban",
|
||||
resModel: "partner",
|
||||
serverData,
|
||||
arch: `
|
||||
<kanban limit="2">
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div><field name="foo"/></div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>`,
|
||||
async mockRPC(route, { method }) {
|
||||
assert.step(method);
|
||||
},
|
||||
});
|
||||
|
||||
assert.containsN(target, ".o_kanban_record:not(.o_kanban_ghost)", 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"]);
|
||||
|
||||
await click(target.querySelector(".o_pager_next"));
|
||||
assert.containsN(target, ".o_kanban_record:not(.o_kanban_ghost)", 2);
|
||||
assert.strictEqual(target.querySelector(".o_pager_value").innerText, "3-4");
|
||||
assert.strictEqual(target.querySelector(".o_pager_limit").innerText, "4");
|
||||
assert.verifySteps(["web_search_read"]);
|
||||
});
|
||||
|
||||
QUnit.test("pager, ungrouped, with count limit reached, click next (2)", async (assert) => {
|
||||
patchWithCleanup(DynamicRecordList, { WEB_SEARCH_READ_COUNT_LIMIT: 3 });
|
||||
serverData.models.partner.records.push({ id: 5, foo: "xxx" });
|
||||
|
||||
await makeView({
|
||||
type: "kanban",
|
||||
resModel: "partner",
|
||||
serverData,
|
||||
arch: `
|
||||
<kanban limit="2">
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div><field name="foo"/></div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>`,
|
||||
async mockRPC(route, { method }) {
|
||||
assert.step(method);
|
||||
},
|
||||
});
|
||||
|
||||
assert.containsN(target, ".o_kanban_record:not(.o_kanban_ghost)", 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"]);
|
||||
|
||||
await click(target.querySelector(".o_pager_next"));
|
||||
assert.containsN(target, ".o_kanban_record:not(.o_kanban_ghost)", 2);
|
||||
assert.strictEqual(target.querySelector(".o_pager_value").innerText, "3-4");
|
||||
assert.strictEqual(target.querySelector(".o_pager_limit").innerText, "4+");
|
||||
assert.verifySteps(["web_search_read"]);
|
||||
|
||||
await click(target.querySelector(".o_pager_next"));
|
||||
assert.containsOnce(target, ".o_kanban_record:not(.o_kanban_ghost)");
|
||||
assert.strictEqual(target.querySelector(".o_pager_value").innerText, "5-5");
|
||||
assert.strictEqual(target.querySelector(".o_pager_limit").innerText, "5");
|
||||
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.partner.records.push({ id: 5, foo: "xxx" });
|
||||
|
||||
await makeView({
|
||||
type: "kanban",
|
||||
resModel: "partner",
|
||||
serverData,
|
||||
arch: `
|
||||
<kanban limit="2">
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div><field name="foo"/></div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>`,
|
||||
async mockRPC(route, { method }) {
|
||||
assert.step(method);
|
||||
},
|
||||
});
|
||||
|
||||
assert.containsN(target, ".o_kanban_record:not(.o_kanban_ghost)", 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"]);
|
||||
|
||||
await click(target.querySelector(".o_pager_previous"));
|
||||
assert.containsOnce(target, ".o_kanban_record:not(.o_kanban_ghost)");
|
||||
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.partner.records.push({ id: 5, foo: "xxx" });
|
||||
|
||||
await makeView({
|
||||
type: "kanban",
|
||||
resModel: "partner",
|
||||
serverData,
|
||||
arch: `
|
||||
<kanban limit="2">
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div><field name="foo"/></div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>`,
|
||||
async mockRPC(route, { method }) {
|
||||
assert.step(method);
|
||||
},
|
||||
});
|
||||
|
||||
assert.containsN(target, ".o_kanban_record:not(.o_kanban_ghost)", 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"]);
|
||||
|
||||
await click(target, ".o_pager_value");
|
||||
await editInput(target, "input.o_pager_value", "2-4");
|
||||
assert.containsN(target, ".o_kanban_record:not(.o_kanban_ghost)", 3);
|
||||
assert.strictEqual(target.querySelector(".o_pager_value").innerText, "2-4");
|
||||
assert.strictEqual(target.querySelector(".o_pager_limit").innerText, "4+");
|
||||
assert.verifySteps(["web_search_read"]);
|
||||
|
||||
await click(target, ".o_pager_value");
|
||||
await editInput(target, "input.o_pager_value", "2-14");
|
||||
assert.containsN(target, ".o_kanban_record:not(.o_kanban_ghost)", 4);
|
||||
assert.strictEqual(target.querySelector(".o_pager_value").innerText, "2-5");
|
||||
assert.strictEqual(target.querySelector(".o_pager_limit").innerText, "5");
|
||||
assert.verifySteps(["web_search_read"]);
|
||||
});
|
||||
|
||||
QUnit.test("count_limit attrs set in arch", async (assert) => {
|
||||
await makeView({
|
||||
type: "kanban",
|
||||
@@ -1197,47 +1342,6 @@ 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: `<kanban limit="3">
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div>
|
||||
<div><a role="menuitem" type="delete" class="dropdown-item">Delete</a></div>
|
||||
<field name="foo"/>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>`,
|
||||
});
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -5684,6 +5684,114 @@ QUnit.module("Views", (hooks) => {
|
||||
assert.verifySteps(["web_search_read"]);
|
||||
});
|
||||
|
||||
QUnit.test("pager, ungrouped, with count limit reached, click next", async function (assert) {
|
||||
patchWithCleanup(DynamicRecordList, { WEB_SEARCH_READ_COUNT_LIMIT: 3 });
|
||||
|
||||
let expectedCountLimit = 4;
|
||||
await makeView({
|
||||
type: "list",
|
||||
resModel: "foo",
|
||||
serverData,
|
||||
arch: '<tree limit="2"><field name="foo"/><field name="bar"/></tree>',
|
||||
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 = 5;
|
||||
await click(target.querySelector(".o_pager_next"));
|
||||
assert.containsN(target, ".o_data_row", 2);
|
||||
assert.strictEqual(target.querySelector(".o_pager_value").innerText, "3-4");
|
||||
assert.strictEqual(target.querySelector(".o_pager_limit").innerText, "4");
|
||||
assert.verifySteps(["web_search_read"]);
|
||||
});
|
||||
|
||||
QUnit.test("pager, ungrouped, with count limit reached, click next (2)", 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: '<tree limit="2"><field name="foo"/><field name="bar"/></tree>',
|
||||
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 = 5;
|
||||
await click(target.querySelector(".o_pager_next"));
|
||||
assert.containsN(target, ".o_data_row", 2);
|
||||
assert.strictEqual(target.querySelector(".o_pager_value").innerText, "3-4");
|
||||
assert.strictEqual(target.querySelector(".o_pager_limit").innerText, "4+");
|
||||
assert.verifySteps(["web_search_read"]);
|
||||
|
||||
expectedCountLimit = 7;
|
||||
await click(target.querySelector(".o_pager_next"));
|
||||
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(["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" });
|
||||
|
||||
let expectedCountLimit = 4;
|
||||
await makeView({
|
||||
type: "list",
|
||||
resModel: "foo",
|
||||
serverData,
|
||||
arch: '<tree limit="2"><field name="foo"/><field name="bar"/></tree>',
|
||||
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 = 5;
|
||||
await click(target, ".o_pager_value");
|
||||
await editInput(target, "input.o_pager_value", "2-4");
|
||||
assert.containsN(target, ".o_data_row", 3);
|
||||
assert.strictEqual(target.querySelector(".o_pager_value").innerText, "2-4");
|
||||
assert.strictEqual(target.querySelector(".o_pager_limit").innerText, "4+");
|
||||
assert.verifySteps(["web_search_read"]);
|
||||
|
||||
expectedCountLimit = 15;
|
||||
await click(target, ".o_pager_value");
|
||||
await editInput(target, "input.o_pager_value", "2-14");
|
||||
assert.containsN(target, ".o_data_row", 4);
|
||||
assert.strictEqual(target.querySelector(".o_pager_value").innerText, "2-5");
|
||||
assert.strictEqual(target.querySelector(".o_pager_limit").innerText, "5");
|
||||
assert.verifySteps(["web_search_read"]);
|
||||
});
|
||||
|
||||
QUnit.test("pager, ungrouped, with count equals count limit", async function (assert) {
|
||||
patchWithCleanup(DynamicRecordList, { WEB_SEARCH_READ_COUNT_LIMIT: 4 });
|
||||
|
||||
|
||||
Reference in New Issue
Block a user