import { StringParam, useQueryParam, withDefault } from "use-query-params"; import { PublishTraceSwitch } from "@/src/components/publish-object-switch"; import { DetailPageNav } from "@/src/features/navigate-detail-pages/DetailPageNav"; import { useRouter } from "next/router"; import { api } from "@/src/utils/api"; import { StarTraceDetailsToggle } from "@/src/components/star-toggle"; import { ErrorPage } from "@/src/components/error-page"; import { DeleteTraceButton } from "@/src/components/deleteButton"; import Page from "@/src/components/layouts/page"; import { Trace } from "@/src/components/trace2/Trace"; import { useSession } from "next-auth/react"; import { useIsAuthenticatedAndProjectMember } from "@/src/features/auth/hooks"; import { Button } from "@/src/components/ui/button"; import Link from "next/link"; import { stripBasePath } from "@/src/utils/redirect"; import { Badge } from "@/src/components/ui/badge"; import { useV4Beta } from "@/src/features/events/hooks/useV4Beta"; import { useEventsTraceData } from "@/src/features/events/hooks/useEventsTraceData"; export function TracePage({ traceId, timestamp, }: { traceId: string; timestamp?: Date; }) { const router = useRouter(); const session = useSession(); const routeProjectId = (router.query.projectId as string) ?? ""; const { isBetaEnabled } = useV4Beta(); // Old path: fetch from traces table (beta OFF) const tracesQuery = api.traces.byIdWithObservationsAndScores.useQuery( { traceId, timestamp, projectId: routeProjectId, }, { enabled: !isBetaEnabled, retry(failureCount, error) { if ( error.data?.code === "UNAUTHORIZED" || error.data?.code === "NOT_FOUND" ) return false; return failureCount < 3; }, }, ); // New path: fetch from events table (beta ON) const eventsData = useEventsTraceData({ projectId: routeProjectId, traceId, timestamp, enabled: isBetaEnabled, }); // Use the appropriate data source based on beta toggle const trace = isBetaEnabled ? { data: eventsData.data, isLoading: eventsData.isLoading, error: eventsData.error as typeof tracesQuery.error, } : tracesQuery; const projectIdForAccessCheck = trace.data?.projectId ?? routeProjectId; const hasProjectAccess = useIsAuthenticatedAndProjectMember( projectIdForAccessCheck, ); const [selectedTab, setSelectedTab] = useQueryParam( "display", withDefault(StringParam, "details"), ); // Handle errors - for events path, we check if there's no data after loading if (!isBetaEnabled && tracesQuery.error?.data?.code === "UNAUTHORIZED") return ; if (!isBetaEnabled && tracesQuery.error?.data?.code === "NOT_FOUND") return ( void window.location.reload(), }} /> ); // For events path: show not found if no observations found after loading if (isBetaEnabled && !eventsData.isLoading && !eventsData.data) return ( void window.location.reload(), }} /> ); if (!trace.data) return
Loading...
; const isSharedTrace = trace.data.public; const showPublicIndicators = isSharedTrace && !hasProjectAccess; const encodedTargetPath = encodeURIComponent( stripBasePath(router.asPath || "/"), ); const leadingControl = showPublicIndicators ? ( session.status === "authenticated" ? ( ) : ( ) ) : undefined; const sharedBadge = showPublicIndicators ? ( Public ) : undefined; return (
), actionButtonsRight: ( <> { const { view, display, projectId } = router.query; const queryParams = new URLSearchParams({ ...(typeof view === "string" ? { view } : {}), ...(typeof display === "string" ? { display } : {}), }); const timestamp = entry.params && entry.params.timestamp ? encodeURIComponent(entry.params.timestamp) : undefined; if (timestamp) { queryParams.set("timestamp", timestamp); } const finalQueryString = queryParams.size ? `?${queryParams.toString()}` : ""; return `/project/${projectId as string}/traces/${entry.id}${finalQueryString}`; }} listKey="traces" /> ), }} >
); }