From 06868738f7e13d4b4fa18c3ce7310ddf6c6610ca Mon Sep 17 00:00:00 2001 From: Arlen Johnson Date: Wed, 12 Aug 2026 13:45:57 -0400 Subject: [PATCH] Ensure read-only items are not bulk-selectable (CFM-536) --- app/templates/Standard/index.php | 14 +- app/templates/element/bulk/checkbox.php | 28 ++++ app/templates/element/javascript.php | 2 +- app/templates/element/menuAction.php | 164 ++++++++++++------------ app/webroot/css/co-base.css | 4 +- 5 files changed, 122 insertions(+), 90 deletions(-) diff --git a/app/templates/Standard/index.php b/app/templates/Standard/index.php index dfaff9d5e..55c4a5cec 100644 --- a/app/templates/Standard/index.php +++ b/app/templates/Standard/index.php @@ -112,7 +112,6 @@ && empty($action_args) ) { $action_args = []; - $action_args['vv_attr_id'] = $vv_user['username']; $action_args['vv_actions'] = []; // Include the Add link to actions menu unless suppressed by the page @@ -171,17 +170,18 @@ ]; } } + } + + if(!empty($bulkActions)) { + $action_args['vv_bulk_actions'] = $bulkActions; // Declare the type of actions being sent so we can produce the bulk actions switch only for top-links. - // XXX Bulk actions are currently being provided if a user has "add" permissions. Review this. $action_args['vv_actions_type'] = 'top-links'; - - if(!empty($bulkActions)) { - $action_args['vv_bulk_actions'] = $bulkActions; - } } ?> - + diff --git a/app/templates/element/bulk/checkbox.php b/app/templates/element/bulk/checkbox.php index 06cbc8055..15cdd108d 100644 --- a/app/templates/element/bulk/checkbox.php +++ b/app/templates/element/bulk/checkbox.php @@ -33,10 +33,36 @@ */ declare(strict_types = 1); + +use App\Lib\Enum\PetitionStatusEnum; + +// Set up defaults +$readOnly = false; +$permissionSet = $vv_permission_set ?? null; + if(empty($entity)) { $id = 'bulk-action-select-all'; } else { $id = "bulk-action-id-{$entity->id}"; + + // Special handling for specific models + // GROUP MEMBERS + if ($entity instanceof \App\Model\Entity\GroupMember) { + // If the member came from a Group Nesting, currently no bulk actions (just delete) are allowed + if(isset($entity->group_nesting)) { + $readOnly = true; + } + } + // PETITIONS + if ($entity instanceof \App\Model\Entity\Petition) { + // Currently, we support bulk termination of Petitions. + // A petition can be terminated only if it is not in a completed status. + // Also cross-reference the $permissionsSet for the entity to see if termination is disallowed. + if(in_array($entity->status, PetitionStatusEnum::getCompleted(), true) + || ($permissionSet[$entity->id]['terminate'] ?? null) === false) { + $readOnly = true; + } + } } ?> @@ -46,11 +72,13 @@ type="checkbox" value="" id="" + data-entity="" data-entity-id="id ?>" > \ No newline at end of file diff --git a/app/templates/element/javascript.php b/app/templates/element/javascript.php index d3376b854..2487234e8 100644 --- a/app/templates/element/javascript.php +++ b/app/templates/element/javascript.php @@ -333,7 +333,7 @@ // Bulk edit select all checkbox $('#bulk-action-select-all').click(function() { if($(this).is(":checked")) { - $('table.index-table.bulk-edit-mode .form-check-input').prop('checked', true); + $('table.index-table.bulk-edit-mode .form-check-input:not(:disabled)').prop('checked', true); } else { $('table.index-table.bulk-edit-mode .form-check-input').prop('checked', false); } diff --git a/app/templates/element/menuAction.php b/app/templates/element/menuAction.php index 1120dcca7..52862355a 100644 --- a/app/templates/element/menuAction.php +++ b/app/templates/element/menuAction.php @@ -27,12 +27,12 @@ // If you're debugging a null $vv_actions, there's probably a permissions problem // you need to trace -$actionsCount = count($vv_actions) + (int)!empty($vv_people_picker); +$actionsCount = count($vv_actions ?? []) + (int)!empty($vv_people_picker); $actionsCountClass = $actionsCount > 0 ? ' actions-count-' . $actionsCount : ''; -$actionsExpandedClass = ($actionsCount > 0 && $actionsCount < 4) ? ' actions-expanded' : ''; +$actionsExpandedClass = ($actionsCount > 0 && $actionsCount < 5) ? ' actions-expanded' : ''; $actionsMenuClass = (!empty($vv_actions_class) ? $vv_actions_class : 'field-actions-menu') . ' dropdown dropleft' . $actionsCountClass . $actionsExpandedClass; -$actionsMenuUid = md5($vv_attr_id); +$actionsMenuUid = md5($vv_attr_id ?? $vv_user['username']); $actionsType = !empty($vv_actions_type) ? $vv_actions_type : 'row-actions'; $actionsTitle = !empty($vv_actions_title) ? $vv_actions_title : ''; $actionsIcon = !empty($vv_actions_icon) ? $vv_actions_icon : 'settings'; @@ -58,10 +58,12 @@ class=""> ); // Sort the actions - usort($vv_actions, function ($item1, $item2) { - if ($item1['order'] == $item2['order']) return 0; - return $item1['order'] < $item2['order'] ? -1 : 1; - }); + if($actionsCount > 1) { + usort($vv_actions, function($item1, $item2) { + if($item1['order'] == $item2['order']) return 0; + return $item1['order'] < $item2['order'] ? -1 : 1; + }); + } ?>