From d4381c0f39175d5cb97d02a92b4d2e9d7bf18d41 Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Mon, 1 Nov 2021 20:28:35 -0400 Subject: [PATCH] SearchKit - Fix action checkboxes to work with any key Lifts the assumption that every entity has a key column named "id" --- .../SearchDisplay/AbstractRunAction.php | 11 ++++++++--- .../Civi/Api4/Action/SearchDisplay/Run.php | 19 ++++++++++++------- .../crmSearchDisplayTableBody.html | 2 +- .../traits/searchDisplayTasksTrait.service.js | 14 +++++++------- 4 files changed, 28 insertions(+), 18 deletions(-) diff --git a/ext/search_kit/Civi/Api4/Action/SearchDisplay/AbstractRunAction.php b/ext/search_kit/Civi/Api4/Action/SearchDisplay/AbstractRunAction.php index d775985b64..4bc6287afd 100644 --- a/ext/search_kit/Civi/Api4/Action/SearchDisplay/AbstractRunAction.php +++ b/ext/search_kit/Civi/Api4/Action/SearchDisplay/AbstractRunAction.php @@ -114,18 +114,23 @@ abstract class AbstractRunAction extends \Civi\Api4\Generic\AbstractAction { */ protected function formatResult(\Civi\Api4\Generic\Result $result): array { $rows = []; - foreach ($result as $index => $row) { + $keyName = CoreUtil::getIdFieldName($this->savedSearch['api_entity']); + foreach ($result as $index => $record) { $data = $columns = []; foreach ($this->getSelectClause() as $key => $item) { - $data[$key] = $this->getValue($key, $row, $index); + $data[$key] = $this->getValue($key, $record, $index); } foreach ($this->display['settings']['columns'] as $column) { $columns[] = $this->formatColumn($column, $data); } - $rows[] = [ + $row = [ 'data' => $data, 'columns' => $columns, ]; + if (isset($data[$keyName])) { + $row['key'] = $data[$keyName]; + } + $rows[] = $row; } return $rows; } diff --git a/ext/search_kit/Civi/Api4/Action/SearchDisplay/Run.php b/ext/search_kit/Civi/Api4/Action/SearchDisplay/Run.php index 564545765d..1b14398e0e 100644 --- a/ext/search_kit/Civi/Api4/Action/SearchDisplay/Run.php +++ b/ext/search_kit/Civi/Api4/Action/SearchDisplay/Run.php @@ -2,6 +2,8 @@ namespace Civi\Api4\Action\SearchDisplay; +use Civi\Api4\Utils\CoreUtil; + /** * Load the results for rendering a SearchDisplay. * @@ -34,23 +36,26 @@ class Run extends AbstractRunAction { $entityName = $this->savedSearch['api_entity']; $apiParams =& $this->savedSearch['api_params']; $settings = $this->display['settings']; - $page = NULL; + $page = $index = NULL; + $key = $this->return; switch ($this->return) { - case 'row_count': case 'id': + $key = CoreUtil::getIdFieldName($this->savedSearch['api_entity']); + $index = [$key]; + case 'row_count': if (empty($apiParams['having'])) { $apiParams['select'] = []; } - if (!in_array($this->return, $apiParams['select'], TRUE)) { - $apiParams['select'][] = $this->return; + if (!in_array($key, $apiParams['select'], TRUE)) { + $apiParams['select'][] = $key; } unset($apiParams['orderBy'], $apiParams['limit']); break; default: - if (($settings['pager'] ?? FALSE) !== FALSE && preg_match('/^page:\d+$/', $this->return)) { - $page = explode(':', $this->return)[1]; + if (($settings['pager'] ?? FALSE) !== FALSE && preg_match('/^page:\d+$/', $key)) { + $page = explode(':', $key)[1]; } $limit = !empty($settings['pager']['expose_limit']) && $this->limit ? $this->limit : NULL; $apiParams['debug'] = $this->debug; @@ -62,7 +67,7 @@ class Run extends AbstractRunAction { $this->applyFilters(); - $apiResult = civicrm_api4($entityName, 'get', $apiParams); + $apiResult = civicrm_api4($entityName, 'get', $apiParams, $index); // Copy over meta properties to this result $result->rowCount = $apiResult->rowCount; $result->debug = $apiResult->debug; diff --git a/ext/search_kit/ang/crmSearchDisplayTable/crmSearchDisplayTableBody.html b/ext/search_kit/ang/crmSearchDisplayTable/crmSearchDisplayTableBody.html index 64a0a2af46..8222cfb22d 100644 --- a/ext/search_kit/ang/crmSearchDisplayTable/crmSearchDisplayTableBody.html +++ b/ext/search_kit/ang/crmSearchDisplayTable/crmSearchDisplayTableBody.html @@ -1,6 +1,6 @@ - + diff --git a/ext/search_kit/ang/crmSearchTasks/traits/searchDisplayTasksTrait.service.js b/ext/search_kit/ang/crmSearchTasks/traits/searchDisplayTasksTrait.service.js index a233b127d0..f7cb558d76 100644 --- a/ext/search_kit/ang/crmSearchTasks/traits/searchDisplayTasksTrait.service.js +++ b/ext/search_kit/ang/crmSearchTasks/traits/searchDisplayTasksTrait.service.js @@ -23,13 +23,13 @@ // Select all ctrl.allRowsSelected = true; if (ctrl.page === 1 && ctrl.results.length < ctrl.limit) { - ctrl.selectedRows = _.pluck(_.pluck(ctrl.results, 'id'), 'raw'); + ctrl.selectedRows = _.pluck(ctrl.results, 'key'); return; } // If more than one page of results, use ajax to fetch all ids ctrl.loadingAllRows = true; var params = ctrl.getApiParams('id'); - crmApi4('SearchDisplay', 'run', params, ['id']).then(function(ids) { + crmApi4('SearchDisplay', 'run', params).then(function(ids) { ctrl.loadingAllRows = false; ctrl.selectedRows = _.toArray(ids); }); @@ -37,9 +37,9 @@ // Toggle row selection selectRow: function(row) { - var index = this.selectedRows.indexOf(row.data.id); + var index = this.selectedRows.indexOf(row.key); if (index < 0) { - this.selectedRows.push(row.data.id); + this.selectedRows.push(row.key); this.allRowsSelected = (this.rowCount === this.selectedRows.length); } else { this.allRowsSelected = false; @@ -49,7 +49,7 @@ // @return bool isRowSelected: function(row) { - return this.allRowsSelected || _.includes(this.selectedRows, row.data.id); + return this.allRowsSelected || _.includes(this.selectedRows, row.key); }, refreshAfterTask: function() { @@ -69,8 +69,8 @@ onPostRun: [function(results, status, editedRow) { if (editedRow && status === 'success') { // If edited row disappears (because edits cause it to not meet search criteria), deselect it - var index = this.selectedRows.indexOf(editedRow.data.id); - if (index > -1 && !_.findWhere(results, {id: editedRow.data.id})) { + var index = this.selectedRows.indexOf(editedRow.key); + if (index > -1 && !_.findWhere(results, {id: editedRow.key})) { this.selectedRows.splice(index, 1); } } -- 2.25.1