diff --git a/src/app/(main)/websites/[websiteId]/events/EventProperties.tsx b/src/app/(main)/websites/[websiteId]/events/EventProperties.tsx index b2fa491a..794a5053 100644 --- a/src/app/(main)/websites/[websiteId]/events/EventProperties.tsx +++ b/src/app/(main)/websites/[websiteId]/events/EventProperties.tsx @@ -8,9 +8,10 @@ import styles from './EventProperties.module.css'; export function EventProperties({ websiteId }: { websiteId: string }) { const [propertyName, setPropertyName] = useState(''); + const [eventName, setEventName] = useState(''); const { formatMessage, labels } = useMessages(); const { data, isLoading, isFetched, error } = useEventDataProperties(websiteId); - const { data: values } = useEventDataValues(websiteId, propertyName); + const { data: values } = useEventDataValues(websiteId, eventName, propertyName); const chartData = propertyName && values ? { @@ -25,13 +26,25 @@ export function EventProperties({ websiteId }: { websiteId: string }) { } : null; + const handleRowClick = row => { + setEventName(row.eventName); + setPropertyName(row.propertyName); + }; + return (
+ + {row => ( +
handleRowClick(row)}> + {row.eventName} +
+ )} +
{row => ( -
setPropertyName(row.propertyName)}> +
handleRowClick(row)}> {row.propertyName}
)} diff --git a/src/components/hooks/queries/useEventDataValues.ts b/src/components/hooks/queries/useEventDataValues.ts index 47b5a513..61aea58e 100644 --- a/src/components/hooks/queries/useEventDataValues.ts +++ b/src/components/hooks/queries/useEventDataValues.ts @@ -4,6 +4,7 @@ import { useFilterParams } from '../useFilterParams'; export function useEventDataValues( websiteId: string, + eventName: string, propertyName: string, options?: Omit, ) { @@ -12,7 +13,8 @@ export function useEventDataValues( return useQuery({ queryKey: ['websites:event-data:values', { websiteId, propertyName, ...params }], - queryFn: () => get(`/websites/${websiteId}/event-data/values`, { ...params, propertyName }), + queryFn: () => + get(`/websites/${websiteId}/event-data/values`, { ...params, eventName, propertyName }), enabled: !!(websiteId && propertyName), ...options, }); diff --git a/src/pages/api/websites/[websiteId]/event-data/values.ts b/src/pages/api/websites/[websiteId]/event-data/values.ts index b9ada96d..e5bb4ab8 100644 --- a/src/pages/api/websites/[websiteId]/event-data/values.ts +++ b/src/pages/api/websites/[websiteId]/event-data/values.ts @@ -11,6 +11,7 @@ export interface EventDataFieldsRequestQuery { websiteId: string; startAt: string; endAt: string; + eventName?: string; propertyName?: string; } @@ -19,6 +20,7 @@ const schema = { websiteId: yup.string().uuid().required(), startAt: yup.number().integer().required(), endAt: yup.number().integer().min(yup.ref('startAt')).required(), + eventName: yup.string(), propertyName: yup.string(), }), }; @@ -32,7 +34,7 @@ export default async ( await useValidate(schema, req, res); if (req.method === 'GET') { - const { websiteId, startAt, endAt, propertyName } = req.query; + const { websiteId, startAt, endAt, eventName, propertyName } = req.query; if (!(await canViewWebsite(req.auth, websiteId))) { return unauthorized(res); @@ -41,7 +43,12 @@ export default async ( const startDate = new Date(+startAt); const endDate = new Date(+endAt); - const data = await getEventDataValues(websiteId, { startDate, endDate, propertyName }); + const data = await getEventDataValues(websiteId, { + startDate, + endDate, + eventName, + propertyName, + }); return ok(res, data); } diff --git a/src/queries/analytics/events/getEventDataProperties.ts b/src/queries/analytics/events/getEventDataProperties.ts index 78fcb2cd..8d1eaf9d 100644 --- a/src/queries/analytics/events/getEventDataProperties.ts +++ b/src/queries/analytics/events/getEventDataProperties.ts @@ -24,14 +24,15 @@ async function relationalQuery( return rawQuery( ` select + event_name as "eventName", data_key as "propertyName", count(*) as "total" from event_data where website_id = {{websiteId::uuid}} and created_at between {{startDate}} and {{endDate}} ${filterQuery} - group by data_key - order by 2 desc + group by event_name, data_key + order by 3 desc limit 500 `, params, @@ -41,7 +42,7 @@ async function relationalQuery( async function clickhouseQuery( websiteId: string, filters: QueryFilters & { propertyName?: string }, -): Promise<{ propertyName: string; dataType: number; propertyValue: string; total: number }[]> { +): Promise<{ eventName: string; propertyName: string; total: number }[]> { const { rawQuery, parseFilters } = clickhouse; const { filterQuery, params } = await parseFilters(websiteId, filters, { columns: { propertyName: 'data_key' }, @@ -50,23 +51,23 @@ async function clickhouseQuery( return rawQuery( ` select + event_name as eventName, data_key as propertyName, count(*) as total from event_data where website_id = {websiteId:UUID} and created_at between {startDate:DateTime64} and {endDate:DateTime64} ${filterQuery} - group by data_key - order by 2 desc + group by event_name, data_key + order by 1, 3 desc limit 500 `, params, ).then(result => { return Object.values(result).map((a: any) => { return { + eventName: a.eventName, propertyName: a.propertyName, - dataType: Number(a.dataType), - propertyValue: a.propertyValue, total: Number(a.total), }; }); diff --git a/src/queries/analytics/events/getEventDataValues.ts b/src/queries/analytics/events/getEventDataValues.ts index d7754ad2..6d50a96d 100644 --- a/src/queries/analytics/events/getEventDataValues.ts +++ b/src/queries/analytics/events/getEventDataValues.ts @@ -4,7 +4,10 @@ import { CLICKHOUSE, PRISMA, runQuery } from 'lib/db'; import { QueryFilters, WebsiteEventData } from 'lib/types'; export async function getEventDataValues( - ...args: [websiteId: string, filters: QueryFilters & { propertyName?: string }] + ...args: [ + websiteId: string, + filters: QueryFilters & { eventName?: string; propertyName?: string }, + ] ): Promise { return runQuery({ [PRISMA]: () => relationalQuery(...args), @@ -14,7 +17,7 @@ export async function getEventDataValues( async function relationalQuery( websiteId: string, - filters: QueryFilters & { propertyName?: string }, + filters: QueryFilters & { eventName?: string; propertyName?: string }, ) { const { rawQuery, parseFilters } = prisma; const { filterQuery, params } = await parseFilters(websiteId, filters); @@ -28,6 +31,7 @@ async function relationalQuery( where website_id = {{websiteId::uuid}} and created_at between {{startDate}} and {{endDate}} and data_key = {{propertyName}} + and event_key = {{eventName}} ${filterQuery} group by string_value order by 2 desc @@ -39,7 +43,7 @@ async function relationalQuery( async function clickhouseQuery( websiteId: string, - filters: QueryFilters & { propertyName?: string }, + filters: QueryFilters & { eventName?: string; propertyName?: string }, ): Promise<{ propertyName: string; dataType: number; propertyValue: string; total: number }[]> { const { rawQuery, parseFilters } = clickhouse; const { filterQuery, params } = await parseFilters(websiteId, filters); @@ -55,8 +59,9 @@ async function clickhouseQuery( where website_id = {websiteId:UUID} and created_at between {startDate:DateTime64} and {endDate:DateTime64} and data_key = {propertyName:String} + and event_name = {eventName:String} ${filterQuery} - group by value + group by event_name, value order by 2 desc limit 500; `,