From d359c66aa1f0053d2fd6bfeb23461b26603dfb93 Mon Sep 17 00:00:00 2001 From: Zane Staggs Date: Sun, 13 Jul 2025 13:58:00 -0700 Subject: [PATCH] added loading state to home and fix jumpiness on settings models page --- .../components/sessions/SessionsInsights.tsx | 108 +++++++++++++++++- .../settings/models/ModelsSection.tsx | 17 ++- 2 files changed, 122 insertions(+), 3 deletions(-) diff --git a/ui/desktop/src/components/sessions/SessionsInsights.tsx b/ui/desktop/src/components/sessions/SessionsInsights.tsx index 84ebb69f7b..e42302b3f2 100644 --- a/ui/desktop/src/components/sessions/SessionsInsights.tsx +++ b/ui/desktop/src/components/sessions/SessionsInsights.tsx @@ -10,6 +10,7 @@ import { Button } from '../ui/button'; import { ChatSmart } from '../icons/'; import { motion, AnimatePresence } from 'framer-motion'; import { Goose } from '../icons/Goose'; +import { Skeleton } from '../ui/skeleton'; interface SessionInsightsType { totalSessions: number; @@ -114,8 +115,113 @@ export function SessionInsights() { .replace(/\//g, '/'); }; + // Render skeleton loader while data is loading + const renderSkeleton = () => ( +
+ {/* Header container with rounded bottom */} +
+
+ + + + +
+
+ + {/* Stats containers - full bleed with 2px gaps */} +
+ {/* Top row with three equal columns */} +
+ {/* Total Sessions Card Skeleton */} + + +
+ + Total sessions +
+
+
+ + {/* Average Duration Card Skeleton */} + + +
+ + Avg. chat length +
+
+
+ + {/* Total Tokens Card Skeleton */} + + +
+ + Total tokens +
+
+
+
+ + {/* Recent Chats Card Skeleton */} +
+ + +
+ + Recent chats + + +
+
+ {/* Skeleton chat items */} +
+
+ + +
+ +
+
+
+ + +
+ +
+
+
+ + +
+ +
+
+
+
+
+ + {/* Filler container - extends to fill remaining space */} +
+
+
+ ); + + // Show skeleton while loading, then show actual content if (!insights) { - return <>; + return renderSkeleton(); } return ( diff --git a/ui/desktop/src/components/settings/models/ModelsSection.tsx b/ui/desktop/src/components/settings/models/ModelsSection.tsx index f4abf1fa18..9d665d5b27 100644 --- a/ui/desktop/src/components/settings/models/ModelsSection.tsx +++ b/ui/desktop/src/components/settings/models/ModelsSection.tsx @@ -16,12 +16,14 @@ interface ModelsSectionProps { export default function ModelsSection({ setView }: ModelsSectionProps) { const [provider, setProvider] = useState(null); const [displayModelName, setDisplayModelName] = useState(''); + const [isLoading, setIsLoading] = useState(true); const { read, getProviders } = useConfig(); const { getCurrentModelDisplayName, getCurrentProviderDisplayName } = useModelAndProvider(); // Function to load model data const loadModelData = useCallback(async () => { try { + setIsLoading(true); const gooseProvider = (await read('GOOSE_PROVIDER', false)) as string; const providers = await getProviders(true); @@ -50,6 +52,8 @@ export default function ModelsSection({ setView }: ModelsSectionProps) { } } catch (error) { console.error('Error loading model data:', error); + } finally { + setIsLoading(false); } }, [read, getProviders, getCurrentModelDisplayName, getCurrentProviderDisplayName]); @@ -62,8 +66,17 @@ export default function ModelsSection({ setView }: ModelsSectionProps) {
-

{displayModelName}

-

{provider}

+ {isLoading ? ( + <> +
+
+ + ) : ( +
+

{displayModelName}

+

{provider}

+
+ )}