Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 76dee02

Browse files
committed
feat(site/src/pages/OperatorDiagnosticPage): add refetch loading indicator
When filters change, the page refetches data while keeping stale data visible via keepPreviousData. Previously there was no visual feedback during the refetch. Now a spinner with 'Updating...' text appears below the toolbar and the data sections dim to 60% opacity until the new data arrives. The initial skeleton loading state is unchanged.
1 parent bf1dd58 commit 76dee02

3 files changed

Lines changed: 48 additions & 13 deletions

File tree

site/src/pages/OperatorDiagnosticPage/OperatorDiagnosticPage.stories.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const meta: Meta<typeof OperatorDiagnosticPageView> = {
1616
onUserSelect: () => {},
1717
onTimeWindowChange: () => {},
1818
isDemo: true,
19+
isFetching: false,
1920
statusFilter: "all",
2021
onStatusFilterChange: () => {},
2122
workspaceFilter: "all",
@@ -66,6 +67,15 @@ export const Loading: Story = {
6667
},
6768
};
6869

70+
export const Refetching: Story = {
71+
args: {
72+
data: SCENARIO_DEVICE_SLEEP,
73+
isLoading: false,
74+
isFetching: true,
75+
username: "sarah-chen",
76+
},
77+
};
78+
6979
export const Empty: Story = {
7080
args: {
7181
data: undefined,

site/src/pages/OperatorDiagnosticPage/OperatorDiagnosticPage.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ const OperatorDiagnosticPage: FC = () => {
4343
<OperatorDiagnosticPageView
4444
data={diagnosticQuery.data}
4545
isLoading={diagnosticQuery.isLoading}
46+
isFetching={diagnosticQuery.isFetching}
4647
username={username}
4748
onUserSelect={handleUserSelect}
4849
onTimeWindowChange={setHours}

site/src/pages/OperatorDiagnosticPage/OperatorDiagnosticPageView.tsx

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ import {
1515
PageHeaderTitle,
1616
} from "components/PageHeader/PageHeader";
1717
import { Skeleton } from "components/Skeleton/Skeleton";
18+
import { Spinner } from "components/Spinner/Spinner";
1819
import type { FC } from "react";
20+
import { cn } from "utils/cn";
1921
import { Link } from "react-router";
2022
import { DiagnosticSummaryBar } from "./DiagnosticSummaryBar";
2123
import { PatternBanner } from "./PatternBanner";
@@ -26,6 +28,7 @@ import { UserSelector } from "./UserSelector";
2628
interface OperatorDiagnosticPageViewProps {
2729
data: UserDiagnosticResponse | undefined;
2830
isLoading: boolean;
31+
isFetching: boolean;
2932
username: string;
3033
onUserSelect: (username: string) => void;
3134
onTimeWindowChange: (hours: number) => void;
@@ -44,6 +47,7 @@ export const OperatorDiagnosticPageView: FC<
4447
> = ({
4548
data,
4649
isLoading,
50+
isFetching,
4751
username,
4852
onUserSelect,
4953
onTimeWindowChange,
@@ -117,21 +121,36 @@ export const OperatorDiagnosticPageView: FC<
117121
</div>
118122
</div>
119123

120-
{/* Stats bar */}
121-
{data && (
122-
<DiagnosticSummaryBar
123-
summary={data.summary}
124-
timeWindow={data.time_window}
125-
/>
126-
)}
127-
128-
{/* Pattern banner */}
129-
{data && data.patterns.length > 0 && (
130-
<div className="mt-4">
131-
<PatternBanner patterns={data.patterns} />
124+
{/* Refetch indicator */}
125+
{isFetching && !isLoading && (
126+
<div className="flex items-center gap-2 text-content-secondary text-sm mb-2">
127+
<Spinner size="sm" loading />
128+
<span>Updating...</span>
132129
</div>
133130
)}
134131

132+
{/* Stats bar */}
133+
<div
134+
className={cn(
135+
"transition-opacity",
136+
isFetching && !isLoading && "opacity-60",
137+
)}
138+
>
139+
{data && (
140+
<DiagnosticSummaryBar
141+
summary={data.summary}
142+
timeWindow={data.time_window}
143+
/>
144+
)}
145+
146+
{/* Pattern banner */}
147+
{data && data.patterns.length > 0 && (
148+
<div className="mt-4">
149+
<PatternBanner patterns={data.patterns} />
150+
</div>
151+
)}
152+
</div>
153+
135154
{/* Loading */}
136155
{isLoading && (
137156
<div className="flex flex-col gap-4">
@@ -143,7 +162,12 @@ export const OperatorDiagnosticPageView: FC<
143162

144163
{/* Session list */}
145164
{data && (
146-
<div className="mt-4">
165+
<div
166+
className={cn(
167+
"mt-4 transition-opacity",
168+
isFetching && !isLoading && "opacity-60",
169+
)}
170+
>
147171
<SessionList
148172
workspaces={data.workspaces}
149173
statusFilter={statusFilter}

0 commit comments

Comments
 (0)