[FIX] web: fix deleted personnal stage reappear after deletion

This commit's purpose is to fix the re apparition of personnal stage on
the todo app when personnal stages are deleted one after the other.

Step to reproduce:
-login as Marc demo
-open todo
-delete any personnal stage without any todo in it
-delete any personnal stage with at least one todo in it

The personnal stage deleted first is now present again in the kanban
view. Note that it is only a frontend bug. The record has been correctly
removed from the db, and any action with it will trigger a cache miss
exception and reloading the view completly will removed those ghost
stages definitly.

Source of the problem:
The problem is that the deletion is only reloading the view completly
when a record with child data is removed. More precisly, the
_deleteGroup function of the dynamic list triggers an rpc call to update
the config of the component only when a record with child data is
deleted, and that data need to be switched to another record, while when
it is an empty record, the record is simply removed from the group
field of the list. The issue is that there is thus a mismatch between
the group in the list.config.groups and the list.group. And when the
config is updated, only the list.config.groups is used to update the
config, meaning it potentially still contains element that were already
deleted.

Solution:
Doing a check up on the list.group to ensure that any deleted element is
also removed from the config when an update is triggered.
Note: I dont why Mitchel admin did not trigger the bug. Code wise, it
should happends no matter the access right of the connectedd user.

Version affected:
17.0+

task - 3553101
https://www.odoo.com/web#id=3553101&menu_id=4720&cids=1&action=333&active_id=4105&model=project.task&view_type=form

closes odoo/odoo#142536

Signed-off-by: Xavier Bol (xbo) <xbo@odoo.com>
This commit is contained in:
damr
2024-02-13 10:07:50 +00:00
committed by Xavier Bol (xbo)
parent 83bc38bd94
commit bf6193fac9
2 changed files with 54 additions and 4 deletions
@@ -249,11 +249,11 @@ export class DynamicGroupList extends DynamicList {
async _deleteGroups(groups) {
const shouldReload = groups.some((g) => g.count > 0);
await this._unlinkGroups(groups);
const configGroups = { ...this.config.groups };
for (const group of groups) {
delete configGroups[group.value];
}
if (shouldReload) {
const configGroups = { ...this.config.groups };
for (const group of groups) {
delete configGroups[group.value];
}
await this.model._updateConfig(
this.config,
{ groups: configGroups },
@@ -263,6 +263,7 @@ export class DynamicGroupList extends DynamicList {
for (const group of groups) {
this._removeGroup(group);
}
this.model._updateConfig(this.config, { groups: configGroups }, { reload: false });
}
}
@@ -6256,6 +6256,55 @@ QUnit.module("Views", (hooks) => {
);
});
QUnit.test("delete an empty column, then a column with records.", async (assert) => {
patchDialog((_cls, props) => props.confirm());
let firstLoad = true;
await makeView({
type: "kanban",
resModel: "partner",
serverData,
arch:
'<kanban on_create="quick_create">' +
'<field name="product_id"/>' +
'<templates><t t-name="kanban-box">' +
'<div><field name="foo"/></div>' +
"</t></templates>" +
"</kanban>",
groupBy: ["product_id"],
async mockRPC(route, args, performRpc) {
if (args.method === "web_read_group") {
// override read_group to return an extra empty groups
const result = await performRpc(...arguments);
if (firstLoad) {
result.groups.unshift({
__domain: [["product_id", "=", 7]],
product_id: [7, "empty group"],
product_id_count: 0,
});
result.length = 3;
firstLoad = false;
}
return result;
}
},
});
assert.containsOnce(target, ".o_kanban_header span:contains('empty group')");
assert.containsOnce(target, ".o_kanban_header span:contains('hello')");
assert.containsNone(target, ".o_kanban_header .o_column_title:contains('None')");
// Delete the empty group
let clickColumnAction = await toggleColumnActions(target);
await clickColumnAction("Delete");
// Delete the group 'hello'
clickColumnAction = await toggleColumnActions(target);
await clickColumnAction("Delete");
// None of the previous groups should be present inside the view. Instead, a 'none' column should be displayed.
assert.containsNone(target, ".o_kanban_header span:contains('empty group')");
assert.containsNone(target, ".o_kanban_header span:contains('hello')");
assert.containsOnce(target, ".o_kanban_header .o_column_title:contains('None')");
});
QUnit.test("edit a column in grouped on m2o", async (assert) => {
serverData.views["product,false,form"] =
'<form string="Product"><field name="display_name"/></form>';