diff --git a/frontend/src/app/(dashboard)/projects/[projectId]/thread/[threadId]/page.tsx b/frontend/src/app/(dashboard)/projects/[projectId]/thread/[threadId]/page.tsx index 42eb85fd..c278adcf 100644 --- a/frontend/src/app/(dashboard)/projects/[projectId]/thread/[threadId]/page.tsx +++ b/frontend/src/app/(dashboard)/projects/[projectId]/thread/[threadId]/page.tsx @@ -52,6 +52,7 @@ export default function ThreadPage({ const [debugMode, setDebugMode] = useState(false); const [initialPanelOpenAttempted, setInitialPanelOpenAttempted] = useState(false); const [selectedAgentId, setSelectedAgentId] = useState(undefined); + const [isSidePanelAnimating, setIsSidePanelAnimating] = useState(false); // Refs const messagesEndRef = useRef(null); @@ -533,6 +534,18 @@ export default function ThreadPage({ } }, [streamingToolCall, handleStreamingToolCall]); + useEffect(() => { + if (isSidePanelOpen) { + setIsSidePanelAnimating(true); + const timer = setTimeout(() => setIsSidePanelAnimating(false), 200); // Match transition duration + return () => clearTimeout(timer); + } else { + setIsSidePanelAnimating(true); + const timer = setTimeout(() => setIsSidePanelAnimating(false), 200); // Match transition duration + return () => clearTimeout(timer); + } + }, [isSidePanelOpen]); + if (!initialLoadCompleted || isLoading) { return ; } @@ -616,6 +629,7 @@ export default function ThreadPage({ isMobile={isMobile} initialLoadCompleted={initialLoadCompleted} agentName={agent && agent.name} + disableInitialAnimation={!initialLoadCompleted && toolCalls.length > 0} > {/* {workflowId && (
@@ -641,7 +655,8 @@ export default function ThreadPage({
@@ -117,6 +119,7 @@ export function ThreadLayout({ isLoading={!initialLoadCompleted || isLoading} onFileClick={onViewFiles} agentName={agentName} + disableInitialAnimation={disableInitialAnimation} /> {sandboxId && ( diff --git a/frontend/src/components/thread/content/ThreadSkeleton.tsx b/frontend/src/components/thread/content/ThreadSkeleton.tsx index 01dc2c78..59e63484 100644 --- a/frontend/src/components/thread/content/ThreadSkeleton.tsx +++ b/frontend/src/components/thread/content/ThreadSkeleton.tsx @@ -1,5 +1,7 @@ import React from 'react'; import { Skeleton } from '@/components/ui/skeleton'; +import { ChatInput } from '@/components/thread/chat-input/chat-input'; +import { cn } from '@/lib/utils'; interface ThreadSkeletonProps { isSidePanelOpen?: boolean; @@ -12,6 +14,17 @@ export function ThreadSkeleton({ showHeader = true, messageCount = 3, }: ThreadSkeletonProps) { + // Mock handlers for the ChatInput component + const handleSubmit = (message: string) => { + // No-op for skeleton + console.log('Skeleton submit:', message); + }; + + const handleChange = (value: string) => { + // No-op for skeleton + console.log('Skeleton change:', value); + }; + return (
+
{/* Generate multiple message skeletons based on messageCount */} {Array.from({ length: messageCount }).map((_, index) => ( @@ -102,20 +115,44 @@ export function ThreadSkeleton({
-
- {/* Skeleton Side Panel (closed state) */} - {isSidePanelOpen && ( -
-
-
- - - -
+ {/* ChatInput - Inside the left div, positioned at bottom with exact same styling */} +
+
+
- )} +
+ + {/* Side Panel - Always visible in skeleton with exact responsive widths */} +
+
+
+ + + +
+
+
); } \ No newline at end of file diff --git a/frontend/src/components/thread/tool-call-side-panel.tsx b/frontend/src/components/thread/tool-call-side-panel.tsx index 04994bb8..f1625e87 100644 --- a/frontend/src/components/thread/tool-call-side-panel.tsx +++ b/frontend/src/components/thread/tool-call-side-panel.tsx @@ -48,6 +48,7 @@ interface ToolCallSidePanelProps { isLoading?: boolean; agentName?: string; onFileClick?: (filePath: string) => void; + disableInitialAnimation?: boolean; } interface ToolCallSnapshot { @@ -73,6 +74,7 @@ export function ToolCallSidePanel({ externalNavigateToIndex, agentName, onFileClick, + disableInitialAnimation, }: ToolCallSidePanelProps) { const [dots, setDots] = React.useState(''); const [internalIndex, setInternalIndex] = React.useState(0); @@ -678,11 +680,11 @@ export function ToolCallSidePanel({