From 539f24244a2b76d395cdca3ee19d29b7a26896d1 Mon Sep 17 00:00:00 2001 From: moonrailgun Date: Sun, 31 Mar 2024 20:27:00 +0800 Subject: [PATCH] feat(v2): add monitor health bar in list --- src/client/components/CommonList.tsx | 2 +- .../components/monitor/MonitorHealthBar.tsx | 67 +++++++++++++++++-- .../components/monitor/MonitorListItem.tsx | 1 + src/client/routes/monitor.tsx | 9 +++ 4 files changed, 72 insertions(+), 7 deletions(-) diff --git a/src/client/components/CommonList.tsx b/src/client/components/CommonList.tsx index b8edf09..05b01ca 100644 --- a/src/client/components/CommonList.tsx +++ b/src/client/components/CommonList.tsx @@ -88,7 +88,7 @@ export const CommonList: React.FC = React.memo((props) => { -
+
{item.content}
{Array.isArray(item.tags) && item.tags.length > 0 ? ( diff --git a/src/client/components/monitor/MonitorHealthBar.tsx b/src/client/components/monitor/MonitorHealthBar.tsx index bc489ec..d993220 100644 --- a/src/client/components/monitor/MonitorHealthBar.tsx +++ b/src/client/components/monitor/MonitorHealthBar.tsx @@ -8,6 +8,7 @@ import { useWatch } from '../../hooks/useWatch'; import { getMonitorProvider, getProviderDisplay } from './provider'; import { MonitorProvider } from './provider/types'; import { useTranslation } from '@i18next-toolkit/react'; +import clsx from 'clsx'; interface MonitorHealthBarProps { workspaceId: string; @@ -16,6 +17,7 @@ interface MonitorHealthBarProps { count?: number; size?: HealthBarProps['size']; showCurrentStatus?: boolean; + showPercent?: boolean; onBeatsItemUpdate?: ( items: ({ value: number; createdAt: string | Date } | null)[] ) => void; @@ -26,9 +28,10 @@ export const MonitorHealthBar: React.FC = React.memo( const { workspaceId, monitorId, - size, + size = 'small', count = 20, showCurrentStatus = false, + showPercent = false, } = props; const { data: recent = [] } = trpc.monitor.recentData.useQuery({ workspaceId, @@ -82,26 +85,78 @@ export const MonitorHealthBar: React.FC = React.memo( }); }, [items, provider]); + const upPercent = useMemo(() => { + let up = 0; + beats.forEach((b) => { + if (!b) { + return; + } + + if (b.status === 'health') { + up++; + } + }); + + return parseFloat(((up / beats.length) * 100).toFixed(1)); + }, [beats]); + useWatch([items], () => { props.onBeatsItemUpdate?.(items); }); return ( -
- +
+ {showPercent && ( + + {upPercent}% + + )} + +
+ +
{showCurrentStatus && ( <> {last(beats)?.status === 'health' ? ( -
+
{t('UP')}
) : last(beats)?.status === 'error' ? ( -
+
{t('DOWN')}
) : ( -
+
{t('NONE')}
)} diff --git a/src/client/components/monitor/MonitorListItem.tsx b/src/client/components/monitor/MonitorListItem.tsx index bcdb12d..7bf019d 100644 --- a/src/client/components/monitor/MonitorListItem.tsx +++ b/src/client/components/monitor/MonitorListItem.tsx @@ -85,6 +85,7 @@ export const MonitorListItem: React.FC<{ {upPercent}%
+
{monitorName}
{/*
diff --git a/src/client/routes/monitor.tsx b/src/client/routes/monitor.tsx index d4a7f49..c408018 100644 --- a/src/client/routes/monitor.tsx +++ b/src/client/routes/monitor.tsx @@ -2,6 +2,7 @@ import { trpc } from '@/api/trpc'; import { CommonHeader } from '@/components/CommonHeader'; import { CommonList } from '@/components/CommonList'; import { CommonWrapper } from '@/components/CommonWrapper'; +import { MonitorHealthBar } from '@/components/monitor/MonitorHealthBar'; import { Button } from '@/components/ui/button'; import { useDataReady } from '@/hooks/useDataReady'; import { useEvent } from '@/hooks/useEvent'; @@ -35,6 +36,14 @@ function MonitorComponent() { const items = data.map((item) => ({ id: item.id, title: item.name, + content: ( + + ), tags: [item.type], href: `/monitor/${item.id}`, }));