From 488560cc83070f0aee6d15525dc0d02ca4d320c4 Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Mon, 15 Nov 2021 09:47:37 -0500 Subject: [PATCH] SearchKit - Add drag-sortable weight functionality Drag-sortable weights are similar to in-place edit in that it uses the API to update records in the table. In this case it updates the "weight" column when the user drags a row into a different position. --- .../SearchDisplay/AbstractRunAction.php | 11 +++++- .../crmSearchAdminDisplay.component.js | 7 ++-- .../searchAdminDisplayTable.component.js | 11 ++++++ .../displays/searchAdminDisplayTable.html | 12 +++++-- .../searchDisplaySortableTrait.service.js | 2 +- .../ang/crmSearchDisplayTable.ang.php | 2 +- .../crmSearchDisplayTable.component.js | 34 ++++++++++++++++++- .../crmSearchDisplayTable.html | 11 +++--- .../crmSearchDisplayTableBody.html | 7 ++-- .../crmSearchDisplayTableLoading.html | 4 +-- ext/search_kit/css/crmSearchDisplay.css | 2 +- 11 files changed, 86 insertions(+), 17 deletions(-) diff --git a/ext/search_kit/Civi/Api4/Action/SearchDisplay/AbstractRunAction.php b/ext/search_kit/Civi/Api4/Action/SearchDisplay/AbstractRunAction.php index d705319fbe..d71beeddbf 100644 --- a/ext/search_kit/Civi/Api4/Action/SearchDisplay/AbstractRunAction.php +++ b/ext/search_kit/Civi/Api4/Action/SearchDisplay/AbstractRunAction.php @@ -712,6 +712,11 @@ abstract class AbstractRunAction extends \Civi\Api4\Generic\AbstractAction { * @return array */ protected function getOrderByFromSort() { + // Drag-sortable tables have a forced order + if (!empty($this->display['settings']['draggable'])) { + return [$this->display['settings']['draggable'] => 'ASC']; + } + $defaultSort = $this->display['settings']['sort'] ?? []; $currentSort = $this->sort; @@ -745,9 +750,13 @@ abstract class AbstractRunAction extends \Civi\Api4\Generic\AbstractAction { }, $apiParams['select']); $additions = []; // Add primary key field if actions are enabled - if (!empty($this->display['settings']['actions'])) { + if (!empty($this->display['settings']['actions']) || !empty($this->display['settings']['draggable'])) { $additions = CoreUtil::getInfoItem($this->savedSearch['api_entity'], 'primary_key'); } + // Add draggable column (typically "weight") + if (!empty($this->display['settings']['draggable'])) { + $additions[] = $this->display['settings']['draggable']; + } // Add style conditions for the display foreach ($this->getCssRulesSelect($this->display['settings']['cssRules'] ?? []) as $addition) { $additions[] = $addition; diff --git a/ext/search_kit/ang/crmSearchAdmin/crmSearchAdminDisplay.component.js b/ext/search_kit/ang/crmSearchAdmin/crmSearchAdminDisplay.component.js index e6d17dd5dc..94d4007ab3 100644 --- a/ext/search_kit/ang/crmSearchAdmin/crmSearchAdminDisplay.component.js +++ b/ext/search_kit/ang/crmSearchAdmin/crmSearchAdminDisplay.component.js @@ -34,8 +34,7 @@ }, controller: function($scope, $timeout, searchMeta) { var ts = $scope.ts = CRM.ts('org.civicrm.search_kit'), - ctrl = this, - afforms; + ctrl = this; this.isSuperAdmin = CRM.checkPerm('all CiviCRM permissions and ACLs'); this.aclBypassHelp = ts('Only users with "all CiviCRM permissions and ACLs" can disable permission checks.'); @@ -186,6 +185,10 @@ // Checks if a column contains a sortable value // Must be a real sql expression (not a pseudo-field like `result_row_num`) this.canBeSortable = function(col) { + // Column-header sorting is incompatible with draggable sorting + if (ctrl.display.settings.draggable) { + return false; + } var expr = ctrl.getExprFromSelect(col.key), info = searchMeta.parseExpr(expr), arg = (info && info.args && _.findWhere(info.args, {type: 'field'})) || {}; diff --git a/ext/search_kit/ang/crmSearchAdmin/displays/searchAdminDisplayTable.component.js b/ext/search_kit/ang/crmSearchAdmin/displays/searchAdminDisplayTable.component.js index 55b4fbbd5f..b8cdfee5a5 100644 --- a/ext/search_kit/ang/crmSearchAdmin/displays/searchAdminDisplayTable.component.js +++ b/ext/search_kit/ang/crmSearchAdmin/displays/searchAdminDisplayTable.component.js @@ -33,6 +33,15 @@ } }; + this.toggleDraggable = function() { + if (ctrl.display.settings.draggable) { + delete ctrl.display.settings.draggable; + } else { + ctrl.display.settings.sort = []; + ctrl.display.settings.draggable = searchMeta.getEntity(ctrl.apiEntity).order_by; + } + }; + this.$onInit = function () { if (!ctrl.display.settings) { ctrl.display.settings = _.extend({}, _.cloneDeep(CRM.crmSearchAdmin.defaultDisplay.settings), {columns: null}); @@ -42,6 +51,8 @@ } // Displays created prior to 5.43 may not have this property ctrl.display.settings.classes = ctrl.display.settings.classes || []; + // Table can be draggable if the main entity is a SortableEntity. + ctrl.canBeDraggable = _.includes(searchMeta.getEntity(ctrl.apiEntity).type, 'SortableEntity'); ctrl.parent.initColumns({label: true, sortable: true}); }; diff --git a/ext/search_kit/ang/crmSearchAdmin/displays/searchAdminDisplayTable.html b/ext/search_kit/ang/crmSearchAdmin/displays/searchAdminDisplayTable.html index a3090f9203..4794ea0e40 100644 --- a/ext/search_kit/ang/crmSearchAdmin/displays/searchAdminDisplayTable.html +++ b/ext/search_kit/ang/crmSearchAdmin/displays/searchAdminDisplayTable.html @@ -1,5 +1,13 @@ -
+
+
+
+ +
+
-
+
diff --git a/ext/search_kit/ang/crmSearchDisplayTable/crmSearchDisplayTableBody.html b/ext/search_kit/ang/crmSearchDisplayTable/crmSearchDisplayTableBody.html index f3f525aa6f..1bb55193a4 100644 --- a/ext/search_kit/ang/crmSearchDisplayTable/crmSearchDisplayTableBody.html +++ b/ext/search_kit/ang/crmSearchDisplayTable/crmSearchDisplayTableBody.html @@ -1,6 +1,9 @@ - - + + + + + diff --git a/ext/search_kit/ang/crmSearchDisplayTable/crmSearchDisplayTableLoading.html b/ext/search_kit/ang/crmSearchDisplayTable/crmSearchDisplayTableLoading.html index a3d01656ae..35738b7edd 100644 --- a/ext/search_kit/ang/crmSearchDisplayTable/crmSearchDisplayTableLoading.html +++ b/ext/search_kit/ang/crmSearchDisplayTable/crmSearchDisplayTableLoading.html @@ -1,7 +1,7 @@ - - + +
diff --git a/ext/search_kit/css/crmSearchDisplay.css b/ext/search_kit/css/crmSearchDisplay.css index 631f3d74a0..a2c84a7a45 100644 --- a/ext/search_kit/css/crmSearchDisplay.css +++ b/ext/search_kit/css/crmSearchDisplay.css @@ -1,5 +1,5 @@ /* Sortable headers */ -#bootstrap-theme .crm-search-display th[ng-click] { +#bootstrap-theme .crm-search-display th.crm-sortable-col { cursor: pointer; } #bootstrap-theme .crm-search-display th i.fa-sort-desc, -- 2.25.1