add limit 50 to event chart, metrics table, and UTM report

This commit is contained in:
Francis Cao 2026-02-17 21:55:35 -08:00
parent 09bc2ee5c8
commit 530c21dac0
6 changed files with 69 additions and 9 deletions

View file

@ -89,13 +89,14 @@ export function EventsPage({ websiteId }) {
<TabPanel id="chart">
<Column gap="6">
<Column border="bottom" paddingBottom="6">
<EventsChart websiteId={websiteId} />
<EventsChart websiteId={websiteId} limit={50} />
</Column>
<MetricsTable
websiteId={websiteId}
type="event"
title={t(labels.event)}
metric={t(labels.count)}
limit={50}
/>
</Column>
</TabPanel>

View file

@ -14,6 +14,7 @@ export async function GET(
endAt: z.coerce.number().int(),
unit: unitParam.optional(),
timezone: timezoneParam,
limit: z.coerce.number().optional(),
...filterParams,
});
@ -29,9 +30,10 @@ export async function GET(
return unauthorized();
}
const { limit } = query;
const filters = await getQueryFilters(query, websiteId);
const data = await getEventStats(websiteId, filters);
const data = await getEventStats(websiteId, { limit }, filters);
return json(data);
}

View file

@ -3,15 +3,29 @@ import { useApi } from '../useApi';
import { useDateParameters } from '../useDateParameters';
import { useFilterParameters } from '../useFilterParameters';
export function useWebsiteEventsSeriesQuery(websiteId: string, options?: ReactQueryOptions) {
export function useWebsiteEventsSeriesQuery(
websiteId: string,
params?: { limit?: number },
options?: ReactQueryOptions,
) {
const { get, useQuery } = useApi();
const { startAt, endAt, unit, timezone } = useDateParameters();
const filters = useFilterParameters();
return useQuery({
queryKey: ['websites:events:series', { websiteId, startAt, endAt, unit, timezone, ...filters }],
queryKey: [
'websites:events:series',
{ websiteId, startAt, endAt, unit, timezone, ...filters, ...params },
],
queryFn: () =>
get(`/websites/${websiteId}/events/series`, { startAt, endAt, unit, timezone, ...filters }),
get(`/websites/${websiteId}/events/series`, {
startAt,
endAt,
unit,
timezone,
...filters,
...params,
}),
enabled: !!websiteId,
...options,
});

View file

@ -15,15 +15,16 @@ import { generateTimeSeries } from '@/lib/date';
export interface EventsChartProps extends BarChartProps {
websiteId: string;
focusLabel?: string;
limit?: number;
}
export function EventsChart({ websiteId, focusLabel }: EventsChartProps) {
export function EventsChart({ websiteId, focusLabel, limit }: EventsChartProps) {
const { timezone } = useTimezone();
const {
dateRange: { startDate, endDate, unit },
} = useDateRange({ timezone: timezone });
const { locale, dateLocale } = useLocale();
const { data, isLoading, error } = useWebsiteEventsSeriesQuery(websiteId);
const { data, isLoading, error } = useWebsiteEventsSeriesQuery(websiteId, { limit });
const [label, setLabel] = useState<string>(focusLabel);
const chartData: any = useMemo(() => {

View file

@ -6,6 +6,10 @@ import type { QueryFilters } from '@/lib/types';
const FUNCTION_NAME = 'getEventStats';
export interface EventStatsParameters {
limit?: number | string;
}
interface WebsiteEventMetric {
x: string;
t: string;
@ -13,7 +17,7 @@ interface WebsiteEventMetric {
}
export async function getEventStats(
...args: [websiteId: string, filters: QueryFilters]
...args: [websiteId: string, parameters: EventStatsParameters, filters: QueryFilters]
): Promise<WebsiteEventMetric[]> {
return runQuery({
[PRISMA]: () => relationalQuery(...args),
@ -21,7 +25,12 @@ export async function getEventStats(
});
}
async function relationalQuery(websiteId: string, filters: QueryFilters) {
async function relationalQuery(
websiteId: string,
parameters: EventStatsParameters,
filters: QueryFilters,
) {
const { limit } = parameters;
const { timezone = 'utc', unit = 'day' } = filters;
const { rawQuery, getDateSQL, parseFilters } = prisma;
const { filterQuery, cohortQuery, joinSessionQuery, queryParams } = parseFilters({
@ -30,6 +39,19 @@ async function relationalQuery(websiteId: string, filters: QueryFilters) {
eventType: EVENT_TYPE.customEvent,
});
const limitQuery = limit
? `and event_name in (
select event_name
from website_event
where website_id = {{websiteId::uuid}}
and created_at between {{startDate}} and {{endDate}}
and event_type = 2
group by event_name
order by count(*) desc
limit ${limit}
)`
: '';
return rawQuery(
`
select
@ -42,6 +64,7 @@ async function relationalQuery(websiteId: string, filters: QueryFilters) {
where website_event.website_id = {{websiteId::uuid}}
and website_event.created_at between {{startDate}} and {{endDate}}
${filterQuery}
${limitQuery}
group by 1, 2
order by 2
`,
@ -52,8 +75,10 @@ async function relationalQuery(websiteId: string, filters: QueryFilters) {
async function clickhouseQuery(
websiteId: string,
parameters: EventStatsParameters,
filters: QueryFilters,
): Promise<{ x: string; t: string; y: number }[]> {
const { limit } = parameters;
const { timezone = 'UTC', unit = 'day' } = filters;
const { rawQuery, getDateSQL, parseFilters } = clickhouse;
const { filterQuery, cohortQuery, queryParams } = parseFilters({
@ -62,6 +87,19 @@ async function clickhouseQuery(
eventType: EVENT_TYPE.customEvent,
});
const limitQuery = limit
? `and event_name in (
select event_name
from website_event
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
and event_type = {eventType:UInt32}
group by event_name
order by count(*) desc
limit ${limit}
)`
: '';
let sql = '';
if (filterQuery || cohortQuery) {
@ -75,6 +113,7 @@ async function clickhouseQuery(
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
${filterQuery}
${limitQuery}
group by x, t
order by t
`;
@ -91,6 +130,7 @@ async function clickhouseQuery(
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
and event_type = {eventType:UInt32}
${limitQuery}
) as g
group by x, t
order by t

View file

@ -47,6 +47,7 @@ async function relationalQuery(
${filterQuery}
group by 1
order by 2 desc
limit 50
`,
queryParams,
);
@ -78,6 +79,7 @@ async function clickhouseQuery(
${filterQuery}
group by 1
order by 2 desc
limit 50
`,
queryParams,
);