feat(frontend): SessionMenu kebab + NavSessions prop-driven; AppShell owns sessions query

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-29 12:50:24 +02:00
co-authored by Claude Sonnet 4.6
parent 8243ce6446
commit d5f82b70a4
4 changed files with 116 additions and 118 deletions
+9 -2
View File
@@ -7,7 +7,9 @@ import { SteerInput, ComposerFooter } from "./SteerInput";
import { WorkflowBar } from "./WorkflowBar";
import { Button } from "../components/ui/button";
import { Toaster } from "../components/ui/sonner";
import { closeSession } from "../api/sessions";
import { closeSession, listSessions, resumeSession } from "../api/sessions";
import type { SessionSummary } from "../api/types";
import { useQuery } from "@tanstack/react-query";
import { useRef, useState } from "react";
/**
@@ -18,6 +20,9 @@ import { useRef, useState } from "react";
*/
export function AppShell() {
const [activeSessionId, setActiveSessionId] = useState<string | null>(null);
const { data: sessions = [] } = useQuery<SessionSummary[]>({
queryKey: ["sessions"], queryFn: listSessions, refetchInterval: 10_000,
});
const composerRef = useRef<HTMLInputElement>(null);
// The harness "holds the ball" whenever a session is live and no widget is
@@ -121,8 +126,10 @@ export function AppShell() {
</div>
<div className="flex-1 overflow-y-auto px-2 pb-4">
<NavSessions
sessions={sessions}
activeSessionId={activeSessionId}
onSessionSelect={setActiveSessionId}
onOpenPanel={async (id) => { await resumeSession(id); setActiveSessionId(id); }}
menuFor={() => null}
/>
</div>
</aside>