From ab5a126f1010345e83e30135c0e47c6af0cebe21 Mon Sep 17 00:00:00 2001 From: FrancoisGe Date: Wed, 9 Nov 2022 10:39:14 +0000 Subject: [PATCH] [FIX] web: empty group when changing page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before this commit, in a grouped list view, it was possible to have empty groups when changing pages. Why: Before this commit, if a grouped list performs a load, then it is checked if its previousParams are equal to the current one. If so, we keep all the old groups empty. This requirement is related to the kanban view, so we will move it to the kanban model. The kanban view needs it when we archive data but don't want to delete groups (colomns). So we perform a load but we don't want to delete the empty columns. How to reproduce: - Go to a grouped list view - Click on a record - Return to the list view using the breadcrumb - Go to the next page Before this commit: The groups on the first page are always present with those on the second page. The groups on the first page are empty. After this commit: We only have the groups on the first page. closes odoo/odoo#105488 X-original-commit: 04467197b9ec0851e3f9f7a74d1b97c5e27420bc Signed-off-by: Julien Mougenot (jum) Signed-off-by: Georis François (fge) --- .../static/src/views/kanban/kanban_model.js | 29 +++++++++++- .../web/static/src/views/relational_model.js | 16 ------- .../web/static/tests/views/list_view_tests.js | 44 +++++++++++++++++++ 3 files changed, 71 insertions(+), 18 deletions(-) diff --git a/addons/web/static/src/views/kanban/kanban_model.js b/addons/web/static/src/views/kanban/kanban_model.js index 545dccc4656..7c22139c828 100644 --- a/addons/web/static/src/views/kanban/kanban_model.js +++ b/addons/web/static/src/views/kanban/kanban_model.js @@ -327,8 +327,9 @@ class KanbanGroup extends Group { } export class KanbanDynamicGroupList extends DynamicGroupList { - setup() { + setup(params, state) { super.setup(...arguments); + this.previousParams = state.previousParams || "[]"; this.groupBy = this.groupBy.slice(0, 1); @@ -352,6 +353,17 @@ export class KanbanDynamicGroupList extends DynamicGroupList { return [...super.fieldNames, ...this.sumFields]; } + get currentParams() { + return JSON.stringify([this.domain, this.groupBy]); + } + + exportState() { + return { + ...super.exportState(), + previousParams: this.currentParams, + }; + } + /** * After a reload, empty groups are expcted to disappear from the web_read_group. * However, if the parameters are the same (domain + groupBy), we want to @@ -360,7 +372,20 @@ export class KanbanDynamicGroupList extends DynamicGroupList { * @override */ async load() { - await this._loadWithProgressData(super.load()); + const load = async () => { + const previousGroups = this.groups.map((g, i) => [g, i]); + await super.load(); + if (this.previousParams === this.currentParams) { + for (const [group, index] of previousGroups) { + const newGroup = this.groups.find((g) => group.valueEquals(g.value)); + if (!group.deleted && !newGroup) { + group.empty(); + this.groups.splice(index, 0, group); + } + } + } + }; + await this._loadWithProgressData(load()); } /** diff --git a/addons/web/static/src/views/relational_model.js b/addons/web/static/src/views/relational_model.js index badacbf650a..60e3f90312a 100644 --- a/addons/web/static/src/views/relational_model.js +++ b/addons/web/static/src/views/relational_model.js @@ -1429,7 +1429,6 @@ class DynamicList extends DataPoint { this.limit = params.limit || state.limit || this.constructor.DEFAULT_LIMIT; this.isDomainSelected = false; this.loadedCount = state.loadedCount || 0; - this.previousParams = state.previousParams || "[]"; this.editedRecord = null; this.onCreateRecord = params.onCreateRecord || (() => {}); @@ -1469,10 +1468,6 @@ class DynamicList extends DataPoint { // Getters // ------------------------------------------------------------------------- - get currentParams() { - return JSON.stringify([this.domain, this.groupBy]); - } - get firstGroupBy() { return this.groupBy[0] || false; } @@ -1539,7 +1534,6 @@ class DynamicList extends DataPoint { limit: this.limit, loadedCount: this.records.length, orderBy: this.orderBy, - previousParams: this.currentParams, }; } @@ -2253,18 +2247,8 @@ export class DynamicGroupList extends DynamicList { this.limit = params.limit === undefined ? this.limit : params.limit; this.offset = params.offset === undefined ? this.offset : params.offset; /** @type {[Group, number][]} */ - const previousGroups = this.groups.map((g, i) => [g, i]); this.groups = await this._loadGroups(); await Promise.all(this.groups.map((group) => group.load())); - if (this.previousParams === this.currentParams) { - for (const [group, index] of previousGroups) { - const newGroup = this.groups.find((g) => group.valueEquals(g.value)); - if (!group.deleted && !newGroup) { - group.empty(); - this.groups.splice(index, 0, group); - } - } - } } get nbTotalRecords() { diff --git a/addons/web/static/tests/views/list_view_tests.js b/addons/web/static/tests/views/list_view_tests.js index d3aeff61938..e5b9226ad18 100644 --- a/addons/web/static/tests/views/list_view_tests.js +++ b/addons/web/static/tests/views/list_view_tests.js @@ -15179,6 +15179,50 @@ QUnit.module("Views", (hooks) => { assert.containsN(target, ".o_data_row", 3); }); + QUnit.test( + "go to the next page after leaving and coming back to a grouped list view", + async (assert) => { + serverData.views = { + "foo,false,list": ``, + "foo,false,search": "", + "foo,false,form": "
", + }; + const webClient = await createWebClient({ serverData }); + await doAction(webClient, { + name: "Partners", + res_model: "foo", + type: "ir.actions.act_window", + views: [ + [false, "list"], + [false, "form"], + ], + context: { + group_by: ["bar"], + }, + }); + assert.containsOnce(target, ".o_list_view"); + assert.containsOnce(target, ".o_group_header"); + assert.strictEqual(target.querySelector(".o_group_header").textContent, "No (1) "); + + // unfold the second group + await click(target, ".o_group_header"); + assert.containsOnce(target, ".o_group_open"); + assert.containsOnce(target, ".o_data_row"); + + // open a record and go back + await click(target.querySelector(".o_data_cell")); + assert.containsOnce(target, ".o_form_view"); + + await click(target.querySelector(".breadcrumb-item a")); + assert.containsOnce(target, ".o_group_header"); + assert.strictEqual(target.querySelector(".o_group_header").textContent, "No (1) "); + + await pagerNext(target); + assert.containsOnce(target, ".o_group_header"); + assert.strictEqual(target.querySelector(".o_group_header").textContent, "Yes (3) "); + } + ); + QUnit.test("keep order after grouping", async (assert) => { serverData.models.foo.fields.foo.sortable = true; await makeView({