From 7fe71c4446a363f745398a5f0c064239d14242e1 Mon Sep 17 00:00:00 2001 From: Robert Joonas Date: Mon, 11 May 2026 12:40:59 +0300 Subject: [PATCH] fix realtime top stats in limited to segment shared link --- .../stats/graph/fetch-top-stats.test.ts | 2 +- .../dashboard/stats/graph/fetch-top-stats.ts | 24 +++++++++++++++---- .../dashboard/stats/graph/visitor-graph.tsx | 5 +++- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/assets/js/dashboard/stats/graph/fetch-top-stats.test.ts b/assets/js/dashboard/stats/graph/fetch-top-stats.test.ts index 9d12a4663ffb..27b5e0920daf 100644 --- a/assets/js/dashboard/stats/graph/fetch-top-stats.test.ts +++ b/assets/js/dashboard/stats/graph/fetch-top-stats.test.ts @@ -325,7 +325,7 @@ describe(`${topStatsQueries.name}`, () => { resolvedFilters: inputDashboardState.filters, ...inputDashboardState } - const queries = topStatsQueries(dashboardState, metrics) + const queries = topStatsQueries(dashboardState, metrics, null) expect(queries).toEqual(expectedQueries) } ) diff --git a/assets/js/dashboard/stats/graph/fetch-top-stats.ts b/assets/js/dashboard/stats/graph/fetch-top-stats.ts index d33b2331ba42..dac01a05fe06 100644 --- a/assets/js/dashboard/stats/graph/fetch-top-stats.ts +++ b/assets/js/dashboard/stats/graph/fetch-top-stats.ts @@ -12,12 +12,15 @@ import { createStatsQuery, ReportParams, StatsQuery } from '../../stats-query' import { hasConversionGoalFilter, hasPageFilter, - isRealTimeDashboard + isRealTimeDashboard, + remapToApiFilters } from '../../util/filters' +import { isSegmentFilter } from '../../filtering/segments' export function topStatsQueries( dashboardState: DashboardState, - metrics: Metric[] + metrics: Metric[], + limitedToSegmentId: number | null ): [StatsQuery, StatsQuery | null] { let currentVisitorsQuery = null @@ -26,7 +29,16 @@ export function topStatsQueries( metrics: ['visitors'] }) - currentVisitorsQuery.filters = [] + const filters = limitedToSegmentId + ? dashboardState.filters.filter((f) => { + const [_op, _key, clauses] = f + return ( + isSegmentFilter(f) && clauses[0] === limitedToSegmentId.toString() + ) + }) + : [] + + currentVisitorsQuery.filters = remapToApiFilters(filters) } const topStatsQuery = constructTopStatsQuery(dashboardState, metrics) @@ -35,12 +47,14 @@ export function topStatsQueries( export async function fetchTopStats( site: PlausibleSite, - dashboardState: DashboardState + dashboardState: DashboardState, + limitedToSegmentId: number | null ) { const metrics = chooseMetrics(site, dashboardState) const [topStatsQuery, currentVisitorsQuery] = topStatsQueries( dashboardState, - metrics + metrics, + limitedToSegmentId ) const topStatsPromise = api.stats(site, topStatsQuery) diff --git a/assets/js/dashboard/stats/graph/visitor-graph.tsx b/assets/js/dashboard/stats/graph/visitor-graph.tsx index 97fa477dfa9c..d04767e5e9f3 100644 --- a/assets/js/dashboard/stats/graph/visitor-graph.tsx +++ b/assets/js/dashboard/stats/graph/visitor-graph.tsx @@ -13,6 +13,7 @@ import { getStaleTime } from '../../hooks/api-client' import { MainGraph, MainGraphContainer, useMainGraphWidth } from './main-graph' import { useGraphIntervalContext } from './graph-interval-context' import { useSetImportsIncluded } from './imports-included-context' +import { useSegmentsContext } from '../../filtering/segments-context' // height of at least one row of top stats const DEFAULT_TOP_STATS_LOADING_HEIGHT_PX = 85 @@ -29,6 +30,8 @@ export default function VisitorGraph({ const { dashboardState } = useDashboardStateContext() const isRealtime = dashboardState.period === DashboardPeriod.realtime const queryClient = useQueryClient() + const { limitedToSegment } = useSegmentsContext() + const limitedToSegmentId = limitedToSegment ? limitedToSegment.id : null const { selectedInterval } = useGraphIntervalContext() @@ -47,7 +50,7 @@ export default function VisitorGraph({ queryKey: ['top-stats', { dashboardState }] as const, queryFn: async ({ queryKey }) => { const [_, opts] = queryKey - return await fetchTopStats(site, opts.dashboardState) + return await fetchTopStats(site, opts.dashboardState, limitedToSegmentId) }, placeholderData: (previousData) => previousData, staleTime: ({ queryKey }) => {