commit bfcf271a64c33a60f61f511cec2198d9c8a9c51a Author: Carl-Gerhard Lindesvärd <lindesvard@gmail.com> Date: Wed Nov 26 12:32:40 2025 +0100 wip commit8cd3b89fa3Author: Carl-Gerhard Lindesvärd <lindesvard@gmail.com> Date: Tue Nov 25 22:33:58 2025 +0100 funnel commit95af86dc44Author: Carl-Gerhard Lindesvärd <lindesvard@gmail.com> Date: Tue Nov 25 22:23:25 2025 +0100 wip commit727a218e6bAuthor: Carl-Gerhard Lindesvärd <lindesvard@gmail.com> Date: Tue Nov 25 10:18:26 2025 +0100 conversion wip commit958ba535d6Author: Carl-Gerhard Lindesvärd <lindesvard@gmail.com> Date: Tue Nov 25 10:18:20 2025 +0100 wip commit3bbeb927ccAuthor: Carl-Gerhard Lindesvärd <lindesvard@gmail.com> Date: Tue Nov 25 09:18:48 2025 +0100 wip commitd99335e2f4Author: Carl-Gerhard Lindesvärd <lindesvard@gmail.com> Date: Mon Nov 24 18:08:10 2025 +0100 wip commit1fa61b1ae9Author: Carl-Gerhard Lindesvärd <lindesvard@gmail.com> Date: Mon Nov 24 15:50:28 2025 +0100 ts commit548747d826Author: Carl-Gerhard Lindesvärd <lindesvard@gmail.com> Date: Mon Nov 24 13:17:01 2025 +0100 fix typecheck events -> series commit7b18544085Author: Carl-Gerhard Lindesvärd <lindesvard@gmail.com> Date: Mon Nov 24 13:06:46 2025 +0100 fix report table commit57697a5a39Author: Carl-Gerhard Lindesvärd <lindesvard@gmail.com> Date: Sat Nov 22 00:05:13 2025 +0100 wip commit06fb6c4f3cAuthor: Carl-Gerhard Lindesvärd <lindesvard@gmail.com> Date: Fri Nov 21 11:21:17 2025 +0100 wip commitdd71fd4e11Author: Carl-Gerhard Lindesvärd <lindesvard@gmail.com> Date: Thu Nov 20 13:56:58 2025 +0100 formulas
204 lines
5.9 KiB
TypeScript
204 lines
5.9 KiB
TypeScript
import {
|
|
OverviewFilterButton,
|
|
OverviewFiltersButtons,
|
|
} from '@/components/overview/filters/overview-filters-buttons';
|
|
import { ReportChartShortcut } from '@/components/report-chart/shortcut';
|
|
import { Widget, WidgetBody, WidgetHead } from '@/components/widget';
|
|
import {
|
|
useEventQueryFilters,
|
|
useEventQueryNamesFilter,
|
|
} from '@/hooks/use-event-query-filters';
|
|
|
|
import type { IChartEventItem } from '@openpanel/validation';
|
|
|
|
import { createFileRoute } from '@tanstack/react-router';
|
|
|
|
export const Route = createFileRoute(
|
|
'/_app/$organizationId/$projectId/events/_tabs/stats',
|
|
)({
|
|
component: Component,
|
|
});
|
|
|
|
function Component() {
|
|
const { projectId } = Route.useParams();
|
|
const [filters] = useEventQueryFilters();
|
|
const [events] = useEventQueryNamesFilter();
|
|
const fallback: IChartEventItem[] = [
|
|
{
|
|
id: 'A',
|
|
name: '*',
|
|
displayName: 'All events',
|
|
segment: 'event',
|
|
filters: filters ?? [],
|
|
type: 'event',
|
|
},
|
|
];
|
|
|
|
return (
|
|
<div>
|
|
<div className="mb-2 flex items-center gap-2">
|
|
<OverviewFilterButton enableEventsFilter />
|
|
<OverviewFiltersButtons className="justify-end p-0" />
|
|
</div>
|
|
<div className="grid grid-cols-1 gap-2 md:grid-cols-2">
|
|
<Widget className="w-full">
|
|
<WidgetHead>
|
|
<span className="title">Events per day</span>
|
|
</WidgetHead>
|
|
<WidgetBody>
|
|
<ReportChartShortcut
|
|
projectId={projectId}
|
|
range="30d"
|
|
chartType="histogram"
|
|
series={
|
|
events && events.length > 0
|
|
? events.map((name) => ({
|
|
id: name,
|
|
name,
|
|
displayName: name,
|
|
segment: 'event',
|
|
filters: filters ?? [],
|
|
type: 'event',
|
|
}))
|
|
: fallback
|
|
}
|
|
/>
|
|
</WidgetBody>
|
|
</Widget>
|
|
<Widget className="w-full">
|
|
<WidgetHead>
|
|
<span className="title">Event distribution</span>
|
|
</WidgetHead>
|
|
<WidgetBody>
|
|
<ReportChartShortcut
|
|
options={{
|
|
renderSerieName(names) {
|
|
return names[1];
|
|
},
|
|
}}
|
|
projectId={projectId}
|
|
range="30d"
|
|
chartType="pie"
|
|
breakdowns={[
|
|
{
|
|
id: 'A',
|
|
name: 'name',
|
|
},
|
|
]}
|
|
series={
|
|
events && events.length > 0
|
|
? events.map((name) => ({
|
|
id: name,
|
|
name,
|
|
displayName: name,
|
|
segment: 'event',
|
|
filters: filters ?? [],
|
|
type: 'event',
|
|
}))
|
|
: [
|
|
{
|
|
id: 'A',
|
|
name: '*',
|
|
displayName: 'All events',
|
|
segment: 'event',
|
|
filters: filters ?? [],
|
|
type: 'event',
|
|
},
|
|
]
|
|
}
|
|
/>
|
|
</WidgetBody>
|
|
</Widget>
|
|
<Widget className="w-full">
|
|
<WidgetHead>
|
|
<span className="title">Event distribution</span>
|
|
</WidgetHead>
|
|
<WidgetBody>
|
|
<ReportChartShortcut
|
|
options={{
|
|
renderSerieName(names) {
|
|
return names[1];
|
|
},
|
|
}}
|
|
projectId={projectId}
|
|
range="30d"
|
|
chartType="bar"
|
|
breakdowns={[
|
|
{
|
|
id: 'A',
|
|
name: 'name',
|
|
},
|
|
]}
|
|
series={
|
|
events && events.length > 0
|
|
? events.map((name) => ({
|
|
id: name,
|
|
name,
|
|
displayName: name,
|
|
segment: 'event',
|
|
filters: filters ?? [],
|
|
type: 'event',
|
|
}))
|
|
: [
|
|
{
|
|
id: 'A',
|
|
name: '*',
|
|
displayName: 'All events',
|
|
segment: 'event',
|
|
filters: filters ?? [],
|
|
type: 'event',
|
|
},
|
|
]
|
|
}
|
|
/>
|
|
</WidgetBody>
|
|
</Widget>
|
|
<Widget className="w-full">
|
|
<WidgetHead>
|
|
<span className="title">Event distribution</span>
|
|
</WidgetHead>
|
|
<WidgetBody>
|
|
<ReportChartShortcut
|
|
options={{
|
|
renderSerieName(names) {
|
|
return names[1];
|
|
},
|
|
}}
|
|
projectId={projectId}
|
|
range="30d"
|
|
chartType="linear"
|
|
breakdowns={[
|
|
{
|
|
id: 'A',
|
|
name: 'name',
|
|
},
|
|
]}
|
|
series={
|
|
events && events.length > 0
|
|
? events.map((name) => ({
|
|
id: name,
|
|
name,
|
|
displayName: name,
|
|
segment: 'event',
|
|
filters: filters ?? [],
|
|
type: 'event',
|
|
}))
|
|
: [
|
|
{
|
|
id: 'A',
|
|
name: '*',
|
|
displayName: 'All events',
|
|
segment: 'event',
|
|
filters: filters ?? [],
|
|
type: 'event',
|
|
},
|
|
]
|
|
}
|
|
/>
|
|
</WidgetBody>
|
|
</Widget>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|