From 0b95d7d4a218ce2a6ef23baea3f999cd0e29c171 Mon Sep 17 00:00:00 2001 From: menzelj Date: Wed, 24 Jun 2026 11:17:32 +0000 Subject: [PATCH] Dashboard: surface fleet load errors instead of infinite skeletons (0.38.1) The cockpit cards gated purely on `fleet.data`, so any failed /api/dashboard/fleet request (e.g. a stale backend returning 404, or a 500) left the new components stuck on skeletons forever. Render a clear error banner with the API message and a Retry button when the query errors with no data, so the actual cause is visible. Co-Authored-By: Claude Opus 4.8 --- backend/version.py | 2 +- frontend/package.json | 2 +- frontend/src/pages/Dashboard.tsx | 70 ++++++++++++++++++++------------ 3 files changed, 46 insertions(+), 28 deletions(-) diff --git a/backend/version.py b/backend/version.py index a779e43..1b3e05a 100644 --- a/backend/version.py +++ b/backend/version.py @@ -1,3 +1,3 @@ """Single source of truth for the StackPilot release version.""" -APP_VERSION = "0.38.0" +APP_VERSION = "0.38.1" diff --git a/frontend/package.json b/frontend/package.json index 018c50a..3ed346d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "stackpilot-frontend", "private": true, - "version": "0.38.0", + "version": "0.38.1", "type": "module", "scripts": { "dev": "vite", diff --git a/frontend/src/pages/Dashboard.tsx b/frontend/src/pages/Dashboard.tsx index 049e76a..3521d49 100644 --- a/frontend/src/pages/Dashboard.tsx +++ b/frontend/src/pages/Dashboard.tsx @@ -1,6 +1,6 @@ import { useState } from "react"; import { useQuery, useQueryClient } from "@tanstack/react-query"; -import { Clock, RefreshCw } from "lucide-react"; +import { AlertTriangle, Clock, RefreshCw } from "lucide-react"; import { toast } from "sonner"; import { Card } from "@/components/ui"; import { HostHeader } from "@/components/hosts/HostHeader"; @@ -66,33 +66,51 @@ export function Dashboard() { - {/* ---- Needs attention ---- */} - - - {/* ---- Fleet KPIs ---- */} - {fleet.data ? ( - - ) : ( -
- {Array.from({ length: 6 }).map((_, i) => ( -
- ))} + {/* ---- Fleet cockpit (attention + KPIs + status + hosts) ---- */} + {fleet.isError && !fleet.data ? ( +
+ + + Couldn’t load fleet overview: {apiErrorMessage(fleet.error)} + +
- )} + ) : ( + <> + {/* Needs attention */} + - {/* ---- Status + hosts ---- */} -
- {fleet.data ? ( - - ) : ( -
- )} - {fleet.data ? ( - - ) : ( -
- )} -
+ {/* Fleet KPIs */} + {fleet.data ? ( + + ) : ( +
+ {Array.from({ length: 6 }).map((_, i) => ( +
+ ))} +
+ )} + + {/* Status + hosts */} +
+ {fleet.data ? ( + + ) : ( +
+ )} + {fleet.data ? ( + + ) : ( +
+ )} +
+ + )} {/* ---- Local host stacks ---- */}