From 117229f9f14edd11b3aa76c96b5f34ff8af5e9ca Mon Sep 17 00:00:00 2001 From: Francis Cao Date: Fri, 14 Jun 2024 12:35:12 -0700 Subject: [PATCH 1/3] Add entry / exit filters --- .../(main)/reports/journey/JourneyView.tsx | 2 - .../[websiteId]/WebsiteExpandedView.tsx | 12 ++++++ src/components/messages.ts | 2 + src/components/metrics/PagesTable.tsx | 17 ++++++--- src/lib/constants.ts | 4 +- .../analytics/pageviews/getPageviewMetrics.ts | 38 ++++++++++++++++++- 6 files changed, 65 insertions(+), 10 deletions(-) diff --git a/src/app/(main)/reports/journey/JourneyView.tsx b/src/app/(main)/reports/journey/JourneyView.tsx index d9a43346..f11e8aa3 100644 --- a/src/app/(main)/reports/journey/JourneyView.tsx +++ b/src/app/(main)/reports/journey/JourneyView.tsx @@ -93,8 +93,6 @@ export default function JourneyView() { return null; } - //console.log({ data, columns, selectedNode, activeNode }); - return (
diff --git a/src/app/(main)/websites/[websiteId]/WebsiteExpandedView.tsx b/src/app/(main)/websites/[websiteId]/WebsiteExpandedView.tsx index ea037852..db4db73f 100644 --- a/src/app/(main)/websites/[websiteId]/WebsiteExpandedView.tsx +++ b/src/app/(main)/websites/[websiteId]/WebsiteExpandedView.tsx @@ -18,6 +18,8 @@ import styles from './WebsiteExpandedView.module.css'; const views = { url: PagesTable, + entry: PagesTable, + exit: PagesTable, title: PagesTable, referrer: ReferrersTable, browser: BrowsersTable, @@ -53,6 +55,16 @@ export default function WebsiteExpandedView({ label: formatMessage(labels.pages), url: renderUrl({ view: 'url' }), }, + { + key: 'entry', + label: formatMessage(labels.entry), + url: renderUrl({ view: 'entry' }), + }, + { + key: 'exit', + label: formatMessage(labels.exit), + url: renderUrl({ view: 'exit' }), + }, { key: 'referrer', label: formatMessage(labels.referrers), diff --git a/src/components/messages.ts b/src/components/messages.ts index a4c43af2..dd5eb9dd 100644 --- a/src/components/messages.ts +++ b/src/components/messages.ts @@ -88,6 +88,8 @@ export const labels = defineMessages({ leaveTeam: { id: 'label.leave-team', defaultMessage: 'Leave team' }, refresh: { id: 'label.refresh', defaultMessage: 'Refresh' }, pages: { id: 'label.pages', defaultMessage: 'Pages' }, + entry: { id: 'label.entry', defaultMessage: 'Entry URL' }, + exit: { id: 'label.exit', defaultMessage: 'Exit URL' }, referrers: { id: 'label.referrers', defaultMessage: 'Referrers' }, screens: { id: 'label.screens', defaultMessage: 'Screens' }, browsers: { id: 'label.browsers', defaultMessage: 'Browsers' }, diff --git a/src/components/metrics/PagesTable.tsx b/src/components/metrics/PagesTable.tsx index d29952d4..f9ded478 100644 --- a/src/components/metrics/PagesTable.tsx +++ b/src/components/metrics/PagesTable.tsx @@ -1,11 +1,10 @@ -import FilterLink from 'components/common/FilterLink'; +import { WebsiteContext } from 'app/(main)/websites/[websiteId]/WebsiteProvider'; import FilterButtons from 'components/common/FilterButtons'; -import MetricsTable, { MetricsTableProps } from './MetricsTable'; -import { useMessages } from 'components/hooks'; -import { useNavigation } from 'components/hooks'; +import FilterLink from 'components/common/FilterLink'; +import { useMessages, useNavigation } from 'components/hooks'; import { emptyFilter } from 'lib/filters'; import { useContext } from 'react'; -import { WebsiteContext } from 'app/(main)/websites/[websiteId]/WebsiteProvider'; +import MetricsTable, { MetricsTableProps } from './MetricsTable'; export interface PagesTableProps extends MetricsTableProps { allowFilter?: boolean; @@ -29,6 +28,14 @@ export function PagesTable({ allowFilter, ...props }: PagesTableProps) { label: 'URL', key: 'url', }, + { + label: formatMessage(labels.entry), + key: 'entry', + }, + { + label: formatMessage(labels.exit), + key: 'exit', + }, { label: formatMessage(labels.title), key: 'title', diff --git a/src/lib/constants.ts b/src/lib/constants.ts index 745673e9..f8447b8b 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -32,7 +32,7 @@ export const FILTER_RANGE = 'filter-range'; export const FILTER_REFERRERS = 'filter-referrers'; export const FILTER_PAGES = 'filter-pages'; export const UNIT_TYPES = ['year', 'month', 'hour', 'day', 'minute']; -export const EVENT_COLUMNS = ['url', 'referrer', 'title', 'query', 'event']; +export const EVENT_COLUMNS = ['url', 'entry', 'exit', 'referrer', 'title', 'query', 'event']; export const SESSION_COLUMNS = [ 'browser', @@ -47,6 +47,8 @@ export const SESSION_COLUMNS = [ export const FILTER_COLUMNS = { url: 'url_path', + entry: 'url_path', + exit: 'url_path', referrer: 'referrer_domain', title: 'page_title', query: 'url_query', diff --git a/src/queries/analytics/pageviews/getPageviewMetrics.ts b/src/queries/analytics/pageviews/getPageviewMetrics.ts index 5f609c12..67ccb04a 100644 --- a/src/queries/analytics/pageviews/getPageviewMetrics.ts +++ b/src/queries/analytics/pageviews/getPageviewMetrics.ts @@ -1,7 +1,7 @@ -import prisma from 'lib/prisma'; import clickhouse from 'lib/clickhouse'; -import { runQuery, CLICKHOUSE, PRISMA } from 'lib/db'; import { EVENT_TYPE, FILTER_COLUMNS, SESSION_COLUMNS } from 'lib/constants'; +import { CLICKHOUSE, PRISMA, runQuery } from 'lib/db'; +import prisma from 'lib/prisma'; import { QueryFilters } from 'lib/types'; export async function getPageviewMetrics( @@ -31,17 +31,34 @@ async function relationalQuery( { joinSession: SESSION_COLUMNS.includes(type) }, ); + let entryExitQuery = ''; let excludeDomain = ''; if (column === 'referrer_domain') { excludeDomain = `and website_event.referrer_domain != {{websiteDomain}} and website_event.referrer_domain is not null`; } + if (type === 'entry' || type === 'exit') { + const aggregrate = type === 'entry' ? 'min' : 'max'; + + entryExitQuery = ` + JOIN (select visit_id, + ${aggregrate}(created_at) target_created_at + from website_event + where website_event.website_id = {{websiteId::uuid}} + and website_event.created_at between {{startDate}} and {{endDate}} + and event_type = {{eventType}} + group by visit_id) x + ON x.visit_id = website_event.visit_id + and x.target_created_at = website_event.created_at`; + } + return rawQuery( ` select ${column} x, count(*) y from website_event ${joinSession} + ${entryExitQuery} where website_event.website_id = {{websiteId::uuid}} and website_event.created_at between {{startDate}} and {{endDate}} and event_type = {{eventType}} @@ -70,15 +87,32 @@ async function clickhouseQuery( eventType: column === 'event_name' ? EVENT_TYPE.customEvent : EVENT_TYPE.pageView, }); + let entryExitQuery = ''; let excludeDomain = ''; if (column === 'referrer_domain') { excludeDomain = `and referrer_domain != {websiteDomain:String} and referrer_domain != ''`; } + if (type === 'entry' || type === 'exit') { + const aggregrate = type === 'entry' ? 'min' : 'max'; + + entryExitQuery = ` + JOIN (select visit_id, + ${aggregrate}(created_at) target_created_at + from website_event + where website_id = {websiteId:UUID} + and created_at between {startDate:DateTime64} and {endDate:DateTime64} + and event_type = {eventType:UInt32} + group by visit_id) x + ON x.visit_id = website_event.visit_id + and x.target_created_at = website_event.created_at`; + } + return rawQuery( ` select ${column} x, count(*) y from website_event + ${entryExitQuery} where website_id = {websiteId:UUID} and created_at between {startDate:DateTime64} and {endDate:DateTime64} and event_type = {eventType:UInt32} From 8493db1402f1ee21e9b0b5164b573a197e590506 Mon Sep 17 00:00:00 2001 From: Francis Cao Date: Fri, 14 Jun 2024 12:41:05 -0700 Subject: [PATCH 2/3] fix scroll and expanded view items --- .../websites/[websiteId]/WebsiteExpandedView.tsx | 10 ---------- src/components/metrics/PagesTable.tsx | 2 +- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/src/app/(main)/websites/[websiteId]/WebsiteExpandedView.tsx b/src/app/(main)/websites/[websiteId]/WebsiteExpandedView.tsx index db4db73f..617015f1 100644 --- a/src/app/(main)/websites/[websiteId]/WebsiteExpandedView.tsx +++ b/src/app/(main)/websites/[websiteId]/WebsiteExpandedView.tsx @@ -55,16 +55,6 @@ export default function WebsiteExpandedView({ label: formatMessage(labels.pages), url: renderUrl({ view: 'url' }), }, - { - key: 'entry', - label: formatMessage(labels.entry), - url: renderUrl({ view: 'entry' }), - }, - { - key: 'exit', - label: formatMessage(labels.exit), - url: renderUrl({ view: 'exit' }), - }, { key: 'referrer', label: formatMessage(labels.referrers), diff --git a/src/components/metrics/PagesTable.tsx b/src/components/metrics/PagesTable.tsx index f9ded478..9a18458d 100644 --- a/src/components/metrics/PagesTable.tsx +++ b/src/components/metrics/PagesTable.tsx @@ -20,7 +20,7 @@ export function PagesTable({ allowFilter, ...props }: PagesTableProps) { const { domain } = useContext(WebsiteContext); const handleSelect = (key: any) => { - router.push(renderUrl({ view: key }), { scroll: true }); + router.push(renderUrl({ view: key }), { scroll: false }); }; const buttons = [ From dd47ca9e339bcf3e0741ebf93b578a659b318801 Mon Sep 17 00:00:00 2001 From: Francis Cao Date: Fri, 14 Jun 2024 13:06:32 -0700 Subject: [PATCH 3/3] fix filterlink logic for entry / exit --- src/components/metrics/PagesTable.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/metrics/PagesTable.tsx b/src/components/metrics/PagesTable.tsx index 9a18458d..767c4764 100644 --- a/src/components/metrics/PagesTable.tsx +++ b/src/components/metrics/PagesTable.tsx @@ -45,11 +45,13 @@ export function PagesTable({ allowFilter, ...props }: PagesTableProps) { const renderLink = ({ x }) => { return ( );