{{:: ts('These relationships are Disabled OR have a past End Date.') }}
-
+
{{:: ts('Permissioned Relationships:') }}
{{:: ts('This contact can be viewed by the other.') }}
diff --git a/ext/afform/core/Civi/Api4/Action/CustomGroup/GetAfforms.php b/ext/afform/core/Civi/Api4/Action/CustomGroup/GetAfforms.php
index 6a2ab0a98680..9cd1d5a0950b 100644
--- a/ext/afform/core/Civi/Api4/Action/CustomGroup/GetAfforms.php
+++ b/ext/afform/core/Civi/Api4/Action/CustomGroup/GetAfforms.php
@@ -26,6 +26,7 @@ class GetAfforms extends \Civi\Api4\Generic\BasicBatchAction {
'afblockCustom',
'afformUpdateCustom',
'afformCreateCustom',
+ 'afformViewCustom',
'afsearchTabCustom',
];
@@ -74,6 +75,7 @@ protected function doTask($item) {
break;
case 'form':
+ $forms[] = $this->generateViewForm($item);
$forms[] = $this->generateUpdateForm($item);
if ($item['is_multiple']) {
$forms[] = $this->generateCreateForm($item);
@@ -83,11 +85,9 @@ protected function doTask($item) {
case 'search':
// TODO:
// 1. tabs with grid display
- // 2. tabs for other entities (e.g. Event)
if (
$item['is_multiple']
&& ($item['style'] === 'Tab with table')
- && CoreUtil::isContact($item['extends'])
) {
$forms[] = $this->generateTabForm($item);
}
@@ -125,6 +125,56 @@ private function generateFieldBlock($item): array {
return $afform;
}
+ private function generateViewForm($item): array {
+ $afform = [
+ 'name' => 'afformViewCustom_' . $item['name'],
+ 'type' => 'form',
+ 'title' => E::ts('View %1', [1 => $item['title']]),
+ 'description' => '',
+ 'is_public' => FALSE,
+ // NOTE: we will use RBAC for entities to ensure
+ // this form does not allow folks who shouldn't
+ // to edit contacts
+ 'permission' => ['access CiviCRM'],
+ 'server_route' => 'civicrm/af/custom/' . $item['name'] . '/view',
+ 'icon' => $item['icon'],
+ ];
+ if ($this->getLayout) {
+
+ // form entity depends on whether this is a multirecord custom group
+ $formEntity = $item['is_multiple'] ?
+ [
+ 'type' => 'Custom_' . $item['name'],
+ 'name' => 'Record',
+ 'label' => $item['extends'] . ' ' . $item['title'],
+ 'parent_field' => 'entity_id',
+ 'parent_field_defn' => [
+ 'input_type' => 'Hidden',
+ 'label' => FALSE,
+ ],
+ ] :
+ [
+ 'type' => $item['extends'],
+ 'name' => $item['extends'] . '1',
+ 'label' => $item['extends'],
+ 'parent_field' => 'id',
+ 'parent_field_defn' => [
+ 'input_type' => 'Hidden',
+ 'label' => FALSE,
+ ],
+ ];
+
+ $afform['layout'] = \CRM_Core_Smarty::singleton()->fetchWith(
+ 'afform/customGroups/afformView.tpl',
+ [
+ 'formEntity' => $formEntity,
+ 'group' => $item,
+ ]
+ );
+ }
+ return $afform;
+ }
+
private function generateUpdateForm($item): array {
$afform = [
'name' => 'afformUpdateCustom_' . $item['name'],
@@ -165,7 +215,7 @@ private function generateUpdateForm($item): array {
];
$afform['layout'] = \CRM_Core_Smarty::singleton()->fetchWith(
- 'afform/customGroups/afform.tpl',
+ 'afform/customGroups/afformEdit.tpl',
[
'formEntity' => $formEntity,
'formActions' => [
@@ -206,7 +256,7 @@ private function generateCreateForm($item): array {
],
];
$afform['layout'] = \CRM_Core_Smarty::singleton()->fetchWith(
- 'afform/customGroups/afform.tpl',
+ 'afform/customGroups/afformEdit.tpl',
[
'formEntity' => $formEntity,
'formActions' => [
@@ -222,10 +272,11 @@ private function generateCreateForm($item): array {
}
private function generateTabForm($item): array {
+ $extendsLabel = CoreUtil::getInfoItem($item['extends'], 'title');
$afform = [
// name required to replace the existing tab
'name' => 'afsearchTabCustom_' . $item['name'],
- 'description' => E::ts('Contact summary tab display for %1', [1 => $item['title']]),
+ 'description' => E::ts('%1 tab display for %2', [1 => $extendsLabel, 2 => $item['title']]),
'type' => 'search',
'is_public' => FALSE,
// Q: should this be more permissive if user has access
@@ -243,7 +294,9 @@ private function generateTabForm($item): array {
$afform['summary_contact_type'] = [$item['extends']];
}
else {
- // TODO implement tabs for other tabsets
+ // tabs for other entities are placed without any
+ // additional afform meta
+ // @see civicrm_admin_ui_civicrm_tabset
}
if ($this->getLayout) {
// TODO: the template should be a table or grid depending
diff --git a/ext/afform/core/afform.php b/ext/afform/core/afform.php
index fccaeb396f69..d46aded2fbfa 100644
--- a/ext/afform/core/afform.php
+++ b/ext/afform/core/afform.php
@@ -194,12 +194,20 @@ function afform_civicrm_tabset($tabsetName, &$tabs, $context) {
'icon' => 'crm-i ' . ($afform['icon'] ?: 'fa-list-alt'),
'is_active' => TRUE,
'contact_type' => _afform_get_contact_types($summaryContactType) ?: NULL,
- 'template' => 'afform/contactSummary/AfformTab.tpl',
+ 'template' => 'afform/InlineAfform.tpl',
'module' => $afform['module_name'],
'directive' => $afform['directive_name'],
];
- // If this is the real contact summary page (and not a callback from ContactLayoutEditor), load module.
+ // If this is the real contact summary page (and not a callback from ContactLayoutEditor), load module
+ // and assign contact id to required smarty variable
if (empty($context['caller'])) {
+ // note we assign the contact id to entity_id as preferred key
+ // but also contact_id to maintain backwards compatibility with older
+ // afforms
+ CRM_Core_Smarty::singleton()->assign('afformOptions', [
+ 'entity_id' => $context['contact_id'],
+ 'contact_id' => $context['contact_id'],
+ ]);
Civi::service('angularjs.loader')->addModules($afform['module_name']);
}
}
diff --git a/ext/afform/core/templates/afform/InlineAfform.tpl b/ext/afform/core/templates/afform/InlineAfform.tpl
new file mode 100644
index 000000000000..42977db4c9ac
--- /dev/null
+++ b/ext/afform/core/templates/afform/InlineAfform.tpl
@@ -0,0 +1,5 @@
+
+
+
diff --git a/ext/afform/core/templates/afform/contactSummary/AfformTab.tpl b/ext/afform/core/templates/afform/contactSummary/AfformTab.tpl
deleted file mode 100644
index d0f4eac9a1cb..000000000000
--- a/ext/afform/core/templates/afform/contactSummary/AfformTab.tpl
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
diff --git a/ext/afform/core/templates/afform/customGroups/afblock.tpl b/ext/afform/core/templates/afform/customGroups/afblock.tpl
index 785631766ad1..f8745449b2d2 100644
--- a/ext/afform/core/templates/afform/customGroups/afblock.tpl
+++ b/ext/afform/core/templates/afform/customGroups/afblock.tpl
@@ -4,7 +4,7 @@
{foreach from=$group.field_names item=field_name}
{* for multiple record fields there is no need to prepend
- the group name because it is provided as the join_entity above *}
+ the group name because it will be the form entity itself *}
{/foreach}
diff --git a/ext/afform/core/templates/afform/customGroups/afform.tpl b/ext/afform/core/templates/afform/customGroups/afformEdit.tpl
similarity index 100%
rename from ext/afform/core/templates/afform/customGroups/afform.tpl
rename to ext/afform/core/templates/afform/customGroups/afformEdit.tpl
diff --git a/ext/afform/core/templates/afform/customGroups/afformView.tpl b/ext/afform/core/templates/afform/customGroups/afformView.tpl
new file mode 100644
index 000000000000..783dbd22e044
--- /dev/null
+++ b/ext/afform/core/templates/afform/customGroups/afformView.tpl
@@ -0,0 +1,22 @@
+
+
+
+
+
diff --git a/ext/afform/core/templates/afform/customGroups/afsearchTab.tpl b/ext/afform/core/templates/afform/customGroups/afsearchTab.tpl
index fb76f8af1ce2..54618fe5a09a 100644
--- a/ext/afform/core/templates/afform/customGroups/afsearchTab.tpl
+++ b/ext/afform/core/templates/afform/customGroups/afsearchTab.tpl
@@ -2,6 +2,6 @@
diff --git a/ext/civicrm_admin_ui/Civi/Api4/Action/CustomGroup/GetSearchKit.php b/ext/civicrm_admin_ui/Civi/Api4/Action/CustomGroup/GetSearchKit.php
index 650525e1a58a..16c319833fa2 100644
--- a/ext/civicrm_admin_ui/Civi/Api4/Action/CustomGroup/GetSearchKit.php
+++ b/ext/civicrm_admin_ui/Civi/Api4/Action/CustomGroup/GetSearchKit.php
@@ -218,12 +218,11 @@ protected function getButtonColumn($group) {
}
public static function getAllManaged() {
- // for now we only fetch for Groups that have a Tab with table on the contact summary
+ // for now we only fetch for Groups that have a Tab
$all = \Civi\Api4\CustomGroup::getSearchKit(FALSE)
->addWhere('is_active', '=', TRUE)
->addWhere('is_multiple', '=', TRUE)
->addWhere('style', 'IN', ['Tab', 'Tab with table'])
- ->addWhere('extends', 'IN', ['Contact', 'Individual', 'Household', 'Organization'])
->execute()
->column('managed');
diff --git a/ext/civicrm_admin_ui/Civi/Api4/Event/Subscriber/CustomGroupEntityLinks.php b/ext/civicrm_admin_ui/Civi/Api4/Event/Subscriber/CustomGroupEntityLinks.php
index 246ce6e87123..704cd4762fe3 100644
--- a/ext/civicrm_admin_ui/Civi/Api4/Event/Subscriber/CustomGroupEntityLinks.php
+++ b/ext/civicrm_admin_ui/Civi/Api4/Event/Subscriber/CustomGroupEntityLinks.php
@@ -34,6 +34,7 @@ public function addCustomGroupLinks(\Civi\Core\Event\GenericHookEvent $event) {
$groupName = substr($name, 7);
$event->entities[$name]['paths']['add'] = "civicrm/af/custom/{$groupName}/create#?entity_id=[entity_id]";
$event->entities[$name]['paths']['update'] = "civicrm/af/custom/{$groupName}/update#?Record=[id]";
+ $event->entities[$name]['paths']['view'] = "civicrm/af/custom/{$groupName}/view#?Record=[id]";
}
}
}
diff --git a/ext/civicrm_admin_ui/ang/afformTabMember.aff.html b/ext/civicrm_admin_ui/ang/afformTabMember.aff.html
index 76fb8a693fe6..8d66bbf6449e 100644
--- a/ext/civicrm_admin_ui/ang/afformTabMember.aff.html
+++ b/ext/civicrm_admin_ui/ang/afformTabMember.aff.html
@@ -1,11 +1,11 @@
{ts}Checking this box allows you to enter multiple sets of values for a given contact.{/ts}
+
{ts}Checking this box allows you to enter multiple sets of values for a given record.{/ts}
{ts}EXAMPLE: When creating a set of custom fields used to collect Employment History - you might have fields for Job Title, Start Date, End Date, and Reason for Leaving. Checking the "multiple records" box allows you to collect information for multiple jobs.{/ts}
{ts}You can also set the maximum number of records which can be recorded per contact. Using the previous example, you might only want data for the three most recent jobs.{/ts}
-
{ts 1=$importMultipleURL}Use the Multi-value Custom Data Import tool to import data into multiple record custom fields (contact records must already exist).{/ts}
-
- {ts}CAUTION: The following features are NOT available for custom fields in 'multiple record' custom set:{/ts}
-
-
{ts}They can not be Exported{/ts}
-
{ts}If they are included in a report as a display column, only the first set of values are shown.{/ts}
-
-
+
{ts 1=$importMultipleURL}Use the Multi-value Custom Data Import tool to import data into multiple record custom fields (the parent records should already exist).{/ts}
{/htxt}
{htxt id="id-max_multiple-title"}
diff --git a/templates/CRM/Custom/Form/Group.tpl b/templates/CRM/Custom/Form/Group.tpl
index 2064a1d32965..7aa8180d3da9 100644
--- a/templates/CRM/Custom/Form/Group.tpl
+++ b/templates/CRM/Custom/Form/Group.tpl
@@ -83,7 +83,7 @@ CRM.$(function($) {
const {/literal}
$form = $('form.{$form.formClass}'),
entityColumnIdOptions = {$entityColumnIdOptions|@json_encode},
- allMultiple = {$allowMultiple|@json_encode},
+ allowMultiple = {$allowMultiple|@json_encode},
defaultSubtypes = {$defaultSubtypes|@json_encode};
{literal}
let tabWithTableOption;
@@ -151,7 +151,7 @@ CRM.$(function($) {
// When changing or initializing the primary `extends` field
function handleExtends() {
- let multiAllowed = $(this).val() && allMultiple[$(this).val()];
+ let multiAllowed = $(this).val() && allowMultiple[$(this).val()];
if (multiAllowed) {
$('tr.field-style, tr.field-is_multiple', $form).show();
diff --git a/templates/CRM/Event/Page/DashBoard.tpl b/templates/CRM/Event/Page/DashBoard.tpl
index 19d258b7eb38..38a431d60d18 100644
--- a/templates/CRM/Event/Page/DashBoard.tpl
+++ b/templates/CRM/Event/Page/DashBoard.tpl
@@ -105,7 +105,7 @@
href="{crmURL p="`$v.url`" q="reset=1&action=browse&setTab=1&id=`$id`"}">{$v.title}
{else}