diff --git a/ui/src/components/InfiniteScrollArea.tsx b/ui/src/components/InfiniteScrollArea.tsx index 7d085260..49b77c04 100644 --- a/ui/src/components/InfiniteScrollArea.tsx +++ b/ui/src/components/InfiniteScrollArea.tsx @@ -6,6 +6,8 @@ export interface InfiniteScrollAreaProps { onTopVisibilityChange?: (atTop: boolean) => void; isFetchingNextPage: boolean; hasNextPage: boolean; + isLoading?: boolean; + hasItems?: boolean; maxHeight?: number | string; children: ReactNode; /** Optional caller-owned scroll container ref (e.g. for scroll-to-top on refresh). */ @@ -18,6 +20,8 @@ export function InfiniteScrollArea({ onTopVisibilityChange, isFetchingNextPage, hasNextPage, + isLoading = false, + hasItems = true, maxHeight = 360, children, scrollRef, @@ -68,7 +72,9 @@ export function InfiniteScrollArea({ {children} ); } diff --git a/ui/src/hooks/useInfiniteStream.ts b/ui/src/hooks/useInfiniteStream.ts index 1285e9fa..47811222 100644 --- a/ui/src/hooks/useInfiniteStream.ts +++ b/ui/src/hooks/useInfiniteStream.ts @@ -1,5 +1,5 @@ import { useInfiniteQuery, useQueryClient } from '@tanstack/react-query'; -import { useMemo } from 'react'; +import { useCallback, useMemo } from 'react'; export interface StreamPage { data: T[]; @@ -52,14 +52,20 @@ export function useInfiniteStream(args: UseInfiniteStreamArgs): UseInfinit [query.data], ); + const fetchNextPage = useCallback(() => { + if (query.hasNextPage && !query.isFetchingNextPage) query.fetchNextPage(); + }, [query.hasNextPage, query.isFetchingNextPage, query.fetchNextPage]); + + const refresh = useCallback(() => { + queryClient.invalidateQueries({ queryKey: [...queryKey] }); + }, [queryClient, queryKey]); + return { items, - fetchNextPage: () => { - if (query.hasNextPage && !query.isFetchingNextPage) query.fetchNextPage(); - }, + fetchNextPage, hasNextPage: !!query.hasNextPage, isFetchingNextPage: query.isFetchingNextPage, isLoading: query.isLoading, - refresh: () => queryClient.invalidateQueries({ queryKey: [...queryKey] }), + refresh, }; } diff --git a/ui/src/pages/AgentHealth/AgentHealth.tsx b/ui/src/pages/AgentHealth/AgentHealth.tsx index a93035d5..d3ca863d 100644 --- a/ui/src/pages/AgentHealth/AgentHealth.tsx +++ b/ui/src/pages/AgentHealth/AgentHealth.tsx @@ -957,6 +957,8 @@ export default function AgentHealth() { onTopVisibilityChange={setIsLogAtTop} isFetchingNextPage={logStream.isFetchingNextPage} hasNextPage={logStream.hasNextPage} + isLoading={logStream.isLoading} + hasItems={logStream.items.length > 0} maxHeight={360} > {filteredLogs.length > 0 ? ( @@ -993,6 +995,8 @@ export default function AgentHealth() { onTopVisibilityChange={setIsTimelineAtTop} isFetchingNextPage={eventStream.isFetchingNextPage} hasNextPage={eventStream.hasNextPage} + isLoading={eventStream.isLoading} + hasItems={eventStream.items.length > 0} maxHeight={360} > {feedEvents.length > 0 ? (