Feature/move list to client (#50)

This commit is contained in:
Carl-Gerhard Lindesvärd
2024-09-01 15:02:12 +02:00
committed by GitHub
parent c2abdaadf2
commit 668434d246
181 changed files with 2922 additions and 1959 deletions

View File

@@ -62,10 +62,10 @@ export function PreviousDiffIndicator({
const renderIcon = () => {
if (state === 'positive') {
return <ArrowUpIcon strokeWidth={3} size={12} color="#000" />;
return <ArrowUpIcon strokeWidth={3} size={10} color="#000" />;
}
if (state === 'negative') {
return <ArrowDownIcon strokeWidth={3} size={12} color="#000" />;
return <ArrowDownIcon strokeWidth={3} size={10} color="#000" />;
}
return null;
};
@@ -74,7 +74,7 @@ export function PreviousDiffIndicator({
<>
<div
className={cn(
'flex items-center gap-1 font-medium',
'font-mono flex items-center gap-1 font-medium',
size === 'lg' && 'gap-2',
className
)}

View File

@@ -89,21 +89,21 @@ export function MetricCard({
)}
</AutoSizer>
</div>
<div className="relative">
<div className="col relative gap-2">
<div className="flex items-center justify-between gap-2">
<div className="flex min-w-0 items-center gap-2 text-left font-semibold">
<span className="overflow-hidden text-ellipsis whitespace-nowrap text-muted-foreground">
<div className="flex min-w-0 items-center gap-2 text-left">
<span className="truncate text-muted-foreground">
<SerieName name={serie.names} />
</span>
</div>
</div>
<div className="flex items-end justify-between">
<div className="overflow-hidden text-ellipsis whitespace-nowrap text-2xl font-bold">
<div className="font-mono truncate text-3xl font-bold">
{renderValue(serie.metrics[metric], 'ml-1 font-light text-xl')}
</div>
<PreviousDiffIndicator
{...previous}
className="text-xs text-muted-foreground"
className="text-sm text-muted-foreground"
/>
</div>
</div>

View File

@@ -37,7 +37,7 @@ export function ReportBarChart({ data }: ReportBarChartProps) {
return (
<div
className={cn(
'flex flex-col text-xs',
'flex flex-col text-sm',
editMode ? 'card gap-2 p-4 text-base' : '-m-3 gap-1'
)}
>
@@ -60,9 +60,9 @@ export function ReportBarChart({ data }: ReportBarChartProps) {
: {})}
>
<div
className="absolute bottom-0 left-0 top-0 rounded bg-def-200"
className="absolute bottom-0.5 left-1 right-1 top-0.5 rounded bg-def-200"
style={{
width: `${(serie.metrics.sum / maxCount) * 100}%`,
width: `calc(${(serie.metrics.sum / maxCount) * 100}% - 8px)`,
}}
/>
<div className="relative z-10 flex w-full flex-1 items-center gap-4 overflow-hidden px-3 py-2">
@@ -70,7 +70,7 @@ export function ReportBarChart({ data }: ReportBarChartProps) {
<SerieIcon name={serie.names[0]} />
<SerieName name={serie.names} />
</div>
<div className="flex flex-shrink-0 items-center justify-end gap-4">
<div className="font-mono flex flex-shrink-0 items-center justify-end gap-4">
<PreviousDiffIndicator
{...serie.metrics.previous?.[metric]}
/>

View File

@@ -42,7 +42,7 @@ export function ReportChartTooltip({
const hidden = sorted.slice(limit);
return (
<div className="flex min-w-[180px] flex-col gap-2 rounded-xl border bg-card p-3 text-sm shadow-xl">
<div className="flex min-w-[180px] flex-col gap-2 rounded-xl border bg-card p-3 shadow-xl">
{visible.map((item, index) => {
// If we have a <Cell /> component, payload can be nested
const payload = item.payload.payload ?? item.payload;
@@ -65,20 +65,22 @@ export function ReportChartTooltip({
className="w-[3px] rounded-full"
style={{ background: data.color }}
/>
<div className="flex flex-1 flex-col">
<div className="col flex-1 gap-1">
<div className="flex items-center gap-1">
<SerieIcon name={data.names} />
<SerieName name={data.names} />
</div>
<div className="flex justify-between gap-8">
<div>{number.formatWithUnit(data.count, unit)}</div>
<div className="flex gap-1">
<PreviousDiffIndicator {...data.previous}>
{!!data.previous &&
`(${number.formatWithUnit(data.previous.value, unit)})`}
</PreviousDiffIndicator>
<div className="font-mono flex justify-between gap-8 font-medium">
<div className="row gap-1">
{number.formatWithUnit(data.count, unit)}
{!!data.previous && (
<span className="text-muted-foreground">
({number.formatWithUnit(data.previous.value, unit)})
</span>
)}
</div>
<PreviousDiffIndicator {...data.previous} />
</div>
</div>
</div>

View File

@@ -1,6 +1,6 @@
'use client';
import React, { useCallback, useMemo } from 'react';
import React, { useCallback } from 'react';
import { useFormatDateInterval } from '@/hooks/useFormatDateInterval';
import { useNumber } from '@/hooks/useNumerFormatter';
import { useRechartDataModel } from '@/hooks/useRechartDataModel';
@@ -10,24 +10,19 @@ import type { IChartData } from '@/trpc/client';
import { cn } from '@/utils/cn';
import { getChartColor } from '@/utils/theme';
import { isSameDay, isSameHour, isSameMonth } from 'date-fns';
import { SplineIcon } from 'lucide-react';
import { last, pathOr } from 'ramda';
import { last } from 'ramda';
import {
Area,
CartesianGrid,
ComposedChart,
Legend,
Line,
LineChart,
ReferenceLine,
Tooltip,
XAxis,
YAxis,
} from 'recharts';
import type { IServiceReference } from '@openpanel/db';
import type { IChartLineType, IInterval } from '@openpanel/validation';
import { getYAxisWidth } from './chart-utils';
import { useChartContext } from './ChartProvider';
import { ReportChartTooltip } from './ReportChartTooltip';

View File

@@ -48,6 +48,7 @@ interface ChartRootShortcutProps {
chartType?: IChartProps['chartType'];
interval?: IChartProps['interval'];
events: IChartProps['events'];
breakdowns?: IChartProps['breakdowns'];
}
export const ChartRootShortcut = ({
@@ -57,12 +58,13 @@ export const ChartRootShortcut = ({
chartType = 'linear',
interval = 'day',
events,
breakdowns,
}: ChartRootShortcutProps) => {
return (
<ChartRoot
projectId={projectId}
range={range}
breakdowns={[]}
breakdowns={breakdowns ?? []}
previous={previous}
chartType={chartType}
interval={interval}

View File

@@ -132,7 +132,7 @@ export function FunnelSteps({
</div>
{finalStep ? (
<div className={cn('flex flex-col items-center p-4')}>
<div className="text-xs font-medium uppercase">
<div className="text-sm font-medium uppercase">
Conversion
</div>
<div
@@ -143,13 +143,13 @@ export function FunnelSteps({
>
{round(step.percent, 1)}%
</div>
<div className="mt-0 text-sm font-medium uppercase text-muted-foreground">
<div className="mt-0 font-medium uppercase text-muted-foreground">
Converted {step.current} of {totalSessions} sessions
</div>
</div>
) : (
<div className={cn('flex flex-col items-center p-4')}>
<div className="text-xs font-medium uppercase">Dropoff</div>
<div className="text-sm font-medium uppercase">Dropoff</div>
<div
className={cn(
'text-3xl font-bold uppercase',
@@ -158,7 +158,7 @@ export function FunnelSteps({
>
{round(step.dropoff.percent, 1)}%
</div>
<div className="mt-0 text-sm font-medium uppercase text-muted-foreground">
<div className="mt-0 font-medium uppercase text-muted-foreground">
Lost {step.dropoff.count} sessions
</div>
</div>

View File

@@ -1,17 +1,14 @@
'use client';
import { ColorSquare } from '@/components/color-square';
import { AutoSizer } from '@/components/react-virtualized-auto-sizer';
import { TooltipComplete } from '@/components/tooltip-complete';
import { Progress } from '@/components/ui/progress';
import { Widget, WidgetBody } from '@/components/widget';
import type { RouterOutputs } from '@/trpc/client';
import { cn } from '@/utils/cn';
import { round } from '@/utils/math';
import { getChartColor } from '@/utils/theme';
import { AlertCircleIcon, TrendingUp } from 'lucide-react';
import { AlertCircleIcon } from 'lucide-react';
import { last } from 'ramda';
import { Cell, Pie, PieChart } from 'recharts';
import { getPreviousMetric } from '@openpanel/common';
import { alphabetIds } from '@openpanel/constants';
@@ -40,7 +37,7 @@ function InsightCard({
}) {
return (
<div className="flex flex-col rounded-lg border border-border p-4 py-3">
<span className="text-sm">{title}</span>
<span className="">{title}</span>
<div className="whitespace-nowrap text-lg">{children}</div>
</div>
);

View File

@@ -54,7 +54,7 @@ export function EventPropertiesCombobox({
>
<button
className={cn(
'flex items-center gap-1 rounded-md border border-border p-1 px-2 text-xs font-medium leading-none',
'flex items-center gap-1 rounded-md border border-border p-1 px-2 text-sm font-medium leading-none',
!event.property && 'border-destructive text-destructive'
)}
>

View File

@@ -106,7 +106,7 @@ export function ReportEvents() {
</div>
{/* Segment and Filter buttons */}
<div className="flex gap-2 p-2 pt-0 text-sm">
<div className="flex gap-2 p-2 pt-0 ">
<DropdownMenuComposed
onChange={(segment) => {
dispatch(
@@ -148,7 +148,7 @@ export function ReportEvents() {
]}
label="Segment"
>
<button className="flex items-center gap-1 rounded-md border border-border bg-card p-1 px-2 text-xs font-medium leading-none">
<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
@@ -216,7 +216,7 @@ export function ReportEvents() {
/>
</div>
<label
className="mt-4 flex cursor-pointer select-none items-center gap-2 text-sm font-medium"
className="mt-4 flex cursor-pointer select-none items-center gap-2 font-medium"
htmlFor="previous"
>
<Checkbox

View File

@@ -103,7 +103,7 @@ export function FilterItem({ filter, event }: FilterProps) {
<ColorSquare className="bg-emerald-500">
<SlidersHorizontal size={10} />
</ColorSquare>
<div className="flex flex-1 text-sm">
<div className="flex flex-1 ">
<RenderDots truncate>{filter.name}</RenderDots>
</div>
<Button variant="ghost" size="sm" onClick={removeFilter}>

View File

@@ -63,7 +63,7 @@ export function FiltersCombobox({ event }: FiltersComboboxProps) {
);
}}
>
<button className="flex items-center gap-1 rounded-md border border-border bg-card p-1 px-2 text-xs font-medium leading-none">
<button className="flex items-center gap-1 rounded-md border border-border bg-card p-1 px-2 text-sm font-medium leading-none">
<FilterIcon size={12} /> Add filter
</button>
</Combobox>