This commit is contained in:
parent
f1277aadf1
commit
f7aaccec76
|
|
@ -6,7 +6,7 @@ import {
|
||||||
Layout
|
Layout
|
||||||
} from './ui';
|
} from './ui';
|
||||||
import { SessionDrawer } from './SessionDrawer';
|
import { SessionDrawer } from './SessionDrawer';
|
||||||
import { SessionSidebar } from './SessionSidebar';
|
import { SessionList } from './SessionList';
|
||||||
import { TimelineFeed } from './TimelineFeed';
|
import { TimelineFeed } from './TimelineFeed';
|
||||||
import { getSampleAgentSessions, getSampleAgentSteps } from '../utils/sample-data';
|
import { getSampleAgentSessions, getSampleAgentSteps } from '../utils/sample-data';
|
||||||
|
|
||||||
|
|
@ -146,13 +146,19 @@ export const DefaultAgentScreen: React.FC = () => {
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
// Render sidebar content
|
// Sidebar content with sessions list
|
||||||
const sidebarContent = (
|
const sidebarContent = (
|
||||||
<SessionSidebar
|
<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}
|
sessions={sessions}
|
||||||
currentSessionId={selectedSessionId || undefined}
|
|
||||||
onSelectSession={handleSessionSelect}
|
onSelectSession={handleSessionSelect}
|
||||||
|
currentSessionId={selectedSessionId || undefined}
|
||||||
|
className="flex-1 mt-3 pr-1 -mr-1"
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
// Render drawer
|
// Render drawer
|
||||||
|
|
|
||||||
|
|
@ -29,16 +29,16 @@ export const SessionDrawer: React.FC<SessionDrawerProps> = ({
|
||||||
<Sheet open={isOpen} onOpenChange={onClose}>
|
<Sheet open={isOpen} onOpenChange={onClose}>
|
||||||
<SheetContent
|
<SheetContent
|
||||||
side="left"
|
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>
|
<SheetTitle>Sessions</SheetTitle>
|
||||||
</SheetHeader>
|
</SheetHeader>
|
||||||
<SessionList
|
<SessionList
|
||||||
sessions={sessions}
|
sessions={sessions}
|
||||||
currentSessionId={currentSessionId}
|
currentSessionId={currentSessionId}
|
||||||
onSelectSession={onSelectSession}
|
onSelectSession={onSelectSession}
|
||||||
className="h-[calc(100vh-9rem)] mt-6"
|
className="h-[calc(100vh-9rem)] mt-4"
|
||||||
wrapperComponent={SheetClose}
|
wrapperComponent={SheetClose}
|
||||||
/>
|
/>
|
||||||
</SheetContent>
|
</SheetContent>
|
||||||
|
|
|
||||||
|
|
@ -45,18 +45,18 @@ export const SessionList: React.FC<SessionListProps> = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScrollArea className={`${className}`}>
|
<ScrollArea className={className}>
|
||||||
<div className="px-2 py-2 space-y-3 w-full">
|
<div className="space-y-1.5 pt-1.5 pb-2">
|
||||||
{sessions.map((session) => {
|
{sessions.map((session) => {
|
||||||
const buttonContent = (
|
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={`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 w-full overflow-hidden">
|
<div className="flex-1 min-w-0 pr-1">
|
||||||
<div className="font-medium truncate max-w-full">{session.name}</div>
|
<div className="font-medium text-sm+ break-words">{session.name}</div>
|
||||||
<div className="text-xs text-muted-foreground mt-0.5 truncate">
|
<div className="text-xs text-muted-foreground mt-1 break-words">
|
||||||
{session.steps.length} steps • {formatDate(session.updated)}
|
{session.steps.length} steps • {formatDate(session.updated)}
|
||||||
</div>
|
</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>
|
<span className="capitalize">{session.status}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -68,19 +68,21 @@ export const SessionList: React.FC<SessionListProps> = ({
|
||||||
{
|
{
|
||||||
key: session.id,
|
key: session.id,
|
||||||
onClick: () => onSelectSession?.(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' : ''
|
currentSessionId === session.id ? 'bg-accent' : ''
|
||||||
}`
|
}`
|
||||||
},
|
},
|
||||||
closeAction ? (
|
closeAction ? (
|
||||||
<>
|
<>
|
||||||
{buttonContent}
|
{buttonContent}
|
||||||
|
<div className="ml-2 flex-shrink-0 self-center">
|
||||||
{React.cloneElement(closeAction as React.ReactElement, {
|
{React.cloneElement(closeAction as React.ReactElement, {
|
||||||
onClick: (e: React.MouseEvent) => {
|
onClick: (e: React.MouseEvent) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
onSelectSession?.(session.id);
|
onSelectSession?.(session.id);
|
||||||
}
|
}
|
||||||
})}
|
})}
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
) : buttonContent
|
) : buttonContent
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ export const TimelineFeed: React.FC<TimelineFeedProps> = ({
|
||||||
return (
|
return (
|
||||||
<div className="w-full rounded-md bg-background">
|
<div className="w-full rounded-md bg-background">
|
||||||
<div
|
<div
|
||||||
className="p-4 space-y-5 overflow-auto"
|
className="px-3 py-3 space-y-4 overflow-auto"
|
||||||
style={{ maxHeight: maxHeight || undefined }}
|
style={{ maxHeight: maxHeight || undefined }}
|
||||||
>
|
>
|
||||||
{sortedSteps.length > 0 ? (
|
{sortedSteps.length > 0 ? (
|
||||||
|
|
|
||||||
|
|
@ -49,18 +49,18 @@ export const TimelineStep: React.FC<TimelineStepProps> = ({ step }) => {
|
||||||
return (
|
return (
|
||||||
<Collapsible className="w-full mb-5 border border-border rounded-md overflow-hidden shadow-sm hover:shadow-md transition-all duration-200">
|
<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">
|
<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="flex items-center space-x-3 min-w-0 flex-1 pr-3">
|
||||||
<div className={`w-3 h-3 rounded-full ${getStatusColor(step.status)} ring-1 ring-ring/20`} />
|
<div className={`flex-shrink-0 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 className="flex-shrink-0 text-lg group-hover:scale-110 transition-transform">{getTypeIcon(step.type)}</div>
|
||||||
<div>
|
<div className="min-w-0 flex-1">
|
||||||
<div className="font-medium text-foreground">{step.title}</div>
|
<div className="font-medium text-foreground break-words">{step.title}</div>
|
||||||
<div className="text-sm text-muted-foreground truncate max-w-md">
|
<div className="text-sm text-muted-foreground line-clamp-2">
|
||||||
{step.type === 'tool-execution' ? 'Run tool' : step.content.substring(0, 60)}
|
{step.type === 'tool-execution' ? 'Run tool' : step.content.substring(0, 60)}
|
||||||
{step.content.length > 60 ? '...' : ''}
|
{step.content.length > 60 ? '...' : ''}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</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>
|
<span className="font-medium">{formatTime(step.timestamp)}</span>
|
||||||
{step.duration && (
|
{step.duration && (
|
||||||
<span className="mt-1 px-2 py-0.5 bg-secondary/50 rounded-full">
|
<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>
|
</CollapsibleTrigger>
|
||||||
<CollapsibleContent>
|
<CollapsibleContent>
|
||||||
<div className="p-5 bg-card/50 border-t border-border">
|
<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}
|
{step.content}
|
||||||
</div>
|
</div>
|
||||||
{step.duration && (
|
{step.duration && (
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ export const Layout: React.FC<LayoutProps> = ({
|
||||||
floatingAction
|
floatingAction
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
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 - 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 className="sticky top-0 z-30 h-16 flex items-center bg-background border-b border-border col-span-full">
|
||||||
{header}
|
{header}
|
||||||
|
|
@ -32,7 +32,7 @@ export const Layout: React.FC<LayoutProps> = ({
|
||||||
|
|
||||||
{/* Sidebar - hidden on mobile, visible on tablet/desktop */}
|
{/* Sidebar - hidden on mobile, visible on tablet/desktop */}
|
||||||
{sidebar && (
|
{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}
|
{sidebar}
|
||||||
</aside>
|
</aside>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -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",
|
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",
|
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",
|
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: {
|
defaultVariants: {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue