From 2c7e2f4b6b195988da15a99566b5f1e3041b9089 Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Fri, 11 Sep 2020 11:58:52 -0400 Subject: [PATCH] Search ext: load saved searches --- ext/search/CRM/Search/Page/Ang.php | 2 +- ext/search/ang/search.module.js | 56 ++++++++++++++++--- ext/search/ang/search/SaveSmartGroup.ctrl.js | 14 +++-- ext/search/ang/search/crmSearch.component.js | 27 +++++++-- ext/search/ang/search/crmSearch/criteria.html | 8 ++- 5 files changed, 89 insertions(+), 18 deletions(-) diff --git a/ext/search/CRM/Search/Page/Ang.php b/ext/search/CRM/Search/Page/Ang.php index 2549f622d5..e38271a694 100644 --- a/ext/search/CRM/Search/Page/Ang.php +++ b/ext/search/CRM/Search/Page/Ang.php @@ -49,7 +49,7 @@ class CRM_Search_Page_Ang extends CRM_Core_Page { $loader->setModules(['search']); $loader->setPageName('civicrm/search'); $loader->useApp([ - 'defaultRoute' => '/Contact', + 'defaultRoute' => '/create/Contact', ]); $loader->load(); parent::run(); diff --git a/ext/search/ang/search.module.js b/ext/search/ang/search.module.js index 3b2eeb34ff..ed60680e00 100644 --- a/ext/search/ang/search.module.js +++ b/ext/search/ang/search.module.js @@ -2,27 +2,67 @@ "use strict"; // Shared between router and searchMeta service - var searchEntity; + var searchEntity, + // For loading saved search + savedSearch, + undefined; // Declare module and route/controller/services angular.module('search', CRM.angRequires('search')) .config(function($routeProvider) { - $routeProvider.when('/:entity', { + $routeProvider.when('/:mode/:entity/:name?', { controller: 'searchRoute', - template: '', - reloadOnSearch: false + template: '', + reloadOnSearch: false, + resolve: { + // For paths like /load/Group/MySmartGroup, load the group, stash it in the savedSearch variable, and then redirect + // For paths like /create/Contact, return the stashed savedSearch if present + savedSearch: function($route, $location, $timeout, crmApi4) { + var retrievedSearch = savedSearch, + params = $route.current.params; + savedSearch = undefined; + switch (params.mode) { + case 'create': + return retrievedSearch; + + case 'load': + // In theory savedSearches could be attached to something other than groups, but for now that's not supported + if (params.entity !== 'Group' || !params.name) { + throw 'Failed to load ' + params.entity; + } + return crmApi4(params.entity, 'get', { + select: ['id', 'title', 'saved_search_id', 'saved_search.api_entity', 'saved_search.api_params'], + where: [['name', '=', params.name]] + }, 0).then(function(retrieved) { + savedSearch = { + type: params.entity, + id: retrieved.id, + title: retrieved.title, + saved_search_id: retrieved.saved_search_id, + api_params: retrieved['saved_search.api_params'] + }; + $timeout(function() { + $location.url('/create/' + retrieved['saved_search.api_entity']); + }); + }); + } + } + } }); }) // Controller binds entity to route - .controller('searchRoute', function($scope, $routeParams, $location) { - searchEntity = $scope.entity = $routeParams.entity; + .controller('searchRoute', function($scope, $routeParams, $location, savedSearch) { + searchEntity = this.entity = $routeParams.entity; + this.mode = $routeParams.mode; + this.savedSearch = savedSearch; + $scope.$ctrl = this; // Changing entity will refresh the angular page - $scope.$watch('entity', function(newEntity, oldEntity) { + $scope.$watch('$ctrl.entity', function(newEntity, oldEntity) { if (newEntity && oldEntity && newEntity !== oldEntity) { - $location.url('/' + newEntity); + $location.url('/create/' + newEntity); } }); }) diff --git a/ext/search/ang/search/SaveSmartGroup.ctrl.js b/ext/search/ang/search/SaveSmartGroup.ctrl.js index 74401b9847..18b0298e96 100644 --- a/ext/search/ang/search/SaveSmartGroup.ctrl.js +++ b/ext/search/ang/search/SaveSmartGroup.ctrl.js @@ -1,7 +1,7 @@ (function(angular, $, _) { "use strict"; - angular.module('search').controller('SaveSmartGroup', function ($scope, crmApi4, dialogService) { + angular.module('search').controller('SaveSmartGroup', function ($scope, $element, crmApi4, dialogService) { var ts = $scope.ts = CRM.ts(), model = $scope.model; $scope.groupEntityRefParams = { @@ -23,9 +23,15 @@ administerReservedGroups: CRM.checkPerm('administer reserved groups') }; $scope.groupFields = _.indexBy(_.find(CRM.vars.search.schema, {name: 'Group'}).fields, 'name'); - $scope.$watch('model.id', function (id) { - if (id) { - _.assign(model, $('#api-save-search-select-group').select2('data').extra); + $element.on('change', '#api-save-search-select-group', function() { + if ($(this).val()) { + $scope.$apply(function() { + var group = $('#api-save-search-select-group').select2('data').extra; + model.saved_search_id = group.saved_search_id; + model.description = group.description || ''; + model.group_type = group.group_type || []; + model.visibility = group.visibility; + }); } }); $scope.cancel = function () { diff --git a/ext/search/ang/search/crmSearch.component.js b/ext/search/ang/search/crmSearch.component.js index 039e74d99a..30ebfa99c3 100644 --- a/ext/search/ang/search/crmSearch.component.js +++ b/ext/search/ang/search/crmSearch.component.js @@ -3,7 +3,8 @@ angular.module('search').component('crmSearch', { bindings: { - entity: '=' + entity: '=', + load: '<' }, templateUrl: '~/search/crmSearch.html', controller: function($scope, $element, $timeout, crmApi4, dialogService, searchMeta, formatForSelect2) { @@ -244,6 +245,9 @@ ctrl.stale = true; } } + if (ctrl.load) { + ctrl.load.saved = false; + } } function onChangeOrderBy() { @@ -255,6 +259,9 @@ function onChangeFilters() { ctrl.stale = true; ctrl.selectedRows.length = 0; + if (ctrl.load) { + ctrl.load.saved = false; + } if (ctrl.autoSearch) { ctrl.refreshAll(); } @@ -526,6 +533,13 @@ } $scope.$watch('$ctrl.params.having', onChangeFilters, true); + if (this.load) { + this.params = this.load.api_params; + $timeout(function() { + ctrl.load.saved = true; + }); + } + loadFieldOptions(); }; @@ -540,16 +554,21 @@ description: '', visibility: 'User and User Admin Only', group_type: [], - id: null, + id: ctrl.load ? ctrl.load.id : null, entity: ctrl.entity, - params: angular.extend({}, ctrl.params, {version: 4, select: [selectField]}) + params: angular.extend({}, ctrl.params, {version: 4}) }; delete model.params.orderBy; var options = CRM.utils.adjustDialogDefaults({ autoOpen: false, title: ts('Save smart group') }); - dialogService.open('saveSearchDialog', '~/search/saveSmartGroup.html', model, options); + dialogService.open('saveSearchDialog', '~/search/saveSmartGroup.html', model, options) + .then(function() { + if (ctrl.load) { + ctrl.load.saved = true; + } + }); }; } }); diff --git a/ext/search/ang/search/crmSearch/criteria.html b/ext/search/ang/search/crmSearch/criteria.html index 6bb500a741..a142e498c5 100644 --- a/ext/search/ang/search/crmSearch/criteria.html +++ b/ext/search/ang/search/crmSearch/criteria.html @@ -2,7 +2,7 @@
- +
@@ -40,6 +40,12 @@
+
-- 2.25.1