From 7067a62aa56753622f619b08c408cc4bd071b055 Mon Sep 17 00:00:00 2001 From: colemanw Date: Sun, 19 Nov 2023 15:15:46 -0500 Subject: [PATCH] Afform - Improve admin links to include search displays Fixes https://lab.civicrm.org/dev/core/-/issues/4786 --- .../Civi/AfformAdmin/AfformAdminInjector.php | 58 +++++++++++++++++-- ext/afform/core/ang/afCore.css | 12 ++-- ext/afform/core/ang/afCore.js | 2 + 3 files changed, 61 insertions(+), 11 deletions(-) diff --git a/ext/afform/admin/Civi/AfformAdmin/AfformAdminInjector.php b/ext/afform/admin/Civi/AfformAdmin/AfformAdminInjector.php index 6248442082..bc14646794 100644 --- a/ext/afform/admin/Civi/AfformAdmin/AfformAdminInjector.php +++ b/ext/afform/admin/Civi/AfformAdmin/AfformAdminInjector.php @@ -11,6 +11,8 @@ namespace Civi\AfformAdmin; +use Civi\Api4\Afform; +use Civi\Api4\SavedSearch; use Civi\Core\Service\AutoSubscriber; use CRM_Afform_ExtensionUtil as E; @@ -36,14 +38,58 @@ class AfformAdminInjector extends AutoSubscriber { $changeSet = \Civi\Angular\ChangeSet::create('afformAdmin') ->alterHtml(';\\.aff\\.html$;', function($doc, $path) { try { - $moduleName = basename($path, '.aff.html'); - // If the user has "administer CiviCRM", inject edit link + // If the user has "administer CiviCRM", inject gear menu with edit links if (\CRM_Core_Permission::check('administer CiviCRM')) { - $url = \CRM_Utils_System::url('civicrm/admin/afform', NULL, FALSE, '/edit/' . $moduleName, TRUE); - // Append link to afform directive element (using loop but there should be only one) - foreach (pq('af-form[ctrl]', $doc) as $afForm) { - pq($afForm)->append(' ' . E::ts('Edit Form') . ''); + $afform = Afform::get() + ->addWhere('module_name', '=', basename($path, '.aff.html')) + ->addSelect('name', 'search_displays', 'title') + ->execute()->single(); + // Create a link to edit the form, plus all embedded SavedSearches + $links = [ + [ + 'url' => \CRM_Utils_System::url('civicrm/admin/afform', NULL, FALSE, "/edit/{$afform['name']}", TRUE), + 'text' => E::ts('Edit %1 in FormBuilder', [1 => "{$afform['title']}"]), + 'icon' => 'fa-pencil', + ], + ]; + if ($afform['search_displays']) { + $searchNames = []; + foreach ($afform['search_displays'] as $searchAndDisplayName) { + $searchNames[] = explode('.', $searchAndDisplayName)[0]; + } + $savedSearches = SavedSearch::get() + ->addWhere('name', 'IN', $searchNames) + ->addSelect('id', 'label') + ->execute(); + foreach ($savedSearches as $savedSearch) { + $links[] = [ + 'url' => \CRM_Utils_System::url('civicrm/admin/search', NULL, FALSE, "/edit/{$savedSearch['id']}", TRUE), + 'text' => E::ts('Edit %1 in SearchKit', [1 => "{$savedSearch['label']}"]), + 'icon' => 'fa-search-plus', + ]; + } } + $linksMarkup = ''; + foreach ($links as $link) { + $linksMarkup .= << + + {$link['text']} + + + HTML; + } + $editMenu = << + + + + HTML; + // Append link to end of afform markup so it has the highest z-index and is clickable. + // afCore.css will control placement at the top of the form. + pq($doc)->append($editMenu); } } catch (\Exception $e) { diff --git a/ext/afform/core/ang/afCore.css b/ext/afform/core/ang/afCore.css index d7dae0164c..28eea63df2 100644 --- a/ext/afform/core/ang/afCore.css +++ b/ext/afform/core/ang/afCore.css @@ -26,6 +26,7 @@ a.af-api4-action-idle { width: 100%; } +.afform-directive, af-form { display: block; position: relative; @@ -87,12 +88,13 @@ af-form { } /* Admin edit links */ -af-form a.af-admin-edit-form-link { - position: absolute; +.afform-directive .af-admin-edit-form-link { + position: absolute !important; right: 0; top: 0; - display: none; + opacity: .5; } -af-form:hover a.af-admin-edit-form-link { - display: block; +.afform-directive .af-admin-edit-form-link.open, +.afform-directive:hover .af-admin-edit-form-link { + opacity: 1; } diff --git a/ext/afform/core/ang/afCore.js b/ext/afform/core/ang/afCore.js index a1dc17aa22..3eb7abf0cf 100644 --- a/ext/afform/core/ang/afCore.js +++ b/ext/afform/core/ang/afCore.js @@ -17,6 +17,8 @@ $scope.crmUiAlert = crmUiAlert; $scope.crmUrl = CRM.url; + $el.addClass('afform-directive'); + // Afforms do not use routing, but some forms get input from search params var dialog = $el.closest('.ui-dialog-content'); if (!dialog.length) { -- 2.25.1