Moves the controller declarations from the inner div onto the frame tags
themselves, so the list refresh controller reloads `this.element` instead
of breaking out via `closest`.
The turbo frame tags carry identical attributes, so that morph refreshes
cannot strip the controllers off the live element.
Resolves a list move when either `list_type` or `list_id` is given, so a
`list_id` passed without its type now fails as an invalid target instead
of being silently ignored by the direction handling.
A menu item that opens a modal closes its popover asynchronously, so the
overlay can disappear between the visibility check in `dismiss_menu` and
the click, raising `Capybara::ElementNotFound`.
Rescues it like the existing interactability case, re-raising unless the
menu is gone or a modal owns focus.
Moves the cursor modifiers from rows onto the card itself, drops the old
row tab stop, and applies the box-list-item state colors. Clicking marks
a card selected instantly; aria-current still tracks the open item.
No template ever sets the per-item `moveUrl` Stimulus value, so the root
controller's URL template is the only move URL source. Drops the defunct
payload field, the resolver precedence branch, and the spec fixtures and
absence assertions that referenced the removed attribute.
Skip action-menu overlay dismissal once a modal is visible. Menu actions
can open the move dialog before the overlay is removed, and Selenium
cannot click that stale overlay while the modal owns focus.
Always restore the Backlogs move-request probe after the pick-up helper
runs, including obsolete-node retries and early exits.
Also make URI template expansion fully null-safe so a missing
URITemplate extension skips template-based moves instead of throwing
from toString().
Keep the move-request probe installed until the no-request assertion has
observed the settled drag result.
Also assert against the real Pragmatic DnD target types so the
pick-up-and-release probe can catch an accidental item-level target.
The Backlogs move service still supports absolute position moves, but
the controller was filtering the position parameter before it reached
the service.
Permit the parameter again and cover the controller hop so position-only
moves keep working while prev_id precedence remains in the service
specs.
Replaces the per-item move URLs with a single RFC 6570 URL template that
the `sortable-lists` container renders once, and the Stimulus controller
expands client-side. This deduplicates the URL across the rows and keeps
query parameters such as `all=1` in one place.
Centralises the sprint/backlog_bucket/inbox to column mapping that was
duplicated as inverse logic between `WorkPackageCardMenuComponent` (work
package state to list inputs) and `Backlogs::WorkPackages::UpdateService`
(list inputs to persisted attributes), so the list-type vocabulary and
the `list_id` normalisation rules live in a single place.
Replaces the previous Dragula-oriented card/list wiring with Pragmatic
Drag and Drop Stimulus controllers for backlog cards and list targets.
Keeps draggable card state client-side, submits moves through the
existing backlogs move endpoints, and tolerates empty drop-target
reports by resolving the element under the pointer.
Renders the draggable attribute and Stimulus item id from the server so
Turbo morphs preserve the DnD contract.
Unifies the move-target encoding on a list_type/list_id pair across the
drag JS, move dialogs, and card menu, dropping the legacy target_id
string so the service resolves the destination list directly. Renders
both move dialogs through the Primer forms DSL instead of safe_join.
https://community.openproject.org/wp/AGILE-251