load thread page no-side-panel skeleton fix

This commit is contained in:
marko-kraemer 2025-05-07 03:23:23 +02:00
parent 9a5bcd00a7
commit 6bffd6d2c4
3 changed files with 57 additions and 17 deletions

View File

@ -40,7 +40,7 @@ MODEL_NAME_ALIASES = {
"gpt-4": "openai/gpt-4",
"gemini-flash-2.5": "openrouter/google/gemini-2.5-flash-preview",
"grok-3": "xai/grok-3-fast-latest",
"deepseek": "deepseek/deepseek-chat",
"deepseek": "openrouter/deepseek/deepseek-chat",
"grok-3-mini": "xai/grok-3-mini-fast-beta",
"qwen3": "openrouter/qwen/qwen3-235b-a22b",
@ -52,7 +52,7 @@ MODEL_NAME_ALIASES = {
"openai/gpt-4": "openai/gpt-4",
"openrouter/google/gemini-2.5-flash-preview": "openrouter/google/gemini-2.5-flash-preview",
"xai/grok-3-fast-latest": "xai/grok-3-fast-latest",
"deepseek/deepseek-chat": "deepseek/deepseek-chat",
"deepseek/deepseek-chat": "openrouter/deepseek/deepseek-chat",
"xai/grok-3-mini-fast-beta": "xai/grok-3-mini-fast-beta",
}

View File

@ -1370,7 +1370,7 @@ export default function ThreadPage({
return (
<div className="flex h-screen">
<div
className={`flex flex-col flex-1 overflow-hidden transition-all duration-200 ease-in-out ${isSidePanelOpen ? 'mr-[90%] sm:mr-[450px] md:mr-[500px] lg:mr-[550px] xl:mr-[650px]' : ''}`}
className={`flex flex-col flex-1 overflow-hidden transition-all duration-200 ease-in-out`}
>
{/* Skeleton Header */}
<div className="border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
@ -1465,16 +1465,7 @@ export default function ThreadPage({
</div>
</div>
{/* Skeleton Side Panel (closed state) */}
<div className={`hidden ${isSidePanelOpen ? 'block' : ''}`}>
<div className="h-screen w-[450px] border-l">
<div className="p-4">
<Skeleton className="h-8 w-32 mb-4" />
<Skeleton className="h-20 w-full rounded-md mb-4" />
<Skeleton className="h-40 w-full rounded-md" />
</div>
</div>
</div>
{/* Skeleton Side Panel (hidden during loading) */}
</div>
);
}
@ -1483,7 +1474,7 @@ export default function ThreadPage({
return (
<div className="flex h-screen">
<div
className={`flex flex-col flex-1 overflow-hidden transition-all duration-200 ease-in-out ${isSidePanelOpen ? 'mr-[90%] sm:mr-[450px] md:mr-[500px] lg:mr-[550px] xl:mr-[650px]' : ''}`}
className={`flex flex-col flex-1 overflow-hidden transition-all duration-200 ease-in-out ${(isSidePanelOpen && initialLoadCompleted.current) ? 'mr-[90%] sm:mr-[450px] md:mr-[500px] lg:mr-[550px] xl:mr-[650px]' : ''}`}
>
<SiteHeader
threadId={threadId}
@ -1512,13 +1503,14 @@ export default function ThreadPage({
</div>
</div>
<ToolCallSidePanel
isOpen={isSidePanelOpen}
isOpen={isSidePanelOpen && initialLoadCompleted.current}
onClose={() => setIsSidePanelOpen(false)}
toolCalls={[]}
currentIndex={0}
onNavigate={handleSidePanelNavigate}
project={project || undefined}
agentStatus="error"
isLoading={!initialLoadCompleted.current || isLoading}
/>
</div>
);
@ -1527,7 +1519,7 @@ export default function ThreadPage({
return (
<div className="flex h-screen">
<div
className={`flex flex-col flex-1 overflow-hidden transition-all duration-200 ease-in-out ${isSidePanelOpen ? 'mr-[90%] sm:mr-[450px] md:mr-[500px] lg:mr-[550px] xl:mr-[650px]' : ''}`}
className={`flex flex-col flex-1 overflow-hidden transition-all duration-200 ease-in-out ${(!initialLoadCompleted.current || isSidePanelOpen) ? 'mr-[90%] sm:mr-[450px] md:mr-[500px] lg:mr-[550px] xl:mr-[650px]' : ''}`}
>
<SiteHeader
threadId={threadId}
@ -1935,7 +1927,7 @@ export default function ThreadPage({
</div>
<ToolCallSidePanel
isOpen={isSidePanelOpen}
isOpen={isSidePanelOpen && initialLoadCompleted.current}
onClose={() => {
setIsSidePanelOpen(false);
userClosedPanelRef.current = true;
@ -1949,6 +1941,7 @@ export default function ThreadPage({
project={project || undefined}
renderAssistantMessage={toolViewAssistant}
renderToolResult={toolViewResult}
isLoading={!initialLoadCompleted.current || isLoading}
/>
{sandboxId && (

View File

@ -4,6 +4,7 @@ import { Project } from '@/lib/api';
import { getToolIcon } from '@/components/thread/utils';
import React from 'react';
import { Slider } from '@/components/ui/slider';
import { Skeleton } from '@/components/ui/skeleton';
import { ApiMessageType } from '@/components/thread/types';
import { CircleDashed, X, ChevronLeft, ChevronRight } from 'lucide-react';
import { cn } from '@/lib/utils';
@ -217,6 +218,7 @@ interface ToolCallSidePanelProps {
toolContent?: string,
isSuccess?: boolean,
) => React.ReactNode;
isLoading?: boolean;
}
export function ToolCallSidePanel({
@ -230,6 +232,7 @@ export function ToolCallSidePanel({
project,
renderAssistantMessage,
renderToolResult,
isLoading = false,
}: ToolCallSidePanelProps) {
// Move hooks outside of conditional
const [dots, setDots] = React.useState('');
@ -308,6 +311,50 @@ export function ToolCallSidePanel({
if (!isOpen) return null;
if (isLoading) {
return (
<div
className={cn(
'fixed inset-y-0 right-0 border-l flex flex-col z-30 h-screen transition-all duration-200 ease-in-out',
isMobile
? 'w-full'
: 'w-[90%] sm:w-[450px] md:w-[500px] lg:w-[550px] xl:w-[650px]',
!isOpen && 'translate-x-full',
)}
>
<div className="flex-1 flex flex-col overflow-hidden bg-background">
<div className="flex flex-col h-full">
<div className="pt-4 pl-4 pr-4">
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<h2 className="text-lg font-medium text-zinc-900 dark:text-zinc-100">
Suna's Computer
</h2>
</div>
<Button
variant="ghost"
size="icon"
onClick={onClose}
className="h-8 w-8"
>
<X className="h-4 w-4" />
</Button>
</div>
</div>
<div className="flex-1 p-4 overflow-auto">
<div className="space-y-4">
<Skeleton className="h-8 w-32" />
<Skeleton className="h-20 w-full rounded-md" />
<Skeleton className="h-40 w-full rounded-md" />
<Skeleton className="h-20 w-full rounded-md" />
</div>
</div>
</div>
</div>
</div>
);
}
const renderContent = () => {
if (!currentToolCall) {
return (