refactor: rename MetricsTable to WebsiteMetricsTable
This commit is contained in:
parent
daef9ff084
commit
1306187f01
@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { MetricsTable } from '../../website/MetricsTable';
|
import { WebsiteMetricsTable } from '../../website/WebsiteMetricsTable';
|
||||||
import { useGlobalRangeDate } from '../../../hooks/useGlobalRangeDate';
|
import { useGlobalRangeDate } from '../../../hooks/useGlobalRangeDate';
|
||||||
|
|
||||||
export const WebsiteEventItem: React.FC<{
|
export const WebsiteEventItem: React.FC<{
|
||||||
@ -10,7 +10,7 @@ export const WebsiteEventItem: React.FC<{
|
|||||||
const endAt = endDate.valueOf();
|
const endAt = endDate.valueOf();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MetricsTable
|
<WebsiteMetricsTable
|
||||||
websiteId={props.websiteId}
|
websiteId={props.websiteId}
|
||||||
type="event"
|
type="event"
|
||||||
title={['Events', 'Actions']}
|
title={['Events', 'Actions']}
|
||||||
|
@ -1,88 +0,0 @@
|
|||||||
import { Table } from 'antd';
|
|
||||||
import { ColumnsType } from 'antd/es/table/interface';
|
|
||||||
import React from 'react';
|
|
||||||
import { AppRouterOutput, trpc } from '../../api/trpc';
|
|
||||||
import { useCurrentWorkspaceId } from '../../store/user';
|
|
||||||
import { sum } from 'lodash-es';
|
|
||||||
import { formatNumber } from '../../utils/common';
|
|
||||||
import { useTranslation } from '@i18next-toolkit/react';
|
|
||||||
|
|
||||||
type MetricsItemType = AppRouterOutput['website']['metrics'][number];
|
|
||||||
|
|
||||||
interface MetricsTableProps {
|
|
||||||
websiteId: string;
|
|
||||||
title: [string, string];
|
|
||||||
type:
|
|
||||||
| 'url'
|
|
||||||
| 'language'
|
|
||||||
| 'referrer'
|
|
||||||
| 'browser'
|
|
||||||
| 'os'
|
|
||||||
| 'device'
|
|
||||||
| 'country'
|
|
||||||
| 'event';
|
|
||||||
startAt: number;
|
|
||||||
endAt: number;
|
|
||||||
}
|
|
||||||
export const MetricsTable: React.FC<MetricsTableProps> = React.memo((props) => {
|
|
||||||
const { websiteId, title, type, startAt, endAt } = props;
|
|
||||||
const workspaceId = useCurrentWorkspaceId();
|
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
const { isLoading, data: metrics = [] } = trpc.website.metrics.useQuery({
|
|
||||||
workspaceId,
|
|
||||||
websiteId,
|
|
||||||
type,
|
|
||||||
startAt,
|
|
||||||
endAt,
|
|
||||||
});
|
|
||||||
|
|
||||||
const total = sum(metrics.map((m) => m.y));
|
|
||||||
|
|
||||||
const columns: ColumnsType<MetricsItemType> = [
|
|
||||||
{
|
|
||||||
title: title[0],
|
|
||||||
dataIndex: 'x',
|
|
||||||
ellipsis: true,
|
|
||||||
render: (val) =>
|
|
||||||
val ?? <span className="italic opacity-60">{t('(None)')}</span>,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: title[1],
|
|
||||||
dataIndex: 'y',
|
|
||||||
width: 100,
|
|
||||||
align: 'center',
|
|
||||||
render: (val) => {
|
|
||||||
const percent = (Number(val) / total) * 100;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="flex">
|
|
||||||
<div className="w-12 text-right">{formatNumber(val)}</div>
|
|
||||||
<div className="inline-block w-12 relative border-l ml-1 px-1">
|
|
||||||
<div
|
|
||||||
className="bg-blue-300 absolute h-full bg-opacity-25 left-0 top-0 pointer-events-none"
|
|
||||||
style={{ width: `${percent}%` }}
|
|
||||||
/>
|
|
||||||
<span>{percent.toFixed(0)}%</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Table
|
|
||||||
rowKey="x"
|
|
||||||
loading={isLoading}
|
|
||||||
dataSource={metrics}
|
|
||||||
columns={columns}
|
|
||||||
pagination={{
|
|
||||||
pageSize: 10,
|
|
||||||
hideOnSinglePage: true,
|
|
||||||
}}
|
|
||||||
size="small"
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
MetricsTable.displayName = 'MetricsTable';
|
|
90
src/client/components/website/WebsiteMetricsTable.tsx
Normal file
90
src/client/components/website/WebsiteMetricsTable.tsx
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
import { Table } from 'antd';
|
||||||
|
import { ColumnsType } from 'antd/es/table/interface';
|
||||||
|
import React from 'react';
|
||||||
|
import { AppRouterOutput, trpc } from '../../api/trpc';
|
||||||
|
import { useCurrentWorkspaceId } from '../../store/user';
|
||||||
|
import { sum } from 'lodash-es';
|
||||||
|
import { formatNumber } from '../../utils/common';
|
||||||
|
import { useTranslation } from '@i18next-toolkit/react';
|
||||||
|
|
||||||
|
type MetricsItemType = AppRouterOutput['website']['metrics'][number];
|
||||||
|
|
||||||
|
interface MetricsTableProps {
|
||||||
|
websiteId: string;
|
||||||
|
title: [string, string];
|
||||||
|
type:
|
||||||
|
| 'url'
|
||||||
|
| 'language'
|
||||||
|
| 'referrer'
|
||||||
|
| 'browser'
|
||||||
|
| 'os'
|
||||||
|
| 'device'
|
||||||
|
| 'country'
|
||||||
|
| 'event';
|
||||||
|
startAt: number;
|
||||||
|
endAt: number;
|
||||||
|
}
|
||||||
|
export const WebsiteMetricsTable: React.FC<MetricsTableProps> = React.memo(
|
||||||
|
(props) => {
|
||||||
|
const { websiteId, title, type, startAt, endAt } = props;
|
||||||
|
const workspaceId = useCurrentWorkspaceId();
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const { isLoading, data: metrics = [] } = trpc.website.metrics.useQuery({
|
||||||
|
workspaceId,
|
||||||
|
websiteId,
|
||||||
|
type,
|
||||||
|
startAt,
|
||||||
|
endAt,
|
||||||
|
});
|
||||||
|
|
||||||
|
const total = sum(metrics.map((m) => m.y));
|
||||||
|
|
||||||
|
const columns: ColumnsType<MetricsItemType> = [
|
||||||
|
{
|
||||||
|
title: title[0],
|
||||||
|
dataIndex: 'x',
|
||||||
|
ellipsis: true,
|
||||||
|
render: (val) =>
|
||||||
|
val ?? <span className="italic opacity-60">{t('(None)')}</span>,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: title[1],
|
||||||
|
dataIndex: 'y',
|
||||||
|
width: 100,
|
||||||
|
align: 'center',
|
||||||
|
render: (val) => {
|
||||||
|
const percent = (Number(val) / total) * 100;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex">
|
||||||
|
<div className="w-12 text-right">{formatNumber(val)}</div>
|
||||||
|
<div className="inline-block w-12 relative border-l ml-1 px-1">
|
||||||
|
<div
|
||||||
|
className="bg-blue-300 absolute h-full bg-opacity-25 left-0 top-0 pointer-events-none"
|
||||||
|
style={{ width: `${percent}%` }}
|
||||||
|
/>
|
||||||
|
<span>{percent.toFixed(0)}%</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Table
|
||||||
|
rowKey="x"
|
||||||
|
loading={isLoading}
|
||||||
|
dataSource={metrics}
|
||||||
|
columns={columns}
|
||||||
|
pagination={{
|
||||||
|
pageSize: 10,
|
||||||
|
hideOnSinglePage: true,
|
||||||
|
}}
|
||||||
|
size="small"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
WebsiteMetricsTable.displayName = 'WebsiteMetricsTable';
|
@ -5,7 +5,7 @@ import { trpc } from '../../api/trpc';
|
|||||||
import { ErrorTip } from '../../components/ErrorTip';
|
import { ErrorTip } from '../../components/ErrorTip';
|
||||||
import { Loading } from '../../components/Loading';
|
import { Loading } from '../../components/Loading';
|
||||||
import { NotFoundTip } from '../../components/NotFoundTip';
|
import { NotFoundTip } from '../../components/NotFoundTip';
|
||||||
import { MetricsTable } from '../../components/website/MetricsTable';
|
import { WebsiteMetricsTable } from '../../components/website/WebsiteMetricsTable';
|
||||||
import { WebsiteOverview } from '../../components/website/WebsiteOverview';
|
import { WebsiteOverview } from '../../components/website/WebsiteOverview';
|
||||||
import { useGlobalRangeDate } from '../../hooks/useGlobalRangeDate';
|
import { useGlobalRangeDate } from '../../hooks/useGlobalRangeDate';
|
||||||
import { useCurrentWorkspaceId } from '../../store/user';
|
import { useCurrentWorkspaceId } from '../../store/user';
|
||||||
@ -45,7 +45,7 @@ export const WebsiteDetail: React.FC = React.memo(() => {
|
|||||||
<WebsiteOverview website={website} showDateFilter={true} />
|
<WebsiteOverview website={website} showDateFilter={true} />
|
||||||
</Card.Grid>
|
</Card.Grid>
|
||||||
<Card.Grid hoverable={false} className="!w-1/2 min-h-[470px]">
|
<Card.Grid hoverable={false} className="!w-1/2 min-h-[470px]">
|
||||||
<MetricsTable
|
<WebsiteMetricsTable
|
||||||
websiteId={websiteId}
|
websiteId={websiteId}
|
||||||
type="url"
|
type="url"
|
||||||
title={[t('Pages'), t('Views')]}
|
title={[t('Pages'), t('Views')]}
|
||||||
@ -54,7 +54,7 @@ export const WebsiteDetail: React.FC = React.memo(() => {
|
|||||||
/>
|
/>
|
||||||
</Card.Grid>
|
</Card.Grid>
|
||||||
<Card.Grid hoverable={false} className="!w-1/2 min-h-[470px]">
|
<Card.Grid hoverable={false} className="!w-1/2 min-h-[470px]">
|
||||||
<MetricsTable
|
<WebsiteMetricsTable
|
||||||
websiteId={websiteId}
|
websiteId={websiteId}
|
||||||
type="referrer"
|
type="referrer"
|
||||||
title={[t('Referrers'), t('Views')]}
|
title={[t('Referrers'), t('Views')]}
|
||||||
@ -63,7 +63,7 @@ export const WebsiteDetail: React.FC = React.memo(() => {
|
|||||||
/>
|
/>
|
||||||
</Card.Grid>
|
</Card.Grid>
|
||||||
<Card.Grid hoverable={false} className="!w-1/3 min-h-[470px]">
|
<Card.Grid hoverable={false} className="!w-1/3 min-h-[470px]">
|
||||||
<MetricsTable
|
<WebsiteMetricsTable
|
||||||
websiteId={websiteId}
|
websiteId={websiteId}
|
||||||
type="browser"
|
type="browser"
|
||||||
title={[t('Browser'), t('Visitors')]}
|
title={[t('Browser'), t('Visitors')]}
|
||||||
@ -72,7 +72,7 @@ export const WebsiteDetail: React.FC = React.memo(() => {
|
|||||||
/>
|
/>
|
||||||
</Card.Grid>
|
</Card.Grid>
|
||||||
<Card.Grid hoverable={false} className="!w-1/3 min-h-[470px]">
|
<Card.Grid hoverable={false} className="!w-1/3 min-h-[470px]">
|
||||||
<MetricsTable
|
<WebsiteMetricsTable
|
||||||
websiteId={websiteId}
|
websiteId={websiteId}
|
||||||
type="os"
|
type="os"
|
||||||
title={[t('OS'), t('Visitors')]}
|
title={[t('OS'), t('Visitors')]}
|
||||||
@ -81,7 +81,7 @@ export const WebsiteDetail: React.FC = React.memo(() => {
|
|||||||
/>
|
/>
|
||||||
</Card.Grid>
|
</Card.Grid>
|
||||||
<Card.Grid hoverable={false} className="!w-1/3 min-h-[470px]">
|
<Card.Grid hoverable={false} className="!w-1/3 min-h-[470px]">
|
||||||
<MetricsTable
|
<WebsiteMetricsTable
|
||||||
websiteId={websiteId}
|
websiteId={websiteId}
|
||||||
type="device"
|
type="device"
|
||||||
title={[t('Devices'), t('Visitors')]}
|
title={[t('Devices'), t('Visitors')]}
|
||||||
@ -90,7 +90,7 @@ export const WebsiteDetail: React.FC = React.memo(() => {
|
|||||||
/>
|
/>
|
||||||
</Card.Grid>
|
</Card.Grid>
|
||||||
<Card.Grid hoverable={false} className="!w-1/2 min-h-[470px]">
|
<Card.Grid hoverable={false} className="!w-1/2 min-h-[470px]">
|
||||||
<MetricsTable
|
<WebsiteMetricsTable
|
||||||
websiteId={websiteId}
|
websiteId={websiteId}
|
||||||
type="country"
|
type="country"
|
||||||
title={[t('Countries'), t('Visitors')]}
|
title={[t('Countries'), t('Visitors')]}
|
||||||
@ -108,7 +108,7 @@ export const WebsiteDetail: React.FC = React.memo(() => {
|
|||||||
</Button>
|
</Button>
|
||||||
</Card.Grid>
|
</Card.Grid>
|
||||||
<Card.Grid hoverable={false} className="!w-1/2 min-h-[470px]">
|
<Card.Grid hoverable={false} className="!w-1/2 min-h-[470px]">
|
||||||
<MetricsTable
|
<WebsiteMetricsTable
|
||||||
websiteId={websiteId}
|
websiteId={websiteId}
|
||||||
type="event"
|
type="event"
|
||||||
title={[t('Events'), t('Actions')]}
|
title={[t('Events'), t('Actions')]}
|
||||||
|
Loading…
Reference in New Issue
Block a user