refactor(sidebar): improve session list UX and organization

- Add two-line session display with title on line 1 and agent/timestamp on line 2
- Include short session ID in title to distinguish sessions in same folder
- Remove status indicator dot for cleaner visual hierarchy
- Show agent name and last updated time as plain text (no badge)
- Update Settings button to ghost variant with better hover state
- Show working directory path in tooltip instead of redundant info

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
Jiayuan
2026-01-15 02:18:43 +08:00
parent 041f9fac32
commit b5b8e66698
2 changed files with 13772 additions and 14 deletions

13753
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -47,9 +47,13 @@ function formatDate(iso: string): string {
function getSessionTitle(session: MulticaSession): string {
if (session.title) return session.title
const parts = session.workingDirectory.split('/')
return parts[parts.length - 1] || session.workingDirectory
const folderName = parts[parts.length - 1] || session.workingDirectory
// Add short ID suffix to distinguish sessions in the same folder
const shortId = session.id.slice(0, 4)
return `${folderName} · ${shortId}`
}
// Session list item component
interface SessionItemProps {
session: MulticaSession
@@ -77,16 +81,17 @@ function SessionItem({ session, isActive, onSelect, onDelete }: SessionItemProps
isActive && "bg-sidebar-accent"
)}
>
{/* Error indicator - only show on error */}
{session.status === 'error' && (
<span className="h-2 w-2 flex-shrink-0 rounded-full bg-red-500" />
)}
{/* Content */}
<div className="min-w-0 flex-1">
<span className="truncate text-sm">
{/* Two-line layout container */}
<div className="flex min-w-0 flex-1 flex-col gap-0.5">
{/* Line 1: Title */}
<span className="truncate text-sm font-medium">
{getSessionTitle(session)}
</span>
{/* Line 2: Agent + Timestamp */}
<span className="text-xs text-muted-foreground/60">
{session.agentId} · {formatDate(session.updatedAt)}
</span>
</div>
{/* Delete button - always rendered, visibility via opacity */}
@@ -96,7 +101,7 @@ function SessionItem({ session, isActive, onSelect, onDelete }: SessionItemProps
onDelete()
}}
className={cn(
"flex-shrink-0 rounded p-1 transition-opacity duration-150",
"flex-shrink-0 self-start rounded p-1 transition-opacity duration-150",
"hover:bg-muted active:bg-muted",
isHovered ? "opacity-50 hover:opacity-100" : "opacity-0"
)}
@@ -106,7 +111,7 @@ function SessionItem({ session, isActive, onSelect, onDelete }: SessionItemProps
</SidebarMenuButton>
</TooltipTrigger>
<TooltipContent side="right">
<p>{session.agentId} · {formatDate(session.updatedAt)}</p>
<p>{session.workingDirectory}</p>
</TooltipContent>
</Tooltip>
</SidebarMenuItem>
@@ -183,13 +188,13 @@ export function AppSidebar({
<SidebarFooter className="px-2 pb-2">
<Button
variant="secondary"
variant="ghost"
size="sm"
onClick={() => openModal('settings')}
className="w-full justify-center gap-2"
className="w-full justify-center gap-2 hover:bg-sidebar-accent"
>
<Settings className="h-4 w-4" />
Setting
Settings
</Button>
</SidebarFooter>
</Sidebar>