mirror of
https://github.com/certimate-go/certimate.git
synced 2026-09-24 23:10:13 +08:00
Merge branch 'dev' of https://github.com/fudiwei/certimate into next
This commit is contained in:
Vendored
+2
-1
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"bradlc.vscode-tailwindcss",
|
||||
"esbenp.prettier-vscode"
|
||||
"dbaeumer.vscode-eslint",
|
||||
"esbenp.prettier-vscode",
|
||||
]
|
||||
}
|
||||
Vendored
+2
-2
@@ -5,7 +5,7 @@
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit"
|
||||
},
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.defaultFormatter": "dbaeumer.vscode-eslint",
|
||||
"editor.formatOnSave": true,
|
||||
"go.useLanguageServer": true,
|
||||
"gopls": {
|
||||
@@ -18,4 +18,4 @@
|
||||
"[typescript]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
+21
-21
@@ -1,53 +1,53 @@
|
||||
{
|
||||
"version": 1.1,
|
||||
"atDirectives": [
|
||||
{
|
||||
"name": "@tailwind",
|
||||
"description": "Use the `@tailwind` directive to insert Tailwind's `base`, `components`, `utilities` and `screens` styles into your CSS.",
|
||||
"references": [
|
||||
{
|
||||
"name": "Tailwind Documentation",
|
||||
"url": "https://tailwindcss.com/docs/functions-and-directives#tailwind"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "@apply",
|
||||
"description": "Use the `@apply` directive to inline any existing utility classes into your own custom CSS. This is useful when you find a common utility pattern in your HTML that you’d like to extract to a new component.",
|
||||
"description": "Use the `@apply` directive to inline any existing utility classes into your own custom CSS.",
|
||||
"references": [
|
||||
{
|
||||
"name": "Tailwind Documentation",
|
||||
"url": "https://tailwindcss.com/docs/functions-and-directives#apply"
|
||||
"url": "https://tailwindcss.com/docs/functions-and-directives#variant-directive"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "@responsive",
|
||||
"description": "You can generate responsive variants of your own classes by wrapping their definitions in the `@responsive` directive:\n```css\n@responsive {\n .alert {\n background-color: #E53E3E;\n }\n}\n```\n",
|
||||
"name": "@source",
|
||||
"description": "Use the `@source` directive to explicitly specify source files that aren't picked up by Tailwind's automatic content detection.",
|
||||
"references": [
|
||||
{
|
||||
"name": "Tailwind Documentation",
|
||||
"url": "https://tailwindcss.com/docs/functions-and-directives#responsive"
|
||||
"url": "https://tailwindcss.com/docs/functions-and-directives#source-directive"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "@screen",
|
||||
"description": "The `@screen` directive allows you to create media queries that reference your breakpoints by **name** instead of duplicating their values in your own CSS:\n```css\n@screen sm {\n /* ... */\n}\n```\n…gets transformed into this:\n```css\n@media (min-width: 640px) {\n /* ... */\n}\n```\n",
|
||||
"name": "@theme",
|
||||
"description": "Use the `@theme` directive to define your project's custom design tokens, like fonts, colors, and breakpoints.",
|
||||
"references": [
|
||||
{
|
||||
"name": "Tailwind Documentation",
|
||||
"url": "https://tailwindcss.com/docs/functions-and-directives#screen"
|
||||
"url": "https://tailwindcss.com/docs/functions-and-directives#theme-directive"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "@variants",
|
||||
"description": "Generate `hover`, `focus`, `active` and other **variants** of your own utilities by wrapping their definitions in the `@variants` directive:\n```css\n@variants hover, focus {\n .btn-brand {\n background-color: #3182CE;\n }\n}\n```\n",
|
||||
"name": "@utility",
|
||||
"description": "Use the `@utility` directive to add custom utilities to your project that work with variants like `hover`, `focus` and `lg`.",
|
||||
"references": [
|
||||
{
|
||||
"name": "Tailwind Documentation",
|
||||
"url": "https://tailwindcss.com/docs/functions-and-directives#variants"
|
||||
"url": "https://tailwindcss.com/docs/functions-and-directives#utility-directive"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "@variant",
|
||||
"description": "Use the `@variant` directive to apply a Tailwind variant to styles in your CSS",
|
||||
"references": [
|
||||
{
|
||||
"name": "Tailwind Documentation",
|
||||
"url": "https://tailwindcss.com/docs/functions-and-directives#variant-directive"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+2
-2
@@ -21,7 +21,7 @@
|
||||
### 要求
|
||||
|
||||
- Go 1.24+(用于修改后端代码)
|
||||
- Node.js 22.0+(用于修改前端代码)
|
||||
- Node.js 22.12+(用于修改前端代码)
|
||||
|
||||
### 后端代码
|
||||
|
||||
@@ -74,7 +74,7 @@ npm run build
|
||||
|
||||
**在向主仓库提交 PR 之前,你应该:**
|
||||
|
||||
- 使用 [ESLint](https://github.com/eslint/eslint) 格式化你的代码。推荐使用 VSCode,并安装 ESLint+Prettier 插件,以便在保存时自动格式化。
|
||||
- 使用 [ESLint](https://github.com/eslint/eslint) 格式化你的代码。推荐使用 VSCode,并安装 ESLint 插件,以便在保存时自动格式化。
|
||||
|
||||
## 提交 PR
|
||||
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ Index:
|
||||
### Prerequisites
|
||||
|
||||
- Go 1.24+ (for backend code changes)
|
||||
- Node.js 22.0+ (for frontend code changes)
|
||||
- Node.js 22.12+ (for frontend code changes)
|
||||
|
||||
### Backend Code
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
FROM node:20-alpine3.19 AS webui-builder
|
||||
FROM node:22-alpine AS webui-builder
|
||||
WORKDIR /app
|
||||
COPY . /app/
|
||||
RUN \
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
/**
|
||||
* @type {import("eslint").Linter.Config}
|
||||
*/
|
||||
module.exports = {
|
||||
root: true,
|
||||
env: {
|
||||
browser: true,
|
||||
node: true,
|
||||
es2020: true,
|
||||
},
|
||||
extends: [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:import/recommended",
|
||||
"plugin:import/typescript",
|
||||
"plugin:prettier/recommended",
|
||||
"plugin:react-hooks/recommended",
|
||||
"plugin:tailwindcss/recommended",
|
||||
],
|
||||
ignorePatterns: ["dist", ".eslintrc.cjs"],
|
||||
parser: "@typescript-eslint/parser",
|
||||
plugins: ["react-refresh"],
|
||||
rules: {
|
||||
"@typescript-eslint/consistent-type-imports": "error",
|
||||
"@typescript-eslint/no-empty-object-type": [
|
||||
"error",
|
||||
{
|
||||
allowInterfaces: "with-single-extends",
|
||||
},
|
||||
],
|
||||
"@typescript-eslint/no-explicit-any": [
|
||||
"warn",
|
||||
{
|
||||
ignoreRestArgs: true,
|
||||
},
|
||||
],
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
argsIgnorePattern: "^_",
|
||||
caughtErrorsIgnorePattern: "^_",
|
||||
destructuredArrayIgnorePattern: "^_",
|
||||
varsIgnorePattern: "^_",
|
||||
},
|
||||
],
|
||||
"import/no-named-as-default-member": "off",
|
||||
"import/no-unresolved": "off",
|
||||
"import/order": [
|
||||
"error",
|
||||
{
|
||||
groups: ["builtin", "external", "internal", ["parent", "sibling"], "index"],
|
||||
pathGroups: [
|
||||
{
|
||||
pattern: "react*",
|
||||
group: "external",
|
||||
position: "before",
|
||||
},
|
||||
{
|
||||
pattern: "react/**",
|
||||
group: "external",
|
||||
position: "before",
|
||||
},
|
||||
{
|
||||
pattern: "react-*",
|
||||
group: "external",
|
||||
position: "before",
|
||||
},
|
||||
{
|
||||
pattern: "react-*/**",
|
||||
group: "external",
|
||||
position: "before",
|
||||
},
|
||||
{
|
||||
pattern: "~/**",
|
||||
group: "external",
|
||||
position: "after",
|
||||
},
|
||||
{
|
||||
pattern: "@/**",
|
||||
group: "internal",
|
||||
position: "before",
|
||||
},
|
||||
],
|
||||
pathGroupsExcludedImportTypes: ["builtin"],
|
||||
alphabetize: {
|
||||
order: "asc",
|
||||
caseInsensitive: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
"react-refresh/only-export-components": [
|
||||
"warn",
|
||||
{
|
||||
allowConstantExport: true,
|
||||
},
|
||||
],
|
||||
"sort-imports": [
|
||||
"error",
|
||||
{
|
||||
ignoreDeclarationSort: true,
|
||||
},
|
||||
],
|
||||
"tailwindcss/no-custom-classname": "off",
|
||||
},
|
||||
settings: {
|
||||
"import/resolver": {
|
||||
node: {
|
||||
extensions: [".js", ".jsx", ".ts", ".tsx"],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -1,17 +0,0 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema.json",
|
||||
"style": "default",
|
||||
"rsc": false,
|
||||
"tsx": true,
|
||||
"tailwind": {
|
||||
"config": "tailwind.config.js",
|
||||
"css": "src/global.css",
|
||||
"baseColor": "slate",
|
||||
"cssVariables": true,
|
||||
"prefix": ""
|
||||
},
|
||||
"aliases": {
|
||||
"components": "@/components",
|
||||
"utils": "@/components/ui/utils"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
import eslint from "@eslint/js";
|
||||
import { defineConfig } from "eslint/config";
|
||||
import tailwindcssPlugin from "eslint-plugin-better-tailwindcss";
|
||||
import importPlugin from "eslint-plugin-import";
|
||||
import prettierPluginConfig from "eslint-plugin-prettier/recommended";
|
||||
import reactHooksPlugin from "eslint-plugin-react-hooks";
|
||||
import reactRefreshPlugin from "eslint-plugin-react-refresh";
|
||||
import typescriptPlugin from "typescript-eslint";
|
||||
|
||||
/**
|
||||
* @type {import("eslint").Linter.Config[]}
|
||||
*/
|
||||
export default defineConfig(
|
||||
// Basic
|
||||
eslint.configs["recommended"],
|
||||
{
|
||||
name: "eslint/import",
|
||||
extends: [importPlugin.flatConfigs["recommended"], importPlugin.flatConfigs["typescript"]],
|
||||
rules: {
|
||||
"import/no-named-as-default-member": "off",
|
||||
"import/no-unresolved": "off",
|
||||
"import/order": [
|
||||
"error",
|
||||
{
|
||||
groups: ["builtin", "external", "internal", ["parent", "sibling"], "index"],
|
||||
pathGroups: [
|
||||
{
|
||||
pattern: "react*",
|
||||
group: "external",
|
||||
position: "before",
|
||||
},
|
||||
{
|
||||
pattern: "react/**",
|
||||
group: "external",
|
||||
position: "before",
|
||||
},
|
||||
{
|
||||
pattern: "react-*",
|
||||
group: "external",
|
||||
position: "before",
|
||||
},
|
||||
{
|
||||
pattern: "react-*/**",
|
||||
group: "external",
|
||||
position: "before",
|
||||
},
|
||||
{
|
||||
pattern: "~/**",
|
||||
group: "external",
|
||||
position: "after",
|
||||
},
|
||||
{
|
||||
pattern: "@/**",
|
||||
group: "internal",
|
||||
position: "before",
|
||||
},
|
||||
],
|
||||
pathGroupsExcludedImportTypes: ["builtin"],
|
||||
alphabetize: {
|
||||
order: "asc",
|
||||
caseInsensitive: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
"sort-imports": [
|
||||
"error",
|
||||
{
|
||||
ignoreDeclarationSort: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
settings: {
|
||||
"import/resolver": {
|
||||
node: {
|
||||
extensions: [".js", ".jsx", ".ts", ".tsx"],
|
||||
},
|
||||
typescript: {
|
||||
alwaysTryTypes: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// Typescript
|
||||
{
|
||||
name: "typescript",
|
||||
extends: [typescriptPlugin.configs["recommended"]],
|
||||
rules: {
|
||||
"@typescript-eslint/consistent-type-imports": "error",
|
||||
"@typescript-eslint/no-empty-object-type": [
|
||||
"error",
|
||||
{
|
||||
allowInterfaces: "with-single-extends",
|
||||
},
|
||||
],
|
||||
"@typescript-eslint/no-explicit-any": [
|
||||
"warn",
|
||||
{
|
||||
ignoreRestArgs: true,
|
||||
},
|
||||
],
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
argsIgnorePattern: "^_",
|
||||
caughtErrorsIgnorePattern: "^_",
|
||||
destructuredArrayIgnorePattern: "^_",
|
||||
varsIgnorePattern: "^_",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
// Pretter
|
||||
{
|
||||
name: "prettier",
|
||||
extends: [prettierPluginConfig],
|
||||
},
|
||||
|
||||
// React
|
||||
{
|
||||
name: "react",
|
||||
extends: [reactHooksPlugin.configs["recommended-latest"], reactRefreshPlugin.configs["vite"]],
|
||||
rules: {
|
||||
"react-refresh/only-export-components": [
|
||||
"warn",
|
||||
{
|
||||
allowConstantExport: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
// TailwindCSS
|
||||
{
|
||||
name: "tailwindcss",
|
||||
plugins: {
|
||||
"better-tailwindcss": tailwindcssPlugin,
|
||||
},
|
||||
rules: {
|
||||
...tailwindcssPlugin.configs["recommended-warn"].rules,
|
||||
...tailwindcssPlugin.configs["recommended-error"].rules,
|
||||
|
||||
"better-tailwindcss/enforce-consistent-line-wrapping": "off",
|
||||
"better-tailwindcss/no-unregistered-classes": "off",
|
||||
},
|
||||
settings: {
|
||||
"better-tailwindcss": {
|
||||
entryPoint: "src/global.css",
|
||||
},
|
||||
},
|
||||
}
|
||||
);
|
||||
Generated
+1700
-1713
File diff suppressed because it is too large
Load Diff
+29
-31
@@ -10,63 +10,61 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^6.0.0",
|
||||
"@ant-design/pro-components": "^2.8.9",
|
||||
"@ant-design/pro-components": "^2.8.10",
|
||||
"@codemirror/lang-json": "^6.0.2",
|
||||
"@codemirror/lang-yaml": "^6.1.2",
|
||||
"@codemirror/language": "^6.11.1",
|
||||
"@codemirror/language": "^6.11.2",
|
||||
"@codemirror/legacy-modes": "^6.5.1",
|
||||
"@uiw/codemirror-extensions-basic-setup": "^4.23.13",
|
||||
"@uiw/codemirror-theme-vscode": "^4.23.13",
|
||||
"@uiw/react-codemirror": "^4.23.13",
|
||||
"ahooks": "^3.8.5",
|
||||
"antd": "^5.26.1",
|
||||
"@tabler/icons-react": "^3.34.1",
|
||||
"@uiw/codemirror-extensions-basic-setup": "^4.24.1",
|
||||
"@uiw/codemirror-theme-vscode": "^4.24.1",
|
||||
"@uiw/react-codemirror": "^4.24.1",
|
||||
"ahooks": "^3.9.0",
|
||||
"antd": "^5.26.6",
|
||||
"antd-zod": "^7.0.0",
|
||||
"clsx": "^2.1.1",
|
||||
"cron-parser": "^5.3.0",
|
||||
"file-saver": "^2.0.5",
|
||||
"i18next": "^25.2.1",
|
||||
"i18next": "^25.3.2",
|
||||
"i18next-browser-languagedetector": "^8.2.0",
|
||||
"immer": "^10.1.1",
|
||||
"lucide-react": "^0.522.0",
|
||||
"nanoid": "^5.1.5",
|
||||
"pocketbase": "^0.26.1",
|
||||
"radash": "^12.1.1",
|
||||
"react": "^18.3.1",
|
||||
"react-copy-to-clipboard": "^5.1.0",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-i18next": "^15.5.3",
|
||||
"react-router-dom": "^7.6.2",
|
||||
"tailwind-merge": "^2.6.0",
|
||||
"zod": "^3.25.67",
|
||||
"zustand": "^5.0.5"
|
||||
"react-i18next": "^15.6.0",
|
||||
"react-router-dom": "^7.7.0",
|
||||
"tailwind-merge": "^3.3.1",
|
||||
"zod": "^4.0.5",
|
||||
"zustand": "^5.0.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.31.0",
|
||||
"@tailwindcss/postcss": "^4.1.11",
|
||||
"@tailwindcss/vite": "^4.1.11",
|
||||
"@types/file-saver": "^2.0.7",
|
||||
"@types/fs-extra": "^11.0.4",
|
||||
"@types/node": "^22.15.17",
|
||||
"@types/react": "^18.3.12",
|
||||
"@types/node": "^22.16.5",
|
||||
"@types/react": "^18.3.19",
|
||||
"@types/react-copy-to-clipboard": "^5.0.7",
|
||||
"@types/react-dom": "^18.3.1",
|
||||
"@typescript-eslint/eslint-plugin": "^8.34.1",
|
||||
"@typescript-eslint/parser": "^8.34.1",
|
||||
"@types/react-dom": "^18.3.7",
|
||||
"@vitejs/plugin-legacy": "^6.1.1",
|
||||
"@vitejs/plugin-react": "^4.6.0",
|
||||
"autoprefixer": "^10.4.21",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-prettier": "^10.1.5",
|
||||
"eslint-import-resolver-typescript": "^3.8.3",
|
||||
"@vitejs/plugin-react": "^4.7.0",
|
||||
"eslint": "^9.31.0",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"eslint-import-resolver-typescript": "^4.4.4",
|
||||
"eslint-plugin-better-tailwindcss": "^3.7.0",
|
||||
"eslint-plugin-import": "^2.32.0",
|
||||
"eslint-plugin-prettier": "^5.5.0",
|
||||
"eslint-plugin-prettier": "^5.5.3",
|
||||
"eslint-plugin-react-hooks": "^5.2.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.20",
|
||||
"eslint-plugin-tailwindcss": "^3.18.0",
|
||||
"fs-extra": "^11.3.0",
|
||||
"postcss": "^8.5.6",
|
||||
"prettier": "^3.6.0",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"prettier": "^3.6.2",
|
||||
"tailwindcss": "^4.1.11",
|
||||
"typescript": "^5.8.3",
|
||||
"typescript-eslint": "^8.37.0",
|
||||
"vite": "^6.3.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
export default {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
};
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @type {import("prettier").Config}
|
||||
*/
|
||||
module.exports = {
|
||||
export default {
|
||||
arrowParens: "always",
|
||||
bracketSpacing: true,
|
||||
editorconfig: true,
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
+58
-22
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useLayoutEffect, useMemo, useState } from "react";
|
||||
import { useEffect, useLayoutEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { RouterProvider } from "react-router-dom";
|
||||
import { App, ConfigProvider, type ThemeConfig, theme } from "antd";
|
||||
@@ -10,25 +10,30 @@ import "dayjs/locale/zh-cn";
|
||||
|
||||
import { useBrowserTheme } from "@/hooks";
|
||||
import { localeNames } from "@/i18n";
|
||||
import { router } from "@/router.tsx";
|
||||
import { router } from "@/routers";
|
||||
|
||||
const antdLocalesMap: Record<string, Locale> = {
|
||||
[localeNames.ZH]: AntdLocaleZhCN,
|
||||
[localeNames.EN]: AntdLocaleEnUs,
|
||||
};
|
||||
const antdThemesMap: Record<string, ThemeConfig> = {
|
||||
["light"]: { algorithm: theme.defaultAlgorithm },
|
||||
["dark"]: { algorithm: theme.darkAlgorithm },
|
||||
};
|
||||
|
||||
const RootApp = () => {
|
||||
const { i18n } = useTranslation();
|
||||
|
||||
const { theme: browserTheme } = useBrowserTheme();
|
||||
|
||||
const antdLocalesMap: Record<string, Locale> = useMemo(
|
||||
() => ({
|
||||
[localeNames.ZH]: AntdLocaleZhCN,
|
||||
[localeNames.EN]: AntdLocaleEnUs,
|
||||
}),
|
||||
[]
|
||||
);
|
||||
const [antdLocale, setAntdLocale] = useState(antdLocalesMap[i18n.language]);
|
||||
const [antdTheme, setAntdTheme] = useState(antdThemesMap[browserTheme]);
|
||||
|
||||
const handleLanguageChanged = () => {
|
||||
setAntdLocale(antdLocalesMap[i18n.language]);
|
||||
dayjs.locale(i18n.language);
|
||||
};
|
||||
|
||||
i18n.on("languageChanged", handleLanguageChanged);
|
||||
useLayoutEffect(() => {
|
||||
handleLanguageChanged();
|
||||
@@ -36,23 +41,15 @@ const RootApp = () => {
|
||||
return () => {
|
||||
i18n.off("languageChanged", handleLanguageChanged);
|
||||
};
|
||||
}, [antdLocalesMap, i18n]);
|
||||
}, [i18n]);
|
||||
|
||||
const antdThemesMap: Record<string, ThemeConfig> = useMemo(
|
||||
() => ({
|
||||
["light"]: { algorithm: theme.defaultAlgorithm },
|
||||
["dark"]: { algorithm: theme.darkAlgorithm },
|
||||
}),
|
||||
[]
|
||||
);
|
||||
const [antdTheme, setAntdTheme] = useState(antdThemesMap[browserTheme]);
|
||||
useEffect(() => {
|
||||
setAntdTheme(antdThemesMap[browserTheme]);
|
||||
|
||||
const root = window.document.documentElement;
|
||||
root.classList.remove("light", "dark");
|
||||
root.classList.add(browserTheme);
|
||||
}, [antdThemesMap, browserTheme]);
|
||||
}, [browserTheme]);
|
||||
|
||||
return (
|
||||
<ConfigProvider
|
||||
@@ -60,9 +57,48 @@ const RootApp = () => {
|
||||
theme={{
|
||||
...antdTheme,
|
||||
token: {
|
||||
/* @see tailwind.config.js */
|
||||
colorPrimary: browserTheme === "dark" ? "hsl(20.5 90.2% 48.2%)" : "hsl(24.6 95% 53.1%)",
|
||||
colorLink: browserTheme === "dark" ? "hsl(20.5 90.2% 48.2%)" : "hsl(24.6 95% 53.1%)",
|
||||
/* @see global.css, YOU MUST MODIFY BOTH DEFINITIONS AT THE SAME TIME! */
|
||||
colorBgBase: browserTheme === "dark" ? "#17191c" : "#ffffff",
|
||||
colorTextBase: browserTheme === "dark" ? "#fafaf9" : "#141414",
|
||||
colorPrimary: browserTheme === "dark" ? "#f97316" : "#ea580c",
|
||||
colorLink: browserTheme === "dark" ? "#f97316" : "#ea580c",
|
||||
colorInfo: browserTheme === "dark" ? "#478be6" : "#0969da",
|
||||
colorSuccess: browserTheme === "dark" ? "#57ab5a" : "#1a7f37",
|
||||
colorWarning: browserTheme === "dark" ? "#daaa3f" : "#eac54f",
|
||||
colorError: browserTheme === "dark" ? "#e5534b" : "#d1242f",
|
||||
|
||||
/* @see https://tailwindcss.com/docs/responsive-design#overview */
|
||||
screenXS: 30 * 16,
|
||||
screenXSMin: 30 * 16,
|
||||
screenXSMax: 40 * 16 - 1,
|
||||
screenSM: 40 * 16,
|
||||
screenSMMin: 40 * 16,
|
||||
screenSMMax: 48 * 16 - 1,
|
||||
screenMD: 48 * 16,
|
||||
screenMDMin: 48 * 16,
|
||||
screenMDMax: 64 * 16 - 1,
|
||||
screenLG: 64 * 16,
|
||||
screenLGMin: 64 * 16,
|
||||
screenLGMax: 80 * 16 - 1,
|
||||
screenXL: 80 * 16,
|
||||
screenXLMin: 80 * 16,
|
||||
screenXLMax: 96 * 16 - 1,
|
||||
screenXXL: 96 * 16,
|
||||
screenXXLMin: 96 * 16,
|
||||
padding: 16,
|
||||
paddingXS: 8,
|
||||
paddingXXS: 6,
|
||||
},
|
||||
components: {
|
||||
Layout: {
|
||||
...antdTheme?.components?.Layout,
|
||||
bodyBg: "transparent",
|
||||
siderBg: "transparent",
|
||||
},
|
||||
Dropdown: {
|
||||
...antdTheme?.components?.Dropdown,
|
||||
paddingBlock: 9,
|
||||
},
|
||||
},
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { IconBook } from "@tabler/icons-react";
|
||||
import { Typography } from "antd";
|
||||
|
||||
import { APP_DOCUMENT_URL } from "@/domain/app";
|
||||
|
||||
export interface AppDocumentLinkButtonProps {
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
showIcon?: boolean;
|
||||
}
|
||||
|
||||
const AppDocumentLinkButton = (props: AppDocumentLinkButtonProps) => {
|
||||
const { className, style, showIcon = true } = props;
|
||||
|
||||
const { i18n, t } = useTranslation();
|
||||
|
||||
const handleDocumentClick = () => {
|
||||
if (i18n.language.startsWith("en")) {
|
||||
window.open(APP_DOCUMENT_URL + "/en/", "_blank");
|
||||
} else {
|
||||
window.open(APP_DOCUMENT_URL, "_blank");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Typography.Link className={className} style={style} type="secondary" onClick={handleDocumentClick}>
|
||||
<div className="flex items-center justify-center space-x-1">
|
||||
{showIcon ? <IconBook size="1em" /> : <></>}
|
||||
<span>{t("common.menu.document")}</span>
|
||||
</div>
|
||||
</Typography.Link>
|
||||
);
|
||||
};
|
||||
|
||||
export default {
|
||||
LinkButton: AppDocumentLinkButton,
|
||||
};
|
||||
@@ -0,0 +1,87 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { IconLanguage, type IconProps } from "@tabler/icons-react";
|
||||
import { Dropdown, type DropdownProps, Typography } from "antd";
|
||||
|
||||
import { IconLanguageEnZh, IconLanguageZhEn } from "@/components/icons";
|
||||
import { localeNames, localeResources } from "@/i18n";
|
||||
import { mergeCls } from "@/utils/css";
|
||||
|
||||
export const useAppLocaleMenuItems = () => {
|
||||
const { i18n } = useTranslation();
|
||||
|
||||
const items = Object.keys(i18n.store.data).map((key) => {
|
||||
return {
|
||||
key: key as string,
|
||||
label: i18n.store.data[key].name as string,
|
||||
onClick: () => {
|
||||
if (key !== i18n.language) {
|
||||
i18n.changeLanguage(key);
|
||||
window.location.reload();
|
||||
}
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
return items;
|
||||
};
|
||||
|
||||
export interface AppLocaleDropdownProps {
|
||||
children?: React.ReactNode;
|
||||
trigger?: DropdownProps["trigger"];
|
||||
}
|
||||
|
||||
const AppLocaleDropdown = (props: AppLocaleDropdownProps) => {
|
||||
const { children, trigger = ["click"] } = props;
|
||||
|
||||
const items = useAppLocaleMenuItems();
|
||||
|
||||
return (
|
||||
<Dropdown menu={{ items }} trigger={trigger}>
|
||||
{children}
|
||||
</Dropdown>
|
||||
);
|
||||
};
|
||||
|
||||
export interface AppLocaleIconProps extends IconProps {}
|
||||
|
||||
const AppLocaleIcon = (props: AppLocaleIconProps) => {
|
||||
const { i18n } = useTranslation();
|
||||
|
||||
return i18n.language === localeNames.EN ? (
|
||||
<IconLanguageEnZh {...props} />
|
||||
) : i18n.language === localeNames.ZH ? (
|
||||
<IconLanguageZhEn {...props} />
|
||||
) : (
|
||||
<IconLanguage {...props} />
|
||||
);
|
||||
};
|
||||
|
||||
export interface AppLocaleLinkButtonProps {
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
showIcon?: boolean;
|
||||
}
|
||||
|
||||
const AppLocaleLinkButton = (props: AppLocaleLinkButtonProps) => {
|
||||
const { className, style, showIcon = true } = props;
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { i18n } = useTranslation();
|
||||
|
||||
return (
|
||||
<AppLocaleDropdown trigger={["click", "hover"]}>
|
||||
<Typography.Text className={mergeCls("cursor-pointer", className)} style={style} type="secondary">
|
||||
<div className="flex items-center justify-center space-x-1">
|
||||
{showIcon ? <AppLocaleIcon size="1em" /> : <></>}
|
||||
<span>{String(localeResources[i18n.language]?.name ?? t("common.menu.locale"))}</span>
|
||||
</div>
|
||||
</Typography.Text>
|
||||
</AppLocaleDropdown>
|
||||
);
|
||||
};
|
||||
|
||||
export default {
|
||||
Dropdown: AppLocaleDropdown,
|
||||
Icon: AppLocaleIcon,
|
||||
LinkButton: AppLocaleLinkButton,
|
||||
};
|
||||
@@ -0,0 +1,91 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { IconMoon, type IconProps, IconSun, IconSunMoon } from "@tabler/icons-react";
|
||||
|
||||
import { Dropdown, type DropdownProps, Typography } from "antd";
|
||||
|
||||
import { useBrowserTheme } from "@/hooks";
|
||||
import { mergeCls } from "@/utils/css";
|
||||
|
||||
export const useAppThemeMenuItems = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { themeMode, setThemeMode } = useBrowserTheme();
|
||||
|
||||
const items = (
|
||||
[
|
||||
["light", "common.theme.light", <IconSun size="1em" />],
|
||||
["dark", "common.theme.dark", <IconMoon size="1em" />],
|
||||
["system", "common.theme.system", <IconSunMoon size="1em" />],
|
||||
] satisfies Array<[string, string, React.ReactNode]>
|
||||
).map(([key, label, icon]) => {
|
||||
return {
|
||||
key: key,
|
||||
label: t(label),
|
||||
icon: icon,
|
||||
onClick: () => {
|
||||
if (key !== themeMode) {
|
||||
setThemeMode(key as Parameters<typeof setThemeMode>[0]);
|
||||
window.location.reload();
|
||||
}
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
return items;
|
||||
};
|
||||
|
||||
export interface AppThemeDropdownProps {
|
||||
children?: React.ReactNode;
|
||||
trigger?: DropdownProps["trigger"];
|
||||
}
|
||||
|
||||
const AppThemeDropdown = (props: AppThemeDropdownProps) => {
|
||||
const { children, trigger = ["click"] } = props;
|
||||
|
||||
const items = useAppThemeMenuItems();
|
||||
|
||||
return (
|
||||
<Dropdown menu={{ items }} trigger={trigger}>
|
||||
{children}
|
||||
</Dropdown>
|
||||
);
|
||||
};
|
||||
|
||||
export interface AppThemeIconProps extends IconProps {}
|
||||
|
||||
const AppThemeIcon = (props: AppThemeIconProps) => {
|
||||
const { theme } = useBrowserTheme();
|
||||
|
||||
return theme === "dark" ? <IconMoon {...props} /> : <IconSun {...props} />;
|
||||
};
|
||||
|
||||
export interface AppThemeLinkButtonProps {
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
showIcon?: boolean;
|
||||
}
|
||||
|
||||
const AppThemeLinkButton = (props: AppThemeLinkButtonProps) => {
|
||||
const { className, style, showIcon = true } = props;
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { themeMode } = useBrowserTheme();
|
||||
|
||||
return (
|
||||
<AppThemeDropdown trigger={["click", "hover"]}>
|
||||
<Typography.Text className={mergeCls("cursor-pointer", className)} style={style} type="secondary">
|
||||
<div className="flex items-center justify-center space-x-1">
|
||||
{showIcon ? <AppThemeIcon size="1em" /> : <></>}
|
||||
<span>{t(`common.theme.${themeMode}`)}</span>
|
||||
</div>
|
||||
</Typography.Text>
|
||||
</AppThemeDropdown>
|
||||
);
|
||||
};
|
||||
|
||||
export default {
|
||||
Dropdown: AppThemeDropdown,
|
||||
Icon: AppThemeIcon,
|
||||
LinkButton: AppThemeLinkButton,
|
||||
};
|
||||
@@ -0,0 +1,45 @@
|
||||
import { Badge, Typography } from "antd";
|
||||
|
||||
import { APP_DOWNLOAD_URL, APP_VERSION } from "@/domain/app";
|
||||
import { useVersionChecker } from "@/hooks";
|
||||
|
||||
export interface AppVersionLinkButtonProps {
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
|
||||
const AppVersionLinkButton = ({ className, style }: AppVersionLinkButtonProps) => {
|
||||
return (
|
||||
<AppVersionBadge>
|
||||
<Typography.Link className={className} style={style} type="secondary" href={APP_DOWNLOAD_URL} target="_blank">
|
||||
{APP_VERSION}
|
||||
</Typography.Link>
|
||||
</AppVersionBadge>
|
||||
);
|
||||
};
|
||||
|
||||
export interface AppVersionBadgeProps {
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
const AppVersionBadge = ({ className, style, children }: AppVersionBadgeProps) => {
|
||||
const { hasNewVersion } = useVersionChecker();
|
||||
|
||||
return (
|
||||
<Badge
|
||||
className={className}
|
||||
style={style}
|
||||
styles={{ indicator: { transform: "scale(0.75) translate(50%, -50%)" } }}
|
||||
count={hasNewVersion ? "NEW" : undefined}
|
||||
>
|
||||
{children}
|
||||
</Badge>
|
||||
);
|
||||
};
|
||||
|
||||
export default {
|
||||
LinkButton: AppVersionLinkButton,
|
||||
Badge: AppVersionBadge,
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useControllableValue } from "ahooks";
|
||||
import { Button, Drawer, type DrawerProps, Form, type FormProps, type ModalProps, Space } from "antd";
|
||||
import { Button, Drawer, type DrawerProps, Flex, Form, type FormProps, type ModalProps } from "antd";
|
||||
|
||||
import { useAntdForm, useTriggerElement } from "@/hooks";
|
||||
|
||||
@@ -109,14 +109,14 @@ const DrawerForm = <T extends NonNullable<unknown> = any>({
|
||||
<Drawer
|
||||
{...mergedDrawerProps}
|
||||
footer={
|
||||
<Space className="w-full justify-end">
|
||||
<Flex justify="end" gap="small">
|
||||
<Button {...cancelButtonProps} onClick={handleCancelClick}>
|
||||
{cancelText ?? t("common.button.cancel")}
|
||||
</Button>
|
||||
<Button {...okButtonProps} type="primary" loading={formPending} onClick={handleOkClick}>
|
||||
{okText ?? t("common.button.ok")}
|
||||
</Button>
|
||||
</Space>
|
||||
</Flex>
|
||||
}
|
||||
forceRender
|
||||
open={open}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Typography, theme } from "antd";
|
||||
|
||||
import Show from "./Show";
|
||||
|
||||
export interface EmptyProps {
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
title?: React.ReactNode;
|
||||
description?: React.ReactNode;
|
||||
extra?: React.ReactNode;
|
||||
icon?: React.ReactNode;
|
||||
}
|
||||
|
||||
const Empty = (props: EmptyProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { className, style, title = t("common.text.nodata"), description, extra, icon } = props;
|
||||
|
||||
const { token: themeToken } = theme.useToken();
|
||||
|
||||
const isPrimitive = (node: React.ReactNode): node is string | number | boolean | null => {
|
||||
return typeof node === "string" || typeof node === "number" || typeof node === "boolean" || node == null;
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={className} style={style}>
|
||||
<div className="relative w-full overflow-hidden">
|
||||
<div className="relative top-0 left-0 z-1 flex h-full w-full py-4">
|
||||
<div className="relative mx-auto w-full max-w-lg">
|
||||
<div className="flex flex-col gap-2 text-center">
|
||||
<Show when={!!icon}>
|
||||
<div className="mx-auto">
|
||||
<div className="flex size-12 items-center justify-center overflow-hidden rounded-md border text-gray-600 shadow-sm dark:text-gray-200">
|
||||
{icon}
|
||||
</div>
|
||||
</div>
|
||||
</Show>
|
||||
<div className="my-2">
|
||||
<Show when={!!title}>
|
||||
<div className="pb-2 text-xl" style={{ color: themeToken.colorTextLabel }}>
|
||||
{title}
|
||||
</div>
|
||||
</Show>
|
||||
<Show when={!!description}>
|
||||
{isPrimitive(description) ? (
|
||||
<Typography.Text type="secondary">{description}</Typography.Text>
|
||||
) : (
|
||||
<div style={{ color: themeToken.colorTextSecondary }}>{description}</div>
|
||||
)}
|
||||
</Show>
|
||||
</div>
|
||||
<Show when={!!extra}>
|
||||
<div>{extra}</div>
|
||||
</Show>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Empty;
|
||||
@@ -122,7 +122,7 @@ const ModalForm = <T extends NonNullable<unknown> = any>({
|
||||
onOk={handleOkClick}
|
||||
onCancel={handleCancelClick}
|
||||
>
|
||||
<div className="pb-2 pt-4">
|
||||
<div className="pt-4 pb-2">
|
||||
<Form className={className} style={style} {...mergedFormProps} form={formInst}>
|
||||
{children}
|
||||
</Form>
|
||||
|
||||
@@ -1,16 +1,11 @@
|
||||
import { type ChangeEvent, forwardRef, useImperativeHandle, useMemo, useRef } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import {
|
||||
ArrowDownOutlined as ArrowDownOutlinedIcon,
|
||||
ArrowUpOutlined as ArrowUpOutlinedIcon,
|
||||
MinusOutlined as MinusOutlinedIcon,
|
||||
PlusOutlined as PlusOutlinedIcon,
|
||||
} from "@ant-design/icons";
|
||||
import { IconCircleArrowDown, IconCircleArrowUp, IconCircleMinus, IconCirclePlus } from "@tabler/icons-react";
|
||||
import { useControllableValue } from "ahooks";
|
||||
import { Button, Input, type InputProps, type InputRef, Space } from "antd";
|
||||
import { Button, Input, type InputProps, type InputRef } from "antd";
|
||||
import { produce } from "immer";
|
||||
|
||||
export type MultipleInputProps = Omit<InputProps, "count" | "defaultValue" | "showCount" | "value" | "onChange" | "onPressEnter" | "onClear"> & {
|
||||
export interface MultipleInputProps extends Omit<InputProps, "count" | "defaultValue" | "showCount" | "value" | "onChange" | "onPressEnter" | "onClear"> {
|
||||
allowClear?: boolean;
|
||||
defaultValue?: string[];
|
||||
maxCount?: number;
|
||||
@@ -22,7 +17,7 @@ export type MultipleInputProps = Omit<InputProps, "count" | "defaultValue" | "sh
|
||||
onValueCreate?: (index: number) => void;
|
||||
onValueRemove?: (index: number) => void;
|
||||
onValueSort?: (oldIndex: number, newIndex: number) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const MultipleInput = ({
|
||||
allowClear = false,
|
||||
@@ -129,7 +124,7 @@ const MultipleInput = ({
|
||||
{t("common.button.add")}
|
||||
</Button>
|
||||
) : (
|
||||
<Space className="w-full" direction="vertical" size="small">
|
||||
<div className="flex flex-col gap-2">
|
||||
{Array.from(value).map((element, index) => {
|
||||
const allowUp = index > 0;
|
||||
const allowDown = index < value.length - 1;
|
||||
@@ -159,7 +154,7 @@ const MultipleInput = ({
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</Space>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -196,7 +191,6 @@ const MultipleInputItem = forwardRef<MultipleInputItemInstance, MultipleInputIte
|
||||
allowUp,
|
||||
disabled,
|
||||
showSortButton,
|
||||
size,
|
||||
onEntryAdd,
|
||||
onEntryDown,
|
||||
onEntryUp,
|
||||
@@ -216,17 +210,17 @@ const MultipleInputItem = forwardRef<MultipleInputItemInstance, MultipleInputIte
|
||||
|
||||
const upBtn = useMemo(() => {
|
||||
if (!showSortButton) return null;
|
||||
return <Button icon={<ArrowUpOutlinedIcon />} color="default" disabled={disabled || !allowUp} type="text" onClick={onEntryUp} />;
|
||||
return <Button icon={<IconCircleArrowUp size="1.25em" />} color="default" disabled={disabled || !allowUp} type="text" onClick={onEntryUp} />;
|
||||
}, [allowUp, disabled, showSortButton, onEntryUp]);
|
||||
const downBtn = useMemo(() => {
|
||||
if (!showSortButton) return null;
|
||||
return <Button icon={<ArrowDownOutlinedIcon />} color="default" disabled={disabled || !allowDown} type="text" onClick={onEntryDown} />;
|
||||
return <Button icon={<IconCircleArrowDown size="1.25em" />} color="default" disabled={disabled || !allowDown} type="text" onClick={onEntryDown} />;
|
||||
}, [allowDown, disabled, showSortButton, onEntryDown]);
|
||||
const removeBtn = useMemo(() => {
|
||||
return <Button icon={<MinusOutlinedIcon />} color="default" disabled={disabled || !allowRemove} type="text" onClick={onEntryRemove} />;
|
||||
return <Button icon={<IconCircleMinus size="1.25em" />} color="default" disabled={disabled || !allowRemove} type="text" onClick={onEntryRemove} />;
|
||||
}, [allowRemove, disabled, onEntryRemove]);
|
||||
const addBtn = useMemo(() => {
|
||||
return <Button icon={<PlusOutlinedIcon />} color="default" disabled={disabled || !allowAdd} type="text" onClick={onEntryAdd} />;
|
||||
return <Button icon={<IconCirclePlus size="1.25em" />} color="default" disabled={disabled || !allowAdd} type="text" onClick={onEntryAdd} />;
|
||||
}, [allowAdd, disabled, onEntryAdd]);
|
||||
|
||||
const handleInputChange = (e: ChangeEvent<HTMLInputElement>) => {
|
||||
@@ -259,12 +253,12 @@ const MultipleInputItem = forwardRef<MultipleInputItemInstance, MultipleInputIte
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
</div>
|
||||
<Space.Compact size={size}>
|
||||
<div className="flex items-center justify-end">
|
||||
{removeBtn}
|
||||
{upBtn}
|
||||
{downBtn}
|
||||
{addBtn}
|
||||
</Space.Compact>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { type ChangeEvent, useEffect } from "react";
|
||||
import { FormOutlined as FormOutlinedIcon } from "@ant-design/icons";
|
||||
import { nanoid } from "@ant-design/pro-components";
|
||||
import { IconList } from "@tabler/icons-react";
|
||||
import { useControllableValue } from "ahooks";
|
||||
import { Button, Form, Input, type InputProps, Space } from "antd";
|
||||
import { nanoid } from "nanoid";
|
||||
|
||||
import { useAntdForm } from "@/hooks";
|
||||
import ModalForm from "./ModalForm";
|
||||
@@ -10,10 +10,10 @@ import MultipleInput from "./MultipleInput";
|
||||
|
||||
type SplitOptions = {
|
||||
removeEmpty?: boolean;
|
||||
trim?: boolean;
|
||||
trimSpace?: boolean;
|
||||
};
|
||||
|
||||
export type MultipleSplitValueInputProps = Omit<InputProps, "count" | "defaultValue" | "showCount" | "value" | "onChange"> & {
|
||||
export interface MultipleSplitValueInputProps extends Omit<InputProps, "count" | "defaultValue" | "showCount" | "value" | "onChange"> {
|
||||
defaultValue?: string;
|
||||
maxCount?: number;
|
||||
minCount?: number;
|
||||
@@ -25,13 +25,14 @@ export type MultipleSplitValueInputProps = Omit<InputProps, "count" | "defaultVa
|
||||
splitOptions?: SplitOptions;
|
||||
value?: string[];
|
||||
onChange?: (value: string) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const DEFAULT_SEPARATOR = ";";
|
||||
|
||||
const MultipleSplitValueInput = ({
|
||||
className,
|
||||
style,
|
||||
size,
|
||||
separator: delimiter = DEFAULT_SEPARATOR,
|
||||
disabled,
|
||||
maxCount,
|
||||
@@ -56,7 +57,7 @@ const MultipleSplitValueInput = ({
|
||||
initialValues: { value: value?.split(delimiter) },
|
||||
onSubmit: (values) => {
|
||||
const temp = values.value ?? [];
|
||||
if (splitOptions.trim) {
|
||||
if (splitOptions.trimSpace) {
|
||||
temp.map((e) => e.trim());
|
||||
}
|
||||
if (splitOptions.removeEmpty) {
|
||||
@@ -81,27 +82,29 @@ const MultipleSplitValueInput = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<Space.Compact className={className} style={{ width: "100%", ...style }}>
|
||||
<Input {...props} disabled={disabled} placeholder={placeholder} value={value} onChange={handleChange} onClear={handleClear} />
|
||||
<ModalForm
|
||||
{...formProps}
|
||||
layout="vertical"
|
||||
form={formInst}
|
||||
modalProps={{ destroyOnHidden: true }}
|
||||
title={modalTitle}
|
||||
trigger={
|
||||
<Button disabled={disabled}>
|
||||
<FormOutlinedIcon />
|
||||
</Button>
|
||||
}
|
||||
validateTrigger="onSubmit"
|
||||
width={modalWidth}
|
||||
>
|
||||
<Form.Item name="value" noStyle>
|
||||
<MultipleInput minCount={minCount} maxCount={maxCount} placeholder={placeholderInModal ?? placeholder} showSortButton={showSortButton} />
|
||||
</Form.Item>
|
||||
</ModalForm>
|
||||
</Space.Compact>
|
||||
<div className={className} style={style}>
|
||||
<Space.Compact className="w-full">
|
||||
<Input {...props} disabled={disabled} placeholder={placeholder} size={size} value={value} onChange={handleChange} onClear={handleClear} />
|
||||
<ModalForm
|
||||
{...formProps}
|
||||
layout="vertical"
|
||||
form={formInst}
|
||||
modalProps={{ destroyOnHidden: true }}
|
||||
title={modalTitle}
|
||||
trigger={
|
||||
<Button className="px-2" disabled={disabled} size={size}>
|
||||
<IconList size="1.25em" />
|
||||
</Button>
|
||||
}
|
||||
validateTrigger="onSubmit"
|
||||
width={modalWidth}
|
||||
>
|
||||
<Form.Item name="value" noStyle>
|
||||
<MultipleInput minCount={minCount} maxCount={maxCount} placeholder={placeholderInModal ?? placeholder} showSortButton={showSortButton} />
|
||||
</Form.Item>
|
||||
</ModalForm>
|
||||
</Space.Compact>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
export type ShowProps = {
|
||||
export interface ShowProps {
|
||||
when: boolean;
|
||||
children: React.ReactNode;
|
||||
fallback?: React.ReactNode;
|
||||
};
|
||||
}
|
||||
|
||||
const Show = ({ when, children, fallback }: ShowProps) => {
|
||||
return when ? children : fallback;
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { type ChangeEvent, useRef } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { UploadOutlined as UploadOutlinedIcon } from "@ant-design/icons";
|
||||
import { Button, type ButtonProps, Input, Space, type UploadProps } from "antd";
|
||||
import { IconFileImport } from "@tabler/icons-react";
|
||||
import { Button, type ButtonProps, Input, type UploadProps } from "antd";
|
||||
import { type TextAreaProps } from "antd/es/input/TextArea";
|
||||
|
||||
import { mergeCls } from "@/utils/css";
|
||||
import { readFileContent } from "@/utils/file";
|
||||
|
||||
export interface TextFileInputProps extends Omit<TextAreaProps, "onChange"> {
|
||||
@@ -34,17 +33,19 @@ const TextFileInput = ({ className, style, accept, disabled, readOnly, uploadTex
|
||||
};
|
||||
|
||||
return (
|
||||
<Space className={mergeCls("w-full", className)} style={style} direction="vertical" size="small">
|
||||
<Input.TextArea {...props} disabled={disabled} readOnly={readOnly} onChange={(e) => onChange?.(e.target.value)} />
|
||||
{!readOnly && (
|
||||
<>
|
||||
<Button {...uploadButtonProps} block disabled={disabled} icon={<UploadOutlinedIcon />} onClick={handleButtonClick}>
|
||||
{uploadText ?? t("common.text.import_from_file")}
|
||||
</Button>
|
||||
<input ref={fileInputRef} type="file" style={{ display: "none" }} accept={accept} onChange={handleFileChange} />
|
||||
</>
|
||||
)}
|
||||
</Space>
|
||||
<div className={className} style={style}>
|
||||
<div className="flex flex-col items-center gap-2">
|
||||
<Input.TextArea {...props} disabled={disabled} readOnly={readOnly} onChange={(e) => onChange?.(e.target.value)} />
|
||||
{!readOnly && (
|
||||
<>
|
||||
<Button {...uploadButtonProps} block disabled={disabled} icon={<IconFileImport size="1.25em" />} onClick={handleButtonClick}>
|
||||
{uploadText ?? t("common.text.import_from_file")}
|
||||
</Button>
|
||||
<input ref={fileInputRef} type="file" style={{ display: "none" }} accept={accept} onChange={handleFileChange} />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
import { memo } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { ReadOutlined as ReadOutlinedIcon } from "@ant-design/icons";
|
||||
import { Badge, Divider, Space, Typography } from "antd";
|
||||
|
||||
import { version } from "@/domain/version";
|
||||
import { useVersionChecker } from "@/hooks";
|
||||
|
||||
export type VersionProps = {
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
};
|
||||
|
||||
const Version = ({ className, style }: VersionProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { hasNewVersion } = useVersionChecker();
|
||||
|
||||
return (
|
||||
<Space className={className} style={style} size={4}>
|
||||
<Typography.Link type="secondary" href="https://docs.certimate.me" target="_blank">
|
||||
<div className="flex items-center justify-center space-x-1">
|
||||
<ReadOutlinedIcon />
|
||||
<span>{t("common.menu.document")}</span>
|
||||
</div>
|
||||
</Typography.Link>
|
||||
|
||||
<Divider type="vertical" />
|
||||
|
||||
<Badge styles={{ indicator: { transform: "scale(0.75) translate(50%, -50%)" } }} count={hasNewVersion ? "NEW" : undefined}>
|
||||
<Typography.Link type="secondary" href="https://github.com/certimate-go/certimate/releases" target="_blank">
|
||||
{version}
|
||||
</Typography.Link>
|
||||
</Badge>
|
||||
</Space>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(Version);
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useRef, useState } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useControllableValue } from "ahooks";
|
||||
import { Button, Drawer, Space, notification } from "antd";
|
||||
import { App, Button, Drawer, Flex } from "antd";
|
||||
|
||||
import { type AccessModel } from "@/domain/access";
|
||||
import { useTriggerElement, useZustandShallowSelector } from "@/hooks";
|
||||
@@ -10,21 +10,21 @@ import { getErrMsg } from "@/utils/error";
|
||||
|
||||
import AccessForm, { type AccessFormInstance, type AccessFormProps } from "./AccessForm";
|
||||
|
||||
export type AccessEditDrawerProps = {
|
||||
export interface AccessEditDrawerProps {
|
||||
data?: AccessFormProps["initialValues"];
|
||||
loading?: boolean;
|
||||
mode: AccessFormProps["mode"];
|
||||
open?: boolean;
|
||||
scene: AccessFormProps["scene"];
|
||||
trigger?: React.ReactNode;
|
||||
usage?: AccessFormProps["usage"];
|
||||
onOpenChange?: (open: boolean) => void;
|
||||
afterSubmit?: (record: AccessModel) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const AccessEditDrawer = ({ data, loading, trigger, scene, usage, afterSubmit, ...props }: AccessEditDrawerProps) => {
|
||||
const AccessEditDrawer = ({ mode, data, loading, trigger, usage, afterSubmit, ...props }: AccessEditDrawerProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [notificationApi, NotificationContextHolder] = notification.useNotification();
|
||||
const { notification } = App.useApp();
|
||||
|
||||
const { createAccess, updateAccess } = useAccessesStore(useZustandShallowSelector(["createAccess", "updateAccess"]));
|
||||
|
||||
@@ -39,6 +39,11 @@ const AccessEditDrawer = ({ data, loading, trigger, scene, usage, afterSubmit, .
|
||||
const formRef = useRef<AccessFormInstance>(null);
|
||||
const [formPending, setFormPending] = useState(false);
|
||||
|
||||
const [footerShow, setFooterShow] = useState(!!data?.provider);
|
||||
useEffect(() => {
|
||||
setFooterShow(!!data?.provider);
|
||||
}, [data?.provider]);
|
||||
|
||||
const handleOkClick = async () => {
|
||||
setFormPending(true);
|
||||
try {
|
||||
@@ -51,26 +56,26 @@ const AccessEditDrawer = ({ data, loading, trigger, scene, usage, afterSubmit, .
|
||||
try {
|
||||
let values: AccessModel = formRef.current!.getFieldsValue();
|
||||
|
||||
if (scene === "add") {
|
||||
if (mode === "create") {
|
||||
if (data?.id) {
|
||||
throw "Invalid props: `data`";
|
||||
}
|
||||
|
||||
values = await createAccess(values);
|
||||
} else if (scene === "edit") {
|
||||
} else if (mode === "edit") {
|
||||
if (!data?.id) {
|
||||
throw "Invalid props: `data`";
|
||||
}
|
||||
|
||||
values = await updateAccess({ ...data, ...values });
|
||||
} else {
|
||||
throw "Invalid props: `scene`";
|
||||
throw "Invalid props: `action`";
|
||||
}
|
||||
|
||||
afterSubmit?.(values);
|
||||
setOpen(false);
|
||||
} catch (err) {
|
||||
notificationApi.error({ message: t("common.text.request_error"), description: getErrMsg(err) });
|
||||
notification.error({ message: t("common.text.request_error"), description: getErrMsg(err) });
|
||||
|
||||
throw err;
|
||||
} finally {
|
||||
@@ -84,10 +89,12 @@ const AccessEditDrawer = ({ data, loading, trigger, scene, usage, afterSubmit, .
|
||||
setOpen(false);
|
||||
};
|
||||
|
||||
const handleFormValuesChange: AccessFormProps["onValuesChange"] = (values) => {
|
||||
setFooterShow(!!values.provider);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{NotificationContextHolder}
|
||||
|
||||
{triggerEl}
|
||||
|
||||
<Drawer
|
||||
@@ -95,21 +102,25 @@ const AccessEditDrawer = ({ data, loading, trigger, scene, usage, afterSubmit, .
|
||||
closable={!formPending}
|
||||
destroyOnHidden
|
||||
footer={
|
||||
<Space className="w-full justify-end">
|
||||
<Button onClick={handleCancelClick}>{t("common.button.cancel")}</Button>
|
||||
<Button loading={formPending} type="primary" onClick={handleOkClick}>
|
||||
{scene === "edit" ? t("common.button.save") : t("common.button.submit")}
|
||||
</Button>
|
||||
</Space>
|
||||
footerShow ? (
|
||||
<Flex justify="end" gap="small">
|
||||
<Button onClick={handleCancelClick}>{t("common.button.cancel")}</Button>
|
||||
<Button loading={formPending} type="primary" onClick={handleOkClick}>
|
||||
{mode === "edit" ? t("common.button.save") : t("common.button.submit")}
|
||||
</Button>
|
||||
</Flex>
|
||||
) : (
|
||||
false
|
||||
)
|
||||
}
|
||||
loading={loading}
|
||||
maskClosable={!formPending}
|
||||
open={open}
|
||||
title={t(`access.action.${scene}`)}
|
||||
title={t(`access.action.${mode}.modal.title`)}
|
||||
width={720}
|
||||
onClose={() => setOpen(false)}
|
||||
>
|
||||
<AccessForm ref={formRef} initialValues={data} scene={scene === "add" ? "add" : "edit"} usage={usage} />
|
||||
<AccessForm ref={formRef} disabled={formPending} initialValues={data} mode={mode} usage={usage} onValuesChange={handleFormValuesChange} />
|
||||
</Drawer>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
import { useRef, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useControllableValue } from "ahooks";
|
||||
import { Modal, notification } from "antd";
|
||||
|
||||
import { type AccessModel } from "@/domain/access";
|
||||
import { useTriggerElement, useZustandShallowSelector } from "@/hooks";
|
||||
import { useAccessesStore } from "@/stores/access";
|
||||
import { getErrMsg } from "@/utils/error";
|
||||
|
||||
import AccessForm, { type AccessFormInstance, type AccessFormProps } from "./AccessForm";
|
||||
|
||||
export type AccessEditModalProps = {
|
||||
data?: AccessFormProps["initialValues"];
|
||||
loading?: boolean;
|
||||
open?: boolean;
|
||||
usage?: AccessFormProps["usage"];
|
||||
scene: AccessFormProps["scene"];
|
||||
trigger?: React.ReactNode;
|
||||
onOpenChange?: (open: boolean) => void;
|
||||
afterSubmit?: (record: AccessModel) => void;
|
||||
};
|
||||
|
||||
const AccessEditModal = ({ data, loading, trigger, scene, usage, afterSubmit, ...props }: AccessEditModalProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [notificationApi, NotificationContextHolder] = notification.useNotification();
|
||||
|
||||
const { createAccess, updateAccess } = useAccessesStore(useZustandShallowSelector(["createAccess", "updateAccess"]));
|
||||
|
||||
const [open, setOpen] = useControllableValue<boolean>(props, {
|
||||
valuePropName: "open",
|
||||
defaultValuePropName: "defaultOpen",
|
||||
trigger: "onOpenChange",
|
||||
});
|
||||
|
||||
const triggerEl = useTriggerElement(trigger, { onClick: () => setOpen(true) });
|
||||
|
||||
const formRef = useRef<AccessFormInstance>(null);
|
||||
const [formPending, setFormPending] = useState(false);
|
||||
|
||||
const handleOkClick = async () => {
|
||||
setFormPending(true);
|
||||
try {
|
||||
await formRef.current!.validateFields();
|
||||
} catch (err) {
|
||||
setFormPending(false);
|
||||
throw err;
|
||||
}
|
||||
|
||||
try {
|
||||
let values: AccessModel = formRef.current!.getFieldsValue();
|
||||
|
||||
if (scene === "add") {
|
||||
if (data?.id) {
|
||||
throw "Invalid props: `data`";
|
||||
}
|
||||
|
||||
values = await createAccess(values);
|
||||
} else if (scene === "edit") {
|
||||
if (!data?.id) {
|
||||
throw "Invalid props: `data`";
|
||||
}
|
||||
|
||||
values = await updateAccess({ ...data, ...values });
|
||||
} else {
|
||||
throw "Invalid props: `preset`";
|
||||
}
|
||||
|
||||
afterSubmit?.(values);
|
||||
setOpen(false);
|
||||
} catch (err) {
|
||||
notificationApi.error({ message: t("common.text.request_error"), description: getErrMsg(err) });
|
||||
|
||||
throw err;
|
||||
} finally {
|
||||
setFormPending(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleCancelClick = () => {
|
||||
if (formPending) return;
|
||||
|
||||
setOpen(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{NotificationContextHolder}
|
||||
|
||||
{triggerEl}
|
||||
|
||||
<Modal
|
||||
styles={{
|
||||
content: {
|
||||
maxHeight: "calc(80vh - 64px)",
|
||||
overflowX: "hidden",
|
||||
overflowY: "auto",
|
||||
},
|
||||
}}
|
||||
afterClose={() => setOpen(false)}
|
||||
cancelButtonProps={{ disabled: formPending }}
|
||||
cancelText={t("common.button.cancel")}
|
||||
closable
|
||||
confirmLoading={formPending}
|
||||
destroyOnHidden
|
||||
loading={loading}
|
||||
okText={scene === "edit" ? t("common.button.save") : t("common.button.submit")}
|
||||
open={open}
|
||||
title={t(`access.action.${scene}`)}
|
||||
width={480}
|
||||
onOk={handleOkClick}
|
||||
onCancel={handleCancelClick}
|
||||
>
|
||||
<div className="pb-2 pt-4">
|
||||
<AccessForm ref={formRef} initialValues={data} scene={scene === "add" ? "add" : "edit"} usage={usage} />
|
||||
</div>
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default AccessEditModal;
|
||||
@@ -2,7 +2,7 @@ import { forwardRef, useImperativeHandle, useMemo, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import AccessProviderPicker from "@/components/provider/AccessProviderPicker";
|
||||
import AccessProviderSelect from "@/components/provider/AccessProviderSelect";
|
||||
@@ -86,26 +86,26 @@ import AccessFormWestcnConfig from "./AccessFormWestcnConfig";
|
||||
import AccessFormZeroSSLConfig from "./AccessFormZeroSSLConfig";
|
||||
|
||||
type AccessFormFieldValues = Partial<MaybeModelRecord<AccessModel>>;
|
||||
type AccessFormScenes = "add" | "edit";
|
||||
type AccessFormUsages = "both-dns-hosting" | "ca-only" | "notification-only";
|
||||
type AccessFormModes = "create" | "edit";
|
||||
type AccessFormUsages = "dns" | "hosting" | "dns-hosting" | "ca" | "notification";
|
||||
|
||||
export type AccessFormProps = {
|
||||
export interface AccessFormProps {
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
mode: AccessFormModes;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormFieldValues;
|
||||
scene: AccessFormScenes;
|
||||
usage?: AccessFormUsages;
|
||||
onValuesChange?: (values: AccessFormFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
export type AccessFormInstance = {
|
||||
export interface AccessFormInstance {
|
||||
getFieldsValue: () => ReturnType<FormInstance<AccessFormFieldValues>["getFieldsValue"]>;
|
||||
resetFields: FormInstance<AccessFormFieldValues>["resetFields"];
|
||||
validateFields: FormInstance<AccessFormFieldValues>["validateFields"];
|
||||
};
|
||||
}
|
||||
|
||||
const AccessForm = forwardRef<AccessFormInstance, AccessFormProps>(({ className, style, disabled, initialValues, usage, scene, onValuesChange }, ref) => {
|
||||
const AccessForm = forwardRef<AccessFormInstance, AccessFormProps>(({ className, style, mode, disabled, initialValues, usage, onValuesChange }, ref) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const formSchema = z.object({
|
||||
@@ -113,14 +113,7 @@ const AccessForm = forwardRef<AccessFormInstance, AccessFormProps>(({ className,
|
||||
.string(t("access.form.name.placeholder"))
|
||||
.min(1, t("access.form.name.placeholder"))
|
||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
||||
provider: z.nativeEnum(ACCESS_PROVIDERS, {
|
||||
message:
|
||||
usage === "ca-only"
|
||||
? t("access.form.certificate_authority.placeholder")
|
||||
: usage === "notification-only"
|
||||
? t("access.form.notification_channel.placeholder")
|
||||
: t("access.form.provider.placeholder"),
|
||||
}),
|
||||
provider: z.enum(ACCESS_PROVIDERS, t("access.form.provider.placeholder")),
|
||||
config: z.any(),
|
||||
reserve: z.string().nullish(),
|
||||
});
|
||||
@@ -132,39 +125,23 @@ const AccessForm = forwardRef<AccessFormInstance, AccessFormProps>(({ className,
|
||||
|
||||
const providerFilter = useMemo(() => {
|
||||
switch (usage) {
|
||||
case "both-dns-hosting":
|
||||
case "dns":
|
||||
return (record: AccessProvider) => record.usages.includes(ACCESS_USAGES.DNS);
|
||||
case "hosting":
|
||||
return (record: AccessProvider) => record.usages.includes(ACCESS_USAGES.HOSTING);
|
||||
case "dns-hosting":
|
||||
return (record: AccessProvider) => record.usages.includes(ACCESS_USAGES.DNS) || record.usages.includes(ACCESS_USAGES.HOSTING);
|
||||
case "ca-only":
|
||||
case "ca":
|
||||
return (record: AccessProvider) => record.usages.includes(ACCESS_USAGES.CA);
|
||||
case "notification-only":
|
||||
case "notification":
|
||||
return (record: AccessProvider) => record.usages.includes(ACCESS_USAGES.NOTIFICATION);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}, [usage]);
|
||||
const providerLabel = useMemo(() => {
|
||||
switch (usage) {
|
||||
case "ca-only":
|
||||
return t("access.form.certificate_authority.label");
|
||||
case "notification-only":
|
||||
return t("access.form.notification_channel.label");
|
||||
}
|
||||
|
||||
return t("access.form.provider.label");
|
||||
}, [usage]);
|
||||
const providerPlaceholder = useMemo(() => {
|
||||
switch (usage) {
|
||||
case "ca-only":
|
||||
return t("access.form.certificate_authority.placeholder");
|
||||
case "notification-only":
|
||||
return t("access.form.notification_channel.placeholder");
|
||||
}
|
||||
|
||||
return t("access.form.provider.placeholder");
|
||||
}, [usage]);
|
||||
const providerTooltip = useMemo(() => {
|
||||
switch (usage) {
|
||||
case "both-dns-hosting":
|
||||
case "dns-hosting":
|
||||
return <span dangerouslySetInnerHTML={{ __html: t("access.form.provider.tooltip") }}></span>;
|
||||
}
|
||||
|
||||
@@ -330,7 +307,7 @@ const AccessForm = forwardRef<AccessFormInstance, AccessFormProps>(({ className,
|
||||
case ACCESS_PROVIDERS.WEBHOOK:
|
||||
return (
|
||||
<AccessFormWebhookConfig
|
||||
usage={usage === "notification-only" ? "notification" : usage === "both-dns-hosting" ? "deployment" : "none"}
|
||||
usage={usage === "notification" ? "notification" : usage === "hosting" || usage === "dns-hosting" ? "deployment" : "none"}
|
||||
{...nestedFormProps}
|
||||
/>
|
||||
);
|
||||
@@ -365,7 +342,7 @@ const AccessForm = forwardRef<AccessFormInstance, AccessFormProps>(({ className,
|
||||
getFieldsValue: () => {
|
||||
const values = formInst.getFieldsValue(true);
|
||||
values.config = nestedFormInst.getFieldsValue();
|
||||
values.reserve = usage === "ca-only" ? "ca" : usage === "notification-only" ? "notification" : undefined;
|
||||
values.reserve = usage === "ca" ? "ca" : usage === "notification" ? "notification" : undefined;
|
||||
return values;
|
||||
},
|
||||
resetFields: (fields) => {
|
||||
@@ -394,7 +371,7 @@ const AccessForm = forwardRef<AccessFormInstance, AccessFormProps>(({ className,
|
||||
autoFocus
|
||||
filter={providerFilter}
|
||||
placeholder={t("access.form.provider.search.placeholder")}
|
||||
showOptionTags={usage == null || (usage === "both-dns-hosting" ? { [ACCESS_USAGES.DNS]: true, [ACCESS_USAGES.HOSTING]: true } : false)}
|
||||
showOptionTags={usage == null || (usage === "dns-hosting" ? { [ACCESS_USAGES.DNS]: true, [ACCESS_USAGES.HOSTING]: true } : false)}
|
||||
onSelect={handleProviderPick}
|
||||
/>
|
||||
}
|
||||
@@ -403,12 +380,12 @@ const AccessForm = forwardRef<AccessFormInstance, AccessFormProps>(({ className,
|
||||
<Input placeholder={t("access.form.name.placeholder")} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item name="provider" label={providerLabel} rules={[formRule]} tooltip={providerTooltip}>
|
||||
<Form.Item name="provider" label={t("access.form.provider.label")} rules={[formRule]} tooltip={providerTooltip}>
|
||||
<AccessProviderSelect
|
||||
filter={providerFilter}
|
||||
disabled={scene !== "add"}
|
||||
placeholder={providerPlaceholder}
|
||||
showOptionTags={usage == null || (usage === "both-dns-hosting" ? { [ACCESS_USAGES.DNS]: true, [ACCESS_USAGES.HOSTING]: true } : false)}
|
||||
disabled={mode !== "create"}
|
||||
placeholder={t("access.form.provider.placeholder")}
|
||||
showOptionTags={usage == null || (usage === "dns-hosting" ? { [ACCESS_USAGES.DNS]: true, [ACCESS_USAGES.HOSTING]: true } : false)}
|
||||
showSearch={!disabled}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input, Select, Switch } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigFor1Panel } from "@/domain/access";
|
||||
|
||||
type AccessForm1PanelConfigFieldValues = Nullish<AccessConfigFor1Panel>;
|
||||
|
||||
export type AccessForm1PanelConfigProps = {
|
||||
export interface AccessForm1PanelConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessForm1PanelConfigFieldValues;
|
||||
onValuesChange?: (values: AccessForm1PanelConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessForm1PanelConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForACMECA } from "@/domain/access";
|
||||
|
||||
type AccessFormACMECAConfigFieldValues = Nullish<AccessConfigForACMECA>;
|
||||
|
||||
export type AccessFormACMECAConfigProps = {
|
||||
export interface AccessFormACMECAConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormACMECAConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormACMECAConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormACMECAConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input, Select } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForACMEHttpReq } from "@/domain/access";
|
||||
|
||||
type AccessFormACMEHttpReqConfigFieldValues = Nullish<AccessConfigForACMEHttpReq>;
|
||||
|
||||
export type AccessFormACMEHttpReqConfigProps = {
|
||||
export interface AccessFormACMEHttpReqConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormACMEHttpReqConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormACMEHttpReqConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormACMEHttpReqConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input, Switch } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForAPISIX } from "@/domain/access";
|
||||
|
||||
type AccessFormAPISIXConfigFieldValues = Nullish<AccessConfigForAPISIX>;
|
||||
|
||||
export type AccessFormAPISIXConfigProps = {
|
||||
export interface AccessFormAPISIXConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormAPISIXConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormAPISIXConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormAPISIXConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForAWS } from "@/domain/access";
|
||||
|
||||
type AccessFormAWSConfigFieldValues = Nullish<AccessConfigForAWS>;
|
||||
|
||||
export type AccessFormAWSConfigProps = {
|
||||
export interface AccessFormAWSConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormAWSConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormAWSConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormAWSConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForAliyun } from "@/domain/access";
|
||||
|
||||
type AccessFormAliyunConfigFieldValues = Nullish<AccessConfigForAliyun>;
|
||||
|
||||
export type AccessFormAliyunConfigProps = {
|
||||
export interface AccessFormAliyunConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormAliyunConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormAliyunConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormAliyunConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { AutoComplete, Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForAzure } from "@/domain/access";
|
||||
|
||||
type AccessFormAzureConfigFieldValues = Nullish<AccessConfigForAzure>;
|
||||
|
||||
export type AccessFormAzureConfigProps = {
|
||||
export interface AccessFormAzureConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormAzureConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormAzureConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormAzureConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForBaiduCloud } from "@/domain/access";
|
||||
|
||||
type AccessFormBaiduCloudConfigFieldValues = Nullish<AccessConfigForBaiduCloud>;
|
||||
|
||||
export type AccessFormBaiduCloudConfigProps = {
|
||||
export interface AccessFormBaiduCloudConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormBaiduCloudConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormBaiduCloudConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormBaiduCloudConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForBaishan } from "@/domain/access";
|
||||
|
||||
type AccessFormBaishanConfigFieldValues = Nullish<AccessConfigForBaishan>;
|
||||
|
||||
export type AccessFormBaishanConfigProps = {
|
||||
export interface AccessFormBaishanConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormBaishanConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormBaishanConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormBaishanConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input, Switch } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForBaotaPanel } from "@/domain/access";
|
||||
|
||||
type AccessFormBaotaPanelConfigFieldValues = Nullish<AccessConfigForBaotaPanel>;
|
||||
|
||||
export type AccessFormBaotaPanelConfigProps = {
|
||||
export interface AccessFormBaotaPanelConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormBaotaPanelConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormBaotaPanelConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormBaotaPanelConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input, Switch } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForBaotaWAF } from "@/domain/access";
|
||||
|
||||
type AccessFormBaotaWAFConfigFieldValues = Nullish<AccessConfigForBaotaWAF>;
|
||||
|
||||
export type AccessFormBaotaWAFConfigProps = {
|
||||
export interface AccessFormBaotaWAFConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormBaotaWAFConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormBaotaWAFConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormBaotaWAFConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForBunny } from "@/domain/access";
|
||||
|
||||
type AccessFormBunnyConfigFieldValues = Nullish<AccessConfigForBunny>;
|
||||
|
||||
export type AccessFormBunnyConfigProps = {
|
||||
export interface AccessFormBunnyConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormBunnyConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormBunnyConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormBunnyConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForBytePlus } from "@/domain/access";
|
||||
|
||||
type AccessFormBytePlusConfigFieldValues = Nullish<AccessConfigForBytePlus>;
|
||||
|
||||
export type AccessFormBytePlusConfigProps = {
|
||||
export interface AccessFormBytePlusConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormBytePlusConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormBytePlusConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormBytePlusConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
import { type AccessConfigForCMCCCloud } from "@/domain/access";
|
||||
|
||||
type AccessFormCMCCCloudConfigFieldValues = Nullish<AccessConfigForCMCCCloud>;
|
||||
|
||||
export type AccessFormCMCCCloudConfigProps = {
|
||||
export interface AccessFormCMCCCloudConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormCMCCCloudConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormCMCCCloudConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormCMCCCloudConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
import { type AccessConfigForCTCCCloud } from "@/domain/access";
|
||||
|
||||
type AccessFormCTCCCloudConfigFieldValues = Nullish<AccessConfigForCTCCCloud>;
|
||||
|
||||
export type AccessFormCTCCCloudConfigProps = {
|
||||
export interface AccessFormCTCCCloudConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormCTCCCloudConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormCTCCCloudConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormCTCCCloudConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForCacheFly } from "@/domain/access";
|
||||
|
||||
type AccessFormCacheFlyConfigFieldValues = Nullish<AccessConfigForCacheFly>;
|
||||
|
||||
export type AccessFormCacheFlyConfigProps = {
|
||||
export interface AccessFormCacheFlyConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormCacheFlyConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormCacheFlyConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormCacheFlyConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input, Switch } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForCdnfly } from "@/domain/access";
|
||||
|
||||
type AccessFormCdnflyConfigFieldValues = Nullish<AccessConfigForCdnfly>;
|
||||
|
||||
export type AccessFormCdnflyConfigProps = {
|
||||
export interface AccessFormCdnflyConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormCdnflyConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormCdnflyConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormCdnflyConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForClouDNS } from "@/domain/access";
|
||||
|
||||
type AccessFormClouDNSConfigFieldValues = Nullish<AccessConfigForClouDNS>;
|
||||
|
||||
export type AccessFormClouDNSConfigProps = {
|
||||
export interface AccessFormClouDNSConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormClouDNSConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormClouDNSConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormClouDNSConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForCloudflare } from "@/domain/access";
|
||||
|
||||
type AccessFormCloudflareConfigFieldValues = Nullish<AccessConfigForCloudflare>;
|
||||
|
||||
export type AccessFormCloudflareConfigProps = {
|
||||
export interface AccessFormCloudflareConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormCloudflareConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormCloudflareConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormCloudflareConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
import { type AccessConfigForConstellix } from "@/domain/access";
|
||||
|
||||
type AccessFormConstellixConfigFieldValues = Nullish<AccessConfigForConstellix>;
|
||||
|
||||
export type AccessFormConstellixConfigProps = {
|
||||
export interface AccessFormConstellixConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormConstellixConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormConstellixConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormConstellixConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForDNSLA } from "@/domain/access";
|
||||
|
||||
type AccessFormDNSLAConfigFieldValues = Nullish<AccessConfigForDNSLA>;
|
||||
|
||||
export type AccessFormDNSLAConfigProps = {
|
||||
export interface AccessFormDNSLAConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormDNSLAConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormDNSLAConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormDNSLAConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForDeSEC } from "@/domain/access";
|
||||
|
||||
type AccessFormDeSECConfigFieldValues = Nullish<AccessConfigForDeSEC>;
|
||||
|
||||
export type AccessFormDeSECConfigProps = {
|
||||
export interface AccessFormDeSECConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormDeSECConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormDeSECConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormDeSECConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForDigitalOcean } from "@/domain/access";
|
||||
|
||||
type AccessFormDigitalOceanConfigFieldValues = Nullish<AccessConfigForDigitalOcean>;
|
||||
|
||||
export type AccessFormDigitalOceanConfigProps = {
|
||||
export interface AccessFormDigitalOceanConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormDigitalOceanConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormDigitalOceanConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormDigitalOceanConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForDingTalkBot } from "@/domain/access";
|
||||
|
||||
type AccessFormDingTalkBotConfigFieldValues = Nullish<AccessConfigForDingTalkBot>;
|
||||
|
||||
export type AccessFormDingTalkBotConfigProps = {
|
||||
export interface AccessFormDingTalkBotConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormDingTalkBotConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormDingTalkBotConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormDingTalkBotConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForDiscordBot } from "@/domain/access";
|
||||
|
||||
type AccessFormDiscordBotConfigFieldValues = Nullish<AccessConfigForDiscordBot>;
|
||||
|
||||
export type AccessFormDiscordBotConfigProps = {
|
||||
export interface AccessFormDiscordBotConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormDiscordBotConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormDiscordBotConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormDiscordBotConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForDogeCloud } from "@/domain/access";
|
||||
|
||||
type AccessFormDogeCloudConfigFieldValues = Nullish<AccessConfigForDogeCloud>;
|
||||
|
||||
export type AccessFormDogeCloudConfigProps = {
|
||||
export interface AccessFormDogeCloudConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormDogeCloudConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormDogeCloudConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormDogeCloudConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForDuckDNS } from "@/domain/access";
|
||||
|
||||
type AccessFormDuckDNSConfigFieldValues = Nullish<AccessConfigForDuckDNS>;
|
||||
|
||||
export type AccessFormDuckDNSConfigProps = {
|
||||
export interface AccessFormDuckDNSConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormDuckDNSConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormDuckDNSConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormDuckDNSConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForDynv6 } from "@/domain/access";
|
||||
|
||||
type AccessFormDynv6ConfigFieldValues = Nullish<AccessConfigForDynv6>;
|
||||
|
||||
export type AccessFormDynv6ConfigProps = {
|
||||
export interface AccessFormDynv6ConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormDynv6ConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormDynv6ConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormDynv6ConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForEdgio } from "@/domain/access";
|
||||
|
||||
type AccessFormEdgioConfigFieldValues = Nullish<AccessConfigForEdgio>;
|
||||
|
||||
export type AccessFormEdgioConfigProps = {
|
||||
export interface AccessFormEdgioConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormEdgioConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormEdgioConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormEdgioConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input, InputNumber, Switch } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForEmail } from "@/domain/access";
|
||||
import { validEmailAddress, validPortNumber } from "@/utils/validators";
|
||||
|
||||
type AccessFormEmailConfigFieldValues = Nullish<AccessConfigForEmail>;
|
||||
|
||||
export type AccessFormEmailConfigProps = {
|
||||
export interface AccessFormEmailConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormEmailConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormEmailConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormEmailConfigFieldValues => {
|
||||
return {
|
||||
@@ -95,7 +95,7 @@ const AccessFormEmailConfig = ({ form: formInst, formName, disabled, initialValu
|
||||
|
||||
<div className="w-2/5">
|
||||
<Form.Item name="smtpPort" label={t("access.form.email_smtp_port.label")} rules={[formRule]}>
|
||||
<InputNumber className="w-full" placeholder={t("access.form.email_smtp_port.placeholder")} min={1} max={65535} />
|
||||
<InputNumber style={{ width: "100%" }} placeholder={t("access.form.email_smtp_port.placeholder")} min={1} max={65535} />
|
||||
</Form.Item>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input, Radio, Switch } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForFlexCDN } from "@/domain/access";
|
||||
|
||||
type AccessFormFlexCDNConfigFieldValues = Nullish<AccessConfigForFlexCDN>;
|
||||
|
||||
export type AccessFormFlexCDNConfigProps = {
|
||||
export interface AccessFormFlexCDNConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormFlexCDNConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormFlexCDNConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormFlexCDNConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForGcore } from "@/domain/access";
|
||||
|
||||
type AccessFormGcoreConfigFieldValues = Nullish<AccessConfigForGcore>;
|
||||
|
||||
export type AccessFormGcoreConfigProps = {
|
||||
export interface AccessFormGcoreConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormGcoreConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormGcoreConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormGcoreConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForGname } from "@/domain/access";
|
||||
|
||||
type AccessFormGnameConfigFieldValues = Nullish<AccessConfigForGname>;
|
||||
|
||||
export type AccessFormGnameConfigProps = {
|
||||
export interface AccessFormGnameConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormGnameConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormGnameConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormGnameConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForGoDaddy } from "@/domain/access";
|
||||
|
||||
type AccessFormGoDaddyConfigFieldValues = Nullish<AccessConfigForGoDaddy>;
|
||||
|
||||
export type AccessFormGoDaddyConfigProps = {
|
||||
export interface AccessFormGoDaddyConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormGoDaddyConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormGoDaddyConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormGoDaddyConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input, Radio, Switch } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForGoEdge } from "@/domain/access";
|
||||
|
||||
type AccessFormGoEdgeConfigFieldValues = Nullish<AccessConfigForGoEdge>;
|
||||
|
||||
export type AccessFormGoEdgeConfigProps = {
|
||||
export interface AccessFormGoEdgeConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormGoEdgeConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormGoEdgeConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormGoEdgeConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForGoogleTrustServices } from "@/domain/access";
|
||||
|
||||
type AccessFormGoogleTrustServicesConfigFieldValues = Nullish<AccessConfigForGoogleTrustServices>;
|
||||
|
||||
export type AccessFormGoogleTrustServicesConfigProps = {
|
||||
export interface AccessFormGoogleTrustServicesConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormGoogleTrustServicesConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormGoogleTrustServicesConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormGoogleTrustServicesConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForHetzner } from "@/domain/access";
|
||||
|
||||
type AccessFormHetznerConfigFieldValues = Nullish<AccessConfigForHetzner>;
|
||||
|
||||
export type AccessFormHetznerConfigProps = {
|
||||
export interface AccessFormHetznerConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormHetznerConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormHetznerConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormHetznerConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForHuaweiCloud } from "@/domain/access";
|
||||
|
||||
type AccessFormHuaweiCloudConfigFieldValues = Nullish<AccessConfigForHuaweiCloud>;
|
||||
|
||||
export type AccessFormHuaweiCloudConfigProps = {
|
||||
export interface AccessFormHuaweiCloudConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormHuaweiCloudConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormHuaweiCloudConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormHuaweiCloudConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForJDCloud } from "@/domain/access";
|
||||
|
||||
type AccessFormJDCloudConfigFieldValues = Nullish<AccessConfigForJDCloud>;
|
||||
|
||||
export type AccessFormJDCloudConfigProps = {
|
||||
export interface AccessFormJDCloudConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormJDCloudConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormJDCloudConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormJDCloudConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input, Switch } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForKong } from "@/domain/access";
|
||||
|
||||
type AccessFormKongConfigFieldValues = Nullish<AccessConfigForKong>;
|
||||
|
||||
export type AccessFormKongConfigProps = {
|
||||
export interface AccessFormKongConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormKongConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormKongConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormKongConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import TextFileInput from "@/components/TextFileInput";
|
||||
import { type AccessConfigForKubernetes } from "@/domain/access";
|
||||
|
||||
type AccessFormKubernetesConfigFieldValues = Nullish<AccessConfigForKubernetes>;
|
||||
|
||||
export type AccessFormKubernetesConfigProps = {
|
||||
export interface AccessFormKubernetesConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormKubernetesConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormKubernetesConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormKubernetesConfigFieldValues => {
|
||||
return {};
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForLarkBot } from "@/domain/access";
|
||||
|
||||
type AccessFormLarkBotConfigFieldValues = Nullish<AccessConfigForLarkBot>;
|
||||
|
||||
export type AccessFormLarkBotConfigProps = {
|
||||
export interface AccessFormLarkBotConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormLarkBotConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormLarkBotConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormLarkBotConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input, Radio, Select, Switch } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForLeCDN } from "@/domain/access";
|
||||
|
||||
type AccessFormLeCDNConfigFieldValues = Nullish<AccessConfigForLeCDN>;
|
||||
|
||||
export type AccessFormLeCDNConfigProps = {
|
||||
export interface AccessFormLeCDNConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormLeCDNConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormLeCDNConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormLeCDNConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForMattermost } from "@/domain/access";
|
||||
|
||||
type AccessFormMattermostConfigFieldValues = Nullish<AccessConfigForMattermost>;
|
||||
|
||||
export type AccessFormMattermostConfigProps = {
|
||||
export interface AccessFormMattermostConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormMattermostConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormMattermostConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormMattermostConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForNS1 } from "@/domain/access";
|
||||
|
||||
type AccessFormNS1ConfigFieldValues = Nullish<AccessConfigForNS1>;
|
||||
|
||||
export type AccessFormNS1ConfigProps = {
|
||||
export interface AccessFormNS1ConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormNS1ConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormNS1ConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormNS1ConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForNameDotCom } from "@/domain/access";
|
||||
|
||||
type AccessFormNameDotComConfigFieldValues = Nullish<AccessConfigForNameDotCom>;
|
||||
|
||||
export type AccessFormNameDotComConfigProps = {
|
||||
export interface AccessFormNameDotComConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormNameDotComConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormNameDotComConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormNameDotComConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForNameSilo } from "@/domain/access";
|
||||
|
||||
type AccessFormNameSiloConfigFieldValues = Nullish<AccessConfigForNameSilo>;
|
||||
|
||||
export type AccessFormNameSiloConfigProps = {
|
||||
export interface AccessFormNameSiloConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormNameSiloConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormNameSiloConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormNameSiloConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForNamecheap } from "@/domain/access";
|
||||
|
||||
type AccessFormNamecheapConfigFieldValues = Nullish<AccessConfigForNamecheap>;
|
||||
|
||||
export type AccessFormNamecheapConfigProps = {
|
||||
export interface AccessFormNamecheapConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormNamecheapConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormNamecheapConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormNamecheapConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForNetcup } from "@/domain/access";
|
||||
|
||||
type AccessFormNetcupConfigFieldValues = Nullish<AccessConfigForNetcup>;
|
||||
|
||||
export type AccessFormNetcupConfigProps = {
|
||||
export interface AccessFormNetcupConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormNetcupConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormNetcupConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormNetcupConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForNetlify } from "@/domain/access";
|
||||
|
||||
type AccessFormNetlifyConfigFieldValues = Nullish<AccessConfigForNetlify>;
|
||||
|
||||
export type AccessFormNetlifyConfigProps = {
|
||||
export interface AccessFormNetlifyConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormNetlifyConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormNetlifyConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormNetlifyConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForPorkbun } from "@/domain/access";
|
||||
|
||||
type AccessFormPorkbunConfigFieldValues = Nullish<AccessConfigForPorkbun>;
|
||||
|
||||
export type AccessFormPorkbunConfigProps = {
|
||||
export interface AccessFormPorkbunConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormPorkbunConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormPorkbunConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormPorkbunConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input, Switch } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForPowerDNS } from "@/domain/access";
|
||||
|
||||
type AccessFormPowerDNSConfigFieldValues = Nullish<AccessConfigForPowerDNS>;
|
||||
|
||||
export type AccessFormPowerDNSConfigProps = {
|
||||
export interface AccessFormPowerDNSConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormPowerDNSConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormPowerDNSConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormPowerDNSConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input, Switch } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForProxmoxVE } from "@/domain/access";
|
||||
|
||||
type AccessFormProxmoxVEConfigFieldValues = Nullish<AccessConfigForProxmoxVE>;
|
||||
|
||||
export type AccessFormProxmoxVEConfigProps = {
|
||||
export interface AccessFormProxmoxVEConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormProxmoxVEConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormProxmoxVEConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormProxmoxVEConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForQiniu } from "@/domain/access";
|
||||
|
||||
type AccessFormQiniuConfigFieldValues = Nullish<AccessConfigForQiniu>;
|
||||
|
||||
export type AccessFormQiniuConfigProps = {
|
||||
export interface AccessFormQiniuConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormQiniuConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormQiniuConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormQiniuConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForRainYun } from "@/domain/access";
|
||||
|
||||
type AccessFormRainYunConfigFieldValues = Nullish<AccessConfigForRainYun>;
|
||||
|
||||
export type AccessFormRainYunConfigProps = {
|
||||
export interface AccessFormRainYunConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormRainYunConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormRainYunConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormRainYunConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input, Switch } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForRatPanel } from "@/domain/access";
|
||||
|
||||
type AccessFormRatPanelConfigFieldValues = Nullish<AccessConfigForRatPanel>;
|
||||
|
||||
export type AccessFormRatPanelConfigProps = {
|
||||
export interface AccessFormRatPanelConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormRatPanelConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormRatPanelConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormRatPanelConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { ArrowDownOutlined, ArrowUpOutlined, CloseOutlined, PlusOutlined } from "@ant-design/icons";
|
||||
import { Button, Collapse, Form, type FormInstance, Input, InputNumber, Select, Space } from "antd";
|
||||
import { IconCircleArrowDown, IconCircleArrowUp, IconCircleMinus, IconCirclePlus } from "@tabler/icons-react";
|
||||
import { Button, Collapse, Form, type FormInstance, Input, InputNumber, Select } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import Show from "@/components/Show";
|
||||
import TextFileInput from "@/components/TextFileInput";
|
||||
@@ -11,13 +11,13 @@ import { validDomainName, validIPv4Address, validIPv6Address, validPortNumber }
|
||||
|
||||
type AccessFormSSHConfigFieldValues = Nullish<AccessConfigForSSH>;
|
||||
|
||||
export type AccessFormSSHConfigProps = {
|
||||
export interface AccessFormSSHConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormSSHConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormSSHConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const AUTH_METHOD_NONE = "none" as const;
|
||||
const AUTH_METHOD_PASSWORD = "password" as const;
|
||||
@@ -129,7 +129,7 @@ const AccessFormSSHConfig = ({ form: formInst, formName, disabled, initialValues
|
||||
|
||||
<div className="w-1/3">
|
||||
<Form.Item name="port" label={t("access.form.ssh_port.label")} rules={[formRule]}>
|
||||
<InputNumber className="w-full" min={1} max={65535} placeholder={t("access.form.ssh_port.placeholder")} />
|
||||
<InputNumber style={{ width: "100%" }} min={1} max={65535} placeholder={t("access.form.ssh_port.placeholder")} />
|
||||
</Form.Item>
|
||||
</div>
|
||||
</div>
|
||||
@@ -171,7 +171,7 @@ const AccessFormSSHConfig = ({ form: formInst, formName, disabled, initialValues
|
||||
<Form.Item name="jumpServers" label={t("access.form.ssh_jump_servers.label")} rules={[formRule]}>
|
||||
<Form.List name="jumpServers">
|
||||
{(fields, { add, remove, move }) => (
|
||||
<Space className="w-full" direction="vertical" size="small">
|
||||
<div className="flex flex-col gap-2">
|
||||
{fields?.length > 0 ? (
|
||||
<Collapse
|
||||
items={fields.map((field, index) => {
|
||||
@@ -198,7 +198,7 @@ const AccessFormSSHConfig = ({ form: formInst, formName, disabled, initialValues
|
||||
</div>
|
||||
<div className="w-1/3">
|
||||
<Form.Item name={[field.name, "port"]} label={t("access.form.ssh_port.label")} rules={[formRule]}>
|
||||
<InputNumber className="w-full" placeholder={t("access.form.ssh_port.placeholder")} min={1} max={65535} />
|
||||
<InputNumber style={{ width: "100%" }} placeholder={t("access.form.ssh_port.placeholder")} min={1} max={65535} />
|
||||
</Form.Item>
|
||||
</div>
|
||||
</div>
|
||||
@@ -244,9 +244,9 @@ const AccessFormSSHConfig = ({ form: formInst, formName, disabled, initialValues
|
||||
key: field.key,
|
||||
label: <Label />,
|
||||
extra: (
|
||||
<Space.Compact>
|
||||
<div className="flex items-center justify-end">
|
||||
<Button
|
||||
icon={<ArrowUpOutlined />}
|
||||
icon={<IconCircleArrowUp size="1.25em" />}
|
||||
color="default"
|
||||
disabled={disabled || index === 0}
|
||||
size="small"
|
||||
@@ -257,7 +257,7 @@ const AccessFormSSHConfig = ({ form: formInst, formName, disabled, initialValues
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
icon={<ArrowDownOutlined />}
|
||||
icon={<IconCircleArrowDown size="1.25em" />}
|
||||
color="default"
|
||||
disabled={disabled || index === fields.length - 1}
|
||||
size="small"
|
||||
@@ -268,7 +268,7 @@ const AccessFormSSHConfig = ({ form: formInst, formName, disabled, initialValues
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
icon={<CloseOutlined />}
|
||||
icon={<IconCircleMinus size="1.25em" />}
|
||||
color="default"
|
||||
disabled={disabled}
|
||||
size="small"
|
||||
@@ -278,17 +278,17 @@ const AccessFormSSHConfig = ({ form: formInst, formName, disabled, initialValues
|
||||
e.stopPropagation();
|
||||
}}
|
||||
/>
|
||||
</Space.Compact>
|
||||
</div>
|
||||
),
|
||||
children: <Fields />,
|
||||
};
|
||||
})}
|
||||
/>
|
||||
) : null}
|
||||
<Button className="w-full" type="dashed" icon={<PlusOutlined />} onClick={() => add(initFormModel())}>
|
||||
<Button className="w-full" type="dashed" icon={<IconCirclePlus size="1.25em" />} onClick={() => add(initFormModel())}>
|
||||
{t("access.form.ssh_jump_servers.add")}
|
||||
</Button>
|
||||
</Space>
|
||||
</div>
|
||||
)}
|
||||
</Form.List>
|
||||
</Form.Item>
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForSSLCom } from "@/domain/access";
|
||||
|
||||
type AccessFormSSLComConfigFieldValues = Nullish<AccessConfigForSSLCom>;
|
||||
|
||||
export type AccessFormSSLComConfigProps = {
|
||||
export interface AccessFormSSLComConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormSSLComConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormSSLComConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormSSLComConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input, Switch } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForSafeLine } from "@/domain/access";
|
||||
|
||||
type AccessFormSafeLineConfigFieldValues = Nullish<AccessConfigForSafeLine>;
|
||||
|
||||
export type AccessFormSafeLineConfigProps = {
|
||||
export interface AccessFormSafeLineConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormSafeLineConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormSafeLineConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormSafeLineConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForSlackBot } from "@/domain/access";
|
||||
|
||||
type AccessFormSlackBotConfigFieldValues = Nullish<AccessConfigForSlackBot>;
|
||||
|
||||
export type AccessFormSlackBotConfigProps = {
|
||||
export interface AccessFormSlackBotConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormSlackBotConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormSlackBotConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormSlackBotConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForSpaceship } from "@/domain/access";
|
||||
|
||||
type AccessFormSpaceshipConfigFieldValues = Nullish<AccessConfigForSpaceship>;
|
||||
|
||||
export type AccessFormSpaceshipConfigProps = {
|
||||
export interface AccessFormSpaceshipConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormSpaceshipConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormSpaceshipConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormSpaceshipConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForTelegramBot } from "@/domain/access";
|
||||
|
||||
type AccessFormTelegramBotConfigFieldValues = Nullish<AccessConfigForTelegramBot>;
|
||||
|
||||
export type AccessFormTelegramBotConfigProps = {
|
||||
export interface AccessFormTelegramBotConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormTelegramBotConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormTelegramBotConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormTelegramBotConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForTencentCloud } from "@/domain/access";
|
||||
|
||||
type AccessFormTencentCloudConfigFieldValues = Nullish<AccessConfigForTencentCloud>;
|
||||
|
||||
export type AccessFormTencentCloudConfigProps = {
|
||||
export interface AccessFormTencentCloudConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormTencentCloudConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormTencentCloudConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormTencentCloudConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForUCloud } from "@/domain/access";
|
||||
|
||||
type AccessFormUCloudConfigFieldValues = Nullish<AccessConfigForUCloud>;
|
||||
|
||||
export type AccessFormUCloudConfigProps = {
|
||||
export interface AccessFormUCloudConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormUCloudConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormUCloudConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormUCloudConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForUniCloud } from "@/domain/access";
|
||||
|
||||
type AccessFormUniCloudConfigFieldValues = Nullish<AccessConfigForUniCloud>;
|
||||
|
||||
export type AccessFormUniCloudConfigProps = {
|
||||
export interface AccessFormUniCloudConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormUniCloudConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormUniCloudConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormUniCloudConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForUpyun } from "@/domain/access";
|
||||
|
||||
type AccessFormUpyunConfigFieldValues = Nullish<AccessConfigForUpyun>;
|
||||
|
||||
export type AccessFormUpyunConfigProps = {
|
||||
export interface AccessFormUpyunConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormUpyunConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormUpyunConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormUpyunConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForVercel } from "@/domain/access";
|
||||
|
||||
type AccessFormVercelConfigFieldValues = Nullish<AccessConfigForVercel>;
|
||||
|
||||
export type AccessFormVercelConfigProps = {
|
||||
export interface AccessFormVercelConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormVercelConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormVercelConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormVercelConfigFieldValues => {
|
||||
return {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod/v4";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type AccessConfigForVolcEngine } from "@/domain/access";
|
||||
|
||||
type AccessFormVolcEngineConfigFieldValues = Nullish<AccessConfigForVolcEngine>;
|
||||
|
||||
export type AccessFormVolcEngineConfigProps = {
|
||||
export interface AccessFormVolcEngineConfigProps {
|
||||
form: FormInstance;
|
||||
formName: string;
|
||||
disabled?: boolean;
|
||||
initialValues?: AccessFormVolcEngineConfigFieldValues;
|
||||
onValuesChange?: (values: AccessFormVolcEngineConfigFieldValues) => void;
|
||||
};
|
||||
}
|
||||
|
||||
const initFormModel = (): AccessFormVolcEngineConfigFieldValues => {
|
||||
return {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user