diff --git a/src/features/decks/deck-column.tsx b/src/features/decks/deck-column.tsx
index 5719af0..6758670 100644
--- a/src/features/decks/deck-column.tsx
+++ b/src/features/decks/deck-column.tsx
@@ -1,6 +1,7 @@
import { Icon } from "#/components/icon";
import { Badge } from "#/components/ui/badge";
import { Button } from "#/components/ui/button";
+import { Skeleton } from "#/components/ui/skeleton";
import {
DropdownMenu,
DropdownMenuContent,
@@ -22,6 +23,7 @@ import { describeSource } from "./source-description";
export function ResearchColumn({
column,
connectionLabel,
+ connectionLoading = false,
onEdit,
onRemove,
onMove,
@@ -32,6 +34,7 @@ export function ResearchColumn({
}: {
column: DeckColumn;
connectionLabel?: string;
+ connectionLoading?: boolean;
onEdit: () => void;
onRemove: () => void;
onMove: (direction: -1 | 1) => void;
@@ -112,9 +115,13 @@ export function ResearchColumn({
-
- {connectionLabel ?? "Connection not found"}
-
+ {connectionLoading ? (
+
+ ) : (
+
+ {connectionLabel ?? "Connection not found"}
+
+ )}
{sourceDescription.label}
diff --git a/src/features/decks/deck-page.tsx b/src/features/decks/deck-page.tsx
index 21f8573..8db578a 100644
--- a/src/features/decks/deck-page.tsx
+++ b/src/features/decks/deck-page.tsx
@@ -15,6 +15,7 @@ import {
EmptyTitle,
} from "#/components/ui/empty";
import { Input } from "#/components/ui/input";
+import { Skeleton } from "#/components/ui/skeleton";
import { loadConnections } from "#/features/connections/server-functions";
import { syncResearchDeck } from "#/features/research/research-deck-sync";
import { ResearchPanel } from "#/features/research/research-panel";
@@ -27,6 +28,7 @@ import { type ColumnRegistry, useColumnTools } from "./column-tools";
import { ResearchColumn } from "./deck-column";
import { DeckSwitcher } from "./deck-switcher";
import { type DeckColumn, MAX_COLUMNS, moveColumn } from "./model";
+import { ResearchDeckSkeleton } from "./research-deck-skeleton";
import { useDeck } from "./use-deck";
import { useDeckTools } from "./webmcp-tools";
@@ -202,10 +204,19 @@ export function DeckPage() {
>
-
{deck.title}
-
- {deck.columns.length} / {MAX_COLUMNS} columns
-
+ {ready ? (
+ <>
+
{deck.title}
+
+ {deck.columns.length} / {MAX_COLUMNS} columns
+
+ >
+ ) : (
+
+
+
+
+ )}
{deck.persisted ? (
@@ -260,11 +271,6 @@ export function DeckPage() {
) : null}
- {!ready ? (
-
- Loading decks…
-
- ) : null}
{profiles.isError ? (
Unable to load connection profiles.
@@ -288,7 +294,6 @@ export function DeckPage() {
{profiles.data.relayError}
) : null}
- {profiles.isPending ?
Loading connection profiles…
: null}
{!renaming && editing === null && !switcherEditing ? storageErrorNotice : null}
{renaming ? (
) : null}
+ {!ready && !storageError ?
: null}
{ready && deck.columns.length === 0 && editing === null ? (
@@ -388,6 +394,7 @@ export function DeckPage() {
key={`${deck.id}:${column.id}`}
registry={registry}
column={column}
+ connectionLoading={profiles.isPending}
citation={
citationNavigation.target?.deckId === deck.id &&
citationNavigation.target.column.id === column.id &&
diff --git a/src/features/decks/research-deck-skeleton.tsx b/src/features/decks/research-deck-skeleton.tsx
new file mode 100644
index 0000000..7ff003a
--- /dev/null
+++ b/src/features/decks/research-deck-skeleton.tsx
@@ -0,0 +1,27 @@
+import { Skeleton } from "#/components/ui/skeleton";
+import { ResearchPostSkeleton } from "./research-post-skeleton";
+
+export function ResearchDeckSkeleton() {
+ return (
+
+ {["first", "second", "third"].map((column) => (
+
+ ))}
+
+ );
+}