import { useEffect } from "react"; import { useSessionOperations, type Operation, } from "../../../state/session-operations"; import { useEventContext } from "../../../state/events"; import { Icon } from "../../icon"; interface StepConfig { label: string; index: number; } const steps: StepConfig[] = [ { label: "Created", index: 1 }, { label: "Building", index: 2 }, { label: "Starting", index: 3 }, { label: "Ready", index: 4 }, ]; function OperationItem({ operation, onDismiss, }: { operation: Operation; onDismiss: () => void; }) { const isDone = operation.status === "success" || operation.status === "error"; const isError = operation.status === "error"; return (
{isError ? ( ) : isDone ? ( ) : ( )} {operation.displayName}
{isDone && ( )}

{operation.message}

{steps.map((step) => { const active = operation.step >= step.index; const current = operation.step === step.index && !isDone; return ( {step.label} ); })}
); } export function SessionProgressPanel() { const { operations, updateOperationFromEvent, dismissOperation } = useSessionOperations(); const { events } = useEventContext(); useEffect(() => { if (events.length === 0) return; const latestEvent = events[events.length - 1]; updateOperationFromEvent(latestEvent); }, [events, updateOperationFromEvent]); const visibleOperations = operations.filter( (op) => op.status === "pending" || op.status === "active" || (op.status === "success" && Date.now() - op.createdAt < 5000) || op.status === "error", ); if (visibleOperations.length === 0) return null; return (
Operations
{visibleOperations.map((operation) => ( dismissOperation(operation.id)} /> ))}
); }