diff --git a/desktop/src/components/layout/Sidebar.test.tsx b/desktop/src/components/layout/Sidebar.test.tsx index 64e3f548..bb4cb2f0 100644 --- a/desktop/src/components/layout/Sidebar.test.tsx +++ b/desktop/src/components/layout/Sidebar.test.tsx @@ -293,6 +293,35 @@ describe('Sidebar', () => { expect(screen.getByRole('button', { name: 'Collapse display' })).toBeInTheDocument() }) + it('lets a manual session refresh supersede a stuck automatic refresh', async () => { + fetchSessions.mockReturnValue(new Promise(() => {})) + + render() + + await waitFor(() => expect(fetchSessions).toHaveBeenCalledTimes(1)) + fireEvent.click(screen.getByRole('button', { name: 'Refresh sessions' })) + + await waitFor(() => expect(fetchSessions).toHaveBeenCalledTimes(2)) + }) + + it('keeps the session refresh control usable when a background refresh is still loading existing sessions', async () => { + useSessionStore.setState({ + sessions: [ + makeSession('session-loaded', 'Loaded session', '/workspace/alpha', '2026-05-15T10:00:00.000Z'), + ], + isLoading: true, + }) + + render() + + const refreshButton = screen.getByRole('button', { name: 'Refresh sessions' }) + expect(refreshButton).not.toBeDisabled() + expect(refreshButton.querySelector('svg')).not.toHaveClass('animate-spin') + + fireEvent.click(refreshButton) + await waitFor(() => expect(fetchSessions).toHaveBeenCalled()) + }) + it('reorders project groups by dragging project headers while preserving expanded state', async () => { const base = new Date('2026-05-15T10:00:00.000Z').getTime() useSessionStore.setState({ diff --git a/desktop/src/components/layout/Sidebar.tsx b/desktop/src/components/layout/Sidebar.tsx index 3dc7ca0a..31e0f92d 100644 --- a/desktop/src/components/layout/Sidebar.tsx +++ b/desktop/src/components/layout/Sidebar.tsx @@ -127,6 +127,7 @@ export function Sidebar({ isMobile = false, onRequestClose }: SidebarProps) { )) }, [hiddenProjectKeys, orderedProjectGroups]) const showInitialLoading = isLoading && sessions.length === 0 + const showRefreshLoading = showInitialLoading const filteredSessionIds = useMemo(() => filteredSessions.map((session) => session.id), [filteredSessions]) const selectedCount = selectedSessionIds.size const sessionsById = useMemo( @@ -709,12 +710,11 @@ export function Sidebar({ isMobile = false, onRequestClose }: SidebarProps) {