[AGILE-364] Apply batch selection to contextual ActionMenus - #24781
Draft
myabc wants to merge 6 commits into
Draft
[AGILE-364] Apply batch selection to contextual ActionMenus#24781myabc wants to merge 6 commits into
myabc wants to merge 6 commits into
Conversation
Resolve each action menu scope before presentation so contextual and More-button invocation share one synchronous selection policy. The item projects availability from that settled scope while retaining non-mutating late refreshes for deferred menu content. https://community.openproject.org/wp/AGILE-364
Render singular and selection-backed actions in stable Primer groups. Project plural headings and hide empty batch groups from the settled action scope while preserving existing action and focus contracts. https://community.openproject.org/wp/AGILE-364
Update the selected count through the group aria-labelledby relationship so Primer heading IDs remain stable. Hide the selected-work-packages heading whenever a true batch has no visible action. https://community.openproject.org/wp/AGILE-364
Locks all card-menu entry points to one observable action-scope contract so presenter changes cannot silently collapse or retarget selected batches. https://community.openproject.org/wp/AGILE-364
Project the settled action scope before exposing deferred batch destinations and position controls. This prevents fixed invokers from presenting a stale selected-group menu while retaining defence-in-depth no-ops and one-card eligible behavior. Remove the obsolete collapseForMove shim and document the selection port accurately. https://community.openproject.org/wp/AGILE-364
Batch top placement into empty targets and source sprint lifecycle operations could race because only append and destination lifecycles were serialized. Lock unanchored target placements, order source and target lifecycle mutexes, and revalidate each member's captured source under lock. https://community.openproject.org/wp/AGILE-364
Contributor
There was a problem hiding this comment.
Pull request overview
This PR unifies Backlogs work package ActionMenu behavior across all entry points (More button, right-click, Context Menu key, Shift+F10) by settling the live action scope before menu presentation, and by splitting the menu into stable singular vs batch action groups while preserving the one-card experience.
Changes:
- Add a shared “prepareActionMenu” pre-open path (contextual
beforeOpen+ popoverbeforetoggle) so every invocation settles selection/action scope consistently. - Render two stable ActionMenu groups (“This work package” vs “Selected work packages”) and let the item controller project visibility + pluralized headings based on the resolved scope.
- Strengthen batch move locking to include ordered source/target lifecycle locks and serialize unanchored placements (append/top), with expanded concurrency coverage.
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| modules/backlogs/spec/support/pages/backlog.rb | Adds higher-level helpers for opening/validating menus via all entry points and probing batch move payloads. |
| modules/backlogs/spec/services/backlogs/work_packages/batch_update_service_spec.rb | Updates lock-order expectations to match new lifecycle/placement locking. |
| modules/backlogs/spec/services/backlogs/work_packages/batch_update_service_concurrency_spec.rb | Adds concurrency scenarios covering inbox placement/top moves and sprint-finish races. |
| modules/backlogs/spec/features/work_packages/move_via_menu_spec.rb | Switches to new batch-aware menu action helper for positional actions. |
| modules/backlogs/spec/features/work_packages/card_context_menu_spec.rb | Uses unified menu-opening helper for right-click and Shift+F10. |
| modules/backlogs/spec/features/work_packages/batch_action_menu_spec.rb | New feature spec ensuring consistent batch projection across all menu entry points. |
| modules/backlogs/spec/components/backlogs/work_package_card_menu_component_spec.rb | Verifies stable ActionMenu groups/headings and fixed-work-package behavior. |
| modules/backlogs/config/locales/js-en.yml | Adds pluralized JS translation for “selected work packages” heading. |
| modules/backlogs/config/locales/en.yml | Adds “This work package” translation for the menu group heading. |
| modules/backlogs/app/services/backlogs/work_packages/batch_update_service.rb | Extends batch move synchronization: ordered lifecycle locks + placement serialization + tighter cohort validation. |
| modules/backlogs/app/components/backlogs/work_package_card_menu_component.html.erb | Renders two Primer ActionMenu groups with hidden headings and moves batch actions into the batch group. |
| frontend/src/stimulus/controllers/dynamic/sortable-lists/selection-orchestrator.ts | Removes now-unused move-collapse hook as action scope settling moves to menu preparation. |
| frontend/src/stimulus/controllers/dynamic/sortable-lists/selection-orchestrator.spec.ts | Adds coverage for fixed invoker behavior without disturbing selection anchors. |
| frontend/src/stimulus/controllers/dynamic/sortable-lists/scrollable.controller.spec.ts | Updates root stub to include the new prepareActionMenu port. |
| frontend/src/stimulus/controllers/dynamic/sortable-lists/list.controller.spec.ts | Updates root stub to include the new prepareActionMenu port. |
| frontend/src/stimulus/controllers/dynamic/sortable-lists/item.controller.ts | Adds pre-open listeners, projects grouped menu visibility/headings, and updates availability projection to use prepared scope. |
| frontend/src/stimulus/controllers/dynamic/sortable-lists/item.controller.spec.ts | Adds extensive tests for pre-open sequencing and grouped heading/group projection. |
| frontend/src/stimulus/controllers/dynamic/sortable-lists/drag-and-drop.ts | Updates SortableListsRoot port documentation and adds prepareActionMenu to the interface. |
| frontend/src/stimulus/controllers/dynamic/sortable-lists.controller.ts | Implements prepareActionMenu by delegating to selection settling (selectForAction). |
| frontend/src/stimulus/controllers/dynamic/sortable-lists.controller.spec.ts | Adds tests for action menu invocation scope behavior and idempotent duplicate delivery. |
| frontend/src/stimulus/controllers/dynamic/contextual-action-menu.controller.spec.ts | Adds tests ensuring beforeOpen dispatch order, cancelability, and cancellation behavior. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| expect(menu).to have_css(batch_group) | ||
|
|
||
| if selected_count > 1 | ||
| expect(menu).to have_css(singular_heading, text: "This work package") |
Comment on lines
+108
to
+110
| expect(menu.find(:menuitem, text: "Copy URL to clipboard")[:value]) | ||
| .to end_with("/work_packages/#{invoker.id}") | ||
| expect(menu.find(:menuitem, text: "Copy work package ID")[:value]).to eq(invoker.id.to_s) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ticket
AGILE-364
This PR is stacked directly on #24780 and is the user-facing tip of the coordinated #24779/#24780/#AGILE-364 release train.
What are you trying to accomplish?
Make every Backlogs ActionMenu entry point settle and present the same action scope while keeping singular actions bound to the invoking card.
The change:
What approach did you choose and why?
The Backlogs item controller listens at the two established pre-open boundaries: contextual
beforeOpenand the menu popover's capture-phasebeforetoggle. Both call the same rootprepareActionMenuoperation; duplicate delivery is idempotent, and the late include-fragment refresh remains non-mutating.Rails renders two stable Primer groups with initially hidden headings. Stimulus reveals plural headings only for a true batch, updates the nested labelled title without disturbing
aria-labelledby, and hides the batch heading and group together when no batch action applies. Each action still re-resolves live scope at activation.Merge checklist