diff --git a/addons/web/static/src/views/list/list_controller.js b/addons/web/static/src/views/list/list_controller.js index 8b287e0572c..fd35453abd7 100644 --- a/addons/web/static/src/views/list/list_controller.js +++ b/addons/web/static/src/views/list/list_controller.js @@ -448,6 +448,7 @@ export class ListController extends Component { confirm: async () => { const total = root.count; const resIds = await this.model.root.deleteRecords(); + this.model.notify(); if ( root.isDomainSelected && resIds.length === session.active_ids_limit && diff --git a/addons/web/static/src/views/relational_model.js b/addons/web/static/src/views/relational_model.js index 28f0eab2b43..977db751896 100644 --- a/addons/web/static/src/views/relational_model.js +++ b/addons/web/static/src/views/relational_model.js @@ -2201,9 +2201,15 @@ export class DynamicGroupList extends DynamicList { } async deleteRecords() { + const allResIds = []; for (const group of this.groups) { - group.list.deleteRecords(); + const resIds = await group.list.deleteRecords(); + group.count = group.count - resIds.length; + allResIds.push(...resIds); } + // Return the list of all deleted resIds. + // Will be used by the calling group to update its count. + return allResIds; } exportState() { diff --git a/addons/web/static/tests/views/list_view_tests.js b/addons/web/static/tests/views/list_view_tests.js index 6ebc8b7acfc..935c88e521a 100644 --- a/addons/web/static/tests/views/list_view_tests.js +++ b/addons/web/static/tests/views/list_view_tests.js @@ -5185,6 +5185,57 @@ QUnit.module("Views", (hooks) => { ); }); + QUnit.test( + "grouped, update the count of the group (and ancestors) when a record is deleted", + async function (assert) { + serverData.models.foo.records = [ + { id: 121, foo: "blip", bar: true }, + { id: 122, foo: "blip", bar: true }, + { id: 123, foo: "blip", bar: true }, + { id: 124, foo: "blip", bar: true }, + { id: 125, foo: "blip", bar: false }, + { id: 126, foo: "blip", bar: false }, + ]; + await makeView({ + type: "list", + resModel: "foo", + serverData, + arch: /*xml*/ ` + + + `, + groupBy: ["foo", "bar"], + actionMenus: {}, + }); + assert.strictEqual( + target.querySelector(".o_group_header:first-child").textContent.trim(), + "blip (6)" + ); + assert.strictEqual( + target.querySelector(".o_group_header:nth-child(2)").textContent.trim(), + "No (2)" + ); + + const secondNestedGroup = target.querySelector(".o_group_header:nth-child(3)"); + assert.strictEqual(secondNestedGroup.textContent.trim(), "Yes (4)"); + await click(secondNestedGroup); + assert.containsN(target, ".o_data_row", 4); + + await click(target.querySelector(".o_data_row input")); + await toggleActionMenu(target); + await toggleMenuItem(target, "Delete"); + await click(target, ".modal .btn-primary"); + assert.strictEqual( + target.querySelector(".o_group_header:first-child").textContent.trim(), + "blip (5)" + ); + assert.strictEqual( + target.querySelector(".o_group_header:nth-child(3)").textContent.trim(), + "Yes (3)" + ); + } + ); + QUnit.test("pager (ungrouped and grouped mode), default limit", async function (assert) { assert.expect(4);