Skip to content

Commit b421474

Browse files
committed
feat: report editor
commit bfcf271a64c33a60f61f511cec2198d9c8a9c51a Author: Carl-Gerhard Lindesvärd <lindesvard@gmail.com> Date: Wed Nov 26 12:32:40 2025 +0100 wip commit 8cd3b89 Author: Carl-Gerhard Lindesvärd <lindesvard@gmail.com> Date: Tue Nov 25 22:33:58 2025 +0100 funnel commit 95af86d Author: Carl-Gerhard Lindesvärd <lindesvard@gmail.com> Date: Tue Nov 25 22:23:25 2025 +0100 wip commit 727a218 Author: Carl-Gerhard Lindesvärd <lindesvard@gmail.com> Date: Tue Nov 25 10:18:26 2025 +0100 conversion wip commit 958ba53 Author: Carl-Gerhard Lindesvärd <lindesvard@gmail.com> Date: Tue Nov 25 10:18:20 2025 +0100 wip commit 3bbeb92 Author: Carl-Gerhard Lindesvärd <lindesvard@gmail.com> Date: Tue Nov 25 09:18:48 2025 +0100 wip commit d99335e Author: Carl-Gerhard Lindesvärd <lindesvard@gmail.com> Date: Mon Nov 24 18:08:10 2025 +0100 wip commit 1fa61b1 Author: Carl-Gerhard Lindesvärd <lindesvard@gmail.com> Date: Mon Nov 24 15:50:28 2025 +0100 ts commit 548747d Author: Carl-Gerhard Lindesvärd <lindesvard@gmail.com> Date: Mon Nov 24 13:17:01 2025 +0100 fix typecheck events -> series commit 7b18544 Author: Carl-Gerhard Lindesvärd <lindesvard@gmail.com> Date: Mon Nov 24 13:06:46 2025 +0100 fix report table commit 57697a5 Author: Carl-Gerhard Lindesvärd <lindesvard@gmail.com> Date: Sat Nov 22 00:05:13 2025 +0100 wip commit 06fb6c4 Author: Carl-Gerhard Lindesvärd <lindesvard@gmail.com> Date: Fri Nov 21 11:21:17 2025 +0100 wip commit dd71fd4 Author: Carl-Gerhard Lindesvärd <lindesvard@gmail.com> Date: Thu Nov 20 13:56:58 2025 +0100 formulas
1 parent 828c8c4 commit b421474

File tree

70 files changed

+6866
-1917
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+6866
-1917
lines changed

.vscode/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"editor.defaultFormatter": "biomejs.biome"
1818
},
1919
"[json]": {
20-
"editor.defaultFormatter": "biomejs.biome"
20+
"editor.defaultFormatter": "vscode.json-language-features"
2121
},
2222
"editor.formatOnSave": true,
2323
"tailwindCSS.experimental.classRegex": [

apps/api/src/controllers/export.controller.ts

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ import {
1212
getEventsCountCached,
1313
getSettingsForProject,
1414
} from '@openpanel/db';
15-
import { getChart } from '@openpanel/trpc/src/routers/chart.helpers';
16-
import { zChartEvent, zChartInput } from '@openpanel/validation';
15+
import { ChartEngine } from '@openpanel/db';
16+
import { zChartEvent, zChartInputBase } from '@openpanel/validation';
1717
import { omit } from 'ramda';
1818

1919
async function getProjectId(
@@ -139,7 +139,7 @@ export async function events(
139139
});
140140
}
141141

142-
const chartSchemeFull = zChartInput
142+
const chartSchemeFull = zChartInputBase
143143
.pick({
144144
breakdowns: true,
145145
interval: true,
@@ -151,14 +151,27 @@ const chartSchemeFull = zChartInput
151151
.extend({
152152
project_id: z.string().optional(),
153153
projectId: z.string().optional(),
154-
events: z.array(
155-
z.object({
156-
name: z.string(),
157-
filters: zChartEvent.shape.filters.optional(),
158-
segment: zChartEvent.shape.segment.optional(),
159-
property: zChartEvent.shape.property.optional(),
160-
}),
161-
),
154+
series: z
155+
.array(
156+
z.object({
157+
name: z.string(),
158+
filters: zChartEvent.shape.filters.optional(),
159+
segment: zChartEvent.shape.segment.optional(),
160+
property: zChartEvent.shape.property.optional(),
161+
}),
162+
)
163+
.optional(),
164+
// Backward compatibility - events will be migrated to series via preprocessing
165+
events: z
166+
.array(
167+
z.object({
168+
name: z.string(),
169+
filters: zChartEvent.shape.filters.optional(),
170+
segment: zChartEvent.shape.segment.optional(),
171+
property: zChartEvent.shape.property.optional(),
172+
}),
173+
)
174+
.optional(),
162175
});
163176

164177
export async function charts(
@@ -179,9 +192,17 @@ export async function charts(
179192

180193
const projectId = await getProjectId(request, reply);
181194
const { timezone } = await getSettingsForProject(projectId);
182-
const { events, ...rest } = query.data;
195+
const { events, series, ...rest } = query.data;
183196

184-
return getChart({
197+
// Use series if available, otherwise fall back to events (backward compat)
198+
const eventSeries = (series ?? events ?? []).map((event: any) => ({
199+
...event,
200+
type: event.type ?? 'event',
201+
segment: event.segment ?? 'event',
202+
filters: event.filters ?? [],
203+
}));
204+
205+
return ChartEngine.execute({
185206
...rest,
186207
startDate: rest.startDate
187208
? DateTime.fromISO(rest.startDate)
@@ -194,11 +215,7 @@ export async function charts(
194215
.toFormat('yyyy-MM-dd HH:mm:ss')
195216
: undefined,
196217
projectId,
197-
events: events.map((event) => ({
198-
...event,
199-
segment: event.segment ?? 'event',
200-
filters: event.filters ?? [],
201-
})),
218+
series: eventSeries,
202219
chartType: 'linear',
203220
metric: 'sum',
204221
});

apps/api/src/utils/ai-tools.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import {
77
ch,
88
clix,
99
} from '@openpanel/db';
10+
import { ChartEngine } from '@openpanel/db';
1011
import { getCache } from '@openpanel/redis';
11-
import { getChart } from '@openpanel/trpc/src/routers/chart.helpers';
1212
import { zChartInputAI } from '@openpanel/validation';
1313
import { tool } from 'ai';
1414
import { z } from 'zod';

apps/start/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@
103103
"lodash.throttle": "^4.1.1",
104104
"lottie-react": "^2.4.0",
105105
"lucide-react": "^0.476.0",
106-
"mathjs": "^12.3.2",
107106
"mitt": "^3.0.1",
108107
"nuqs": "^2.5.2",
109108
"prisma-error-enum": "^0.1.3",

apps/start/src/components/overview/overview-metric-card.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ export function OverviewMetricCard({
153153
width={width}
154154
height={height / 4}
155155
data={data}
156-
style={{ marginTop: (height / 4) * 3 }}
156+
style={{ marginTop: (height / 4) * 3, background: 'transparent' }}
157157
onMouseMove={(event) => {
158158
setCurrentIndex(event.activeTooltipIndex ?? null);
159159
}}

apps/start/src/components/overview/overview-top-devices.tsx

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,9 @@ export default function OverviewTopDevices({
4545
projectId,
4646
startDate,
4747
endDate,
48-
events: [
48+
series: [
4949
{
50+
type: 'event',
5051
segment: 'user',
5152
filters,
5253
id: 'A',
@@ -81,8 +82,9 @@ export default function OverviewTopDevices({
8182
projectId,
8283
startDate,
8384
endDate,
84-
events: [
85+
series: [
8586
{
87+
type: 'event',
8688
segment: 'user',
8789
filters,
8890
id: 'A',
@@ -120,8 +122,9 @@ export default function OverviewTopDevices({
120122
projectId,
121123
startDate,
122124
endDate,
123-
events: [
125+
series: [
124126
{
127+
type: 'event',
125128
segment: 'user',
126129
filters,
127130
id: 'A',
@@ -160,8 +163,9 @@ export default function OverviewTopDevices({
160163
projectId,
161164
startDate,
162165
endDate,
163-
events: [
166+
series: [
164167
{
168+
type: 'event',
165169
segment: 'user',
166170
filters,
167171
id: 'A',
@@ -199,8 +203,9 @@ export default function OverviewTopDevices({
199203
projectId,
200204
startDate,
201205
endDate,
202-
events: [
206+
series: [
203207
{
208+
type: 'event',
204209
segment: 'user',
205210
filters,
206211
id: 'A',
@@ -239,8 +244,9 @@ export default function OverviewTopDevices({
239244
projectId,
240245
startDate,
241246
endDate,
242-
events: [
247+
series: [
243248
{
249+
type: 'event',
244250
segment: 'user',
245251
filters,
246252
id: 'A',
@@ -278,8 +284,9 @@ export default function OverviewTopDevices({
278284
projectId,
279285
startDate,
280286
endDate,
281-
events: [
287+
series: [
282288
{
289+
type: 'event',
283290
segment: 'user',
284291
filters,
285292
id: 'A',

apps/start/src/components/overview/overview-top-events.tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import type { IChartType } from '@openpanel/validation';
77

88
import { useTRPC } from '@/integrations/trpc/react';
99
import { useQuery } from '@tanstack/react-query';
10+
import { SerieIcon } from '../report-chart/common/serie-icon';
1011
import { Widget, WidgetBody } from '../widget';
1112
import { OverviewChartToggle } from './overview-chart-toggle';
1213
import { WidgetButtons, WidgetFooter, WidgetHead } from './overview-widget';
@@ -37,8 +38,9 @@ export default function OverviewTopEvents({
3738
projectId,
3839
startDate,
3940
endDate,
40-
events: [
41+
series: [
4142
{
43+
type: 'event',
4244
segment: 'event',
4345
filters: [
4446
...filters,
@@ -78,8 +80,9 @@ export default function OverviewTopEvents({
7880
projectId,
7981
startDate,
8082
endDate,
81-
events: [
83+
series: [
8284
{
85+
type: 'event',
8386
segment: 'event',
8487
filters: [...filters],
8588
id: 'A',
@@ -112,8 +115,9 @@ export default function OverviewTopEvents({
112115
projectId,
113116
startDate,
114117
endDate,
115-
events: [
118+
series: [
116119
{
120+
type: 'event',
117121
segment: 'event',
118122
filters: [
119123
...filters,
@@ -168,7 +172,13 @@ export default function OverviewTopEvents({
168172
</WidgetHead>
169173
<WidgetBody className="p-3">
170174
<ReportChart
171-
options={{ hideID: true, columns: ['Event', 'Count'] }}
175+
options={{
176+
hideID: true,
177+
columns: ['Event'],
178+
renderSerieName(names) {
179+
return names[1];
180+
},
181+
}}
172182
report={{
173183
...widget.chart.report,
174184
previous: false,

apps/start/src/components/overview/overview-top-geo.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import type { IChartType } from '@openpanel/validation';
77
import { useNumber } from '@/hooks/use-numer-formatter';
88
import { useTRPC } from '@/integrations/trpc/react';
99
import { pushModal } from '@/modals';
10+
import { countries } from '@/translations/countries';
1011
import { NOT_SET_VALUE } from '@openpanel/constants';
1112
import { useQuery } from '@tanstack/react-query';
1213
import { ChevronRightIcon } from 'lucide-react';
@@ -108,13 +109,19 @@ export default function OverviewTopGeo({ projectId }: OverviewTopGeoProps) {
108109
>
109110
{item.prefix && (
110111
<span className="mr-1 row inline-flex items-center gap-1">
111-
<span>{item.prefix}</span>
112+
<span>
113+
{countries[
114+
item.prefix as keyof typeof countries
115+
] ?? item.prefix}
116+
</span>
112117
<span>
113118
<ChevronRightIcon className="size-3" />
114119
</span>
115120
</span>
116121
)}
117-
{item.name || 'Not set'}
122+
{(countries[item.name as keyof typeof countries] ??
123+
item.name) ||
124+
'Not set'}
118125
</button>
119126
</div>
120127
);
@@ -146,8 +153,9 @@ export default function OverviewTopGeo({ projectId }: OverviewTopGeoProps) {
146153
projectId,
147154
startDate,
148155
endDate,
149-
events: [
156+
series: [
150157
{
158+
type: 'event',
151159
segment: 'event',
152160
filters,
153161
id: 'A',

apps/start/src/components/profiles/profile-charts.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ export const ProfileCharts = memo(
1515
const pageViewsChart: IChartProps = {
1616
projectId,
1717
chartType: 'linear',
18-
events: [
18+
series: [
1919
{
20+
type: 'event',
2021
segment: 'event',
2122
filters: [
2223
{
@@ -48,8 +49,9 @@ export const ProfileCharts = memo(
4849
const eventsChart: IChartProps = {
4950
projectId,
5051
chartType: 'linear',
51-
events: [
52+
series: [
5253
{
54+
type: 'event',
5355
segment: 'event',
5456
filters: [
5557
{

0 commit comments

Comments
 (0)