SearchKit - Improve searchDisplay pager with additional options
authorColeman Watts <coleman@civicrm.org>
Fri, 6 Aug 2021 16:26:09 +0000 (12:26 -0400)
committerColeman Watts <coleman@civicrm.org>
Sun, 8 Aug 2021 21:36:16 +0000 (17:36 -0400)
Adds 'show_count' and 'expose_limit' as options to searchDisplay pagers

12 files changed:
ext/search_kit/Civi/Api4/Action/SearchDisplay/Run.php
ext/search_kit/ang/crmSearchAdmin.ang.php
ext/search_kit/ang/crmSearchAdmin/crmSearchAdminDisplay.component.js
ext/search_kit/ang/crmSearchAdmin/displays/common/searchAdminPagerConfig.component.js [new file with mode: 0644]
ext/search_kit/ang/crmSearchAdmin/displays/common/searchAdminPagerConfig.html [new file with mode: 0644]
ext/search_kit/ang/crmSearchAdmin/displays/searchAdminDisplayList.component.js
ext/search_kit/ang/crmSearchAdmin/displays/searchAdminDisplayList.html
ext/search_kit/ang/crmSearchAdmin/displays/searchAdminDisplayTable.component.js
ext/search_kit/ang/crmSearchAdmin/displays/searchAdminDisplayTable.html
ext/search_kit/ang/crmSearchDisplay/Pager.html
ext/search_kit/ang/crmSearchDisplay/traits/searchDisplayBaseTrait.service.js
ext/search_kit/ang/crmSearchTasks/traits/searchDisplayTasksTrait.service.js

index a4ef5d8f5ae16b561d267fe36421a810d011c10b..d5a93d5aacc5b103ec7e4ff3f3ddfc73754b5206 100644 (file)
@@ -34,6 +34,12 @@ class Run extends \Civi\Api4\Generic\AbstractAction {
    */
   protected $sort = [];
 
+  /**
+   * Number of results to return
+   * @var int
+   */
+  protected $limit;
+
   /**
    * Should this api call return a page of results or the row_count or the ids
    * E.g. "page:1" or "row_count" or "id"
@@ -123,7 +129,8 @@ class Run extends \Civi\Api4\Generic\AbstractAction {
         if (!empty($settings['pager']) && preg_match('/^page:\d+$/', $this->return)) {
           $page = explode(':', $this->return)[1];
         }
-        $apiParams['limit'] = $settings['limit'] ?? NULL;
+        $limit = !empty($settings['pager']['expose_limit']) && $this->limit ? $this->limit : NULL;
+        $apiParams['limit'] = $limit ?? $settings['limit'] ?? NULL;
         $apiParams['offset'] = $page ? $apiParams['limit'] * ($page - 1) : 0;
         $apiParams['orderBy'] = $this->getOrderByFromSort();
         $this->augmentSelectClause($apiParams);
index 31ff79962f249a9902c217577b48d7043aea56d3..f6c673415c8f1d7cbc97e68bb138ef33a3c51a1e 100644 (file)
@@ -5,6 +5,7 @@ return [
     'ang/crmSearchAdmin.module.js',
     'ang/crmSearchAdmin/*.js',
     'ang/crmSearchAdmin/*/*.js',
+    'ang/crmSearchAdmin/*/*/*.js',
   ],
   'css' => [
     'css/crmSearchAdmin.css',
index f151226aa3cbfa3119f4cee379344ec8673898a1..f895d2d538317b52bb8fa731f549d8501cdc2e19 100644 (file)
         },
       };
 
-      this.toggleLimit = function() {
-        if (ctrl.display.settings.limit) {
-          ctrl.display.settings.limit = 0;
-          if (ctrl.display.settings.pager) {
-            ctrl.display.settings.pager = false;
-          }
-        } else {
-          ctrl.display.settings.limit = CRM.crmSearchAdmin.defaultPagerSize;
-        }
-      };
-
       // Drag-n-drop settings for reordering columns
       this.sortableOptions = {
         connectWith: '.crm-search-admin-edit-columns',
diff --git a/ext/search_kit/ang/crmSearchAdmin/displays/common/searchAdminPagerConfig.component.js b/ext/search_kit/ang/crmSearchAdmin/displays/common/searchAdminPagerConfig.component.js
new file mode 100644 (file)
index 0000000..d4fd289
--- /dev/null
@@ -0,0 +1,48 @@
+(function(angular, $, _) {
+  "use strict";
+
+  angular.module('crmSearchAdmin').component('searchAdminPagerConfig', {
+    bindings: {
+      display: '<',
+    },
+    templateUrl: '~/crmSearchAdmin/displays/common/searchAdminPagerConfig.html',
+    controller: function($scope) {
+      var ts = $scope.ts = CRM.ts('org.civicrm.search_kit'),
+        ctrl = this;
+
+      function getDefaultSettings() {
+        return _.cloneDeep({
+          show_count: false,
+          expose_limit: false
+        });
+      }
+
+      this.$onInit = function() {
+        // Legacy support
+        if (this.display.settings.pager === true) {
+          this.display.settings.pager = getDefaultSettings();
+        }
+        if (this.display.settings.pager && !this.display.settings.limit) {
+          this.toggleLimit();
+        }
+      };
+
+      this.togglePager = function() {
+        this.display.settings.pager = this.display.settings.pager ? false : getDefaultSettings();
+        if (this.display.settings.pager && !this.display.settings.limit) {
+          this.toggleLimit();
+        }
+      };
+
+      this.toggleLimit = function() {
+        if (ctrl.display.settings.limit) {
+          ctrl.display.settings.limit = 0;
+        } else {
+          ctrl.display.settings.limit = CRM.crmSearchAdmin.defaultPagerSize;
+        }
+      };
+
+    }
+  });
+
+})(angular, CRM.$, CRM._);
diff --git a/ext/search_kit/ang/crmSearchAdmin/displays/common/searchAdminPagerConfig.html b/ext/search_kit/ang/crmSearchAdmin/displays/common/searchAdminPagerConfig.html
new file mode 100644 (file)
index 0000000..184f6ff
--- /dev/null
@@ -0,0 +1,33 @@
+<div class="form-inline">
+  <div class="checkbox-inline form-control">
+    <label>
+      <input type="checkbox" ng-checked="$ctrl.display.settings.pager" ng-click="$ctrl.togglePager()">
+      <span>{{:: ts('Use Pager') }}</span>
+    </label>
+  </div>
+  <div class="checkbox-inline form-control" ng-if="!$ctrl.display.settings.pager">
+    <label>
+      <input type="checkbox" ng-checked="$ctrl.display.settings.limit" ng-click="$ctrl.toggleLimit()">
+      <span>{{:: ts('Limit Results') }}</span>
+    </label>
+    <input ng-if="$ctrl.display.settings.limit" type="number" min="1" step="1" class="form-control" ng-model="$ctrl.display.settings.limit">
+  </div>
+  <div class="form-group" ng-if="$ctrl.display.settings.pager">
+    <label for="crm-search-admin-display-limit">
+      {{:: ts('Page Size') }}
+    </label>
+    <input id="crm-search-admin-display-limit" ng-if="$ctrl.display.settings.limit" type="number" min="1" step="1" class="form-control" ng-model="$ctrl.display.settings.limit">
+    <div class="checkbox-inline form-control">
+      <label>
+        <input type="checkbox" ng-model="$ctrl.display.settings.pager.show_count" >
+        <span>{{:: ts('Show Count') }}</span>
+      </label>
+    </div>
+    <div class="checkbox-inline form-control">
+      <label>
+        <input type="checkbox" ng-model="$ctrl.display.settings.pager.expose_limit" >
+        <span>{{:: ts('Adjustable Page Size') }}</span>
+      </label>
+    </div>
+  </div>
+</div>
index 081b45393f4adbde1445163cbe8314acfeded12d..dc4ceda0d835e7c7a08dd6bb35381669fb646f95 100644 (file)
@@ -35,7 +35,7 @@
           ctrl.display.settings = {
             style: 'ul',
             limit: CRM.crmSearchAdmin.defaultPagerSize,
-            pager: true
+            pager: {}
           };
         }
         ctrl.parent.initColumns({key: true, dataType: true, type: 'field'});
index 51aeaccf727e2076cb961866946a865a1e097a16..3cbb992d9329fbe2ace3aab4de7a0e41492bec23 100644 (file)
       </option>
     </select>
   </div>
-  <div class="form-inline">
-    <div class="checkbox-inline form-control">
-      <label>
-        <input type="checkbox" ng-checked="$ctrl.display.settings.limit" ng-click="$ctrl.parent.toggleLimit()">
-        <span>{{:: ts('Limit Results') }}</span>
-      </label>
-      <input id="crm-search-admin-display-limit" ng-if="$ctrl.display.settings.limit" type="number" min="1" step="1" class="form-control" ng-model="$ctrl.display.settings.limit">
-    </div>
-    <div class="checkbox-inline form-control">
-      <label ng-class="{disabled: !$ctrl.display.settings.limit}">
-        <input type="checkbox" ng-model="$ctrl.display.settings.pager" ng-disabled="!$ctrl.display.settings.limit">
-        <span>{{:: ts('Use Pager') }}</span>
-      </label>
-    </div>
-  </div>
+  <search-admin-pager-config display="$ctrl.display"></search-admin-pager-config>
 </fieldset>
 <fieldset class="crm-search-admin-edit-columns-wrapper">
   <legend>
index 937b85d17436213567ff48036e987c4a3ac0a16c..6c95159180ebe84c77fb6c18e96ad27b25686a11 100644 (file)
@@ -19,7 +19,7 @@
         if (!ctrl.display.settings) {
           ctrl.display.settings = {
             limit: CRM.crmSearchAdmin.defaultPagerSize,
-            pager: true
+            pager: {}
           };
         }
         ctrl.parent.initColumns({key: true, label: true, dataType: true, type: 'field'});
index f068b4bcda0ce97a029703dc0e2d638ee4065d3b..1fe4a157c7b2011f6f8792b1939d988575138c1c 100644 (file)
@@ -1,19 +1,6 @@
 <fieldset ng-include="'~/crmSearchAdmin/crmSearchAdminDisplaySort.html'"></fieldset>
 <fieldset>
   <div class="form-inline">
-    <div class="checkbox-inline form-control">
-      <label>
-        <input type="checkbox" ng-checked="$ctrl.display.settings.limit" ng-click="$ctrl.parent.toggleLimit()">
-        <span>{{:: ts('Limit Results') }}</span>
-      </label>
-      <input id="crm-search-admin-display-limit" ng-if="$ctrl.display.settings.limit" type="number" min="1" step="1" class="form-control" ng-model="$ctrl.display.settings.limit">
-    </div>
-    <div class="checkbox-inline form-control">
-      <label ng-class="{disabled: !$ctrl.display.settings.limit}">
-        <input type="checkbox" ng-model="$ctrl.display.settings.pager" ng-disabled="!$ctrl.display.settings.limit">
-        <span>{{:: ts('Use Pager') }}</span>
-      </label>
-    </div>
     <div class="checkbox-inline form-control">
       <label>
         <input type="checkbox" ng-model="$ctrl.display.settings.actions">
@@ -21,6 +8,7 @@
       </label>
     </div>
   </div>
+  <search-admin-pager-config display="$ctrl.display"></search-admin-pager-config>
 </fieldset>
 <fieldset class="crm-search-admin-edit-columns-wrapper">
   <legend>
index d760bec287fd6f56bfaf7ea3d3b69820ee74961f..d33473c687e7dc5e3dbb56e14e6a93154674bb7a 100644 (file)
@@ -1,16 +1,36 @@
-<div class="text-center" ng-if="$ctrl.rowCount && $ctrl.settings.pager">
-  <ul uib-pagination
-      class="pagination"
-      boundary-links="true"
-      total-items="$ctrl.rowCount"
-      ng-model="$ctrl.page"
-      ng-change="$ctrl.getResults()"
-      items-per-page="$ctrl.settings.limit"
-      max-size="6"
-      force-ellipses="true"
-      previous-text="&lsaquo;"
-      next-text="&rsaquo;"
-      first-text="&laquo;"
-      last-text="&raquo;"
-  ></ul>
+<div class="crm-flex-box crm-search-display-pager" ng-if="$ctrl.rowCount && $ctrl.settings.pager">
+  <div>
+    <div class="form-inline" ng-if="$ctrl.settings.pager.show_count">
+      <label ng-if="$ctrl.rowCount === 1">
+        {{ $ctrl.selectedRows && $ctrl.selectedRows.length ? ts('%1 selected of 1 result', {1: $ctrl.selectedRows.length}) : ts('1 result') }}
+      </label>
+      <label ng-if="$ctrl.rowCount === 0 || $ctrl.rowCount > 1">
+        {{ $ctrl.selectedRows && $ctrl.selectedRows.length ? ts('%1 selected of %2 results', {1: $ctrl.selectedRows.length, 2: $ctrl.rowCount}) : ts('%1 results', {1: $ctrl.rowCount}) }}
+      </label>
+    </div>
+  </div>
+  <div class="text-center crm-flex-2">
+    <ul uib-pagination
+        class="pagination"
+        boundary-links="true"
+        total-items="$ctrl.rowCount"
+        ng-model="$ctrl.page"
+        ng-change="$ctrl.getResults()"
+        items-per-page="$ctrl.limit"
+        max-size="6"
+        force-ellipses="true"
+        previous-text="&lsaquo;"
+        next-text="&rsaquo;"
+        first-text="&laquo;"
+        last-text="&raquo;"
+    ></ul>
+  </div>
+  <div>
+    <div class="form-inline text-right" ng-if="$ctrl.settings.pager.expose_limit">
+      <label for="crm-search-results-page-size" >
+        {{:: ts('Page Size') }}
+      </label>
+      <input class="form-control" id="crm-search-results-page-size" type="number" ng-model="$ctrl.limit" min="10" step="10" ng-change="onChangeLimit()">
+    </div>
+  </div>
 </div>
index d7b2da89c136567d3f6c0c9ad650bf2322688c63..733105f74f7d103f967e0264d61b1cf19b34aa05 100644 (file)
@@ -83,6 +83,7 @@
       // Called by the controller's $onInit function
       initializeDisplay: function($scope, $element) {
         var ctrl = this;
+        this.limit = this.settings.limit;
         this.sort = this.settings.sort ? _.cloneDeep(this.settings.sort) : [];
 
         this.getResults = _.debounce(function() {
           ctrl.getResults();
         }
 
+        function onChangePageSize() {
+          ctrl.page = 1;
+          ctrl.getResults();
+        }
+
         if (this.afFieldset) {
           $scope.$watch(this.afFieldset.getFieldData, onChangeFilters, true);
         }
+        if (this.settings.pager && this.settings.pager.expose_limit) {
+          $scope.$watch('$ctrl.limit', onChangePageSize);
+        }
         $scope.$watch('$ctrl.filters', onChangeFilters, true);
       },
 
           savedSearch: this.search,
           display: this.display,
           sort: this.sort,
+          limit: this.limit,
           filters: _.assign({}, (this.afFieldset ? this.afFieldset.getFieldData() : {}), this.filters),
           afform: this.afFieldset ? this.afFieldset.getFormName() : null
         };
           ctrl.results = results;
           ctrl.editing = false;
           if (!ctrl.rowCount) {
-            if (!ctrl.settings.limit || results.length < ctrl.settings.limit) {
+            if (!ctrl.limit || results.length < ctrl.limit) {
               ctrl.rowCount = results.length;
             } else if (ctrl.settings.pager) {
               var params = ctrl.getApiParams('row_count');
index bfbb4f9aa92f9d2ef84b6bc1479d093d9fd0a308..1644052869edfc601f1afbd35370b9b8d7424728 100644 (file)
@@ -22,7 +22,7 @@
         }
         // Select all
         ctrl.allRowsSelected = true;
-        if (ctrl.page === 1 && ctrl.results.length < ctrl.settings.limit) {
+        if (ctrl.page === 1 && ctrl.results.length < ctrl.limit) {
           ctrl.selectedRows = _.pluck(ctrl.results, 'id');
           return;
         }