diff --git a/src/ui/viewer/App.tsx b/src/ui/viewer/App.tsx index e2696e93..bd3fde0c 100644 --- a/src/ui/viewer/App.tsx +++ b/src/ui/viewer/App.tsx @@ -25,29 +25,26 @@ export function App() { const { preference, resolvedTheme, setThemePreference } = useTheme(); const pagination = usePagination(currentFilter); - // When filtering by project: ONLY use paginated data (API-filtered) - // When showing all projects: merge SSE live data with paginated data + // Merge SSE live data with paginated data, filtering by project when active const allObservations = useMemo(() => { - if (currentFilter) { - // Project filter active: API handles filtering, ignore SSE items - return paginatedObservations; - } - // No filter: merge SSE + paginated, deduplicate by ID - return mergeAndDeduplicateByProject(observations, paginatedObservations); + const live = currentFilter + ? observations.filter(o => o.project === currentFilter) + : observations; + return mergeAndDeduplicateByProject(live, paginatedObservations); }, [observations, paginatedObservations, currentFilter]); const allSummaries = useMemo(() => { - if (currentFilter) { - return paginatedSummaries; - } - return mergeAndDeduplicateByProject(summaries, paginatedSummaries); + const live = currentFilter + ? summaries.filter(s => s.project === currentFilter) + : summaries; + return mergeAndDeduplicateByProject(live, paginatedSummaries); }, [summaries, paginatedSummaries, currentFilter]); const allPrompts = useMemo(() => { - if (currentFilter) { - return paginatedPrompts; - } - return mergeAndDeduplicateByProject(prompts, paginatedPrompts); + const live = currentFilter + ? prompts.filter(p => p.project === currentFilter) + : prompts; + return mergeAndDeduplicateByProject(live, paginatedPrompts); }, [prompts, paginatedPrompts, currentFilter]); // Toggle context preview modal diff --git a/src/ui/viewer/utils/data.ts b/src/ui/viewer/utils/data.ts index 5211a5c2..e72d9307 100644 --- a/src/ui/viewer/utils/data.ts +++ b/src/ui/viewer/utils/data.ts @@ -5,10 +5,9 @@ /** * Merge real-time SSE items with paginated items, removing duplicates by ID - * NOTE: This should ONLY be used when no project filter is active. - * When filtering, use ONLY paginated data (API-filtered). + * Callers should pre-filter liveItems by project when a filter is active. * - * @param liveItems - Items from SSE stream (unfiltered) + * @param liveItems - Items from SSE stream (pre-filtered if needed) * @param paginatedItems - Items from pagination API * @returns Merged and deduplicated array */