feat(ui): improve git diff panel with grouped file status display

Replace individual file status badges with grouped status summaries showing count and icon for each file type (modified, untracked, etc.). This improves UX when dealing with large changesets by reducing visual clutter.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
This commit is contained in:
Kacper
2025-12-10 14:21:52 +01:00
parent 1ea18b779e
commit fff8a6398f
2 changed files with 74 additions and 16 deletions

View File

@@ -292,5 +292,24 @@
"skipTests": true,
"model": "sonnet",
"thinkingLevel": "medium"
},
{
"id": "feature-1765372497502-kxppqqv3k",
"category": "Uncategorized",
"description": "As u can see in our git diff panel on each new file its show modified or untracked if it untracked and that not good for ui / ux what if user / agett change over 40-50 files in one go this wiould be complete mess i would rather do 1 type for each with number and icon",
"steps": [],
"status": "verified",
"startedAt": "2025-12-10T13:15:19.417Z",
"imagePaths": [
{
"id": "img-1765372428239-jg07w3zxv",
"path": "/Users/shirone/Library/Application Support/automaker/images/1765372428236-6t02kvclp_SCR-20251210-mplr.png",
"filename": "SCR-20251210-mplr.png",
"mimeType": "image/png"
}
],
"skipTests": false,
"model": "sonnet",
"thinkingLevel": "none"
}
]

View File

@@ -82,6 +82,27 @@ const getStatusBadgeColor = (status: string) => {
}
};
const getStatusDisplayName = (status: string) => {
switch (status) {
case "A":
return "Added";
case "?":
return "Untracked";
case "D":
return "Deleted";
case "M":
return "Modified";
case "U":
return "Updated";
case "R":
return "Renamed";
case "C":
return "Copied";
default:
return "Changed";
}
};
/**
* Parse unified diff format into structured data
*/
@@ -505,23 +526,41 @@ export function GitDiffPanel({
{/* Summary bar */}
<div className="flex items-center justify-between">
<div className="flex items-center gap-4 flex-wrap">
{files.map((file) => (
<div
key={file.path}
className="flex items-center gap-1.5"
title={file.path}
>
{getFileIcon(file.status)}
<span
className={cn(
"text-xs px-1.5 py-0.5 rounded border",
getStatusBadgeColor(file.status)
)}
{(() => {
// Group files by status
const statusGroups = files.reduce((acc, file) => {
const status = file.status;
if (!acc[status]) {
acc[status] = {
count: 0,
statusText: getStatusDisplayName(status),
files: []
};
}
acc[status].count += 1;
acc[status].files.push(file.path);
return acc;
}, {} as Record<string, {count: number, statusText: string, files: string[]}>);
return Object.entries(statusGroups).map(([status, group]) => (
<div
key={status}
className="flex items-center gap-1.5"
title={group.files.join('\n')}
data-testid={`git-status-group-${status.toLowerCase()}`}
>
{file.statusText}
</span>
</div>
))}
{getFileIcon(status)}
<span
className={cn(
"text-xs px-1.5 py-0.5 rounded border font-medium",
getStatusBadgeColor(status)
)}
>
{group.count} {group.statusText}
</span>
</div>
));
})()}
</div>
<div className="flex items-center gap-2">
<Button