Let a column go where it is dropped, instead of stepping it one place at a time with a button.
What it is like today. A column moves only through ◀ / ▶ (POST /b/:id/columns/:columnId/move with direction=left|right), and db.moveColumn (src/db.ts:268) swaps it with its neighbour. Moving the fifth column to the front is four requests, four live events and four rows in the undo log — and four presses of Undo to put it back. Cards can be dragged; columns cannot be dragged at all (dragstart in static/board.822340210.js is bound to .card only). On a board at this app's cap that is 50 columns reachable one swap at a time.
Done looks like
[ ] db.moveColumnTo(boardId, columnId, index) places a column at a 0-based index among its siblings, with a fractional position from its neighbours and a renormalise-to-1..n when the gap collapses — the same shape moveCard already has, in one immediate() transaction, logging every row it overwrote so one Undo restores the whole order.
[ ] POST /b/:id/columns/:columnId/move accepts index=<n> as well as direction=left|right; direction keeps working unchanged (JavaScript off, the terminal's [ and ], and the existing tests). index is validated at the boundary exactly as moveCard's is — finite, non-negative, floored, clamped in the query.
[ ] Dragging a column header moves it: the header is the drag handle, a column dropped on another column takes its place, and the card drag path is untouched — a card dragged onto a column still lands in that column, which is the test that proves the two drags do not cross (distinct dataTransfer type per kind).
[ ] A focused column header moves with Alt+← / Alt+→ in one press per step, and both are in the ? dialog and the README.
[ ] Exactly one column.moved event per move, so another open tab reorders without a reload — the existing live handler for column.moved covers it or is extended.
[ ] Tests that fail without the change: src/db.test.ts (move to an index, the collapse renormalisation, one undo restoring the original order), src/server.test.ts (an index that is rubbish is refused with the board's own error shape; direction still works), and a happy-dom drag test.
It shares the drag code with #105 (an empty column as a drop target) and the header markup with #48 — land after #105 rather than editing the same handlers twice.
Touch: the press-and-hold path (src/touch.test.ts) is for cards. Either column drag is mouse-and-keyboard only, said plainly in the README, or it gets the same treatment — do not leave a half-working gesture on a phone.
Keep direction on the same route rather than adding a second one: the terminal and the no-JS forms both post it today.
Suggested: scout, reviewed by juniper. Waits for #105.
Let a column go where it is dropped, instead of stepping it one place at a time with a button.
What it is like today. A column moves only through ◀ / ▶ (
POST /b/:id/columns/:columnId/movewithdirection=left|right), anddb.moveColumn(src/db.ts:268) swaps it with its neighbour. Moving the fifth column to the front is four requests, four live events and four rows in the undo log — and four presses of Undo to put it back. Cards can be dragged; columns cannot be dragged at all (dragstartinstatic/board.822340210.jsis bound to.cardonly). On a board at this app's cap that is 50 columns reachable one swap at a time.Done looks like
db.moveColumnTo(boardId, columnId, index)places a column at a 0-based index among its siblings, with a fractional position from its neighbours and a renormalise-to-1..n when the gap collapses — the same shapemoveCardalready has, in oneimmediate()transaction, logging every row it overwrote so one Undo restores the whole order.POST /b/:id/columns/:columnId/moveacceptsindex=<n>as well asdirection=left|right;directionkeeps working unchanged (JavaScript off, the terminal's[and], and the existing tests).indexis validated at the boundary exactly asmoveCard's is — finite, non-negative, floored, clamped in the query.dataTransfertype per kind).Alt+←/Alt+→in one press per step, and both are in the?dialog and the README.column.movedevent per move, so another open tab reorders without a reload — the existing live handler forcolumn.movedcovers it or is extended.src/db.test.ts(move to an index, the collapse renormalisation, one undo restoring the original order),src/server.test.ts(anindexthat is rubbish is refused with the board's own error shape;directionstill works), and a happy-dom drag test.Files I expect to change
src/db.ts,src/routes.ts,src/pages/board.ts(header markup, shortcuts),static/board.<new-hash>.js+BOARD_JS,src/db.test.ts,src/server.test.ts,src/drag.test.ts,README.md.Risks
src/touch.test.ts) is for cards. Either column drag is mouse-and-keyboard only, said plainly in the README, or it gets the same treatment — do not leave a half-working gesture on a phone.directionon the same route rather than adding a second one: the terminal and the no-JS forms both post it today.Suggested: scout, reviewed by juniper. Waits for #105.