SearchKit - Add Import dialog
authorColeman Watts <coleman@civicrm.org>
Wed, 8 Dec 2021 17:04:36 +0000 (12:04 -0500)
committerColeman Watts <coleman@civicrm.org>
Mon, 20 Dec 2021 21:51:32 +0000 (16:51 -0500)
ext/search_kit/ang/crmSearchAdmin.ang.php
ext/search_kit/ang/crmSearchAdmin.module.js
ext/search_kit/ang/crmSearchAdmin/crmSearchAdminImport.component.js [new file with mode: 0644]
ext/search_kit/ang/crmSearchAdmin/crmSearchAdminImport.html [new file with mode: 0644]
ext/search_kit/ang/crmSearchAdmin/searchListing/import.html [new file with mode: 0644]
ext/search_kit/ang/crmSearchAdmin/searchListing/searchList.html
ext/search_kit/css/crmSearchAdmin.css

index f6c673415c8f1d7cbc97e68bb138ef33a3c51a1e..346f08243a30cb2d407943c44f1769de28cbd167 100644 (file)
@@ -15,7 +15,7 @@ return [
   ],
   'bundles' => ['bootstrap3'],
   'basePages' => ['civicrm/admin/search'],
-  'requires' => ['crmUi', 'crmUtil', 'ngRoute', 'ui.sortable', 'ui.bootstrap', 'api4', 'crmSearchTasks', 'crmRouteBinder'],
+  'requires' => ['crmUi', 'crmUtil', 'ngRoute', 'ui.sortable', 'ui.bootstrap', 'api4', 'crmSearchTasks', 'crmRouteBinder', 'crmDialog'],
   'settingsFactory' => ['\Civi\Search\Admin', 'getAdminSettings'],
   'permissions' => ['all CiviCRM permissions and ACLs'],
 ];
index 5e34b1ee6665a8e186fc2941037476988dc6406c..7e2edcfd6e65afd5ebca0dc4bb1e9cdff0795bef 100644 (file)
@@ -45,7 +45,7 @@
     })
 
     // Controller for tabbed view of SavedSearches
-    .controller('searchList', function($scope, searchMeta, formatForSelect2) {
+    .controller('searchList', function($scope, $timeout, searchMeta, formatForSelect2, dialogService) {
       var ts = $scope.ts = CRM.ts('org.civicrm.search_kit'),
         ctrl = $scope.$ctrl = this;
       searchEntity = 'SavedSearch';
       if (!this.tab) {
         this.tab = this.tabs[0].name;
       }
+
+      this.openImportDialog = function() {
+        var options = CRM.utils.adjustDialogDefaults({
+          autoOpen: false,
+          title: ts('Import Saved Search')
+        });
+        dialogService.open('crmSearchAdminImport', '~/crmSearchAdmin/searchListing/import.html', {}, options)
+          .then(function() {
+            // Refresh the custom tab by resetting the filters
+            ctrl.tabs[0].filters = {};
+            // Timeout ensures the change gets noticed by the display's $watch
+            $timeout(function() {
+              ctrl.tabs[0].filters = {has_base: false};
+            }, 300);
+          }, _.noop);
+      };
     })
 
     // Controller for creating a new search
diff --git a/ext/search_kit/ang/crmSearchAdmin/crmSearchAdminImport.component.js b/ext/search_kit/ang/crmSearchAdmin/crmSearchAdminImport.component.js
new file mode 100644 (file)
index 0000000..cfc3b7d
--- /dev/null
@@ -0,0 +1,41 @@
+(function(angular, $, _) {
+  "use strict";
+
+  angular.module('crmSearchAdmin').component('crmSearchAdminImport', {
+    templateUrl: '~/crmSearchAdmin/crmSearchAdminImport.html',
+    controller: function ($scope, dialogService, crmApi4) {
+      var ts = $scope.ts = CRM.ts('org.civicrm.search_kit'),
+        ctrl = this;
+
+      this.values = '';
+
+      this.run = function() {
+        ctrl.running = true;
+        try {
+          var apiCalls = JSON.parse(ctrl.values);
+          _.each(apiCalls, function(apiCall) {
+            if (apiCall[1] !== 'create' || ('chain' in apiCall[2] && !_.isEmpty(apiCall[2].chain))) {
+              throw ts('Unsupported API action: only "create" is allowed.');
+            }
+          });
+          crmApi4(apiCalls)
+            .then(function(result) {
+              CRM.alert(
+                result.length === 1 ? ts('1 record successfully imported.') : ts('%1 records successfully imported.', {1: results.length}),
+                ts('Saved'),
+                'success'
+              );
+              dialogService.close('crmSearchAdminImport');
+            }, function(error) {
+              ctrl.running = false;
+              alert(ts('Processing Error') + "\n" + error.error_message);
+            });
+        } catch(e) {
+          ctrl.running = false;
+          alert(ts('Input Error') + "\n" + e);
+        }
+      };
+    }
+  });
+
+})(angular, CRM.$, CRM._);
diff --git a/ext/search_kit/ang/crmSearchAdmin/crmSearchAdminImport.html b/ext/search_kit/ang/crmSearchAdmin/crmSearchAdminImport.html
new file mode 100644 (file)
index 0000000..64872d1
--- /dev/null
@@ -0,0 +1,14 @@
+<div id="bootstrap-theme" crm-dialog="crmSearchAdminImport">
+  <div class="alert alert-info">
+    <p>
+      <i class="crm-i fa-info-circle"></i>
+      {{:: ts('A Search configuration copied from the "Export" action can be pasted here.') }}
+    </p>
+    <p>
+      {{:: ts('Note: a Saved Search with the same name must not already exist.') }}
+    </p>
+  </div>
+  <textarea id="crm-search-admin-export-output-code" class="form-control" ng-model="$ctrl.values" rows="15"></textarea>
+  <crm-dialog-button text="ts('Import')" icons="{primary: 'fa-save'}" on-click="$ctrl.run()" disabled="$ctrl.running || !$ctrl.values" />
+  <crm-dialog-button text="ts('Cancel')" icons="{primary: 'fa-times'}" on-click="crmSearchAdminImport.cancel()" disabled="$ctrl.running" />
+</div>
diff --git a/ext/search_kit/ang/crmSearchAdmin/searchListing/import.html b/ext/search_kit/ang/crmSearchAdmin/searchListing/import.html
new file mode 100644 (file)
index 0000000..c990104
--- /dev/null
@@ -0,0 +1 @@
+<crm-search-admin-import></crm-search-admin-import>
index f549ca1bca15d8b396aa9f479eba98365fadde07..9eaa2bfda105769c7fd4c663d58cd137b1756017 100644 (file)
       <span ng-if="$ctrl.getTags().results.length">
         <input class="form-control" ng-model="tab.filters.tags" ng-list crm-ui-select="{multiple: true, data: $ctrl.getTags, placeholder: ts('Filter by tags...')}">
       </span>
+      <a class="btn btn-secondary btn-sm pull-right" ng-if="tab.name === 'custom'" href ng-click="$ctrl.openImportDialog()">
+        <i class="crm-i fa-upload"></i>
+        {{:: ts('Import') }}
+      </a>
     </div>
     <crm-search-admin-search-listing filters="tab.filters" tab-count="tab.rowCount"></crm-search-admin-search-listing>
   </div>
index 3d159af72a4c2f56d3d9c2826f66719a2bc620bd..cfcb8941ba7592304c03677ebcae70c1435e6f91 100644 (file)
   text-align: left;
 }
 
-crm-search-admin-export {
+crm-search-admin-export,
+crm-search-admin-import {
   display: block;
 }