feat: LIVE/PAUSED toggle controls data fetching on sidebar navigation
All checks were successful
CI / build (push) Successful in 1m13s
CI / cleanup-branch (push) Has been skipped
CI / docker (push) Successful in 55s
CI / deploy (push) Successful in 39s
CI / deploy-feature (push) Has been skipped

LIVE: sidebar clicks trigger initial fetch + polling for the new route.
PAUSED: sidebar clicks navigate but queries are disabled — no fetches
until the user switches back to LIVE.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-03-25 10:01:14 +01:00
parent 9866dd5f23
commit 996ea65293
2 changed files with 23 additions and 9 deletions

View File

@@ -1,7 +1,7 @@
import { useQuery } from '@tanstack/react-query';
import { api } from '../client';
import type { SearchRequest } from '../types';
import { useRefreshInterval } from './use-refresh-interval';
import { useLiveQuery } from './use-refresh-interval';
export function useExecutionStats(
timeFrom: string | undefined,
@@ -9,7 +9,7 @@ export function useExecutionStats(
routeId?: string,
application?: string,
) {
const refetchInterval = useRefreshInterval(10_000);
const live = useLiveQuery(10_000);
return useQuery({
queryKey: ['executions', 'stats', timeFrom, timeTo, routeId, application],
queryFn: async () => {
@@ -26,14 +26,14 @@ export function useExecutionStats(
if (error) throw new Error('Failed to load stats');
return data!;
},
enabled: !!timeFrom,
enabled: !!timeFrom && live.enabled,
placeholderData: (prev) => prev,
refetchInterval,
refetchInterval: live.refetchInterval,
});
}
export function useSearchExecutions(filters: SearchRequest, live = false) {
const refetchInterval = useRefreshInterval(5_000);
const liveQuery = useLiveQuery(5_000);
return useQuery({
queryKey: ['executions', 'search', filters],
queryFn: async () => {
@@ -44,7 +44,8 @@ export function useSearchExecutions(filters: SearchRequest, live = false) {
return data!;
},
placeholderData: (prev) => prev,
refetchInterval: live ? refetchInterval : false,
enabled: live ? liveQuery.enabled : true,
refetchInterval: live ? liveQuery.refetchInterval : false,
});
}
@@ -54,7 +55,7 @@ export function useStatsTimeseries(
routeId?: string,
application?: string,
) {
const refetchInterval = useRefreshInterval(30_000);
const live = useLiveQuery(30_000);
return useQuery({
queryKey: ['executions', 'timeseries', timeFrom, timeTo, routeId, application],
queryFn: async () => {
@@ -72,9 +73,9 @@ export function useStatsTimeseries(
if (error) throw new Error('Failed to load timeseries');
return data!;
},
enabled: !!timeFrom,
enabled: !!timeFrom && live.enabled,
placeholderData: (prev) => prev,
refetchInterval,
refetchInterval: live.refetchInterval,
});
}

View File

@@ -8,3 +8,16 @@ export function useRefreshInterval(intervalMs: number): number | false {
const { autoRefresh } = useGlobalFilters();
return autoRefresh ? intervalMs : false;
}
/**
* Returns `enabled` and `refetchInterval` tied to the LIVE/PAUSED toggle.
* - LIVE: enabled=true, refetchInterval=intervalMs (fetch + poll)
* - PAUSED: enabled=false, refetchInterval=false (no fetch at all)
*/
export function useLiveQuery(intervalMs: number) {
const { autoRefresh } = useGlobalFilters();
return {
enabled: autoRefresh,
refetchInterval: autoRefresh ? intervalMs : false as number | false,
};
}