diff --git a/src/client/App.tsx b/src/client/App.tsx index 0d879f5..3e56adb 100644 --- a/src/client/App.tsx +++ b/src/client/App.tsx @@ -2,7 +2,6 @@ import { BrowserRouter, Route, Routes, Navigate } from 'react-router-dom'; import { Layout } from './pages/Layout'; import { Dashboard } from './pages/Dashboard'; import { Login } from './pages/Login'; -import { Monitor } from './pages/Monitor'; import { Website } from './pages/Website'; import { SettingsPage } from './pages/Settings'; import { Servers } from './pages/Servers'; @@ -13,6 +12,7 @@ import { queryClient } from './api/cache'; import { TokenLoginContainer } from './components/TokenLoginContainer'; import React from 'react'; import { trpc, trpcClient } from './api/trpc'; +import { MonitorPage } from './pages/Monitor'; export const AppRoutes: React.FC = React.memo(() => { const { info } = useUserStore(); @@ -22,7 +22,7 @@ export const AppRoutes: React.FC = React.memo(() => { {info ? ( }> } /> - } /> + } /> } /> } /> } /> diff --git a/src/client/components/MonitorInfoEditor.tsx b/src/client/components/MonitorInfoEditor.tsx new file mode 100644 index 0000000..990ba40 --- /dev/null +++ b/src/client/components/MonitorInfoEditor.tsx @@ -0,0 +1,17 @@ +import React from 'react'; +import type { Monitor } from '@prisma/client'; + +type MonitorInfoEditorValues = Omit & { + id?: string; +}; + +interface MonitorInfoEditorProps { + initValue?: MonitorInfoEditorValues; + onSave: (value: MonitorInfoEditorValues) => void; +} +export const MonitorInfoEditor: React.FC = React.memo( + (props) => { + return
MonitorInfoEditor
; + } +); +MonitorInfoEditor.displayName = 'MonitorInfoEditor'; diff --git a/src/client/components/MonitorList.tsx b/src/client/components/MonitorList.tsx new file mode 100644 index 0000000..b438129 --- /dev/null +++ b/src/client/components/MonitorList.tsx @@ -0,0 +1,71 @@ +import clsx from 'clsx'; +import React, { useState } from 'react'; +import { trpc } from '../api/trpc'; +import { useCurrentWorkspaceId } from '../store/user'; +import { HealthBar } from './HealthBar'; +import { NoWorkspaceTip } from './NoWorkspaceTip'; + +export const MonitorList: React.FC = React.memo(() => { + const currentWorkspaceId = useCurrentWorkspaceId()!; + const { data: monitors = [] } = trpc.monitor.all.useQuery({ + workspaceId: currentWorkspaceId, + }); + + const [selectedMonitorId, setSelectedMonitorId] = useState( + null + ); + + if (!currentWorkspaceId) { + return ; + } + + return ( +
+ {monitors.map((monitor) => ( +
setSelectedMonitorId(monitor.id)} + > +
+ + {/* {monitor.monthOnlineRate * 100}% */} + 80% + +
+
+
{monitor.name}
+ {/*
+ {monitor.tags.map((tag) => ( + + {tag.label} + + ))} +
*/} +
+ +
+ ({ + status: 'health', + }))} + /> +
+
+ ))} +
+ ); +}); +MonitorList.displayName = 'MonitorList'; diff --git a/src/client/components/WebsiteList.tsx b/src/client/components/WebsiteList.tsx index 8b7c88d..0ab62d0 100644 --- a/src/client/components/WebsiteList.tsx +++ b/src/client/components/WebsiteList.tsx @@ -95,7 +95,6 @@ const WebsiteListTable: React.FC<{ workspaceId: string }> = React.memo( const navigate = useNavigate(); const handleEdit = useEvent((websiteId) => { - console.log(`/settings/website/${websiteId}`); navigate(`/settings/website/${websiteId}`); }); diff --git a/src/client/pages/Monitor.tsx b/src/client/pages/Monitor.tsx deleted file mode 100644 index 273689f..0000000 --- a/src/client/pages/Monitor.tsx +++ /dev/null @@ -1,117 +0,0 @@ -import clsx from 'clsx'; -import React from 'react'; -import { RouterOutput, trpc } from '../api/trpc'; -import { HealthBar } from '../components/HealthBar'; -import { useEvent } from '../hooks/useEvent'; -import { useCurrentWorkspaceId } from '../store/user'; - -interface MonitorHeartbeatInfo { - name: string; - dayOnlineRate: number; - monthOnlineRate: number; - certificateExpiredTo: string; - detectFrequency: number; // second - response: number; - avgResponse: number; // 24hour - tags: { label: string; color: string }[]; -} - -const demoMonitors = [ - { - name: 'Tianji', - dayOnlineRate: 1, - monthOnlineRate: 0.8, - certificateExpiredTo: '2023-9-2 15:49:56', - detectFrequency: 300, - response: 592, - avgResponse: 846, - tags: [{ label: 'Core', color: 'red' }], - }, -]; - -export const Monitor: React.FC = React.memo(() => { - const currentWorkspaceId = useCurrentWorkspaceId()!; - const { data: monitors = [] } = trpc.monitor.all.useQuery({ - workspaceId: currentWorkspaceId, - }); - - const handleCreateMonitor = useEvent(() => { - // TODO - }); - - return ( -
-
-
-
- Add new Montior -
-
-
-
-
- -
-
Info
-
-
- ); -}); -Monitor.displayName = 'Monitor'; - -const MonitorList: React.FC<{ - monitors: RouterOutput['monitor']['all']; -}> = React.memo((props) => { - const selectedMonitorName = 'Tianji1'; - - return ( -
- {props.monitors.map((monitor) => ( -
-
- - {/* {monitor.monthOnlineRate * 100}% */} - 80% - -
-
-
{monitor.name}
- {/*
- {monitor.tags.map((tag) => ( - - {tag.label} - - ))} -
*/} -
- -
- ({ - status: 'health', - }))} - /> -
-
- ))} -
- ); -}); -MonitorList.displayName = 'MonitorList'; diff --git a/src/client/pages/Monitor/Add.tsx b/src/client/pages/Monitor/Add.tsx new file mode 100644 index 0000000..7345535 --- /dev/null +++ b/src/client/pages/Monitor/Add.tsx @@ -0,0 +1,18 @@ +import React from 'react'; +import { MonitorInfoEditor } from '../../components/MonitorInfoEditor'; +import { useCurrentWorkspaceId } from '../../store/user'; + +export const MonitorAdd: React.FC = React.memo(() => { + const currentWorkspaceId = useCurrentWorkspaceId(); + + return ( +
+ { + // console.log(value); + }} + /> +
+ ); +}); +MonitorAdd.displayName = 'MonitorAdd'; diff --git a/src/client/pages/Monitor/Detail.tsx b/src/client/pages/Monitor/Detail.tsx new file mode 100644 index 0000000..99d7862 --- /dev/null +++ b/src/client/pages/Monitor/Detail.tsx @@ -0,0 +1,6 @@ +import React from 'react'; + +export const MonitorDetail: React.FC = React.memo(() => { + return
Detail
; +}); +MonitorDetail.displayName = 'MonitorDetail'; diff --git a/src/client/pages/Monitor/Edit.tsx b/src/client/pages/Monitor/Edit.tsx new file mode 100644 index 0000000..b066356 --- /dev/null +++ b/src/client/pages/Monitor/Edit.tsx @@ -0,0 +1,36 @@ +import React from 'react'; +import { useParams } from 'react-router'; +import { trpc } from '../../api/trpc'; +import { ErrorTip } from '../../components/ErrorTip'; +import { Loading } from '../../components/Loading'; +import { MonitorInfoEditor } from '../../components/MonitorInfoEditor'; +import { useCurrentWorkspaceId } from '../../store/user'; + +export const MonitorEdit: React.FC = React.memo(() => { + const { monitorId } = useParams<{ monitorId: string }>(); + const currentWorkspaceId = useCurrentWorkspaceId(); + const { data: monitor, isLoading } = trpc.monitor.get.useQuery({ + id: monitorId!, + workspaceId: currentWorkspaceId!, + }); + + if (isLoading) { + return ; + } + + if (!monitor) { + return ; + } + + return ( +
+ { + console.log(value); + }} + /> +
+ ); +}); +MonitorEdit.displayName = 'MonitorEdit'; diff --git a/src/client/pages/Monitor/Overview.tsx b/src/client/pages/Monitor/Overview.tsx new file mode 100644 index 0000000..b9ed6b6 --- /dev/null +++ b/src/client/pages/Monitor/Overview.tsx @@ -0,0 +1,6 @@ +import React from 'react'; + +export const MonitorOverview: React.FC = React.memo(() => { + return
Overview
; +}); +MonitorOverview.displayName = 'MonitorOverview'; diff --git a/src/client/pages/Monitor/index.tsx b/src/client/pages/Monitor/index.tsx new file mode 100644 index 0000000..7910c09 --- /dev/null +++ b/src/client/pages/Monitor/index.tsx @@ -0,0 +1,40 @@ +import React from 'react'; +import { Route, Routes, useNavigate } from 'react-router'; +import { MonitorList } from '../../components/MonitorList'; +import { MonitorAdd } from './Add'; +import { MonitorDetail } from './Detail'; +import { MonitorEdit } from './Edit'; +import { MonitorOverview } from './Overview'; + +export const MonitorPage: React.FC = React.memo(() => { + const navigate = useNavigate(); + + return ( +
+
+
+
navigate('/monitor/add')} + > + Add new Montior +
+
+
+
+
+ +
+
+ + } /> + } /> + } /> + } /> + +
+
+
+ ); +}); +MonitorPage.displayName = 'MonitorPage'; diff --git a/src/server/trpc/routers/monitor.ts b/src/server/trpc/routers/monitor.ts index 84209f7..4f53442 100644 --- a/src/server/trpc/routers/monitor.ts +++ b/src/server/trpc/routers/monitor.ts @@ -13,9 +13,27 @@ export const monitorRouter = router({ return monitors; }), - create: workspaceOwnerProcedure + get: workspaceProcedure .input( z.object({ + id: z.string(), + }) + ) + .query(async ({ input }) => { + const { id, workspaceId } = input; + const monitor = await prisma.monitor.findUnique({ + where: { + id, + workspaceId, + }, + }); + + return monitor; + }), + upsert: workspaceOwnerProcedure + .input( + z.object({ + id: z.string().optional(), name: z.string(), type: z.string(), active: z.boolean().default(true), @@ -27,6 +45,7 @@ export const monitorRouter = router({ ) .mutation(async ({ input }) => { const { + id, workspaceId, name, type, @@ -37,19 +56,35 @@ export const monitorRouter = router({ payload, } = input; - const monitor = await prisma.monitor.create({ - data: { - workspaceId, - name, - type, - active, - interval, - maxRetry, - retryInterval, - payload, - }, - }); - - return monitor; + if (id) { + return prisma.monitor.update({ + data: { + name, + type, + active, + interval, + maxRetry, + retryInterval, + payload, + }, + where: { + id, + workspaceId, + }, + }); + } else { + return prisma.monitor.create({ + data: { + workspaceId, + name, + type, + active, + interval, + maxRetry, + retryInterval, + payload, + }, + }); + } }), });