From e015a941b8c032c4e94129af2ead23734bbfcbff Mon Sep 17 00:00:00 2001 From: Arlen Johnson Date: Thu, 13 Nov 2025 13:41:45 -0500 Subject: [PATCH] Improve alert banner configuration (CFM-218/CFM-465) --- .../templates/ApiSourceEndpoints/fields.inc | 8 +-- .../templates/ApiSources/fields.inc | 8 +-- .../templates/Passwords/fields.inc | 10 ++-- .../templates/MatchCallbacks/fields.inc | 8 +-- .../templates/SshKeyAuthenticators/fields.inc | 9 ++-- app/src/View/Helper/FieldHelper.php | 26 +++++----- app/templates/ApiUsers/columns.inc | 4 +- app/templates/ApiUsers/fields-generate.inc | 4 +- app/templates/ApiUsers/fields.inc | 4 +- app/templates/Dashboards/dashboard.php | 4 +- .../ExtIdentitySourceRecords/columns.inc | 6 ++- .../ExtIdentitySourceRecords/fields.inc | 8 +-- app/templates/ExternalIdentities/fields.inc | 10 ++-- app/templates/HistoryRecords/columns.inc | 4 +- app/templates/Standard/add-edit-view.php | 49 ++++++++++--------- app/templates/Standard/index.php | 6 +-- app/templates/element/flash.php | 15 +++--- app/templates/element/notify/alert.php | 3 +- app/templates/element/notify/banner.php | 39 --------------- app/templates/layout/iframe.php | 30 ++++++------ app/webroot/css/co-base.css | 2 +- 21 files changed, 117 insertions(+), 140 deletions(-) delete mode 100644 app/templates/element/notify/banner.php diff --git a/app/availableplugins/ApiConnector/templates/ApiSourceEndpoints/fields.inc b/app/availableplugins/ApiConnector/templates/ApiSourceEndpoints/fields.inc index faa75fdee..909625d5f 100644 --- a/app/availableplugins/ApiConnector/templates/ApiSourceEndpoints/fields.inc +++ b/app/availableplugins/ApiConnector/templates/ApiSourceEndpoints/fields.inc @@ -27,9 +27,11 @@ if(!empty($vv_push_endpoint)) { - // XXX https://todos.internet2.edu/browse/CFM-465 send type - this should be 'information' (not a warning) - $banners = [ - __d('api_connector', 'information.endpoint.push', [$vv_push_endpoint]) + $alerts = [ + [ + 'type' => 'information', + 'message' => __d('api_connector', 'information.endpoint.push', [$vv_push_endpoint]) + ] ]; } diff --git a/app/availableplugins/ApiConnector/templates/ApiSources/fields.inc b/app/availableplugins/ApiConnector/templates/ApiSources/fields.inc index 25798a722..32722bfa7 100644 --- a/app/availableplugins/ApiConnector/templates/ApiSources/fields.inc +++ b/app/availableplugins/ApiConnector/templates/ApiSources/fields.inc @@ -25,9 +25,11 @@ * @license Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) */ -// XXX https://todos.internet2.edu/browse/CFM-465 send type - this should be 'information' (not a warning) -$banners = [ - __d('information', 'plugin.config.none') +$alerts = [ + [ + 'type' => 'information', + 'message' => __d('information', 'plugin.config.none') + ] ]; // XXX Revisit this - what's the "Push Mode" text attempting to convey here (with no other information)? diff --git a/app/availableplugins/PasswordAuthenticator/templates/Passwords/fields.inc b/app/availableplugins/PasswordAuthenticator/templates/Passwords/fields.inc index 6d4863354..935c130d8 100644 --- a/app/availableplugins/PasswordAuthenticator/templates/Passwords/fields.inc +++ b/app/availableplugins/PasswordAuthenticator/templates/Passwords/fields.inc @@ -27,10 +27,12 @@ // We provide the current password status in a banner message since that's all the // information we really want to display about a password. - -// XXX https://todos.internet2.edu/browse/CFM-465 send type - this should be 'information' (not a warning) -$banners = [ - $vv_status->comment + +$alerts = [ + [ + 'type' => 'information', + 'message' => $vv_status->comment + ] ]; $fields = []; diff --git a/app/plugins/CoreApi/templates/MatchCallbacks/fields.inc b/app/plugins/CoreApi/templates/MatchCallbacks/fields.inc index 03a0d342a..b348baefd 100644 --- a/app/plugins/CoreApi/templates/MatchCallbacks/fields.inc +++ b/app/plugins/CoreApi/templates/MatchCallbacks/fields.inc @@ -26,9 +26,11 @@ */ if(!empty($vv_api_endpoint)) { - // XXX https://todos.internet2.edu/browse/CFM-465 send type - this should be 'information' (not a warning) - $banners = [ - __d('core_api', 'information.endpoint.match.callback', [$vv_api_endpoint]) + $alerts = [ + [ + 'type' => 'information', + 'message' => __d('core_api', 'information.endpoint.match.callback', [$vv_api_endpoint]) + ] ]; } diff --git a/app/plugins/SshKeyAuthenticator/templates/SshKeyAuthenticators/fields.inc b/app/plugins/SshKeyAuthenticator/templates/SshKeyAuthenticators/fields.inc index 4bdc5d8ef..8ab1f70bc 100644 --- a/app/plugins/SshKeyAuthenticator/templates/SshKeyAuthenticators/fields.inc +++ b/app/plugins/SshKeyAuthenticator/templates/SshKeyAuthenticators/fields.inc @@ -30,8 +30,9 @@ declare(strict_types = 1); $this->Field->disableFormEditMode(); // There are currently no configurable options for the SSH Key Authenticator - -// XXX https://todos.internet2.edu/browse/CFM-465 send type - this should be 'information' (not a warning) -$banners = [ - __d('information', 'plugin.config.none') +$alerts = [ + [ + 'type' => 'information', + 'message' => __d('information', 'plugin.config.none') + ] ]; \ No newline at end of file diff --git a/app/src/View/Helper/FieldHelper.php b/app/src/View/Helper/FieldHelper.php index 2ae9440c0..73fb183be 100644 --- a/app/src/View/Helper/FieldHelper.php +++ b/app/src/View/Helper/FieldHelper.php @@ -736,56 +736,56 @@ public function restructureFieldArguments(array $fieldArgs) { // Pull out the top-level field options that are intended for Cake, and // insert them into the $fieldOptions array. - if(isset($fieldArgs['empty'])) { + if(array_key_exists('empty', $fieldArgs)) { $fieldOptions['empty'] = $fieldArgs['empty']; unset($fieldArgs['empty']); } - if(isset($fieldArgs['required'])) { + if(array_key_exists('required', $fieldArgs)) { $fieldOptions['required'] = $fieldArgs['required']; unset($fieldArgs['required']); } - if(isset($fieldArgs['default'])) { + if(array_key_exists('default', $fieldArgs)) { $fieldOptions['default'] = $fieldArgs['default']; unset($fieldArgs['default']); } - if(isset($fieldArgs['readonly'])) { + if(array_key_exists('readonly', $fieldArgs)) { $fieldOptions['readonly'] = $fieldArgs['readonly']; unset($fieldArgs['readonly']); } - if(isset($fieldArgs['value'])) { + if(array_key_exists('value', $fieldArgs)) { $fieldOptions['value'] = $fieldArgs['value']; unset($fieldArgs['value']); } - if(isset($fieldArgs['type'])) { + if(array_key_exists('type', $fieldArgs)) { $fieldOptions['type'] = $fieldArgs['type']; unset($fieldArgs['type']); } - if(isset($fieldArgs['options'])) { + if(array_key_exists('options', $fieldArgs)) { // select options that are set explicitly $fieldOptions['options'] = $fieldArgs['options']; unset($fieldArgs['options']); } - if(isset($fieldArgs['placeholder'])) { + if(array_key_exists('placeholder', $fieldArgs)) { $fieldOptions['placeholder'] = $fieldArgs['placeholder']; unset($fieldArgs['placeholder']); } - if(isset($fieldArgs['class'])) { + if(array_key_exists('class', $fieldArgs)) { $fieldOptions['class'] = $fieldArgs['class']; unset($fieldArgs['class']); } - if(isset($fieldArgs['id'])) { + if(array_key_exists('id', $fieldArgs)) { $fieldOptions['id'] = $fieldArgs['id']; unset($fieldArgs['id']); } - if(isset($fieldArgs['style'])) { + if(array_key_exists('style', $fieldArgs)) { $fieldOptions['style'] = $fieldArgs['style']; unset($fieldArgs['style']); } - if(isset($fieldArgs['checked'])) { + if(array_key_exists('checked', $fieldArgs)) { $fieldOptions['checked'] = $fieldArgs['checked']; unset($fieldArgs['checked']); } - if(isset($fieldArgs['label'])) { + if(array_key_exists('label', $fieldArgs)) { // The label field maps to the CakePHP label field (can be "false" to hide the label) $fieldOptions['label'] = $fieldArgs['label']; unset($fieldArgs['label']); diff --git a/app/templates/ApiUsers/columns.inc b/app/templates/ApiUsers/columns.inc index 8fd2e4db4..65313d1de 100644 --- a/app/templates/ApiUsers/columns.inc +++ b/app/templates/ApiUsers/columns.inc @@ -27,8 +27,8 @@ // Output advisory banner when co=1 if($vv_cur_co->isCOmanageCO()) { - $banners = [ - __d('information','api.cmp') + $alerts = [ + ['message' => __d('information','api.cmp')] ]; } diff --git a/app/templates/ApiUsers/fields-generate.inc b/app/templates/ApiUsers/fields-generate.inc index e7394695d..5e2704a4b 100644 --- a/app/templates/ApiUsers/fields-generate.inc +++ b/app/templates/ApiUsers/fields-generate.inc @@ -25,8 +25,8 @@ * @license Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) */ -$banners = [ - __d('information', 'api.key') +$alerts = [ + ['message' => __d('information', 'api.key')] ]; $fields = [ diff --git a/app/templates/ApiUsers/fields.inc b/app/templates/ApiUsers/fields.inc index 4972d3c73..5bebf489a 100644 --- a/app/templates/ApiUsers/fields.inc +++ b/app/templates/ApiUsers/fields.inc @@ -26,8 +26,8 @@ */ if($vv_cur_co->isCOmanageCO()) { - $banners = [ - __d('information', 'api.cmp') + $alerts = [ + ['message' => __d('information', 'api.cmp')] ]; } diff --git a/app/templates/Dashboards/dashboard.php b/app/templates/Dashboards/dashboard.php index 70f1e2285..aa8d2ddec 100644 --- a/app/templates/Dashboards/dashboard.php +++ b/app/templates/Dashboards/dashboard.php @@ -29,8 +29,8 @@ // $flashArgs pass banner messages to the flash element container $flashArgs = []; -if(!empty($banners)) { - $flashArgs['vv_banners'] = $banners; +if(!empty($alerts)) { + $flashArgs['vv_alerts'] = $alerts; } ?> diff --git a/app/templates/ExtIdentitySourceRecords/columns.inc b/app/templates/ExtIdentitySourceRecords/columns.inc index f9b1f0a1b..9606bc195 100644 --- a/app/templates/ExtIdentitySourceRecords/columns.inc +++ b/app/templates/ExtIdentitySourceRecords/columns.inc @@ -29,7 +29,11 @@ $indexColumns = [ // We start with id to ensure there is a clickable field in the row 'id' => [ 'type' => 'link', - 'sortable' => true + 'sortable' => true, + 'class' => 'cm-modal-link nospin', // launch this in a modal + 'dataAttrs' => [ + ['data-cm-modal-title', __d('controller', 'ExtIdentitySourceRecords', 1)] + ] ], 'source_key' => [ 'type' => 'echo', diff --git a/app/templates/ExtIdentitySourceRecords/fields.inc b/app/templates/ExtIdentitySourceRecords/fields.inc index 8081e39a8..c220f5b62 100644 --- a/app/templates/ExtIdentitySourceRecords/fields.inc +++ b/app/templates/ExtIdentitySourceRecords/fields.inc @@ -42,9 +42,11 @@ $noticeText = __d( ] ); -// XXX https://todos.internet2.edu/browse/CFM-465 send type - this should be 'information' (not a warning) -$banners = [ - $noticeText +$alerts = [ + [ + 'type' => 'information', + 'message' => $noticeText + ] ]; // This view does not support add or edit diff --git a/app/templates/ExternalIdentities/fields.inc b/app/templates/ExternalIdentities/fields.inc index a80f0aa9d..36e679059 100644 --- a/app/templates/ExternalIdentities/fields.inc +++ b/app/templates/ExternalIdentities/fields.inc @@ -42,10 +42,12 @@ if(!empty($vv_obj->ext_identity_source_record)) { ] ); - // XXX https://todos.internet2.edu/browse/CFM-465 send type - this should be 'information' (not a warning) - // XXX Also: the placement here is wrong; this should be displaying under the subtitle, not the main title. - $banners = [ - $noticeText + // XXX The placement here is wrong; this should be displaying under the subtitle, not the main title. + $alerts = [ + [ + 'type' => 'information', + 'message' => $noticeText + ] ]; } diff --git a/app/templates/HistoryRecords/columns.inc b/app/templates/HistoryRecords/columns.inc index f244c2117..c5d7a33f8 100644 --- a/app/templates/HistoryRecords/columns.inc +++ b/app/templates/HistoryRecords/columns.inc @@ -25,9 +25,9 @@ * @license Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) */ -$banners = [ +$alerts = [ // CFM-76 info message pending eventual "virtual" view consolidating all History Record types - __d('information', 'HistoryRecords.xref') + ['message' => __d('information', 'HistoryRecords.xref')] ]; $indexColumns = [ diff --git a/app/templates/Standard/add-edit-view.php b/app/templates/Standard/add-edit-view.php index 13a67a416..21c1cbd13 100644 --- a/app/templates/Standard/add-edit-view.php +++ b/app/templates/Standard/add-edit-view.php @@ -46,11 +46,32 @@ } include($templatePath . DS . $fieldsFile); -// $flashArgs pass banner messages to the flash element container +// $flashArgs pass alert messages to the flash element container. +// $alertMessages will hold the messages to pass to $flashArgs. $flashArgs = []; -if(!empty($banners)) { - // Pass in any configured banners from the fields file - $flashArgs['vv_banners'] = $banners; +$alertMessages = []; + +// Check for changelog archive view. These alerts come first. +$clfield = $vv_obj->changelogAttributeName(); + +if($vv_obj->deleted) { + $alertMessages[] = [ + 'type' => 'information', + 'message' => __d('information', 'changelog.deleted') + ]; +} elseif(!empty($vv_obj->$clfield)) { + $alertMessages[] = [ + 'type' => 'information', + 'message' => __d('information', 'changelog.archived') + ]; +} + +// Include any configured messages from the $alerts array in the fields file +$alertMessages = array_merge($alertMessages, $alerts ?? []); + +if(!empty($alertMessages)) { + // We have alerts. Assign them to $flashArgs for later rendering. + $flashArgs['vv_alerts'] = $alertMessages; } // If you're looking to set a custom $vv_title, you might be able to use @@ -189,26 +210,6 @@ element('flash', $flashArgs) ?> -changelogAttributeName(); - - if($vv_obj->deleted) { - print $this->element('notify/alert', - ['type' => 'information', - 'message' => __d('information', 'changelog.deleted'), - 'dismissible ' => false] - ); - } elseif(!empty($vv_obj->$clfield)) { - print $this->element('notify/alert', - ['type' => 'information', - 'message' => __d('information', 'changelog.archived'), - 'dismissible ' => false] - ); - } -?> - - +
Flash->render(); /* Render information banners explicitly defined in Configuration. - In columns.inc files, these are defined in the banners[] array. + These are defined in the alerts[] array in columns.inc and fields.inc files. See app/templates/ApiUsers/columns.inc for an example. These must - be passed in as $vv_banners to this element from the calling template. - - NOTE: In fields.inc files, add information banners by referencing - the 'notify/alert' element directly (just as we do here). + be passed in as $vv_alerts to this element from the calling template. */ - if(!empty($vv_banners)) { - foreach($vv_banners as $b) { - print $this->element('notify/alert', ['message' => $b]); + if(!empty($vv_alerts)) { + foreach($vv_alerts as $a) { + print $this->element('notify/alert', $a); } } ?> diff --git a/app/templates/element/notify/alert.php b/app/templates/element/notify/alert.php index 966bbf36f..110a05091 100644 --- a/app/templates/element/notify/alert.php +++ b/app/templates/element/notify/alert.php @@ -36,7 +36,6 @@ */ $type ??= 'warning'; - $alertClass = "alert-{$type}"; $showButton = false; @@ -47,7 +46,7 @@ ?>