Skip to content

[AGILE-363] Add positional actions for contiguous selections - #24780

Draft
myabc wants to merge 6 commits into
implementation/AGILE-362-batch-destinationsfrom
implementation/AGILE-363-batch-position-actions
Draft

[AGILE-363] Add positional actions for contiguous selections#24780
myabc wants to merge 6 commits into
implementation/AGILE-362-batch-destinationsfrom
implementation/AGILE-363-batch-position-actions

Conversation

@myabc

@myabc myabc commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

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:

  • resolves Top, Up, Down, and Bottom from one pure block-placement contract
  • omits positional actions for sparse, cross-list, truncated, unaddressable, and effective no-op scopes
  • preserves selected document order and excludes selected rows from predecessor resolution
  • reuses the existing optimistic atomic collection move, rollback, announcement, busy, and selection lifecycle

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 performMove path. 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

  • Added/updated tests: 53 focused Rails/component/Selenium examples; 343 focused frontend tests
  • Ran focused RuboCop and ESLint
  • Independent task reviews completed; whole-branch review completed before publication
  • Added/updated documentation in Lookbook (not applicable)
  • Tested major browsers beyond the Chromium feature suite

myabc added 6 commits August 16, 2026 04:05
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
@myabc myabc changed the title implementation/AGILE 363 batch position actions [AGILE-363] Add positional actions for contiguous selections Aug 16, 2026
@myabc
myabc requested a lite review from Copilot August 16, 2026 09:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 / resolveBlockMoveAvailability to 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants