import { type AnnotationQueueItem, type ScoreConfigDomain, } from "@langfuse/shared"; import { AnnotationDrawerSection } from "../shared/AnnotationDrawerSection"; import { AnnotationProcessingLayout } from "../shared/AnnotationProcessingLayout"; import { SessionIO } from "@/src/components/session"; import { useState, useEffect } from "react"; import { Button } from "@/src/components/ui/button"; import { ItemBadge } from "@/src/components/ItemBadge"; import { CopyIdsPopover } from "@/src/components/trace2/components/_shared/CopyIdsPopover"; import { Badge } from "@/src/components/ui/badge"; import { Separator } from "@/src/components/ui/separator"; import Link from "next/link"; import { Card } from "@/src/components/ui/card"; interface SessionAnnotationProcessorProps { item: AnnotationQueueItem & { parentTraceId?: string | null; lockedByUser: { name: string | null | undefined } | null; }; data: any; // // Session data with scores configs: ScoreConfigDomain[]; projectId: string; } // some projects have thousands of traces in a session, paginate to avoid rendering all at once const PAGE_SIZE = 10; export const SessionAnnotationProcessor: React.FC< SessionAnnotationProcessorProps > = ({ item, data, configs, projectId }) => { const [visibleTraces, setVisibleTraces] = useState(PAGE_SIZE); const [currentTraceIndex, setCurrentTraceIndex] = useState(1); // Intersection observer to which trace is currently in view useEffect(() => { if (!data?.traces) return; const observer = new IntersectionObserver( (entries) => { entries.forEach((entry) => { if (entry.isIntersecting && entry.intersectionRatio > 0.5) { const index = parseInt( entry.target.getAttribute("data-trace-index") || "0", ); setCurrentTraceIndex(index + 1); } }); }, { threshold: 0.5, // Trigger when 50% of trace is visible rootMargin: "-25% 0px -25% 0px", // Focus on center area }, ); // Observe all trace cards const traceCards = document.querySelectorAll("[data-trace-index]"); traceCards.forEach((card) => observer.observe(card)); return () => observer.disconnect(); }, [data?.traces, visibleTraces]); const leftPanel = (