From 606da1c8940795921a7cb9a447eedc5762d8a23e Mon Sep 17 00:00:00 2001 From: Jamie Pine Date: Mon, 16 Mar 2026 22:54:11 -0700 Subject: [PATCH] fix generation list not updating on completion Use refetchQueries instead of invalidateQueries for more reliable history refresh. Add history refetch to SSE onerror handler so dropped connections don't leave the list stale. Reset page to 0 in HistoryTable when a pending generation completes. Closes #231 --- app/src/components/History/HistoryTable.tsx | 17 ++++++++++++++++- app/src/lib/hooks/useGenerationProgress.ts | 11 ++++++----- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/app/src/components/History/HistoryTable.tsx b/app/src/components/History/HistoryTable.tsx index 65f201d7..e88c7701 100644 --- a/app/src/components/History/HistoryTable.tsx +++ b/app/src/components/History/HistoryTable.tsx @@ -153,7 +153,9 @@ export function HistoryTable() { } }, [historyData, page]); - // Reset to page 0 when deletions or imports occur + // Reset to page 0 when deletions, imports, or generation completions occur + const pendingCount = useGenerationStore((state) => state.pendingGenerationIds.size); + const prevPendingCountRef = useRef(pendingCount); useEffect(() => { if (deleteGeneration.isSuccess || importGeneration.isSuccess) { setPage(0); @@ -161,6 +163,19 @@ export function HistoryTable() { } }, [deleteGeneration.isSuccess, importGeneration.isSuccess]); + useEffect(() => { + // A generation finished (pending count decreased) — scroll back to show it + if ( + prevPendingCountRef.current > 0 && + pendingCount < prevPendingCountRef.current && + page !== 0 + ) { + setPage(0); + setAllHistory([]); + } + prevPendingCountRef.current = pendingCount; + }, [pendingCount, page]); + // Intersection Observer for infinite scroll useEffect(() => { const loadMoreEl = loadMoreRef.current; diff --git a/app/src/lib/hooks/useGenerationProgress.ts b/app/src/lib/hooks/useGenerationProgress.ts index 17d9e0cd..4c6e9143 100644 --- a/app/src/lib/hooks/useGenerationProgress.ts +++ b/app/src/lib/hooks/useGenerationProgress.ts @@ -75,8 +75,8 @@ export function useGenerationProgress() { currentSources.delete(id); removePendingGeneration(id); - // Refresh history to pick up the completed generation - queryClient.invalidateQueries({ queryKey: ['history'] }); + // Refetch history to pick up the completed generation + queryClient.refetchQueries({ queryKey: ['history'] }); // If this generation was queued for a story, add it now const storyId = removePendingStoryAdd(id); @@ -120,7 +120,7 @@ export function useGenerationProgress() { removePendingGeneration(id); removePendingStoryAdd(id); - queryClient.invalidateQueries({ queryKey: ['history'] }); + queryClient.refetchQueries({ queryKey: ['history'] }); toast({ title: data.status === 'not_found' ? 'Generation not found' : 'Generation failed', @@ -134,11 +134,12 @@ export function useGenerationProgress() { }; source.onerror = () => { - // EventSource auto-reconnects, but if we get repeated errors - // just clean up + // SSE connection dropped — clean up and refresh history so any + // completed/failed generation still appears in the list source.close(); currentSources.delete(id); removePendingGeneration(id); + queryClient.refetchQueries({ queryKey: ['history'] }); }; currentSources.set(id, source);