diff --git a/frontend/common/dist/styles/global.css b/frontend/common/dist/styles/global.css index 908bb9f..3b8e0f9 100644 --- a/frontend/common/dist/styles/global.css +++ b/frontend/common/dist/styles/global.css @@ -812,6 +812,9 @@ video { -moz-user-select: none; user-select: none; } +.resize { + resize: both; +} .grid-cols-1 { grid-template-columns: repeat(1, minmax(0, 1fr)); } @@ -1025,9 +1028,6 @@ video { -webkit-background-clip: text; background-clip: text; } -.p-2 { - padding: 0.5rem; -} .p-3 { padding: 0.75rem; } diff --git a/frontend/common/src/components/DefaultAgentScreen.tsx b/frontend/common/src/components/DefaultAgentScreen.tsx index 8537e1b..fb34934 100644 --- a/frontend/common/src/components/DefaultAgentScreen.tsx +++ b/frontend/common/src/components/DefaultAgentScreen.tsx @@ -42,6 +42,22 @@ export const DefaultAgentScreen: React.FC = () => { } }, [sessions, selectedSessionId]); + // Close drawer when window resizes to desktop width + useEffect(() => { + const handleResize = () => { + // Check if we're at desktop size (corresponds to md: breakpoint in Tailwind) + if (window.innerWidth >= 768 && isDrawerOpen) { + setIsDrawerOpen(false); + } + }; + + // Add event listener + window.addEventListener('resize', handleResize); + + // Clean up event listener on component unmount + return () => window.removeEventListener('resize', handleResize); + }, [isDrawerOpen]); + // Filter steps for selected session const selectedSessionSteps = selectedSessionId ? allSteps.filter(step => sessions.find(s => s.id === selectedSessionId)?.steps.some(s => s.id === step.id)) diff --git a/frontend/common/src/components/SessionDrawer.tsx b/frontend/common/src/components/SessionDrawer.tsx index 1343a63..2c2a1f6 100644 --- a/frontend/common/src/components/SessionDrawer.tsx +++ b/frontend/common/src/components/SessionDrawer.tsx @@ -6,9 +6,9 @@ import { SheetTitle, SheetClose } from './ui/sheet'; -import { ScrollArea } from './ui/scroll-area'; import { AgentSession } from '../utils/types'; import { getSampleAgentSessions } from '../utils/sample-data'; +import { SessionList } from './SessionList'; interface SessionDrawerProps { onSelectSession?: (sessionId: string) => void; @@ -25,30 +25,6 @@ export const SessionDrawer: React.FC = ({ isOpen = false, onClose }) => { - // Get status color - const getStatusColor = (status: string) => { - switch (status) { - case 'active': - return 'bg-blue-500'; - case 'completed': - return 'bg-green-500'; - case 'error': - return 'bg-red-500'; - default: - return 'bg-gray-500'; - } - }; - - // Format timestamp - const formatDate = (date: Date) => { - return date.toLocaleDateString([], { - month: 'short', - day: 'numeric', - hour: '2-digit', - minute: '2-digit' - }); - }; - return ( = ({ Sessions - -
- {sessions.map((session) => ( - - - - ))} -
-
+
); diff --git a/frontend/common/src/components/SessionList.tsx b/frontend/common/src/components/SessionList.tsx new file mode 100644 index 0000000..d517a23 --- /dev/null +++ b/frontend/common/src/components/SessionList.tsx @@ -0,0 +1,91 @@ +import React from 'react'; +import { ScrollArea } from './ui/scroll-area'; +import { AgentSession } from '../utils/types'; +import { getSampleAgentSessions } from '../utils/sample-data'; + +interface SessionListProps { + onSelectSession?: (sessionId: string) => void; + currentSessionId?: string; + sessions?: AgentSession[]; + className?: string; + wrapperComponent?: React.ElementType; + closeAction?: React.ReactNode; +} + +export const SessionList: React.FC = ({ + onSelectSession, + currentSessionId, + sessions = getSampleAgentSessions(), + className = '', + wrapperComponent: WrapperComponent = 'button', + closeAction +}) => { + // Get status color + const getStatusColor = (status: string) => { + switch (status) { + case 'active': + return 'bg-blue-500'; + case 'completed': + return 'bg-green-500'; + case 'error': + return 'bg-red-500'; + default: + return 'bg-gray-500'; + } + }; + + // Format timestamp + const formatDate = (date: Date) => { + return date.toLocaleDateString([], { + month: 'short', + day: 'numeric', + hour: '2-digit', + minute: '2-digit' + }); + }; + + return ( + +
+ {sessions.map((session) => { + const buttonContent = ( + <> +
+
+
{session.name}
+
+ {session.steps.length} steps • {formatDate(session.updated)} +
+
+ {session.status} +
+
+ + ); + + return React.createElement( + WrapperComponent, + { + key: session.id, + onClick: () => onSelectSession?.(session.id), + className: `w-full flex items-start p-3 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); + } + })} + + ) : buttonContent + ); + })} +
+ + ); +}; diff --git a/frontend/common/src/components/SessionSidebar.tsx b/frontend/common/src/components/SessionSidebar.tsx index 0b52e8c..6ce00a1 100644 --- a/frontend/common/src/components/SessionSidebar.tsx +++ b/frontend/common/src/components/SessionSidebar.tsx @@ -1,7 +1,7 @@ import React from 'react'; -import { ScrollArea } from './ui/scroll-area'; import { AgentSession } from '../utils/types'; import { getSampleAgentSessions } from '../utils/sample-data'; +import { SessionList } from './SessionList'; interface SessionSidebarProps { onSelectSession?: (sessionId: string) => void; @@ -16,59 +16,17 @@ export const SessionSidebar: React.FC = ({ sessions = getSampleAgentSessions(), className = '' }) => { - // Get status color - const getStatusColor = (status: string) => { - switch (status) { - case 'active': - return 'bg-blue-500'; - case 'completed': - return 'bg-green-500'; - case 'error': - return 'bg-red-500'; - default: - return 'bg-gray-500'; - } - }; - - // Format timestamp - const formatDate = (date: Date) => { - return date.toLocaleDateString([], { - month: 'short', - day: 'numeric', - hour: '2-digit', - minute: '2-digit' - }); - }; - return (

Sessions

- -
- {sessions.map((session) => ( - - ))} -
-
+
); }; \ No newline at end of file