feat(frontend): sessions list/create + steering + resume + selectors
- NavSessions: left nav listing sessions via listSessions (TanStack Query), clicking resumes via resumeSession and sets active; active item highlighted - NewSessionDialog: ShadCn dialog with question textarea, workspace native select (from listWorkspaces), graceful model field (dropdown when models list is non-empty, free-text input when empty per §9 degradation), optional thinking/provider fields; try/catch surfaces errors inline - SteerInput: text input + button POSTs to postSteer, clears on send, supports Enter key; only shown when a session is active - WorkflowBar: renders 8 phases (F1..F8) with data-active highlighting driven by useSessionStore.currentPhase (new store field + setPhase action) - AppShell: wires all four components; right artifact sidebar now collapsible via a toggle button (useState sidebarOpen); replaces old "Nuova domanda" button with NewSessionDialog trigger - f1-loop.test: updated to drive through the new dialog flow (open → fill question → submit → wait for SSE → respond) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,46 +1,62 @@
|
||||
import { useState } from "react";
|
||||
import { createSession } from "../api/sessions";
|
||||
import { useSessionStream } from "../stream/useSessionStream";
|
||||
import { WidgetHost } from "./WidgetHost";
|
||||
import { NavSessions } from "./NavSessions";
|
||||
import { NewSessionDialog } from "./NewSessionDialog";
|
||||
import { SteerInput } from "./SteerInput";
|
||||
import { WorkflowBar } from "./WorkflowBar";
|
||||
|
||||
export function AppShell() {
|
||||
const [activeSessionId, setActiveSessionId] = useState<string | null>(null);
|
||||
const [sidebarOpen, setSidebarOpen] = useState(true);
|
||||
|
||||
useSessionStream(activeSessionId);
|
||||
|
||||
async function handleNuovaDomanda() {
|
||||
const { id } = await createSession({ workspace: "default", question: "" });
|
||||
function handleSessionSelect(id: string) {
|
||||
setActiveSessionId(id);
|
||||
}
|
||||
|
||||
function handleCreated(id: string) {
|
||||
setActiveSessionId(id);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex h-screen">
|
||||
{/* Left nav / session list */}
|
||||
{/* Left nav: new session button + sessions list */}
|
||||
<aside className="w-48 border-r p-2 flex flex-col gap-2">
|
||||
<button
|
||||
className="border rounded px-2 py-1 text-sm hover:bg-accent"
|
||||
onClick={handleNuovaDomanda}
|
||||
>
|
||||
Nuova domanda
|
||||
</button>
|
||||
<NewSessionDialog onCreated={handleCreated} />
|
||||
<NavSessions
|
||||
activeSessionId={activeSessionId}
|
||||
onSessionSelect={handleSessionSelect}
|
||||
/>
|
||||
</aside>
|
||||
|
||||
<div className="flex flex-col flex-1">
|
||||
<div className="flex flex-col flex-1 min-w-0">
|
||||
{/* Top workflow bar */}
|
||||
<header className="border-b px-4 py-2 text-sm text-muted-foreground">
|
||||
Workflow
|
||||
<header className="border-b px-4 py-2 flex items-center gap-4">
|
||||
<WorkflowBar />
|
||||
<button
|
||||
className="ml-auto text-xs text-muted-foreground hover:text-foreground border rounded px-2 py-0.5"
|
||||
onClick={() => setSidebarOpen((v) => !v)}
|
||||
aria-label={sidebarOpen ? "Chiudi sidebar" : "Apri sidebar"}
|
||||
>
|
||||
{sidebarOpen ? "←" : "→"}
|
||||
</button>
|
||||
</header>
|
||||
|
||||
{/* Center: chat + input */}
|
||||
<main className="flex-1 overflow-auto p-4">
|
||||
{/* Center: chat + steer input */}
|
||||
<main className="flex-1 overflow-auto p-4 flex flex-col gap-2">
|
||||
<WidgetHost sessionId={activeSessionId} />
|
||||
{activeSessionId && <SteerInput sessionId={activeSessionId} />}
|
||||
</main>
|
||||
</div>
|
||||
|
||||
{/* Right artifact sidebar */}
|
||||
<aside className="w-64 border-l p-2">
|
||||
<p className="text-xs text-muted-foreground">Artefatti</p>
|
||||
</aside>
|
||||
{/* Right artifact sidebar — collapsible */}
|
||||
{sidebarOpen && (
|
||||
<aside className="w-64 border-l p-2 flex flex-col">
|
||||
<p className="text-xs text-muted-foreground">Artefatti</p>
|
||||
</aside>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user