import { Button } from "@/components/ui/button"; import { Sheet, SheetContent, SheetTitle } from "@/components/ui/sheet"; import { useGetLogByIdQuery } from "@/lib/store/apis/logsApi"; import { useGetPromptQuery } from "@/lib/store/apis/promptsApi"; import type { LogEntry } from "@/lib/types/logs"; import { ChevronDown, ChevronUp, Loader2 } from "lucide-react"; import { useEffect, useState } from "react"; import { useHotkeys } from "react-hotkeys-hook"; import { LogDetailView } from "./logDetailView"; interface LogDetailSheetProps { log: LogEntry | null; open: boolean; onOpenChange: (open: boolean) => void; handleDelete: (log: LogEntry) => void; onNavigate?: (direction: "prev" | "next") => void; hasPrev?: boolean; hasNext?: boolean; onViewSession?: (sessionId: string, logId: string) => void; onFilterByParentRequestId?: (parentRequestId: string) => void; } export function LogDetailSheet({ log, open, onOpenChange, handleDelete, onNavigate, hasPrev = false, hasNext = false, onViewSession, onFilterByParentRequestId, }: LogDetailSheetProps) { const [pollingInterval, setPollingInterval] = useState(0); const { data: fullLog, isLoading, isError, } = useGetLogByIdQuery(log?.id ?? "", { skip: !open || !log?.id, pollingInterval, }); const shouldPoll = isError || fullLog?.status === "processing"; const isFullDataReady = log != null && (isError || (fullLog?.id === log.id && !isLoading)); // Prefer full log when loaded; otherwise list row — enables prompt fetch in parallel with getLogById const selectedPromptId = log ? (fullLog?.id === log.id ? fullLog : log).selected_prompt_id : undefined; const { data: selectedPromptData } = useGetPromptQuery(selectedPromptId ?? "", { skip: !open || !selectedPromptId, }); useEffect(() => { setPollingInterval(shouldPoll ? 2000 : 0); }, [shouldPoll]); // Keyboard navigation: arrow up/down to navigate between logs useHotkeys("up", () => onNavigate?.("prev"), { enabled: open && hasPrev, preventDefault: true, }); useHotkeys("down", () => onNavigate?.("next"), { enabled: open && hasNext, preventDefault: true, }); if (!log) return null; // Show a loader only on the initial fetch, not during background polling refetches. const displayLog: LogEntry = isFullDataReady && fullLog ? fullLog : log; const resolvedSelectedPromptName = selectedPromptData?.prompt?.name ?? displayLog.selected_prompt_name ?? ""; return ( {!isFullDataReady ? (
Loading log details
) : ( onOpenChange(false)} onFilterByParentRequestId={onFilterByParentRequestId} headerAction={ <> {displayLog.parent_request_id && onViewSession ? ( ) : null}
} /> )}
); }