[AGILE-363] Add positional actions for contiguous selections - #24780
Draft
myabc wants to merge 6 commits into
Draft
[AGILE-363] Add positional actions for contiguous selections#24780myabc wants to merge 6 commits into
myabc wants to merge 6 commits into
Conversation
Batch position actions need one authoritative DOM resolution so menu availability and execution cannot disagree. This change validates a live contiguous block and returns explicit reasons for every unavailable move, while preserving singular placement and sparse-list boundaries. https://community.openproject.org/wp/AGILE-363
Nested sortable lists can make an inner item appear to belong to an outer row during ancestor resolution. This guard verifies that each resolved row owns the supplied item, preventing mixed scopes from moving outer hosts. https://community.openproject.org/wp/AGILE-363
Resolve positional availability over the invoker's prospective action scope so the menu only offers batch moves the block resolver can execute. Preserve destination projection and divider composition while allowing contiguous selections to expose Move to position. https://community.openproject.org/wp/AGILE-363
Move to position resolved availability over selected blocks, but execution still collapsed to a singular member request. Route collection-capable roots through the live block resolver and shared optimistic lifecycle so ordered batches preserve rollback and selection semantics while other consumers keep their member endpoint. https://community.openproject.org/wp/AGILE-363
The positional block resolver and collection move lifecycle need browser-level guards for their shared menu behavior and async selection boundary. Cover all four directions, availability edge cases, optimistic order and announcements, success clearing, 422 rollback, and singular compatibility through semantic page helpers. https://community.openproject.org/wp/AGILE-363
Selection-enabled roots without a collection endpoint advertised batch position actions and, when the attribute was absent, executed the invoker through the singular member endpoint. Resolve the same nonblank collection capability before availability or selection mutation so batch menus fail closed while roots without selection retain their member behavior. https://community.openproject.org/wp/AGILE-363
5 tasks
Contributor
There was a problem hiding this comment.
Pull request overview
Adds support for Move to position actions to operate on a contiguous selected block of backlog cards (while preserving existing single-card behavior), using a shared block-move resolver for both menu gating and execution.
Changes:
- Introduces
resolveBlockMove/resolveBlockMoveAvailabilityto resolve predecessor placement for contiguous selections (and to reject sparse/cross-list/truncation-boundary/no-op scopes). - Updates sortable-lists controller/menu plumbing to use action-scope-based availability and to execute batch menu moves through the existing optimistic collection-move path.
- Expands backend + frontend test coverage for contiguous selection moves, gating behavior, and rollback/selection lifecycle.
Reviewed changes
Copilot reviewed 12 out of 12 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 page helpers for selecting contiguous cards and asserting Move-to-position availability. |
| modules/backlogs/spec/features/work_packages/batch_move_via_menu_spec.rb | New Selenium spec covering contiguous-block positional moves and rollback behavior. |
| modules/backlogs/spec/features/work_packages/batch_destination_menu_spec.rb | Updates destination menu spec to expect Move-to-position availability for contiguous multi-card scopes. |
| modules/backlogs/spec/components/backlogs/work_package_card_menu_component_spec.rb | Tightens expectations around Move-to-position menu rendering (client-driven availability, no legacy form fields). |
| frontend/src/stimulus/controllers/dynamic/sortable-lists/selection-orchestrator.ts | Updates documentation/comments to distinguish singular-collapse vs batch menu moves. |
| frontend/src/stimulus/controllers/dynamic/sortable-lists/list-dom.ts | Implements block-move resolution + availability helpers for contiguous selections. |
| frontend/src/stimulus/controllers/dynamic/sortable-lists/list-dom.spec.ts | Adds unit tests for block-move resolution across many boundary cases. |
| frontend/src/stimulus/controllers/dynamic/sortable-lists/item.controller.ts | Switches Move-to-position gating to rely on root-provided availability (no longer hides submenu purely for multi-card scope). |
| frontend/src/stimulus/controllers/dynamic/sortable-lists/item.controller.spec.ts | Updates/extends menu tests for showing/hiding batch position directions and the submenu. |
| frontend/src/stimulus/controllers/dynamic/sortable-lists/drag-and-drop.ts | Clarifies move availability semantics in the interface comment. |
| frontend/src/stimulus/controllers/dynamic/sortable-lists.controller.ts | Uses block-move availability/execution for selection-backed menu moves. |
| frontend/src/stimulus/controllers/dynamic/sortable-lists.controller.spec.ts | Adds coverage for batch menu moves, rollback behavior, and batch availability reporting. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
420
to
+424
| moveAvailability(itemElement:HTMLElement):MoveAvailability|null { | ||
| const scope = this.actionScopeFor(itemElement); | ||
| if (scope.kind === 'singular') { | ||
| return null; | ||
| } |
Comment on lines
+774
to
778
| def select_contiguous_cards(first, last) | ||
| toggle_card(first) | ||
| extend_selection_to(last) | ||
| expect(page).to have_css("[data-batch-selected]", count: 2) | ||
| end |
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-363
This PR is stacked directly on #24779.
What are you trying to accomplish?
Make the existing Backlogs Move to position submenu move either one card or one contiguous selected block in the same list.
The change:
What approach did you choose and why?
Menu availability and activation both call the same resolver. Activation settles the live action scope, resolves again against the current innermost owned list, and passes the ordered rows and IDs to the existing collection
performMovepath. Roots without the selection/collection capability retain their singular member-move behavior.The resolver validates row ownership so nested sortable lists cannot substitute an outer host row for an inner work package. Fixed rows remain addressable neighbours but cannot enter the selected block, and one-step moves never cross a truncation marker.
Merge checklist