|
1 | 1 | 'use client'; |
2 | 2 |
|
3 | | -import { ListCommitsToolUIPart } from "@/features/chat/tools"; |
4 | | -import { useMemo, useState } from "react"; |
5 | | -import { ToolHeader, TreeList } from "./shared"; |
6 | | -import { CodeSnippet } from "@/app/components/codeSnippet"; |
| 3 | +import { ListCommitsMetadata, ToolResult } from "@/features/tools"; |
| 4 | +import { RepoBadge } from "./repoBadge"; |
7 | 5 | import { Separator } from "@/components/ui/separator"; |
8 | | -import { GitCommitVerticalIcon } from "lucide-react"; |
9 | 6 |
|
10 | | -export const ListCommitsToolComponent = ({ part }: { part: ListCommitsToolUIPart }) => { |
11 | | - const [isExpanded, setIsExpanded] = useState(false); |
12 | | - |
13 | | - const label = useMemo(() => { |
14 | | - switch (part.state) { |
15 | | - case 'input-streaming': |
16 | | - return 'Listing commits...'; |
17 | | - case 'output-error': |
18 | | - return '"List commits" tool call failed'; |
19 | | - case 'input-available': |
20 | | - case 'output-available': |
21 | | - return 'Listed commits'; |
22 | | - } |
23 | | - }, [part]); |
| 7 | +export const ListCommitsToolComponent = ({ metadata }: ToolResult<ListCommitsMetadata>) => { |
| 8 | + const count = metadata.commits.length; |
| 9 | + const label = `${count} ${count === 1 ? 'commit' : 'commits'}`; |
24 | 10 |
|
25 | 11 | return ( |
26 | | - <div> |
27 | | - <ToolHeader |
28 | | - isLoading={part.state !== 'output-available' && part.state !== 'output-error'} |
29 | | - isError={part.state === 'output-error'} |
30 | | - isExpanded={isExpanded} |
31 | | - label={label} |
32 | | - Icon={GitCommitVerticalIcon} |
33 | | - onExpand={setIsExpanded} |
34 | | - input={part.state !== 'input-streaming' ? JSON.stringify(part.input) : undefined} |
35 | | - output={part.state === 'output-available' ? part.output.output : undefined} |
36 | | - /> |
37 | | - {part.state === 'output-available' && isExpanded && ( |
38 | | - <> |
39 | | - {part.output.metadata.commits.length === 0 ? ( |
40 | | - <span className="text-sm text-muted-foreground ml-[25px]">No commits found</span> |
41 | | - ) : ( |
42 | | - <TreeList> |
43 | | - <div className="text-sm text-muted-foreground mb-2"> |
44 | | - Found {part.output.metadata.commits.length} of {part.output.metadata.totalCount} total commits: |
45 | | - </div> |
46 | | - {part.output.metadata.commits.map((commit) => ( |
47 | | - <div key={commit.hash} className="mb-3 last:mb-0"> |
48 | | - <div className="flex items-start gap-2 text-sm"> |
49 | | - <GitCommitVerticalIcon className="h-4 w-4 text-muted-foreground mt-0.5 flex-shrink-0" /> |
50 | | - <div className="flex-1 min-w-0"> |
51 | | - <div className="flex items-center gap-2 flex-wrap"> |
52 | | - <CodeSnippet className="text-xs font-mono"> |
53 | | - {commit.hash.substring(0, 7)} |
54 | | - </CodeSnippet> |
55 | | - {commit.refs && ( |
56 | | - <span className="text-xs text-muted-foreground"> |
57 | | - {commit.refs} |
58 | | - </span> |
59 | | - )} |
60 | | - </div> |
61 | | - <div className="mt-1 font-medium"> |
62 | | - {commit.message} |
63 | | - </div> |
64 | | - <div className="flex items-center gap-2 mt-1 text-xs text-muted-foreground"> |
65 | | - <span>{commit.author_name}</span> |
66 | | - <span>•</span> |
67 | | - <span>{new Date(commit.date).toLocaleString()}</span> |
68 | | - </div> |
69 | | - </div> |
70 | | - </div> |
71 | | - </div> |
72 | | - ))} |
73 | | - </TreeList> |
74 | | - )} |
75 | | - <Separator className='ml-[7px] my-2' /> |
76 | | - </> |
77 | | - )} |
| 12 | + <div className="flex items-center gap-2 select-none cursor-default text-sm text-muted-foreground"> |
| 13 | + <span className="flex-shrink-0">Listed commits in</span> |
| 14 | + <RepoBadge repo={metadata.repoInfo} /> |
| 15 | + <span className="flex-1" /> |
| 16 | + <span className="text-xs flex-shrink-0">{label}</span> |
| 17 | + <Separator orientation="vertical" className="h-3 flex-shrink-0" /> |
78 | 18 | </div> |
79 | | - ) |
80 | | -} |
| 19 | + ); |
| 20 | +}; |
0 commit comments