diff --git a/components/pages/reports/ReportTemplates.js b/components/pages/reports/ReportTemplates.js index 60ae11e7..c1e0acdf 100644 --- a/components/pages/reports/ReportTemplates.js +++ b/components/pages/reports/ReportTemplates.js @@ -33,14 +33,12 @@ export function ReportTemplates() { const { formatMessage, labels } = useMessages(); const reports = [ - /* { title: formatMessage(labels.insights), description: 'Dive deeper into your data by using segments and filters.', url: '/reports/insights', icon: , }, - */ { title: formatMessage(labels.funnel), description: 'Understand the conversion and drop-off rate of users.', diff --git a/components/pages/reports/insights/InsightsTable.js b/components/pages/reports/insights/InsightsTable.js index a767468e..d751445b 100644 --- a/components/pages/reports/insights/InsightsTable.js +++ b/components/pages/reports/insights/InsightsTable.js @@ -6,11 +6,13 @@ import { ReportContext } from '../Report'; export function InsightsTable() { const { report } = useContext(ReportContext); const { formatMessage, labels } = useMessages(); + const { fields = [] } = report?.parameters || {}; return ( - - + {fields.map(({ name }) => { + return ; + })} ); diff --git a/queries/analytics/reports/getInsights.ts b/queries/analytics/reports/getInsights.ts index 1d8970ed..68f06e21 100644 --- a/queries/analytics/reports/getInsights.ts +++ b/queries/analytics/reports/getInsights.ts @@ -1,11 +1,14 @@ import { CLICKHOUSE, PRISMA, runQuery } from 'lib/db'; import prisma from 'lib/prisma'; import clickhouse from 'lib/clickhouse'; +import { maxDate } from 'lib/date'; +import { EVENT_TYPE } from 'lib/constants'; +import { loadWebsite } from 'lib/load'; export interface GetInsightsCriteria { startDate: Date; endDate: Date; - fields: string[]; + fields: { name: string; type: string; value: string }[]; filters: string[]; groups: string[]; } @@ -26,7 +29,33 @@ async function relationalQuery( y: number; }[] > { - return null; + const { startDate, endDate, fields = [], filters = [], groups = [] } = criteria; + const { parseFilters, rawQuery } = prisma; + const website = await loadWebsite(websiteId); + const params = {}; + const { filterQuery, joinSession } = parseFilters(params); + + return rawQuery( + ` + select + url_path, + count(*) y + from website_event + ${joinSession} + where website_event.website_id = {{websiteId::uuid}} + and website_event.created_at between {{startDate}} and {{endDate}} + and website_event.event_type = {{eventType}} + ${filterQuery} + group by 1 + `, + { + ...filters, + websiteId, + startDate: maxDate(startDate, website.resetAt), + endDate, + eventType: EVENT_TYPE.pageView, + }, + ); } async function clickhouseQuery( @@ -38,5 +67,54 @@ async function clickhouseQuery( y: number; }[] > { - return null; + const { startDate, endDate, fields = [], filters = [], groups = [] } = criteria; + const { parseFilters, rawQuery } = clickhouse; + const website = await loadWebsite(websiteId); + const params = {}; + const { filterQuery } = parseFilters(params); + + const fieldsQuery = parseFields(fields); + + return rawQuery( + ` + select + ${fieldsQuery} + from website_event + where website_id = {websiteId:UUID} + and created_at between {startDate:DateTime} and {endDate:DateTime} + and event_type = {eventType:UInt32} + ${filterQuery} + group by ${fields.map(({ name }) => name).join(',')} + order by total desc + limit 500 + `, + { + ...filters, + websiteId, + startDate: maxDate(startDate, website.resetAt), + endDate, + eventType: EVENT_TYPE.pageView, + }, + ); +} + +function parseFields(fields) { + let count = false; + let distinct = false; + + const query = fields.reduce((arr, field) => { + const { name, value } = field; + + if (!count && value === 'total') { + count = true; + arr = arr.concat(`count(*) as total`); + } else if (!distinct && value === 'unique') { + distinct = true; + //arr = arr.concat(`count(distinct ${name})`); + } + + return arr.concat(name); + }, []); + + return query.join(',\n'); }