SearchKit - Make loading placeholders configurable
authorColeman Watts <coleman@civicrm.org>
Mon, 6 Jun 2022 14:26:28 +0000 (10:26 -0400)
committerColeman Watts <coleman@civicrm.org>
Mon, 6 Jun 2022 14:30:48 +0000 (10:30 -0400)
This allows the admin to control how many (if any) skeleton results are shown
during ajax loading.

It also lightens the colors to make the flashing a bit more subtle.

ext/search_kit/Civi/Api4/Action/SearchDisplay/GetDefault.php
ext/search_kit/ang/crmSearchAdmin/displays/common/searchAdminPlaceholderConfig.component.js [new file with mode: 0644]
ext/search_kit/ang/crmSearchAdmin/displays/common/searchAdminPlaceholderConfig.html [new file with mode: 0644]
ext/search_kit/ang/crmSearchAdmin/displays/searchAdminDisplayGrid.html
ext/search_kit/ang/crmSearchAdmin/displays/searchAdminDisplayList.html
ext/search_kit/ang/crmSearchAdmin/displays/searchAdminDisplayTable.html
ext/search_kit/ang/crmSearchDisplay/traits/searchDisplayBaseTrait.service.js
ext/search_kit/ang/crmSearchDisplayGrid/crmSearchDisplayGridLoading.html
ext/search_kit/ang/crmSearchDisplayList/crmSearchDisplayListLoading.html
ext/search_kit/ang/crmSearchDisplayTable/crmSearchDisplayTableLoading.html
ext/search_kit/css/crmSearchDisplay.css

index 9ae2d8ad6dfd529edc60f69b1ffb0acae3c729c8..56dc8967b97500f699459ed5dcc5cdfaaea383d0 100644 (file)
@@ -72,6 +72,7 @@ class GetDefault extends \Civi\Api4\Generic\AbstractAction {
           'show_count' => TRUE,
           'expose_limit' => TRUE,
         ],
+        'placeholder' => 5,
         'sort' => [],
         'columns' => [],
       ],
diff --git a/ext/search_kit/ang/crmSearchAdmin/displays/common/searchAdminPlaceholderConfig.component.js b/ext/search_kit/ang/crmSearchAdmin/displays/common/searchAdminPlaceholderConfig.component.js
new file mode 100644 (file)
index 0000000..4529454
--- /dev/null
@@ -0,0 +1,27 @@
+(function(angular, $, _) {
+  "use strict";
+
+  angular.module('crmSearchAdmin').component('searchAdminPlaceholderConfig', {
+    bindings: {
+      display: '<',
+    },
+    templateUrl: '~/crmSearchAdmin/displays/common/searchAdminPlaceholderConfig.html',
+    controller: function($scope) {
+      var ts = $scope.ts = CRM.ts('org.civicrm.search_kit'),
+        ctrl = this;
+
+      this.$onInit = function() {
+        // Legacy support
+        if (!('placeholder' in this.display.settings)) {
+          this.display.settings.placeholder = 5;
+        }
+      };
+
+      this.togglePlaceholder = function() {
+        this.display.settings.placeholder = this.display.settings.placeholder ? 0 : 5;
+      };
+
+    }
+  });
+
+})(angular, CRM.$, CRM._);
diff --git a/ext/search_kit/ang/crmSearchAdmin/displays/common/searchAdminPlaceholderConfig.html b/ext/search_kit/ang/crmSearchAdmin/displays/common/searchAdminPlaceholderConfig.html
new file mode 100644 (file)
index 0000000..a988a90
--- /dev/null
@@ -0,0 +1,9 @@
+<div class="form-inline">
+  <div class="checkbox-inline form-control" title="{{:: ts('Show wireframe placeholder results while waiting for data') }}">
+    <label>
+      <input type="checkbox" ng-checked="$ctrl.display.settings.placeholder" ng-click="$ctrl.togglePlaceholder()">
+      <span>{{:: ts('Loading Placeholders') }}</span>
+    </label>
+    <input ng-if="$ctrl.display.settings.placeholder" type="number" min="0" step="1" class="form-control" ng-model="$ctrl.display.settings.placeholder" ng-model-options="{updateOn: 'blur'}">
+  </div>
+</div>
index f08c98c633768d4b01082a2e7cebd69e8c7f30f6..a614443acdb59c0e8e674e4975a5caa15a4836ee 100644 (file)
@@ -11,6 +11,7 @@
     <div class="form-group" ng-include="'~/crmSearchAdmin/displays/common/searchButtonConfig.html'"></div>
   </div>
   <search-admin-pager-config display="$ctrl.display"></search-admin-pager-config>
+  <search-admin-placeholder-config display="$ctrl.display"></search-admin-placeholder-config>
 </fieldset>
 <fieldset class="crm-search-admin-edit-columns-wrapper">
   <legend>
index 3561df20b9236b0db70f6c8d4dee97854be1ce93..57a5dbac5c81379bcf811c6b8d93ad47c4eafbd0 100644 (file)
@@ -15,6 +15,7 @@
     <div class="form-group" ng-include="'~/crmSearchAdmin/displays/common/searchButtonConfig.html'"></div>
   </div>
   <search-admin-pager-config display="$ctrl.display"></search-admin-pager-config>
+  <search-admin-placeholder-config display="$ctrl.display"></search-admin-placeholder-config>
 </fieldset>
 <fieldset class="crm-search-admin-edit-columns-wrapper">
   <legend>
index 99971ebbb03ac2e2da67db61128aa264e3ef836e..f45b49342e46522d70f0b9206ba665a86cdebb2e 100644 (file)
@@ -28,6 +28,7 @@
   </div>
   <search-admin-css-rules label="{{:: ts('Row Style') }}" item="$ctrl.display.settings"></search-admin-css-rules>
   <search-admin-pager-config display="$ctrl.display"></search-admin-pager-config>
+  <search-admin-placeholder-config display="$ctrl.display"></search-admin-placeholder-config>
   <div class="form-inline crm-search-admin-flex-row" title="{{:: ts('Text to display if the table is empty.') }}">
     <label for="crm-search-admin-display-no-results-text">{{:: ts('No Results Text') }}</label>
     <input class="form-control crm-flex-1" id="crm-search-admin-display-no-results-text" ng-model="$ctrl.display.settings.noResultsText" placeholder="{{:: ts('None found.') }}">
index 9014c30393d50c6de405546bb8e5b5ea1815111f..9f4a63c33ab40b5bc01f7140eeb2e59bf5299581 100644 (file)
         this.limit = this.settings.limit;
         this.sort = this.settings.sort ? _.cloneDeep(this.settings.sort) : [];
         this.seed = Date.now();
+        this.placeholders = [];
+        var placeholderCount = 'placeholder' in this.settings ? this.settings.placeholder : 5;
+        for (var p=0; p < placeholderCount; ++p) {
+          this.placeholders.push({});
+        }
 
         this.getResults = _.debounce(function() {
           $scope.$apply(function() {
index b63dd058f7fa31d15e05d4d1367f456c6fc4a419..40b5a46144439a2966a1493c3c5c5567c1d8d351 100644 (file)
@@ -1,4 +1,4 @@
 <!-- Placeholder shown during ajax loading -->
-<div ng-repeat="num in [1,2,3,4,5] track by $index" style="width: 100px; height: 50px;">
+<div ng-repeat="num in $ctrl.placeholders" style="width: 100px; height: 50px;">
   <div class="crm-search-loading-placeholder"></div>
 </div>
index af84f53ea46e94b27d6d4f136137422880624a30..9a669b9284dc834bc1b6925ae83f77255021f13a 100644 (file)
@@ -1,4 +1,4 @@
 <!-- Placeholder shown during ajax loading -->
-<li ng-repeat="num in [1,2,3,4,5] track by $index">
+<li ng-repeat="num in $ctrl.placeholders">
   <div class="crm-search-loading-placeholder"></div>
 </li>
index 8054df17d46bb5cbc59386af79f09ca7e6356960..f0a0d2ed5a1e2b09ed3fc2b0cdfb632ddde2f2fb 100644 (file)
@@ -1,5 +1,5 @@
 <!-- Placeholder table rows shown during ajax loading -->
-<tr ng-repeat="num in [1,2,3,4,5] track by $index">
+<tr ng-repeat="num in $ctrl.placeholders">
   <td ng-if=":: $ctrl.hasExtraFirstColumn()">
     <input ng-if=":: $ctrl.settings.actions" type="checkbox" disabled>
   </td>
index 1438c50815def62f25f1ae853f987f0bb5ca837e..095115e4946e3ce2c9f49bfb5543c63019ae8281 100644 (file)
@@ -26,7 +26,7 @@
   width: 80%;
   position: relative;
   overflow: hidden;
-  background-color: rgba(0,0,0,.04);
+  background-color: rgba(0,0,0,.03);
   display: inline-block;
 }
 #bootstrap-theme .crm-search-loading-placeholder::before {
@@ -37,7 +37,7 @@
   top: 0;
   height: 100%;
   width: 150px;
-  background: linear-gradient(to right, transparent 0%, rgba(0,0,0,.1) 50%, transparent 100%);
+  background: linear-gradient(to right, transparent 0%, rgba(0,0,0,.05) 50%, transparent 100%);
   animation: searchKitLoadingAnimation 1s cubic-bezier(0.4, 0.0, 0.2, 1) infinite;
 }
 @keyframes searchKitLoadingAnimation {