From ee4749c6c6c357b4bee26adb4982c200db7c18d7 Mon Sep 17 00:00:00 2001 From: "IGNY8 VPS (Salman)" Date: Thu, 15 Jan 2026 06:28:29 +0000 Subject: [PATCH] metrics to always show total fixed --- frontend/src/pages/Planner/Clusters.tsx | 12 ++++++++---- frontend/src/pages/Planner/Ideas.tsx | 12 ++++++++---- frontend/src/pages/Planner/Keywords.tsx | 12 ++++++++---- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/frontend/src/pages/Planner/Clusters.tsx b/frontend/src/pages/Planner/Clusters.tsx index 1fe1e5bc..aaf84613 100644 --- a/frontend/src/pages/Planner/Clusters.tsx +++ b/frontend/src/pages/Planner/Clusters.tsx @@ -49,6 +49,8 @@ export default function Clusters() { const [totalImagesCount, setTotalImagesCount] = useState(0); const [totalVolume, setTotalVolume] = useState(0); const [totalKeywords, setTotalKeywords] = useState(0); + // Actual total count (unfiltered) for header metrics - not affected by filters + const [actualTotalClusters, setActualTotalClusters] = useState(0); // Dynamic filter options (loaded from backend based on current data) // Initialize as undefined to distinguish "not loaded yet" from "loaded but empty array" @@ -175,7 +177,7 @@ export default function Clusters() { fetchImages({ page_size: 1 }), ]); - setTotalCount(allRes.count || 0); + setActualTotalClusters(allRes.count || 0); // Store actual total (unfiltered) for header metrics setTotalWithIdeas(mappedRes.count || 0); setTotalReady(newRes.count || 0); setTotalImagesCount(imagesRes.count || 0); @@ -471,8 +473,9 @@ export default function Clusters() { handleRowAction, ]); - // Calculate header metrics - use totalWithIdeas/totalReady from API calls (not page data) + // Calculate header metrics - use actualTotalClusters/totalWithIdeas/totalReady from API calls (not page data) // This ensures metrics show correct totals across all pages, not just current page + // Note: actualTotalClusters is NOT affected by filters - it always shows the true total const headerMetrics = useMemo(() => { if (!pageConfig?.headerMetrics) return []; @@ -482,7 +485,8 @@ export default function Clusters() { switch (metric.label) { case 'Clusters': - value = totalCount || 0; + // Use actualTotalClusters (unfiltered) for header metrics - not affected by filters + value = actualTotalClusters || 0; break; case 'New': // Use totalReady from loadTotalMetrics() (clusters without ideas) @@ -507,7 +511,7 @@ export default function Clusters() { tooltip: (metric as any).tooltip, }; }); - }, [pageConfig?.headerMetrics, clusters, totalCount, totalReady, totalWithIdeas, totalVolume, totalKeywords]); + }, [pageConfig?.headerMetrics, clusters, totalCount, totalReady, totalWithIdeas, totalVolume, totalKeywords, actualTotalClusters]); const resetForm = useCallback(() => { setFormData({ diff --git a/frontend/src/pages/Planner/Ideas.tsx b/frontend/src/pages/Planner/Ideas.tsx index 799d7c5f..8bc3e66b 100644 --- a/frontend/src/pages/Planner/Ideas.tsx +++ b/frontend/src/pages/Planner/Ideas.tsx @@ -50,6 +50,8 @@ export default function Ideas() { const [totalInTasks, setTotalInTasks] = useState(0); const [totalPending, setTotalPending] = useState(0); const [totalImagesCount, setTotalImagesCount] = useState(0); + // Actual total count (unfiltered) for header metrics - not affected by filters + const [actualTotalIdeas, setActualTotalIdeas] = useState(0); // Dynamic filter options // Initialize as undefined to distinguish "not loaded yet" from "loaded but empty array" @@ -178,7 +180,7 @@ export default function Ideas() { fetchImages({ page_size: 1 }), ]); - setTotalCount(allRes.count || 0); + setActualTotalIdeas(allRes.count || 0); // Store actual total (unfiltered) for header metrics setTotalInTasks((queuedRes.count || 0) + (completedRes.count || 0)); setTotalPending(newRes.count || 0); setTotalImagesCount(imagesRes.count || 0); @@ -359,8 +361,9 @@ export default function Ideas() { }); }, [clusters, activeSector, formData, searchTerm, statusFilter, clusterFilter, structureFilter, typeFilter, statusOptions, contentTypeOptions, contentStructureOptions, clusterOptions]); - // Calculate header metrics - use totalInTasks/totalPending from API calls (not page data) + // Calculate header metrics - use actualTotalIdeas/totalInTasks/totalPending from API calls (not page data) // This ensures metrics show correct totals across all pages, not just current page + // Note: actualTotalIdeas is NOT affected by filters - it always shows the true total const headerMetrics = useMemo(() => { if (!pageConfig?.headerMetrics) return []; @@ -370,7 +373,8 @@ export default function Ideas() { switch (metric.label) { case 'Ideas': - value = totalCount || 0; + // Use actualTotalIdeas (unfiltered) for header metrics - not affected by filters + value = actualTotalIdeas || 0; break; case 'New': // Use totalPending from loadTotalMetrics() (ideas with status='new') @@ -395,7 +399,7 @@ export default function Ideas() { tooltip: (metric as any).tooltip, }; }); - }, [pageConfig?.headerMetrics, ideas, totalCount, totalPending, totalInTasks]); + }, [pageConfig?.headerMetrics, ideas, totalCount, totalPending, totalInTasks, actualTotalIdeas]); const resetForm = useCallback(() => { setFormData({ diff --git a/frontend/src/pages/Planner/Keywords.tsx b/frontend/src/pages/Planner/Keywords.tsx index 776c9f24..57f8106b 100644 --- a/frontend/src/pages/Planner/Keywords.tsx +++ b/frontend/src/pages/Planner/Keywords.tsx @@ -55,6 +55,8 @@ export default function Keywords() { const [totalUnmapped, setTotalUnmapped] = useState(0); const [totalVolume, setTotalVolume] = useState(0); const [totalImagesCount, setTotalImagesCount] = useState(0); + // Actual total count (unfiltered) for header metrics - not affected by filters + const [actualTotalKeywords, setActualTotalKeywords] = useState(0); // Dynamic filter options (loaded from backend based on current data) // Initialize as undefined to distinguish "not loaded yet" from "loaded but empty array" @@ -218,7 +220,7 @@ export default function Keywords() { fetchPlannerKeywordStats(activeSite.id), ]); - setTotalCount(allRes.count || 0); + setActualTotalKeywords(allRes.count || 0); // Store actual total (unfiltered) for header metrics setTotalClustered(mappedRes.count || 0); setTotalUnmapped(newRes.count || 0); setTotalImagesCount(imagesRes.count || 0); @@ -628,8 +630,9 @@ export default function Keywords() { difficultyOptions, ]); - // Calculate header metrics - use totalClustered/totalUnmapped from API calls (not page data) + // Calculate header metrics - use actualTotalKeywords/totalClustered/totalUnmapped from API calls (not page data) // This ensures metrics show correct totals across all pages, not just current page + // Note: actualTotalKeywords is NOT affected by filters - it always shows the true total const headerMetrics = useMemo(() => { if (!pageConfig?.headerMetrics) return []; @@ -639,7 +642,8 @@ export default function Keywords() { switch (metric.label) { case 'Keywords': - value = totalCount || 0; + // Use actualTotalKeywords (unfiltered) for header metrics - not affected by filters + value = actualTotalKeywords || 0; break; case 'Clustered': // Use totalClustered from loadTotalMetrics() instead of filtering page data @@ -664,7 +668,7 @@ export default function Keywords() { tooltip: (metric as any).tooltip, }; }); - }, [pageConfig?.headerMetrics, keywords, totalCount, clusters, totalClustered, totalUnmapped, totalVolume]); + }, [pageConfig?.headerMetrics, keywords, totalCount, clusters, totalClustered, totalUnmapped, totalVolume, actualTotalKeywords]); // Calculate workflow insights based on UX doc principles const workflowStats = useMemo(() => {