/** * The row and dialog pieces of `VersionHistoryPanel`: one version's table row and * action cluster (`VersionRow`), the selected version's body (`SelectedVersionBody`), * the two-version compare dialog (`CompareDialog`), and the rollback confirm * dialog (`RollbackConfirmDialog`). All generic and kind-agnostic. */ import type { ReactNode } from 'react'; import { Dialog } from './dialog'; import { CheckCircleIcon, PendingIcon } from './icons'; import { JsonDiff } from './json-diff'; import { JsonTree } from './json-tree'; import { Button, Card, ErrorState, Spinner } from './primitives'; import { ScrollRegion } from './scroll-region'; import { TD, TR } from './table'; import { TagChips } from './tags'; import type { VersionHistoryEntry } from './version-history-panel'; interface VersionRowProps { readonly entry: VersionHistoryEntry; readonly showTags: boolean; readonly canCompare: boolean; /** This row is the armed Compare source. */ readonly compareArmed: boolean; readonly readOnly: boolean; /** An edit-tags affordance is available (the consumer supplied `onEditTags`). */ readonly canEditTags: boolean; readonly onView: (version: number) => void; readonly onCompare: (version: number) => void; readonly onEditTags: (version: number) => void; readonly onRollback: (version: number) => void; } /** One version's row: its number, timestamp, status mark, optional tags, and the * View / Compare / Edit tags / Roll back action cluster. */ export function VersionRow({ entry, showTags, canCompare, compareArmed, readOnly, canEditTags, onView, onCompare, onEditTags, onRollback, }: VersionRowProps): ReactNode { return ( {entry.version} {entry.created_at} {entry.is_current ? ( Current ) : ( Historical )} {showTags ? ( {(entry.tags ?? []).length > 0 ? ( ) : ( — )} ) : null}
{canCompare ? ( ) : null} {canEditTags && !readOnly ? ( ) : null} {readOnly ? null : ( )}
); } /** The selected version's opaque body, rendered through `JsonTree`. */ export function SelectedVersionBody({ entry }: { readonly entry: VersionHistoryEntry }): ReactNode { return (

Version {entry.version} body

); } /** A structural diff of two version bodies, in a dialog. */ export function CompareDialog({ from, to, fromBody, toBody, onClose, }: { readonly from: number; readonly to: number; readonly fromBody: unknown; readonly toBody: unknown; readonly onClose: () => void; }): ReactNode { return ( { if (!next) onClose(); }} > {/* A deep diff row can run wider than the dialog; it scrolls in place. */}
); } /** The rollback confirmation, surfacing any rollback failure verbatim. */ export function RollbackConfirmDialog({ version, rollbackPending, rollbackError, extraDescription, onCancel, onConfirm, }: { readonly version: number; readonly rollbackPending: boolean | undefined; readonly rollbackError: string | undefined; readonly extraDescription: string | undefined; readonly onCancel: () => void; readonly onConfirm: (version: number) => void; }): ReactNode { return ( { if (!next) onCancel(); }} > {rollbackError !== undefined ? : null}
); }