From e5e77dbdeeeecb773237b84e3c671dd16e61d458 Mon Sep 17 00:00:00 2001 From: moonrailgun Date: Sun, 13 Oct 2024 22:38:07 +0800 Subject: [PATCH] refactor: change public summary display logic old is recent data, now is monthly data --- src/client/components/HealthBar.tsx | 2 +- .../components/monitor/StatusPage/Body.tsx | 97 ++++++++++++++++--- src/server/model/monitor/index.ts | 31 +++++- src/server/trpc/routers/monitor.ts | 31 ++++++ 4 files changed, 142 insertions(+), 19 deletions(-) diff --git a/src/client/components/HealthBar.tsx b/src/client/components/HealthBar.tsx index 0485557..8a4dbff 100644 --- a/src/client/components/HealthBar.tsx +++ b/src/client/components/HealthBar.tsx @@ -3,7 +3,7 @@ import { cn } from '@/utils/style'; import clsx from 'clsx'; import React from 'react'; -type HealthStatus = 'health' | 'error' | 'warning' | 'none'; +export type HealthStatus = 'health' | 'error' | 'warning' | 'none'; export interface HealthBarBeat { title?: string; diff --git a/src/client/components/monitor/StatusPage/Body.tsx b/src/client/components/monitor/StatusPage/Body.tsx index bdca06b..61ec953 100644 --- a/src/client/components/monitor/StatusPage/Body.tsx +++ b/src/client/components/monitor/StatusPage/Body.tsx @@ -4,6 +4,10 @@ import { bodySchema } from './schema'; import { Empty } from 'antd'; import { useTranslation } from '@i18next-toolkit/react'; import { MonitorListItem } from '../MonitorListItem'; +import { cn } from '@/utils/style'; +import { Tooltip } from '@/components/ui/tooltip'; +import { MonitorHealthBar } from '../MonitorHealthBar'; +import { HealthBar, HealthStatus } from '@/components/HealthBar'; interface StatusPageBodyProps { workspaceId: string; @@ -62,29 +66,90 @@ export const StatusItemMonitor: React.FC<{ showCurrent: boolean; workspaceId: string; }> = React.memo((props) => { - const { data: list = [], isLoading } = trpc.monitor.getPublicInfo.useQuery({ - monitorIds: [props.id], + const { t } = useTranslation(); + const { data: info } = trpc.monitor.getPublicInfo.useQuery( + { + monitorIds: [props.id], + }, + { + select: (data) => data[0], + } + ); + + const { data: list = [], isLoading } = trpc.monitor.publicSummary.useQuery({ + workspaceId: props.workspaceId, + monitorId: props.id, }); if (isLoading) { return null; } - const item = list[0]; - - if (!item) { - return null; - } - return ( - +
+ {/*
+ + {upPercent}% + +
*/} + +
+
{info?.name}
+
+ + {/* {props.showCurrent && latestResponse && ( + +
+ {latestResponse} +
+
+ )} */} + +
+ { + let status: HealthStatus = 'none'; + + if (item.upRate === 1) { + status = 'health'; + } else if (item.upRate === 0 && item.totalCount === 0) { + status = 'none'; + } else if (item.upCount === 0 && item.totalCount !== 0) { + status = 'error'; + } else { + status = 'warning'; + } + + return { + status, + title: `${item.day} | (${item.upCount}/${item.totalCount}) ${item.upRate}%`, + }; + })} + /> +
+
); + + // return ( + // + // ); }); StatusItemMonitor.displayName = 'StatusItemMonitor'; diff --git a/src/server/model/monitor/index.ts b/src/server/model/monitor/index.ts index f63af05..5abf56e 100644 --- a/src/server/model/monitor/index.ts +++ b/src/server/model/monitor/index.ts @@ -1,3 +1,4 @@ +import dayjs from 'dayjs'; import { prisma } from '../_client.js'; import { monitorPublicInfoSchema } from '../_schema/monitor.js'; import { MonitorManager } from './manager.js'; @@ -68,7 +69,7 @@ export function getMonitorRecentData( .then((arr) => arr.reverse()); } -export function getMonitorSummaryWithDay( +export async function getMonitorSummaryWithDay( monitorId: string, beforeDay: number = 30 ) { @@ -79,7 +80,7 @@ export function getMonitorSummaryWithDay( up_rate: number; } - return prisma.$queryRaw` + const list = await prisma.$queryRaw` SELECT DATE("createdAt") AS day, COUNT(1) AS total_count, @@ -94,4 +95,30 @@ export function getMonitorSummaryWithDay( DATE("createdAt") ORDER BY day;`; + + const map: Record = {}; + for (const item of list) { + const date = dayjs(item.day).format('YYYY-MM-DD'); + map[date] = item; + } + + return Array.from({ length: beforeDay }).map((_, i) => { + const target = dayjs().subtract(i, 'days').format('YYYY-MM-DD'); + + if (map[target]) { + return { + day: target, + totalCount: Number(map[target].total_count), + upCount: Number(map[target].up_count), + upRate: Number(Number(map[target].up_rate).toFixed(1)), + }; + } else { + return { + day: target, + totalCount: 0, + upCount: 0, + upRate: 0, + }; + } + }); } diff --git a/src/server/trpc/routers/monitor.ts b/src/server/trpc/routers/monitor.ts index 6e894e7..fab6bdf 100644 --- a/src/server/trpc/routers/monitor.ts +++ b/src/server/trpc/routers/monitor.ts @@ -11,6 +11,7 @@ import { getMonitorData, getMonitorPublicInfos, getMonitorRecentData, + getMonitorSummaryWithDay, monitorManager, } from '../../model/monitor/index.js'; import dayjs from 'dayjs'; @@ -330,6 +331,36 @@ export const monitorRouter = router({ return getMonitorRecentData(workspaceId, monitorId, take); }), + publicSummary: publicProcedure + .meta( + buildMonitorOpenapi({ + method: 'GET', + protect: false, + path: '/{monitorId}/publicSummary', + }) + ) + .input( + z.object({ + workspaceId: z.string().cuid2(), + monitorId: z.string().cuid2(), + }) + ) + .output( + z.array( + z.object({ + day: z.string(), + totalCount: z.number(), + upCount: z.number(), + upRate: z.number(), + }) + ) + ) + .query(async ({ input }) => { + const { monitorId } = input; + const summary = await getMonitorSummaryWithDay(monitorId, 30); + + return summary; + }), dataMetrics: workspaceProcedure .meta( buildMonitorOpenapi({