vibe-kanban
vibe-kanban copied to clipboard
Add drag-and-drop workspace reordering with persistent sort order (Vibe Kanban)
Summary
- Added drag-and-drop reordering for workspaces in the sidebar
- Implemented persistent sort order that survives across sessions
- Uses fractional indexing for efficient reordering (single API call per drag operation)
- Supports reordering within both active and archived workspace views
- Pinned workspaces stay grouped at top; reordering works within pinned/unpinned groups separately
Test plan
- [ ] Create several workspaces and verify they appear newest-first by default
- [ ] Drag a workspace to reorder it within unpinned workspaces
- [ ] Pin some workspaces and verify pinned group stays at top
- [ ] Drag to reorder within pinned workspaces
- [ ] Archive workspaces and switch to archived view
- [ ] Verify archived workspaces appear newest-first
- [ ] Drag to reorder archived workspaces
- [ ] Refresh the page and verify all reordering persists
Changes
Database
- Added
sort_ordercolumn (REAL type for fractional indexing) to workspaces table - Migration initializes existing workspaces with sort order based on creation date (newest first)
- New workspaces default to sort_order=0, appearing at top of the list
Backend (Rust)
- Extended
Workspacemodel withsort_order: f64field - Updated all workspace SQL queries to include sort_order
- Extended
UpdateWorkspaceendpoint to accept optionalsort_orderparameter
Frontend (TypeScript/React)
- Installed
@dnd-kit/sortablepackage - Created
SortableWorkspaceItemcomponent with drag handle and visual feedback - Wrapped workspace lists in
DndContextandSortableContextproviders - Implemented
calculateNewSortOrderusing fractional indexing algorithm - Added optimistic updates for smooth drag-and-drop UX
- Updated sorting logic: pinned first, then by sort_order ascending
Key Implementation Details
- Fractional indexing: When moving an item, its new sort_order is calculated as the midpoint between its new neighbors, avoiding the need to update multiple records
- Optimistic updates: UI updates immediately on drag end, API call happens in background
- Separation of concerns: State management in container component, presentation in view component (per ESLint rules)
This PR was written using Vibe Kanban
🤖 Generated with Claude Code