FN-5886: show empty usage state after empty fetch

Handle empty usage responses without leaving the panel in its loading skeleton.

- add a hasFetched flag to useUsageData so the UI can distinguish initial loading from an empty completed response
- update UsageIndicator to render the skeleton only before the first fetch completes and show the empty state afterward
- refresh dashboard hook and component tests to cover empty fetches, refresh behavior, and the new loading semantics

Files changed:
 .../dashboard/app/components/UsageIndicator.tsx    |  19 +-
 .../components/__tests__/UsageIndicator.test.tsx   | 395 +++++++++++----------
 .../app/hooks/__tests__/useUsageData.test.ts       |  42 ++-
 packages/dashboard/app/hooks/useUsageData.ts       |   5 +
 4 files changed, 245 insertions(+), 216 deletions(-)

Fusion-Task-Id: FN-5886

Fusion-Task-Lineage: 8fa901a9-3167-4e33-a082-e5de95f692da
This commit is contained in:
gsxdsm
2026-06-02 09:24:42 -07:00
parent fa68edf9fa
commit cf3b9a575e
4 changed files with 245 additions and 216 deletions

View File

@@ -7,6 +7,7 @@ interface UsageDataState {
loading: boolean;
error: string | null;
lastUpdated: Date | null;
hasFetched: boolean;
}
interface UseUsageDataOptions {
@@ -34,6 +35,7 @@ export function useUsageData(options: UseUsageDataOptions = {}) {
loading: true,
error: null,
lastUpdated: null,
hasFetched: false,
});
const pollRef = useRef<ReturnType<typeof setInterval> | null>(null);
@@ -57,6 +59,7 @@ export function useUsageData(options: UseUsageDataOptions = {}) {
loading: false,
error: null,
lastUpdated: new Date(),
hasFetched: true,
});
} catch (err) {
// Don't update state if the request was aborted
@@ -66,6 +69,7 @@ export function useUsageData(options: UseUsageDataOptions = {}) {
...prev,
loading: false,
error: getErrorMessage(err) || "Failed to fetch usage data",
hasFetched: true,
}));
}
}, []);
@@ -112,6 +116,7 @@ export function useUsageData(options: UseUsageDataOptions = {}) {
loading: state.loading,
error: state.error,
lastUpdated: state.lastUpdated,
hasFetched: state.hasFetched,
refresh,
};
}