Skip to content

feat(desktop): drag-and-drop for panes between tabs#859

Merged
Kitenite merged 8 commits into
mainfrom
reimpl-drag-pane
Jan 21, 2026
Merged

feat(desktop): drag-and-drop for panes between tabs#859
Kitenite merged 8 commits into
mainfrom
reimpl-drag-pane

Conversation

@Kitenite
Copy link
Copy Markdown
Collaborator

@Kitenite Kitenite commented Jan 20, 2026

Summary

  • Reimplements pane drag-and-drop to move panes between tabs using mosaic's built-in drag system
  • Adds drag-pane-store to track which pane is being dragged (since MosaicDragItem only has mosaicId)
  • Drop on existing tab moves pane to that tab with duplicate prevention
  • Drop on new tab area creates a new tab with the dragged pane
  • Fixes bug where moved panes were incorrectly deleted (now checks if pane's tabId changed before removing)

Test plan

  • Drag a pane from one tab to another tab - should move the pane
  • Drag a pane to the new tab drop zone (right of tabs) - should create new tab
  • Verify dragging the last pane in a tab to new tab is prevented
  • Verify duplicate panes cannot be added to the same tab
  • Verify tabs show subtle highlight when dragging over them
  • Verify new tab area shows left indicator when dragging over

Summary by CodeRabbit

  • New Features

    • Drag-and-drop to reorganize panes across tabs, including dropping onto existing or new tabs.
    • Visual drop targets and highlights while dragging.
    • Expanded tab presets UI with preset icons, default badge, and "Configure Presets" option.
  • Bug Fixes

    • Prevents creating duplicate panes in the same tab when moving.
    • Avoids accidental removal of panes belonging to other tabs during moves.
    • More reliable drag state tracking (start/end).

✏️ Tip: You can customize this high-level summary in your review settings.

- Tabs show subtle bg-primary/5 highlight when dragging over
- NewTabDropZone shows left indicator bar without layout shift
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 20, 2026

📝 Walkthrough

Walkthrough

Adds pane drag-and-drop across tabs: introduces a drag-pane Zustand store, a reusable NewTabDropZone, drop handling in GroupItem/GroupStrip, drag wiring in BasePaneWindow, and guards in tabs store and move-pane action to avoid unintended removals or duplicates.

Changes

Cohort / File(s) Summary
Drag-pane state management
apps/desktop/src/renderer/stores/drag-pane-store.ts
New useDragPaneStore Zustand hook tracking draggingPaneId and draggingSourceTabId with setDragging(paneId, tabId) and clearDragging() actions.
Drop zone component
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/GroupStrip/NewTabDropZone.tsx
New NewTabDropZone component using useDrop for MosaicDragType.WINDOW; enforces canDrop (avoids last-in-tab), calls onDrop(paneId), clears drag state, and exposes hover feedback.
Tab strip & group integration
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/GroupStrip/GroupItem.tsx, .../GroupStrip.tsx
GroupItem wired with useDrop, visual highlight when droppable, and new props isActive, status, onPaneDrop?: (paneId: string) => void. GroupStrip wraps dropdown with NewTabDropZone, wires movePaneToTab/movePaneToNewTab, passes onPaneDrop, and updates preset dropdown UI.
Pane window drag lifecycle
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/components/BasePaneWindow/BasePaneWindow.tsx
Adds onDragStart -> setDragging and onDragEnd -> clearDragging to populate/clear drag store during user drags.
Tab layout / pane removal guards
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/index.tsx, apps/desktop/src/renderer/stores/tabs/store.ts, apps/desktop/src/renderer/stores/tabs/actions/move-pane.ts
TabView.handleLayoutChange reads fresh panes/layout to compute removals and skips panes moved to another tab; updateTabLayout only deletes panes that still belong to the tab (prevents foreign deletions); movePaneToTab guards against duplicate pane moves.
Misc UI & table tweaks
apps/desktop/src/renderer/screens/main/components/TasksView/..., apps/desktop/src/renderer/screens/main/components/TasksView/hooks/useTasksTable/...
Minor table/layout refactors: remove status column for leaf rows, rename constants for slug width, remove placeholder column and cleanup comments.
CLI minor cleanup
apps/cli/src/lib/launch/config.ts
Simplified getLaunchCommand by removing intermediate agentType variable and cleaning related comments.

Sequence Diagram

sequenceDiagram
    participant User
    participant BasePaneWindow
    participant DragPaneStore
    participant GroupItem
    participant GroupStrip
    participant TabsStore

    User->>BasePaneWindow: drag start (onDragStart)
    BasePaneWindow->>DragPaneStore: setDragging(paneId, sourceTabId)
    DragPaneStore->>DragPaneStore: store draggingPaneId, draggingSourceTabId

    User->>GroupItem: hover / enter
    GroupItem->>DragPaneStore: read draggingPaneId & draggingSourceTabId
    GroupItem->>GroupItem: canDrop? (not same, not duplicate, not last-in-tab)
    Note over GroupItem: show highlight if droppable

    User->>GroupItem: drop
    alt canDrop true
        GroupItem->>GroupStrip: onPaneDrop(paneId)
        GroupStrip->>TabsStore: movePaneToTab(paneId, targetTabId) / movePaneToNewTab(paneId)
        TabsStore->>TabsStore: check duplicate, update layouts, preserve panes that moved away
    end

    User->>BasePaneWindow: drag end (onDragEnd)
    BasePaneWindow->>DragPaneStore: clearDragging()
    DragPaneStore->>DragPaneStore: reset dragging state
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly Related PRs

Poem

🐰 I hopped a pane from here to there,
Across the tabs with gentle care,
Zustand held my tiny trail,
Drop zones lit — a glowing veil,
A happy hop — the workspace fair!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: reimplementing drag-and-drop functionality for panes between tabs, which is the primary focus of the changeset.
Description check ✅ Passed The PR description provides a clear summary of changes and includes a comprehensive test plan, though it lacks formal issue links, explicit type of change classification, and testing results.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Return { handled: true } from drop handlers to signal that the drop
was processed, preventing mosaic from also trying to handle the drop.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jan 21, 2026

🧹 Preview Cleanup Complete

The following preview resources have been cleaned up:

  • ✅ Neon database branch
  • ✅ Electric Fly.io app

Thank you for your contribution! 🎉

@Kitenite Kitenite changed the title feat(desktop): reimplement drag-and-drop for panes between tabs feat(desktop): drag-and-drop for panes between tabs Jan 21, 2026
@Kitenite Kitenite merged commit 8db4e68 into main Jan 21, 2026
12 of 13 checks passed
@Kitenite Kitenite deleted the reimpl-drag-pane branch January 21, 2026 01:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant