Skip to content

Commit 7044321

Browse files
list commits updated ui
1 parent ea801f1 commit 7044321

File tree

3 files changed

+26
-76
lines changed

3 files changed

+26
-76
lines changed

packages/web/src/features/chat/components/chatThread/detailsCard.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,9 +255,12 @@ export const StepPartRenderer = ({ part }: { part: SBChatMessagePart }) => {
255255
)
256256
case 'tool-list_commits':
257257
return (
258-
<ListCommitsToolComponent
258+
<ToolLoadingGuard
259259
part={part}
260-
/>
260+
loadingText="Listing commits..."
261+
>
262+
{(output) => <ListCommitsToolComponent {...output} />}
263+
</ToolLoadingGuard>
261264
)
262265
case 'tool-list_tree':
263266
return (
Lines changed: 13 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,20 @@
11
'use client';
22

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";
75
import { Separator } from "@/components/ui/separator";
8-
import { GitCommitVerticalIcon } from "lucide-react";
96

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'}`;
2410

2511
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" />
7818
</div>
79-
)
80-
}
19+
);
20+
};

packages/web/src/features/chat/components/chatThread/tools/toolLoadingGuard.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,14 @@ export const ToolLoadingGuard = <T extends ToolUIPart<{ [K in keyof SBChatMessag
2424

2525
const requestText = hasInput ? JSON.stringify(part.input, null, 2) : '';
2626
const responseText = part.state === 'output-available'
27-
? (part.output as { output: string }).output
27+
? (() => {
28+
const raw = (part.output as { output: string }).output;
29+
try {
30+
return JSON.stringify(JSON.parse(raw), null, 2);
31+
} catch {
32+
return raw;
33+
}
34+
})()
2835
: part.state === 'output-error'
2936
? (part.errorText ?? '')
3037
: undefined;

0 commit comments

Comments
 (0)