From 4159717939212c27482b05458b219a15a7b4cf80 Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Tue, 24 Aug 2021 13:36:11 -0400 Subject: [PATCH] Afform - move max-repeat to entity definition not afform block definition Adds entity definition files for joins like Email, Address, etc, and pre-loads all joined entities including custom on the afform gui screen. --- .../Civi/AfformAdmin/AfformAdminMeta.php | 31 ++++++++++++++++--- .../Civi/Api4/Action/Afform/LoadAdminData.php | 2 +- ext/afform/admin/afformEntities/Activity.php | 1 + ext/afform/admin/afformEntities/Address.php | 5 +++ ext/afform/admin/afformEntities/Email.php | 5 +++ ext/afform/admin/afformEntities/Household.php | 1 + ext/afform/admin/afformEntities/IM.php | 5 +++ .../admin/afformEntities/Individual.php | 1 + .../admin/afformEntities/Organization.php | 1 + ext/afform/admin/afformEntities/Phone.php | 5 +++ ext/afform/admin/afformEntities/Website.php | 5 +++ .../ang/afAdmin/afAdminList.controller.js | 2 +- .../ang/afGuiEditor/afGuiEntity.component.js | 11 ++++--- .../elements/afGuiContainer-menu.html | 2 +- .../elements/afGuiContainer.component.js | 12 +++++++ .../core/Civi/Api4/Action/Afform/Get.php | 1 - ext/afform/core/Civi/Api4/Afform.php | 4 --- .../core/ang/afblockContactAddress.aff.json | 3 +- .../core/ang/afblockContactEmail.aff.json | 3 +- ext/afform/core/ang/afblockContactIM.aff.json | 3 +- .../core/ang/afblockContactPhone.aff.json | 3 +- .../core/ang/afblockContactWebsite.aff.json | 3 +- 22 files changed, 83 insertions(+), 26 deletions(-) create mode 100644 ext/afform/admin/afformEntities/Address.php create mode 100644 ext/afform/admin/afformEntities/Email.php create mode 100644 ext/afform/admin/afformEntities/IM.php create mode 100644 ext/afform/admin/afformEntities/Phone.php create mode 100644 ext/afform/admin/afformEntities/Website.php diff --git a/ext/afform/admin/Civi/AfformAdmin/AfformAdminMeta.php b/ext/afform/admin/Civi/AfformAdmin/AfformAdminMeta.php index fa8554171b..e34943a99a 100644 --- a/ext/afform/admin/Civi/AfformAdmin/AfformAdminMeta.php +++ b/ext/afform/admin/Civi/AfformAdmin/AfformAdminMeta.php @@ -2,6 +2,7 @@ namespace Civi\AfformAdmin; +use Civi\Api4\Entity; use Civi\Api4\Utils\CoreUtil; use CRM_AfformAdmin_ExtensionUtil as E; @@ -67,17 +68,32 @@ class AfformAdminMeta { } $info = \Civi\Api4\Entity::get(FALSE) ->addWhere('name', '=', $entityName) - ->addSelect('title', 'icon') ->execute()->first(); if (!$info) { // Disabled contact type or nonexistent api entity return NULL; } - return [ - 'entity' => $entityName, + return self::entityToAfformMeta($info); + } + + /** + * Converts info from API.Entity.get to an array of afform entity metadata + * @param array $info + * @return array + */ + private static function entityToAfformMeta(array $info): array { + $meta = [ + 'entity' => $info['name'], 'label' => $info['title'], 'icon' => $info['icon'], ]; + // Custom entities are always type 'join' + if (in_array('CustomValue', $info['type'], TRUE)) { + $meta['type'] = 'join'; + $max = (int) \CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomGroup', substr($info['name'], 7), 'max_multiple', 'name'); + $meta['repeat_max'] = $max ?: NULL; + } + return $meta; } /** @@ -140,10 +156,17 @@ class AfformAdminMeta { 'icon' => 'fa-pencil-square-o', 'fields' => [], ], - 'Contact' => self::getApiEntity('Contact'), ], ]; + // Explicitly load Contact and Custom entities because they do not have afformEntity files + $entities = Entity::get(TRUE) + ->addClause('OR', ['name', '=', 'Contact'], ['type', 'CONTAINS', 'CustomValue']) + ->execute()->indexBy('name'); + foreach ($entities as $name => $entity) { + $data['entities'][$name] = self::entityToAfformMeta($entity); + } + $contactTypes = \CRM_Contact_BAO_ContactType::basicTypeInfo(); // Call getFields on getFields to get input type labels diff --git a/ext/afform/admin/Civi/Api4/Action/Afform/LoadAdminData.php b/ext/afform/admin/Civi/Api4/Action/Afform/LoadAdminData.php index fa2c2f535a..289206b08f 100644 --- a/ext/afform/admin/Civi/Api4/Action/Afform/LoadAdminData.php +++ b/ext/afform/admin/Civi/Api4/Action/Afform/LoadAdminData.php @@ -237,7 +237,7 @@ class LoadAdminData extends \Civi\Api4\Generic\AbstractAction { } if ($entities) { $blockInfo = Afform::get($this->checkPermissions) - ->addSelect('name', 'title', 'entity_type', 'join_entity', 'directive_name', 'repeat') + ->addSelect('name', 'title', 'entity_type', 'join_entity', 'directive_name') ->setWhere($where) ->addWhere('type', '=', 'block') ->addWhere('entity_type', 'IN', $entities) diff --git a/ext/afform/admin/afformEntities/Activity.php b/ext/afform/admin/afformEntities/Activity.php index 860d68fd1d..cff72ead28 100644 --- a/ext/afform/admin/afformEntities/Activity.php +++ b/ext/afform/admin/afformEntities/Activity.php @@ -1,5 +1,6 @@ 'primary', 'defaults' => "{ data: { source_contact_id: 'user_contact_id', diff --git a/ext/afform/admin/afformEntities/Address.php b/ext/afform/admin/afformEntities/Address.php new file mode 100644 index 0000000000..a8a35545a2 --- /dev/null +++ b/ext/afform/admin/afformEntities/Address.php @@ -0,0 +1,5 @@ + 'join', + 'repeat_max' => NULL, +]; diff --git a/ext/afform/admin/afformEntities/Email.php b/ext/afform/admin/afformEntities/Email.php new file mode 100644 index 0000000000..a8a35545a2 --- /dev/null +++ b/ext/afform/admin/afformEntities/Email.php @@ -0,0 +1,5 @@ + 'join', + 'repeat_max' => NULL, +]; diff --git a/ext/afform/admin/afformEntities/Household.php b/ext/afform/admin/afformEntities/Household.php index 20cbab0c6d..808565deab 100644 --- a/ext/afform/admin/afformEntities/Household.php +++ b/ext/afform/admin/afformEntities/Household.php @@ -1,5 +1,6 @@ 'primary', 'defaults' => "{ data: { contact_type: 'Household', diff --git a/ext/afform/admin/afformEntities/IM.php b/ext/afform/admin/afformEntities/IM.php new file mode 100644 index 0000000000..a8a35545a2 --- /dev/null +++ b/ext/afform/admin/afformEntities/IM.php @@ -0,0 +1,5 @@ + 'join', + 'repeat_max' => NULL, +]; diff --git a/ext/afform/admin/afformEntities/Individual.php b/ext/afform/admin/afformEntities/Individual.php index 31e5ace425..3d124377d8 100644 --- a/ext/afform/admin/afformEntities/Individual.php +++ b/ext/afform/admin/afformEntities/Individual.php @@ -1,5 +1,6 @@ 'primary', 'defaults' => "{ data: { contact_type: 'Individual', diff --git a/ext/afform/admin/afformEntities/Organization.php b/ext/afform/admin/afformEntities/Organization.php index ecbf7fdd70..b36455be1b 100644 --- a/ext/afform/admin/afformEntities/Organization.php +++ b/ext/afform/admin/afformEntities/Organization.php @@ -1,5 +1,6 @@ 'primary', 'defaults' => "{ data: { contact_type: 'Organization', diff --git a/ext/afform/admin/afformEntities/Phone.php b/ext/afform/admin/afformEntities/Phone.php new file mode 100644 index 0000000000..a8a35545a2 --- /dev/null +++ b/ext/afform/admin/afformEntities/Phone.php @@ -0,0 +1,5 @@ + 'join', + 'repeat_max' => NULL, +]; diff --git a/ext/afform/admin/afformEntities/Website.php b/ext/afform/admin/afformEntities/Website.php new file mode 100644 index 0000000000..a8a35545a2 --- /dev/null +++ b/ext/afform/admin/afformEntities/Website.php @@ -0,0 +1,5 @@ + 'join', + 'repeat_max' => NULL, +]; diff --git a/ext/afform/admin/ang/afAdmin/afAdminList.controller.js b/ext/afform/admin/ang/afAdmin/afAdminList.controller.js index df46006d1b..c48d9c5586 100644 --- a/ext/afform/admin/ang/afAdmin/afAdminList.controller.js +++ b/ext/afform/admin/ang/afAdmin/afAdminList.controller.js @@ -58,7 +58,7 @@ if (ctrl.tab === 'form') { _.each(CRM.afGuiEditor.entities, function(entity, name) { - if (entity.defaults) { + if (entity.type === 'primary') { links.push({ url: '#create/form/' + name, label: entity.label, diff --git a/ext/afform/admin/ang/afGuiEditor/afGuiEntity.component.js b/ext/afform/admin/ang/afGuiEditor/afGuiEntity.component.js index 2e6b72c3c5..de487e19a7 100644 --- a/ext/afform/admin/ang/afGuiEditor/afGuiEntity.component.js +++ b/ext/afform/admin/ang/afGuiEditor/afGuiEntity.component.js @@ -99,14 +99,17 @@ ) { var item = {"#tag": block.join_entity ? "div" : directive}; if (block.join_entity) { + var joinEntity = afGui.getEntity(block.join_entity); + // Skip adding block if entity does not exist + if (!joinEntity) { + return; + } item['af-join'] = block.join_entity; item['#children'] = [{"#tag": directive}]; - } - if (block.repeat) { item['af-repeat'] = ts('Add'); item.min = '1'; - if (typeof block.repeat === 'number') { - item.max = '' + block.repeat; + if (typeof joinEntity.repeat_max === 'number') { + item.max = '' + joinEntity.repeat_max; } } $scope.blockList.push(item); diff --git a/ext/afform/admin/ang/afGuiEditor/elements/afGuiContainer-menu.html b/ext/afform/admin/ang/afGuiEditor/elements/afGuiContainer-menu.html index 9121bfeb7d..4a9b6d6fb7 100644 --- a/ext/afform/admin/ang/afGuiEditor/elements/afGuiContainer-menu.html +++ b/ext/afform/admin/ang/afGuiEditor/elements/afGuiContainer-menu.html @@ -16,7 +16,7 @@ - - + - diff --git a/ext/afform/admin/ang/afGuiEditor/elements/afGuiContainer.component.js b/ext/afform/admin/ang/afGuiEditor/elements/afGuiContainer.component.js index 539d6b96c2..097782c795 100644 --- a/ext/afform/admin/ang/afGuiEditor/elements/afGuiContainer.component.js +++ b/ext/afform/admin/ang/afGuiEditor/elements/afGuiContainer.component.js @@ -88,6 +88,7 @@ } }; + // Sets min value for af-repeat as a string, returns it as an int $scope.getSetMin = function(val) { if (arguments.length) { if (ctrl.node.max && val > parseInt(ctrl.node.max, 10)) { @@ -103,6 +104,7 @@ return ctrl.node.min ? parseInt(ctrl.node.min, 10) : null; }; + // Sets max value for af-repeat as a string, returns it as an int $scope.getSetMax = function(val) { if (arguments.length) { if (ctrl.node.min && val && val < parseInt(ctrl.node.min, 10)) { @@ -118,6 +120,16 @@ return ctrl.node.max ? parseInt(ctrl.node.max, 10) : null; }; + // Returns the maximum number of repeats allowed if this is a joined entity with a limit + // Value comes from civicrm_custom_group.max_multiple for custom entities, + // or from afformEntity php file for core entities. + $scope.getRepeatMax = function() { + if (ctrl.join) { + return afGui.getEntity(ctrl.join).repeat_max || ''; + } + return ''; + }; + $scope.pickAddIcon = function() { afGui.pickIcon().then(function(val) { ctrl.node['add-icon'] = val; diff --git a/ext/afform/core/Civi/Api4/Action/Afform/Get.php b/ext/afform/core/Civi/Api4/Action/Afform/Get.php index 2d4fa6e86a..10e035b2dc 100644 --- a/ext/afform/core/Civi/Api4/Action/Afform/Get.php +++ b/ext/afform/core/Civi/Api4/Action/Afform/Get.php @@ -135,7 +135,6 @@ class Get extends \Civi\Api4\Generic\BasicGetAction { 'permission' => 'access CiviCRM', 'join_entity' => 'Custom_' . $custom['name'], 'entity_type' => $custom['extends'], - 'repeat' => $custom['max_multiple'] ?: TRUE, 'has_base' => TRUE, ]; if ($getLayout) { diff --git a/ext/afform/core/Civi/Api4/Afform.php b/ext/afform/core/Civi/Api4/Afform.php index 378b874e31..ec76fd3df2 100644 --- a/ext/afform/core/Civi/Api4/Afform.php +++ b/ext/afform/core/Civi/Api4/Afform.php @@ -178,10 +178,6 @@ class Afform extends Generic\AbstractEntity { 'tab' => ts('Contact Summary Tab'), ], ], - [ - 'name' => 'repeat', - 'data_type' => 'Mixed', - ], [ 'name' => 'server_route', ], diff --git a/ext/afform/core/ang/afblockContactAddress.aff.json b/ext/afform/core/ang/afblockContactAddress.aff.json index 41a28494a1..0a0e209345 100644 --- a/ext/afform/core/ang/afblockContactAddress.aff.json +++ b/ext/afform/core/ang/afblockContactAddress.aff.json @@ -2,6 +2,5 @@ "title": "Contact Address(es)", "type": "block", "entity_type": "Contact", - "join_entity": "Address", - "repeat": true + "join_entity": "Address" } diff --git a/ext/afform/core/ang/afblockContactEmail.aff.json b/ext/afform/core/ang/afblockContactEmail.aff.json index 0b8a749a4c..6ddb66f259 100644 --- a/ext/afform/core/ang/afblockContactEmail.aff.json +++ b/ext/afform/core/ang/afblockContactEmail.aff.json @@ -2,6 +2,5 @@ "title": "Contact Email(s)", "type": "block", "entity_type": "Contact", - "join_entity": "Email", - "repeat": true + "join_entity": "Email" } diff --git a/ext/afform/core/ang/afblockContactIM.aff.json b/ext/afform/core/ang/afblockContactIM.aff.json index 0d7ea0ff46..953d1a09d1 100644 --- a/ext/afform/core/ang/afblockContactIM.aff.json +++ b/ext/afform/core/ang/afblockContactIM.aff.json @@ -2,6 +2,5 @@ "title": "Contact IM(s)", "type": "block", "entity_type": "Contact", - "join_entity": "IM", - "repeat": true + "join_entity": "IM" } diff --git a/ext/afform/core/ang/afblockContactPhone.aff.json b/ext/afform/core/ang/afblockContactPhone.aff.json index fa7cad2168..c66eae8b24 100644 --- a/ext/afform/core/ang/afblockContactPhone.aff.json +++ b/ext/afform/core/ang/afblockContactPhone.aff.json @@ -2,6 +2,5 @@ "title": "Contact Phone(s)", "type": "block", "entity_type": "Contact", - "join_entity": "Phone", - "repeat": true + "join_entity": "Phone" } diff --git a/ext/afform/core/ang/afblockContactWebsite.aff.json b/ext/afform/core/ang/afblockContactWebsite.aff.json index 3cea837cca..89288fcfd0 100644 --- a/ext/afform/core/ang/afblockContactWebsite.aff.json +++ b/ext/afform/core/ang/afblockContactWebsite.aff.json @@ -2,6 +2,5 @@ "title": "Contact Website(s)", "type": "block", "entity_type": "Contact", - "join_entity": "Website", - "repeat": true + "join_entity": "Website" } -- 2.25.1