perf: add loading.tsx skeletons for observability detail pages
Add Suspense-boundary loading skeletons for the LLM Calls list page and the LLM Call detail page. These pages lack internal Suspense boundaries and make database queries at the server component level, so Next.js loading.tsx provides instant streaming of the shell while data fetches resolve. The traces and trace detail pages already have internal Suspense boundaries and don't need this.
This commit is contained in:
parent
f96fba76f3
commit
d6cab273bc
2 changed files with 85 additions and 0 deletions
48
js/cf-webapp/src/app/observability/llm-call/[id]/loading.tsx
Normal file
48
js/cf-webapp/src/app/observability/llm-call/[id]/loading.tsx
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
export default function LLMCallDetailLoading() {
|
||||
return (
|
||||
<div className="container mx-auto px-4 py-8">
|
||||
{/* Header */}
|
||||
<div className="mb-8">
|
||||
<div className="h-4 w-32 bg-gray-200 dark:bg-gray-700 rounded mb-4 animate-pulse" />
|
||||
<div className="h-8 w-48 bg-gray-200 dark:bg-gray-700 rounded mb-3 animate-pulse" />
|
||||
<div className="space-y-2">
|
||||
<div className="h-6 w-80 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" />
|
||||
<div className="h-6 w-96 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" />
|
||||
</div>
|
||||
</div>
|
||||
{/* Summary Cards */}
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-5 mb-8">
|
||||
{[1, 2, 3, 4].map(i => (
|
||||
<div
|
||||
key={i}
|
||||
className="bg-white dark:bg-gray-800 rounded-lg shadow p-6 border border-gray-200 dark:border-gray-700"
|
||||
>
|
||||
<div className="h-4 w-20 bg-gray-200 dark:bg-gray-700 rounded mb-2 animate-pulse" />
|
||||
<div className="h-8 w-24 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
{/* Metadata */}
|
||||
<div className="bg-white dark:bg-gray-800 rounded-lg shadow p-6 mb-8 border border-gray-200 dark:border-gray-700">
|
||||
<div className="h-6 w-28 bg-gray-200 dark:bg-gray-700 rounded mb-4 animate-pulse" />
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
{[1, 2, 3, 4, 5, 6].map(i => (
|
||||
<div key={i}>
|
||||
<div className="h-4 w-24 bg-gray-200 dark:bg-gray-700 rounded mb-2 animate-pulse" />
|
||||
<div className="h-5 w-36 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
{/* Prompt skeletons */}
|
||||
<div className="bg-white dark:bg-gray-800 rounded-lg shadow p-6 mb-8 border border-gray-200 dark:border-gray-700">
|
||||
<div className="h-6 w-36 bg-gray-200 dark:bg-gray-700 rounded mb-4 animate-pulse" />
|
||||
<div className="h-48 bg-gray-100 dark:bg-gray-900 rounded animate-pulse" />
|
||||
</div>
|
||||
<div className="bg-white dark:bg-gray-800 rounded-lg shadow p-6 mb-8 border border-gray-200 dark:border-gray-700">
|
||||
<div className="h-6 w-32 bg-gray-200 dark:bg-gray-700 rounded mb-4 animate-pulse" />
|
||||
<div className="h-48 bg-gray-100 dark:bg-gray-900 rounded animate-pulse" />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
37
js/cf-webapp/src/app/observability/llm-calls/loading.tsx
Normal file
37
js/cf-webapp/src/app/observability/llm-calls/loading.tsx
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
export default function LLMCallsLoading() {
|
||||
return (
|
||||
<div className="container mx-auto p-6">
|
||||
<div className="mb-8">
|
||||
<div className="flex items-center justify-between gap-4 mb-2">
|
||||
<div className="h-8 w-32 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" />
|
||||
<div className="flex items-center gap-2 flex-1 max-w-3xl">
|
||||
<div className="flex-1 h-10 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" />
|
||||
<div className="w-32 h-10 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" />
|
||||
<div className="w-32 h-10 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" />
|
||||
<div className="w-32 h-10 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" />
|
||||
<div className="w-20 h-10 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="h-4 w-80 bg-gray-200 dark:bg-gray-700 rounded animate-pulse mt-2" />
|
||||
</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-4 gap-5 mb-8">
|
||||
{[1, 2, 3, 4].map(i => (
|
||||
<div
|
||||
key={i}
|
||||
className="bg-white dark:bg-gray-800 rounded-lg shadow p-6 border border-gray-200 dark:border-gray-700"
|
||||
>
|
||||
<div className="h-4 w-24 bg-gray-200 dark:bg-gray-700 rounded mb-2 animate-pulse" />
|
||||
<div className="h-8 w-16 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="bg-white dark:bg-gray-800 rounded-lg shadow border border-gray-200 dark:border-gray-700">
|
||||
<div className="p-4 space-y-3">
|
||||
{[1, 2, 3, 4, 5, 6, 7, 8].map(i => (
|
||||
<div key={i} className="h-12 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Loading…
Reference in a new issue