diff --git a/ui/src/components/certimate/StringList.tsx b/ui/src/components/certimate/StringList.tsx index 02517b6f..0ce888aa 100644 --- a/ui/src/components/certimate/StringList.tsx +++ b/ui/src/components/certimate/StringList.tsx @@ -20,13 +20,14 @@ import { Edit, Plus, Trash2 } from "lucide-react"; type StringListProps = { className?: string; value: string; - valueType?: "domain" | "ip"; + valueType?: ValueType; onValueChange: (value: string) => void; }; const titles: Record = { domain: "domain", ip: "IP", + dns: "dns", }; const StringList = ({ @@ -100,7 +101,9 @@ const StringList = ({ when={list.length > 0} fallback={
-
暂未添加域名
+
+ {t("not.added.yet." + valueType)} +
= { domain: domainSchema, - ip: ipSchema, + dns: ipSchema, + host: ipSchema, }; const onSaveClick = useCallback(() => { diff --git a/ui/src/domain/domain.ts b/ui/src/domain/domain.ts index e4c031c1..a49378bf 100644 --- a/ui/src/domain/domain.ts +++ b/ui/src/domain/domain.ts @@ -7,7 +7,7 @@ export type Domain = { crontab: string; access: string; targetAccess?: string; - targetType: string; + targetType?: string; expiredAt?: string; phase?: Pahse; phaseSuccess?: boolean; @@ -31,10 +31,19 @@ export type Domain = { deployConfig?: DeployConfig[]; }; +type KVType = { + key: string; + value: string; +}; + export type DeployConfig = { access: string; type: string; - config?: Record; + config?: { + [key: string]: string; + } & { + variables?: KVType[]; + }; }; export type ApplyConfig = { diff --git a/ui/src/i18n/locales/en.json b/ui/src/i18n/locales/en.json index d9f85adb..c2b8b2d2 100644 --- a/ui/src/i18n/locales/en.json +++ b/ui/src/i18n/locales/en.json @@ -4,12 +4,14 @@ "username.not.empty": "Please enter username", "password": "Password", "password.not.empty": "Please enter password", + "ip.not.empty.verify.message": "Please enter Ip", "email": "Email", "logout": "Logout", "setting": "Settings", "account": "Account", "template": "Template", "save": "Save", + "next": "Next", "no.data": "No data available", "status": "Status", "operation": "Operation", @@ -28,12 +30,15 @@ "variables": "Variables", "dns": "Domain Name Server", "name": "Name", + "timeout": "Time Out", + "not.added.yet.domain": "Domain not added yet.", + "not.added.yet.dns": "Nameserver not added yet.", "create.time": "CreateTime", "update.time": "UpdateTime", "created.in": "Created in", "updated.in": "Updated in", - "basic.setting": "Basic Settings", - "advanced.setting": "Advanced Settings", + "apply.setting": "Apply Settings", + "deploy.setting": "Deploy Settings", "operation.succeed": "Operation Successful", "save.succeed": "Save Successful", "save.failed": "Save Failed", @@ -83,7 +88,7 @@ "pagination.prev": "Previous", "domain": "Domain", "domain.add": "Add Domain", - "domain.edit":"Edit Domain", + "domain.edit": "Edit Domain", "domain.delete": "Delete Domain", "domain.not.empty.verify.message": "Please enter domain", "domain.management.name": "Domain List", @@ -120,6 +125,10 @@ "domain.management.edit.variables.placeholder": "It can be used in SSH deployment, like:\nkey=val;\nkey2=val2;", "domain.management.edit.dns.placeholder": "Custom domain name server, separates multiple entries with semicolon, like:\n8.8.8.8;\n8.8.4.4;", "domain.management.add.succeed.tips": "Domain added successfully", + "domain.management.edit.timeout.placeholder": "Timeout (seconds)", + "domain.management.edit.deploy.error": "Please save applyment configuration first", + "domain.management.enabled.failed": "Enable failed", + "domain.management.enabled.without.deployments": "Failed to enable, no deployment configuration found", "email.add": "Add Email", "email.list": "Email List", "email.valid.message": "Please enter a valid email address", diff --git a/ui/src/i18n/locales/zh.json b/ui/src/i18n/locales/zh.json index 9a25bcdc..ed28deed 100644 --- a/ui/src/i18n/locales/zh.json +++ b/ui/src/i18n/locales/zh.json @@ -4,12 +4,14 @@ "username.not.empty": "请输入用户名", "password": "密码", "password.not.empty": "请输入密码", + "ip.not.empty.verify.message": "请输入 IP", "email": "邮箱", "logout": "退出登录", "setting": "设置", "account": "账户", "template": "模版", "save": "保存", + "next": "下一步", "no.data": "暂无数据", "status": "状态", "operation": "操作", @@ -28,12 +30,15 @@ "variables": "变量", "dns": "域名服务器", "name": "名称", + "timeout": "超时时间", + "not.added.yet.domain": "域名未添加", + "not.added.yet.dns": "域名服务器暂未添加", "create.time": "创建时间", "update.time": "更新时间", "created.in": "创建于", "updated.in": "更新于", - "basic.setting": "基础设置", - "advanced.setting": "高级设置", + "apply.setting": "申请设置", + "deploy.setting": "部署设置", "operation.succeed": "操作成功", "save.succeed": "保存成功", "save.failed": "保存失败", @@ -120,6 +125,10 @@ "domain.management.edit.variables.placeholder": "可在SSH部署中使用,形如:\nkey=val;\nkey2=val2;", "domain.management.edit.dns.placeholder": "自定义域名服务器,多个用分号隔开,如:\n8.8.8.8;\n8.8.4.4;", "domain.management.add.succeed.tips": "域名添加成功", + "domain.management.edit.timeout.placeholder": "超时时间(单位:秒)", + "domain.management.edit.deploy.error": "请先保存申请配置", + "domain.management.enabled.failed": "启用失败", + "domain.management.enabled.without.deployments": "启用失败,请先设置部署配置", "email.add": "添加邮箱", "email.list": "邮箱列表", "email.valid.message": "请输入正确的邮箱地址", diff --git a/ui/src/pages/domains/Edit.tsx b/ui/src/pages/domains/Edit.tsx index 5827db01..b01c9219 100644 --- a/ui/src/pages/domains/Edit.tsx +++ b/ui/src/pages/domains/Edit.tsx @@ -30,7 +30,7 @@ import { PbErrorData } from "@/domain/base"; import { useToast } from "@/components/ui/use-toast"; import { Toaster } from "@/components/ui/toaster"; import { useLocation, useNavigate } from "react-router-dom"; -import { Plus } from "lucide-react"; +import { Plus, Trash2, Edit as EditIcon } from "lucide-react"; import { AccessEdit } from "@/components/certimate/AccessEdit"; import { accessTypeMap } from "@/domain/access"; import EmailsEdit from "@/components/certimate/EmailsEdit"; @@ -39,6 +39,7 @@ import { cn } from "@/lib/utils"; import { EmailsSetting } from "@/domain/settings"; import { useTranslation } from "react-i18next"; import StringList from "@/components/certimate/StringList"; +import { Input } from "@/components/ui/input"; const Edit = () => { const { @@ -50,7 +51,7 @@ const Edit = () => { const location = useLocation(); const { t } = useTranslation(); - const [tab, setTab] = useState<"base" | "advance">("base"); + const [tab, setTab] = useState<"apply" | "deploy">("apply"); const [targetType, setTargetType] = useState(domain ? domain.targetType : ""); @@ -77,13 +78,8 @@ const Edit = () => { access: z.string().regex(/^[a-zA-Z0-9]+$/, { message: "domain.management.edit.dns.access.not.empty.message", }), - targetAccess: z.string().optional(), - targetType: z.string().regex(/^[a-zA-Z0-9-]+$/, { - message: "domain.management.edit.target.type.not.empty.message", - }), - variables: z.string().optional(), - group: z.string().optional(), nameservers: z.string().optional(), + timeout: z.number().optional(), }); const form = useForm>({ @@ -93,11 +89,8 @@ const Edit = () => { domain: "", email: "", access: "", - targetAccess: "", - targetType: "", - variables: "", - group: "", nameservers: "", + timeout: 60, }, }); @@ -106,13 +99,11 @@ const Edit = () => { form.reset({ id: domain.id, domain: domain.domain, - email: domain.email, - access: domain.access, - targetAccess: domain.targetAccess, - targetType: domain.targetType, - variables: domain.variables, - group: domain.group, - nameservers: domain.nameservers, + email: domain.applyConfig?.email, + access: domain.applyConfig?.access, + + nameservers: domain.applyConfig?.nameservers, + timeout: domain.applyConfig?.timeout, }); } }, [domain, form]); @@ -134,32 +125,19 @@ const Edit = () => { const navigate = useNavigate(); const onSubmit = async (data: z.infer) => { - const group = data.group == "emptyId" ? "" : data.group; - const targetAccess = - data.targetAccess === "emptyId" ? "" : data.targetAccess; - if (group == "" && targetAccess == "") { - form.setError("group", { - type: "manual", - message: "domain.management.edit.target.access.verify.msg", - }); - form.setError("targetAccess", { - type: "manual", - message: "domain.management.edit.target.access.verify.msg", - }); - return; - } - + console.log(data); const req: Domain = { id: data.id as string, crontab: "0 0 * * *", domain: data.domain, email: data.email, access: data.access, - group: group, - targetAccess: targetAccess, - targetType: data.targetType, - variables: data.variables, - nameservers: data.nameservers, + applyConfig: { + email: data.email ?? "", + access: data.access, + nameservers: data.nameservers, + timeout: data.timeout, + }, }; try { @@ -173,7 +151,7 @@ const Edit = () => { title: t("succeed"), description, }); - navigate("/domains"); + if (!domain?.id) setTab("deploy"); } catch (e) { const err = e as ClientResponseError; @@ -198,400 +176,271 @@ const Edit = () => { {domain?.id ? t("domain.edit") : t("domain.add")}
-
+
{ - setTab("base"); + setTab("apply"); }} > - {t("basic.setting")} + {t("apply.setting")}
{ - setTab("advance"); + if (!domain?.id) { + toast({ + title: t("domain.management.edit.deploy.error"), + description: t("domain.management.edit.deploy.error"), + variant: "destructive", + }); + return; + } + setTab("deploy"); }} > - {t("advanced.setting")} + {t("deploy.setting")}
+
+
+
+ + {/* 域名 */} + ( + + <> + { + form.setValue("domain", domain); + }} + /> + -
- - - ( - - )} - /> - ( -
- } - /> - - - - - - -
- )} - /> - ( -
- } - op="add" - /> - - - - - - - - )} - /> - ( - - )} - /> - ( -
- } - op="add" - /> - - - - - - - - )} - /> - - ( - - )} - /> - ( -