vibe-kanban icon indicating copy to clipboard operation
vibe-kanban copied to clipboard

Add drag-and-drop workspace reordering with persistent sort order (Vibe Kanban)

Open stunningpixels opened this issue 3 months ago • 2 comments

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_order column (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 Workspace model with sort_order: f64 field
  • Updated all workspace SQL queries to include sort_order
  • Extended UpdateWorkspace endpoint to accept optional sort_order parameter

Frontend (TypeScript/React)

  • Installed @dnd-kit/sortable package
  • Created SortableWorkspaceItem component with drag handle and visual feedback
  • Wrapped workspace lists in DndContext and SortableContext providers
  • Implemented calculateNewSortOrder using 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

stunningpixels avatar Jan 15 '26 12:01 stunningpixels