diff --git a/ui/package-lock.json b/ui/package-lock.json index e2b71062..09c55d31 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -15,7 +15,6 @@ "@radix-ui/react-dialog": "^1.1.2", "@radix-ui/react-dropdown-menu": "^2.1.1", "@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-scroll-area": "^1.1.0", "@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": { "version": "1.2.0", "resolved": "https://registry.npmmirror.com/@radix-ui/react-popper/-/react-popper-1.2.0.tgz", diff --git a/ui/package.json b/ui/package.json index a7963f08..9889164f 100644 --- a/ui/package.json +++ b/ui/package.json @@ -17,7 +17,6 @@ "@radix-ui/react-dialog": "^1.1.2", "@radix-ui/react-dropdown-menu": "^2.1.1", "@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-scroll-area": "^1.1.0", "@radix-ui/react-select": "^2.1.1", diff --git a/ui/src/components/certimate/AccessAliyunForm.tsx b/ui/src/components/certimate/AccessAliyunForm.tsx deleted file mode 100644 index ebae48a4..00000000 --- a/ui/src/components/certimate/AccessAliyunForm.tsx +++ /dev/null @@ -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>({ - resolver: zodResolver(formSchema), - defaultValues: { - id: data?.id, - name: data?.name || "", - configType: "aliyun", - accessKeyId: config.accessKeyId, - accessSecretId: config.accessKeySecret, - }, - }); - - const onSubmit = async (data: z.infer) => { - 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, { - type: "manual", - message: value.message, - }); - }); - - return; - } - }; - - return ( - <> -
- { - e.stopPropagation(); - form.handleSubmit(onSubmit)(e); - }} - className="space-y-8" - > - ( - - {t("access.form.name.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> - - ( - - {t("access.form.access_key_id.label")} - - - - - - - )} - /> - - ( - - {t("access.form.access_key_secret.label")} - - - - - - - )} - /> - - - -
- -
- - - - ); -}; - -export default AccessAliyunForm; diff --git a/ui/src/components/certimate/AccessAwsForm.tsx b/ui/src/components/certimate/AccessAwsForm.tsx deleted file mode 100644 index 4669bb12..00000000 --- a/ui/src/components/certimate/AccessAwsForm.tsx +++ /dev/null @@ -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>({ - 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) => { - 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, { - type: "manual", - message: value.message, - }); - }); - - return; - } - }; - - return ( - <> -
- { - e.stopPropagation(); - form.handleSubmit(onSubmit)(e); - }} - className="space-y-8" - > - ( - - {t("access.form.name.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> - - ( - - {t("access.form.region.label")} - - - - - - - )} - /> - - ( - - {t("access.form.access_key_id.label")} - - - - - - - )} - /> - - ( - - {t("access.form.secret_access_key.label")} - - - - - - - )} - /> - - ( - - {t("access.form.aws_hosted_zone_id.label")} - - - - - - - )} - /> - - - -
- -
- - - - ); -}; - -export default AccessAwsForm; diff --git a/ui/src/components/certimate/AccessBaiduCloudForm.tsx b/ui/src/components/certimate/AccessBaiduCloudForm.tsx deleted file mode 100644 index 2bd1bb59..00000000 --- a/ui/src/components/certimate/AccessBaiduCloudForm.tsx +++ /dev/null @@ -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>({ - resolver: zodResolver(formSchema), - defaultValues: { - id: data?.id, - name: data?.name || "", - configType: "baiducloud", - accessKeyId: config.accessKeyId, - secretAccessKey: config.secretAccessKey, - }, - }); - - const onSubmit = async (data: z.infer) => { - 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, { - type: "manual", - message: value.message, - }); - }); - - return; - } - }; - - return ( - <> -
- { - e.stopPropagation(); - form.handleSubmit(onSubmit)(e); - }} - className="space-y-8" - > - ( - - {t("access.form.name.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> - - ( - - {t("access.form.access_key_id.label")} - - - - - - - )} - /> - - ( - - {t("access.form.secret_access_key.label")} - - - - - - - )} - /> - - - -
- -
- - - - ); -}; - -export default AccessBaiduCloudForm; diff --git a/ui/src/components/certimate/AccessByteplusForm.tsx b/ui/src/components/certimate/AccessByteplusForm.tsx deleted file mode 100644 index d069383b..00000000 --- a/ui/src/components/certimate/AccessByteplusForm.tsx +++ /dev/null @@ -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>({ - resolver: zodResolver(formSchema), - defaultValues: { - id: data?.id, - name: data?.name || "", - configType: "byteplus", - accessKey: config.accessKey, - secretKey: config.secretKey, - }, - }); - - const onSubmit = async (data: z.infer) => { - 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, { - type: "manual", - message: value.message, - }); - }); - - return; - } - }; - - return ( - <> -
- { - e.stopPropagation(); - form.handleSubmit(onSubmit)(e); - }} - className="space-y-8" - > - ( - - {t("access.form.name.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> - - ( - - {t("access.form.access_key.label")} - - - - - - - )} - /> - - ( - - {t("access.form.secret_key.label")} - - - - - - - )} - /> - - - -
- -
- - - - ); -}; - -export default AccessByteplusForm; diff --git a/ui/src/components/certimate/AccessCloudflareForm.tsx b/ui/src/components/certimate/AccessCloudflareForm.tsx deleted file mode 100644 index 874ca81d..00000000 --- a/ui/src/components/certimate/AccessCloudflareForm.tsx +++ /dev/null @@ -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>({ - resolver: zodResolver(formSchema), - defaultValues: { - id: data?.id, - name: data?.name || "", - configType: "cloudflare", - dnsApiToken: config.dnsApiToken, - }, - }); - - const onSubmit = async (data: z.infer) => { - 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, { - type: "manual", - message: value.message, - }); - }); - } - }; - - return ( - <> -
- { - e.stopPropagation(); - form.handleSubmit(onSubmit)(e); - }} - className="space-y-8" - > - ( - - {t("access.form.name.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> - - ( - - {t("access.form.cloud_dns_api_token.label")} - - - - - - - )} - /> - -
- -
- - - - ); -}; - -export default AccessCloudflareForm; diff --git a/ui/src/components/certimate/AccessDogeCloudForm.tsx b/ui/src/components/certimate/AccessDogeCloudForm.tsx deleted file mode 100644 index aa963503..00000000 --- a/ui/src/components/certimate/AccessDogeCloudForm.tsx +++ /dev/null @@ -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>({ - resolver: zodResolver(formSchema), - defaultValues: { - id: data?.id, - name: data?.name || "", - configType: "dogecloud", - accessKey: config.accessKey, - secretKey: config.secretKey, - }, - }); - - const onSubmit = async (data: z.infer) => { - 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, { - type: "manual", - message: value.message, - }); - }); - - return; - } - }; - - return ( - <> -
- { - e.stopPropagation(); - form.handleSubmit(onSubmit)(e); - }} - className="space-y-8" - > - ( - - {t("access.form.name.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> - - ( - - {t("access.form.access_key.label")} - - - - - - - )} - /> - - ( - - {t("access.form.secret_key.label")} - - - - - - - )} - /> - - - -
- -
- - - - ); -}; - -export default AccessDogeCloudForm; diff --git a/ui/src/components/certimate/AccessEditDialog.tsx b/ui/src/components/certimate/AccessEditDialog.tsx deleted file mode 100644 index d777dbcb..00000000 --- a/ui/src/components/certimate/AccessEditDialog.tsx +++ /dev/null @@ -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 = ( - { - setOpen(false); - }} - /> - ); - break; - case "tencentcloud": - childComponent = ( - { - setOpen(false); - }} - /> - ); - break; - case "huaweicloud": - childComponent = ( - { - setOpen(false); - }} - /> - ); - break; - case "baiducloud": - childComponent = ( - { - setOpen(false); - }} - /> - ); - break; - case "qiniu": - childComponent = ( - { - setOpen(false); - }} - /> - ); - break; - case "dogecloud": - childComponent = ( - { - setOpen(false); - }} - /> - ); - break; - case "aws": - childComponent = ( - { - setOpen(false); - }} - /> - ); - break; - case "cloudflare": - childComponent = ( - { - setOpen(false); - }} - /> - ); - break; - case "namesilo": - childComponent = ( - { - setOpen(false); - }} - /> - ); - break; - case "godaddy": - childComponent = ( - { - setOpen(false); - }} - /> - ); - break; - case "powerdns": - childComponent = ( - { - setOpen(false); - }} - /> - ); - break; - case "acmehttpreq": - childComponent = ( - { - setOpen(false); - }} - /> - ); - break; - case "local": - childComponent = ( - { - setOpen(false); - }} - /> - ); - break; - case "ssh": - childComponent = ( - { - setOpen(false); - }} - /> - ); - break; - case "webhook": - childComponent = ( - { - setOpen(false); - }} - /> - ); - break; - case "k8s": - childComponent = ( - { - setOpen(false); - }} - /> - ); - break; - case "volcengine": - childComponent = ( - { - setOpen(false); - }} - /> - ); - break; - case "byteplus": - childComponent = ( - { - setOpen(false); - }} - /> - ); - break; - } - - return ( - { - if (openState) { - document.body.style.pointerEvents = "auto"; - } - setOpen(openState); - }} - open={open} - modal={false} - > - - {trigger} - - { - event.preventDefault(); - }} - > - - - { - { - ["add"]: t("access.action.add"), - ["edit"]: t("access.action.edit"), - ["copy"]: t("access.action.copy"), - }[op] - } - - - -
-
- - { - setConfigType(val); - }} - /> -
- -
{childComponent}
-
-
-
-
- ); -}; - -export default AccessEditDialog; diff --git a/ui/src/components/certimate/AccessGodaddyForm.tsx b/ui/src/components/certimate/AccessGodaddyForm.tsx deleted file mode 100644 index a56c98b8..00000000 --- a/ui/src/components/certimate/AccessGodaddyForm.tsx +++ /dev/null @@ -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>({ - resolver: zodResolver(formSchema), - defaultValues: { - id: data?.id, - name: data?.name || "", - configType: "godaddy", - apiKey: config.apiKey, - apiSecret: config.apiSecret, - }, - }); - - const onSubmit = async (data: z.infer) => { - 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, { - type: "manual", - message: value.message, - }); - }); - } - }; - - return ( - <> -
- { - e.stopPropagation(); - form.handleSubmit(onSubmit)(e); - }} - className="space-y-8" - > - ( - - {t("access.form.name.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> - - ( - - {t("access.form.godaddy_api_key.label")} - - - - - - - )} - /> - - ( - - {t("access.form.godaddy_api_secret.label")} - - - - - - - )} - /> - -
- -
- - - - ); -}; - -export default AccessGodaddyForm; diff --git a/ui/src/components/certimate/AccessHttpreqForm.tsx b/ui/src/components/certimate/AccessHttpreqForm.tsx deleted file mode 100644 index ac8c7fac..00000000 --- a/ui/src/components/certimate/AccessHttpreqForm.tsx +++ /dev/null @@ -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>({ - 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) => { - 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, { - type: "manual", - message: value.message, - }); - }); - - return; - } - }; - - return ( - <> -
- { - e.stopPropagation(); - form.handleSubmit(onSubmit)(e); - }} - className="space-y-8" - > - ( - - {t("access.form.name.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> - - ( - - {t("access.form.httpreq_endpoint.label")} - - - - - - - )} - /> - - ( - - {t("access.form.httpreq_mode.label")} - - - - - - - )} - /> - - ( - - {t("access.form.username.label")} - - - - - - - )} - /> - - ( - - {t("access.form.password.label")} - - - - - - - )} - /> - - - -
- -
- - - - ); -}; - -export default AccessHttpreqForm; diff --git a/ui/src/components/certimate/AccessHuaweicloudForm.tsx b/ui/src/components/certimate/AccessHuaweicloudForm.tsx deleted file mode 100644 index 00167d75..00000000 --- a/ui/src/components/certimate/AccessHuaweicloudForm.tsx +++ /dev/null @@ -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>({ - 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) => { - 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, { - type: "manual", - message: value.message, - }); - }); - - return; - } - }; - - return ( - <> -
- { - e.stopPropagation(); - form.handleSubmit(onSubmit)(e); - }} - className="space-y-8" - > - ( - - {t("access.form.name.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> - - ( - - {t("access.form.region.label")} - - - - - - - )} - /> - - ( - - {t("access.form.access_key_id.label")} - - - - - - - )} - /> - - ( - - {t("access.form.secret_access_key.label")} - - - - - - - )} - /> - - - -
- -
- - - - ); -}; - -export default AccessHuaweiCloudForm; diff --git a/ui/src/components/certimate/AccessKubernetesForm.tsx b/ui/src/components/certimate/AccessKubernetesForm.tsx deleted file mode 100644 index 14db9997..00000000 --- a/ui/src/components/certimate/AccessKubernetesForm.tsx +++ /dev/null @@ -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(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>({ - resolver: zodResolver(formSchema), - defaultValues: { - id: data?.id, - name: data?.name || "", - configType: "k8s", - kubeConfig: config.kubeConfig, - kubeConfigFile: config.kubeConfigFile, - }, - }); - - const onSubmit = async (data: z.infer) => { - 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, { - type: "manual", - message: value.message, - }); - }); - - return; - } - }; - - const handleFileChange = async (event: React.ChangeEvent) => { - 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 ( - <> -
- { - e.stopPropagation(); - form.handleSubmit(onSubmit)(e); - }} - className="space-y-8" - > - ( - - {t("access.form.name.label")} - - - - - - - )} - /> - - ( - - )} - /> - - ( - - {t("access.form.k8s_kubeconfig.label")} - -
- - -
-
- - -
- )} - /> - - - -
- -
- - - - ); -}; - -export default AccessKubernetesForm; diff --git a/ui/src/components/certimate/AccessLocalForm.tsx b/ui/src/components/certimate/AccessLocalForm.tsx deleted file mode 100644 index 83a70f17..00000000 --- a/ui/src/components/certimate/AccessLocalForm.tsx +++ /dev/null @@ -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>({ - resolver: zodResolver(formSchema), - defaultValues: { - id: data?.id, - name: data?.name || "", - configType: "local", - }, - }); - - const onSubmit = async (data: z.infer) => { - 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, { - type: "manual", - message: value.message, - }); - }); - - return; - } - }; - - return ( - <> -
- { - e.stopPropagation(); - form.handleSubmit(onSubmit)(e); - }} - className="space-y-8" - > - ( - - {t("access.form.name.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> - - - -
- -
- - - - ); -}; - -export default AccessLocalForm; diff --git a/ui/src/components/certimate/AccessNamesiloForm.tsx b/ui/src/components/certimate/AccessNamesiloForm.tsx deleted file mode 100644 index cf47dd70..00000000 --- a/ui/src/components/certimate/AccessNamesiloForm.tsx +++ /dev/null @@ -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>({ - resolver: zodResolver(formSchema), - defaultValues: { - id: data?.id, - name: data?.name || "", - configType: "namesilo", - apiKey: config.apiKey, - }, - }); - - const onSubmit = async (data: z.infer) => { - 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, { - type: "manual", - message: value.message, - }); - }); - } - }; - - return ( - <> -
- { - e.stopPropagation(); - form.handleSubmit(onSubmit)(e); - }} - className="space-y-8" - > - ( - - {t("access.form.name.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> - - ( - - {t("access.form.namesilo_api_key.label")} - - - - - - - )} - /> - -
- -
- - - - ); -}; - -export default AccessNameSiloForm; diff --git a/ui/src/components/certimate/AccessPdnsForm.tsx b/ui/src/components/certimate/AccessPdnsForm.tsx deleted file mode 100644 index e49c8271..00000000 --- a/ui/src/components/certimate/AccessPdnsForm.tsx +++ /dev/null @@ -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>({ - resolver: zodResolver(formSchema), - defaultValues: { - id: data?.id, - name: data?.name || "", - configType: "powerdns", - apiUrl: config.apiUrl, - apiKey: config.apiKey, - }, - }); - - const onSubmit = async (data: z.infer) => { - 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, { - type: "manual", - message: value.message, - }); - }); - - return; - } - }; - - return ( - <> -
- { - e.stopPropagation(); - form.handleSubmit(onSubmit)(e); - }} - className="space-y-8" - > - ( - - {t("access.form.name.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> - - ( - - {t("access.form.pdns_api_url.label")} - - - - - - - )} - /> - - ( - - {t("access.form.pdns_api_key.label")} - - - - - - - )} - /> - - - -
- -
- - - - ); -}; - -export default AccessPdnsForm; diff --git a/ui/src/components/certimate/AccessQiniuForm.tsx b/ui/src/components/certimate/AccessQiniuForm.tsx deleted file mode 100644 index 512cdb99..00000000 --- a/ui/src/components/certimate/AccessQiniuForm.tsx +++ /dev/null @@ -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>({ - resolver: zodResolver(formSchema), - defaultValues: { - id: data?.id, - name: data?.name || "", - configType: "qiniu", - accessKey: config.accessKey, - secretKey: config.secretKey, - }, - }); - - const onSubmit = async (data: z.infer) => { - 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, { - type: "manual", - message: value.message, - }); - }); - - return; - } - }; - - return ( - <> -
- { - e.stopPropagation(); - form.handleSubmit(onSubmit)(e); - }} - className="space-y-8" - > - ( - - {t("access.form.name.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> - - ( - - {t("access.form.access_key.label")} - - - - - - - )} - /> - - ( - - {t("access.form.secret_key.label")} - - - - - - - )} - /> - - - -
- -
- - - - ); -}; - -export default AccessQiniuForm; diff --git a/ui/src/components/certimate/AccessSSHForm.tsx b/ui/src/components/certimate/AccessSSHForm.tsx deleted file mode 100644 index 3c1790ec..00000000 --- a/ui/src/components/certimate/AccessSSHForm.tsx +++ /dev/null @@ -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(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>({ - 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) => { - 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, { - type: "manual", - message: value.message, - }); - }); - - return; - } - }; - - const handleFileChange = async (event: React.ChangeEvent) => { - 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 ( - <> -
- { - e.stopPropagation(); - form.handleSubmit(onSubmit)(e); - }} - className="space-y-8" - > - ( - - {t("access.form.name.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> -
- ( - - {t("access.form.ssh_host.label")} - - - - - - - )} - /> - - ( - - {t("access.form.ssh_port.label")} - - - - - - - )} - /> -
- - ( - - {t("access.form.ssh_username.label")} - - - - - - - )} - /> - - ( - - {t("access.form.ssh_password.label")} - - - - - - - )} - /> - - ( - - )} - /> - - ( - - {t("access.form.ssh_key.label")} - -
- - -
-
- - -
- )} - /> - - ( - - {t("access.form.ssh_key_passphrase.label")} - - - - - - - )} - /> - - - -
- -
- - - - ); -}; - -export default AccessSSHForm; diff --git a/ui/src/components/certimate/AccessTencentForm.tsx b/ui/src/components/certimate/AccessTencentForm.tsx deleted file mode 100644 index 5eab43b4..00000000 --- a/ui/src/components/certimate/AccessTencentForm.tsx +++ /dev/null @@ -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>({ - resolver: zodResolver(formSchema), - defaultValues: { - id: data?.id, - name: data?.name || "", - configType: "tencentcloud", - secretId: config.secretId, - secretKey: config.secretKey, - }, - }); - - const onSubmit = async (data: z.infer) => { - 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, { - type: "manual", - message: value.message, - }); - }); - } - }; - - return ( - <> -
- { - e.stopPropagation(); - form.handleSubmit(onSubmit)(e); - }} - className="space-y-8" - > - ( - - {t("access.form.name.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> - - ( - - {t("access.form.secret_id.label")} - - - - - - - )} - /> - - ( - - {t("access.form.secret_key.label")} - - - - - - - )} - /> - -
- -
- - - - ); -}; - -export default AccessTencentForm; diff --git a/ui/src/components/certimate/AccessVolcengineForm.tsx b/ui/src/components/certimate/AccessVolcengineForm.tsx deleted file mode 100644 index f9c8894e..00000000 --- a/ui/src/components/certimate/AccessVolcengineForm.tsx +++ /dev/null @@ -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>({ - resolver: zodResolver(formSchema), - defaultValues: { - id: data?.id, - name: data?.name || "", - configType: "volcengine", - accessKeyId: config.accessKeyId, - secretAccessKey: config.secretAccessKey, - }, - }); - - const onSubmit = async (data: z.infer) => { - 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, { - type: "manual", - message: value.message, - }); - }); - - return; - } - }; - - return ( - <> -
- { - e.stopPropagation(); - form.handleSubmit(onSubmit)(e); - }} - className="space-y-8" - > - ( - - {t("access.form.name.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> - - ( - - {t("access.form.access_key_id.label")} - - - - - - - )} - /> - - ( - - {t("access.form.secret_access_key.label")} - - - - - - - )} - /> - - - -
- -
- - - - ); -}; - -export default AccessVolcengineForm; diff --git a/ui/src/components/certimate/AccessWebhookForm.tsx b/ui/src/components/certimate/AccessWebhookForm.tsx deleted file mode 100644 index d7a79f59..00000000 --- a/ui/src/components/certimate/AccessWebhookForm.tsx +++ /dev/null @@ -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>({ - resolver: zodResolver(formSchema), - defaultValues: { - id: data?.id, - name: data?.name || "", - configType: "webhook", - url: config.url, - }, - }); - - const onSubmit = async (data: z.infer) => { - 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, { - type: "manual", - message: value.message, - }); - }); - } - }; - - return ( - <> -
- { - e.stopPropagation(); - form.handleSubmit(onSubmit)(e); - }} - className="space-y-8" - > - ( - - {t("access.form.name.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> - - ( - - {t("access.form.config.label")} - - - - - - - )} - /> - - ( - - {t("access.form.webhook_url.label")} - - - - - - - )} - /> - -
- -
- - - - ); -}; - -export default AccessWebhookForm; diff --git a/ui/src/components/ui/popover.tsx b/ui/src/components/ui/popover.tsx deleted file mode 100644 index 3f188b41..00000000 --- a/ui/src/components/ui/popover.tsx +++ /dev/null @@ -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.ComponentPropsWithoutRef>( - ({ className, align = "center", sideOffset = 4, ...props }, ref) => ( - - - - ) -); -PopoverContent.displayName = PopoverPrimitive.Content.displayName; - -export { Popover, PopoverTrigger, PopoverContent }; diff --git a/ui/src/components/workflow/AccessSelect.tsx b/ui/src/components/workflow/AccessSelect.tsx index 8ced0156..827c82ad 100644 --- a/ui/src/components/workflow/AccessSelect.tsx +++ b/ui/src/components/workflow/AccessSelect.tsx @@ -13,7 +13,11 @@ type AccessSelectProps = { const AccessSelect = ({ value, onValueChange, providerType }: AccessSelectProps) => { const [localValue, setLocalValue] = React.useState(""); const { t } = useTranslation(); - const { accesses } = useAccessStore(); + const { accesses, fetchAccesses } = useAccessStore(); + + useEffect(() => { + fetchAccesses(); + }, []); useEffect(() => { setLocalValue(value); diff --git a/ui/src/domain/access.ts b/ui/src/domain/access.ts index fab3cf61..94864129 100644 --- a/ui/src/domain/access.ts +++ b/ui/src/domain/access.ts @@ -1,4 +1,3 @@ -import { z } from "zod"; import { type BaseModel } from "pocketbase"; /* @@ -44,7 +43,7 @@ export const ACCESS_PROVIDER_TYPES = Object.freeze({ WEBHOOK: ACCESS_PROVIDER_TYPE_WEBHOOK, } as const); -export interface AccessModel extends Omit { +export interface AccessModel extends BaseModel { name: string; configType: string; usage: AccessUsages; @@ -202,27 +201,3 @@ export const accessProvidersMap: Map = n [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 }]) ); - -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" } -); diff --git a/ui/src/i18n/locales/en/nls.access.json b/ui/src/i18n/locales/en/nls.access.json index a43ec3ac..573e98c2 100644 --- a/ui/src/i18n/locales/en/nls.access.json +++ b/ui/src/i18n/locales/en/nls.access.json @@ -135,33 +135,5 @@ "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.placeholder": "Please enter SSH Key passphrase", - "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" + "access.form.ssh_key_passphrase.tooltip": "Optional when using key to connect to SSH." } diff --git a/ui/src/i18n/locales/zh/nls.access.json b/ui/src/i18n/locales/zh/nls.access.json index bf4969e1..843e0e9d 100644 --- a/ui/src/i18n/locales/zh/nls.access.json +++ b/ui/src/i18n/locales/zh/nls.access.json @@ -135,33 +135,5 @@ "access.form.ssh_key.tooltip": "使用 SSH 密钥连接到 SSH 时必填。", "access.form.ssh_key_passphrase.label": "SSH 密钥口令", "access.form.ssh_key_passphrase.placeholder": "请输入 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": "请输入密码" + "access.form.ssh_key_passphrase.tooltip": "使用 SSH 密钥连接到 SSH 时选填。" } diff --git a/ui/src/repository/access.ts b/ui/src/repository/access.ts index 2d114a45..6f0f7d1c 100644 --- a/ui/src/repository/access.ts +++ b/ui/src/repository/access.ts @@ -12,7 +12,7 @@ export const list = async () => { }); }; -export const save = async (record: Partial) => { +export const save = async (record: AccessModel | Omit) => { if (record.id) { return await getPocketBase().collection(COLLECTION_NAME).update(record.id, record); } @@ -20,7 +20,7 @@ export const save = async (record: Partial) => { return await getPocketBase().collection(COLLECTION_NAME).create(record); }; -export const remove = async (record: Partial) => { +export const remove = async (record: AccessModel) => { record = { ...record, deleted: dayjs.utc().format("YYYY-MM-DD HH:mm:ss") }; - await getPocketBase().collection(COLLECTION_NAME).update(record.id, record); + await getPocketBase().collection(COLLECTION_NAME).update(record.id!, record); };