feat(left-bar): add drop zone for ungrouping when all sessions are in groups

- Shows "Drop here to ungroup" zone when dragging a session and no ungrouped sessions exist
- Allows users to drag sessions out of groups even when Ungrouped Agents folder is hidden
- Added tests for drop zone visibility and drop handler
This commit is contained in:
Pedram Amini
2026-02-01 22:46:01 -06:00
parent 434f89268e
commit 9dbb2419b6
2 changed files with 58 additions and 2 deletions

View File

@@ -1195,6 +1195,45 @@ describe('SessionList', () => {
expect(handleDropOnGroup).toHaveBeenCalledWith('g1');
});
it('shows drop zone for ungrouping when dragging and all sessions are grouped', () => {
const handleDropOnUngrouped = vi.fn();
const group = createMockGroup({ id: 'g1', name: 'My Group', sessionIds: ['s1'] });
const sessions = [createMockSession({ id: 's1', name: 'Grouped Session', groupId: 'g1' })];
const props = createDefaultProps({
sessions,
sortedSessions: sessions,
groups: [group],
leftSidebarOpen: true,
draggingSessionId: 's1', // Simulating active drag
handleDropOnUngrouped,
});
render(<SessionList {...props} />);
// Drop zone should be visible when dragging
expect(screen.getByText('Drop here to ungroup')).toBeInTheDocument();
});
it('calls handleDropOnUngrouped when dropping on ungroup zone', () => {
const handleDropOnUngrouped = vi.fn();
const group = createMockGroup({ id: 'g1', name: 'My Group', sessionIds: ['s1'] });
const sessions = [createMockSession({ id: 's1', name: 'Grouped Session', groupId: 'g1' })];
const props = createDefaultProps({
sessions,
sortedSessions: sessions,
groups: [group],
leftSidebarOpen: true,
draggingSessionId: 's1',
handleDropOnUngrouped,
});
render(<SessionList {...props} />);
// Find the drop zone and drop on it
const dropZone = screen.getByText('Drop here to ungroup');
fireEvent.drop(dropZone);
expect(handleDropOnUngrouped).toHaveBeenCalled();
});
});
// ============================================================================

View File

@@ -2726,8 +2726,25 @@ function SessionListInner(props: SessionListProps) {
)}
</div>
) : groups.length > 0 ? (
/* NO UNGROUPED AGENTS - Show standalone New Group button */
<div className="mt-4 px-3">
/* NO UNGROUPED AGENTS - Show drop zone for ungrouping + New Group button */
<div
className="mt-4 px-3"
onDragOver={handleDragOver}
onDrop={handleDropOnUngrouped}
>
{/* Drop zone indicator when dragging */}
{draggingSessionId && (
<div
className="mb-2 px-3 py-2 rounded border-2 border-dashed text-center text-xs"
style={{
borderColor: theme.colors.accent,
color: theme.colors.textDim,
backgroundColor: theme.colors.accent + '10',
}}
>
Drop here to ungroup
</div>
)}
<button
onClick={createNewGroup}
className="w-full px-2 py-1.5 rounded-full text-[10px] font-medium hover:opacity-80 transition-opacity flex items-center justify-center gap-1"