langfuse
83 строки · 2.3 Кб
1import { Badge } from "@/src/components/ui/badge";
2import {
3HoverCard,
4HoverCardContent,
5HoverCardTrigger,
6} from "@/src/components/ui/hover-card";
7import { type ScoreSimplified } from "@/src/server/api/routers/generations/getAllQuery";
8import { cn } from "@/src/utils/tailwind";
9import { MessageCircle } from "lucide-react";
10
11export const GroupedScoreBadges = ({
12scores,
13variant = "badge",
14}: {
15scores: ScoreSimplified[];
16variant?: "badge" | "headings";
17}) => {
18const groupedScores = scores.reduce<Record<string, ScoreSimplified[]>>(
19(acc, score) => {
20if (!acc[score.name] || !Array.isArray(acc[score.name])) {
21acc[score.name] = [score];
22} else {
23(acc[score.name] as ScoreSimplified[]).push(score);
24}
25return acc;
26},
27{},
28);
29
30const ScoresOfGroup = (props: {
31scores: ScoreSimplified[];
32className?: string;
33}) => (
34<div className={cn("text-xs", props.className)}>
35{props.scores.map((s, i) => (
36<span key={i} className="group/score ml-1 first:ml-0">
37{s.value.toFixed(2)}
38{s.comment && (
39<HoverCard>
40<HoverCardTrigger className="ml-1 inline-block cursor-pointer">
41<MessageCircle size={12} />
42</HoverCardTrigger>
43<HoverCardContent>
44<p>{s.comment}</p>
45</HoverCardContent>
46</HoverCard>
47)}
48<span className="group-last/score:hidden">,</span>
49</span>
50))}
51</div>
52);
53
54if (variant === "headings")
55return (
56<div className="flex items-center gap-3">
57{Object.entries(groupedScores)
58.sort(([a], [b]) => (a < b ? -1 : 1))
59.map(([name, scores]) => (
60<div key={name}>
61<div className="text-xs text-gray-500">{name}</div>
62<ScoresOfGroup scores={scores} />
63</div>
64))}
65</div>
66);
67else
68return (
69<>
70{Object.entries(groupedScores)
71.sort(([a], [b]) => (a < b ? -1 : 1))
72.map(([name, scores]) => (
73<Badge
74variant="outline"
75key={name}
76className="break-all font-normal"
77>
78{name}: <ScoresOfGroup scores={scores} className="ml-2" />
79</Badge>
80))}
81</>
82);
83};
84