Skip to content

Commit 3be40be

Browse files
author
Dylan Huang
committed
"Copy" button
1 parent 54333cf commit 3be40be

2 files changed

Lines changed: 84 additions & 1 deletion

File tree

vite-app/src/components/EvaluationRow.tsx

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,68 @@ import { MetadataSection } from "./MetadataSection";
55
import StatusIndicator from "./StatusIndicator";
66
import { state } from "../App";
77
import { TableCell, TableRowInteractive } from "./TableContainer";
8+
import { useState } from "react";
9+
10+
// Copy button component
11+
const CopyButton = observer(({ text }: { text: string }) => {
12+
const [copied, setCopied] = useState(false);
13+
14+
const handleClick = async (e: React.MouseEvent) => {
15+
e.stopPropagation(); // Prevent row expansion
16+
try {
17+
await navigator.clipboard.writeText(text);
18+
setCopied(true);
19+
// Reset to "Copy" state after 2 seconds
20+
setTimeout(() => setCopied(false), 2000);
21+
} catch (err) {
22+
console.error("Failed to copy text: ", err);
23+
}
24+
};
25+
26+
return (
27+
<button
28+
className="p-1 text-gray-400 hover:text-gray-600 transition-colors relative group cursor-pointer"
29+
onClick={handleClick}
30+
title="Copy to clipboard"
31+
>
32+
{/* Tooltip */}
33+
<div className="absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 px-2 py-1 text-xs text-white bg-gray-800 rounded opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none whitespace-nowrap">
34+
{copied ? "Copied!" : "Copy"}
35+
</div>
36+
37+
{/* Icon */}
38+
{copied ? (
39+
<svg
40+
className="w-3 h-3 text-green-600"
41+
fill="none"
42+
stroke="currentColor"
43+
viewBox="0 0 24 24"
44+
>
45+
<path
46+
strokeLinecap="round"
47+
strokeLinejoin="round"
48+
strokeWidth={2}
49+
d="M5 13l4 4L19 7"
50+
/>
51+
</svg>
52+
) : (
53+
<svg
54+
className="w-3 h-3"
55+
fill="none"
56+
stroke="currentColor"
57+
viewBox="0 0 24 24"
58+
>
59+
<path
60+
strokeLinecap="round"
61+
strokeLinejoin="round"
62+
strokeWidth={2}
63+
d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"
64+
/>
65+
</svg>
66+
)}
67+
</button>
68+
);
69+
});
870

971
// Small, focused components following "dereference values late" principle
1072
const ExpandIcon = observer(({ rolloutId }: { rolloutId?: string }) => {
@@ -59,11 +121,24 @@ const RolloutId = observer(
59121
return (
60122
<span className="font-mono text-gray-900 whitespace-nowrap">
61123
{rolloutId}
124+
<CopyButton text={rolloutId} />
62125
</span>
63126
);
64127
}
65128
);
66129

130+
const InvocationId = observer(({ invocationId }: { invocationId?: string }) => {
131+
if (!invocationId) {
132+
return null;
133+
}
134+
return (
135+
<span className="font-mono text-gray-900 whitespace-nowrap">
136+
{invocationId}
137+
<CopyButton text={invocationId} />
138+
</span>
139+
);
140+
});
141+
67142
const RowModel = observer(({ model }: { model: string | undefined }) => (
68143
<span className="text-gray-900 truncate block">{model || "N/A"}</span>
69144
));
@@ -224,6 +299,13 @@ export const EvaluationRow = observer(
224299
/>
225300
</TableCell>
226301

302+
{/* Invocation ID */}
303+
<TableCell className="py-3 text-xs">
304+
<InvocationId
305+
invocationId={row.execution_metadata?.invocation_id}
306+
/>
307+
</TableCell>
308+
227309
{/* Rollout ID */}
228310
<TableCell className="py-3 text-xs">
229311
<RolloutId rolloutId={row.execution_metadata?.rollout_id} />
@@ -248,7 +330,7 @@ export const EvaluationRow = observer(
248330
{/* Expanded Content Row */}
249331
{isExpanded && (
250332
<tr>
251-
<td colSpan={8} className="p-0">
333+
<td colSpan={9} className="p-0">
252334
<ExpandedContent
253335
row={row}
254336
messages={row.messages}

vite-app/src/components/EvaluationTable.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ export const EvaluationTable = observer(() => {
162162
<TableHeader className="w-8">&nbsp;</TableHeader>
163163
<TableHeader>Name</TableHeader>
164164
<TableHeader>Status</TableHeader>
165+
<TableHeader>Invocation ID</TableHeader>
165166
<TableHeader>Rollout ID</TableHeader>
166167
<TableHeader>Model</TableHeader>
167168
<TableHeader>Score</TableHeader>

0 commit comments

Comments
 (0)