From 5cf55f7f33d7708ea8fc75e7e215b6e74e89c4c2 Mon Sep 17 00:00:00 2001 From: Jorge Pinna Puissant Date: Tue, 25 Jul 2023 11:08:24 +0200 Subject: [PATCH] [FIX] web: Kanban progressbar update count after domain change - open a grouped kanban view with progressbar; - select a progressbar; - the records are filtered and the count/aggregate is updated; - change the filter/domain that will reduce/increase the filtered records. Before this commit, the records are correctly update but the count/aggregate is not update. Now, the count/aggregate of a selected progressbar is updated if the domain changes. task-3422009 X-original-commit: 95a94e0d928729bbbc80a627f816f9e575121f8d --- .../src/views/kanban/progress_bar_hook.js | 41 ++++-- .../tests/views/kanban/kanban_view_tests.js | 122 ++++++++++++++++++ 2 files changed, 150 insertions(+), 13 deletions(-) diff --git a/addons/web/static/src/views/kanban/progress_bar_hook.js b/addons/web/static/src/views/kanban/progress_bar_hook.js index a96ef80aa2a..c5633cab752 100644 --- a/addons/web/static/src/views/kanban/progress_bar_hook.js +++ b/addons/web/static/src/views/kanban/progress_bar_hook.js @@ -89,14 +89,28 @@ class ProgressBarState { color: "200", }); - if ( - this.activeBars[group.value] && - bars.find((b) => b.value === this.activeBars[group.value].value).count === 0 - ) { - group.applyFilter(undefined).then(() => { - delete this.activeBars[group.value]; - group.model.notify(); - }); + // Update activeBars count and aggreagates + if (this.activeBars[group.value]) { + this.activeBars[group.value].count = bars.find( + (x) => x.value === this.activeBars[group.value].value + ).count; + + if (this.activeBars[group.value].count === 0) { + group.applyFilter(undefined).then(() => { + delete this.activeBars[group.value]; + group.model.notify(); + }); + } + + if (this._aggregateFields.length) { + //recompute the aggregates is not necessary + //the web_read_group was already done with the correct domain (containing the applied filter) + this.activeBars[group.value].aggregates = _findGroup( + this._aggregateValues, + group.groupByField, + group.value + ); + } } const self = this; @@ -164,17 +178,16 @@ class ProgressBarState { }) ); if (this._aggregateFields.length) { - proms.push(this._updateAggregateGroup(group, nextActiveBar)); + proms.push(this._updateAggregateGroup(group, bars, nextActiveBar)); } await Promise.all(proms); this.activeBars[group.value] = nextActiveBar; } - _updateAggregateGroup(group, activeBar) { - const groupInfo = this.getGroupInfo(group); + _updateAggregateGroup(group, bars, activeBar) { const filterDomain = _createFilterDomain( this.progressAttributes.fieldName, - groupInfo.bars, + bars, activeBar.value ); const { context, groupBy, resModel } = this.model.root; @@ -214,7 +227,8 @@ class ProgressBarState { updateAggreagteGroup(group) { if (group && this.activeBars[group.value]) { - this._updateAggregateGroup(group, this.activeBars[group.value]); + const { bars } = this.getGroupInfo(group); + this._updateAggregateGroup(group, bars, this.activeBars[group.value]); } } @@ -294,6 +308,7 @@ class ProgressBarState { context, }); this._groupsInfo = {}; + this._aggregateValues = []; this._pbCounts = res; } } diff --git a/addons/web/static/tests/views/kanban/kanban_view_tests.js b/addons/web/static/tests/views/kanban/kanban_view_tests.js index 4ee9f3bc0f6..757773a6c25 100644 --- a/addons/web/static/tests/views/kanban/kanban_view_tests.js +++ b/addons/web/static/tests/views/kanban/kanban_view_tests.js @@ -9849,6 +9849,128 @@ QUnit.module("Views", (hooks) => { } ); + QUnit.test("progress bar recompute after filter selection", async (assert) => { + serverData.models.partner.records.push({ + foo: "yop", + bar: true, + qux: 100, + }); + serverData.models.partner.records.push({ + foo: "yop", + bar: true, + qux: 100, + }); + serverData.models.partner.records.push({ + foo: "yop", + bar: true, + qux: 100, + }); + + const kanban = await makeView({ + type: "kanban", + resModel: "partner", + serverData, + arch: ` + + +
+ +
+
+
`, + groupBy: ["bar"], + async mockRPC(route, args) { + assert.step(args.method || route); + }, + }); + + assert.deepEqual(getTooltips(), ["1 blip", "4 yop", "1 gnap", "1 blip"]); + assert.deepEqual(getCounters(), ["1", "6"]); + assert.verifySteps([ + "get_views", + "web_read_group", + "read_progress_bar", + "unity_web_search_read", + "unity_web_search_read", + ]); + + await click(getColumn(1), ".progress-bar.bg-success"); + + assert.deepEqual(getTooltips(), ["1 blip", "4 yop", "1 gnap", "1 blip"]); + assert.deepEqual(getCounters(), ["1", "4"]); + assert.verifySteps(["unity_web_search_read"]); + + // Add searchdomain to something restricting progressbars' values (records still in filtered group) + await reload(kanban, { domain: [["qux", "=", 100]], groupBy: ["bar"] }); + assert.deepEqual(getTooltips(), ["3 yop"]); + assert.deepEqual(getCounters(), ["3"]); + assert.verifySteps(["web_read_group", "read_progress_bar", "unity_web_search_read"]); + }); + + QUnit.test("progress bar recompute after filter selection (aggregates)", async (assert) => { + serverData.models.partner.records.push({ + foo: "yop", + bar: true, + qux: 100, + int_field: 100, + }); + serverData.models.partner.records.push({ + foo: "yop", + bar: true, + qux: 100, + int_field: 200, + }); + serverData.models.partner.records.push({ + foo: "yop", + bar: true, + qux: 100, + int_field: 300, + }); + + const kanban = await makeView({ + type: "kanban", + resModel: "partner", + serverData, + arch: ` + + +
+ +
+
+
`, + groupBy: ["bar"], + async mockRPC(route, args) { + assert.step(args.method || route); + }, + }); + + assert.deepEqual(getTooltips(), ["1 blip", "4 yop", "1 gnap", "1 blip"]); + assert.deepEqual(getCounters(), ["-4", "636"]); + assert.verifySteps([ + "get_views", + "web_read_group", + "read_progress_bar", + "unity_web_search_read", + "unity_web_search_read", + ]); + + await click(getColumn(1), ".progress-bar.bg-success"); + + assert.deepEqual(getTooltips(), ["1 blip", "4 yop", "1 gnap", "1 blip"]); + assert.deepEqual(getCounters(), ["-4", "610"]); + assert.verifySteps([ + "web_read_group", // recomputes aggregates + "unity_web_search_read", + ]); + + // Add searchdomain to something restricting progressbars' values (records still in filtered group) + await reload(kanban, { domain: [["qux", "=", 100]], groupBy: ["bar"] }); + assert.deepEqual(getTooltips(), ["3 yop"]); + assert.deepEqual(getCounters(), ["600"]); + assert.verifySteps(["web_read_group", "read_progress_bar", "unity_web_search_read"]); + }); + QUnit.test("load more should load correct records after drag&drop event", async (assert) => { // Add a sequence number and initialize serverData.models.partner.records.forEach((el, i) => (el.sequence = i));