From: Coleman Watts Date: Tue, 13 Oct 2020 15:54:36 +0000 (-0400) Subject: Search ext: Reorganize into searchAdmin and searchActions modules X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=e78d6a2d4feafe787dbeee0b6afa34741b32e295;p=civicrm-core.git Search ext: Reorganize into searchAdmin and searchActions modules --- diff --git a/ext/search/CRM/Search/Page/Ang.php b/ext/search/CRM/Search/Page/Admin.php similarity index 64% rename from ext/search/CRM/Search/Page/Ang.php rename to ext/search/CRM/Search/Page/Admin.php index 22cab1dcfa..c1d06ab0f8 100644 --- a/ext/search/CRM/Search/Page/Ang.php +++ b/ext/search/CRM/Search/Page/Admin.php @@ -1,6 +1,18 @@ $this->schema, 'links' => $this->getLinks(), 'loadOptions' => $this->loadOptions, - 'actions' => $this->getActions(), 'functions' => CRM_Api4_Page_Api4Explorer::getSqlFunctions(), ]; Civi::resources() - ->addPermissions(['edit groups', 'administer reserved groups']) ->addBundle('bootstrap3') ->addVars('search', $vars); // Load angular module $loader = new Civi\Angular\AngularLoader(); - $loader->setModules(['search']); + $loader->setModules(['searchAdmin']); $loader->setPageName('civicrm/search'); $loader->useApp([ 'defaultRoute' => '/create/Contact', @@ -134,65 +144,4 @@ class CRM_Search_Page_Ang extends CRM_Core_Page { return array_filter($results); } - /** - * @return array[] - */ - private function getActions() { - // Note: the placeholder %1 will be replaced with entity name on the clientside - $actions = [ - 'export' => [ - 'title' => ts('Export %1'), - 'icon' => 'fa-file-excel-o', - 'entities' => array_keys(CRM_Export_BAO_Export::getComponents()), - 'crmPopup' => [ - 'path' => "'civicrm/export/standalone'", - 'query' => "{entity: entity, id: ids.join(',')}", - ], - ], - 'update' => [ - 'title' => ts('Update %1'), - 'icon' => 'fa-save', - 'entities' => [], - 'uiDialog' => ['templateUrl' => '~/search/crmSearchActions/crmSearchActionUpdate.html'], - ], - 'delete' => [ - 'title' => ts('Delete %1'), - 'icon' => 'fa-trash', - 'entities' => [], - 'uiDialog' => ['templateUrl' => '~/search/crmSearchActions/crmSearchActionDelete.html'], - ], - ]; - - // Check permissions for update & delete actions - foreach ($this->allowedEntities as $entity) { - $result = civicrm_api4($entity, 'getActions', [ - 'where' => [['name', 'IN', ['update', 'delete']]], - ], ['name']); - foreach ($result as $action) { - // Contacts have their own delete action - if (!($entity === 'Contact' && $action === 'delete')) { - $actions[$action]['entities'][] = $entity; - } - } - } - - // Add contact tasks which support standalone mode (with a 'url' property) - $contactTasks = CRM_Contact_Task::permissionedTaskTitles(CRM_Core_Permission::getPermission()); - foreach (CRM_Contact_Task::tasks() as $id => $task) { - if (isset($contactTasks[$id]) && !empty($task['url'])) { - $actions['contact.' . $id] = [ - 'title' => $task['title'], - 'entities' => ['Contact'], - 'icon' => $task['icon'] ?? 'fa-gear', - 'crmPopup' => [ - 'path' => "'{$task['url']}'", - 'query' => "{cids: ids.join(',')}", - ], - ]; - } - } - - return $actions; - } - } diff --git a/ext/search/Civi/Search/Actions.php b/ext/search/Civi/Search/Actions.php new file mode 100644 index 0000000000..4771101183 --- /dev/null +++ b/ext/search/Civi/Search/Actions.php @@ -0,0 +1,90 @@ + self::getTasks(), + 'groupOptions' => self::getGroupOptions(), + ]; + } + + /** + * @return array + */ + public static function getGroupOptions():array { + return \Civi\Api4\Group::getFields(FALSE) + ->setLoadOptions(['id', 'label']) + ->addWhere('name', 'IN', ['group_type', 'visibility']) + ->execute() + ->indexBy('name') + ->column('options'); + } + + /** + * @return array + */ + public static function getTasks():array { + // Note: the placeholder %1 will be replaced with entity name on the clientside + $tasks = [ + 'export' => [ + 'title' => ts('Export %1'), + 'icon' => 'fa-file-excel-o', + 'entities' => array_keys(\CRM_Export_BAO_Export::getComponents()), + 'crmPopup' => [ + 'path' => "'civicrm/export/standalone'", + 'query' => "{entity: entity, id: ids.join(',')}", + ], + ], + 'update' => [ + 'title' => ts('Update %1'), + 'icon' => 'fa-save', + 'entities' => [], + 'uiDialog' => ['templateUrl' => '~/searchActions/crmSearchActionUpdate.html'], + ], + 'delete' => [ + 'title' => ts('Delete %1'), + 'icon' => 'fa-trash', + 'entities' => [], + 'uiDialog' => ['templateUrl' => '~/searchActions/crmSearchActionDelete.html'], + ], + ]; + + // Add contact tasks which support standalone mode (with a 'url' property) + $contactTasks = \CRM_Contact_Task::permissionedTaskTitles(\CRM_Core_Permission::getPermission()); + foreach (\CRM_Contact_Task::tasks() as $id => $task) { + if (isset($contactTasks[$id]) && !empty($task['url']) && $task['url'] !== 'civicrm/task/delete-contact') { + $tasks['contact.' . $id] = [ + 'title' => $task['title'], + 'entities' => ['Contact'], + 'icon' => $task['icon'] ?? 'fa-gear', + 'crmPopup' => [ + 'path' => "'{$task['url']}'", + 'query' => "{cids: ids.join(',')}", + ], + ]; + } + } + + return $tasks; + } + +} diff --git a/ext/search/ang/searchActions.ang.php b/ext/search/ang/searchActions.ang.php new file mode 100644 index 0000000000..6699110540 --- /dev/null +++ b/ext/search/ang/searchActions.ang.php @@ -0,0 +1,16 @@ + [ + 'ang/searchActions.module.js', + 'ang/searchActions/*.js', + 'ang/searchActions/*/*.js', + ], + 'partials' => [ + 'ang/searchActions', + ], + 'basePages' => [], + 'requires' => ['crmUi', 'crmUtil', 'dialogService', 'api4'], + 'settingsFactory' => ['\Civi\Search\Actions', 'getActionSettings'], + 'permissions' => ['edit groups', 'administer reserved groups'], +]; diff --git a/ext/search/ang/searchActions.module.js b/ext/search/ang/searchActions.module.js new file mode 100644 index 0000000000..9f4204c0bf --- /dev/null +++ b/ext/search/ang/searchActions.module.js @@ -0,0 +1,7 @@ +(function(angular, $, _) { + "use strict"; + + // Declare module + angular.module('searchActions', CRM.angRequires('searchActions')); + +})(angular, CRM.$, CRM._); diff --git a/ext/search/ang/search/SaveSmartGroup.ctrl.js b/ext/search/ang/searchActions/SaveSmartGroup.ctrl.js similarity index 93% rename from ext/search/ang/search/SaveSmartGroup.ctrl.js rename to ext/search/ang/searchActions/SaveSmartGroup.ctrl.js index 47837b2c8c..ab6cb21447 100644 --- a/ext/search/ang/search/SaveSmartGroup.ctrl.js +++ b/ext/search/ang/searchActions/SaveSmartGroup.ctrl.js @@ -1,7 +1,7 @@ (function(angular, $, _) { "use strict"; - angular.module('search').controller('SaveSmartGroup', function ($scope, $element, $timeout, crmApi4, dialogService, searchMeta) { + angular.module('searchActions').controller('SaveSmartGroup', function ($scope, $element, $timeout, crmApi4, dialogService, searchMeta) { var ts = $scope.ts = CRM.ts(), model = $scope.model, joins = _.pluck((model.api_params.join || []), 0), @@ -53,7 +53,7 @@ $scope.perm = { administerReservedGroups: CRM.checkPerm('administer reserved groups') }; - $scope.groupFields = _.indexBy(_.find(CRM.vars.search.schema, {name: 'Group'}).fields, 'name'); + $scope.groupOptions = CRM.searchActions.groupOptions; $element.on('change', '#api-save-search-select-group', function() { if ($(this).val()) { $scope.$apply(function() { diff --git a/ext/search/ang/search/crmSearchActions/crmSearchActionDelete.ctrl.js b/ext/search/ang/searchActions/crmSearchActionDelete.ctrl.js similarity index 80% rename from ext/search/ang/search/crmSearchActions/crmSearchActionDelete.ctrl.js rename to ext/search/ang/searchActions/crmSearchActionDelete.ctrl.js index 28a401e652..f81d915acf 100644 --- a/ext/search/ang/search/crmSearchActions/crmSearchActionDelete.ctrl.js +++ b/ext/search/ang/searchActions/crmSearchActionDelete.ctrl.js @@ -1,7 +1,7 @@ (function(angular, $, _) { "use strict"; - angular.module('search').controller('crmSearchActionDelete', function($scope, crmApi4, dialogService, searchMeta) { + angular.module('searchActions').controller('crmSearchActionDelete', function($scope, crmApi4, dialogService, searchMeta) { var ts = $scope.ts = CRM.ts(), model = $scope.model, ctrl = $scope.$ctrl = this; diff --git a/ext/search/ang/search/crmSearchActions/crmSearchActionDelete.html b/ext/search/ang/searchActions/crmSearchActionDelete.html similarity index 100% rename from ext/search/ang/search/crmSearchActions/crmSearchActionDelete.html rename to ext/search/ang/searchActions/crmSearchActionDelete.html diff --git a/ext/search/ang/search/crmSearchActions/crmSearchActionUpdate.ctrl.js b/ext/search/ang/searchActions/crmSearchActionUpdate.ctrl.js similarity index 92% rename from ext/search/ang/search/crmSearchActions/crmSearchActionUpdate.ctrl.js rename to ext/search/ang/searchActions/crmSearchActionUpdate.ctrl.js index a4fb759887..b44acb29a9 100644 --- a/ext/search/ang/search/crmSearchActions/crmSearchActionUpdate.ctrl.js +++ b/ext/search/ang/searchActions/crmSearchActionUpdate.ctrl.js @@ -1,7 +1,7 @@ (function(angular, $, _) { "use strict"; - angular.module('search').controller('crmSearchActionUpdate', function ($scope, $timeout, crmApi4, dialogService, searchMeta) { + angular.module('searchActions').controller('crmSearchActionUpdate', function ($scope, $timeout, crmApi4, dialogService, searchMeta) { var ts = $scope.ts = CRM.ts(), model = $scope.model, ctrl = $scope.$ctrl = this; diff --git a/ext/search/ang/search/crmSearchActions/crmSearchActionUpdate.html b/ext/search/ang/searchActions/crmSearchActionUpdate.html similarity index 100% rename from ext/search/ang/search/crmSearchActions/crmSearchActionUpdate.html rename to ext/search/ang/searchActions/crmSearchActionUpdate.html diff --git a/ext/search/ang/search/crmSearchActions.component.js b/ext/search/ang/searchActions/crmSearchActions.component.js similarity index 66% rename from ext/search/ang/search/crmSearchActions.component.js rename to ext/search/ang/searchActions/crmSearchActions.component.js index 212b8d914f..a7bfb3cef5 100644 --- a/ext/search/ang/search/crmSearchActions.component.js +++ b/ext/search/ang/searchActions/crmSearchActions.component.js @@ -1,29 +1,44 @@ (function(angular, $, _) { "use strict"; - angular.module('search').component('crmSearchActions', { + angular.module('searchActions').component('crmSearchActions', { bindings: { entity: '<', refresh: '&', ids: '<' }, - templateUrl: '~/search/crmSearchActions.html', + templateUrl: '~/searchActions/crmSearchActions.html', controller: function($scope, crmApi4, dialogService, searchMeta) { var ts = $scope.ts = CRM.ts(), - ctrl = this; + ctrl = this, + initialized = false, + unwatchIDs = $scope.$watch('$ctrl.ids.length', watchIDs); - this.$onInit = function() { + function watchIDs() { + if (ctrl.ids && ctrl.ids.length && !initialized) { + unwatchIDs(); + initialized = true; + initialize(); + } + } + + function initialize() { var entityTitle = searchMeta.getEntity(ctrl.entity).titlePlural; - if (!ctrl.actions) { - var actions = _.transform(_.cloneDeep(CRM.vars.search.actions), function (actions, action) { + crmApi4(ctrl.entity, 'getActions', { + where: [['name', 'IN', ['update', 'delete']]], + }, ['name']).then(function(allowed) { + _.each(allowed, function(action) { + CRM.searchActions.tasks[action].entities.push(ctrl.entity); + }); + var actions = _.transform(_.cloneDeep(CRM.searchActions.tasks), function(actions, action) { if (_.includes(action.entities, ctrl.entity)) { action.title = action.title.replace('%1', entityTitle); actions.push(action); } }, []); ctrl.actions = _.sortBy(actions, 'title'); - } - }; + }); + } this.isActionAllowed = function(action) { return !action.number || $scope.eval('' + $ctrl.ids.length + action.number); diff --git a/ext/search/ang/search/crmSearchActions.html b/ext/search/ang/searchActions/crmSearchActions.html similarity index 67% rename from ext/search/ang/search/crmSearchActions.html rename to ext/search/ang/searchActions/crmSearchActions.html index 7442efbe09..41696415e0 100644 --- a/ext/search/ang/search/crmSearchActions.html +++ b/ext/search/ang/searchActions/crmSearchActions.html @@ -1,5 +1,5 @@
-