import type { ReactNode } from "react"; import { ChevronDown, ChevronRight } from "lucide-react"; import { cn, relativeTime } from "../lib/utils"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { AgentIcon } from "./AgentIconPicker"; import { deriveInitials } from "./Identity"; export type DocumentFrameHeaderRevisionActor = { kind: "agent" | "user" | "system"; name: string; agentIcon?: string | null; imageUrl?: string | null; }; export type DocumentFrameHeaderRevision = { id: string; revisionNumber: number; createdAt: string | Date; actor: DocumentFrameHeaderRevisionActor; }; export type DocumentFrameHeaderRevisionMenu = { open: boolean; onOpenChange: (open: boolean) => void; loading: boolean; revisions: DocumentFrameHeaderRevision[]; selectedRevisionId: string | null; currentRevisionId: string | null; displayedRevisionNumber: number; historicalPreview: boolean; onSelectRevision: (revisionId: string, isCurrentRevision: boolean) => void; }; export interface DocumentFrameHeaderProps { documentKey: string; documentLabel?: string; folded: boolean; onToggleFolded: () => void; revisionMenu?: DocumentFrameHeaderRevisionMenu; updatedAt?: string | Date | null; updatedHref?: string; sourceTrustSlot?: ReactNode; annotationSlot?: ReactNode; titleSlot?: ReactNode; actionsSlot?: ReactNode; } function RevisionActorAvatar({ actor }: { actor: DocumentFrameHeaderRevisionActor }) { return ( {actor.kind === "agent" ? ( ) : ( <> {actor.imageUrl ? : null} {deriveInitials(actor.name)} )} ); } export function DocumentFrameHeader({ documentKey, documentLabel, folded, onToggleFolded, revisionMenu, updatedAt, updatedHref, sourceTrustSlot, annotationSlot, titleSlot, actionsSlot, }: DocumentFrameHeaderProps) { return (
{documentLabel ? ( <> {documentLabel} {documentKey} ) : ( {documentKey} )} {sourceTrustSlot} {revisionMenu ? ( Revision history {revisionMenu.loading && revisionMenu.revisions.length === 0 ? ( Loading revisions... ) : revisionMenu.revisions.length > 0 ? ( {revisionMenu.revisions.map((revision) => { const isCurrentRevision = revision.id === revisionMenu.currentRevisionId; return ( revisionMenu.onSelectRevision(revision.id, isCurrentRevision)} className="items-start" >
rev {revision.revisionNumber} {isCurrentRevision ? ( Current ) : null}
{relativeTime(revision.createdAt)} • {revision.actor.name}
); })}
) : ( No revisions yet )}
) : null} {updatedAt ? ( updated {relativeTime(updatedAt)} ) : null} {annotationSlot}
{titleSlot}
{actionsSlot ?
{actionsSlot}
: null}
); }