fix(api): filter empty values when using sum and average, added min and max

This commit is contained in:
Carl-Gerhard Lindesvärd
2025-06-04 12:45:26 +02:00
parent 5c5154ee86
commit 5b1e94e9ad
8 changed files with 142 additions and 135 deletions

View File

@@ -0,0 +1,92 @@
import {
ActivityIcon,
ClockIcon,
EqualApproximatelyIcon,
type LucideIcon,
SigmaIcon,
TrendingDownIcon,
TrendingUpIcon,
UserCheck2Icon,
UserCheckIcon,
UsersIcon,
} from 'lucide-react';
import { chartSegments } from '@openpanel/constants';
import { type IChartEventSegment, mapKeys } from '@openpanel/validation';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuShortcut,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { cn } from '@/utils/cn';
import { Button } from '../ui/button';
interface ReportChartTypeProps {
className?: string;
value: IChartEventSegment;
onChange: (segment: IChartEventSegment) => void;
}
export function ReportSegment({
className,
value,
onChange,
}: ReportChartTypeProps) {
const items = mapKeys(chartSegments).map((key) => ({
label: chartSegments[key],
value: key,
}));
const Icons: Record<IChartEventSegment, LucideIcon> = {
event: ActivityIcon,
user: UsersIcon,
session: ClockIcon,
user_average: UserCheck2Icon,
one_event_per_user: UserCheckIcon,
property_sum: SigmaIcon,
property_average: EqualApproximatelyIcon,
property_max: TrendingUpIcon,
property_min: TrendingDownIcon,
};
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
variant="outline"
icon={Icons[value]}
className={cn('justify-start', className)}
>
{items.find((item) => item.value === value)?.label}
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-56">
<DropdownMenuLabel>Available charts</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuGroup>
{items.map((item) => {
const Icon = Icons[item.value];
return (
<DropdownMenuItem
key={item.value}
onClick={() => onChange(item.value)}
className="group"
>
{item.label}
<DropdownMenuShortcut>
<Icon className="size-4 group-hover:text-blue-500 group-hover:scale-125 transition-all group-hover:rotate-12" />
</DropdownMenuShortcut>
</DropdownMenuItem>
);
})}
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
);
}

View File

@@ -3,7 +3,6 @@
import { ColorSquare } from '@/components/color-square';
import { Combobox } from '@/components/ui/combobox';
import { ComboboxAdvanced } from '@/components/ui/combobox-advanced';
import { DropdownMenuComposed } from '@/components/ui/dropdown-menu';
import { Input } from '@/components/ui/input';
import { useAppParams } from '@/hooks/useAppParams';
import { useDebounceFn } from '@/hooks/useDebounceFn';
@@ -28,7 +27,8 @@ import { CSS } from '@dnd-kit/utilities';
import { shortId } from '@openpanel/common';
import { alphabetIds } from '@openpanel/constants';
import type { IChartEvent } from '@openpanel/validation';
import { FilterIcon, GanttChartIcon, HandIcon, Users } from 'lucide-react';
import { FilterIcon, GanttChartIcon, HandIcon } from 'lucide-react';
import { ReportSegment } from '../ReportSegment';
import {
addEvent,
changeEvent,
@@ -82,7 +82,8 @@ function SortableEvent({
{(showSegment || showAddFilter) && (
<div className="flex gap-2 p-2 pt-0">
{showSegment && (
<DropdownMenuComposed
<ReportSegment
value={event.segment}
onChange={(segment) => {
dispatch(
changeEvent({
@@ -91,73 +92,7 @@ function SortableEvent({
}),
);
}}
items={[
{
value: 'event',
label: 'All events',
},
{
value: 'user',
label: 'Unique users',
},
{
value: 'session',
label: 'Unique sessions',
},
{
value: 'user_average',
label: 'Average event per user',
},
{
value: 'one_event_per_user',
label: 'One event per user',
},
{
value: 'property_sum',
label: 'Sum of property',
},
{
value: 'property_average',
label: 'Average of property',
},
]}
label="Segment"
>
<button
type="button"
className="flex items-center gap-1 rounded-md border border-border bg-card p-1 px-2 text-sm font-medium leading-none"
>
{event.segment === 'user' ? (
<>
<Users size={12} /> Unique users
</>
) : event.segment === 'session' ? (
<>
<Users size={12} /> Unique sessions
</>
) : event.segment === 'user_average' ? (
<>
<Users size={12} /> Average event per user
</>
) : event.segment === 'one_event_per_user' ? (
<>
<Users size={12} /> One event per user
</>
) : event.segment === 'property_sum' ? (
<>
<Users size={12} /> Sum of property
</>
) : event.segment === 'property_average' ? (
<>
<Users size={12} /> Average of property
</>
) : (
<>
<GanttChartIcon size={12} /> All events
</>
)}
</button>
</DropdownMenuComposed>
/>
)}
{showAddFilter && (
<PropertiesCombobox