mirror of
https://github.com/umami-software/umami.git
synced 2026-02-25 06:55:35 +01:00
add limit 50 to event chart, metrics table, and UTM report
This commit is contained in:
parent
09bc2ee5c8
commit
530c21dac0
6 changed files with 69 additions and 9 deletions
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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(() => {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue