1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
import { Grid, Icon, Row, Text } from '@umami/react-zen';
import { useEffect, useMemo } from 'react';
import { LinkButton } from '@/components/common/LinkButton';
import { LoadingPanel } from '@/components/common/LoadingPanel';
import { useMessages, useNavigation, useWebsiteMetricsQuery } from '@/components/hooks';
import { Maximize } from '@/components/icons';
import { MetricLabel } from '@/components/metrics/MetricLabel';
import { percentFilter } from '@/lib/filters';
import { ListTable, type ListTableProps } from './ListTable';
export interface MetricsTableProps extends ListTableProps {
websiteId: string;
type: string;
dataFilter?: (data: any) => any;
limit?: number;
showMore?: boolean;
filterLink?: boolean;
params?: Record<string, any>;
onDataLoad?: (data: any) => void;
}
export function MetricsTable({
websiteId,
type,
dataFilter,
limit,
showMore = false,
filterLink = true,
params,
onDataLoad,
...props
}: MetricsTableProps) {
const { updateParams } = useNavigation();
const { formatMessage, labels } = useMessages();
const { data, isLoading, isFetching, error } = useWebsiteMetricsQuery(websiteId, {
type,
limit,
...params,
});
const filteredData = useMemo(() => {
if (data) {
let items = data as any[];
if (dataFilter) {
if (Array.isArray(dataFilter)) {
items = dataFilter.reduce((arr, filter) => {
return filter(arr);
}, items);
} else {
items = dataFilter(items);
}
}
items = percentFilter(items);
return items.map(({ x, y, z, ...props }) => ({ label: x, count: y, percent: z, ...props }));
}
return [];
}, [data, dataFilter, limit, type]);
useEffect(() => {
if (data) {
onDataLoad?.(data);
}
}, [data]);
const renderLabel = (row: any) => {
return filterLink ? <MetricLabel type={type} data={row} /> : row.label;
};
return (
<LoadingPanel
data={data}
isFetching={isFetching}
isLoading={isLoading}
error={error}
minHeight="400px"
>
<Grid>
{data && <ListTable {...props} data={filteredData} renderLabel={renderLabel} />}
{showMore && limit && (
<Row justifyContent="center" alignItems="flex-end">
<LinkButton href={updateParams({ view: type })} variant="quiet">
<Icon size="sm">
<Maximize />
</Icon>
<Text>{formatMessage(labels.more)}</Text>
</LinkButton>
</Row>
)}
</Grid>
</LoadingPanel>
);
}
|