import { api } from "@/src/utils/api"; import { type FilterState } from "@langfuse/shared"; import { ExpandListButton } from "@/src/features/dashboard/components/cards/ChevronButton"; import { useState } from "react"; import { DashboardCard } from "@/src/features/dashboard/components/cards/DashboardCard"; import { TotalMetric } from "@/src/features/dashboard/components/TotalMetric"; import { BarList } from "@tremor/react"; import { compactNumberFormatter } from "@/src/utils/numbers"; import { NoDataOrLoading } from "@/src/components/NoDataOrLoading"; import { type QueryType, mapLegacyUiTableFilterToView, } from "@/src/features/query"; export const TracesBarListChart = ({ className, projectId, globalFilterState, fromTimestamp, toTimestamp, isLoading = false, }: { className?: string; projectId: string; globalFilterState: FilterState; fromTimestamp: Date; toTimestamp: Date; isLoading?: boolean; }) => { const [isExpanded, setIsExpanded] = useState(false); // Total traces query using executeQuery const totalTracesQuery: QueryType = { view: "traces", dimensions: [], metrics: [{ measure: "count", aggregation: "count" }], filters: mapLegacyUiTableFilterToView("traces", globalFilterState), timeDimension: null, fromTimestamp: fromTimestamp.toISOString(), toTimestamp: toTimestamp.toISOString(), orderBy: null, }; const totalTraces = api.dashboard.executeQuery.useQuery( { projectId, query: totalTracesQuery, }, { trpc: { context: { skipBatch: true, }, }, enabled: !isLoading, }, ); // Traces grouped by name query using executeQuery const tracesQuery: QueryType = { view: "traces", dimensions: [{ field: "name" }], metrics: [{ measure: "count", aggregation: "count" }], filters: mapLegacyUiTableFilterToView("traces", globalFilterState), timeDimension: null, fromTimestamp: fromTimestamp.toISOString(), toTimestamp: toTimestamp.toISOString(), orderBy: null, }; const traces = api.dashboard.executeQuery.useQuery( { projectId, query: tracesQuery, }, { trpc: { context: { skipBatch: true, }, }, enabled: !isLoading, }, ); // Transform the data to match the expected format for the BarList const transformedTraces = traces.data?.map((item: any) => { return { name: item.name ? (item.name as string) : "Unknown", value: Number(item.count_count), }; }) ?? []; const maxNumberOfEntries = { collapsed: 5, expanded: 20 }; const adjustedData = isExpanded ? transformedTraces.slice(0, maxNumberOfEntries.expanded) : transformedTraces.slice(0, maxNumberOfEntries.collapsed); return ( <> {adjustedData.length > 0 ? ( <> Intl.NumberFormat("en-US").format(number).toString() } className="mt-6 [&_*]:text-muted-foreground [&_p]:text-muted-foreground [&_span]:text-muted-foreground" showAnimation={true} color={"indigo"} /> ) : ( )} maxNumberOfEntries.expanded ? `Show top ${maxNumberOfEntries.expanded}` : "Show all" } /> ); };