Standardise loading state naming across dashboard hooks

This commit is contained in:
2026-04-21 19:12:43 +02:00
parent 094fb4fece
commit b3eb5dc6ec
9 changed files with 25 additions and 25 deletions

View File

@@ -399,7 +399,7 @@ const source = timeRange === "24h" ? "fail2ban" : "archive";
--- ---
### TASK-020 — Standardise `loading` vs `isLoading` naming across hooks ### TASK-020 — Standardise `loading` vs `isLoading` naming across hooks (done)
**Where found:** Dashboard and country-data hooks (`useBans`, `useBanTrend`, `useDashboardCountryData`) return `isLoading`. All other hooks (`useActiveBans`, `useJails`, `useBlocklists`, `useFilterList`, `useActionList`, etc.) return `loading`. **Where found:** Dashboard and country-data hooks (`useBans`, `useBanTrend`, `useDashboardCountryData`) return `isLoading`. All other hooks (`useActiveBans`, `useJails`, `useBlocklists`, `useFilterList`, `useActionList`, etc.) return `loading`.

View File

@@ -200,7 +200,7 @@ export const BanTrendChart = memo(function BanTrendChart({
source = "fail2ban", source = "fail2ban",
}: BanTrendChartProps): React.JSX.Element { }: BanTrendChartProps): React.JSX.Element {
const styles = useStyles(); const styles = useStyles();
const { buckets, isLoading, error, reload } = useBanTrend(timeRange, origin, source); const { buckets, loading, error, reload } = useBanTrend(timeRange, origin, source);
const isEmpty = buckets.every((b) => b.count === 0); const isEmpty = buckets.every((b) => b.count === 0);
const entries = buildEntries(buckets, timeRange); const entries = buildEntries(buckets, timeRange);
@@ -227,7 +227,7 @@ export const BanTrendChart = memo(function BanTrendChart({
return ( return (
<ChartStateWrapper <ChartStateWrapper
isLoading={isLoading} isLoading={loading}
error={error} error={error}
onRetry={reload} onRetry={reload}
isEmpty={isEmpty} isEmpty={isEmpty}

View File

@@ -134,7 +134,7 @@ export const JailDistributionChart = memo(function JailDistributionChart({
origin, origin,
}: JailDistributionChartProps): React.JSX.Element { }: JailDistributionChartProps): React.JSX.Element {
const styles = useStyles(); const styles = useStyles();
const { jails, isLoading, error, reload } = useJailDistribution(timeRange, origin); const { jails, loading, error, reload } = useJailDistribution(timeRange, origin);
const entries = buildEntries(jails); const entries = buildEntries(jails);
const chartHeight = Math.max(entries.length * BAR_HEIGHT_PX, MIN_CHART_HEIGHT); const chartHeight = Math.max(entries.length * BAR_HEIGHT_PX, MIN_CHART_HEIGHT);
@@ -149,7 +149,7 @@ export const JailDistributionChart = memo(function JailDistributionChart({
return ( return (
<ChartStateWrapper <ChartStateWrapper
isLoading={isLoading} isLoading={loading}
error={error} error={error}
onRetry={reload} onRetry={reload}
isEmpty={jails.length === 0} isEmpty={jails.length === 0}

View File

@@ -36,7 +36,7 @@ function wrap(ui: React.ReactElement) {
const defaultResult: UseBanTrendResult = { const defaultResult: UseBanTrendResult = {
buckets: [], buckets: [],
bucketSize: "1h", bucketSize: "1h",
isLoading: false, loading: false,
error: null, error: null,
reload: vi.fn(), reload: vi.fn(),
}; };
@@ -54,7 +54,7 @@ beforeEach(() => {
describe("BanTrendChart", () => { describe("BanTrendChart", () => {
it("shows a spinner while loading", () => { it("shows a spinner while loading", () => {
mockHook({ isLoading: true }); mockHook({ loading: true });
wrap(<BanTrendChart timeRange="24h" origin="all" />); wrap(<BanTrendChart timeRange="24h" origin="all" />);
expect(screen.getByRole("progressbar")).toBeInTheDocument(); expect(screen.getByRole("progressbar")).toBeInTheDocument();
}); });

View File

@@ -33,7 +33,7 @@ function wrap(ui: React.ReactElement) {
const defaultResult: UseJailDistributionResult = { const defaultResult: UseJailDistributionResult = {
jails: [], jails: [],
total: 0, total: 0,
isLoading: false, loading: false,
error: null, error: null,
reload: vi.fn(), reload: vi.fn(),
}; };
@@ -53,7 +53,7 @@ beforeEach(() => {
describe("JailDistributionChart", () => { describe("JailDistributionChart", () => {
it("shows a spinner while loading", () => { it("shows a spinner while loading", () => {
mockHook({ isLoading: true }); mockHook({ loading: true });
wrap(<JailDistributionChart timeRange="24h" origin="all" />); wrap(<JailDistributionChart timeRange="24h" origin="all" />);
expect(screen.getByRole("progressbar")).toBeInTheDocument(); expect(screen.getByRole("progressbar")).toBeInTheDocument();
}); });

View File

@@ -21,7 +21,7 @@ export interface UseBanTrendResult {
/** Human-readable bucket size label, e.g. `"1h"`. */ /** Human-readable bucket size label, e.g. `"1h"`. */
bucketSize: string; bucketSize: string;
/** True while a fetch is in flight. */ /** True while a fetch is in flight. */
isLoading: boolean; loading: boolean;
/** Error message or `null`. */ /** Error message or `null`. */
error: string | null; error: string | null;
/** Re-fetch the data immediately. */ /** Re-fetch the data immediately. */
@@ -46,7 +46,7 @@ export function useBanTrend(
): UseBanTrendResult { ): UseBanTrendResult {
const [buckets, setBuckets] = useState<BanTrendBucket[]>([]); const [buckets, setBuckets] = useState<BanTrendBucket[]>([]);
const [bucketSize, setBucketSize] = useState<string>("1h"); const [bucketSize, setBucketSize] = useState<string>("1h");
const [isLoading, setIsLoading] = useState<boolean>(true); const [loading, setLoading] = useState<boolean>(true);
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<string | null>(null);
const abortRef = useRef<AbortController | null>(null); const abortRef = useRef<AbortController | null>(null);
@@ -56,7 +56,7 @@ export function useBanTrend(
const controller = new AbortController(); const controller = new AbortController();
abortRef.current = controller; abortRef.current = controller;
setIsLoading(true); setLoading(true);
setError(null); setError(null);
fetchBanTrend(timeRange, origin, source, controller.signal) fetchBanTrend(timeRange, origin, source, controller.signal)
@@ -71,7 +71,7 @@ export function useBanTrend(
}) })
.finally(() => { .finally(() => {
if (!controller.signal.aborted) { if (!controller.signal.aborted) {
setIsLoading(false); setLoading(false);
} }
}); });
}, [timeRange, origin, source]); }, [timeRange, origin, source]);
@@ -83,5 +83,5 @@ export function useBanTrend(
}; };
}, [load]); }, [load]);
return { buckets, bucketSize, isLoading, error, reload: load }; return { buckets, bucketSize, loading, error, reload: load };
} }

View File

@@ -27,7 +27,7 @@ export interface UseDashboardCountryDataResult {
/** Total ban count in the window. */ /** Total ban count in the window. */
total: number; total: number;
/** True while a fetch is in flight. */ /** True while a fetch is in flight. */
isLoading: boolean; loading: boolean;
/** Error message or `null`. */ /** Error message or `null`. */
error: string | null; error: string | null;
/** Re-fetch the data immediately. */ /** Re-fetch the data immediately. */
@@ -54,7 +54,7 @@ export function useDashboardCountryData(
const [countryNames, setCountryNames] = useState<Record<string, string>>({}); const [countryNames, setCountryNames] = useState<Record<string, string>>({});
const [bans, setBans] = useState<DashboardBanItem[]>([]); const [bans, setBans] = useState<DashboardBanItem[]>([]);
const [total, setTotal] = useState<number>(0); const [total, setTotal] = useState<number>(0);
const [isLoading, setIsLoading] = useState<boolean>(true); const [loading, setLoading] = useState<boolean>(true);
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<string | null>(null);
const abortRef = useRef<AbortController | null>(null); const abortRef = useRef<AbortController | null>(null);
@@ -65,7 +65,7 @@ export function useDashboardCountryData(
const controller = new AbortController(); const controller = new AbortController();
abortRef.current = controller; abortRef.current = controller;
setIsLoading(true); setLoading(true);
setError(null); setError(null);
fetchBansByCountry(timeRange, origin, source) fetchBansByCountry(timeRange, origin, source)
@@ -82,7 +82,7 @@ export function useDashboardCountryData(
}) })
.finally(() => { .finally(() => {
if (!controller.signal.aborted) { if (!controller.signal.aborted) {
setIsLoading(false); setLoading(false);
} }
}); });
}, [timeRange, origin, source]); }, [timeRange, origin, source]);
@@ -94,5 +94,5 @@ export function useDashboardCountryData(
}; };
}, [load]); }, [load]);
return { countries, countryNames, bans, total, isLoading, error, reload: load }; return { countries, countryNames, bans, total, loading, error, reload: load };
} }

View File

@@ -21,7 +21,7 @@ export interface UseJailDistributionResult {
/** Total ban count for the selected window. */ /** Total ban count for the selected window. */
total: number; total: number;
/** True while a fetch is in flight. */ /** True while a fetch is in flight. */
isLoading: boolean; loading: boolean;
/** Error message or `null`. */ /** Error message or `null`. */
error: string | null; error: string | null;
/** Re-fetch the data immediately. */ /** Re-fetch the data immediately. */
@@ -45,7 +45,7 @@ export function useJailDistribution(
): UseJailDistributionResult { ): UseJailDistributionResult {
const [jails, setJails] = useState<JailBanCount[]>([]); const [jails, setJails] = useState<JailBanCount[]>([]);
const [total, setTotal] = useState<number>(0); const [total, setTotal] = useState<number>(0);
const [isLoading, setIsLoading] = useState<boolean>(true); const [loading, setLoading] = useState<boolean>(true);
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<string | null>(null);
const abortRef = useRef<AbortController | null>(null); const abortRef = useRef<AbortController | null>(null);
@@ -55,7 +55,7 @@ export function useJailDistribution(
const controller = new AbortController(); const controller = new AbortController();
abortRef.current = controller; abortRef.current = controller;
setIsLoading(true); setLoading(true);
setError(null); setError(null);
fetchBansByJail(timeRange, origin, "fail2ban", controller.signal) fetchBansByJail(timeRange, origin, "fail2ban", controller.signal)
@@ -70,7 +70,7 @@ export function useJailDistribution(
}) })
.finally(() => { .finally(() => {
if (!controller.signal.aborted) { if (!controller.signal.aborted) {
setIsLoading(false); setLoading(false);
} }
}); });
}, [timeRange, origin]); }, [timeRange, origin]);
@@ -82,5 +82,5 @@ export function useJailDistribution(
}; };
}, [load]); }, [load]);
return { jails, total, isLoading, error, reload: load }; return { jails, total, loading, error, reload: load };
} }

View File

@@ -80,7 +80,7 @@ export function DashboardPage(): React.JSX.Element {
const source = getDataSource(timeRange); const source = getDataSource(timeRange);
const { countries, countryNames, isLoading: countryLoading, error: countryError, reload: reloadCountry } = const { countries, countryNames, loading: countryLoading, error: countryError, reload: reloadCountry } =
useDashboardCountryData(timeRange, originFilter, source); useDashboardCountryData(timeRange, originFilter, source);
const sectionStyles = useCommonSectionStyles(); const sectionStyles = useCommonSectionStyles();