From 7f7c0519a08023e1629baedd086ae2292a579a39 Mon Sep 17 00:00:00 2001 From: JimmFly Date: Tue, 13 Aug 2024 14:38:39 +0800 Subject: [PATCH] feat(admin): add config page to admin (#7619) --- packages/frontend/admin/src/app.tsx | 4 + .../admin/src/modules/config/about.tsx | 88 +++++++ .../admin/src/modules/config/index.tsx | 221 ++++++++++++++++++ .../graphql/get-server-service-configs.gql | 6 + .../frontend/graphql/src/graphql/index.ts | 14 ++ packages/frontend/graphql/src/schema.ts | 18 ++ 6 files changed, 351 insertions(+) create mode 100644 packages/frontend/admin/src/modules/config/about.tsx create mode 100644 packages/frontend/admin/src/modules/config/index.tsx create mode 100644 packages/frontend/graphql/src/graphql/get-server-service-configs.gql diff --git a/packages/frontend/admin/src/app.tsx b/packages/frontend/admin/src/app.tsx index 921338fbe7..331fe982a5 100644 --- a/packages/frontend/admin/src/app.tsx +++ b/packages/frontend/admin/src/app.tsx @@ -55,6 +55,10 @@ export const router = _createBrowserRouter( path: '/admin/setup', lazy: () => import('./modules/setup'), }, + { + path: '/admin/config', + lazy: () => import('./modules/config'), + }, ], }, ], diff --git a/packages/frontend/admin/src/modules/config/about.tsx b/packages/frontend/admin/src/modules/config/about.tsx new file mode 100644 index 0000000000..8812c09051 --- /dev/null +++ b/packages/frontend/admin/src/modules/config/about.tsx @@ -0,0 +1,88 @@ +import { buttonVariants } from '@affine/admin/components/ui/button'; +import { Separator } from '@affine/admin/components/ui/separator'; +import { cn } from '@affine/admin/utils'; +import { + AlbumIcon, + ChevronRightIcon, + GithubIcon, + MailWarningIcon, + UploadCloudIcon, +} from 'lucide-react'; +import { z } from 'zod'; + +const appChannelSchema = z.enum(['stable', 'canary', 'beta', 'internal']); + +type Channel = z.infer; + +const appNames = { + stable: 'AFFiNE', + canary: 'AFFiNE Canary', + beta: 'AFFiNE Beta', + internal: 'AFFiNE Internal', +} satisfies Record; + +const links = [ + { + href: runtimeConfig.githubUrl, + icon: , + label: 'Star AFFiNE on GitHub', + }, + { + href: runtimeConfig.githubUrl, + icon: , + label: 'Report an Issue', + }, + { + href: 'https://docs.affine.pro/docs/self-host-affine', + icon: , + label: 'Self-host Document', + }, + { + href: 'https://affine.pro/pricing', + icon: , + label: 'Upgrade to Pro', + }, +]; + +export function AboutAFFiNE() { + const { appBuildType, appVersion, editorVersion } = runtimeConfig; + const appName = appNames[appBuildType]; + + return ( +
+
+ About AFFiNE +
+
+
+ {links.map(({ href, icon, label }, index) => ( +
+ +
+ {icon} + {label} +
+
+ +
+
+ {index < links.length - 1 && } +
+ ))} +
+
+
+
{`App Version: ${appName} ${appVersion}`}
+
{`Editor Version: ${editorVersion}`}
+
+
+ ); +} diff --git a/packages/frontend/admin/src/modules/config/index.tsx b/packages/frontend/admin/src/modules/config/index.tsx new file mode 100644 index 0000000000..70f4578beb --- /dev/null +++ b/packages/frontend/admin/src/modules/config/index.tsx @@ -0,0 +1,221 @@ +import { + Card, + CardContent, + CardHeader, + CardTitle, +} from '@affine/admin/components/ui/card'; +import { ScrollArea } from '@affine/admin/components/ui/scroll-area'; +import { Separator } from '@affine/admin/components/ui/separator'; +import { useQuery } from '@affine/core/hooks/use-query'; +import { getServerServiceConfigsQuery } from '@affine/graphql'; + +import { Layout } from '../layout'; +import { AboutAFFiNE } from './about'; + +type ServerConfig = { + externalUrl: string; + https: boolean; + host: string; + port: number; + path: string; +}; + +type MailerConfig = { + host: string; + port: number; + sender: string; +}; + +type DatabaseConfig = { + host: string; + port: number; + user: string; + database: string; +}; + +type ServerServiceConfig = { + name: string; + config: ServerConfig | MailerConfig | DatabaseConfig; +}; + +export function Config() { + return } />; +} + +export function ConfigPage() { + return ( +
+
+
Config
+
+ + + + + +
+ ); +} + +const ServerCard = ({ serverConfig }: { serverConfig?: ServerConfig }) => { + if (!serverConfig) return null; + return ( + + + Server + + +
+
+
Domain
+
+ {serverConfig.host} +
+
+
+
Port
+
+ {serverConfig.port} +
+
+
+
HTTPS Prefix
+
+ {serverConfig.https.toString()} +
+
+
+
External Url
+
+ {serverConfig.externalUrl} +
+
+
+
+
+ ); +}; +const DatabaseCard = ({ + databaseConfig, +}: { + databaseConfig?: DatabaseConfig; +}) => { + if (!databaseConfig) return null; + return ( + + + Database + + +
+
+
Domain
+
+ {databaseConfig.host} +
+
+
+
Port
+
+ {databaseConfig.port} +
+
+
+
User
+
+ {databaseConfig.user} +
+
+
+
Database
+
+ {databaseConfig.database} +
+
+
+
+
+ ); +}; +const MailerCard = ({ mailerConfig }: { mailerConfig?: MailerConfig }) => { + if (!mailerConfig) return null; + return ( + + + Email + + +
+
+
Provider Domain
+
+ {mailerConfig.host} +
+
+
+
Port
+
+ {mailerConfig.port} +
+
+
+
Sender
+
+ {mailerConfig.sender} +
+
+
+
+
+ ); +}; + +export function ServerServiceConfig() { + const { data } = useQuery({ + query: getServerServiceConfigsQuery, + }); + const server = data.serverServiceConfigs.find( + (service: ServerServiceConfig) => service.name === 'server' + ); + const mailer = data.serverServiceConfigs.find( + (service: ServerServiceConfig) => service.name === 'mailer' + ); + const database = data.serverServiceConfigs.find( + (service: ServerServiceConfig) => service.name === 'database' + ); + + const serverConfig = server?.config as ServerConfig | undefined; + const mailerConfig = mailer?.config as MailerConfig | undefined; + const databaseConfig = database?.config as DatabaseConfig | undefined; + + return ( +
+
+ Server Config +
+
+
+ + +
+
+ +
+ + These settings are controlled by Docker environment variables. + Refer to the + + + Selfhost documentation. + +
+
+
+
+ ); +} + +export { Config as Component }; diff --git a/packages/frontend/graphql/src/graphql/get-server-service-configs.gql b/packages/frontend/graphql/src/graphql/get-server-service-configs.gql new file mode 100644 index 0000000000..279e77d15a --- /dev/null +++ b/packages/frontend/graphql/src/graphql/get-server-service-configs.gql @@ -0,0 +1,6 @@ +query getServerServiceConfigs { + serverServiceConfigs { + name + config + } +} diff --git a/packages/frontend/graphql/src/graphql/index.ts b/packages/frontend/graphql/src/graphql/index.ts index a8537c5caa..288b206d45 100644 --- a/packages/frontend/graphql/src/graphql/index.ts +++ b/packages/frontend/graphql/src/graphql/index.ts @@ -515,6 +515,20 @@ query getServerRuntimeConfig { }`, }; +export const getServerServiceConfigsQuery = { + id: 'getServerServiceConfigsQuery' as const, + operationName: 'getServerServiceConfigs', + definitionName: 'serverServiceConfigs', + containsFile: false, + query: ` +query getServerServiceConfigs { + serverServiceConfigs { + name + config + } +}`, +}; + export const getUserByEmailQuery = { id: 'getUserByEmailQuery' as const, operationName: 'getUserByEmail', diff --git a/packages/frontend/graphql/src/schema.ts b/packages/frontend/graphql/src/schema.ts index 005b5b925c..77ce8e7bed 100644 --- a/packages/frontend/graphql/src/schema.ts +++ b/packages/frontend/graphql/src/schema.ts @@ -1702,6 +1702,19 @@ export type GetServerRuntimeConfigQuery = { }>; }; +export type GetServerServiceConfigsQueryVariables = Exact<{ + [key: string]: never; +}>; + +export type GetServerServiceConfigsQuery = { + __typename?: 'Query'; + serverServiceConfigs: Array<{ + __typename?: 'ServerServiceConfig'; + name: string; + config: any; + }>; +}; + export type GetUserByEmailQueryVariables = Exact<{ email: Scalars['String']['input']; }>; @@ -2424,6 +2437,11 @@ export type Queries = variables: GetServerRuntimeConfigQueryVariables; response: GetServerRuntimeConfigQuery; } + | { + name: 'getServerServiceConfigsQuery'; + variables: GetServerServiceConfigsQueryVariables; + response: GetServerServiceConfigsQuery; + } | { name: 'getUserByEmailQuery'; variables: GetUserByEmailQueryVariables;