Kanban: columns cannot be reordered #69
Labels
No labels
prio_critical
prio_low
type_bug
type_contact
type_issue
type_lead
type_question
type_story
type_task
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
lhumina_code/hero_whiteboard#69
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
On a Kanban board, columns cannot be rearranged — dragging a column header
does not reorder it relative to the other columns. The column order remains
fixed at whatever was set at creation time.
Steps to reproduce
Expected
The dragged column is reordered to the drop position and the new column
order is persisted (survives reload).
Actual
The column does not move.
Implementation Spec for Issue #69
Objective
Enable Kanban column reordering via drag-and-drop of the column title handle, with the new order persisted across reloads, undoable/redoable, and synced to collaborators — without regressing existing column/card interactions.
Requirements
WhiteboardSync.onUpdate(group), which already serializesstate.columnsin array order.WhiteboardHistory.snapshotBefore/commitUpdate.×still works.Files to Modify
crates/hero_whiteboard_ui/static/web/js/whiteboard/kanban.js— the only file.No backend, schema, or serialization changes: column order is implicit in
state.columnsarray order, already round-tripped.Implementation Plan
Step 1 — Capture column layout at render time
Files:
kanban.js, functionrenderKanbancolumns.forEach(renderColumn ...)loop, stash per-column horizontal bounds on the group:state.columns.Dependencies: none.
Step 2 — Make
colTitlethe drag handleFiles:
kanban.js, functionrenderColumndraggable: trueto thecolTitleKonva.Text construction.×,+ Add card, cards remain independently interactive. Konva's dblclick threshold still triggers rename on no-drag clicks.Dependencies: none.
Step 3 —
colTitle.on('dragstart')Files:
kanban.jsgroup.add(colTitle)(and before the existing dblclick handler):e.cancelBubble = trueprevents the kanban group's existingdragstartfrom running simultaneously (otherwise both title and whole group would drag).moveToTop()keeps the dragged title above neighboring column backgrounds (same trickcardGroupuses).Dependencies: Step 2.
Step 4 —
colTitle.on('dragend')with reorder mathFiles:
kanban.jsdragstart:WhiteboardSync.onUpdatefires only after a real mutation (not on snap-back / same-slot), avoiding needless traffic.splice → renderKanban → commit → onUpdatepattern used by card reorder.Dependencies: Steps 1, 2, 3.
Acceptance Criteria
×delete, color indicator,+ Add card,+ Columnall still work.tr.forceUpdate()tail inrenderKanban).Notes
colTitlemoves with the cursor during drag. Column bg, color indicator,×,+ Add card, and cards stay put. Standard "grab the handle" affordance. A future enhancement could wrap the whole header band in a cardGroup-equivalent for richer feedback; out of scope here.state.columnsarray order.cardGroup.dragstart/dragendandgroup.dragstart/dragendare untouched. New handlers are additive.×, and future header UI. Narrow handle avoids coupling.draggable: truewithdblclick dbltapsuccessfully; same pattern here.Test Results
JavaScript-only change in
kanban.js; Rust workspace validated for regressions.cargo check --workspacecargo clippy --workspace -- -D warningscargo fmt --checkManual verification required: drag a column title past an adjacent column, release, confirm the columns reorder and that the new order persists across reload. Verify dblclick-to-rename, color indicator,
×delete, and card drag-and-drop still work.Implementation Summary
Kanban columns can now be reordered by dragging the column title. The new order persists across reload and supports undo/redo.
Files changed
crates/hero_whiteboard_ui/static/web/js/whiteboard/kanban.js(+66)Changes
renderKanbannow populatesgroup._kbColumnLayout— a per-render array of{x, w, center}per column, consumed by the dragend slot math.colTitleis markeddraggable: trueinrenderColumn.colTitle.on('dragstart'): cancels bubble (so the whole-kanban drag does not also fire), clears card selection, snapshots history, callsmoveToTop(), and records the source column index on the group.colTitle.on('dragend'): converts pointer to group-local coords, finds the target slot via the stored layout (with clamping for out-of-bounds drops), splices the column to its new position, re-renders, commits history, and callsWhiteboardSync.onUpdate. Snap-back / same-slot / single-column drops are no-ops and do not send sync traffic.Preserved
×delete button,+ Add card,+ Column.Scope notes
state.columnsarray order and already round-trips.colTitleKonva.Text moves with the cursor; the column background, color indicator,×,+ Add card, and cards stay in place. Standard "grab the handle" affordance — a future enhancement could wrap the whole header band into a drag sub-group.Test results
cargo check --workspace: passcargo clippy --workspace -- -D warnings: passcargo fmt --check: passManual QA required: reorder via drag, reload to verify persistence, Ctrl/Cmd+Z to verify undo, and regression-check the preserved interactions.
Pull request opened: #71
This PR implements the changes discussed in this issue.