chore: remove unused code

This commit is contained in:
Fu Diwei 2024-12-17 19:10:32 +08:00
parent c27818b3b0
commit 0fa6d2980b
27 changed files with 11 additions and 4193 deletions

161
ui/package-lock.json generated
View File

@ -15,7 +15,6 @@
"@radix-ui/react-dialog": "^1.1.2", "@radix-ui/react-dialog": "^1.1.2",
"@radix-ui/react-dropdown-menu": "^2.1.1", "@radix-ui/react-dropdown-menu": "^2.1.1",
"@radix-ui/react-label": "^2.1.0", "@radix-ui/react-label": "^2.1.0",
"@radix-ui/react-popover": "^1.1.2",
"@radix-ui/react-radio-group": "^1.2.0", "@radix-ui/react-radio-group": "^1.2.0",
"@radix-ui/react-scroll-area": "^1.1.0", "@radix-ui/react-scroll-area": "^1.1.0",
"@radix-ui/react-select": "^2.1.1", "@radix-ui/react-select": "^2.1.1",
@ -2166,166 +2165,6 @@
} }
} }
}, },
"node_modules/@radix-ui/react-popover": {
"version": "1.1.2",
"resolved": "https://registry.npmmirror.com/@radix-ui/react-popover/-/react-popover-1.1.2.tgz",
"integrity": "sha512-u2HRUyWW+lOiA2g0Le0tMmT55FGOEWHwPFt1EPfbLly7uXQExFo5duNKqG2DzmFXIdqOeNd+TpE8baHWJCyP9w==",
"dependencies": {
"@radix-ui/primitive": "1.1.0",
"@radix-ui/react-compose-refs": "1.1.0",
"@radix-ui/react-context": "1.1.1",
"@radix-ui/react-dismissable-layer": "1.1.1",
"@radix-ui/react-focus-guards": "1.1.1",
"@radix-ui/react-focus-scope": "1.1.0",
"@radix-ui/react-id": "1.1.0",
"@radix-ui/react-popper": "1.2.0",
"@radix-ui/react-portal": "1.1.2",
"@radix-ui/react-presence": "1.1.1",
"@radix-ui/react-primitive": "2.0.0",
"@radix-ui/react-slot": "1.1.0",
"@radix-ui/react-use-controllable-state": "1.1.0",
"aria-hidden": "^1.1.1",
"react-remove-scroll": "2.6.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-context": {
"version": "1.1.1",
"resolved": "https://registry.npmmirror.com/@radix-ui/react-context/-/react-context-1.1.1.tgz",
"integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==",
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-dismissable-layer": {
"version": "1.1.1",
"resolved": "https://registry.npmmirror.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.1.tgz",
"integrity": "sha512-QSxg29lfr/xcev6kSz7MAlmDnzbP1eI/Dwn3Tp1ip0KT5CUELsxkekFEMVBEoykI3oV39hKT4TKZzBNMbcTZYQ==",
"dependencies": {
"@radix-ui/primitive": "1.1.0",
"@radix-ui/react-compose-refs": "1.1.0",
"@radix-ui/react-primitive": "2.0.0",
"@radix-ui/react-use-callback-ref": "1.1.0",
"@radix-ui/react-use-escape-keydown": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-focus-guards": {
"version": "1.1.1",
"resolved": "https://registry.npmmirror.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.1.tgz",
"integrity": "sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==",
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-portal": {
"version": "1.1.2",
"resolved": "https://registry.npmmirror.com/@radix-ui/react-portal/-/react-portal-1.1.2.tgz",
"integrity": "sha512-WeDYLGPxJb/5EGBoedyJbT0MpoULmwnIPMJMSldkuiMsBAv7N1cRdsTWZWht9vpPOiN3qyiGAtbK2is47/uMFg==",
"dependencies": {
"@radix-ui/react-primitive": "2.0.0",
"@radix-ui/react-use-layout-effect": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-presence": {
"version": "1.1.1",
"resolved": "https://registry.npmmirror.com/@radix-ui/react-presence/-/react-presence-1.1.1.tgz",
"integrity": "sha512-IeFXVi4YS1K0wVZzXNrbaaUvIJ3qdY+/Ih4eHFhWA9SwGR9UDX7Ck8abvL57C4cv3wwMvUE0OG69Qc3NCcTe/A==",
"dependencies": {
"@radix-ui/react-compose-refs": "1.1.0",
"@radix-ui/react-use-layout-effect": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-popover/node_modules/react-remove-scroll": {
"version": "2.6.0",
"resolved": "https://registry.npmmirror.com/react-remove-scroll/-/react-remove-scroll-2.6.0.tgz",
"integrity": "sha512-I2U4JVEsQenxDAKaVa3VZ/JeJZe0/2DxPWL8Tj8yLKctQJQiZM52pn/GWFpSp8dftjM3pSAHVJZscAnC/y+ySQ==",
"dependencies": {
"react-remove-scroll-bar": "^2.3.6",
"react-style-singleton": "^2.2.1",
"tslib": "^2.1.0",
"use-callback-ref": "^1.3.0",
"use-sidecar": "^1.1.2"
},
"engines": {
"node": ">=10"
},
"peerDependencies": {
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-popper": { "node_modules/@radix-ui/react-popper": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmmirror.com/@radix-ui/react-popper/-/react-popper-1.2.0.tgz", "resolved": "https://registry.npmmirror.com/@radix-ui/react-popper/-/react-popper-1.2.0.tgz",

View File

@ -17,7 +17,6 @@
"@radix-ui/react-dialog": "^1.1.2", "@radix-ui/react-dialog": "^1.1.2",
"@radix-ui/react-dropdown-menu": "^2.1.1", "@radix-ui/react-dropdown-menu": "^2.1.1",
"@radix-ui/react-label": "^2.1.0", "@radix-ui/react-label": "^2.1.0",
"@radix-ui/react-popover": "^1.1.2",
"@radix-ui/react-radio-group": "^1.2.0", "@radix-ui/react-radio-group": "^1.2.0",
"@radix-ui/react-scroll-area": "^1.1.0", "@radix-ui/react-scroll-area": "^1.1.0",
"@radix-ui/react-select": "^2.1.1", "@radix-ui/react-select": "^2.1.1",

View File

@ -1,197 +0,0 @@
import { useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import z from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { ClientResponseError } from "pocketbase";
import { Button } from "@/components/ui/button";
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { PbErrorData } from "@/domain/base";
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type AliyunAccessConfig } from "@/domain/access";
import { save } from "@/repository/access";
import { useAccessStore } from "@/stores/access";
type AccessAliyunFormProps = {
op: "add" | "edit" | "copy";
data?: AccessModel;
onAfterReq: () => void;
};
const AccessAliyunForm = ({ data, op, onAfterReq }: AccessAliyunFormProps) => {
const { t } = useTranslation();
const { createAccess, updateAccess } = useAccessStore();
const formSchema = z.object({
id: z.string().optional(),
name: z
.string()
.min(1, "access.form.name.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
configType: accessTypeFormSchema,
accessKeyId: z
.string()
.min(1, "access.form.access_key_id.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
accessSecretId: z
.string()
.min(1, "access.form.access_key_secret.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
});
let config: AliyunAccessConfig = {
accessKeyId: "",
accessKeySecret: "",
};
if (data) config = data.config as AliyunAccessConfig;
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
id: data?.id,
name: data?.name || "",
configType: "aliyun",
accessKeyId: config.accessKeyId,
accessSecretId: config.accessKeySecret,
},
});
const onSubmit = async (data: z.infer<typeof formSchema>) => {
const req: AccessModel = {
id: data.id as string,
name: data.name,
configType: data.configType,
usage: accessProvidersMap.get(data.configType)!.usage,
config: {
accessKeyId: data.accessKeyId,
accessKeySecret: data.accessSecretId,
},
};
try {
req.id = op == "copy" ? "" : req.id;
const rs = await save(req);
onAfterReq();
req.id = rs.id;
req.created = rs.created;
req.updated = rs.updated;
if (data.id && op == "edit") {
updateAccess(req);
return;
}
createAccess(req);
} catch (e) {
const err = e as ClientResponseError;
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
form.setError(key as keyof z.infer<typeof formSchema>, {
type: "manual",
message: value.message,
});
});
return;
}
};
return (
<>
<Form {...form}>
<form
onSubmit={(e) => {
e.stopPropagation();
form.handleSubmit(onSubmit)(e);
}}
className="space-y-8"
>
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.name.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.name.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="id"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="configType"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="accessKeyId"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.access_key_id.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.access_key_id.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="accessSecretId"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.access_key_secret.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.access_key_secret.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormMessage />
<div className="flex justify-end">
<Button type="submit">{t("common.button.save")}</Button>
</div>
</form>
</Form>
</>
);
};
export default AccessAliyunForm;

View File

@ -1,241 +0,0 @@
import { useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import z from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { ClientResponseError } from "pocketbase";
import { Input } from "@/components/ui/input";
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
import { Button } from "@/components/ui/button";
import { PbErrorData } from "@/domain/base";
import { AccessModel, accessProvidersMap, accessTypeFormSchema, type AWSAccessConfig } from "@/domain/access";
import { save } from "@/repository/access";
import { useAccessStore } from "@/stores/access";
type AccessAwsFormProps = {
op: "add" | "edit" | "copy";
data?: AccessModel;
onAfterReq: () => void;
};
const AccessAwsForm = ({ data, op, onAfterReq }: AccessAwsFormProps) => {
const { t } = useTranslation();
const { createAccess, updateAccess } = useAccessStore();
const formSchema = z.object({
id: z.string().optional(),
name: z
.string()
.min(1, "access.form.name.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
configType: accessTypeFormSchema,
region: z
.string()
.min(1, "access.form.region.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
accessKeyId: z
.string()
.min(1, "access.form.access_key_id.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
secretAccessKey: z
.string()
.min(1, "access.form.secret_access_key.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
hostedZoneId: z
.string()
.min(0, "access.form.aws_hosted_zone_id.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
});
let config: AWSAccessConfig = {
region: "cn-north-1",
accessKeyId: "",
secretAccessKey: "",
hostedZoneId: "",
};
if (data) config = data.config as AWSAccessConfig;
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
id: data?.id,
name: data?.name || "",
configType: "aws",
region: config.region,
accessKeyId: config.accessKeyId,
secretAccessKey: config.secretAccessKey,
hostedZoneId: config.hostedZoneId,
},
});
const onSubmit = async (data: z.infer<typeof formSchema>) => {
const req: AccessModel = {
id: data.id as string,
name: data.name,
configType: data.configType,
usage: accessProvidersMap.get(data.configType)!.usage,
config: {
region: data.region,
accessKeyId: data.accessKeyId,
secretAccessKey: data.secretAccessKey,
hostedZoneId: data.hostedZoneId,
},
};
try {
req.id = op == "copy" ? "" : req.id;
const rs = await save(req);
onAfterReq();
req.id = rs.id;
req.created = rs.created;
req.updated = rs.updated;
if (data.id && op == "edit") {
updateAccess(req);
return;
}
createAccess(req);
} catch (e) {
const err = e as ClientResponseError;
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
form.setError(key as keyof z.infer<typeof formSchema>, {
type: "manual",
message: value.message,
});
});
return;
}
};
return (
<>
<Form {...form}>
<form
onSubmit={(e) => {
e.stopPropagation();
form.handleSubmit(onSubmit)(e);
}}
className="space-y-8"
>
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.name.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.name.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="id"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="configType"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="region"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.region.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.region.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="accessKeyId"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.access_key_id.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.access_key_id.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="secretAccessKey"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.secret_access_key.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.secret_access_key.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="hostedZoneId"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.aws_hosted_zone_id.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.aws_hosted_zone_id.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormMessage />
<div className="flex justify-end">
<Button type="submit">{t("common.button.save")}</Button>
</div>
</form>
</Form>
</>
);
};
export default AccessAwsForm;

View File

@ -1,197 +0,0 @@
import { useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import z from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { ClientResponseError } from "pocketbase";
import { Input } from "@/components/ui/input";
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
import { Button } from "@/components/ui/button";
import { PbErrorData } from "@/domain/base";
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type BaiduCloudAccessConfig } from "@/domain/access";
import { save } from "@/repository/access";
import { useAccessStore } from "@/stores/access";
type AccessBaiduCloudFormProps = {
op: "add" | "edit" | "copy";
data?: AccessModel;
onAfterReq: () => void;
};
const AccessBaiduCloudForm = ({ data, op, onAfterReq }: AccessBaiduCloudFormProps) => {
const { t } = useTranslation();
const { createAccess, updateAccess } = useAccessStore();
const formSchema = z.object({
id: z.string().optional(),
name: z
.string()
.min(1, "access.form.name.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
configType: accessTypeFormSchema,
accessKeyId: z
.string()
.min(1, "access.form.access_key_id.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
secretAccessKey: z
.string()
.min(1, "access.form.secret_access_key.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
});
let config: BaiduCloudAccessConfig = {
accessKeyId: "",
secretAccessKey: "",
};
if (data) config = data.config as BaiduCloudAccessConfig;
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
id: data?.id,
name: data?.name || "",
configType: "baiducloud",
accessKeyId: config.accessKeyId,
secretAccessKey: config.secretAccessKey,
},
});
const onSubmit = async (data: z.infer<typeof formSchema>) => {
const req: AccessModel = {
id: data.id as string,
name: data.name,
configType: data.configType,
usage: accessProvidersMap.get(data.configType)!.usage,
config: {
accessKeyId: data.accessKeyId,
secretAccessKey: data.secretAccessKey,
},
};
try {
req.id = op == "copy" ? "" : req.id;
const rs = await save(req);
onAfterReq();
req.id = rs.id;
req.created = rs.created;
req.updated = rs.updated;
if (data.id && op == "edit") {
updateAccess(req);
return;
}
createAccess(req);
} catch (e) {
const err = e as ClientResponseError;
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
form.setError(key as keyof z.infer<typeof formSchema>, {
type: "manual",
message: value.message,
});
});
return;
}
};
return (
<>
<Form {...form}>
<form
onSubmit={(e) => {
e.stopPropagation();
form.handleSubmit(onSubmit)(e);
}}
className="space-y-8"
>
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.name.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.name.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="id"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="configType"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="accessKeyId"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.access_key_id.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.access_key_id.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="secretAccessKey"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.secret_access_key.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.secret_access_key.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormMessage />
<div className="flex justify-end">
<Button type="submit">{t("common.button.save")}</Button>
</div>
</form>
</Form>
</>
);
};
export default AccessBaiduCloudForm;

View File

@ -1,194 +0,0 @@
import { useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import z from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { ClientResponseError } from "pocketbase";
import { Input } from "@/components/ui/input";
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
import { Button } from "@/components/ui/button";
import { PbErrorData } from "@/domain/base";
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type BytePlusAccessConfig } from "@/domain/access";
import { save } from "@/repository/access";
import { useAccessStore } from "@/stores/access";
type AccessByteplusFormProps = {
op: "add" | "edit" | "copy";
data?: AccessModel;
onAfterReq: () => void;
};
const AccessByteplusForm = ({ data, op, onAfterReq }: AccessByteplusFormProps) => {
const { createAccess, updateAccess } = useAccessStore();
const { t } = useTranslation();
const formSchema = z.object({
id: z.string().optional(),
name: z
.string()
.min(1, "access.form.name.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
configType: accessTypeFormSchema,
accessKey: z
.string()
.min(1, "access.form.access_key.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
secretKey: z
.string()
.min(1, "access.form.secret_key.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
});
let config: BytePlusAccessConfig = {
accessKey: "",
secretKey: "",
};
if (data) config = data.config as BytePlusAccessConfig;
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
id: data?.id,
name: data?.name || "",
configType: "byteplus",
accessKey: config.accessKey,
secretKey: config.secretKey,
},
});
const onSubmit = async (data: z.infer<typeof formSchema>) => {
const req: AccessModel = {
id: data.id as string,
name: data.name,
configType: data.configType,
usage: accessProvidersMap.get(data.configType)!.usage,
config: {
accessKey: data.accessKey,
secretKey: data.secretKey,
},
};
try {
req.id = op == "copy" ? "" : req.id;
const rs = await save(req);
onAfterReq();
req.id = rs.id;
req.created = rs.created;
req.updated = rs.updated;
if (data.id && op == "edit") {
updateAccess(req);
return;
}
createAccess(req);
} catch (e) {
const err = e as ClientResponseError;
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
form.setError(key as keyof z.infer<typeof formSchema>, {
type: "manual",
message: value.message,
});
});
return;
}
};
return (
<>
<Form {...form}>
<form
onSubmit={(e) => {
e.stopPropagation();
form.handleSubmit(onSubmit)(e);
}}
className="space-y-8"
>
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.name.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.name.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="id"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="configType"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="accessKey"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.access_key.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.access_key.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="secretKey"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.secret_key.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.secret_key.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormMessage />
<div className="flex justify-end">
<Button type="submit">{t("common.button.save")}</Button>
</div>
</form>
</Form>
</>
);
};
export default AccessByteplusForm;

View File

@ -1,168 +0,0 @@
import { useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import z from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { ClientResponseError } from "pocketbase";
import { Button } from "@/components/ui/button";
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { PbErrorData } from "@/domain/base";
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type CloudflareAccessConfig } from "@/domain/access";
import { save } from "@/repository/access";
import { useAccessStore } from "@/stores/access";
type AccessCloudflareFormProps = {
op: "add" | "edit" | "copy";
data?: AccessModel;
onAfterReq: () => void;
};
const AccessCloudflareForm = ({ data, op, onAfterReq }: AccessCloudflareFormProps) => {
const { createAccess, updateAccess } = useAccessStore();
const { t } = useTranslation();
const formSchema = z.object({
id: z.string().optional(),
name: z
.string()
.min(1, "access.form.name.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
configType: accessTypeFormSchema,
dnsApiToken: z
.string()
.min(1, "access.form.cloud_dns_api_token.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
});
let config: CloudflareAccessConfig = {
dnsApiToken: "",
};
if (data) config = data.config as CloudflareAccessConfig;
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
id: data?.id,
name: data?.name || "",
configType: "cloudflare",
dnsApiToken: config.dnsApiToken,
},
});
const onSubmit = async (data: z.infer<typeof formSchema>) => {
const req: AccessModel = {
id: data.id as string,
name: data.name,
configType: data.configType,
usage: accessProvidersMap.get(data.configType)!.usage,
config: {
dnsApiToken: data.dnsApiToken,
},
};
try {
req.id = op == "copy" ? "" : req.id;
const rs = await save(req);
onAfterReq();
req.id = rs.id;
req.created = rs.created;
req.updated = rs.updated;
if (data.id && op == "edit") {
updateAccess(req);
return;
}
createAccess(req);
} catch (e) {
const err = e as ClientResponseError;
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
form.setError(key as keyof z.infer<typeof formSchema>, {
type: "manual",
message: value.message,
});
});
}
};
return (
<>
<Form {...form}>
<form
onSubmit={(e) => {
e.stopPropagation();
form.handleSubmit(onSubmit)(e);
}}
className="space-y-8"
>
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.name.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.name.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="id"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="configType"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="dnsApiToken"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.cloud_dns_api_token.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.cloud_dns_api_token.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<div className="flex justify-end">
<Button type="submit">{t("common.button.save")}</Button>
</div>
</form>
</Form>
</>
);
};
export default AccessCloudflareForm;

View File

@ -1,188 +0,0 @@
import { useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import z from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { ClientResponseError } from "pocketbase";
import { Button } from "@/components/ui/button";
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { PbErrorData } from "@/domain/base";
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type DogeCloudAccessConfig } from "@/domain/access";
import { save } from "@/repository/access";
import { useAccessStore } from "@/stores/access";
type AccessDogeCloudFormProps = {
op: "add" | "edit" | "copy";
data?: AccessModel;
onAfterReq: () => void;
};
const AccessDogeCloudForm = ({ data, op, onAfterReq }: AccessDogeCloudFormProps) => {
const { createAccess, updateAccess } = useAccessStore();
const { t } = useTranslation();
const formSchema = z.object({
id: z.string().optional(),
name: z
.string()
.min(1, "access.form.name.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
configType: accessTypeFormSchema,
accessKey: z.string().min(1, "access.form.access_key.placeholder").max(64),
secretKey: z.string().min(1, "access.form.secret_key.placeholder").max(64),
});
let config: DogeCloudAccessConfig = {
accessKey: "",
secretKey: "",
};
if (data) config = data.config as DogeCloudAccessConfig;
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
id: data?.id,
name: data?.name || "",
configType: "dogecloud",
accessKey: config.accessKey,
secretKey: config.secretKey,
},
});
const onSubmit = async (data: z.infer<typeof formSchema>) => {
const req: AccessModel = {
id: data.id as string,
name: data.name,
configType: data.configType,
usage: accessProvidersMap.get(data.configType)!.usage,
config: {
accessKey: data.accessKey,
secretKey: data.secretKey,
},
};
try {
req.id = op == "copy" ? "" : req.id;
const rs = await save(req);
onAfterReq();
req.id = rs.id;
req.created = rs.created;
req.updated = rs.updated;
if (data.id && op == "edit") {
updateAccess(req);
return;
}
createAccess(req);
} catch (e) {
const err = e as ClientResponseError;
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
form.setError(key as keyof z.infer<typeof formSchema>, {
type: "manual",
message: value.message,
});
});
return;
}
};
return (
<>
<Form {...form}>
<form
onSubmit={(e) => {
e.stopPropagation();
form.handleSubmit(onSubmit)(e);
}}
className="space-y-8"
>
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.name.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.name.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="id"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="configType"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="accessKey"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.access_key.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.access_key.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="secretKey"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.secret_key.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.secret_key.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormMessage />
<div className="flex justify-end">
<Button type="submit">{t("common.button.save")}</Button>
</div>
</form>
</Form>
</>
);
};
export default AccessDogeCloudForm;

View File

@ -1,306 +0,0 @@
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { cn } from "@/components/ui/utils";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog";
import { Label } from "@/components/ui/label";
import { ScrollArea } from "@/components/ui/scroll-area";
import AccessTypeSelect from "@/components/access/AccessTypeSelect";
import AccessAliyunForm from "./AccessAliyunForm";
import AccessTencentForm from "./AccessTencentForm";
import AccessHuaweiCloudForm from "./AccessHuaweicloudForm";
import AccessBaiduCloudForm from "./AccessBaiduCloudForm";
import AccessQiniuForm from "./AccessQiniuForm";
import AccessDogeCloudForm from "./AccessDogeCloudForm";
import AccessAwsForm from "./AccessAwsForm";
import AccessCloudflareForm from "./AccessCloudflareForm";
import AccessNamesiloForm from "./AccessNamesiloForm";
import AccessGodaddyForm from "./AccessGodaddyForm";
import AccessPdnsForm from "./AccessPdnsForm";
import AccessHttpreqForm from "./AccessHttpreqForm";
import AccessLocalForm from "./AccessLocalForm";
import AccessSSHForm from "./AccessSSHForm";
import AccessWebhookForm from "./AccessWebhookForm";
import AccessKubernetesForm from "./AccessKubernetesForm";
import AccessVolcengineForm from "./AccessVolcengineForm";
import AccessByteplusForm from "./AccessByteplusForm";
import { AccessModel } from "@/domain/access";
type AccessEditProps = {
op: "add" | "edit" | "copy";
className?: string;
trigger: React.ReactNode;
data?: AccessModel;
outConfigType?: string;
};
const AccessEditDialog = ({ trigger, op, data, className, outConfigType }: AccessEditProps) => {
const { t } = useTranslation();
const [open, setOpen] = useState(false);
const [configType, setConfigType] = useState(data?.configType || "");
useEffect(() => {
if (outConfigType) {
setConfigType(outConfigType);
}
}, [outConfigType]);
let childComponent = <> </>;
switch (configType) {
case "aliyun":
childComponent = (
<AccessAliyunForm
data={data}
op={op}
onAfterReq={() => {
setOpen(false);
}}
/>
);
break;
case "tencentcloud":
childComponent = (
<AccessTencentForm
data={data}
op={op}
onAfterReq={() => {
setOpen(false);
}}
/>
);
break;
case "huaweicloud":
childComponent = (
<AccessHuaweiCloudForm
data={data}
op={op}
onAfterReq={() => {
setOpen(false);
}}
/>
);
break;
case "baiducloud":
childComponent = (
<AccessBaiduCloudForm
data={data}
op={op}
onAfterReq={() => {
setOpen(false);
}}
/>
);
break;
case "qiniu":
childComponent = (
<AccessQiniuForm
data={data}
op={op}
onAfterReq={() => {
setOpen(false);
}}
/>
);
break;
case "dogecloud":
childComponent = (
<AccessDogeCloudForm
data={data}
op={op}
onAfterReq={() => {
setOpen(false);
}}
/>
);
break;
case "aws":
childComponent = (
<AccessAwsForm
data={data}
op={op}
onAfterReq={() => {
setOpen(false);
}}
/>
);
break;
case "cloudflare":
childComponent = (
<AccessCloudflareForm
data={data}
op={op}
onAfterReq={() => {
setOpen(false);
}}
/>
);
break;
case "namesilo":
childComponent = (
<AccessNamesiloForm
data={data}
op={op}
onAfterReq={() => {
setOpen(false);
}}
/>
);
break;
case "godaddy":
childComponent = (
<AccessGodaddyForm
data={data}
op={op}
onAfterReq={() => {
setOpen(false);
}}
/>
);
break;
case "powerdns":
childComponent = (
<AccessPdnsForm
data={data}
op={op}
onAfterReq={() => {
setOpen(false);
}}
/>
);
break;
case "acmehttpreq":
childComponent = (
<AccessHttpreqForm
data={data}
op={op}
onAfterReq={() => {
setOpen(false);
}}
/>
);
break;
case "local":
childComponent = (
<AccessLocalForm
data={data}
op={op}
onAfterReq={() => {
setOpen(false);
}}
/>
);
break;
case "ssh":
childComponent = (
<AccessSSHForm
data={data}
op={op}
onAfterReq={() => {
setOpen(false);
}}
/>
);
break;
case "webhook":
childComponent = (
<AccessWebhookForm
data={data}
op={op}
onAfterReq={() => {
setOpen(false);
}}
/>
);
break;
case "k8s":
childComponent = (
<AccessKubernetesForm
data={data}
op={op}
onAfterReq={() => {
setOpen(false);
}}
/>
);
break;
case "volcengine":
childComponent = (
<AccessVolcengineForm
data={data}
op={op}
onAfterReq={() => {
setOpen(false);
}}
/>
);
break;
case "byteplus":
childComponent = (
<AccessByteplusForm
data={data}
op={op}
onAfterReq={() => {
setOpen(false);
}}
/>
);
break;
}
return (
<Dialog
onOpenChange={(openState) => {
if (openState) {
document.body.style.pointerEvents = "auto";
}
setOpen(openState);
}}
open={open}
modal={false}
>
<DialogTrigger asChild className={cn(className)}>
{trigger}
</DialogTrigger>
<DialogContent
className="sm:max-w-[600px] w-full dark:text-stone-200"
onInteractOutside={(event) => {
event.preventDefault();
}}
>
<DialogHeader>
<DialogTitle>
{
{
["add"]: t("access.action.add"),
["edit"]: t("access.action.edit"),
["copy"]: t("access.action.copy"),
}[op]
}
</DialogTitle>
</DialogHeader>
<ScrollArea className="max-h-[80vh]">
<div className="container py-3">
<div>
<Label>{t("access.form.type.label")}</Label>
<AccessTypeSelect
className="w-full mt-3"
placeholder={t("access.form.type.placeholder")}
value={configType}
showSearch={true}
onChange={(val) => {
setConfigType(val);
}}
/>
</div>
<div className="mt-8">{childComponent}</div>
</div>
</ScrollArea>
</DialogContent>
</Dialog>
);
};
export default AccessEditDialog;

View File

@ -1,190 +0,0 @@
import { useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import z from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { ClientResponseError } from "pocketbase";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
import { PbErrorData } from "@/domain/base";
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type GoDaddyAccessConfig } from "@/domain/access";
import { save } from "@/repository/access";
import { useAccessStore } from "@/stores/access";
type AccessGodaddyFormProps = {
op: "add" | "edit" | "copy";
data?: AccessModel;
onAfterReq: () => void;
};
const AccessGodaddyForm = ({ data, op, onAfterReq }: AccessGodaddyFormProps) => {
const { createAccess, updateAccess } = useAccessStore();
const { t } = useTranslation();
const formSchema = z.object({
id: z.string().optional(),
name: z
.string()
.min(1, "access.form.name.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
configType: accessTypeFormSchema,
apiKey: z
.string()
.min(1, "access.form.godaddy_api_key.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
apiSecret: z
.string()
.min(1, "access.form.godaddy_api_secret.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
});
let config: GoDaddyAccessConfig = {
apiKey: "",
apiSecret: "",
};
if (data) config = data.config as GoDaddyAccessConfig;
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
id: data?.id,
name: data?.name || "",
configType: "godaddy",
apiKey: config.apiKey,
apiSecret: config.apiSecret,
},
});
const onSubmit = async (data: z.infer<typeof formSchema>) => {
const req: AccessModel = {
id: data.id as string,
name: data.name,
configType: data.configType,
usage: accessProvidersMap.get(data.configType)!.usage,
config: {
apiKey: data.apiKey,
apiSecret: data.apiSecret,
},
};
try {
req.id = op == "copy" ? "" : req.id;
const rs = await save(req);
onAfterReq();
req.id = rs.id;
req.created = rs.created;
req.updated = rs.updated;
if (data.id && op == "edit") {
updateAccess(req);
return;
}
createAccess(req);
} catch (e) {
const err = e as ClientResponseError;
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
form.setError(key as keyof z.infer<typeof formSchema>, {
type: "manual",
message: value.message,
});
});
}
};
return (
<>
<Form {...form}>
<form
onSubmit={(e) => {
e.stopPropagation();
form.handleSubmit(onSubmit)(e);
}}
className="space-y-8"
>
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.name.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.name.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="id"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="configType"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="apiKey"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.godaddy_api_key.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.godaddy_api_key.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="apiSecret"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.godaddy_api_secret.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.godaddy_api_secret.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<div className="flex justify-end">
<Button type="submit">{t("common.button.save")}</Button>
</div>
</form>
</Form>
</>
);
};
export default AccessGodaddyForm;

View File

@ -1,233 +0,0 @@
import { useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import z from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { ClientResponseError } from "pocketbase";
import { Button } from "@/components/ui/button";
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { PbErrorData } from "@/domain/base";
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type ACMEHttpReqAccessConfig } from "@/domain/access";
import { save } from "@/repository/access";
import { useAccessStore } from "@/stores/access";
type AccessHttpreqFormProps = {
op: "add" | "edit" | "copy";
data?: AccessModel;
onAfterReq: () => void;
};
const AccessHttpreqForm = ({ data, op, onAfterReq }: AccessHttpreqFormProps) => {
const { createAccess, updateAccess } = useAccessStore();
const { t } = useTranslation();
const formSchema = z.object({
id: z.string().optional(),
name: z
.string()
.min(1, "access.form.name.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
configType: accessTypeFormSchema,
endpoint: z.string().url("common.errmsg.url_invalid"),
mode: z.enum(["RAW", ""]),
username: z
.string()
.min(1, "access.form.access_key_secret.placeholder")
.max(128, t("common.errmsg.string_max", { max: 128 })),
password: z
.string()
.min(1, "access.form.access_key_secret.placeholder")
.max(128, t("common.errmsg.string_max", { max: 128 })),
});
let config: ACMEHttpReqAccessConfig = {
endpoint: "",
mode: "",
username: "",
password: "",
};
if (data) config = data.config as ACMEHttpReqAccessConfig;
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
id: data?.id,
name: data?.name || "",
configType: "acmehttpreq",
endpoint: config.endpoint,
mode: config.mode === "RAW" ? "RAW" : "",
username: config.username,
password: config.password,
},
});
const onSubmit = async (data: z.infer<typeof formSchema>) => {
const req: AccessModel = {
id: data.id as string,
name: data.name,
configType: data.configType,
usage: accessProvidersMap.get(data.configType)!.usage,
config: {
endpoint: data.endpoint,
mode: data.mode,
username: data.username,
password: data.password,
},
};
try {
req.id = op == "copy" ? "" : req.id;
const rs = await save(req);
onAfterReq();
req.id = rs.id;
req.created = rs.created;
req.updated = rs.updated;
if (data.id && op == "edit") {
updateAccess(req);
return;
}
createAccess(req);
} catch (e) {
const err = e as ClientResponseError;
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
form.setError(key as keyof z.infer<typeof formSchema>, {
type: "manual",
message: value.message,
});
});
return;
}
};
return (
<>
<Form {...form}>
<form
onSubmit={(e) => {
e.stopPropagation();
form.handleSubmit(onSubmit)(e);
}}
className="space-y-8"
>
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.name.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.name.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="id"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="configType"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="endpoint"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.httpreq_endpoint.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.httpreq_endpoint.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="mode"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.httpreq_mode.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.httpreq_mode.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="username"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.username.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.username.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="password"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.password.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.password.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormMessage />
<div className="flex justify-end">
<Button type="submit">{t("common.button.save")}</Button>
</div>
</form>
</Form>
</>
);
};
export default AccessHttpreqForm;

View File

@ -1,216 +0,0 @@
import { useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import z from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { ClientResponseError } from "pocketbase";
import { Input } from "@/components/ui/input";
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
import { Button } from "@/components/ui/button";
import { PbErrorData } from "@/domain/base";
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type HuaweiCloudAccessConfig } from "@/domain/access";
import { save } from "@/repository/access";
import { useAccessStore } from "@/stores/access";
type AccessHuaweiCloudFormProps = {
op: "add" | "edit" | "copy";
data?: AccessModel;
onAfterReq: () => void;
};
const AccessHuaweiCloudForm = ({ data, op, onAfterReq }: AccessHuaweiCloudFormProps) => {
const { createAccess, updateAccess } = useAccessStore();
const { t } = useTranslation();
const formSchema = z.object({
id: z.string().optional(),
name: z
.string()
.min(1, "access.form.name.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
configType: accessTypeFormSchema,
region: z
.string()
.min(1, "access.form.region.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
accessKeyId: z
.string()
.min(1, "access.form.access_key_id.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
secretAccessKey: z
.string()
.min(1, "access.form.secret_access_key.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
});
let config: HuaweiCloudAccessConfig = {
region: "cn-north-1",
accessKeyId: "",
secretAccessKey: "",
};
if (data) config = data.config as HuaweiCloudAccessConfig;
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
id: data?.id,
name: data?.name || "",
configType: "huaweicloud",
region: config.region,
accessKeyId: config.accessKeyId,
secretAccessKey: config.secretAccessKey,
},
});
const onSubmit = async (data: z.infer<typeof formSchema>) => {
const req: AccessModel = {
id: data.id as string,
name: data.name,
configType: data.configType,
usage: accessProvidersMap.get(data.configType)!.usage,
config: {
region: data.region,
accessKeyId: data.accessKeyId,
secretAccessKey: data.secretAccessKey,
},
};
try {
req.id = op == "copy" ? "" : req.id;
const rs = await save(req);
onAfterReq();
req.id = rs.id;
req.created = rs.created;
req.updated = rs.updated;
if (data.id && op == "edit") {
updateAccess(req);
return;
}
createAccess(req);
} catch (e) {
const err = e as ClientResponseError;
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
form.setError(key as keyof z.infer<typeof formSchema>, {
type: "manual",
message: value.message,
});
});
return;
}
};
return (
<>
<Form {...form}>
<form
onSubmit={(e) => {
e.stopPropagation();
form.handleSubmit(onSubmit)(e);
}}
className="space-y-8"
>
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.name.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.name.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="id"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="configType"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="region"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.region.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.region.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="accessKeyId"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.access_key_id.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.access_key_id.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="secretAccessKey"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.secret_access_key.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.secret_access_key.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormMessage />
<div className="flex justify-end">
<Button type="submit">{t("common.button.save")}</Button>
</div>
</form>
</Form>
</>
);
};
export default AccessHuaweiCloudForm;

View File

@ -1,193 +0,0 @@
import { useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { ClientResponseError } from "pocketbase";
import { Button } from "@/components/ui/button";
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { readFileContent } from "@/utils/file";
import { PbErrorData } from "@/domain/base";
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type KubernetesAccessConfig } from "@/domain/access";
import { save } from "@/repository/access";
import { useAccessStore } from "@/stores/access";
type AccessKubernetesFormProps = {
op: "add" | "edit" | "copy";
data?: AccessModel;
onAfterReq: () => void;
};
const AccessKubernetesForm = ({ data, op, onAfterReq }: AccessKubernetesFormProps) => {
const { createAccess, updateAccess } = useAccessStore();
const fileInputRef = useRef<HTMLInputElement | null>(null);
const [fileName, setFileName] = useState("");
const { t } = useTranslation();
const formSchema = z.object({
id: z.string().optional(),
name: z
.string()
.min(1, "access.form.name.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
configType: accessTypeFormSchema,
kubeConfig: z
.string()
.min(0, "access.form.k8s_kubeconfig.placeholder")
.max(20480, t("common.errmsg.string_max", { max: 20480 })),
kubeConfigFile: z.any().optional(),
});
let config: KubernetesAccessConfig & { kubeConfigFile?: string } = {
kubeConfig: "",
kubeConfigFile: "",
};
if (data) config = data.config as typeof config;
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
id: data?.id,
name: data?.name || "",
configType: "k8s",
kubeConfig: config.kubeConfig,
kubeConfigFile: config.kubeConfigFile,
},
});
const onSubmit = async (data: z.infer<typeof formSchema>) => {
const req: AccessModel = {
id: data.id as string,
name: data.name,
configType: data.configType,
usage: accessProvidersMap.get(data.configType)!.usage,
config: {
kubeConfig: data.kubeConfig,
},
};
try {
req.id = op == "copy" ? "" : req.id;
const rs = await save(req);
onAfterReq();
req.id = rs.id;
req.created = rs.created;
req.updated = rs.updated;
if (data.id && op == "edit") {
updateAccess(req);
} else {
createAccess(req);
}
} catch (e) {
const err = e as ClientResponseError;
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
form.setError(key as keyof z.infer<typeof formSchema>, {
type: "manual",
message: value.message,
});
});
return;
}
};
const handleFileChange = async (event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0];
if (!file) return;
const savedFile = file;
setFileName(savedFile.name);
const content = await readFileContent(savedFile);
form.setValue("kubeConfig", content);
};
const handleSelectFileClick = () => {
fileInputRef.current?.click();
};
return (
<>
<Form {...form}>
<form
onSubmit={(e) => {
e.stopPropagation();
form.handleSubmit(onSubmit)(e);
}}
className="space-y-8"
>
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.name.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.name.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="kubeConfig"
render={({ field }) => (
<FormItem hidden>
<FormLabel>{t("access.form.k8s_kubeconfig.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.k8s_kubeconfig.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="kubeConfigFile"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.k8s_kubeconfig.label")}</FormLabel>
<FormControl>
<div>
<Button type={"button"} variant={"secondary"} size={"sm"} className="w-48" onClick={handleSelectFileClick}>
{fileName ? fileName : t("access.form.k8s_kubeconfig_file.placeholder")}
</Button>
<Input
placeholder={t("access.form.k8s_kubeconfig.placeholder")}
{...field}
ref={fileInputRef}
className="hidden"
hidden
type="file"
onChange={handleFileChange}
/>
</div>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormMessage />
<div className="flex justify-end">
<Button type="submit">{t("common.button.save")}</Button>
</div>
</form>
</Form>
</>
);
};
export default AccessKubernetesForm;

View File

@ -1,147 +0,0 @@
import { useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { ClientResponseError } from "pocketbase";
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { PbErrorData } from "@/domain/base";
import { accessProvidersMap, accessTypeFormSchema, type AccessModel } from "@/domain/access";
import { save } from "@/repository/access";
import { useAccessStore } from "@/stores/access";
type AccessLocalFormProps = {
op: "add" | "edit" | "copy";
data?: AccessModel;
onAfterReq: () => void;
};
const AccessLocalForm = ({ data, op, onAfterReq }: AccessLocalFormProps) => {
const { createAccess, updateAccess } = useAccessStore();
const { t } = useTranslation();
const formSchema = z.object({
id: z.string().optional(),
name: z
.string()
.min(1, "access.form.name.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
configType: accessTypeFormSchema,
});
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
id: data?.id,
name: data?.name || "",
configType: "local",
},
});
const onSubmit = async (data: z.infer<typeof formSchema>) => {
const req: AccessModel = {
id: data.id as string,
name: data.name,
configType: data.configType,
usage: accessProvidersMap.get(data.configType)!.usage,
config: {},
};
try {
req.id = op == "copy" ? "" : req.id;
const rs = await save(req);
onAfterReq();
req.id = rs.id;
req.created = rs.created;
req.updated = rs.updated;
if (data.id && op == "edit") {
updateAccess(req);
} else {
createAccess(req);
}
} catch (e) {
const err = e as ClientResponseError;
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
form.setError(key as keyof z.infer<typeof formSchema>, {
type: "manual",
message: value.message,
});
});
return;
}
};
return (
<>
<Form {...form}>
<form
onSubmit={(e) => {
e.stopPropagation();
form.handleSubmit(onSubmit)(e);
}}
className="space-y-8"
>
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.name.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.name.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="id"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="configType"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormMessage />
<div className="flex justify-end">
<Button type="submit">{t("common.button.save")}</Button>
</div>
</form>
</Form>
</>
);
};
export default AccessLocalForm;

View File

@ -1,168 +0,0 @@
import { useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import z from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { ClientResponseError } from "pocketbase";
import { Button } from "@/components/ui/button";
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { PbErrorData } from "@/domain/base";
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type NameSiloAccessConfig } from "@/domain/access";
import { save } from "@/repository/access";
import { useAccessStore } from "@/stores/access";
type AccessNameSiloFormProps = {
op: "add" | "edit" | "copy";
data?: AccessModel;
onAfterReq: () => void;
};
const AccessNameSiloForm = ({ data, op, onAfterReq }: AccessNameSiloFormProps) => {
const { createAccess, updateAccess } = useAccessStore();
const { t } = useTranslation();
const formSchema = z.object({
id: z.string().optional(),
name: z
.string()
.min(1, "access.form.name.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
configType: accessTypeFormSchema,
apiKey: z
.string()
.min(1, "access.form.namesilo_api_key.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
});
let config: NameSiloAccessConfig = {
apiKey: "",
};
if (data) config = data.config as NameSiloAccessConfig;
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
id: data?.id,
name: data?.name || "",
configType: "namesilo",
apiKey: config.apiKey,
},
});
const onSubmit = async (data: z.infer<typeof formSchema>) => {
const req: AccessModel = {
id: data.id as string,
name: data.name,
configType: data.configType,
usage: accessProvidersMap.get(data.configType)!.usage,
config: {
apiKey: data.apiKey,
},
};
try {
req.id = op == "copy" ? "" : req.id;
const rs = await save(req);
onAfterReq();
req.id = rs.id;
req.created = rs.created;
req.updated = rs.updated;
if (data.id && op == "edit") {
updateAccess(req);
return;
}
createAccess(req);
} catch (e) {
const err = e as ClientResponseError;
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
form.setError(key as keyof z.infer<typeof formSchema>, {
type: "manual",
message: value.message,
});
});
}
};
return (
<>
<Form {...form}>
<form
onSubmit={(e) => {
e.stopPropagation();
form.handleSubmit(onSubmit)(e);
}}
className="space-y-8"
>
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.name.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.name.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="id"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="configType"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="apiKey"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.namesilo_api_key.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.namesilo_api_key.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<div className="flex justify-end">
<Button type="submit">{t("common.button.save")}</Button>
</div>
</form>
</Form>
</>
);
};
export default AccessNameSiloForm;

View File

@ -1,192 +0,0 @@
import { useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import z from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { ClientResponseError } from "pocketbase";
import { Button } from "@/components/ui/button";
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { PbErrorData } from "@/domain/base";
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type PowerDNSAccessConfig } from "@/domain/access";
import { save } from "@/repository/access";
import { useAccessStore } from "@/stores/access";
type AccessPdnsFormProps = {
op: "add" | "edit" | "copy";
data?: AccessModel;
onAfterReq: () => void;
};
const AccessPdnsForm = ({ data, op, onAfterReq }: AccessPdnsFormProps) => {
const { createAccess, updateAccess } = useAccessStore();
const { t } = useTranslation();
const formSchema = z.object({
id: z.string().optional(),
name: z
.string()
.min(1, "access.form.name.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
configType: accessTypeFormSchema,
apiUrl: z.string().url("common.errmsg.url_invalid"),
apiKey: z
.string()
.min(1, "access.form.access_key_secret.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
});
let config: PowerDNSAccessConfig = {
apiUrl: "",
apiKey: "",
};
if (data) config = data.config as PowerDNSAccessConfig;
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
id: data?.id,
name: data?.name || "",
configType: "powerdns",
apiUrl: config.apiUrl,
apiKey: config.apiKey,
},
});
const onSubmit = async (data: z.infer<typeof formSchema>) => {
const req: AccessModel = {
id: data.id as string,
name: data.name,
configType: data.configType,
usage: accessProvidersMap.get(data.configType)!.usage,
config: {
apiUrl: data.apiUrl,
apiKey: data.apiKey,
},
};
try {
req.id = op == "copy" ? "" : req.id;
const rs = await save(req);
onAfterReq();
req.id = rs.id;
req.created = rs.created;
req.updated = rs.updated;
if (data.id && op == "edit") {
updateAccess(req);
return;
}
createAccess(req);
} catch (e) {
const err = e as ClientResponseError;
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
form.setError(key as keyof z.infer<typeof formSchema>, {
type: "manual",
message: value.message,
});
});
return;
}
};
return (
<>
<Form {...form}>
<form
onSubmit={(e) => {
e.stopPropagation();
form.handleSubmit(onSubmit)(e);
}}
className="space-y-8"
>
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.name.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.name.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="id"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="configType"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="apiUrl"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.pdns_api_url.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.pdns_api_url.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="apiKey"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.pdns_api_key.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.pdns_api_key.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormMessage />
<div className="flex justify-end">
<Button type="submit">{t("common.button.save")}</Button>
</div>
</form>
</Form>
</>
);
};
export default AccessPdnsForm;

View File

@ -1,188 +0,0 @@
import { useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import z from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { ClientResponseError } from "pocketbase";
import { Button } from "@/components/ui/button";
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { PbErrorData } from "@/domain/base";
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type QiniuAccessConfig } from "@/domain/access";
import { save } from "@/repository/access";
import { useAccessStore } from "@/stores/access";
type AccessQiniuFormProps = {
op: "add" | "edit" | "copy";
data?: AccessModel;
onAfterReq: () => void;
};
const AccessQiniuForm = ({ data, op, onAfterReq }: AccessQiniuFormProps) => {
const { createAccess, updateAccess } = useAccessStore();
const { t } = useTranslation();
const formSchema = z.object({
id: z.string().optional(),
name: z
.string()
.min(1, "access.form.name.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
configType: accessTypeFormSchema,
accessKey: z.string().min(1, "access.form.access_key.placeholder").max(64),
secretKey: z.string().min(1, "access.form.secret_key.placeholder").max(64),
});
let config: QiniuAccessConfig = {
accessKey: "",
secretKey: "",
};
if (data) config = data.config as QiniuAccessConfig;
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
id: data?.id,
name: data?.name || "",
configType: "qiniu",
accessKey: config.accessKey,
secretKey: config.secretKey,
},
});
const onSubmit = async (data: z.infer<typeof formSchema>) => {
const req: AccessModel = {
id: data.id as string,
name: data.name,
configType: data.configType,
usage: accessProvidersMap.get(data.configType)!.usage,
config: {
accessKey: data.accessKey,
secretKey: data.secretKey,
},
};
try {
req.id = op == "copy" ? "" : req.id;
const rs = await save(req);
onAfterReq();
req.id = rs.id;
req.created = rs.created;
req.updated = rs.updated;
if (data.id && op == "edit") {
updateAccess(req);
return;
}
createAccess(req);
} catch (e) {
const err = e as ClientResponseError;
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
form.setError(key as keyof z.infer<typeof formSchema>, {
type: "manual",
message: value.message,
});
});
return;
}
};
return (
<>
<Form {...form}>
<form
onSubmit={(e) => {
e.stopPropagation();
form.handleSubmit(onSubmit)(e);
}}
className="space-y-8"
>
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.name.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.name.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="id"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="configType"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="accessKey"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.access_key.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.access_key.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="secretKey"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.secret_key.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.secret_key.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormMessage />
<div className="flex justify-end">
<Button type="submit">{t("common.button.save")}</Button>
</div>
</form>
</Form>
</>
);
};
export default AccessQiniuForm;

View File

@ -1,348 +0,0 @@
import { useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { ClientResponseError } from "pocketbase";
import { Button } from "@/components/ui/button";
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { readFileContent } from "@/utils/file";
import { PbErrorData } from "@/domain/base";
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type SSHAccessConfig } from "@/domain/access";
import { save } from "@/repository/access";
import { useAccessStore } from "@/stores/access";
type AccessSSHFormProps = {
op: "add" | "edit" | "copy";
data?: AccessModel;
onAfterReq: () => void;
};
const AccessSSHForm = ({ data, op, onAfterReq }: AccessSSHFormProps) => {
const { createAccess, updateAccess } = useAccessStore();
const fileInputRef = useRef<HTMLInputElement | null>(null);
const [fileName, setFileName] = useState("");
const { t } = useTranslation();
const domainReg = /^(?:\*\.)?([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}$/;
const ipReg =
/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
const formSchema = z.object({
id: z.string().optional(),
name: z
.string()
.min(1, "access.form.name.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
configType: accessTypeFormSchema,
host: z.string().refine(
(str) => {
return ipReg.test(str) || domainReg.test(str);
},
{
message: "common.errmsg.host_invalid",
}
),
group: z.string().optional(),
port: z
.string()
.min(1, "access.form.ssh_port.placeholder")
.max(5, t("common.errmsg.string_max", { max: 5 })),
username: z
.string()
.min(1, "access.form.ssh_username.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
password: z
.string()
.min(0, "access.form.ssh_password.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
key: z
.string()
.min(0, "access.form.ssh_key.placeholder")
.max(20480, t("common.errmsg.string_max", { max: 20480 })),
keyFile: z.any().optional(),
keyPassphrase: z
.string()
.min(0, "access.form.ssh_key_passphrase.placeholder")
.max(2048, t("common.errmsg.string_max", { max: 2048 })),
});
let config: SSHAccessConfig = {
host: "127.0.0.1",
port: "22",
username: "root",
password: "",
key: "",
keyFile: "",
keyPassphrase: "",
};
if (data) config = data.config as SSHAccessConfig;
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
id: data?.id,
name: data?.name || "",
configType: "ssh",
group: data?.group,
host: config.host,
port: config.port,
username: config.username,
password: config.password,
key: config.key,
keyFile: config.keyFile,
keyPassphrase: config.keyPassphrase,
},
});
const onSubmit = async (data: z.infer<typeof formSchema>) => {
let group = data.group;
if (group == "emptyId") group = "";
const req: AccessModel = {
id: data.id as string,
name: data.name,
configType: data.configType,
usage: accessProvidersMap.get(data.configType)!.usage,
group: group,
config: {
host: data.host,
port: data.port,
username: data.username,
password: data.password,
key: data.key,
keyPassphrase: data.keyPassphrase,
},
};
try {
req.id = op == "copy" ? "" : req.id;
const rs = await save(req);
onAfterReq();
req.id = rs.id;
req.created = rs.created;
req.updated = rs.updated;
if (data.id && op == "edit") {
updateAccess(req);
} else {
createAccess(req);
}
} catch (e) {
const err = e as ClientResponseError;
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
form.setError(key as keyof z.infer<typeof formSchema>, {
type: "manual",
message: value.message,
});
});
return;
}
};
const handleFileChange = async (event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0];
if (!file) return;
const savedFile = file;
setFileName(savedFile.name);
const content = await readFileContent(savedFile);
form.setValue("key", content);
};
const handleSelectFileClick = () => {
fileInputRef.current?.click();
};
return (
<>
<Form {...form}>
<form
onSubmit={(e) => {
e.stopPropagation();
form.handleSubmit(onSubmit)(e);
}}
className="space-y-8"
>
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.name.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.name.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="id"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="configType"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<div className="flex space-x-2">
<FormField
control={form.control}
name="host"
render={({ field }) => (
<FormItem className="grow">
<FormLabel>{t("access.form.ssh_host.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.ssh_host.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="port"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.ssh_port.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.ssh_port.placeholder")} {...field} type="number" />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
<FormField
control={form.control}
name="username"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.ssh_username.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.ssh_username.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="password"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.ssh_password.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.ssh_password.placeholder")} {...field} type="password" />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="key"
render={({ field }) => (
<FormItem hidden>
<FormLabel>{t("access.form.ssh_key.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.ssh_key.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="keyFile"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.ssh_key.label")}</FormLabel>
<FormControl>
<div>
<Button type={"button"} variant={"secondary"} size={"sm"} className="w-48" onClick={handleSelectFileClick}>
{fileName ? fileName : t("access.form.ssh_key_file.placeholder")}
</Button>
<Input
placeholder={t("access.form.ssh_key.placeholder")}
{...field}
ref={fileInputRef}
className="hidden"
hidden
type="file"
onChange={handleFileChange}
/>
</div>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="keyPassphrase"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.ssh_key_passphrase.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.ssh_key_passphrase.placeholder")} {...field} type="password" />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormMessage />
<div className="flex justify-end">
<Button type="submit">{t("common.button.save")}</Button>
</div>
</form>
</Form>
</>
);
};
export default AccessSSHForm;

View File

@ -1,190 +0,0 @@
import { useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import z from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { ClientResponseError } from "pocketbase";
import { Button } from "@/components/ui/button";
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { PbErrorData } from "@/domain/base";
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type TencentCloudAccessConfig } from "@/domain/access";
import { save } from "@/repository/access";
import { useAccessStore } from "@/stores/access";
type AccessTencentFormProps = {
op: "add" | "edit" | "copy";
data?: AccessModel;
onAfterReq: () => void;
};
const AccessTencentForm = ({ data, op, onAfterReq }: AccessTencentFormProps) => {
const { createAccess, updateAccess } = useAccessStore();
const { t } = useTranslation();
const formSchema = z.object({
id: z.string().optional(),
name: z
.string()
.min(1, "access.form.name.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
configType: accessTypeFormSchema,
secretId: z
.string()
.min(1, "access.form.secret_id.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
secretKey: z
.string()
.min(1, "access.form.secret_key.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
});
let config: TencentCloudAccessConfig = {
secretId: "",
secretKey: "",
};
if (data) config = data.config as TencentCloudAccessConfig;
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
id: data?.id,
name: data?.name || "",
configType: "tencentcloud",
secretId: config.secretId,
secretKey: config.secretKey,
},
});
const onSubmit = async (data: z.infer<typeof formSchema>) => {
const req: AccessModel = {
id: data.id as string,
name: data.name,
configType: data.configType,
usage: accessProvidersMap.get(data.configType)!.usage,
config: {
secretId: data.secretId,
secretKey: data.secretKey,
},
};
try {
req.id = op == "copy" ? "" : req.id;
const rs = await save(req);
onAfterReq();
req.id = rs.id;
req.created = rs.created;
req.updated = rs.updated;
if (data.id && op == "edit") {
updateAccess(req);
return;
}
createAccess(req);
} catch (e) {
const err = e as ClientResponseError;
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
form.setError(key as keyof z.infer<typeof formSchema>, {
type: "manual",
message: value.message,
});
});
}
};
return (
<>
<Form {...form}>
<form
onSubmit={(e) => {
e.stopPropagation();
form.handleSubmit(onSubmit)(e);
}}
className="space-y-8"
>
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.name.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.name.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="id"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="configType"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="secretId"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.secret_id.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.secret_id.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="secretKey"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.secret_key.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.secret_key.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<div className="flex justify-end">
<Button type="submit">{t("common.button.save")}</Button>
</div>
</form>
</Form>
</>
);
};
export default AccessTencentForm;

View File

@ -1,194 +0,0 @@
import { useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import z from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { ClientResponseError } from "pocketbase";
import { Input } from "@/components/ui/input";
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
import { Button } from "@/components/ui/button";
import { PbErrorData } from "@/domain/base";
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type VolcEngineAccessConfig } from "@/domain/access";
import { save } from "@/repository/access";
import { useAccessStore } from "@/stores/access";
type AccessVolcengineFormProps = {
op: "add" | "edit" | "copy";
data?: AccessModel;
onAfterReq: () => void;
};
const AccessVolcengineForm = ({ data, op, onAfterReq }: AccessVolcengineFormProps) => {
const { createAccess, updateAccess } = useAccessStore();
const { t } = useTranslation();
const formSchema = z.object({
id: z.string().optional(),
name: z
.string()
.min(1, "access.form.name.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
configType: accessTypeFormSchema,
accessKeyId: z
.string()
.min(1, "access.form.access_key_id.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
secretAccessKey: z
.string()
.min(1, "access.form.secret_access_key.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
});
let config: VolcEngineAccessConfig = {
accessKeyId: "",
secretAccessKey: "",
};
if (data) config = data.config as VolcEngineAccessConfig;
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
id: data?.id,
name: data?.name || "",
configType: "volcengine",
accessKeyId: config.accessKeyId,
secretAccessKey: config.secretAccessKey,
},
});
const onSubmit = async (data: z.infer<typeof formSchema>) => {
const req: AccessModel = {
id: data.id as string,
name: data.name,
configType: data.configType,
usage: accessProvidersMap.get(data.configType)!.usage,
config: {
accessKeyId: data.accessKeyId,
secretAccessKey: data.secretAccessKey,
},
};
try {
req.id = op == "copy" ? "" : req.id;
const rs = await save(req);
onAfterReq();
req.id = rs.id;
req.created = rs.created;
req.updated = rs.updated;
if (data.id && op == "edit") {
updateAccess(req);
return;
}
createAccess(req);
} catch (e) {
const err = e as ClientResponseError;
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
form.setError(key as keyof z.infer<typeof formSchema>, {
type: "manual",
message: value.message,
});
});
return;
}
};
return (
<>
<Form {...form}>
<form
onSubmit={(e) => {
e.stopPropagation();
form.handleSubmit(onSubmit)(e);
}}
className="space-y-8"
>
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.name.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.name.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="id"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="configType"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="accessKeyId"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.access_key_id.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.access_key_id.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="secretAccessKey"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.secret_access_key.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.secret_access_key.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormMessage />
<div className="flex justify-end">
<Button type="submit">{t("common.button.save")}</Button>
</div>
</form>
</Form>
</>
);
};
export default AccessVolcengineForm;

View File

@ -1,165 +0,0 @@
import { useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import z from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { ClientResponseError } from "pocketbase";
import { Button } from "@/components/ui/button";
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { PbErrorData } from "@/domain/base";
import { AccessModel, accessProvidersMap, accessTypeFormSchema, WebhookAccessConfig } from "@/domain/access";
import { save } from "@/repository/access";
import { useAccessStore } from "@/stores/access";
type AccessWebhookFormProps = {
op: "add" | "edit" | "copy";
data?: AccessModel;
onAfterReq: () => void;
};
const AccessWebhookForm = ({ data, op, onAfterReq }: AccessWebhookFormProps) => {
const { createAccess, updateAccess } = useAccessStore();
const { t } = useTranslation();
const formSchema = z.object({
id: z.string().optional(),
name: z
.string()
.min(1, "access.form.name.placeholder")
.max(64, t("common.errmsg.string_max", { max: 64 })),
configType: accessTypeFormSchema,
url: z.string().url("common.errmsg.url_invalid"),
});
let config: WebhookAccessConfig = {
url: "",
};
if (data) config = data.config as WebhookAccessConfig;
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
id: data?.id,
name: data?.name || "",
configType: "webhook",
url: config.url,
},
});
const onSubmit = async (data: z.infer<typeof formSchema>) => {
const req: AccessModel = {
id: data.id as string,
name: data.name,
configType: data.configType,
usage: accessProvidersMap.get(data.configType)!.usage,
config: {
url: data.url,
},
};
try {
req.id = op == "copy" ? "" : req.id;
const rs = await save(req);
onAfterReq();
req.id = rs.id;
req.created = rs.created;
req.updated = rs.updated;
if (data.id && op == "edit") {
updateAccess(req);
return;
}
createAccess(req);
} catch (e) {
const err = e as ClientResponseError;
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
form.setError(key as keyof z.infer<typeof formSchema>, {
type: "manual",
message: value.message,
});
});
}
};
return (
<>
<Form {...form}>
<form
onSubmit={(e) => {
e.stopPropagation();
form.handleSubmit(onSubmit)(e);
}}
className="space-y-8"
>
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.name.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.name.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="id"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="configType"
render={({ field }) => (
<FormItem className="hidden">
<FormLabel>{t("access.form.config.label")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="url"
render={({ field }) => (
<FormItem>
<FormLabel>{t("access.form.webhook_url.label")}</FormLabel>
<FormControl>
<Input placeholder={t("access.form.webhook_url.placeholder")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<div className="flex justify-end">
<Button type="submit">{t("common.button.save")}</Button>
</div>
</form>
</Form>
</>
);
};
export default AccessWebhookForm;

View File

@ -1,28 +0,0 @@
import * as React from "react";
import * as PopoverPrimitive from "@radix-ui/react-popover";
import { cn } from "./utils";
const Popover = PopoverPrimitive.Root;
const PopoverTrigger = PopoverPrimitive.Trigger;
const PopoverContent = React.forwardRef<React.ElementRef<typeof PopoverPrimitive.Content>, React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>>(
({ className, align = "center", sideOffset = 4, ...props }, ref) => (
<PopoverPrimitive.Portal>
<PopoverPrimitive.Content
ref={ref}
align={align}
sideOffset={sideOffset}
className={cn(
"z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className
)}
{...props}
/>
</PopoverPrimitive.Portal>
)
);
PopoverContent.displayName = PopoverPrimitive.Content.displayName;
export { Popover, PopoverTrigger, PopoverContent };

View File

@ -13,7 +13,11 @@ type AccessSelectProps = {
const AccessSelect = ({ value, onValueChange, providerType }: AccessSelectProps) => { const AccessSelect = ({ value, onValueChange, providerType }: AccessSelectProps) => {
const [localValue, setLocalValue] = React.useState<string>(""); const [localValue, setLocalValue] = React.useState<string>("");
const { t } = useTranslation(); const { t } = useTranslation();
const { accesses } = useAccessStore(); const { accesses, fetchAccesses } = useAccessStore();
useEffect(() => {
fetchAccesses();
}, []);
useEffect(() => { useEffect(() => {
setLocalValue(value); setLocalValue(value);

View File

@ -1,4 +1,3 @@
import { z } from "zod";
import { type BaseModel } from "pocketbase"; import { type BaseModel } from "pocketbase";
/* /*
@ -44,7 +43,7 @@ export const ACCESS_PROVIDER_TYPES = Object.freeze({
WEBHOOK: ACCESS_PROVIDER_TYPE_WEBHOOK, WEBHOOK: ACCESS_PROVIDER_TYPE_WEBHOOK,
} as const); } as const);
export interface AccessModel extends Omit<BaseModel, "created" | "updated"> { export interface AccessModel extends BaseModel {
name: string; name: string;
configType: string; configType: string;
usage: AccessUsages; usage: AccessUsages;
@ -202,27 +201,3 @@ export const accessProvidersMap: Map<AccessProvider["type"], AccessProvider> = n
[ACCESS_PROVIDER_TYPE_ACMEHTTPREQ, "common.provider.acmehttpreq", "/imgs/providers/acmehttpreq.svg", "apply"], [ACCESS_PROVIDER_TYPE_ACMEHTTPREQ, "common.provider.acmehttpreq", "/imgs/providers/acmehttpreq.svg", "apply"],
].map(([type, name, icon, usage]) => [type, { type, name, icon, usage: usage as AccessUsages }]) ].map(([type, name, icon, usage]) => [type, { type, name, icon, usage: usage as AccessUsages }])
); );
export const accessTypeFormSchema = z.union(
[
z.literal("aliyun"),
z.literal("tencentcloud"),
z.literal("huaweicloud"),
z.literal("baiducloud"),
z.literal("qiniu"),
z.literal("dogecloud"),
z.literal("aws"),
z.literal("cloudflare"),
z.literal("namesilo"),
z.literal("godaddy"),
z.literal("powerdns"),
z.literal("acmehttpreq"),
z.literal("local"),
z.literal("ssh"),
z.literal("webhook"),
z.literal("k8s"),
z.literal("volcengine"),
z.literal("byteplus"),
],
{ message: "access.form.type.placeholder" }
);

View File

@ -135,33 +135,5 @@
"access.form.ssh_key.tooltip": "Required when using key to connect to SSH.", "access.form.ssh_key.tooltip": "Required when using key to connect to SSH.",
"access.form.ssh_key_passphrase.label": "SSH Key Passphrase", "access.form.ssh_key_passphrase.label": "SSH Key Passphrase",
"access.form.ssh_key_passphrase.placeholder": "Please enter SSH Key passphrase", "access.form.ssh_key_passphrase.placeholder": "Please enter SSH Key passphrase",
"access.form.ssh_key_passphrase.tooltip": "Optional when using key to connect to SSH.", "access.form.ssh_key_passphrase.tooltip": "Optional when using key to connect to SSH."
"access.form.region.label": "Region",
"access.form.region.placeholder": "Please enter Region",
"access.form.access_key_id.label": "AccessKeyId",
"access.form.access_key_id.placeholder": "Please enter AccessKeyId",
"access.form.access_key_secret.label": "AccessKeySecret",
"access.form.access_key_secret.placeholder": "Please enter AccessKeySecret",
"access.form.access_key.label": "AccessKey",
"access.form.access_key.placeholder": "Please enter AccessKey",
"access.form.secret_id.label": "SecretId",
"access.form.secret_id.placeholder": "Please enter SecretId",
"access.form.secret_key.label": "SecretKey",
"access.form.secret_key.placeholder": "Please enter SecretKey",
"access.form.secret_access_key.label": "SecretAccessKey",
"access.form.secret_access_key.placeholder": "Please enter SecretAccessKey",
"access.form.cloud_dns_api_token.label": "CLOUD_DNS_API_TOKEN",
"access.form.cloud_dns_api_token.placeholder": "Please enter CLOUD_DNS_API_TOKEN",
"access.form.pdns_api_url.label": "PDNS_API_URL",
"access.form.pdns_api_url.placeholder": "Please enter PDNS_API_URL",
"access.form.pdns_api_key.label": "PDNS_API_KEY",
"access.form.pdns_api_key.placeholder": "Please enter PDNS_API_KEY",
"access.form.httpreq_endpoint.label": "HTTPREQ_ENDPOINT",
"access.form.httpreq_endpoint.placeholder": "Please enter HTTPREQ_ENDPOINT",
"access.form.httpreq_mode.label": "HTTPREQ_MODE",
"access.form.httpreq_mode.placeholder": "Please enter HTTPREQ_MODE(RAW or '')",
"access.form.username.label": "Username",
"access.form.username.placeholder": "Please enter username",
"access.form.password.label": "Password",
"access.form.password.placeholder": "Please enter password"
} }

View File

@ -135,33 +135,5 @@
"access.form.ssh_key.tooltip": "使用 SSH 密钥连接到 SSH 时必填。", "access.form.ssh_key.tooltip": "使用 SSH 密钥连接到 SSH 时必填。",
"access.form.ssh_key_passphrase.label": "SSH 密钥口令", "access.form.ssh_key_passphrase.label": "SSH 密钥口令",
"access.form.ssh_key_passphrase.placeholder": "请输入 SSH 密钥口令", "access.form.ssh_key_passphrase.placeholder": "请输入 SSH 密钥口令",
"access.form.ssh_key_passphrase.tooltip": "使用 SSH 密钥连接到 SSH 时选填。", "access.form.ssh_key_passphrase.tooltip": "使用 SSH 密钥连接到 SSH 时选填。"
"access.form.region.label": "Region",
"access.form.region.placeholder": "请输入区域",
"access.form.access_key_id.label": "AccessKeyId",
"access.form.access_key_id.placeholder": "请输入 AccessKeyId",
"access.form.access_key_secret.label": "AccessKeySecret",
"access.form.access_key_secret.placeholder": "请输入 AccessKeySecret",
"access.form.access_key.label": "AccessKey",
"access.form.access_key.placeholder": "请输入 AccessKey",
"access.form.secret_id.label": "SecretId",
"access.form.secret_id.placeholder": "请输入 SecretId",
"access.form.secret_key.label": "SecretKey",
"access.form.secret_key.placeholder": "请输入 SecretKey",
"access.form.secret_access_key.label": "SecretAccessKey",
"access.form.secret_access_key.placeholder": "请输入 SecretAccessKey",
"access.form.cloud_dns_api_token.label": "CLOUD_DNS_API_TOKEN",
"access.form.cloud_dns_api_token.placeholder": "请输入 CLOUD_DNS_API_TOKEN",
"access.form.pdns_api_url.label": "PDNS_API_URL",
"access.form.pdns_api_url.placeholder": "请输入 PDNS_API_URL",
"access.form.pdns_api_key.label": "PDNS_API_KEY",
"access.form.pdns_api_key.placeholder": "请输入 PDNS_API_KEY",
"access.form.httpreq_endpoint.label": "HTTP 请求端点",
"access.form.httpreq_endpoint.placeholder": "请输入 请求端点",
"access.form.httpreq_mode.label": "模式",
"access.form.httpreq_mode.placeholder": "请输入模式( RAW or '')",
"access.form.username.label": "用户名",
"access.form.username.placeholder": "请输入用户名",
"access.form.password.label": "密码",
"access.form.password.placeholder": "请输入密码"
} }

View File

@ -12,7 +12,7 @@ export const list = async () => {
}); });
}; };
export const save = async (record: Partial<AccessModel>) => { export const save = async (record: AccessModel | Omit<AccessModel, "id" | "created" | "updated" | "deleted">) => {
if (record.id) { if (record.id) {
return await getPocketBase().collection(COLLECTION_NAME).update<AccessModel>(record.id, record); return await getPocketBase().collection(COLLECTION_NAME).update<AccessModel>(record.id, record);
} }
@ -20,7 +20,7 @@ export const save = async (record: Partial<AccessModel>) => {
return await getPocketBase().collection(COLLECTION_NAME).create<AccessModel>(record); return await getPocketBase().collection(COLLECTION_NAME).create<AccessModel>(record);
}; };
export const remove = async (record: Partial<AccessModel>) => { export const remove = async (record: AccessModel) => {
record = { ...record, deleted: dayjs.utc().format("YYYY-MM-DD HH:mm:ss") }; record = { ...record, deleted: dayjs.utc().format("YYYY-MM-DD HH:mm:ss") };
await getPocketBase().collection(COLLECTION_NAME).update<AccessModel>(record.id, record); await getPocketBase().collection(COLLECTION_NAME).update<AccessModel>(record.id!, record);
}; };