SearchKit - Animated loading skeleton
authorColeman Watts <coleman@civicrm.org>
Wed, 10 Nov 2021 00:43:34 +0000 (19:43 -0500)
committerColeman Watts <coleman@civicrm.org>
Wed, 10 Nov 2021 00:43:34 +0000 (19:43 -0500)
ext/search_kit/ang/crmSearchAdmin/resultsTable/crmSearchAdminResultsTable.html
ext/search_kit/ang/crmSearchDisplay.ang.php
ext/search_kit/ang/crmSearchDisplayGrid/crmSearchDisplayGrid.html
ext/search_kit/ang/crmSearchDisplayGrid/crmSearchDisplayGridLoading.html [new file with mode: 0644]
ext/search_kit/ang/crmSearchDisplayList/crmSearchDisplayList.html
ext/search_kit/ang/crmSearchDisplayList/crmSearchDisplayListLoading.html [new file with mode: 0644]
ext/search_kit/ang/crmSearchDisplayTable/crmSearchDisplayTable.html
ext/search_kit/ang/crmSearchDisplayTable/crmSearchDisplayTableLoading.html [new file with mode: 0644]
ext/search_kit/css/crmSearchDisplay.css [new file with mode: 0644]
ext/search_kit/css/crmSearchTasks.css

index f8c04f2f6cfe6b088e520acb98736067ed604653..aff0c96b795aa14c3f3af53cb5311a78eda0d24e 100644 (file)
@@ -25,7 +25,7 @@
         </th>
       </tr>
     </thead>
-    <tbody ng-include="'~/crmSearchDisplayTable/crmSearchDisplayTableBody.html'"></tbody>
+    <tbody ng-include="'~/crmSearchDisplayTable/crmSearchDisplayTable' + ($ctrl.loading ? 'Loading' : 'Body') + '.html'"></tbody>
   </table>
   <div ng-include="'~/crmSearchDisplay/Pager.html'"></div>
 </div>
index a70d2f1ec263be994446eab027cac2c0d48e3844..0dbdeb3526e2bb9c2ec8e3c87061bb48337326e8 100644 (file)
@@ -9,6 +9,9 @@ return [
   'partials' => [
     'ang/crmSearchDisplay',
   ],
+  'css' => [
+    'css/crmSearchDisplay.css',
+  ],
   'basePages' => [],
   'requires' => ['api4', 'ngSanitize'],
   'exports' => [
index 5d8c3b71964265d8a7b9b0611e4a9477474516d3..46c09304ed634b513b85fda8a44b102518c27fec 100644 (file)
@@ -2,7 +2,7 @@
   <div ng-include="'~/crmSearchDisplay/SearchButton.html'" ng-if="$ctrl.settings.button"></div>
   <div
     class="crm-search-display-grid-container crm-search-display-grid-layout-{{$ctrl.settings.colno}}"
-    ng-include="'~/crmSearchDisplayGrid/crmSearchDisplayGridItems.html'"
+    ng-include="'~/crmSearchDisplayGrid/crmSearchDisplayGrid' + ($ctrl.loading ? 'Loading' : 'Items') + '.html'"
   ></div>
   <div ng-include="'~/crmSearchDisplay/Pager.html'"></div>
 </div>
diff --git a/ext/search_kit/ang/crmSearchDisplayGrid/crmSearchDisplayGridLoading.html b/ext/search_kit/ang/crmSearchDisplayGrid/crmSearchDisplayGridLoading.html
new file mode 100644 (file)
index 0000000..b63dd05
--- /dev/null
@@ -0,0 +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 class="crm-search-loading-placeholder"></div>
+</div>
index 5428a7713d1e755412e7e1812ffc474d979d7696..1b20b52b6d18c37d3a50093ba6db7415e1a23ed4 100644 (file)
@@ -1,6 +1,6 @@
 <div class="crm-search-display crm-search-display-list">
   <div ng-include="'~/crmSearchDisplay/SearchButton.html'" ng-if="$ctrl.settings.button"></div>
-  <ol ng-if=":: $ctrl.settings.style === 'ol'" ng-include="'~/crmSearchDisplayList/crmSearchDisplayListItems.html'" ng-style="{'list-style': $ctrl.settings.symbol}"></ol>
-  <ul ng-if=":: $ctrl.settings.style !== 'ol'" ng-include="'~/crmSearchDisplayList/crmSearchDisplayListItems.html'" ng-style="{'list-style': $ctrl.settings.symbol}"></ul>
+  <ol ng-if=":: $ctrl.settings.style === 'ol'" ng-include="'~/crmSearchDisplayList/crmSearchDisplayList' + ($ctrl.loading ? 'Loading' : 'Items') + '.html'" ng-style="{'list-style': $ctrl.settings.symbol}"></ol>
+  <ul ng-if=":: $ctrl.settings.style !== 'ol'" ng-include="'~/crmSearchDisplayList/crmSearchDisplayList' + ($ctrl.loading ? 'Loading' : 'Items') + '.html'" ng-style="{'list-style': $ctrl.settings.symbol}"></ul>
   <div ng-include="'~/crmSearchDisplay/Pager.html'"></div>
 </div>
diff --git a/ext/search_kit/ang/crmSearchDisplayList/crmSearchDisplayListLoading.html b/ext/search_kit/ang/crmSearchDisplayList/crmSearchDisplayListLoading.html
new file mode 100644 (file)
index 0000000..af84f53
--- /dev/null
@@ -0,0 +1,4 @@
+<!-- Placeholder shown during ajax loading -->
+<li ng-repeat="num in [1,2,3,4,5] track by $index">
+  <div class="crm-search-loading-placeholder"></div>
+</li>
index 5857239c13684814984f958f3c61e95f1c4fa488..b5e28566f74daaa788b7a9088c40e21d44d66af1 100644 (file)
@@ -15,7 +15,7 @@
         </th>
       </tr>
     </thead>
-    <tbody ng-include="'~/crmSearchDisplayTable/crmSearchDisplayTableBody.html'"></tbody>
+    <tbody ng-include="'~/crmSearchDisplayTable/crmSearchDisplayTable' + ($ctrl.loading ? 'Loading' : 'Body') + '.html'"></tbody>
   </table>
   <div ng-include="'~/crmSearchDisplay/Pager.html'"></div>
 </div>
diff --git a/ext/search_kit/ang/crmSearchDisplayTable/crmSearchDisplayTableLoading.html b/ext/search_kit/ang/crmSearchDisplayTable/crmSearchDisplayTableLoading.html
new file mode 100644 (file)
index 0000000..a3d0165
--- /dev/null
@@ -0,0 +1,9 @@
+<!-- Placeholder table rows shown during ajax loading -->
+<tr ng-repeat="num in [1,2,3,4,5] track by $index">
+  <td ng-if=":: $ctrl.settings.actions">
+    <input type="checkbox" disabled>
+  </td>
+  <td ng-repeat="col in $ctrl.settings.columns">
+    <div class="crm-search-loading-placeholder"></div>
+  </td>
+</tr>
diff --git a/ext/search_kit/css/crmSearchDisplay.css b/ext/search_kit/css/crmSearchDisplay.css
new file mode 100644 (file)
index 0000000..631f3d7
--- /dev/null
@@ -0,0 +1,40 @@
+/* Sortable headers */
+#bootstrap-theme .crm-search-display th[ng-click] {
+  cursor: pointer;
+}
+#bootstrap-theme .crm-search-display th i.fa-sort-desc,
+#bootstrap-theme .crm-search-display th i.fa-sort-asc {
+  color: #1a5a82;
+}
+#bootstrap-theme .crm-search-display th:not(:hover) i.fa-sort {
+  opacity: .5;
+}
+
+/* Loading placeholders */
+#bootstrap-theme .crm-search-loading-placeholder {
+  height: 2em;
+  width: 80%;
+  position: relative;
+  overflow: hidden;
+  background-color: rgba(0,0,0,.04);
+  display: inline-block;
+}
+#bootstrap-theme .crm-search-loading-placeholder::before {
+  content: '';
+  display: block;
+  position: absolute;
+  left: -150px;
+  top: 0;
+  height: 100%;
+  width: 150px;
+  background: linear-gradient(to right, transparent 0%, rgba(0,0,0,.1) 50%, transparent 100%);
+  animation: searchKitLoadingAnimation 1s cubic-bezier(0.4, 0.0, 0.2, 1) infinite;
+}
+@keyframes searchKitLoadingAnimation {
+  from {
+    left: -150px;
+  }
+  to   {
+    left: 100%;
+  }
+}
index dbd48542e1c2ea67f80c5e4b48cc1ba21a50bd4f..89fada1d5909697343b820e7a8f22db270184be5 100644 (file)
   bottom: -22px;
   left: 0;
 }
-#bootstrap-theme .crm-search-display th[ng-click] {
-  cursor: pointer;
-}
-#bootstrap-theme .crm-search-display th i.fa-sort-desc,
-#bootstrap-theme .crm-search-display th i.fa-sort-asc {
-  color: #1a5a82;
-}
-#bootstrap-theme .crm-search-display th:not(:hover) i.fa-sort {
-  opacity: .5;
-}