Conversation
Allow dragging panes from the mosaic layout to the tab bar: - Drop on existing tab to move pane to that tab - Drop on empty tab bar space to create new tab with pane Uses MosaicWindow's onDragStart/onDragEnd callbacks to track the currently dragged pane, since react-mosaic's drag item doesn't include the pane ID.
|
Caution Review failedThe pull request is closed. 📝 WalkthroughWalkthroughAdds drag-and-drop for panes into tab groups: introduces a dragging-pane Zustand store, wires drag start/end on pane windows, and implements drop targets on group items and the strip to move panes between tabs or create new tabs. Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant PaneWindow as Pane Window
participant DragStore as Dragging Pane Store
participant GroupStrip as GroupStrip
participant GroupItem as GroupItem (Tab)
participant TabStore as Tab Store
User->>PaneWindow: drag start (pointer down + move)
PaneWindow->>DragStore: setDraggingPane(paneId, tabId)
DragStore-->>PaneWindow: dragging state set
User->>GroupItem: drag over
GroupItem->>DragStore: read draggingPaneId/draggingTabId (canDrop)
GroupItem-->>User: show highlight (isOver/canDrop)
User->>GroupItem: drop
GroupItem->>DragStore: get fresh draggingPaneId & clear dragging state
GroupItem->>GroupStrip: onPaneDrop(paneId) / notify strip
GroupStrip->>TabStore: movePaneToTab(paneId, targetTabId) or movePaneToNewTab(paneId)
TabStore-->>GroupStrip: pane relocated
User->>PaneWindow: drag end
PaneWindow->>DragStore: setDraggingPane(null, null)
DragStore-->>All: dragging cleared
Estimated code review effort🎯 4 (Complex) | ⏱️ ~40 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In
`@apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/GroupStrip/GroupItem.tsx`:
- Around line 37-58: The canDrop logic is too permissive: tighten canDrop and
the drop handler in the useDrop call so they inspect the dragged item (via
monitor.getItem()) and ensure the pane's source tab/workspace differ (or
otherwise meet your valid-target rules) before returning true or invoking
onPaneDrop; update both the canDrop function and the drop callback to read the
dragged item's metadata (e.g., paneId/tabId/workspaceId) and compare it against
this group's identifiers (use the component props/IDs that identify the current
tab/workspace) and only allow drop/trigger onPaneDrop when the checks pass.
In `@apps/desktop/src/renderer/stores/tabs/dragging-pane.ts`:
- Around line 3-13: Change setDraggingPane to accept a single params object
instead of positional arguments: update the DraggingPaneState type so
setDraggingPane: (args: { paneId: string | null; tabId: string | null }) =>
void, and update the useDraggingPaneStore initializer to implement
setDraggingPane: ({ paneId, tabId }) => set({ draggingPaneId: paneId,
draggingTabId: tabId }). Rename parameters in the implementation as shown and
then find and update all call sites that invoke
useDraggingPaneStore().setDraggingPane(paneId, tabId) to the new form
setDraggingPane({ paneId, tabId }); keep the property names paneId and tabId
exactly to match the type.
🧹 Nitpick comments (1)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/GroupStrip/GroupStrip.tsx (1)
124-134: Use a params object forhandlePaneDropToTab.This new helper has 2 parameters; adopt a single params object to match project conventions and improve readability. As per coding guidelines, ...
♻️ Proposed refactor
- const handlePaneDropToTab = (paneId: string, targetTabId: string) => { + const handlePaneDropToTab = ({ + paneId, + targetTabId, + }: { + paneId: string; + targetTabId: string; + }) => { const pane = panes[paneId]; if (!pane || pane.tabId === targetTabId) return; @@ movePaneToTab(paneId, targetTabId); };- onPaneDrop={(paneId) => handlePaneDropToTab(paneId, tab.id)} + onPaneDrop={(paneId) => + handlePaneDropToTab({ paneId, targetTabId: tab.id }) + }Also applies to: 189-196
| interface DraggingPaneState { | ||
| draggingPaneId: string | null; | ||
| draggingTabId: string | null; | ||
| setDraggingPane: (paneId: string | null, tabId: string | null) => void; | ||
| } | ||
|
|
||
| export const useDraggingPaneStore = create<DraggingPaneState>((set) => ({ | ||
| draggingPaneId: null, | ||
| draggingTabId: null, | ||
| setDraggingPane: (paneId, tabId) => | ||
| set({ draggingPaneId: paneId, draggingTabId: tabId }), |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Use a params object for setDraggingPane to avoid positional arguments.
This API now has 2+ parameters and should follow the project convention for self-documentation and future extensibility. Update call sites accordingly. As per coding guidelines, ...
♻️ Proposed refactor
interface DraggingPaneState {
draggingPaneId: string | null;
draggingTabId: string | null;
- setDraggingPane: (paneId: string | null, tabId: string | null) => void;
+ setDraggingPane: (params: {
+ paneId: string | null;
+ tabId: string | null;
+ }) => void;
}
export const useDraggingPaneStore = create<DraggingPaneState>((set) => ({
draggingPaneId: null,
draggingTabId: null,
- setDraggingPane: (paneId, tabId) =>
- set({ draggingPaneId: paneId, draggingTabId: tabId }),
+ setDraggingPane: ({ paneId, tabId }) =>
+ set({ draggingPaneId: paneId, draggingTabId: tabId }),
}));- setDraggingPane(paneId, tabId);
+ setDraggingPane({ paneId, tabId });- setDraggingPane(null, null);
+ setDraggingPane({ paneId: null, tabId: null });🤖 Prompt for AI Agents
In `@apps/desktop/src/renderer/stores/tabs/dragging-pane.ts` around lines 3 - 13,
Change setDraggingPane to accept a single params object instead of positional
arguments: update the DraggingPaneState type so setDraggingPane: (args: {
paneId: string | null; tabId: string | null }) => void, and update the
useDraggingPaneStore initializer to implement setDraggingPane: ({ paneId, tabId
}) => set({ draggingPaneId: paneId, draggingTabId: tabId }). Rename parameters
in the implementation as shown and then find and update all call sites that
invoke useDraggingPaneStore().setDraggingPane(paneId, tabId) to the new form
setDraggingPane({ paneId, tabId }); keep the property names paneId and tabId
exactly to match the type.
|
Closing because this is buggy |
🧹 Preview Cleanup CompleteThe following preview resources have been cleaned up:
Thank you for your contribution! 🎉 |
Fetch greptile-apps[bot] inline review comments and extract the structured "Prompt To Fix With AI" sections (wrapped in 5-backtick markdown blocks). These contain file path, line number, issue description, and fix suggestion ready to feed to the auto-fix bot. Falls back to full comment bodies and Greptile PR body section for score/issues. Tested against Alike-AI/arch-one PR superset-sh#856 — extracts all 4 prompts correctly. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Greptile embeds the "Prompt To Fix All With AI" section in the PR description (body), not in the review body (which the API returns as empty). Extract it from pr.body using the <details><summary> + 5-backtick markdown pattern. Falls back to individual inline comment prompts if not found in PR body. Verified against Alike-AI/arch-one PR superset-sh#856 — extracts 2700 chars of fix prompts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
Test plan
Summary by CodeRabbit
New Features
✏️ Tip: You can customize this high-level summary in your review settings.