add details button on overview

This commit is contained in:
Carl-Gerhard Lindesvärd
2024-05-20 09:45:30 +02:00
parent 4a7f21663f
commit 4350670bbc
13 changed files with 79 additions and 9 deletions

View File

@@ -0,0 +1,25 @@
import { pushModal } from '@/modals';
import { ScanEyeIcon } from 'lucide-react';
import type { IChartInput } from '@openpanel/validation';
type Props = {
chart: IChartInput;
};
const OverviewDetailsButton = ({ chart }: Props) => {
return (
<button
className="-mb-2 mt-5 flex w-full items-center justify-center gap-2 text-sm font-semibold"
onClick={() => {
pushModal('OverviewChartDetails', {
chart: chart,
});
}}
>
<ScanEyeIcon size={18} /> Details
</button>
);
};
export default OverviewDetailsButton;

View File

@@ -5,6 +5,7 @@ import { useEventQueryFilters } from '@/hooks/useEventQueryFilters';
import { cn } from '@/utils/cn';
import { Widget, WidgetBody } from '../../widget';
import OverviewDetailsButton from '../overview-details-button';
import { WidgetButtons, WidgetHead } from '../overview-widget';
import { useOverviewOptions } from '../useOverviewOptions';
import { useOverviewWidget } from '../useOverviewWidget';
@@ -121,6 +122,7 @@ export default function OverviewLatestEvents({
</WidgetHead>
<WidgetBody>
<LazyChart hideID {...widget.chart} previous={false} />
<OverviewDetailsButton chart={widget.chart} />
</WidgetBody>
</Widget>
</>

View File

@@ -9,6 +9,7 @@ import type { IChartType } from '@openpanel/validation';
import { LazyChart } from '../report/chart/LazyChart';
import { Widget, WidgetBody } from '../widget';
import { OverviewChartToggle } from './overview-chart-toggle';
import OverviewDetailsButton from './overview-details-button';
import { WidgetButtons, WidgetHead } from './overview-widget';
import { useOverviewOptions } from './useOverviewOptions';
import { useOverviewWidget } from './useOverviewWidget';
@@ -222,6 +223,7 @@ export default function OverviewTopDevices({
}
}}
/>
<OverviewDetailsButton chart={widget.chart} />
</WidgetBody>
</Widget>
</>

View File

@@ -1,17 +1,15 @@
'use client';
import { useState } from 'react';
import { ChartSwitch } from '@/components/report/chart';
import { LazyChart } from '@/components/report/chart/LazyChart';
import { Button } from '@/components/ui/button';
import { useEventQueryFilters } from '@/hooks/useEventQueryFilters';
import { cn } from '@/utils/cn';
import { BarChartIcon, LineChart, LineChartIcon } from 'lucide-react';
import type { IChartType } from '@openpanel/validation';
import { Widget, WidgetBody } from '../../widget';
import { OverviewChartToggle } from '../overview-chart-toggle';
import OverviewDetailsButton from '../overview-details-button';
import { WidgetButtons, WidgetHead } from '../overview-widget';
import { useOverviewOptions } from '../useOverviewOptions';
import { useOverviewWidget } from '../useOverviewWidget';
@@ -132,6 +130,7 @@ export default function OverviewTopEvents({
</WidgetHead>
<WidgetBody>
<LazyChart hideID {...widget.chart} previous={false} />
<OverviewDetailsButton chart={widget.chart} />
</WidgetBody>
</Widget>
</>

View File

@@ -10,6 +10,7 @@ import type { IChartType } from '@openpanel/validation';
import { LazyChart } from '../report/chart/LazyChart';
import { Widget, WidgetBody } from '../widget';
import { OverviewChartToggle } from './overview-chart-toggle';
import OverviewDetailsButton from './overview-details-button';
import { WidgetButtons, WidgetHead } from './overview-widget';
import { useOverviewOptions } from './useOverviewOptions';
import { useOverviewWidget } from './useOverviewWidget';
@@ -157,6 +158,7 @@ export default function OverviewTopGeo({ projectId }: OverviewTopGeoProps) {
}
}}
/>
<OverviewDetailsButton chart={widget.chart} />
</WidgetBody>
</Widget>
<Widget className="col-span-6 md:col-span-3">

View File

@@ -9,6 +9,7 @@ import type { IChartType } from '@openpanel/validation';
import { LazyChart } from '../report/chart/LazyChart';
import { Widget, WidgetBody } from '../widget';
import { OverviewChartToggle } from './overview-chart-toggle';
import OverviewDetailsButton from './overview-details-button';
import OverviewTopBots from './overview-top-bots';
import { WidgetButtons, WidgetHead } from './overview-widget';
import { useOverviewOptions } from './useOverviewOptions';
@@ -154,6 +155,7 @@ export default function OverviewTopPages({ projectId }: OverviewTopPagesProps) {
}}
/>
)}
<OverviewDetailsButton chart={widget.chart} />
</WidgetBody>
</Widget>
</>

View File

@@ -2,13 +2,16 @@
import { useState } from 'react';
import { useEventQueryFilters } from '@/hooks/useEventQueryFilters';
import { pushModal } from '@/modals';
import { cn } from '@/utils/cn';
import { ScanEyeIcon } from 'lucide-react';
import type { IChartType } from '@openpanel/validation';
import { LazyChart } from '../report/chart/LazyChart';
import { Widget, WidgetBody } from '../widget';
import { OverviewChartToggle } from './overview-chart-toggle';
import OverviewDetailsButton from './overview-details-button';
import { WidgetButtons, WidgetHead } from './overview-widget';
import { useOverviewOptions } from './useOverviewOptions';
import { useOverviewWidget } from './useOverviewWidget';
@@ -324,6 +327,7 @@ export default function OverviewTopSources({
}
}}
/>
<OverviewDetailsButton chart={widget.chart} />
</WidgetBody>
</Widget>
</>

View File

@@ -20,7 +20,7 @@ export function WidgetHead({ className, ...props }: WidgetHeadProps) {
return (
<WidgetHeadBase
className={cn(
'flex flex-col rounded-t-xl p-0 [&_.title]:flex [&_.title]:items-center [&_.title]:justify-between [&_.title]:p-4',
'flex flex-col rounded-t-xl p-0 [&_.title]:flex [&_.title]:items-center [&_.title]:justify-between [&_.title]:p-4 [&_.title]:font-semibold',
className
)}
{...props}

View File

@@ -20,6 +20,7 @@ export interface ChartContextType extends IChartInput {
editMode?: boolean;
hideID?: boolean;
onClick?: (item: IChartSerie) => void;
limit?: number;
}
type ChartProviderProps = {
@@ -37,6 +38,7 @@ const ChartContext = createContext<ChartContextType | null>({
metric: 'sum',
previous: false,
projectId: '',
limit: undefined,
});
export function ChartProvider({
@@ -44,6 +46,7 @@ export function ChartProvider({
editMode,
previous,
hideID,
limit,
...props
}: ChartProviderProps) {
return (
@@ -54,8 +57,9 @@ export function ChartProvider({
editMode: editMode ?? false,
previous: previous ?? false,
hideID: hideID ?? false,
limit,
}),
[editMode, previous, hideID, props]
[editMode, previous, hideID, limit, props]
)}
>
{children}

View File

@@ -17,11 +17,11 @@ interface ReportBarChartProps {
}
export function ReportBarChart({ data }: ReportBarChartProps) {
const { editMode, metric, onClick } = useChartContext();
const { editMode, metric, onClick, limit } = useChartContext();
const number = useNumber();
const series = useMemo(
() => (editMode ? data.series : data.series.slice(0, 10)),
[data, editMode]
() => (editMode ? data.series : data.series.slice(0, limit || 10)),
[data, editMode, limit]
);
const maxCount = Math.max(...series.map((serie) => serie.metrics[metric]));

View File

@@ -0,0 +1,25 @@
import { ChartSwitch } from '@/components/report/chart';
import { ScrollArea } from '@/components/ui/scroll-area';
import type { IChartInput } from '@openpanel/validation';
import { ModalContent, ModalHeader } from './Modal/Container';
type Props = {
chart: IChartInput;
};
const OverviewChartDetails = (props: Props) => {
return (
<ModalContent>
<ModalHeader title={props.chart.name} />
<ScrollArea className="-m-6 max-h-[calc(100vh-200px)]">
<div className="p-6">
<ChartSwitch {...props.chart} limit={999} chartType="bar" />
</div>
</ScrollArea>
</ModalContent>
);
};
export default OverviewChartDetails;

View File

@@ -62,6 +62,9 @@ const modals = {
DateRangerPicker: dynamic(() => import('./DateRangerPicker'), {
loading: Loading,
}),
OverviewChartDetails: dynamic(() => import('./OverviewChartDetails'), {
loading: Loading,
}),
};
export const {

View File

@@ -209,7 +209,9 @@ export const chartRouter = createTRPCRouter({
const final: FinalChart = {
events: input.events,
series: series.map((serie, index) => {
const previousSerie = previousSeries?.[index];
const previousSerie = previousSeries?.find(
(item) => item.name === serie.name
);
const metrics = {
sum: sum(serie.data.map((item) => item.count)),
average: round(average(serie.data.map((item) => item.count)), 2),