From 2b8e5ee4303f8aa7b55d75ac0a7de79c7aa6f944 Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Thu, 4 Feb 2021 09:32:32 -0500 Subject: [PATCH] Afform GUI - Enable blocks on search display afforms & optimize loading --- .../Civi/Api4/Action/Afform/LoadAdminData.php | 49 +++++++++++++------ .../ang/afGuiEditor/afGuiSearch.component.js | 15 ++++++ .../admin/ang/afGuiEditor/afGuiSearch.html | 8 +++ .../elements/afGuiContainer.component.js | 9 +++- 4 files changed, 64 insertions(+), 17 deletions(-) diff --git a/ext/afform/admin/Civi/Api4/Action/Afform/LoadAdminData.php b/ext/afform/admin/Civi/Api4/Action/Afform/LoadAdminData.php index 3341f3da58..f840cbec9e 100644 --- a/ext/afform/admin/Civi/Api4/Action/Afform/LoadAdminData.php +++ b/ext/afform/admin/Civi/Api4/Action/Afform/LoadAdminData.php @@ -15,6 +15,7 @@ class LoadAdminData extends \Civi\Api4\Generic\AbstractAction { /** * Any properties already known about the afform * @var array + * @required */ protected $definition; @@ -24,8 +25,14 @@ class LoadAdminData extends \Civi\Api4\Generic\AbstractAction { */ protected $entity; + /** + * A list of entities whose blocks & fields are not needed + * @var array + */ + protected $skipEntities = []; + public function _run(\Civi\Api4\Generic\Result $result) { - $info = ['fields' => [], 'blocks' => []]; + $info = ['entities' => [], 'fields' => [], 'blocks' => []]; $entities = []; $newForm = empty($this->definition['name']); @@ -81,7 +88,11 @@ class LoadAdminData extends \Civi\Api4\Generic\AbstractAction { foreach ($allAfforms as $name => $path) { $allAfforms[$name] = _afform_angular_module_name($name, 'dash'); } - // Find all entities by recursing into embedded afforms + + /** + * Find all entities by recursing into embedded afforms + * @param array $layout + */ $scanBlocks = function($layout) use (&$scanBlocks, &$info, &$entities, $allAfforms) { // Find declared af-entity tags foreach (\CRM_Utils_Array::findAll($layout, ['#tag' => 'af-entity']) as $afEntity) { @@ -171,7 +182,10 @@ class LoadAdminData extends \Civi\Api4\Generic\AbstractAction { $entities[] = explode(' AS ', $join[0])[0]; } } - $entities = array_unique($entities); + if (!$newForm) { + $scanBlocks($info['definition']['layout']); + } + $this->loadAvailableBlocks($entities, $info, [['join', 'IS NULL']]); } // Optimization - since contact fields are a combination of these three, @@ -180,10 +194,11 @@ class LoadAdminData extends \Civi\Api4\Generic\AbstractAction { $entities = array_diff($entities, ['Contact']); } - foreach ($entities as $entity) { + foreach (array_diff($entities, $this->skipEntities) as $entity) { $info['entities'][$entity] = AfformAdminMeta::getApiEntity($entity); $info['fields'][$entity] = AfformAdminMeta::getFields($entity, ['action' => $getFieldsMode]); } + $info['blocks'] = array_values($info['blocks']); $result[] = $info; } @@ -199,20 +214,24 @@ class LoadAdminData extends \Civi\Api4\Generic\AbstractAction { /** * Get basic info about blocks relevant to these entities. * - * @param $entities - * @param $info + * @param array $entities + * @param array $info + * @param array $where * @throws \API_Exception * @throws \Civi\API\Exception\UnauthorizedException */ - private function loadAvailableBlocks($entities, &$info) { - // The full contents of blocks used on the form have been loaded. Get basic info about others relevant to these entities. - $blockInfo = Afform::get($this->checkPermissions) - ->addSelect('name', 'title', 'block', 'join', 'directive_name', 'repeat') - ->addWhere('type', '=', 'block') - ->addWhere('block', 'IN', $entities) - ->addWhere('directive_name', 'NOT IN', array_keys($info['blocks'])) - ->execute(); - $info['blocks'] = array_merge(array_values($info['blocks']), (array) $blockInfo); + private function loadAvailableBlocks($entities, &$info, $where = []) { + $entities = array_diff($entities, $this->skipEntities); + if ($entities) { + $blockInfo = Afform::get($this->checkPermissions) + ->addSelect('name', 'title', 'block', 'join', 'directive_name', 'repeat') + ->setWhere($where) + ->addWhere('type', '=', 'block') + ->addWhere('block', 'IN', $entities) + ->addWhere('directive_name', 'NOT IN', array_keys($info['blocks'])) + ->execute(); + $info['blocks'] = array_merge(array_values($info['blocks']), (array) $blockInfo); + } } public function fields() { diff --git a/ext/afform/admin/ang/afGuiEditor/afGuiSearch.component.js b/ext/afform/admin/ang/afGuiEditor/afGuiSearch.component.js index cfe19c928c..e8d8be0581 100644 --- a/ext/afform/admin/ang/afGuiEditor/afGuiSearch.component.js +++ b/ext/afform/admin/ang/afGuiEditor/afGuiSearch.component.js @@ -13,6 +13,8 @@ var ctrl = this; $scope.controls = {}; $scope.fieldList = []; + $scope.blockList = []; + $scope.blockTitles = []; $scope.elementList = []; $scope.elementTitles = []; @@ -21,9 +23,22 @@ function buildPaletteLists() { var search = $scope.controls.fieldSearch ? $scope.controls.fieldSearch.toLowerCase() : null; buildFieldList(search); + buildBlockList(search); buildElementList(search); } + function buildBlockList(search) { + $scope.blockList.length = 0; + $scope.blockTitles.length = 0; + _.each(afGui.meta.blocks, function(block, directive) { + if (!search || _.contains(directive, search) || _.contains(block.name.toLowerCase(), search) || _.contains(block.title.toLowerCase(), search)) { + var item = {"#tag": directive}; + $scope.blockList.push(item); + $scope.blockTitles.push(block.title); + } + }); + } + function buildFieldList(search) { $scope.fieldList.length = 0; var entity = afGui.getEntity(ctrl.display['saved_search.api_entity']), diff --git a/ext/afform/admin/ang/afGuiEditor/afGuiSearch.html b/ext/afform/admin/ang/afGuiEditor/afGuiSearch.html index aaaccd991f..f166371a00 100644 --- a/ext/afform/admin/ang/afGuiEditor/afGuiSearch.html +++ b/ext/afform/admin/ang/afGuiEditor/afGuiSearch.html @@ -5,6 +5,14 @@
+
+ +
+
+ {{ blockTitles[$index] }} +
+
+
diff --git a/ext/afform/admin/ang/afGuiEditor/elements/afGuiContainer.component.js b/ext/afform/admin/ang/afGuiEditor/elements/afGuiContainer.component.js index aa85e2e5c5..745c596eee 100644 --- a/ext/afform/admin/ang/afGuiEditor/elements/afGuiContainer.component.js +++ b/ext/afform/admin/ang/afGuiEditor/elements/afGuiContainer.component.js @@ -22,7 +22,12 @@ if (blockTag && (blockTag in afGui.meta.blocks) && !afGui.meta.blocks[blockTag].layout) { ctrl.loading = true; crmApi4('Afform', 'loadAdminData', { - definition: {name: afGui.meta.blocks[blockTag].name} + definition: {name: afGui.meta.blocks[blockTag].name}, + skipEntities: _.transform(afGui.meta.entities, function(result, entity, entityName) { + if (entity.fields) { + result.push(entityName); + } + }, []) }, 0).then(function(data) { afGui.addMeta(data); initializeBlockContainer(); @@ -180,7 +185,7 @@ }; _.each(afGui.meta.blocks, function(blockInfo, directive) { - if (directive === ctrl.node['#tag'] || blockInfo.join === ctrl.getFieldEntityType()) { + if (directive === ctrl.node['#tag'] || (blockInfo.join && blockInfo.join === ctrl.getFieldEntityType())) { block.options.push({ id: directive, text: blockInfo.title -- 2.25.1