This commit is contained in:
AI Christianson 2025-03-14 17:28:21 -04:00
parent f1277aadf1
commit f7aaccec76
7 changed files with 44 additions and 36 deletions

View File

@ -6,7 +6,7 @@ import {
Layout
} from './ui';
import { SessionDrawer } from './SessionDrawer';
import { SessionSidebar } from './SessionSidebar';
import { SessionList } from './SessionList';
import { TimelineFeed } from './TimelineFeed';
import { getSampleAgentSessions, getSampleAgentSteps } from '../utils/sample-data';
@ -146,13 +146,19 @@ export const DefaultAgentScreen: React.FC = () => {
</div>
);
// Render sidebar content
// Sidebar content with sessions list
const sidebarContent = (
<SessionSidebar
sessions={sessions}
currentSessionId={selectedSessionId || undefined}
onSelectSession={handleSessionSelect}
/>
<div className="h-full flex flex-col px-4 py-3">
<div className="border-b border-border pb-3">
<h2 className="text-xl font-semibold">Sessions</h2>
</div>
<SessionList
sessions={sessions}
onSelectSession={handleSessionSelect}
currentSessionId={selectedSessionId || undefined}
className="flex-1 mt-3 pr-1 -mr-1"
/>
</div>
);
// Render drawer

View File

@ -29,16 +29,16 @@ export const SessionDrawer: React.FC<SessionDrawerProps> = ({
<Sheet open={isOpen} onOpenChange={onClose}>
<SheetContent
side="left"
className="w-full sm:max-w-md border-r border-border"
className="w-full sm:max-w-md border-r border-border p-4"
>
<SheetHeader>
<SheetHeader className="px-2">
<SheetTitle>Sessions</SheetTitle>
</SheetHeader>
<SessionList
sessions={sessions}
currentSessionId={currentSessionId}
onSelectSession={onSelectSession}
className="h-[calc(100vh-9rem)] mt-6"
className="h-[calc(100vh-9rem)] mt-4"
wrapperComponent={SheetClose}
/>
</SheetContent>

View File

@ -45,18 +45,18 @@ export const SessionList: React.FC<SessionListProps> = ({
};
return (
<ScrollArea className={`${className}`}>
<div className="px-2 py-2 space-y-3 w-full">
<ScrollArea className={className}>
<div className="space-y-1.5 pt-1.5 pb-2">
{sessions.map((session) => {
const buttonContent = (
<>
<div className={`w-2.5 h-2.5 rounded-full ${getStatusColor(session.status)} mt-1.5 mr-2 flex-shrink-0`} />
<div className="flex-1 min-w-0 w-full overflow-hidden">
<div className="font-medium truncate max-w-full">{session.name}</div>
<div className="text-xs text-muted-foreground mt-0.5 truncate">
<div className={`w-2.5 h-2.5 rounded-full ${getStatusColor(session.status)} mt-1.5 mr-3 flex-shrink-0`} />
<div className="flex-1 min-w-0 pr-1">
<div className="font-medium text-sm+ break-words">{session.name}</div>
<div className="text-xs text-muted-foreground mt-1 break-words">
{session.steps.length} steps {formatDate(session.updated)}
</div>
<div className="text-xs text-muted-foreground mt-0.5 truncate">
<div className="text-xs text-muted-foreground mt-0.5 break-words">
<span className="capitalize">{session.status}</span>
</div>
</div>
@ -68,19 +68,21 @@ export const SessionList: React.FC<SessionListProps> = ({
{
key: session.id,
onClick: () => onSelectSession?.(session.id),
className: `w-full flex items-start px-2 py-2 text-left rounded-md transition-colors hover:bg-accent/50 ${
className: `w-full flex items-start px-3 py-2.5 text-left rounded-md transition-colors hover:bg-accent/50 ${
currentSessionId === session.id ? 'bg-accent' : ''
}`
},
closeAction ? (
<>
{buttonContent}
{React.cloneElement(closeAction as React.ReactElement, {
onClick: (e: React.MouseEvent) => {
e.stopPropagation();
onSelectSession?.(session.id);
}
})}
<div className="ml-2 flex-shrink-0 self-center">
{React.cloneElement(closeAction as React.ReactElement, {
onClick: (e: React.MouseEvent) => {
e.stopPropagation();
onSelectSession?.(session.id);
}
})}
</div>
</>
) : buttonContent
);

View File

@ -24,7 +24,7 @@ export const TimelineFeed: React.FC<TimelineFeedProps> = ({
return (
<div className="w-full rounded-md bg-background">
<div
className="p-4 space-y-5 overflow-auto"
className="px-3 py-3 space-y-4 overflow-auto"
style={{ maxHeight: maxHeight || undefined }}
>
{sortedSteps.length > 0 ? (

View File

@ -49,18 +49,18 @@ export const TimelineStep: React.FC<TimelineStepProps> = ({ step }) => {
return (
<Collapsible className="w-full mb-5 border border-border rounded-md overflow-hidden shadow-sm hover:shadow-md transition-all duration-200">
<CollapsibleTrigger className="w-full flex items-center justify-between p-4 text-left hover:bg-accent/30 cursor-pointer group">
<div className="flex items-center space-x-3">
<div className={`w-3 h-3 rounded-full ${getStatusColor(step.status)} ring-1 ring-ring/20`} />
<div className="text-lg group-hover:scale-110 transition-transform">{getTypeIcon(step.type)}</div>
<div>
<div className="font-medium text-foreground">{step.title}</div>
<div className="text-sm text-muted-foreground truncate max-w-md">
<div className="flex items-center space-x-3 min-w-0 flex-1 pr-3">
<div className={`flex-shrink-0 w-3 h-3 rounded-full ${getStatusColor(step.status)} ring-1 ring-ring/20`} />
<div className="flex-shrink-0 text-lg group-hover:scale-110 transition-transform">{getTypeIcon(step.type)}</div>
<div className="min-w-0 flex-1">
<div className="font-medium text-foreground break-words">{step.title}</div>
<div className="text-sm text-muted-foreground line-clamp-2">
{step.type === 'tool-execution' ? 'Run tool' : step.content.substring(0, 60)}
{step.content.length > 60 ? '...' : ''}
</div>
</div>
</div>
<div className="text-xs text-muted-foreground flex flex-col items-end">
<div className="text-xs text-muted-foreground flex flex-col items-end flex-shrink-0 min-w-[70px] text-right">
<span className="font-medium">{formatTime(step.timestamp)}</span>
{step.duration && (
<span className="mt-1 px-2 py-0.5 bg-secondary/50 rounded-full">
@ -71,7 +71,7 @@ export const TimelineStep: React.FC<TimelineStepProps> = ({ step }) => {
</CollapsibleTrigger>
<CollapsibleContent>
<div className="p-5 bg-card/50 border-t border-border">
<div className="text-sm whitespace-pre-wrap text-foreground leading-relaxed">
<div className="text-sm break-words text-foreground leading-relaxed">
{step.content}
</div>
{step.duration && (

View File

@ -24,7 +24,7 @@ export const Layout: React.FC<LayoutProps> = ({
floatingAction
}) => {
return (
<div className="grid min-h-screen grid-cols-1 grid-rows-[64px_1fr] md:grid-cols-[250px_1fr] lg:grid-cols-[300px_1fr] bg-background text-foreground relative">
<div className="grid min-h-screen grid-cols-1 grid-rows-[64px_1fr] md:grid-cols-[280px_1fr] lg:grid-cols-[320px_1fr] xl:grid-cols-[350px_1fr] bg-background text-foreground relative">
{/* Header - always visible, spans full width */}
<header className="sticky top-0 z-30 h-16 flex items-center bg-background border-b border-border col-span-full">
{header}
@ -32,7 +32,7 @@ export const Layout: React.FC<LayoutProps> = ({
{/* Sidebar - hidden on mobile, visible on tablet/desktop */}
{sidebar && (
<aside className="hidden md:block sticky top-16 h-[calc(100vh-64px)] overflow-y-auto z-20 bg-background border-r border-border row-start-2 col-start-1">
<aside className="hidden md:block h-[calc(100vh-64px)] overflow-hidden z-20 bg-background border-r border-border row-start-2 col-start-1">
{sidebar}
</aside>
)}

View File

@ -36,7 +36,7 @@ const sheetVariants = cva(
top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
right: "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
bottom: "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
left: "inset-y-0 left-0 h-full w-full border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
},
},
defaultVariants: {