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}%
+
+
*/}
+
+
+
+ {/* {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({