4.2.5 Multi-select + atomic bulk move + inline create + row context menu (the grooming actions)
Estimate: 30m · Depends on: 4.2.1, 4.2.3, 4.2.4, 4.2.2
The grooming actions on top of the rendered + draggable backlog: multi-select with an atomic bulk move, inline issue create into the backlog or a sprint, and the per-row ⋯ context menu. Drawn per the 4.2.1 multi-select + context-menu panels; binds to the 4.2.2 bulk/create endpoints.
Multi-select. A selection model over the rows: click selects, shift-click selects the range, ⌘/ctrl-click toggles one (the Jira backlog selection model). Selected rows take the design's selected treatment; a selection bar shows "N selected" + bulk Move to sprint ▸ (submenu of the project's sprints) + Move to backlog. Selection survives lazy-load of more rows (key by issue id, not row index — it must not break as the virtualized window scrolls).
Atomic bulk move (binds to 4.2.2). Bulk actions call 4.2.2 bulkAssignToSprint / bulkMoveToBacklog — ONE request, one transaction (NOT a client loop over the single-issue endpoint): the whole selection moves or none does. Optimistic with snap-back on failure (the 4.2.4 contract); counts update; the selection clears on success. Multi-select drag (dragging a selection of N rows, the "N issues" overlay from 4.2.1) routes through the same bulk path.
Inline create (binds to 4.2.2). The + Create issue rows (in the backlog and in each sprint container, placed by 4.2.3) call 4.2.2 createBacklogIssue — into the backlog (rank-appended) or directly into that sprint (assigned) — in one action; the new row appears in place without a full reload.
Row context menu (⋯). Per-row actions: Move to sprint ▸ (submenu), Move to backlog, Move to top / bottom of backlog (rank to the boundary via 4.1.4 rankIssue append/prepend). The menu reuses the shipped menu primitive (no nested buttons, no hand-rolled popover). Keyboard-operable; the seams later stories add (estimate/points) are NOT here.
Out of scope here: the points/velocity numbers (Stories 4.3 / 4.6); the Start/Complete-sprint FLOWS (Story 4.4 — the entry points are seams from 4.2.3); rich filtering (Epic 6).
Acceptance criteria
- Rows support click / shift-range / ⌘-toggle selection (keyed by issue id so it survives lazy-load + virtualized scroll); selected rows take the design treatment; a selection bar shows "N selected" + Move to sprint ▸ + Move to backlog.
- Bulk move calls 4.2.2
bulkAssignToSprint/bulkMoveToBacklogas ONE atomic request (not a client loop); optimistic with snap-back on failure; counts update; selection clears on success; multi-select drag of N rows routes through the same bulk path. - The inline + Create issue rows call 4.2.2
createBacklogIssueto create into the backlog (rank-appended) or a sprint (assigned) in one action; the new row appears in place. - The
⋯row menu offers Move to sprint ▸ / Move to backlog / Move to top|bottom of backlog (4.1.4rankIssueboundary), reuses the shipped menu primitive (no nested buttons), and is keyboard-operable. - Colour via
--el-*, shape via element tokens, AA-safe; matchesdesign/backlog/backlog.mock.html. - Component tests assert the selection model (incl. shift-range + survive-lazy-load), the atomic bulk move (one request + snap-back), inline create into backlog + sprint, and the
⋯menu actions.
Context refs
- Story 4.2.2 (
bulkAssignToSprint/bulkMoveToBacklog/createBacklogIssue) — the atomic endpoints these actions bind to; Story 4.2.4 (optimistic/snap-back + the dnd context) — the drag path multi-select drag reuses design/backlog/backlog.mock.htmlmulti-select + context-menu panels (4.2.1) — the selection bar +⋯menu speccomponents/ui/*menu primitive (the shipped dropdown/menu; no nested buttons) + the work-items row;app/(authed)/boards/_components/ColumnActionsMenu.tsx— the row/column⋯menu pattern to mirror- finding #35 (selection read as text, not colour-alone);
motir-core/CLAUDE.md(--el-*+ element-shape, menu primitive reuse)