[FIX] web: kanban column counter when grouped by a date
Before this commit, if the kanban was grouped by a date field, and have an aggregate, the column counter was always 0. Now, the column counter has the correct value. closes odoo/odoo#133114 X-original-commit: ea3809a480c29eafd6ab8433d5ae0e378b1d9967 Signed-off-by: Aaron Bohy (aab) <aab@odoo.com> Signed-off-by: Jorge Pinna Puissant (jpp) <jpp@odoo.com>
This commit is contained in:
@@ -230,6 +230,7 @@ export class DynamicGroupList extends DynamicList {
|
||||
[this.groupByField.name]: [id, groupName],
|
||||
value: id,
|
||||
displayName: groupName,
|
||||
rawValue: [id, groupName],
|
||||
};
|
||||
|
||||
const group = this._createGroupDatapoint(data);
|
||||
|
||||
@@ -408,7 +408,7 @@ export class RelationalModel extends Model {
|
||||
groupData[config.groupBy[0]],
|
||||
group.range
|
||||
);
|
||||
group.rawValue = groupData[groupByField.name];
|
||||
group.rawValue = groupData[config.groupBy];
|
||||
group.displayName = getDisplayNameFromGroupData(
|
||||
groupByField,
|
||||
groupData[config.groupBy[0]]
|
||||
|
||||
@@ -14,15 +14,7 @@ const FALSE = Symbol("False");
|
||||
*/
|
||||
|
||||
function _findGroup(groups, groupByField, value) {
|
||||
return (
|
||||
groups.find((s) => {
|
||||
if (Array.isArray(s[groupByField.name])) {
|
||||
return s[groupByField.name][0] === value;
|
||||
} else {
|
||||
return s[groupByField.name] === value;
|
||||
}
|
||||
}) || {}
|
||||
);
|
||||
return groups.find((g) => g[groupByField.name] === value) || {};
|
||||
}
|
||||
|
||||
function _createFilterDomain(fieldName, bars, value) {
|
||||
@@ -50,12 +42,13 @@ class ProgressBarState {
|
||||
getGroupInfo(group) {
|
||||
if (!this._groupsInfo[group.id]) {
|
||||
if (
|
||||
!Object.keys(_findGroup(this._aggregateValues, group.groupByField, group.value))
|
||||
.length
|
||||
!Object.keys(
|
||||
_findGroup(this._aggregateValues, group.groupByField, group.serverValue)
|
||||
).length
|
||||
) {
|
||||
this._aggregateValues.push({
|
||||
...group.aggregates,
|
||||
[group.groupByField.name]: group.value,
|
||||
[group.groupByField.name]: group.serverValue,
|
||||
});
|
||||
}
|
||||
let groupValue = group.displayName || group.value;
|
||||
@@ -90,14 +83,14 @@ class ProgressBarState {
|
||||
});
|
||||
|
||||
// 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
|
||||
if (this.activeBars[group.serverValue]) {
|
||||
this.activeBars[group.serverValue].count = bars.find(
|
||||
(x) => x.value === this.activeBars[group.serverValue].value
|
||||
).count;
|
||||
|
||||
if (this.activeBars[group.value].count === 0) {
|
||||
if (this.activeBars[group.serverValue].count === 0) {
|
||||
group.applyFilter(undefined).then(() => {
|
||||
delete this.activeBars[group.value];
|
||||
delete this.activeBars[group.serverValue];
|
||||
group.model.notify();
|
||||
});
|
||||
}
|
||||
@@ -105,10 +98,10 @@ class ProgressBarState {
|
||||
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.activeBars[group.serverValue].aggregates = _findGroup(
|
||||
this._aggregateValues,
|
||||
group.groupByField,
|
||||
group.value
|
||||
group.serverValue
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -116,7 +109,7 @@ class ProgressBarState {
|
||||
const self = this;
|
||||
const progressBar = {
|
||||
get activeBar() {
|
||||
return self.activeBars[group.value]?.value || null;
|
||||
return self.activeBars[group.serverValue]?.value || null;
|
||||
},
|
||||
bars,
|
||||
};
|
||||
@@ -129,20 +122,20 @@ class ProgressBarState {
|
||||
getAggregateValue(group, aggregateField) {
|
||||
const title = aggregateField ? aggregateField.string : _t("Count");
|
||||
let value = 0;
|
||||
if (!this.activeBars[group.value]) {
|
||||
if (!this.activeBars[group.serverValue]) {
|
||||
value = group.count;
|
||||
if (aggregateField) {
|
||||
value =
|
||||
_findGroup(this._aggregateValues, group.groupByField, group.value)[
|
||||
_findGroup(this._aggregateValues, group.groupByField, group.serverValue)[
|
||||
aggregateField.name
|
||||
] || 0;
|
||||
}
|
||||
} else {
|
||||
value = this.activeBars[group.value].count;
|
||||
value = this.activeBars[group.serverValue].count;
|
||||
if (aggregateField) {
|
||||
value =
|
||||
(this.activeBars[group.value]?.aggregates &&
|
||||
this.activeBars[group.value]?.aggregates[aggregateField.name]) ||
|
||||
(this.activeBars[group.serverValue]?.aggregates &&
|
||||
this.activeBars[group.serverValue]?.aggregates[aggregateField.name]) ||
|
||||
0;
|
||||
}
|
||||
}
|
||||
@@ -153,11 +146,11 @@ class ProgressBarState {
|
||||
const group = this.model.root.groups.find((group) => group.id === groupId);
|
||||
const progressBar = this.getGroupInfo(group);
|
||||
const nextActiveBar = {};
|
||||
if (bar.value && this.activeBars[group.value]?.value !== bar.value) {
|
||||
if (bar.value && this.activeBars[group.serverValue]?.value !== bar.value) {
|
||||
nextActiveBar.value = bar.value;
|
||||
} else {
|
||||
group.applyFilter(undefined).then(() => {
|
||||
delete this.activeBars[group.value];
|
||||
delete this.activeBars[group.serverValue];
|
||||
group.model.notify();
|
||||
});
|
||||
return;
|
||||
@@ -181,7 +174,7 @@ class ProgressBarState {
|
||||
proms.push(this._updateAggregateGroup(group, bars, nextActiveBar));
|
||||
}
|
||||
await Promise.all(proms);
|
||||
this.activeBars[group.value] = nextActiveBar;
|
||||
this.activeBars[group.serverValue] = nextActiveBar;
|
||||
}
|
||||
|
||||
_updateAggregateGroup(group, bars, activeBar) {
|
||||
@@ -201,10 +194,10 @@ class ProgressBarState {
|
||||
.webReadGroup(resModel, domain, fields, groupBy, kwargs)
|
||||
.then((res) => {
|
||||
if (res.length) {
|
||||
const resGroup = _findGroup(res.groups, group.groupByField, group.value);
|
||||
const resGroup = _findGroup(res.groups, group.groupByField, group.serverValue);
|
||||
activeBar.aggregates = {
|
||||
...resGroup,
|
||||
[group.groupByField.name]: group.value,
|
||||
[group.groupByField.name]: group.serverValue,
|
||||
};
|
||||
}
|
||||
});
|
||||
@@ -219,16 +212,16 @@ class ProgressBarState {
|
||||
|
||||
// If the selected bar is empty, remove the selection
|
||||
for (const group of this.model.root.groups) {
|
||||
if (this.activeBars[group.value] && group.list.count === 0) {
|
||||
if (this.activeBars[group.serverValue] && group.list.count === 0) {
|
||||
this.selectBar(group.id, { value: null });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateAggreagteGroup(group) {
|
||||
if (group && this.activeBars[group.value]) {
|
||||
if (group && this.activeBars[group.serverValue]) {
|
||||
const { bars } = this.getGroupInfo(group);
|
||||
this._updateAggregateGroup(group, bars, this.activeBars[group.value]);
|
||||
this._updateAggregateGroup(group, bars, this.activeBars[group.serverValue]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,7 +237,9 @@ class ProgressBarState {
|
||||
groupBy,
|
||||
kwargs
|
||||
);
|
||||
this._aggregateValues = res.groups;
|
||||
this._aggregateValues = res.groups.map((r) => {
|
||||
return { ...r, [firstGroupByName]: r[groupBy] };
|
||||
});
|
||||
}
|
||||
|
||||
async _updateProgressBar() {
|
||||
@@ -282,9 +277,9 @@ class ProgressBarState {
|
||||
? group.count - Object.values(counts).reduce((a, b) => a + b, 0)
|
||||
: group.count;
|
||||
|
||||
if (this.activeBars[group.value]) {
|
||||
this.activeBars[group.value].count = groupInfo.bars.find(
|
||||
(x) => x.value === this.activeBars[group.value].value
|
||||
if (this.activeBars[group.serverValue]) {
|
||||
this.activeBars[group.serverValue].count = groupInfo.bars.find(
|
||||
(x) => x.value === this.activeBars[group.serverValue].value
|
||||
).count;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ import { AnimatedNumber } from "@web/views/view_components/animated_number";
|
||||
|
||||
import { Component, onWillRender, xml } from "@odoo/owl";
|
||||
import { SampleServer } from "@web/model/sample_server";
|
||||
import { KanbanRenderer } from "@web/views/kanban/kanban_renderer";
|
||||
|
||||
const serviceRegistry = registry.category("services");
|
||||
const viewWidgetRegistry = registry.category("view_widgets");
|
||||
@@ -9897,6 +9898,68 @@ QUnit.module("Views", (hooks) => {
|
||||
]);
|
||||
});
|
||||
|
||||
QUnit.test(
|
||||
"drag & drop records grouped by date with progressbar with aggregates",
|
||||
async (assert) => {
|
||||
serverData.models.partner.records[0].date = "2010-11-30";
|
||||
serverData.models.partner.records[1].date = "2010-11-30";
|
||||
serverData.models.partner.records[2].date = "2010-10-30";
|
||||
serverData.models.partner.records[3].date = "2010-10-30";
|
||||
|
||||
// Usually kanban views grouped by a date, cannot drag and drop.
|
||||
// There are some overrides that allow the drag and drop of dates (CRM forecast for instance).
|
||||
// This patch is done to simulate these overrides.
|
||||
patchWithCleanup(KanbanRenderer.prototype, {
|
||||
isMovableField() {
|
||||
return true;
|
||||
},
|
||||
});
|
||||
|
||||
await makeView({
|
||||
type: "kanban",
|
||||
resModel: "partner",
|
||||
serverData,
|
||||
arch: `
|
||||
<kanban>
|
||||
<progressbar field="foo" colors='{"yop": "success", "gnap": "warning", "blip": "danger"}' sum_field="int_field"/>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div>
|
||||
<field name="int_field"/>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>`,
|
||||
groupBy: ["date:month"],
|
||||
async mockRPC(route, args) {
|
||||
assert.step(args.method || route);
|
||||
},
|
||||
});
|
||||
|
||||
assert.deepEqual(getCounters(), ["13", "19"]);
|
||||
|
||||
await dragAndDrop(
|
||||
".o_kanban_group:first-child .o_kanban_record",
|
||||
".o_kanban_group:nth-child(2)"
|
||||
);
|
||||
|
||||
assert.deepEqual(getCounters(), ["-4", "36"]);
|
||||
|
||||
assert.verifySteps([
|
||||
"get_views",
|
||||
"web_read_group",
|
||||
"read_progress_bar",
|
||||
"unity_web_search_read",
|
||||
"unity_web_search_read",
|
||||
"write",
|
||||
"read_progress_bar",
|
||||
"web_read_group",
|
||||
"/web/dataset/resequence",
|
||||
"read",
|
||||
]);
|
||||
}
|
||||
);
|
||||
|
||||
QUnit.test("progress bar subgroup count recompute", async (assert) => {
|
||||
await makeView({
|
||||
type: "kanban",
|
||||
|
||||
Reference in New Issue
Block a user