From 5bfe0b9e35268a610912fb19f37acf5adc190372 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl-Gerhard=20Lindesva=CC=88rd?= Date: Wed, 28 Feb 2024 22:09:44 +0100 Subject: [PATCH] fixed alot of bugs in overview --- .../dashboards/[dashboardId]/page.tsx | 4 +-- .../[projectId]/layout-project-selector.tsx | 8 ++--- .../[projectId]/overview-metrics.tsx | 14 ++++---- .../overview/overview-top-devices.tsx | 35 +++++++++++++++---- .../components/overview/overview-top-geo.tsx | 8 ++--- .../overview/overview-top-sources.tsx | 17 ++++----- .../components/report/chart/MetricCard.tsx | 1 - .../report/sidebar/ReportEvents.tsx | 8 +++++ apps/web/src/utils/math.ts | 3 +- packages/db/src/services/chart.service.ts | 4 +++ packages/db/src/services/dashboard.service.ts | 3 +- packages/validation/src/index.ts | 1 + 12 files changed, 71 insertions(+), 35 deletions(-) diff --git a/apps/web/src/app/(app)/[organizationId]/[projectId]/dashboards/[dashboardId]/page.tsx b/apps/web/src/app/(app)/[organizationId]/[projectId]/dashboards/[dashboardId]/page.tsx index dc6d34f1..d2a27ba2 100644 --- a/apps/web/src/app/(app)/[organizationId]/[projectId]/dashboards/[dashboardId]/page.tsx +++ b/apps/web/src/app/(app)/[organizationId]/[projectId]/dashboards/[dashboardId]/page.tsx @@ -18,9 +18,9 @@ export default async function Page({ params: { organizationId, projectId, dashboardId }, }: PageProps) { const [dashboard, reports] = await Promise.all([ - getDashboardById(dashboardId), + getDashboardById(dashboardId, projectId), getReportsByDashboardId(dashboardId), - getExists(organizationId, projectId), + getExists(organizationId), ]); if (!dashboard) { diff --git a/apps/web/src/app/(app)/[organizationId]/[projectId]/layout-project-selector.tsx b/apps/web/src/app/(app)/[organizationId]/[projectId]/layout-project-selector.tsx index e56a397f..52a86986 100644 --- a/apps/web/src/app/(app)/[organizationId]/[projectId]/layout-project-selector.tsx +++ b/apps/web/src/app/(app)/[organizationId]/[projectId]/layout-project-selector.tsx @@ -23,12 +23,10 @@ export default function LayoutProjectSelector({ className="w-auto min-w-0 max-sm:max-w-[100px]" placeholder={'Select project'} onChange={(value) => { - // If we are on a page with only organizationId and projectId (as params) - // we know its safe to just replace the current projectId - // since the rest of the url is to a static page - // e.g. /[organizationId]/[projectId]/events if (organizationId && projectId) { - router.push(pathname.replace(projectId, value)); + const split = pathname.replace(projectId, value).split('/'); + // slicing here will remove everything after /{orgId}/{projectId}/dashboards [slice here] /xxx/xxx/xxx + router.push(split.slice(0, 4).join('/')); } else { router.push(`/${organizationId}/${value}`); } diff --git a/apps/web/src/app/(app)/[organizationId]/[projectId]/overview-metrics.tsx b/apps/web/src/app/(app)/[organizationId]/[projectId]/overview-metrics.tsx index bf1fb31c..e1a32842 100644 --- a/apps/web/src/app/(app)/[organizationId]/[projectId]/overview-metrics.tsx +++ b/apps/web/src/app/(app)/[organizationId]/[projectId]/overview-metrics.tsx @@ -17,7 +17,7 @@ export default function OverviewMetrics({ projectId }: OverviewMetricsProps) { const { previous, range, interval, metric, setMetric, startDate, endDate } = useOverviewOptions(); const [filters] = useEventQueryFilters(); - + const isPageFilter = filters.find((filter) => filter.name === 'path'); const reports = [ { id: 'Visitors', @@ -29,7 +29,7 @@ export default function OverviewMetrics({ projectId }: OverviewMetricsProps) { segment: 'user', filters, id: 'A', - name: 'session_start', + name: isPageFilter ? 'screen_view' : 'session_start', displayName: 'Visitors', }, ], @@ -49,10 +49,10 @@ export default function OverviewMetrics({ projectId }: OverviewMetricsProps) { endDate, events: [ { - segment: 'event', + segment: 'session', filters, id: 'A', - name: 'session_start', + name: isPageFilter ? 'screen_view' : 'session_start', displayName: 'Sessions', }, ], @@ -122,7 +122,7 @@ export default function OverviewMetrics({ projectId }: OverviewMetricsProps) { filters: [ { id: '1', - name: 'properties._bounce', + name: 'properties.__bounce', operator: 'is', value: ['true'], }, @@ -171,8 +171,8 @@ export default function OverviewMetrics({ projectId }: OverviewMetricsProps) { ], id: 'A', property: 'duration', - name: 'screen_view', - displayName: 'Visit duration', + name: isPageFilter ? 'screen_view' : 'session_end', + displayName: isPageFilter ? 'Time on page' : 'Visit duration', }, ], breakdowns: [], diff --git a/apps/web/src/components/overview/overview-top-devices.tsx b/apps/web/src/components/overview/overview-top-devices.tsx index 0b3daebb..ca2085ce 100644 --- a/apps/web/src/components/overview/overview-top-devices.tsx +++ b/apps/web/src/components/overview/overview-top-devices.tsx @@ -31,7 +31,7 @@ export default function OverviewTopDevices({ segment: 'user', filters, id: 'A', - name: 'session_start', + name: '*', }, ], breakdowns: [ @@ -61,7 +61,7 @@ export default function OverviewTopDevices({ segment: 'user', filters, id: 'A', - name: 'session_start', + name: '*', }, ], breakdowns: [ @@ -91,7 +91,7 @@ export default function OverviewTopDevices({ segment: 'user', filters, id: 'A', - name: 'session_start', + name: '*', }, ], breakdowns: [ @@ -121,7 +121,7 @@ export default function OverviewTopDevices({ segment: 'user', filters, id: 'A', - name: 'session_start', + name: '*', }, ], breakdowns: [ @@ -151,7 +151,7 @@ export default function OverviewTopDevices({ segment: 'user', filters, id: 'A', - name: 'session_start', + name: '*', }, ], breakdowns: [ @@ -189,7 +189,30 @@ export default function OverviewTopDevices({ - + { + switch (widget.key) { + case 'devices': + setFilter('device', item.name); + break; + case 'browser': + setFilter('browser', item.name); + break; + case 'browser_version': + setFilter('browser_version', item.name); + break; + case 'os': + setFilter('os', item.name); + break; + case 'os_version': + setFilter('os_version', item.name); + break; + } + }} + /> diff --git a/apps/web/src/components/overview/overview-top-geo.tsx b/apps/web/src/components/overview/overview-top-geo.tsx index 7e0e3b09..9a1e3146 100644 --- a/apps/web/src/components/overview/overview-top-geo.tsx +++ b/apps/web/src/components/overview/overview-top-geo.tsx @@ -29,7 +29,7 @@ export default function OverviewTopGeo({ projectId }: OverviewTopGeoProps) { segment: 'event', filters, id: 'A', - name: 'session_start', + name: '*', }, ], breakdowns: [ @@ -59,7 +59,7 @@ export default function OverviewTopGeo({ projectId }: OverviewTopGeoProps) { segment: 'event', filters, id: 'A', - name: 'session_start', + name: '*', }, ], breakdowns: [ @@ -89,7 +89,7 @@ export default function OverviewTopGeo({ projectId }: OverviewTopGeoProps) { segment: 'event', filters, id: 'A', - name: 'session_start', + name: '*', }, ], breakdowns: [ @@ -165,7 +165,7 @@ export default function OverviewTopGeo({ projectId }: OverviewTopGeoProps) { segment: 'event', filters, id: 'A', - name: 'session_start', + name: '*', }, ], breakdowns: [ diff --git a/apps/web/src/components/overview/overview-top-sources.tsx b/apps/web/src/components/overview/overview-top-sources.tsx index b139c25e..5a8e3329 100644 --- a/apps/web/src/components/overview/overview-top-sources.tsx +++ b/apps/web/src/components/overview/overview-top-sources.tsx @@ -18,6 +18,7 @@ export default function OverviewTopSources({ const { interval, range, previous, startDate, endDate } = useOverviewOptions(); const [filters, setFilter] = useEventQueryFilters(); + const isPageFilter = filters.find((filter) => filter.name === 'path'); const [widget, setWidget, widgets] = useOverviewWidget('sources', { all: { title: 'Top sources', @@ -31,7 +32,7 @@ export default function OverviewTopSources({ segment: 'event', filters: filters, id: 'A', - name: 'session_start', + name: isPageFilter ? 'screen_view' : 'session_start', }, ], breakdowns: [ @@ -61,7 +62,7 @@ export default function OverviewTopSources({ segment: 'event', filters: filters, id: 'A', - name: 'session_start', + name: isPageFilter ? 'screen_view' : 'session_start', }, ], breakdowns: [ @@ -91,7 +92,7 @@ export default function OverviewTopSources({ segment: 'event', filters: filters, id: 'A', - name: 'session_start', + name: isPageFilter ? 'screen_view' : 'session_start', }, ], breakdowns: [ @@ -121,7 +122,7 @@ export default function OverviewTopSources({ segment: 'event', filters, id: 'A', - name: 'session_start', + name: isPageFilter ? 'screen_view' : 'session_start', }, ], breakdowns: [ @@ -151,7 +152,7 @@ export default function OverviewTopSources({ segment: 'event', filters, id: 'A', - name: 'session_start', + name: isPageFilter ? 'screen_view' : 'session_start', }, ], breakdowns: [ @@ -181,7 +182,7 @@ export default function OverviewTopSources({ segment: 'event', filters, id: 'A', - name: 'session_start', + name: isPageFilter ? 'screen_view' : 'session_start', }, ], breakdowns: [ @@ -211,7 +212,7 @@ export default function OverviewTopSources({ segment: 'event', filters, id: 'A', - name: 'session_start', + name: isPageFilter ? 'screen_view' : 'session_start', }, ], breakdowns: [ @@ -241,7 +242,7 @@ export default function OverviewTopSources({ segment: 'event', filters, id: 'A', - name: 'session_start', + name: isPageFilter ? 'screen_view' : 'session_start', }, ], breakdowns: [ diff --git a/apps/web/src/components/report/chart/MetricCard.tsx b/apps/web/src/components/report/chart/MetricCard.tsx index cbb12418..5d8fb760 100644 --- a/apps/web/src/components/report/chart/MetricCard.tsx +++ b/apps/web/src/components/report/chart/MetricCard.tsx @@ -29,7 +29,6 @@ export function MetricCard({ unit, }: MetricCardProps) { const { previousIndicatorInverted } = useChartContext(); - const color = _color || theme?.colors['chart-0']; const number = useNumber(); const renderValue = (value: number, unitClassName?: string) => { diff --git a/apps/web/src/components/report/sidebar/ReportEvents.tsx b/apps/web/src/components/report/sidebar/ReportEvents.tsx index 80c19262..1b21aa82 100644 --- a/apps/web/src/components/report/sidebar/ReportEvents.tsx +++ b/apps/web/src/components/report/sidebar/ReportEvents.tsx @@ -112,6 +112,10 @@ export function ReportEvents() { value: 'user', label: 'Unique users', }, + { + value: 'session', + label: 'Unique sessions', + }, { value: 'user_average', label: 'Average event per user', @@ -136,6 +140,10 @@ export function ReportEvents() { <> Unique users + ) : event.segment === 'session' ? ( + <> + Unique sessions + ) : event.segment === 'user_average' ? ( <> Average event per user diff --git a/apps/web/src/utils/math.ts b/apps/web/src/utils/math.ts index e7a77151..c24eb461 100644 --- a/apps/web/src/utils/math.ts +++ b/apps/web/src/utils/math.ts @@ -7,7 +7,8 @@ export const round = (num: number, decimals = 2) => { export const average = (arr: (number | null)[]) => { const filtered = arr.filter( - (n): n is number => isNumber(n) && !Number.isNaN(n) && Number.isFinite(n) + (n): n is number => + isNumber(n) && !Number.isNaN(n) && Number.isFinite(n) && n !== 0 ); const avg = filtered.reduce((p, c) => p + c, 0) / filtered.length; return Number.isNaN(avg) ? 0 : avg; diff --git a/packages/db/src/services/chart.service.ts b/packages/db/src/services/chart.service.ts index 9226c350..56290e44 100644 --- a/packages/db/src/services/chart.service.ts +++ b/packages/db/src/services/chart.service.ts @@ -76,6 +76,10 @@ export function getChartSql({ sb.select.count = `countDistinct(profile_id) as count`; } + if (event.segment === 'session') { + sb.select.count = `countDistinct(session_id) as count`; + } + if (event.segment === 'user_average') { sb.select.count = `COUNT(*)::float / COUNT(DISTINCT profile_id)::float as count`; } diff --git a/packages/db/src/services/dashboard.service.ts b/packages/db/src/services/dashboard.service.ts index 126bfef6..52bae331 100644 --- a/packages/db/src/services/dashboard.service.ts +++ b/packages/db/src/services/dashboard.service.ts @@ -5,10 +5,11 @@ export type IServiceDashboards = Awaited< ReturnType >; -export async function getDashboardById(id: string) { +export async function getDashboardById(id: string, projectId: string) { const dashboard = await db.dashboard.findUnique({ where: { id, + project_id: projectId, }, include: { project: true, diff --git a/packages/validation/src/index.ts b/packages/validation/src/index.ts index 550df515..9084ebd0 100644 --- a/packages/validation/src/index.ts +++ b/packages/validation/src/index.ts @@ -26,6 +26,7 @@ export const zChartEvent = z.object({ segment: z.enum([ 'event', 'user', + 'session', 'user_average', 'one_event_per_user', 'property_sum',