diff --git a/package.json b/package.json index 25c3d18..b115a63 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ "request-ip": "^3.3.0", "socket.io": "^4.7.2", "socket.io-client": "^4.7.2", + "str2int": "^1.1.0", "ts-node": "^10.9.1", "uuid": "^9.0.0", "vite-express": "^0.10.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 369fe0d..c3aa936 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -142,6 +142,9 @@ dependencies: socket.io-client: specifier: ^4.7.2 version: 4.7.2 + str2int: + specifier: ^1.1.0 + version: 1.1.0 ts-node: specifier: ^10.9.1 version: 10.9.1(@types/node@18.17.12)(typescript@5.2.2) @@ -6263,6 +6266,10 @@ packages: engines: {node: '>= 0.8'} dev: false + /str2int@1.1.0: + resolution: {integrity: sha512-Eb9eGdySBmA2cQyJaxsiB9a6IJ7t1RCQK6o3pUZf6dTI3CVq9TkMcUCVNoWeonv7mNza3Hcp3cf1j73vEhL4ag==} + dev: false + /streamx@2.15.1: resolution: {integrity: sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA==} dependencies: diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 985cb57..467f22a 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -54,16 +54,18 @@ model WorkspacesOnUsers { model Website { id String @id @unique @default(cuid()) @db.VarChar(30) + workspaceId String @db.VarChar(30) name String @db.VarChar(100) domain String? @db.VarChar(500) shareId String? @unique @db.VarChar(50) resetAt DateTime? @db.Timestamptz(6) - workspaceId String @db.VarChar(30) + monitorId String? @db.VarChar(30) createdAt DateTime @default(now()) @db.Timestamptz(6) updatedAt DateTime @updatedAt @db.Timestamptz(6) deletedAt DateTime? @db.Timestamptz(6) workspace Workspace @relation(fields: [workspaceId], references: [id], onUpdate: Cascade, onDelete: Cascade) + monitor Monitor? @relation(fields: [monitorId], references: [id], onUpdate: Cascade, onDelete: Cascade) sessions WebsiteSession[] eventData WebsiteEventData[] @@ -242,6 +244,7 @@ model Monitor { workspace Workspace @relation(fields: [workspaceId], references: [id]) + websites Website[] notifications Notification[] events MonitorEvent[] datas MonitorData[] diff --git a/src/client/api/model/website.ts b/src/client/api/model/website.ts index b6d23e2..bbdf131 100644 --- a/src/client/api/model/website.ts +++ b/src/client/api/model/website.ts @@ -3,18 +3,9 @@ import { DateUnit } from '../../utils/date'; import { queryClient } from '../cache'; import { request } from '../request'; import { getUserTimezone } from './user'; +import { Website as WebsiteInfo } from '@prisma/client'; -export interface WebsiteInfo { - id: string; - name: string; - domain: string | null; - shareId: string | null; - resetAt: string | null; - workspaceId: string; - createdAt: string | null; - updatedAt: string | null; - deletedAt: string | null; -} +export type { WebsiteInfo }; export async function getWorkspaceWebsites( workspaceId: string diff --git a/src/client/components/ColorTag.tsx b/src/client/components/ColorTag.tsx new file mode 100644 index 0000000..180755e --- /dev/null +++ b/src/client/components/ColorTag.tsx @@ -0,0 +1,29 @@ +import { Tag } from 'antd'; +import React, { useMemo } from 'react'; +import str2int from 'str2int'; + +const builtinColors = [ + 'magenta', + 'red', + 'volcano', + 'orange', + 'gold', + 'lime', + 'green', + 'cyan', + 'blue', + 'geekblue', + 'purple', +]; + +export const ColorTag: React.FC<{ label: string; colors?: string[] }> = + React.memo((props) => { + const { label, colors = builtinColors } = props; + const color = useMemo( + () => colors[str2int(label) % colors.length], + [label] + ); + + return {label}; + }); +ColorTag.displayName = 'ColorTag'; diff --git a/src/client/components/WebsiteInfo.tsx b/src/client/components/WebsiteInfo.tsx index 616e7f4..7103862 100644 --- a/src/client/components/WebsiteInfo.tsx +++ b/src/client/components/WebsiteInfo.tsx @@ -10,6 +10,7 @@ import { useCurrentWorkspaceId } from '../store/user'; import { ErrorTip } from './ErrorTip'; import { Loading } from './Loading'; import { NoWorkspaceTip } from './NoWorkspaceTip'; +import { MonitorPicker } from './monitor/MonitorPicker'; import { defaultErrorHandler, defaultSuccessHandler, trpc } from '../api/trpc'; import { useQueryClient } from '@tanstack/react-query'; import { useEvent } from '../hooks/useEvent'; @@ -35,12 +36,13 @@ export const WebsiteInfo: React.FC = React.memo(() => { }); const handleSave = useEvent( - async (values: { name: string; domain: string }) => { + async (values: { name: string; domain: string; monitorId: string }) => { await updateMutation.mutateAsync({ workspaceId, websiteId: websiteId!, name: values.name, domain: values.domain, + monitorId: values.monitorId, }); } ); @@ -84,6 +86,7 @@ export const WebsiteInfo: React.FC = React.memo(() => { id: website.id, name: website.name, domain: website.domain, + monitorId: website.monitorId, }} onFinish={handleSave} > @@ -101,6 +104,10 @@ export const WebsiteInfo: React.FC = React.memo(() => { + + + +