This commit is contained in:
yoan
2024-10-10 11:13:45 +08:00
parent 30ef5841d6
commit 9f1b00f04c
6 changed files with 301 additions and 420 deletions

View File

@@ -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<z.infer<typeof formSchema>>({
@@ -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<typeof formSchema>) => {
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")}
</div>
<div className="mt-5 flex w-full justify-center md:space-x-10 flex-col md:flex-row">
<div className="w-full md:w-[200px] text-muted-foreground space-x-3 md:space-y-3 flex-row md:flex-col flex">
<div className="w-full md:w-[200px] text-muted-foreground space-x-3 md:space-y-3 flex-row md:flex-col flex md:mt-5">
<div
className={cn(
"cursor-pointer text-right",
tab === "base" ? "text-primary" : ""
tab === "apply" ? "text-primary" : ""
)}
onClick={() => {
setTab("base");
setTab("apply");
}}
>
{t("basic.setting")}
{t("apply.setting")}
</div>
<div
className={cn(
"cursor-pointer text-right",
tab === "advance" ? "text-primary" : ""
tab === "deploy" ? "text-primary" : ""
)}
onClick={() => {
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")}
</div>
</div>
<div className="flex flex-col">
<div
className={cn(
"w-full md:w-[35em] p-5 rounded mt-3 md:mt-0",
tab == "deploy" && "hidden"
)}
>
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="space-y-8 dark:text-stone-200"
>
{/* 域名 */}
<FormField
control={form.control}
name="domain"
render={({ field }) => (
<FormItem>
<>
<StringList
value={field.value}
valueType="domain"
onValueChange={(domain: string) => {
form.setValue("domain", domain);
}}
/>
</>
<div className="w-full md:w-[35em] bg-gray-100 dark:bg-gray-900 p-5 rounded mt-3 md:mt-0">
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="space-y-8 dark:text-stone-200"
>
<FormField
control={form.control}
name="domain"
render={({ field }) => (
<FormItem hidden={tab != "base"}>
<>
<StringList
value={field.value}
valueType="domain"
onValueChange={(domain: string) => {
form.setValue("domain", domain);
}}
/>
</>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem hidden={tab != "base"}>
<FormLabel className="flex w-full justify-between">
<div>
{t("email") +
t("domain.management.edit.email.description")}
</div>
<EmailsEdit
trigger={
<div className="font-normal text-primary hover:underline cursor-pointer flex items-center">
<Plus size={14} />
{t("add")}
</div>
}
/>
</FormLabel>
<FormControl>
<Select
{...field}
value={field.value}
onValueChange={(value) => {
form.setValue("email", value);
}}
>
<SelectTrigger>
<SelectValue
placeholder={t(
"domain.management.edit.email.not.empty.message"
)}
/>
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>{t("email.list")}</SelectLabel>
{(emails.content as EmailsSetting).emails.map(
(item) => (
<SelectItem key={item} value={item}>
<div>{item}</div>
</SelectItem>
)
)}
</SelectGroup>
</SelectContent>
</Select>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="access"
render={({ field }) => (
<FormItem hidden={tab != "base"}>
<FormLabel className="flex w-full justify-between">
<div>
{t("domain.management.edit.dns.access.label")}
</div>
<AccessEdit
trigger={
<div className="font-normal text-primary hover:underline cursor-pointer flex items-center">
<Plus size={14} />
{t("add")}
</div>
}
op="add"
/>
</FormLabel>
<FormControl>
<Select
{...field}
value={field.value}
onValueChange={(value) => {
form.setValue("access", value);
}}
>
<SelectTrigger>
<SelectValue
placeholder={t(
"domain.management.edit.access.not.empty.message"
)}
/>
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>
{t("domain.management.edit.access.label")}
</SelectLabel>
{accesses
.filter((item) => item.usage != "deploy")
.map((item) => (
<SelectItem key={item.id} value={item.id}>
<div className="flex items-center space-x-2">
<img
className="w-6"
src={
accessTypeMap.get(
item.configType
)?.[1]
}
/>
<div>{item.name}</div>
</div>
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="targetType"
render={({ field }) => (
<FormItem hidden={tab != "base"}>
<FormLabel>
{t("domain.management.edit.target.type")}
</FormLabel>
<FormControl>
<Select
{...field}
onValueChange={(value) => {
setTargetType(value);
form.setValue("targetType", value);
}}
>
<SelectTrigger>
<SelectValue
placeholder={t(
"domain.management.edit.target.type.not.empty.message"
)}
/>
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>
{t("domain.management.edit.target.type")}
</SelectLabel>
{targetTypeKeys.map((key) => (
<SelectItem key={key} value={key}>
<div className="flex items-center space-x-2">
<img
className="w-6"
src={targetTypeMap.get(key)?.[1]}
/>
<div>
{t(targetTypeMap.get(key)?.[0] || "")}
</div>
</div>
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="targetAccess"
render={({ field }) => (
<FormItem hidden={tab != "base"}>
<FormLabel className="w-full flex justify-between">
<div>{t("domain.management.edit.target.access")}</div>
<AccessEdit
trigger={
<div className="font-normal text-primary hover:underline cursor-pointer flex items-center">
<Plus size={14} />
{t("add")}
</div>
}
op="add"
/>
</FormLabel>
<FormControl>
<Select
{...field}
onValueChange={(value) => {
form.setValue("targetAccess", value);
}}
>
<SelectTrigger>
<SelectValue
placeholder={t(
"domain.management.edit.target.access.not.empty.message"
)}
/>
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>
{t(
"domain.management.edit.target.access.content.label"
)}{" "}
{form.getValues().targetAccess}
</SelectLabel>
<SelectItem value="emptyId">
<div className="flex items-center space-x-2">
--
</div>
</SelectItem>
{targetAccesses.map((item) => (
<SelectItem key={item.id} value={item.id}>
<div className="flex items-center space-x-2">
<img
className="w-6"
src={
accessTypeMap.get(item.configType)?.[1]
}
/>
<div>{item.name}</div>
</div>
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="group"
render={({ field }) => (
<FormItem hidden={tab != "advance" || targetType != "ssh"}>
<FormLabel className="w-full flex justify-between">
<div>{t("domain.management.edit.group.label")}</div>
</FormLabel>
<FormControl>
<Select
{...field}
value={field.value}
defaultValue="emptyId"
onValueChange={(value) => {
form.setValue("group", value);
}}
>
<SelectTrigger>
<SelectValue
placeholder={t(
"domain.management.edit.group.not.empty.message"
)}
/>
</SelectTrigger>
<SelectContent>
<SelectItem value="emptyId">
<div
className={cn(
"flex items-center space-x-2 rounded cursor-pointer"
)}
>
--
<FormMessage />
</FormItem>
)}
/>
{/* 邮箱 */}
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem>
<FormLabel className="flex w-full justify-between">
<div>
{t("email") +
t("domain.management.edit.email.description")}
</div>
<EmailsEdit
trigger={
<div className="font-normal text-primary hover:underline cursor-pointer flex items-center">
<Plus size={14} />
{t("add")}
</div>
</SelectItem>
{accessGroups
.filter((item) => {
return (
item.expand && item.expand?.access.length > 0
);
})
.map((item) => (
<SelectItem
value={item.id ? item.id : ""}
key={item.id}
>
<div
className={cn(
"flex items-center space-x-2 rounded cursor-pointer"
)}
>
{item.name}
</div>
</SelectItem>
))}
</SelectContent>
</Select>
</FormControl>
}
/>
</FormLabel>
<FormControl>
<Select
{...field}
value={field.value}
onValueChange={(value) => {
form.setValue("email", value);
}}
>
<SelectTrigger>
<SelectValue
placeholder={t(
"domain.management.edit.email.not.empty.message"
)}
/>
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>{t("email.list")}</SelectLabel>
{(emails.content as EmailsSetting).emails.map(
(item) => (
<SelectItem key={item} value={item}>
<div>{item}</div>
</SelectItem>
)
)}
</SelectGroup>
</SelectContent>
</Select>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="variables"
render={({ field }) => (
<FormItem hidden={tab != "advance"}>
<FormLabel>{t("variables")}</FormLabel>
<FormControl>
<Textarea
placeholder={t(
"domain.management.edit.variables.placeholder"
)}
{...field}
className="placeholder:whitespace-pre-wrap"
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
{/* 授权 */}
<FormField
control={form.control}
name="access"
render={({ field }) => (
<FormItem>
<FormLabel className="flex w-full justify-between">
<div>
{t("domain.management.edit.dns.access.label")}
</div>
<AccessEdit
trigger={
<div className="font-normal text-primary hover:underline cursor-pointer flex items-center">
<Plus size={14} />
{t("add")}
</div>
}
op="add"
/>
</FormLabel>
<FormControl>
<Select
{...field}
value={field.value}
onValueChange={(value) => {
form.setValue("access", value);
}}
>
<SelectTrigger>
<SelectValue
placeholder={t(
"domain.management.edit.access.not.empty.message"
)}
/>
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>
{t("domain.management.edit.access.label")}
</SelectLabel>
{accesses
.filter((item) => item.usage != "deploy")
.map((item) => (
<SelectItem key={item.id} value={item.id}>
<div className="flex items-center space-x-2">
<img
className="w-6"
src={
accessTypeMap.get(
item.configType
)?.[1]
}
/>
<div>{item.name}</div>
</div>
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="nameservers"
render={({ field }) => (
<FormItem hidden={tab != "advance"}>
<FormLabel>{t("dns")}</FormLabel>
<FormControl>
<Textarea
placeholder={t(
"domain.management.edit.dns.placeholder"
)}
{...field}
className="placeholder:whitespace-pre-wrap"
/>
</FormControl>
{/* 超时时间 */}
<FormField
control={form.control}
name="timeout"
render={({ field }) => (
<FormItem>
<FormLabel>{t("timeout")}</FormLabel>
<FormControl>
<Input
type="number"
placeholder={t(
"domain.management.edit.timeout.placeholder"
)}
{...field}
value={field.value}
onChange={(e) => {
form.setValue(
"timeout",
parseInt(e.target.value)
);
}}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormMessage />
</FormItem>
)}
/>
<div className="flex justify-end">
<Button type="submit">{t("save")}</Button>
{/* nameservers */}
<FormField
control={form.control}
name="nameservers"
render={({ field }) => (
<FormItem>
<StringList
value={field.value ?? ""}
onValueChange={(val: string) => {
form.setValue("nameservers", val);
}}
valueType="dns"
></StringList>
<FormMessage />
</FormItem>
)}
/>
<div className="flex justify-end">
<Button type="submit">
{domain?.id ? t("save") : t("next")}
</Button>
</div>
</form>
</Form>
</div>
<div
className={cn(
"flex flex-col space-y-5",
tab == "apply" && "hidden"
)}
>
<div className="flex justify-end py-2 border-b">
<Button size={"sm"} variant={"secondary"}>
</Button>
</div>
<div className="w-full md:w-[35em] rounded mt-5 border">
<div className="">
<div className="flex justify-between text-sm p-3 items-center text-stone-700">
<div>ALIYUN-CDN</div>
<div className="flex space-x-2">
<EditIcon size={16} />
<Trash2 size={16} />
</div>
</div>
</div>
</form>
</Form>
</div>
</div>
</div>
</div>
</div>

View File

@@ -96,6 +96,7 @@ const Home = () => {
const handelCheckedChange = async (id: string) => {
const checkedDomains = domains.filter((domain) => domain.id === id);
const isChecked = checkedDomains[0].enabled;
const data = checkedDomains[0];
data.enabled = !isChecked;