import { type RouterOutputs } from "@/src/utils/api"; import { type NextRouter, useRouter } from "next/router"; import { useState, useRef, useEffect } from "react"; import { PromptVersionDiffDialog } from "./PromptVersionDiffDialog"; import { Timeline, TimelineItem } from "@/src/components/ui/timeline"; import { Badge } from "@/src/components/ui/badge"; import { CommandItem } from "@/src/components/ui/command"; import { SetPromptVersionLabels } from "@/src/features/prompts/components/SetPromptVersionLabels"; import { CommentCountIcon } from "@/src/features/comments/CommentCountIcon"; const PromptHistoryTraceNode = (props: { index: number; prompt: RouterOutputs["prompts"]["allVersions"]["promptVersions"][number]; currentPrompt?: RouterOutputs["prompts"]["allVersions"]["promptVersions"][number]; currentPromptVersion: number | undefined; setCurrentPromptVersion: (version: number | undefined) => void; router: NextRouter; projectId: string; totalCount: number; commentCounts?: Map; }) => { const [isHovered, setIsHovered] = useState(false); const [isPromptDiffOpen, setIsPromptDiffOpen] = useState(false); const [isLabelPopoverOpen, setIsLabelPopoverOpen] = useState(false); const { prompt } = props; // Add ref for scroll into view const currentPromptRef = useRef(null); // Add useEffect for scroll into view behavior useEffect(() => { if ( props.currentPromptVersion && currentPromptRef.current && props.currentPromptVersion === prompt.version ) { currentPromptRef.current.scrollIntoView({ behavior: "smooth", block: "center", }); } // Should only trigger a single time on initial render // eslint-disable-next-line react-hooks/exhaustive-deps }, [currentPromptRef.current]); return ( setIsHovered(true)} onMouseLeave={() => setIsHovered(false)} onClick={(e) => { const target = e.target as HTMLElement; if ( target.closest('[role="button"]') || target.closest('[data-version-trigger="true"]') ) { return; } props.index === 0 ? props.setCurrentPromptVersion(undefined) : props.setCurrentPromptVersion(prompt.version); }} >
{ e.stopPropagation(); props.index === 0 ? props.setCurrentPromptVersion(undefined) : props.setCurrentPromptVersion(prompt.version); }} variant="outline" className="h-6 shrink-0 bg-background/50" data-version-trigger="false" > # {prompt.version} } promptLabels={prompt.labels} prompt={prompt} isOpen={isLabelPopoverOpen} setIsOpen={setIsLabelPopoverOpen} showOnlyOnHover /> {props.commentCounts?.get(prompt.id) ? ( { e.stopPropagation(); void props.router.push( { pathname: props.router.pathname, query: { ...props.router.query, version: prompt.version, comments: "open", commentObjectType: "PROMPT", commentObjectId: prompt.id, }, }, undefined, { shallow: true }, ); }} className="cursor-pointer" role="button" > ) : null}
{prompt.commitMessage && (
{prompt.commitMessage}
)}
{prompt.createdAt.toLocaleString()} by{" "} {prompt.creator || prompt.createdBy}
{(isHovered || props.currentPromptVersion === prompt.version || isPromptDiffOpen) && (props.currentPrompt && props.currentPromptVersion !== prompt.version ? ( { setIsPromptDiffOpen(open); }} leftPrompt={prompt} rightPrompt={props.currentPrompt} /> ) : null)}
); }; export const PromptHistoryNode = (props: { prompts: RouterOutputs["prompts"]["allVersions"]["promptVersions"]; currentPromptVersion: number | undefined; setCurrentPromptVersion: (id: number | undefined) => void; totalCount: number; commentCounts?: Map; }) => { const router = useRouter(); const projectId = router.query.projectId as string; const currentPrompt = props.prompts.find( (p) => p.version === props.currentPromptVersion, ); return ( {props.prompts.map((prompt, index) => ( ))} ); };