import type { ReactNode } from "react"; import { useTranslation } from "react-i18next"; import { nextPageOnClick } from "../../lib/nextPage"; import type { HistoryList as HistoryListState } from "../../lib/useHistoryList"; import NavGrid from "../../components/ui/NavGrid"; import { Button } from "../../components/ui/Button"; import { LoadingState, StateMessage } from "../../components/ui/QueryState"; // The frame of a history list on the activity page — the runs, the admin actions, the server log: // its own bar (if any), the rows or the honest state instead of them (a failed read is an error with a // retry, never an empty list), a read that failed over rows still on screen, the count, and "Older". // `HistoryFrame` draws it; each list says only what its failure and its "Older" are — the server log's // count its filter facets and stop while Live (AdminLogs), the others not (HistoryList, below). /** What a read that failed while rows stayed on screen means, and how to try it again. */ export interface FrameFailure { text: string; onRetry: () => void; } export function HistoryFrame({ list, rowCount, header, failure, older, count, empty, rowsClassName = "", testId, children, }: { /** The list's read. */ list: { data?: unknown; isError: boolean; isLoading: boolean; isPlaceholderData: boolean; refetch: () => unknown; }; rowCount: number; /** The list's own bar above the rows. */ header?: ReactNode; failure: FrameFailure | null; /** "Older", when there is an older page to ask for. */ older: { label: string; onClick: () => void; disabled: boolean } | null; /** "N runs shown", for the footer. */ count: string; /** Shown when the filters match nothing. */ empty: string; rowsClassName?: string; testId?: string; /** The rows. */ children: ReactNode; }) { const { t } = useTranslation(); return (