import { useEffect, useId, useState } from "react"; import { ChevronIcon, SparkleIcon } from "@chopin/icons"; import { researchProvenance } from "./research-requests"; import type { Research } from "@chopin/protocol"; import type { ChildParent } from "./workspace-model"; function plural(count: number, noun: string): string { return `${count} ${noun}${count === 1 ? "" : "s"}`; } /** A quiet line above a research child that names its parent, brief, and sources. */ export function ChildProvenance({ channelId, parent }: { channelId: string; parent: ChildParent }) { let [provenance, setProvenance] = useState(); let [briefOpen, setBriefOpen] = useState(false); let briefId = useId(); useEffect(() => { let controller = new AbortController(); setProvenance(undefined); setBriefOpen(false); researchProvenance(channelId, controller.signal) .then(value => { if (!controller.signal.aborted) setProvenance(value); }) // Provenance is context, not content; the document stays usable without it. .catch(() => {}); return () => controller.abort(); }, [channelId]); if (!provenance || provenance.parentChannelId !== parent.id) return null; let requestId = provenance.requestId; let returnToCard = () => { // The parent card may still be loading while the child closes. parent.onReturn({ get current() { return document.querySelector( `[data-workspace-room="${CSS.escape(parent.id)}"] [data-research-request="${ CSS.escape(requestId) }"]`, ); }, }); }; return (

Research from{" "} {provenance.startedBy && ( <> {" "} · by {provenance.startedBy} )}{" "} · {provenance.sourceCount === 0 ? "No sources" : plural(provenance.sourceCount, "source")}

); }