|
1 | 1 | "use client" |
2 | 2 |
|
3 | | -import { useCallback, useMemo, useState } from "react" |
| 3 | +import { useCallback, useState, useRef } from "react" |
4 | 4 | import { useRouter } from "next/navigation" |
5 | 5 | import Link from "next/link" |
6 | 6 | import { Ellipsis, Rocket } from "lucide-react" |
@@ -35,8 +35,7 @@ export function Home({ runs }: { runs: (Run & { taskMetrics: TaskMetrics | null |
35 | 35 | const router = useRouter() |
36 | 36 |
|
37 | 37 | const [deleteRunId, setDeleteRunId] = useState<number>() |
38 | | - |
39 | | - const visibleRuns = useMemo(() => runs.filter((run) => run.taskMetrics !== null), [runs]) |
| 38 | + const continueRef = useRef<HTMLButtonElement>(null) |
40 | 39 |
|
41 | 40 | const onConfirmDelete = useCallback(async () => { |
42 | 41 | if (!deleteRunId) { |
@@ -67,33 +66,43 @@ export function Home({ runs }: { runs: (Run & { taskMetrics: TaskMetrics | null |
67 | 66 | </TableRow> |
68 | 67 | </TableHeader> |
69 | 68 | <TableBody> |
70 | | - {visibleRuns.length ? ( |
71 | | - visibleRuns.map(({ taskMetrics, ...run }) => ( |
| 69 | + {runs.length ? ( |
| 70 | + runs.map(({ taskMetrics, ...run }) => ( |
72 | 71 | <TableRow key={run.id}> |
73 | 72 | <TableCell>{run.model}</TableCell> |
74 | 73 | <TableCell>{run.passed}</TableCell> |
75 | 74 | <TableCell>{run.failed}</TableCell> |
76 | | - <TableCell>{((run.passed / (run.passed + run.failed)) * 100).toFixed(1)}%</TableCell> |
77 | 75 | <TableCell> |
78 | | - <div className="flex items-center justify-evenly"> |
79 | | - <div>{formatTokens(taskMetrics!.tokensIn)}</div>/ |
80 | | - <div>{formatTokens(taskMetrics!.tokensOut)}</div> |
81 | | - </div> |
| 76 | + {run.passed + run.failed > 0 && ( |
| 77 | + <span>{((run.passed / (run.passed + run.failed)) * 100).toFixed(1)}%</span> |
| 78 | + )} |
| 79 | + </TableCell> |
| 80 | + <TableCell> |
| 81 | + {taskMetrics && ( |
| 82 | + <div className="flex items-center justify-evenly"> |
| 83 | + <div>{formatTokens(taskMetrics.tokensIn)}</div>/ |
| 84 | + <div>{formatTokens(taskMetrics.tokensOut)}</div> |
| 85 | + </div> |
| 86 | + )} |
82 | 87 | </TableCell> |
83 | | - <TableCell>{formatCurrency(taskMetrics!.cost)}</TableCell> |
84 | | - <TableCell>{formatDuration(taskMetrics!.duration)}</TableCell> |
| 88 | + <TableCell>{taskMetrics && formatCurrency(taskMetrics.cost)}</TableCell> |
| 89 | + <TableCell>{taskMetrics && formatDuration(taskMetrics.duration)}</TableCell> |
85 | 90 | <TableCell> |
86 | 91 | <DropdownMenu> |
87 | 92 | <Button variant="ghost" size="icon" asChild> |
88 | 93 | <DropdownMenuTrigger> |
89 | 94 | <Ellipsis /> |
90 | 95 | </DropdownMenuTrigger> |
91 | 96 | </Button> |
92 | | - <DropdownMenuContent> |
| 97 | + <DropdownMenuContent align="end"> |
93 | 98 | <DropdownMenuItem asChild> |
94 | 99 | <Link href={`/runs/${run.id}`}>View Tasks</Link> |
95 | 100 | </DropdownMenuItem> |
96 | | - <DropdownMenuItem onClick={() => setDeleteRunId(run.id)}> |
| 101 | + <DropdownMenuItem |
| 102 | + onClick={() => { |
| 103 | + setDeleteRunId(run.id) |
| 104 | + setTimeout(() => continueRef.current?.focus(), 0) |
| 105 | + }}> |
97 | 106 | Delete |
98 | 107 | </DropdownMenuItem> |
99 | 108 | </DropdownMenuContent> |
@@ -128,7 +137,9 @@ export function Home({ runs }: { runs: (Run & { taskMetrics: TaskMetrics | null |
128 | 137 | </AlertDialogHeader> |
129 | 138 | <AlertDialogFooter> |
130 | 139 | <AlertDialogCancel>Cancel</AlertDialogCancel> |
131 | | - <AlertDialogAction onClick={onConfirmDelete}>Continue</AlertDialogAction> |
| 140 | + <AlertDialogAction ref={continueRef} onClick={onConfirmDelete}> |
| 141 | + Continue |
| 142 | + </AlertDialogAction> |
132 | 143 | </AlertDialogFooter> |
133 | 144 | </AlertDialogContent> |
134 | 145 | </AlertDialog> |
|
0 commit comments