Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,26 @@ const SessionsSection: React.FC<SessionsSectionProps> = ({
void loadMetadataPage(SESSIONS_LEVEL_0, undefined, 'sessions_nav_initial');
}, [isVisible, workspacePath, remoteConnectionId, remoteSshHost, loadMetadataPage]);

// When sessions are archived, reset stale metadata so the expand toggle
// doesn't linger with old counts after all sessions are gone.
useEffect(() => {
const handler = () => {
metadataLoadRequestIdRef.current += 1;
setExpandLevel(0);
setMetadataPageState({
totalTopLevelCount: null,
nextCursor: undefined,
hasMore: false,
isLoading: false,
});
if (isVisible && workspacePath) {
void loadMetadataPage(SESSIONS_LEVEL_0, undefined, 'sessions_nav_post_archive');
}
};
window.addEventListener('bitfun:session-archived', handler);
return () => window.removeEventListener('bitfun:session-archived', handler);
}, [isVisible, workspacePath, loadMetadataPage]);

useEffect(() => {
if (!openMenuSessionId) return;
const handleOutside = (event: MouseEvent) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,21 @@
color: var(--color-text-muted);
text-transform: uppercase;
letter-spacing: 0.04em;
width: 100%;
border: none;
background: transparent;
cursor: pointer;
transition: background var(--motion-fast) var(--easing-standard);

&:hover {
background: var(--element-bg-hover);
}
}

&__group-chevron {
flex-shrink: 0;
color: var(--color-text-muted);
opacity: 0.6;
}

&__group-name {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
* confirmation dialog.
*/

import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { Trash2, RotateCcw, Inbox, RefreshCw } from 'lucide-react';
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { Trash2, RotateCcw, Inbox, RefreshCw, ChevronRight, ChevronDown } from 'lucide-react';
import { useTranslation } from 'react-i18next';
import {
ConfigPageLayout,
Expand Down Expand Up @@ -114,6 +114,8 @@ const ArchivedSessionsConfig: React.FC = () => {

const [loading, setLoading] = useState(true);
const [entries, setEntries] = useState<ArchivedEntry[]>([]);
const [collapsedWorkspaces, setCollapsedWorkspaces] = useState<Set<string>>(new Set());
const prevLoadingRef = useRef(loading);

// ── Load archived sessions from all open workspaces ──────────────────────

Expand Down Expand Up @@ -180,6 +182,14 @@ const ArchivedSessionsConfig: React.FC = () => {
return map;
}, [entries]);

// Collapse all workspace groups by default when data finishes loading
useEffect(() => {
if (prevLoadingRef.current && !loading && grouped.size > 0) {
setCollapsedWorkspaces(new Set(grouped.keys()));
}
prevLoadingRef.current = loading;
}, [loading, grouped]);

// ── Remove an entry from local state after mutation ──────────────────────

const removeEntry = useCallback((sessionId: string) => {
Expand All @@ -190,6 +200,18 @@ const ArchivedSessionsConfig: React.FC = () => {
setEntries([]);
}, []);

const toggleWorkspace = useCallback((workspacePath: string) => {
setCollapsedWorkspaces(prev => {
const next = new Set(prev);
if (next.has(workspacePath)) {
next.delete(workspacePath);
} else {
next.add(workspacePath);
}
return next;
});
}, []);

// ── Restore single session ───────────────────────────────────────────────

const handleRestore = useCallback(async (entry: ArchivedEntry) => {
Expand Down Expand Up @@ -333,14 +355,26 @@ const ArchivedSessionsConfig: React.FC = () => {
title={t('nav.sessions.archivedSessions')}
extra={headerExtra}
>
{Array.from(grouped.entries()).map(([workspacePath, group]) => (
{Array.from(grouped.entries()).map(([workspacePath, group]) => {
const isCollapsed = collapsedWorkspaces.has(workspacePath);
return (
<div key={workspacePath} className="archived-sessions-config__group">
<div className="archived-sessions-config__group-header">
<span className="archived-sessions-config__group-name">{group.name}</span>
<button
type="button"
className="archived-sessions-config__group-header"
onClick={() => toggleWorkspace(workspacePath)}
>
{isCollapsed ? (
<ChevronRight size={14} className="archived-sessions-config__group-chevron" />
) : (
<ChevronDown size={14} className="archived-sessions-config__group-chevron" />
)}
<span className="archived-sessions-config__group-name">{workspacePath}</span>
<span className="archived-sessions-config__group-count">
{group.entries.length}
</span>
</div>
</button>
{!isCollapsed && (
<div className="archived-sessions-config__group-list">
{group.entries.map(entry => (
<ArchivedRow
Expand All @@ -352,8 +386,10 @@ const ArchivedSessionsConfig: React.FC = () => {
/>
))}
</div>
)}
</div>
))}
);
})}
</ConfigPageSection>
)}
</ConfigPageContent>
Expand Down
Loading