From 6f08752fc2e052eed25ada4d0c5419f6508c71fd Mon Sep 17 00:00:00 2001 From: "Hubert Van de Walle (huvw)" Date: Mon, 13 Sep 2021 10:06:20 +0000 Subject: [PATCH] [FIX] web: select all feature now works as intended Steps to follow - Go to the variant tab of a product - Add an attribute and click search more - Select the checkbox at the top to select all records from the current page - Click on Select all - Click on Select -> Only the records from the first page are added Cause of the issue `getSelectedRecords` doesn't return the record from all pages but only from the current one Solution If the domain is selected, use all the records opw-2586877 closes odoo/odoo#77228 X-original-commit: 963ccf1b4f3bb82c974af2ac0e47344c0ce060ac Signed-off-by: Aaron Bohy (aab) Signed-off-by: Hubert Van De Walle --- .../legacy/js/views/list/list_controller.js | 42 +++++++++++-------- .../src/legacy/js/views/view_dialogs.js | 11 ++--- .../tests/legacy/views/view_dialogs_tests.js | 34 +++++++++++++++ 3 files changed, 61 insertions(+), 26 deletions(-) diff --git a/addons/web/static/src/legacy/js/views/list/list_controller.js b/addons/web/static/src/legacy/js/views/list/list_controller.js index 14541756f68..0679f86d25f 100644 --- a/addons/web/static/src/legacy/js/views/list/list_controller.js +++ b/addons/web/static/src/legacy/js/views/list/list_controller.js @@ -107,6 +107,24 @@ var ListController = BasicController.extend({ return record.res_id; }); }, + + /** + * Returns the list of currently selected res_ids (with the check boxes on + * the left) or the whole domain res_ids if it is selected + * + * This method should be the implementation of getSelectedIds but it is kept for compatibility reasons + * + * @returns {Promise} + */ + getSelectedIdsWithDomain: async function () { + if (this.isDomainSelected) { + const state = this.model.get(this.handle, {raw: true}); + return await this._domainToResIds(state.getDomain(), session.active_ids_limit); + } else { + return Promise.resolve(this.model.localIdsToResIds(this.selectedRecords)); + } + }, + /** * Returns the list of currently selected records (with the check boxes on * the left) @@ -595,20 +613,14 @@ var ListController = BasicController.extend({ * @returns {Promise} */ _toggleArchiveState: async function (archive) { - let resIds; - let displayNotif = false; - const state = this.model.get(this.handle, {raw: true}); - if (this.isDomainSelected) { - resIds = await this._domainToResIds(state.getDomain(), session.active_ids_limit); - displayNotif = (resIds.length === session.active_ids_limit); - } else { - resIds = this.model.localIdsToResIds(this.selectedRecords); - } + const resIds = await this.getSelectedIdsWithDomain() + const notif = this.isDomainSelected; await this._archive(resIds, archive); - if (displayNotif) { + const total = this.model.get(this.handle, {raw: true}).count; + if (notif && resIds.length === session.active_ids_limit && resIds.length < total) { const msg = _.str.sprintf( _t("Of the %d records selected, only the first %d have been archived/unarchived."), - state.count, resIds.length + total, resIds.length ); this.displayNotification({ title: _t('Warning'), message: msg }); } @@ -881,13 +893,7 @@ var ListController = BasicController.extend({ this._disableButtons(); const state = this.model.get(this.handle); try { - let resIds; - if (this.isDomainSelected) { - const limit = session.active_ids_limit; - resIds = await this._domainToResIds(state.getDomain(), limit); - } else { - resIds = this.getSelectedIds(); - } + const resIds = await this.getSelectedIdsWithDomain(); // add the context of the button node (in the xml) and our custom one // (active_ids and domain) to the action's execution context const actionData = Object.assign({}, node.attrs, { diff --git a/addons/web/static/src/legacy/js/views/view_dialogs.js b/addons/web/static/src/legacy/js/views/view_dialogs.js index 898ff3ffcc5..cd60f3281aa 100644 --- a/addons/web/static/src/legacy/js/views/view_dialogs.js +++ b/addons/web/static/src/legacy/js/views/view_dialogs.js @@ -462,14 +462,9 @@ var SelectCreateDialog = ViewDialog.extend({ classes: 'btn-primary o_select_button', disabled: true, close: true, - click: function () { - var records = this.viewController.getSelectedRecords(); - var values = _.map(records, function (record) { - return { - id: record.res_id, - display_name: record.data.display_name, - }; - }); + click: async () => { + const resIds = await this.viewController.getSelectedIdsWithDomain(); + const values = resIds.map(e => ({id: e})); this.on_selected(values); }, }); diff --git a/addons/web/static/tests/legacy/views/view_dialogs_tests.js b/addons/web/static/tests/legacy/views/view_dialogs_tests.js index e4db6ba058a..b5c3aa4915c 100644 --- a/addons/web/static/tests/legacy/views/view_dialogs_tests.js +++ b/addons/web/static/tests/legacy/views/view_dialogs_tests.js @@ -584,6 +584,40 @@ QUnit.module('Views', { parent.destroy(); }); + QUnit.test('SelectCreateDialog calls on_selected with every record matching the domain', async function (assert) { + assert.expect(1); + + const parent = await createParent({ + data: this.data, + archs: { + 'partner,false,list': + '' + + '' + + '' + + '', + 'partner,false,search': + '' + + '' + + '', + }, + session: {}, + }); + + new dialogs.SelectCreateDialog(parent, { + res_model: 'partner', + on_selected: function(records) { + assert.equal(records.length, 3) + } + }).open(); + await testUtils.nextTick(); + + await testUtils.dom.click($('thead .o_list_record_selector input')); + await testUtils.dom.click($('.o_list_selection_box .o_list_select_domain')); + await testUtils.dom.click($('.modal .o_select_button')); + + parent.destroy(); + }); + QUnit.test('propagate can_create onto the search popup o2m', async function (assert) { assert.expect(4);