import { useQuery } from "@tanstack/react-query"; import { X } from "lucide-react"; import { getSessionDocuments } from "../api/sessions"; import type { SessionDocument, SessionSummary } from "../api/types"; import { Button } from "../components/ui/button"; import { ErrorBoundary } from "../components/ErrorBoundary"; import { SqlViewer } from "../viewers/SqlViewer"; import { SchemaLinkingViewer } from "../viewers/SchemaLinkingViewer"; import { MarkdownView } from "../viewers/MarkdownView"; interface Props { session: SessionSummary; onClose: () => void; onResume: (id: string) => void; } function statusLabel(s: SessionSummary): string { if (s.archived) return "Archived"; if (s.status === "finalized") return "Completed"; return `In progress · ${s.status}`; } function DocBody({ doc }: { doc: SessionDocument }) { if (doc.format === "sql") return ; if (doc.format === "markdown") return ; if (doc.format === "schema-linking") { try { const linking = JSON.parse(doc.content); return ; } catch { return
{doc.content}
; } } if (doc.format === "decisions") { const items = doc.content .split("\n") .filter(Boolean) .map((line) => { try { return JSON.parse(line) as { type?: string; subject?: string; detail?: string }; } catch { return null; } }) .filter((d): d is { type?: string; subject?: string; detail?: string } => d !== null); if (items.length === 0) return

No decisions recorded.

; return (
    {items.map((d, i) => (
  • {(d.type ?? "decision").replace(/_/g, " ")} {d.subject &&

    {d.subject}

    } {d.detail &&

    {d.detail}

    }
  • ))}
); } return

{doc.content}

; } /** Semantic tint for a decision-type chip: approvals/promotions read as progress * (green), exclusions as neutral, everything else carries the brand accent. */ function decisionChipClass(type: string): string { const t = type.toLowerCase(); if (t.includes("approved") || t.includes("promoted")) return "bg-[oklch(var(--success)/0.15)] text-[oklch(0.47_0.12_165)]"; if (t.includes("excluded") || t.includes("rejected") || t.includes("reopened")) return "bg-muted text-muted-foreground"; return "bg-[oklch(var(--primary)/0.1)] text-primary"; } export function SessionDocumentsPanel({ session, onClose, onResume }: Props) { const { data: docs = [], isLoading } = useQuery({ queryKey: ["session-documents", session.id], queryFn: () => getSessionDocuments(session.id), }); const resumable = session.status !== "finalized" && !session.archived; return ( ); }