From 308bb9563ab3ce2ad20cc7d1e1f42e07724dffe4 Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Thu, 26 Jun 2025 17:04:28 +0300 Subject: [PATCH] select all result for relationships --- .../modules/crm/src/views/activities/list.js | 2 +- client/src/collection.js | 7 ++-- client/src/search-manager.js | 2 +- .../src/views/admin/auth-token/record/list.js | 2 +- client/src/views/list-related.js | 22 +++++++++- .../modals/select-category-tree-records.js | 2 +- client/src/views/modals/select-records.js | 2 +- client/src/views/record/list.js | 42 ++++++++++++++----- schema/metadata/clientDefs.json | 4 ++ 9 files changed, 65 insertions(+), 20 deletions(-) diff --git a/client/modules/crm/src/views/activities/list.js b/client/modules/crm/src/views/activities/list.js index 210f75416a..9aa28b5db4 100644 --- a/client/modules/crm/src/views/activities/list.js +++ b/client/modules/crm/src/views/activities/list.js @@ -30,10 +30,10 @@ import ListRelatedView from 'views/list-related'; export default class ActivitiesListView extends ListRelatedView { - createButton = false unlinkDisabled = true filtersDisabled = true + allResultDisabled = true; setup() { this.rowActionsView = 'views/record/row-actions/default'; diff --git a/client/src/collection.js b/client/src/collection.js index b583ffc95d..f842f25b81 100644 --- a/client/src/collection.js +++ b/client/src/collection.js @@ -134,6 +134,7 @@ class Collection { /** * @deprecated + * @type {module:search-manager~whereItem[]|null} */ whereAdditional = null @@ -154,7 +155,7 @@ class Collection { /** * A where function. * - * @type {function(): Object[]} + * @type {function(): module:search-manager~whereItem[]} */ whereFunction @@ -897,10 +898,10 @@ class Collection { /** * Get a where clause. * - * @returns {Object[]} + * @returns {module:search-manager~whereItem[]} */ getWhere() { - let where = (this.where || []).concat(this.whereAdditional || []); + let where = (this.where ?? []).concat(this.whereAdditional || []); if (this.whereFunction) { where = where.concat(this.whereFunction() || []); diff --git a/client/src/search-manager.js b/client/src/search-manager.js index a201f947d4..1496d2c4ad 100644 --- a/client/src/search-manager.js +++ b/client/src/search-manager.js @@ -48,7 +48,7 @@ * * @property {string} type A type. * @property {string} [attribute] An attribute (field). - * @property {module:search-manager~whereItem[]|string|number|boolean|null} [value] A value. + * @property {module:search-manager~whereItem[]|string|number|boolean|string[]|null} [value] A value. * @property {boolean} [dateTime] Is a date-time item. * @property {string} [timeZone] A time-zone. */ diff --git a/client/src/views/admin/auth-token/record/list.js b/client/src/views/admin/auth-token/record/list.js index c4dd008c25..d0138ae69d 100644 --- a/client/src/views/admin/auth-token/record/list.js +++ b/client/src/views/admin/auth-token/record/list.js @@ -53,7 +53,7 @@ export default class extends ListRecordView { entityType: this.entityType, params: { ids: ids || null, - where: (!ids || ids.length === 0) ? this.collection.getWhere() : null, + where: (!ids || ids.length === 0) ? this.getWhereForAllResult() : null, searchParams: (!ids || ids.length === 0) ? this.collection.data : null, }, data: attributes, diff --git a/client/src/views/list-related.js b/client/src/views/list-related.js index 7c8fa6d9e6..488778b4aa 100644 --- a/client/src/views/list-related.js +++ b/client/src/views/list-related.js @@ -140,6 +140,14 @@ class ListRelatedView extends MainView { */ nameAttribute + /** + * Disable select-all-result. + * + * @protected + * @type {boolean} + */ + allResultDisabled = false + /** * @inheritDoc */ @@ -596,11 +604,23 @@ class ListRelatedView extends MainView { o.type = 'listSmall'; } + const foreignLink = this.model.getLinkParam(this.link, 'foreign'); + + if (!this.allResultDisabled && !this.panelDefs.allResultDisabled && foreignLink) { + o.forceAllResultSelectable = true; + + o.allResultWhereItem = { + type: 'linkedWith', + attribute: foreignLink, + value: [this.model.id], + }; + } + this.prepareRecordViewOptions(o); const listViewName = this.getRecordViewName(); - this.createView('list', listViewName, o, view =>{ + this.createView('list', listViewName, o, view => { if (!this.hasParentView()) { view.undelegateEvents(); diff --git a/client/src/views/modals/select-category-tree-records.js b/client/src/views/modals/select-category-tree-records.js index ae7a17307c..5c5d200b6e 100644 --- a/client/src/views/modals/select-category-tree-records.js +++ b/client/src/views/modals/select-category-tree-records.js @@ -61,7 +61,7 @@ class SelectCategoryTreeRecordsModalView extends SelectRecordsModalView { if (listView.allResultIsChecked) { const data = { massRelate: true, - where: this.collection.getWhere(), + where: listView.getWhereForAllResult(), searchParams: this.collection.data, }; diff --git a/client/src/views/modals/select-records.js b/client/src/views/modals/select-records.js index abb0df6a05..886c502625 100644 --- a/client/src/views/modals/select-records.js +++ b/client/src/views/modals/select-records.js @@ -463,7 +463,7 @@ class SelectRecordsModalView extends ModalView { if (listView.allResultIsChecked) { const data = { massRelate: true, - where: this.collection.getWhere(), + where: listView.getWhereForAllResult(), searchParams: this.collection.data, }; diff --git a/client/src/views/record/list.js b/client/src/views/record/list.js index 33132191c0..4bc2898da9 100644 --- a/client/src/views/record/list.js +++ b/client/src/views/record/list.js @@ -99,6 +99,8 @@ class ListRecordView extends View { * @property {function(import('model').default[])} [onSelect] An on-select callback. Actual if selectable. * As of v9.1.0. * @property {boolean} [forceSettings] Force settings. As of v9.2.0. + * @property {boolean} [forceAllResultSelectable] Force select all result. As of v9.2.0. + * @property {module:search-manager~whereItem} [allResultWhereItem] Where item for select all result. As of v9.2.0. */ /** @@ -1203,11 +1205,10 @@ class ListRecordView extends View { }; if (this.allResultIsChecked) { - data.where = this.collection.getWhere(); + data.where = this.getWhereForAllResult(); data.searchParams = this.collection.data || null; data.searchData = this.collection.data || {}; // for bc; - } - else { + } else { data.ids = this.checkedList; } } @@ -1325,7 +1326,7 @@ class ListRecordView extends View { const data = {}; if (this.allResultIsChecked) { - data.where = this.collection.getWhere(); + data.where = this.getWhereForAllResult(); data.searchParams = this.collection.data || {}; data.selectData = data.searchData; // for bc; data.byWhere = true; // for bc @@ -1370,16 +1371,35 @@ class ListRecordView extends View { } } + /** + * Get the where clause for all result. + * + * @return {module:search-manager~whereItem[]} + * @since 9.2.0 + */ + getWhereForAllResult() { + const where = [...this.collection.getWhere()]; + + if (this.options.allResultWhereItem) { + where.push(this.options.allResultWhereItem); + } + + return where; + } + + /** + * @private + * @return {Record} + */ getMassActionSelectionPostData() { const data = {}; if (this.allResultIsChecked) { - data.where = this.collection.getWhere(); + data.where = this.getWhereForAllResult(); data.searchParams = this.collection.data || {}; data.selectData = this.collection.data || {}; // for bc; data.byWhere = true; // for bc; - } - else { + } else { data.ids = []; for (const i in this.checkedList) { @@ -1768,7 +1788,7 @@ class ListRecordView extends View { scope: this.scope, entityType: this.entityType, ids: ids, - where: this.collection.getWhere(), + where: this.getWhereForAllResult(), searchParams: this.collection.data, byWhere: this.allResultIsChecked, totalCount: this.collection.total, @@ -1861,7 +1881,7 @@ class ListRecordView extends View { this.createView('modalConvertCurrency', 'views/modals/mass-convert-currency', { entityType: this.entityType, ids: ids, - where: this.collection.getWhere(), + where: this.getWhereForAllResult(), searchParams: this.collection.data, byWhere: this.allResultIsChecked, totalCount: this.collection.total, @@ -1942,7 +1962,7 @@ class ListRecordView extends View { this.massActionList.unshift(item) : this.massActionList.push(item); - if (allResult && this.collection.url === this.entityType) { + if (allResult && !this.noAllResultMassActions) { toBeginning ? this.checkAllResultMassActionList.unshift(item) : this.checkAllResultMassActionList.push(item); @@ -2376,7 +2396,7 @@ class ListRecordView extends View { this.massActionList.push(item); }); - this.noAllResultMassActions = this.collection.url !== this.entityType; + this.noAllResultMassActions = this.collection.url !== this.entityType && !this.options.forceAllResultSelectable; this.checkAllResultMassActionList = this.checkAllResultMassActionList .filter(item => this.massActionList.includes(item)); diff --git a/schema/metadata/clientDefs.json b/schema/metadata/clientDefs.json index 5801f5650f..e1b06160e4 100644 --- a/schema/metadata/clientDefs.json +++ b/schema/metadata/clientDefs.json @@ -594,6 +594,10 @@ } }, "description": "Header dropdown actions. As of v8.4." + }, + "allResultDisabled": { + "type": "boolean", + "description": "Disable the ability to select all result. Important for non-standard relationship panels. As of v9.2." } } }