diff --git a/ui/src/components/access/AccessEditDrawer.tsx b/ui/src/components/access/AccessEditDrawer.tsx index 6792dfebd..29c02c12f 100644 --- a/ui/src/components/access/AccessEditDrawer.tsx +++ b/ui/src/components/access/AccessEditDrawer.tsx @@ -1,25 +1,28 @@ -import { startTransition, useCallback, useEffect, useRef, useState } from "react"; +import { startTransition, useCallback, useState } from "react"; import { useTranslation } from "react-i18next"; import { IconX } from "@tabler/icons-react"; import { useControllableValue, useGetState } from "ahooks"; -import { App, Button, Drawer, Flex } from "antd"; +import { App, Button, Drawer, Flex, Form } from "antd"; +import AccessProviderPicker from "@/components/provider/AccessProviderPicker"; +import Show from "@/components/Show"; import { type AccessModel } from "@/domain/access"; +import { ACCESS_USAGES } from "@/domain/provider"; import { useTriggerElement, useZustandShallowSelector } from "@/hooks"; import { useAccessesStore } from "@/stores/access"; import { getErrMsg } from "@/utils/error"; -import AccessForm, { type AccessFormInstance, type AccessFormProps } from "./AccessForm"; +import AccessForm, { type AccessFormModes, type AccessFormProps, type AccessFormUsages } from "./AccessForm"; export interface AccessEditDrawerProps { afterClose?: () => void; afterSubmit?: (record: AccessModel) => void; data?: AccessFormProps["initialValues"]; loading?: boolean; - mode: AccessFormProps["mode"]; + mode: AccessFormModes; open?: boolean; trigger?: React.ReactNode; - usage?: AccessFormProps["usage"]; + usage?: AccessFormUsages; onOpenChange?: (open: boolean) => void; } @@ -38,25 +41,29 @@ const AccessEditDrawer = ({ afterClose, afterSubmit, mode, data, loading, trigge const triggerEl = useTriggerElement(trigger, { onClick: () => setOpen(true) }); - const formRef = useRef(null); + const providerFilter = AccessForm.useProviderFilterByUsage(usage); + + const [formInst] = Form.useForm(); const [formPending, setFormPending] = useState(false); - const [footerShow, setFooterShow] = useState(!!data?.provider); - useEffect(() => { - setFooterShow(!!data?.provider); - }, [data?.provider]); + const fieldProvider = Form.useWatch("provider", { form: formInst, preserve: true }); + + const handleProviderPick = (value: string) => { + formInst.setFieldValue("provider", value); + }; const handleOkClick = async () => { setFormPending(true); try { - await formRef.current!.validateFields(); + await formInst.validateFields(); } catch (err) { setFormPending(false); throw err; } try { - let values: AccessModel = formRef.current!.getFieldsValue(); + let values: AccessModel = formInst.getFieldsValue(true); + values.reserve = usage === "ca" ? "ca" : usage === "notification" ? "notif" : void 0; if (mode === "create") { if (data?.id) { @@ -91,10 +98,6 @@ const AccessEditDrawer = ({ afterClose, afterSubmit, mode, data, loading, trigge setOpen(false); }; - const handleFormValuesChange: AccessFormProps["onValuesChange"] = (values) => { - setFooterShow(!!values.provider); - }; - return ( <> {triggerEl} @@ -105,7 +108,7 @@ const AccessEditDrawer = ({ afterClose, afterSubmit, mode, data, loading, trigge closeIcon={false} destroyOnHidden footer={ - footerShow ? ( + fieldProvider ? ( - - )} - - - - ); -}; - -export default AccessFormSSHConfig; diff --git a/ui/src/components/access/AccessFormSafeLineConfig.tsx b/ui/src/components/access/AccessFormSafeLineConfig.tsx deleted file mode 100644 index 909a2b7a2..000000000 --- a/ui/src/components/access/AccessFormSafeLineConfig.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input, Switch } from "antd"; -import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; - -import { type AccessConfigForSafeLine } from "@/domain/access"; - -type AccessFormSafeLineConfigFieldValues = Nullish; - -export interface AccessFormSafeLineConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormSafeLineConfigFieldValues; - onValuesChange?: (values: AccessFormSafeLineConfigFieldValues) => void; -} - -const initFormModel = (): AccessFormSafeLineConfigFieldValues => { - return { - serverUrl: "http://:9443/", - apiToken: "", - }; -}; - -const AccessFormSafeLineConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormSafeLineConfigProps) => { - const { t } = useTranslation(); - - const formSchema = z.object({ - serverUrl: z.url(t("common.errmsg.url_invalid")), - apiToken: z - .string() - .min(1, t("access.form.safeline_api_token.placeholder")) - .max(64, t("common.errmsg.string_max", { max: 64 })), - allowInsecureConnections: z.boolean().nullish(), - }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- - - - - } - > - - - - - - -
- ); -}; - -export default AccessFormSafeLineConfig; diff --git a/ui/src/components/access/AccessFormSpaceshipConfig.tsx b/ui/src/components/access/AccessFormSpaceshipConfig.tsx deleted file mode 100644 index a3b57625c..000000000 --- a/ui/src/components/access/AccessFormSpaceshipConfig.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; -import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; - -import { type AccessConfigForSpaceship } from "@/domain/access"; - -type AccessFormSpaceshipConfigFieldValues = Nullish; - -export interface AccessFormSpaceshipConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormSpaceshipConfigFieldValues; - onValuesChange?: (values: AccessFormSpaceshipConfigFieldValues) => void; -} - -const initFormModel = (): AccessFormSpaceshipConfigFieldValues => { - return { - apiKey: "", - apiSecret: "", - }; -}; - -const AccessFormSpaceshipConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormSpaceshipConfigProps) => { - const { t } = useTranslation(); - - const formSchema = z.object({ - apiKey: z.string().nonempty(t("access.form.spaceship_api_key.placeholder")), - apiSecret: z.string().nonempty(t("access.form.spaceship_api_secret.placeholder")), - }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- } - > - - - - } - > - - -
- ); -}; - -export default AccessFormSpaceshipConfig; diff --git a/ui/src/components/access/AccessFormUniCloudConfig.tsx b/ui/src/components/access/AccessFormUniCloudConfig.tsx deleted file mode 100644 index ec01b7666..000000000 --- a/ui/src/components/access/AccessFormUniCloudConfig.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; -import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; - -import { type AccessConfigForUniCloud } from "@/domain/access"; - -type AccessFormUniCloudConfigFieldValues = Nullish; - -export interface AccessFormUniCloudConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormUniCloudConfigFieldValues; - onValuesChange?: (values: AccessFormUniCloudConfigFieldValues) => void; -} - -const initFormModel = (): AccessFormUniCloudConfigFieldValues => { - return { - username: "", - password: "", - }; -}; - -const AccessFormUniCloudConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormUniCloudConfigProps) => { - const { t } = useTranslation(); - - const formSchema = z.object({ - username: z.string().nonempty(t("access.form.unicloud_username.placeholder")), - password: z.string().nonempty(t("access.form.unicloud_password.placeholder")), - }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- } - > - - - - } - > - - -
- ); -}; - -export default AccessFormUniCloudConfig; diff --git a/ui/src/components/access/AccessFormWeComBotConfig.tsx b/ui/src/components/access/AccessFormWeComBotConfig.tsx deleted file mode 100644 index befd2c7b2..000000000 --- a/ui/src/components/access/AccessFormWeComBotConfig.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; -import { createSchemaFieldRule } from "antd-zod"; -import { z } from "zod"; - -import { type AccessConfigForWeComBot } from "@/domain/access"; - -type AccessFormWeComBotConfigFieldValues = Nullish; - -export interface AccessFormWeComBotConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormWeComBotConfigFieldValues; - onValuesChange?: (values: AccessFormWeComBotConfigFieldValues) => void; -} - -const initFormModel = (): AccessFormWeComBotConfigFieldValues => { - return { - webhookUrl: "", - }; -}; - -const AccessFormWeComBotConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormWeComBotConfigProps) => { - const { t } = useTranslation(); - - const formSchema = z.object({ - webhookUrl: z.url(t("common.errmsg.url_invalid")), - }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- } - > - - -
- ); -}; - -export default AccessFormWeComBotConfig; diff --git a/ui/src/components/access/forms/AccessConfigFieldsProvider1Panel.tsx b/ui/src/components/access/forms/AccessConfigFieldsProvider1Panel.tsx new file mode 100644 index 000000000..c2e79e451 --- /dev/null +++ b/ui/src/components/access/forms/AccessConfigFieldsProvider1Panel.tsx @@ -0,0 +1,90 @@ +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input, Select, Switch } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { useFormNestedFieldsContext } from "./_context"; + +const AccessConfigFormFieldsProvider1Panel = () => { + const { i18n, t } = useTranslation(); + + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); + + return ( + <> + + + + + + + + + } + > + + + + + + + + ); +}; + +const getInitialValues = (): Nullish>> => { + return { + serverUrl: "http://:9180/", + apiKey: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + serverUrl: z.url(t("common.errmsg.url_invalid")), + apiKey: z.string().nonempty(t("access.form.apisix_api_key.placeholder")), + allowInsecureConnections: z.boolean().nullish(), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderAPISIX, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormAWSConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderAWS.tsx similarity index 53% rename from ui/src/components/access/AccessFormAWSConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderAWS.tsx index 15ea5e9fe..9b1685f7c 100644 --- a/ui/src/components/access/AccessFormAWSConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderAWS.tsx @@ -1,31 +1,56 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForAWS } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormAWSConfigFieldValues = Nullish; +const AccessConfigFormFieldsProviderAWS = () => { + const { i18n, t } = useTranslation(); -export interface AccessFormAWSConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormAWSConfigFieldValues; - onValuesChange?: (values: AccessFormAWSConfigFieldValues) => void; -} + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); -const initFormModel = (): AccessFormAWSConfigFieldValues => { + return ( + <> + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { return { accessKeyId: "", secretAccessKey: "", }; }; -const AccessFormAWSConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormAWSConfigProps) => { - const { t } = useTranslation(); +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; - const formSchema = z.object({ + return z.object({ accessKeyId: z .string() .min(1, t("access.form.aws_access_key_id.placeholder")) @@ -35,40 +60,11 @@ const AccessFormAWSConfig = ({ form: formInst, formName, disabled, initialValues .min(1, t("access.form.aws_secret_access_key.placeholder")) .max(64, t("common.errmsg.string_max", { max: 64 })), }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- } - > - - - - } - > - - -
- ); }; -export default AccessFormAWSConfig; +const _default = Object.assign(AccessConfigFormFieldsProviderAWS, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormAliyunConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderAliyun.tsx similarity index 59% rename from ui/src/components/access/AccessFormAliyunConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderAliyun.tsx index 5abfaf463..74fda3517 100644 --- a/ui/src/components/access/AccessFormAliyunConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderAliyun.tsx @@ -1,31 +1,66 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForAliyun } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormAliyunConfigFieldValues = Nullish; +const AccessConfigFormFieldsProviderAliyun = () => { + const { i18n, t } = useTranslation(); -export interface AccessFormAliyunConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormAliyunConfigFieldValues; - onValuesChange?: (values: AccessFormAliyunConfigFieldValues) => void; -} + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); -const initFormModel = (): AccessFormAliyunConfigFieldValues => { + return ( + <> + } + > + + + + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { return { accessKeyId: "", accessKeySecret: "", }; }; -const AccessFormAliyunConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange: onValuesChange }: AccessFormAliyunConfigProps) => { - const { t } = useTranslation(); +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; - const formSchema = z.object({ + return z.object({ accessKeyId: z .string() .min(1, t("access.form.aliyun_access_key_id.placeholder")) @@ -36,49 +71,11 @@ const AccessFormAliyunConfig = ({ form: formInst, formName, disabled, initialVal .max(64, t("common.errmsg.string_max", { max: 64 })), resourceGroupId: z.string().nullish(), }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- } - > - - - - } - > - - - - } - > - - -
- ); }; -export default AccessFormAliyunConfig; +const _default = Object.assign(AccessConfigFormFieldsProviderAliyun, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormAzureConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderAzure.tsx similarity index 66% rename from ui/src/components/access/AccessFormAzureConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderAzure.tsx index e6c8bfcd3..375123097 100644 --- a/ui/src/components/access/AccessFormAzureConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderAzure.tsx @@ -1,21 +1,70 @@ -import { useTranslation } from "react-i18next"; -import { AutoComplete, Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { AutoComplete, Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForAzure } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormAzureConfigFieldValues = Nullish; +const AccessConfigFormFieldsProviderAzure = () => { + const { i18n, t } = useTranslation(); -export interface AccessFormAzureConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormAzureConfigFieldValues; - onValuesChange?: (values: AccessFormAzureConfigFieldValues) => void; -} + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); -const initFormModel = (): AccessFormAzureConfigFieldValues => { + return ( + <> + } + > + + + + } + > + + + + } + > + + + + } + > + ({ value }))} + placeholder={t("access.form.azure_cloud_name.placeholder")} + filterOption={(inputValue, option) => option!.value.toLowerCase().includes(inputValue.toLowerCase())} + /> + + + ); +}; + +const getInitialValues = (): Nullish>> => { return { tenantId: "", clientId: "", @@ -23,10 +72,10 @@ const initFormModel = (): AccessFormAzureConfigFieldValues => { }; }; -const AccessFormAzureConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormAzureConfigProps) => { - const { t } = useTranslation(); +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; - const formSchema = z.object({ + return z.object({ tenantId: z .string() .min(1, t("access.form.azure_tenant_id.placeholder")) @@ -41,62 +90,11 @@ const AccessFormAzureConfig = ({ form: formInst, formName, disabled, initialValu .max(64, t("common.errmsg.string_max", { max: 64 })), cloudName: z.string().nullish(), }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- } - > - - - - } - > - - - - } - > - - - - } - > - ({ value }))} - placeholder={t("access.form.azure_cloud_name.placeholder")} - filterOption={(inputValue, option) => option!.value.toLowerCase().includes(inputValue.toLowerCase())} - /> - -
- ); }; -export default AccessFormAzureConfig; +const _default = Object.assign(AccessConfigFormFieldsProviderAzure, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormBaiduCloudConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderBaiduCloud.tsx similarity index 53% rename from ui/src/components/access/AccessFormBaiduCloudConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderBaiduCloud.tsx index 49b555d93..2a4221b6a 100644 --- a/ui/src/components/access/AccessFormBaiduCloudConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderBaiduCloud.tsx @@ -1,31 +1,56 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForBaiduCloud } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormBaiduCloudConfigFieldValues = Nullish; +const AccessConfigFormFieldsProviderBaiduCloud = () => { + const { i18n, t } = useTranslation(); -export interface AccessFormBaiduCloudConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormBaiduCloudConfigFieldValues; - onValuesChange?: (values: AccessFormBaiduCloudConfigFieldValues) => void; -} + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); -const initFormModel = (): AccessFormBaiduCloudConfigFieldValues => { + return ( + <> + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { return { accessKeyId: "", secretAccessKey: "", }; }; -const AccessFormBaiduCloudConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormBaiduCloudConfigProps) => { - const { t } = useTranslation(); +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; - const formSchema = z.object({ + return z.object({ accessKeyId: z .string() .min(1, t("access.form.baiducloud_access_key_id.placeholder")) @@ -35,40 +60,11 @@ const AccessFormBaiduCloudConfig = ({ form: formInst, formName, disabled, initia .min(1, t("access.form.baiducloud_secret_access_key.placeholder")) .max(64, t("common.errmsg.string_max", { max: 64 })), }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- } - > - - - - } - > - - -
- ); }; -export default AccessFormBaiduCloudConfig; +const _default = Object.assign(AccessConfigFormFieldsProviderBaiduCloud, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/forms/AccessConfigFieldsProviderBaishan.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderBaishan.tsx new file mode 100644 index 000000000..93aff79e9 --- /dev/null +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderBaishan.tsx @@ -0,0 +1,49 @@ +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { useFormNestedFieldsContext } from "./_context"; + +const AccessConfigFormFieldsProviderBaishan = () => { + const { i18n, t } = useTranslation(); + + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); + + return ( + <> + + + + + ); +}; + +const getInitialValues = (): Nullish>> => { + return { + apiToken: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + apiToken: z + .string() + .min(1, t("access.form.baishan_api_token.placeholder")) + .max(64, t("common.errmsg.string_max", { max: 64 })), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderBaishan, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/forms/AccessConfigFieldsProviderBaotaPanel.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderBaotaPanel.tsx new file mode 100644 index 000000000..c5eca4b5f --- /dev/null +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderBaotaPanel.tsx @@ -0,0 +1,76 @@ +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input, Switch } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { useFormNestedFieldsContext } from "./_context"; + +const AccessConfigFormFieldsProviderBaotaPanel = () => { + const { i18n, t } = useTranslation(); + + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); + + return ( + <> + + + + + } + > + + + + + + + + ); +}; + +const getInitialValues = (): Nullish>> => { + return { + serverUrl: "http://:8888/", + apiKey: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + serverUrl: z.url(t("common.errmsg.url_invalid")), + apiKey: z.string().nonempty(t("access.form.baotapanel_api_key.placeholder")), + allowInsecureConnections: z.boolean().nullish(), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderBaotaPanel, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/forms/AccessConfigFieldsProviderBaotaWAF.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderBaotaWAF.tsx new file mode 100644 index 000000000..dc4cd4229 --- /dev/null +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderBaotaWAF.tsx @@ -0,0 +1,76 @@ +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input, Switch } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { useFormNestedFieldsContext } from "./_context"; + +const AccessConfigFormFieldsProviderBaotaWAF = () => { + const { i18n, t } = useTranslation(); + + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); + + return ( + <> + + + + + } + > + + + + + + + + ); +}; + +const getInitialValues = (): Nullish>> => { + return { + serverUrl: "http://:8379/", + apiKey: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + serverUrl: z.url(t("common.errmsg.url_invalid")), + apiKey: z.string().nonempty(t("access.form.baotawaf_api_key.placeholder")), + allowInsecureConnections: z.boolean().nullish(), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderBaotaWAF, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/forms/AccessConfigFieldsProviderBunny.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderBunny.tsx new file mode 100644 index 000000000..208af0396 --- /dev/null +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderBunny.tsx @@ -0,0 +1,52 @@ +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { useFormNestedFieldsContext } from "./_context"; + +const AccessConfigFormFieldsProviderBunny = () => { + const { i18n, t } = useTranslation(); + + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); + + return ( + <> + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { + return { + apiKey: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + apiKey: z.string().nonempty(t("access.form.bunny_api_key.placeholder")), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderBunny, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormBytePlusConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderBytePlus.tsx similarity index 52% rename from ui/src/components/access/AccessFormBytePlusConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderBytePlus.tsx index dea9fd62e..daf88ca54 100644 --- a/ui/src/components/access/AccessFormBytePlusConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderBytePlus.tsx @@ -1,31 +1,56 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForBytePlus } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormBytePlusConfigFieldValues = Nullish; +const AccessConfigFormFieldsProviderBytePlus = () => { + const { i18n, t } = useTranslation(); -export interface AccessFormBytePlusConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormBytePlusConfigFieldValues; - onValuesChange?: (values: AccessFormBytePlusConfigFieldValues) => void; -} + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); -const initFormModel = (): AccessFormBytePlusConfigFieldValues => { + return ( + <> + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { return { accessKey: "", secretKey: "", }; }; -const AccessFormBytePlusConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormBytePlusConfigProps) => { - const { t } = useTranslation(); +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; - const formSchema = z.object({ + return z.object({ accessKey: z .string() .min(1, t("access.form.byteplus_access_key.placeholder")) @@ -35,40 +60,11 @@ const AccessFormBytePlusConfig = ({ form: formInst, formName, disabled, initialV .min(1, t("access.form.byteplus_secret_key.placeholder")) .max(64, t("common.errmsg.string_max", { max: 64 })), }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- } - > - - - - } - > - - -
- ); }; -export default AccessFormBytePlusConfig; +const _default = Object.assign(AccessConfigFormFieldsProviderBytePlus, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormCMCCCloudConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderCMCCCloud.tsx similarity index 53% rename from ui/src/components/access/AccessFormCMCCCloudConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderCMCCCloud.tsx index 9d2912fed..280c90672 100644 --- a/ui/src/components/access/AccessFormCMCCCloudConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderCMCCCloud.tsx @@ -1,30 +1,56 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForCMCCCloud } from "@/domain/access"; -type AccessFormCMCCCloudConfigFieldValues = Nullish; +import { useFormNestedFieldsContext } from "./_context"; -export interface AccessFormCMCCCloudConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormCMCCCloudConfigFieldValues; - onValuesChange?: (values: AccessFormCMCCCloudConfigFieldValues) => void; -} +const AccessConfigFormFieldsProviderCMCCCloud = () => { + const { i18n, t } = useTranslation(); -const initFormModel = (): AccessFormCMCCCloudConfigFieldValues => { + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); + + return ( + <> + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { return { accessKeyId: "", accessKeySecret: "", }; }; -const AccessFormCMCCCloudConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange: onValuesChange }: AccessFormCMCCCloudConfigProps) => { - const { t } = useTranslation(); +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; - const formSchema = z.object({ + return z.object({ accessKeyId: z .string() .min(1, t("access.form.cmcccloud_access_key_id.placeholder")) @@ -34,40 +60,11 @@ const AccessFormCMCCCloudConfig = ({ form: formInst, formName, disabled, initial .min(1, t("access.form.cmcccloud_access_key_secret.placeholder")) .max(64, t("common.errmsg.string_max", { max: 64 })), }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- } - > - - - - } - > - - -
- ); }; -export default AccessFormCMCCCloudConfig; +const _default = Object.assign(AccessConfigFormFieldsProviderCMCCCloud, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormCTCCCloudConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderCTCCCloud.tsx similarity index 53% rename from ui/src/components/access/AccessFormCTCCCloudConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderCTCCCloud.tsx index 9284e17bf..7beb283e3 100644 --- a/ui/src/components/access/AccessFormCTCCCloudConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderCTCCCloud.tsx @@ -1,30 +1,56 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForCTCCCloud } from "@/domain/access"; -type AccessFormCTCCCloudConfigFieldValues = Nullish; +import { useFormNestedFieldsContext } from "./_context"; -export interface AccessFormCTCCCloudConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormCTCCCloudConfigFieldValues; - onValuesChange?: (values: AccessFormCTCCCloudConfigFieldValues) => void; -} +const AccessConfigFormFieldsProviderCTCCCloud = () => { + const { i18n, t } = useTranslation(); -const initFormModel = (): AccessFormCTCCCloudConfigFieldValues => { + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); + + return ( + <> + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { return { accessKeyId: "", secretAccessKey: "", }; }; -const AccessFormCTCCCloudConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange: onValuesChange }: AccessFormCTCCCloudConfigProps) => { - const { t } = useTranslation(); +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; - const formSchema = z.object({ + return z.object({ accessKeyId: z .string() .min(1, t("access.form.ctcccloud_access_key_id.placeholder")) @@ -34,40 +60,11 @@ const AccessFormCTCCCloudConfig = ({ form: formInst, formName, disabled, initial .min(1, t("access.form.ctcccloud_secret_access_key.placeholder")) .max(64, t("common.errmsg.string_max", { max: 64 })), }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- } - > - - - - } - > - - -
- ); }; -export default AccessFormCTCCCloudConfig; +const _default = Object.assign(AccessConfigFormFieldsProviderCTCCCloud, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/forms/AccessConfigFieldsProviderCacheFly.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderCacheFly.tsx new file mode 100644 index 000000000..769001718 --- /dev/null +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderCacheFly.tsx @@ -0,0 +1,46 @@ +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { useFormNestedFieldsContext } from "./_context"; + +const AccessConfigFormFieldsProviderCacheFly = () => { + const { i18n, t } = useTranslation(); + + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); + + return ( + <> + + + + + ); +}; + +const getInitialValues = (): Nullish>> => { + return { + apiToken: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + apiToken: z.string().nonempty(t("access.form.cachefly_api_token.placeholder")), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderCacheFly, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormCdnflyConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderCdnfly.tsx similarity index 55% rename from ui/src/components/access/AccessFormCdnflyConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderCdnfly.tsx index 43fdade8a..7877b2ac6 100644 --- a/ui/src/components/access/AccessFormCdnflyConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderCdnfly.tsx @@ -1,21 +1,67 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input, Switch } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input, Switch } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForCdnfly } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormCdnflyConfigFieldValues = Nullish; +const AccessConfigFormFieldsProviderCdnfly = () => { + const { i18n, t } = useTranslation(); -export interface AccessFormCdnflyConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormCdnflyConfigFieldValues; - onValuesChange?: (values: AccessFormCdnflyConfigFieldValues) => void; -} + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); -const initFormModel = (): AccessFormCdnflyConfigFieldValues => { + return ( + <> + + + + + } + > + + + + } + > + + + + + + + + ); +}; + +const getInitialValues = (): Nullish>> => { return { serverUrl: "http://:88/", apiKey: "", @@ -23,10 +69,10 @@ const initFormModel = (): AccessFormCdnflyConfigFieldValues => { }; }; -const AccessFormCdnflyConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormCdnflyConfigProps) => { - const { t } = useTranslation(); +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; - const formSchema = z.object({ + return z.object({ serverUrl: z.url(t("common.errmsg.url_invalid")), apiKey: z .string() @@ -38,51 +84,11 @@ const AccessFormCdnflyConfig = ({ form: formInst, formName, disabled, initialVal .max(64, t("common.errmsg.string_max", { max: 64 })), allowInsecureConnections: z.boolean().nullish(), }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- - - - - } - > - - - - } - > - - - - - - -
- ); }; -export default AccessFormCdnflyConfig; +const _default = Object.assign(AccessConfigFormFieldsProviderCdnfly, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormClouDNSConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderClouDNS.tsx similarity index 52% rename from ui/src/components/access/AccessFormClouDNSConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderClouDNS.tsx index d8048ec4e..0efdf49ce 100644 --- a/ui/src/components/access/AccessFormClouDNSConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderClouDNS.tsx @@ -1,31 +1,56 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForClouDNS } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormClouDNSConfigFieldValues = Nullish; +const AccessConfigFormFieldsProviderClouDNS = () => { + const { i18n, t } = useTranslation(); -export interface AccessFormClouDNSConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormClouDNSConfigFieldValues; - onValuesChange?: (values: AccessFormClouDNSConfigFieldValues) => void; -} + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); -const initFormModel = (): AccessFormClouDNSConfigFieldValues => { + return ( + <> + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { return { authId: "", authPassword: "", }; }; -const AccessFormClouDNSConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormClouDNSConfigProps) => { - const { t } = useTranslation(); +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; - const formSchema = z.object({ + return z.object({ authId: z .string() .min(1, t("access.form.cloudns_auth_id.placeholder")) @@ -35,40 +60,11 @@ const AccessFormClouDNSConfig = ({ form: formInst, formName, disabled, initialVa .min(1, t("access.form.cloudns_auth_password.placeholder")) .max(64, t("common.errmsg.string_max", { max: 64 })), }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- } - > - - - - } - > - - -
- ); }; -export default AccessFormClouDNSConfig; +const _default = Object.assign(AccessConfigFormFieldsProviderClouDNS, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormCloudflareConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderCloudflare.tsx similarity index 52% rename from ui/src/components/access/AccessFormCloudflareConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderCloudflare.tsx index 14e384cfa..cbb72b75f 100644 --- a/ui/src/components/access/AccessFormCloudflareConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderCloudflare.tsx @@ -1,30 +1,55 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForCloudflare } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormCloudflareConfigFieldValues = Nullish; +const AccessConfigFormFieldsProviderCloudflare = () => { + const { i18n, t } = useTranslation(); -export interface AccessFormCloudflareConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormCloudflareConfigFieldValues; - onValuesChange?: (values: AccessFormCloudflareConfigFieldValues) => void; -} + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); -const initFormModel = (): AccessFormCloudflareConfigFieldValues => { + return ( + <> + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { return { dnsApiToken: "", }; }; -const AccessFormCloudflareConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormCloudflareConfigProps) => { - const { t } = useTranslation(); +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; - const formSchema = z.object({ + return z.object({ dnsApiToken: z .string() .min(1, t("access.form.cloudflare_dns_api_token.placeholder")) @@ -34,40 +59,11 @@ const AccessFormCloudflareConfig = ({ form: formInst, formName, disabled, initia .max(64, t("common.errmsg.string_max", { max: 64 })) .nullish(), }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- } - > - - - - } - > - - -
- ); }; -export default AccessFormCloudflareConfig; +const _default = Object.assign(AccessConfigFormFieldsProviderCloudflare, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/forms/AccessConfigFieldsProviderConstellix.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderConstellix.tsx new file mode 100644 index 000000000..4ca6c1132 --- /dev/null +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderConstellix.tsx @@ -0,0 +1,64 @@ +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { useFormNestedFieldsContext } from "./_context"; + +const AccessConfigFormFieldsProviderConstellix = () => { + const { i18n, t } = useTranslation(); + + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); + + return ( + <> + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { + return { + apiKey: "", + secretKey: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + apiKey: z.string().nonempty(t("access.form.constellix_api_key.placeholder")), + secretKey: z.string().nonempty(t("access.form.constellix_secret_key.placeholder")), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderConstellix, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormDNSLAConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderDNSLA.tsx similarity index 52% rename from ui/src/components/access/AccessFormDNSLAConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderDNSLA.tsx index c3fc6d80b..dce2b407f 100644 --- a/ui/src/components/access/AccessFormDNSLAConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderDNSLA.tsx @@ -1,31 +1,56 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForDNSLA } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormDNSLAConfigFieldValues = Nullish; +const AccessConfigFormFieldsProviderDNSLA = () => { + const { i18n, t } = useTranslation(); -export interface AccessFormDNSLAConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormDNSLAConfigFieldValues; - onValuesChange?: (values: AccessFormDNSLAConfigFieldValues) => void; -} + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); -const initFormModel = (): AccessFormDNSLAConfigFieldValues => { + return ( + <> + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { return { apiId: "", apiSecret: "", }; }; -const AccessFormDNSLAConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange: onValuesChange }: AccessFormDNSLAConfigProps) => { - const { t } = useTranslation(); +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; - const formSchema = z.object({ + return z.object({ apiId: z .string() .min(1, t("access.form.dnsla_api_id.placeholder")) @@ -35,40 +60,11 @@ const AccessFormDNSLAConfig = ({ form: formInst, formName, disabled, initialValu .min(1, t("access.form.dnsla_api_secret.placeholder")) .max(64, t("common.errmsg.string_max", { max: 64 })), }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- } - > - - - - } - > - - -
- ); }; -export default AccessFormDNSLAConfig; +const _default = Object.assign(AccessConfigFormFieldsProviderDNSLA, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/forms/AccessConfigFieldsProviderDeSEC.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderDeSEC.tsx new file mode 100644 index 000000000..8a8110fd3 --- /dev/null +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderDeSEC.tsx @@ -0,0 +1,55 @@ +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { useFormNestedFieldsContext } from "./_context"; + +const AccessConfigFormFieldsProviderDeSEC = () => { + const { i18n, t } = useTranslation(); + + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); + + return ( + <> + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { + return { + token: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + token: z + .string() + .min(1, t("access.form.desec_token.placeholder")) + .max(256, t("common.errmsg.string_max", { max: 256 })), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderDeSEC, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/forms/AccessConfigFieldsProviderDigitalOcean.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderDigitalOcean.tsx new file mode 100644 index 000000000..22f9c3bef --- /dev/null +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderDigitalOcean.tsx @@ -0,0 +1,52 @@ +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { useFormNestedFieldsContext } from "./_context"; + +const AccessConfigFormFieldsProviderDigitalOcean = () => { + const { i18n, t } = useTranslation(); + + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); + + return ( + <> + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { + return { + accessToken: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + accessToken: z.string().nonempty(t("access.form.digitalocean_access_token.placeholder")), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderDigitalOcean, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/forms/AccessConfigFieldsProviderDingTalkBot.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderDingTalkBot.tsx new file mode 100644 index 000000000..c9c8591d9 --- /dev/null +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderDingTalkBot.tsx @@ -0,0 +1,64 @@ +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { useFormNestedFieldsContext } from "./_context"; + +const AccessConfigFormFieldsProviderDingTalkBot = () => { + const { i18n, t } = useTranslation(); + + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); + + return ( + <> + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { + return { + webhookUrl: "", + secret: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + webhookUrl: z.url(t("common.errmsg.url_invalid")), + secret: z.string().nonempty(t("access.form.dingtalkbot_secret.placeholder")), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderDingTalkBot, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormDiscordBotConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderDiscordBot.tsx similarity index 50% rename from ui/src/components/access/AccessFormDiscordBotConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderDiscordBot.tsx index bef914805..8abfbc021 100644 --- a/ui/src/components/access/AccessFormDiscordBotConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderDiscordBot.tsx @@ -1,53 +1,25 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForDiscordBot } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormDiscordBotConfigFieldValues = Nullish; - -export interface AccessFormDiscordBotConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormDiscordBotConfigFieldValues; - onValuesChange?: (values: AccessFormDiscordBotConfigFieldValues) => void; -} - -const initFormModel = (): AccessFormDiscordBotConfigFieldValues => { - return { - botToken: "", - }; -}; - -const AccessFormDiscordBotConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormDiscordBotConfigProps) => { - const { t } = useTranslation(); +const AccessConfigFormFieldsProviderDiscordBot = () => { + const { i18n, t } = useTranslation(); + const { parentNamePath } = useFormNestedFieldsContext(); const formSchema = z.object({ - botToken: z - .string() - .min(1, t("access.form.discordbot_token.placeholder")) - .max(256, t("common.errmsg.string_max", { max: 256 })), - channelId: z.string().nullish(), + [parentNamePath]: getSchema({ i18n }), }); const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; + const initialValues = getInitialValues(); return ( -
+ <> } @@ -56,7 +28,8 @@ const AccessFormDiscordBotConfig = ({ form: formInst, formName, disabled, initia -
+ ); }; -export default AccessFormDiscordBotConfig; +const getInitialValues = (): Nullish>> => { + return { + botToken: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + botToken: z + .string() + .min(1, t("access.form.discordbot_token.placeholder")) + .max(256, t("common.errmsg.string_max", { max: 256 })), + channelId: z.string().nullish(), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderDiscordBot, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormDogeCloudConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderDogeCloud.tsx similarity index 52% rename from ui/src/components/access/AccessFormDogeCloudConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderDogeCloud.tsx index b23a399d8..69fa743b7 100644 --- a/ui/src/components/access/AccessFormDogeCloudConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderDogeCloud.tsx @@ -1,31 +1,56 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForDogeCloud } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormDogeCloudConfigFieldValues = Nullish; +const AccessConfigFormFieldsProviderDogeCloud = () => { + const { i18n, t } = useTranslation(); -export interface AccessFormDogeCloudConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormDogeCloudConfigFieldValues; - onValuesChange?: (values: AccessFormDogeCloudConfigFieldValues) => void; -} + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); -const initFormModel = (): AccessFormDogeCloudConfigFieldValues => { + return ( + <> + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { return { accessKey: "", secretKey: "", }; }; -const AccessFormDogeCloudConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormDogeCloudConfigProps) => { - const { t } = useTranslation(); +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; - const formSchema = z.object({ + return z.object({ accessKey: z .string() .min(1, t("access.form.dogecloud_access_key.placeholder")) @@ -35,40 +60,11 @@ const AccessFormDogeCloudConfig = ({ form: formInst, formName, disabled, initial .min(1, t("access.form.dogecloud_secret_key.placeholder")) .max(64, t("common.errmsg.string_max", { max: 64 })), }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- } - > - - - - } - > - - -
- ); }; -export default AccessFormDogeCloudConfig; +const _default = Object.assign(AccessConfigFormFieldsProviderDogeCloud, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/forms/AccessConfigFieldsProviderDuckDNS.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderDuckDNS.tsx new file mode 100644 index 000000000..a685a31d6 --- /dev/null +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderDuckDNS.tsx @@ -0,0 +1,52 @@ +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { useFormNestedFieldsContext } from "./_context"; + +const AccessConfigFormFieldsProviderDuckDNS = () => { + const { i18n, t } = useTranslation(); + + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); + + return ( + <> + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { + return { + token: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + token: z.string().nonempty(t("access.form.duckdns_token.placeholder")), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderDuckDNS, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/forms/AccessConfigFieldsProviderDynv6.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderDynv6.tsx new file mode 100644 index 000000000..3b23629a4 --- /dev/null +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderDynv6.tsx @@ -0,0 +1,55 @@ +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { useFormNestedFieldsContext } from "./_context"; + +const AccessConfigFormFieldsProviderDynv6 = () => { + const { i18n, t } = useTranslation(); + + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); + + return ( + <> + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { + return { + httpToken: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + httpToken: z + .string() + .min(1, t("access.form.dynv6_http_token.placeholder")) + .max(256, t("common.errmsg.string_max", { max: 256 })), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderDynv6, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormEdgioConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderEdgio.tsx similarity index 53% rename from ui/src/components/access/AccessFormEdgioConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderEdgio.tsx index d97430db0..036b7f468 100644 --- a/ui/src/components/access/AccessFormEdgioConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderEdgio.tsx @@ -1,31 +1,56 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForEdgio } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormEdgioConfigFieldValues = Nullish; +const AccessConfigFormFieldsProviderEdgio = () => { + const { i18n, t } = useTranslation(); -export interface AccessFormEdgioConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormEdgioConfigFieldValues; - onValuesChange?: (values: AccessFormEdgioConfigFieldValues) => void; -} + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); -const initFormModel = (): AccessFormEdgioConfigFieldValues => { + return ( + <> + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { return { clientId: "", clientSecret: "", }; }; -const AccessFormEdgioConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormEdgioConfigProps) => { - const { t } = useTranslation(); +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; - const formSchema = z.object({ + return z.object({ clientId: z .string() .min(1, t("access.form.edgio_client_id.placeholder")) @@ -35,40 +60,11 @@ const AccessFormEdgioConfig = ({ form: formInst, formName, disabled, initialValu .min(1, t("access.form.edgio_client_secret.placeholder")) .max(64, t("common.errmsg.string_max", { max: 64 })), }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- } - > - - - - } - > - - -
- ); }; -export default AccessFormEdgioConfig; +const _default = Object.assign(AccessConfigFormFieldsProviderEdgio, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormEmailConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderEmail.tsx similarity index 57% rename from ui/src/components/access/AccessFormEmailConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderEmail.tsx index 95148f793..378f0d3c5 100644 --- a/ui/src/components/access/AccessFormEmailConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderEmail.tsx @@ -1,22 +1,101 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input, InputNumber, Switch } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input, InputNumber, Switch } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForEmail } from "@/domain/access"; import { validEmailAddress, validPortNumber } from "@/utils/validators"; -type AccessFormEmailConfigFieldValues = Nullish; +import { useFormNestedFieldsContext } from "./_context"; -export interface AccessFormEmailConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormEmailConfigFieldValues; - onValuesChange?: (values: AccessFormEmailConfigFieldValues) => void; -} +const AccessConfigFormFieldsProviderEmail = () => { + const { i18n, t } = useTranslation(); -const initFormModel = (): AccessFormEmailConfigFieldValues => { + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const formInst = Form.useFormInstance(); + const initialValues = getInitialValues(); + + const handleTlsSwitchChange = (checked: boolean) => { + const oldPort = formInst.getFieldValue("smtpPort"); + const newPort = checked && (oldPort == null || oldPort === 25) ? 465 : !checked && (oldPort == null || oldPort === 465) ? 25 : oldPort; + if (newPort !== oldPort) { + formInst.setFieldValue("smtpPort", newPort); + } + }; + + return ( + <> +
+
+ + + +
+ +
+ + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; + +const getInitialValues = (): Nullish>> => { return { smtpHost: "", smtpPort: 465, @@ -29,10 +108,10 @@ const initFormModel = (): AccessFormEmailConfigFieldValues => { }; }; -const AccessFormEmailConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormEmailConfigProps) => { - const { t } = useTranslation(); +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; - const formSchema = z.object({ + return z.object({ smtpHost: z .string() .min(1, t("access.form.email_smtp_host.placeholder")) @@ -60,73 +139,11 @@ const AccessFormEmailConfig = ({ form: formInst, formName, disabled, initialValu return validEmailAddress(v); }, t("common.errmsg.email_invalid")), }); - const formRule = createSchemaFieldRule(formSchema); - - const handleTlsSwitchChange = (checked: boolean) => { - const oldPort = formInst.getFieldValue("smtpPort"); - const newPort = checked && (oldPort == null || oldPort === 25) ? 465 : !checked && (oldPort == null || oldPort === 465) ? 25 : oldPort; - if (newPort !== oldPort) { - formInst.setFieldValue("smtpPort", newPort); - } - }; - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
-
-
- - - -
- -
- - - -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- ); }; -export default AccessFormEmailConfig; +const _default = Object.assign(AccessConfigFormFieldsProviderEmail, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormFlexCDNConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderFlexCDN.tsx similarity index 52% rename from ui/src/components/access/AccessFormFlexCDNConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderFlexCDN.tsx index 59ff94111..898f483e6 100644 --- a/ui/src/components/access/AccessFormFlexCDNConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderFlexCDN.tsx @@ -1,64 +1,38 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input, Radio, Switch } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input, Radio, Switch } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForFlexCDN } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormFlexCDNConfigFieldValues = Nullish; - -export interface AccessFormFlexCDNConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormFlexCDNConfigFieldValues; - onValuesChange?: (values: AccessFormFlexCDNConfigFieldValues) => void; -} - -const initFormModel = (): AccessFormFlexCDNConfigFieldValues => { - return { - serverUrl: "http://:8000/", - apiRole: "user", - accessKeyId: "", - accessKey: "", - }; -}; - -const AccessFormFlexCDNConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormFlexCDNConfigProps) => { - const { t } = useTranslation(); +const AccessConfigFormFieldsProviderFlexCDN = () => { + const { i18n, t } = useTranslation(); + const { parentNamePath } = useFormNestedFieldsContext(); const formSchema = z.object({ - serverUrl: z.url(t("common.errmsg.url_invalid")), - role: z.literal(["user", "admin"], t("access.form.flexcdn_api_role.placeholder")), - accessKeyId: z.string().nonempty(t("access.form.flexcdn_access_key_id.placeholder")), - accessKey: z.string().nonempty(t("access.form.flexcdn_access_key.placeholder")), - allowInsecureConnections: z.boolean().nullish(), + [parentNamePath]: getSchema({ i18n }), }); const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; + const initialValues = getInitialValues(); return ( -
- + <> + - + ({ label: t(`access.form.flexcdn_api_role.option.${s}.label`), value: s }))} /> } @@ -67,7 +41,8 @@ const AccessFormFlexCDNConfig = ({ form: formInst, formName, disabled, initialVa } @@ -75,14 +50,45 @@ const AccessFormFlexCDNConfig = ({ form: formInst, formName, disabled, initialVa - + - + ); }; -export default AccessFormFlexCDNConfig; +const getInitialValues = (): Nullish>> => { + return { + serverUrl: "http://:8000/", + apiRole: "user", + accessKeyId: "", + accessKey: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + serverUrl: z.url(t("common.errmsg.url_invalid")), + apiRole: z.literal(["user", "admin"], t("access.form.flexcdn_api_role.placeholder")), + accessKeyId: z.string().nonempty(t("access.form.flexcdn_access_key_id.placeholder")), + accessKey: z.string().nonempty(t("access.form.flexcdn_access_key.placeholder")), + allowInsecureConnections: z.boolean().nullish(), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderFlexCDN, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/forms/AccessConfigFieldsProviderGcore.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderGcore.tsx new file mode 100644 index 000000000..e39ac98bc --- /dev/null +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderGcore.tsx @@ -0,0 +1,55 @@ +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { useFormNestedFieldsContext } from "./_context"; + +const AccessConfigFormFieldsProviderGcore = () => { + const { i18n, t } = useTranslation(); + + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); + + return ( + <> + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { + return { + apiToken: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + apiToken: z + .string() + .min(1, t("access.form.gcore_api_token.placeholder")) + .max(256, t("common.errmsg.string_max", { max: 256 })), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderGcore, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormGnameConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderGname.tsx similarity index 52% rename from ui/src/components/access/AccessFormGnameConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderGname.tsx index 1cf716a10..746187601 100644 --- a/ui/src/components/access/AccessFormGnameConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderGname.tsx @@ -1,31 +1,56 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForGname } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormGnameConfigFieldValues = Nullish; +const AccessConfigFormFieldsProviderGname = () => { + const { i18n, t } = useTranslation(); -export interface AccessFormGnameConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormGnameConfigFieldValues; - onValuesChange?: (values: AccessFormGnameConfigFieldValues) => void; -} + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); -const initFormModel = (): AccessFormGnameConfigFieldValues => { + return ( + <> + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { return { appId: "", appKey: "", }; }; -const AccessFormGnameConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormGnameConfigProps) => { - const { t } = useTranslation(); +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; - const formSchema = z.object({ + return z.object({ appId: z .string() .min(1, t("access.form.gname_app_id.placeholder")) @@ -35,40 +60,11 @@ const AccessFormGnameConfig = ({ form: formInst, formName, disabled, initialValu .min(1, t("access.form.gname_app_key.placeholder")) .max(64, t("common.errmsg.string_max", { max: 64 })), }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- } - > - - - - } - > - - -
- ); }; -export default AccessFormGnameConfig; +const _default = Object.assign(AccessConfigFormFieldsProviderGname, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormGoDaddyConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderGoDaddy.tsx similarity index 52% rename from ui/src/components/access/AccessFormGoDaddyConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderGoDaddy.tsx index f71d1e854..3dd30815c 100644 --- a/ui/src/components/access/AccessFormGoDaddyConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderGoDaddy.tsx @@ -1,31 +1,56 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForGoDaddy } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormGoDaddyConfigFieldValues = Nullish; +const AccessConfigFormFieldsProviderGoDaddy = () => { + const { i18n, t } = useTranslation(); -export interface AccessFormGoDaddyConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormGoDaddyConfigFieldValues; - onValuesChange?: (values: AccessFormGoDaddyConfigFieldValues) => void; -} + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); -const initFormModel = (): AccessFormGoDaddyConfigFieldValues => { + return ( + <> + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { return { apiKey: "", apiSecret: "", }; }; -const AccessFormGoDaddyConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormGoDaddyConfigProps) => { - const { t } = useTranslation(); +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; - const formSchema = z.object({ + return z.object({ apiKey: z .string() .min(1, t("access.form.godaddy_api_key.placeholder")) @@ -35,40 +60,11 @@ const AccessFormGoDaddyConfig = ({ form: formInst, formName, disabled, initialVa .min(1, t("access.form.godaddy_api_secret.placeholder")) .max(64, t("common.errmsg.string_max", { max: 64 })), }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- } - > - - - - } - > - - -
- ); }; -export default AccessFormGoDaddyConfig; +const _default = Object.assign(AccessConfigFormFieldsProviderGoDaddy, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormGoEdgeConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderGoEdge.tsx similarity index 52% rename from ui/src/components/access/AccessFormGoEdgeConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderGoEdge.tsx index affc32822..5f285f6a3 100644 --- a/ui/src/components/access/AccessFormGoEdgeConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderGoEdge.tsx @@ -1,64 +1,38 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input, Radio, Switch } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input, Radio, Switch } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForGoEdge } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormGoEdgeConfigFieldValues = Nullish; - -export interface AccessFormGoEdgeConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormGoEdgeConfigFieldValues; - onValuesChange?: (values: AccessFormGoEdgeConfigFieldValues) => void; -} - -const initFormModel = (): AccessFormGoEdgeConfigFieldValues => { - return { - serverUrl: "http://:7788/", - apiRole: "user", - accessKeyId: "", - accessKey: "", - }; -}; - -const AccessFormGoEdgeConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormGoEdgeConfigProps) => { - const { t } = useTranslation(); +const AccessConfigFormFieldsProviderGoEdge = () => { + const { i18n, t } = useTranslation(); + const { parentNamePath } = useFormNestedFieldsContext(); const formSchema = z.object({ - serverUrl: z.url(t("common.errmsg.url_invalid")), - role: z.literal(["user", "admin"], t("access.form.goedge_api_role.placeholder")), - accessKeyId: z.string().nonempty(t("access.form.goedge_access_key_id.placeholder")), - accessKey: z.string().nonempty(t("access.form.goedge_access_key.placeholder")), - allowInsecureConnections: z.boolean().nullish(), + [parentNamePath]: getSchema({ i18n }), }); const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; + const initialValues = getInitialValues(); return ( -
- + <> + - + ({ label: t(`access.form.goedge_api_role.option.${s}.label`), value: s }))} /> } @@ -67,7 +41,8 @@ const AccessFormGoEdgeConfig = ({ form: formInst, formName, disabled, initialVal } @@ -75,14 +50,45 @@ const AccessFormGoEdgeConfig = ({ form: formInst, formName, disabled, initialVal - + - + ); }; -export default AccessFormGoEdgeConfig; +const getInitialValues = (): Nullish>> => { + return { + serverUrl: "http://:7788/", + apiRole: "user", + accessKeyId: "", + accessKey: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + serverUrl: z.url(t("common.errmsg.url_invalid")), + apiRole: z.literal(["user", "admin"], t("access.form.goedge_api_role.placeholder")), + accessKeyId: z.string().nonempty(t("access.form.goedge_access_key_id.placeholder")), + accessKey: z.string().nonempty(t("access.form.goedge_access_key.placeholder")), + allowInsecureConnections: z.boolean().nullish(), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderGoEdge, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormGoogleTrustServicesConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderGoogleTrustServices.tsx similarity index 51% rename from ui/src/components/access/AccessFormGoogleTrustServicesConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderGoogleTrustServices.tsx index 36d576a1c..4f5da5b5d 100644 --- a/ui/src/components/access/AccessFormGoogleTrustServicesConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderGoogleTrustServices.tsx @@ -1,37 +1,56 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForGoogleTrustServices } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormGoogleTrustServicesConfigFieldValues = Nullish; +const AccessConfigFormFieldsProviderGoogleTrustServices = () => { + const { i18n, t } = useTranslation(); -export interface AccessFormGoogleTrustServicesConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormGoogleTrustServicesConfigFieldValues; - onValuesChange?: (values: AccessFormGoogleTrustServicesConfigFieldValues) => void; -} + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); -const initFormModel = (): AccessFormGoogleTrustServicesConfigFieldValues => { + return ( + <> + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { return { eabKid: "", eabHmacKey: "", }; }; -const AccessFormGoogleTrustServicesConfig = ({ - form: formInst, - formName, - disabled, - initialValues, - onValuesChange, -}: AccessFormGoogleTrustServicesConfigProps) => { - const { t } = useTranslation(); +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; - const formSchema = z.object({ + return z.object({ eabKid: z .string() .min(1, t("access.form.googletrustservices_eab_kid.placeholder")) @@ -41,40 +60,11 @@ const AccessFormGoogleTrustServicesConfig = ({ .min(1, t("access.form.googletrustservices_eab_hmac_key.placeholder")) .max(256, t("common.errmsg.string_max", { max: 256 })), }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- } - > - - - - } - > - - -
- ); }; -export default AccessFormGoogleTrustServicesConfig; +const _default = Object.assign(AccessConfigFormFieldsProviderGoogleTrustServices, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/forms/AccessConfigFieldsProviderHetzner.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderHetzner.tsx new file mode 100644 index 000000000..b4e275fe9 --- /dev/null +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderHetzner.tsx @@ -0,0 +1,52 @@ +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { useFormNestedFieldsContext } from "./_context"; + +const AccessConfigFormFieldsProviderHetzner = () => { + const { i18n, t } = useTranslation(); + + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); + + return ( + <> + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { + return { + apiToken: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + apiToken: z.string().nonempty(t("access.form.hetzner_api_token.placeholder")), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderHetzner, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormHuaweiCloudConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderHuaweiCloud.tsx similarity index 59% rename from ui/src/components/access/AccessFormHuaweiCloudConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderHuaweiCloud.tsx index 82486ae12..279703835 100644 --- a/ui/src/components/access/AccessFormHuaweiCloudConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderHuaweiCloud.tsx @@ -1,31 +1,66 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForHuaweiCloud } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormHuaweiCloudConfigFieldValues = Nullish; +const AccessConfigFormFieldsProviderHuaweiCloud = () => { + const { i18n, t } = useTranslation(); -export interface AccessFormHuaweiCloudConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormHuaweiCloudConfigFieldValues; - onValuesChange?: (values: AccessFormHuaweiCloudConfigFieldValues) => void; -} + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); -const initFormModel = (): AccessFormHuaweiCloudConfigFieldValues => { + return ( + <> + } + > + + + + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { return { accessKeyId: "", secretAccessKey: "", }; }; -const AccessFormHuaweiCloudConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormHuaweiCloudConfigProps) => { - const { t } = useTranslation(); +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; - const formSchema = z.object({ + return z.object({ accessKeyId: z .string() .min(1, t("access.form.huaweicloud_access_key_id.placeholder")) @@ -36,49 +71,11 @@ const AccessFormHuaweiCloudConfig = ({ form: formInst, formName, disabled, initi .max(64, t("common.errmsg.string_max", { max: 64 })), enterpriseProjectId: z.string().nullish(), }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- } - > - - - - } - > - - - - } - > - - -
- ); }; -export default AccessFormHuaweiCloudConfig; +const _default = Object.assign(AccessConfigFormFieldsProviderHuaweiCloud, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormJDCloudConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderJDCloud.tsx similarity index 53% rename from ui/src/components/access/AccessFormJDCloudConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderJDCloud.tsx index ca1bdcc93..4a58c29ce 100644 --- a/ui/src/components/access/AccessFormJDCloudConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderJDCloud.tsx @@ -1,31 +1,56 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForJDCloud } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormJDCloudConfigFieldValues = Nullish; +const AccessConfigFormFieldsProviderJDCloud = () => { + const { i18n, t } = useTranslation(); -export interface AccessFormJDCloudConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormJDCloudConfigFieldValues; - onValuesChange?: (values: AccessFormJDCloudConfigFieldValues) => void; -} + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); -const initFormModel = (): AccessFormJDCloudConfigFieldValues => { + return ( + <> + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { return { accessKeyId: "", accessKeySecret: "", }; }; -const AccessFormJDCloudConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange: onValuesChange }: AccessFormJDCloudConfigProps) => { - const { t } = useTranslation(); +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; - const formSchema = z.object({ + return z.object({ accessKeyId: z .string() .min(1, t("access.form.jdcloud_access_key_id.placeholder")) @@ -35,40 +60,11 @@ const AccessFormJDCloudConfig = ({ form: formInst, formName, disabled, initialVa .min(1, t("access.form.jdcloud_access_key_secret.placeholder")) .max(64, t("common.errmsg.string_max", { max: 64 })), }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- } - > - - - - } - > - - -
- ); }; -export default AccessFormJDCloudConfig; +const _default = Object.assign(AccessConfigFormFieldsProviderJDCloud, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/forms/AccessConfigFieldsProviderKong.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderKong.tsx new file mode 100644 index 000000000..1b84b385b --- /dev/null +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderKong.tsx @@ -0,0 +1,71 @@ +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input, Switch } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { useFormNestedFieldsContext } from "./_context"; + +const AccessConfigFormFieldsProviderKong = () => { + const { i18n, t } = useTranslation(); + + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); + + return ( + <> + + + + + } + > + + + + + + + + ); +}; + +const getInitialValues = (): Nullish>> => { + return { + serverUrl: "http://:8001/", + apiToken: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + serverUrl: z.url(t("common.errmsg.url_invalid")), + apiToken: z.string().nullish(), + allowInsecureConnections: z.boolean().nullish(), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderKong, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/forms/AccessConfigFieldsProviderKubernetes.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderKubernetes.tsx new file mode 100644 index 000000000..cb2167c69 --- /dev/null +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderKubernetes.tsx @@ -0,0 +1,56 @@ +import { getI18n, useTranslation } from "react-i18next"; +import { Form } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import TextFileInput from "@/components/TextFileInput"; + +import { useFormNestedFieldsContext } from "./_context"; + +const AccessConfigFormFieldsProviderKubernetes = () => { + const { i18n, t } = useTranslation(); + + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); + + return ( + <> + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { + return {}; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + kubeConfig: z + .string() + .max(20480, t("common.errmsg.string_max", { max: 20480 })) + .nullish(), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderKubernetes, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/forms/AccessConfigFieldsProviderLarkBot.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderLarkBot.tsx new file mode 100644 index 000000000..6966a978f --- /dev/null +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderLarkBot.tsx @@ -0,0 +1,52 @@ +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { useFormNestedFieldsContext } from "./_context"; + +const AccessConfigFormFieldsProviderLarkBot = () => { + const { i18n, t } = useTranslation(); + + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); + + return ( + <> + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { + return { + webhookUrl: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + webhookUrl: z.url(t("common.errmsg.url_invalid")), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderLarkBot, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/forms/AccessConfigFieldsProviderLeCDN.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderLeCDN.tsx new file mode 100644 index 000000000..e008b4a04 --- /dev/null +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderLeCDN.tsx @@ -0,0 +1,88 @@ +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input, Radio, Select, Switch } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { useFormNestedFieldsContext } from "./_context"; + +const AccessConfigFormFieldsProviderLeCDN = () => { + const { i18n, t } = useTranslation(); + + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); + + return ( + <> + + + + + + + + + + + + + + + + + ); +}; + +const getInitialValues = (): Nullish>> => { + return { + serverUrl: "http://:5090/", + apiVersion: "v3", + apiRole: "client", + username: "", + password: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + serverUrl: z.url(t("common.errmsg.url_invalid")), + apiVersion: z.literal(["v3"], t("access.form.lecdn_api_version.placeholder")), + apiRole: z.literal(["client", "master"], t("access.form.lecdn_api_role.placeholder")), + username: z.string().nonempty(t("access.form.lecdn_username.placeholder")), + password: z.string().nonempty(t("access.form.lecdn_password.placeholder")), + allowInsecureConnections: z.boolean().nullish(), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderLeCDN, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormMattermostConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderMattermost.tsx similarity index 52% rename from ui/src/components/access/AccessFormMattermostConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderMattermost.tsx index 881b43b40..05323e4f0 100644 --- a/ui/src/components/access/AccessFormMattermostConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderMattermost.tsx @@ -1,54 +1,25 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForMattermost } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormMattermostConfigFieldValues = Nullish; - -export interface AccessFormMattermostConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormMattermostConfigFieldValues; - onValuesChange?: (values: AccessFormMattermostConfigFieldValues) => void; -} - -const initFormModel = (): AccessFormMattermostConfigFieldValues => { - return { - serverUrl: "http://:8065/", - username: "", - password: "", - }; -}; - -const AccessFormMattermostConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormMattermostConfigProps) => { - const { t } = useTranslation(); +const AccessConfigFormFieldsProviderMattermost = () => { + const { i18n, t } = useTranslation(); + const { parentNamePath } = useFormNestedFieldsContext(); const formSchema = z.object({ - serverUrl: z.url(t("common.errmsg.url_invalid")), - username: z.string().nonempty(t("access.form.mattermost_username.placeholder")), - password: z.string().nonempty(t("access.form.mattermost_password.placeholder")), - channelId: z.string().nullish(), + [parentNamePath]: getSchema({ i18n }), }); const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; + const initialValues = getInitialValues(); return ( -
+ <> } @@ -56,16 +27,27 @@ const AccessFormMattermostConfig = ({ form: formInst, formName, disabled, initia - + - + - + ); }; -export default AccessFormMattermostConfig; +const getInitialValues = (): Nullish>> => { + return { + serverUrl: "http://:8065/", + username: "", + password: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + serverUrl: z.url(t("common.errmsg.url_invalid")), + username: z.string().nonempty(t("access.form.mattermost_username.placeholder")), + password: z.string().nonempty(t("access.form.mattermost_password.placeholder")), + channelId: z.string().nullish(), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderMattermost, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/forms/AccessConfigFieldsProviderNS1.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderNS1.tsx new file mode 100644 index 000000000..b60f766d4 --- /dev/null +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderNS1.tsx @@ -0,0 +1,55 @@ +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { useFormNestedFieldsContext } from "./_context"; + +const AccessConfigFormFieldsProviderNS1 = () => { + const { i18n, t } = useTranslation(); + + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); + + return ( + <> + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { + return { + apiKey: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + apiKey: z + .string() + .min(1, t("access.form.ns1_api_key.placeholder")) + .max(64, t("common.errmsg.string_max", { max: 64 })), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderNS1, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormNameDotComConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderNameDotCom.tsx similarity index 52% rename from ui/src/components/access/AccessFormNameDotComConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderNameDotCom.tsx index 5adba9376..1efbf2b2d 100644 --- a/ui/src/components/access/AccessFormNameDotComConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderNameDotCom.tsx @@ -1,31 +1,56 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForNameDotCom } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormNameDotComConfigFieldValues = Nullish; +const AccessConfigFormFieldsProviderNameDotCom = () => { + const { i18n, t } = useTranslation(); -export interface AccessFormNameDotComConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormNameDotComConfigFieldValues; - onValuesChange?: (values: AccessFormNameDotComConfigFieldValues) => void; -} + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); -const initFormModel = (): AccessFormNameDotComConfigFieldValues => { + return ( + <> + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { return { username: "", apiToken: "", }; }; -const AccessFormNameDotComConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormNameDotComConfigProps) => { - const { t } = useTranslation(); +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; - const formSchema = z.object({ + return z.object({ username: z .string() .min(1, t("access.form.namedotcom_username.placeholder")) @@ -35,40 +60,11 @@ const AccessFormNameDotComConfig = ({ form: formInst, formName, disabled, initia .min(1, t("access.form.namedotcom_api_token.placeholder")) .max(64, t("common.errmsg.string_max", { max: 64 })), }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- } - > - - - - } - > - - -
- ); }; -export default AccessFormNameDotComConfig; +const _default = Object.assign(AccessConfigFormFieldsProviderNameDotCom, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/forms/AccessConfigFieldsProviderNameSilo.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderNameSilo.tsx new file mode 100644 index 000000000..aba5bf4b1 --- /dev/null +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderNameSilo.tsx @@ -0,0 +1,55 @@ +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { useFormNestedFieldsContext } from "./_context"; + +const AccessConfigFormFieldsProviderNameSilo = () => { + const { i18n, t } = useTranslation(); + + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); + + return ( + <> + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { + return { + apiKey: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + apiKey: z + .string() + .min(1, t("access.form.namesilo_api_key.placeholder")) + .max(64, t("common.errmsg.string_max", { max: 64 })), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderNameSilo, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormNamecheapConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderNamecheap.tsx similarity index 52% rename from ui/src/components/access/AccessFormNamecheapConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderNamecheap.tsx index 761cccc0f..0b3018a5e 100644 --- a/ui/src/components/access/AccessFormNamecheapConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderNamecheap.tsx @@ -1,31 +1,56 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForNamecheap } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormNamecheapConfigFieldValues = Nullish; +const AccessConfigFormFieldsProviderNamecheap = () => { + const { i18n, t } = useTranslation(); -export interface AccessFormNamecheapConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormNamecheapConfigFieldValues; - onValuesChange?: (values: AccessFormNamecheapConfigFieldValues) => void; -} + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); -const initFormModel = (): AccessFormNamecheapConfigFieldValues => { + return ( + <> + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { return { username: "", apiKey: "", }; }; -const AccessFormNamecheapConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormNamecheapConfigProps) => { - const { t } = useTranslation(); +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; - const formSchema = z.object({ + return z.object({ username: z .string() .min(1, t("access.form.namecheap_username.placeholder")) @@ -35,40 +60,11 @@ const AccessFormNamecheapConfig = ({ form: formInst, formName, disabled, initial .min(1, t("access.form.namecheap_api_key.placeholder")) .max(64, t("common.errmsg.string_max", { max: 64 })), }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- } - > - - - - } - > - - -
- ); }; -export default AccessFormNamecheapConfig; +const _default = Object.assign(AccessConfigFormFieldsProviderNamecheap, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormNetcupConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderNetcup.tsx similarity index 58% rename from ui/src/components/access/AccessFormNetcupConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderNetcup.tsx index bcd7ca26e..cfbe6b547 100644 --- a/ui/src/components/access/AccessFormNetcupConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderNetcup.tsx @@ -1,53 +1,25 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForNetcup } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormNetcupConfigFieldValues = Nullish; - -export interface AccessFormNetcupConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormNetcupConfigFieldValues; - onValuesChange?: (values: AccessFormNetcupConfigFieldValues) => void; -} - -const initFormModel = (): AccessFormNetcupConfigFieldValues => { - return { - customerNumber: "", - apiKey: "", - apiPassword: "", - }; -}; - -const AccessFormNetcupConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormNetcupConfigProps) => { - const { t } = useTranslation(); +const AccessConfigFormFieldsProviderNetcup = () => { + const { i18n, t } = useTranslation(); + const { parentNamePath } = useFormNestedFieldsContext(); const formSchema = z.object({ - customerNumber: z.string().nonempty(t("access.form.netcup_customer_number.placeholder")), - apiKey: z.string().nonempty(t("access.form.netcup_api_key.placeholder")), - apiPassword: z.string().nonempty(t("access.form.netcup_api_password.placeholder")), + [parentNamePath]: getSchema({ i18n }), }); const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; + const initialValues = getInitialValues(); return ( -
+ <> } @@ -56,7 +28,8 @@ const AccessFormNetcupConfig = ({ form: formInst, formName, disabled, initialVal } @@ -65,15 +38,39 @@ const AccessFormNetcupConfig = ({ form: formInst, formName, disabled, initialVal } > -
+ ); }; -export default AccessFormNetcupConfig; +const getInitialValues = (): Nullish>> => { + return { + customerNumber: "", + apiKey: "", + apiPassword: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + customerNumber: z.string().nonempty(t("access.form.netcup_customer_number.placeholder")), + apiKey: z.string().nonempty(t("access.form.netcup_api_key.placeholder")), + apiPassword: z.string().nonempty(t("access.form.netcup_api_password.placeholder")), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderNetcup, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/forms/AccessConfigFieldsProviderNetlify.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderNetlify.tsx new file mode 100644 index 000000000..9aa2ac191 --- /dev/null +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderNetlify.tsx @@ -0,0 +1,52 @@ +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { useFormNestedFieldsContext } from "./_context"; + +const AccessConfigFormFieldsProviderNetlify = () => { + const { i18n, t } = useTranslation(); + + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); + + return ( + <> + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { + return { + apiToken: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + apiToken: z.string().nonempty(t("access.form.netlify_api_token.placeholder")), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderNetlify, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormPorkbunConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderPorkbun.tsx similarity index 52% rename from ui/src/components/access/AccessFormPorkbunConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderPorkbun.tsx index b4db53a05..881d32325 100644 --- a/ui/src/components/access/AccessFormPorkbunConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderPorkbun.tsx @@ -1,31 +1,56 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForPorkbun } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormPorkbunConfigFieldValues = Nullish; +const AccessConfigFormFieldsProviderPorkbun = () => { + const { i18n, t } = useTranslation(); -export interface AccessFormPorkbunConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormPorkbunConfigFieldValues; - onValuesChange?: (values: AccessFormPorkbunConfigFieldValues) => void; -} + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); -const initFormModel = (): AccessFormPorkbunConfigFieldValues => { + return ( + <> + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { return { apiKey: "", secretApiKey: "", }; }; -const AccessFormPorkbunConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormPorkbunConfigProps) => { - const { t } = useTranslation(); +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; - const formSchema = z.object({ + return z.object({ apiKey: z .string() .min(1, t("access.form.porkbun_api_key.placeholder")) @@ -35,40 +60,11 @@ const AccessFormPorkbunConfig = ({ form: formInst, formName, disabled, initialVa .min(1, t("access.form.porkbun_secret_api_key.placeholder")) .max(256, t("common.errmsg.string_max", { max: 256 })), }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- } - > - - - - } - > - - -
- ); }; -export default AccessFormPorkbunConfig; +const _default = Object.assign(AccessConfigFormFieldsProviderPorkbun, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/forms/AccessConfigFieldsProviderPowerDNS.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderPowerDNS.tsx new file mode 100644 index 000000000..37d0d8cc6 --- /dev/null +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderPowerDNS.tsx @@ -0,0 +1,79 @@ +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input, Switch } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { useFormNestedFieldsContext } from "./_context"; + +const AccessConfigFormFieldsProviderPowerDNS = () => { + const { i18n, t } = useTranslation(); + + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); + + return ( + <> + + + + + } + > + + + + + + + + ); +}; + +const getInitialValues = (): Nullish>> => { + return { + serverUrl: "http://:8082/", + apiKey: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + serverUrl: z.url(t("common.errmsg.url_invalid")), + apiKey: z + .string() + .min(1, t("access.form.powerdns_api_key.placeholder")) + .max(64, t("common.errmsg.string_max", { max: 64 })), + allowInsecureConnections: z.boolean().nullish(), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderPowerDNS, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormProxmoxVEConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderProxmoxVE.tsx similarity index 53% rename from ui/src/components/access/AccessFormProxmoxVEConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderProxmoxVE.tsx index 2158f431f..5767da947 100644 --- a/ui/src/components/access/AccessFormProxmoxVEConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderProxmoxVE.tsx @@ -1,57 +1,34 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input, Switch } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input, Switch } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForProxmoxVE } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormProxmoxVEConfigFieldValues = Nullish; - -export interface AccessFormProxmoxVEConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormProxmoxVEConfigFieldValues; - onValuesChange?: (values: AccessFormProxmoxVEConfigFieldValues) => void; -} - -const initFormModel = (): AccessFormProxmoxVEConfigFieldValues => { - return { - serverUrl: "http://:8006/", - apiToken: "", - }; -}; - -const AccessFormProxmoxVEConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormProxmoxVEConfigProps) => { - const { t } = useTranslation(); +const AccessConfigFormFieldsProviderProxmoxVE = () => { + const { i18n, t } = useTranslation(); + const { parentNamePath } = useFormNestedFieldsContext(); const formSchema = z.object({ - serverUrl: z.url(t("common.errmsg.url_invalid")), - apiToken: z.string().nonempty(t("access.form.proxmoxve_api_token.placeholder")), - apiTokenSecret: z.string().nullish(), - allowInsecureConnections: z.boolean().nullish(), + [parentNamePath]: getSchema({ i18n }), }); const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; + const initialValues = getInitialValues(); return ( -
- + <> + } @@ -60,7 +37,8 @@ const AccessFormProxmoxVEConfig = ({ form: formInst, formName, disabled, initial } @@ -68,14 +46,42 @@ const AccessFormProxmoxVEConfig = ({ form: formInst, formName, disabled, initial - + - + ); }; -export default AccessFormProxmoxVEConfig; +const getInitialValues = (): Nullish>> => { + return { + serverUrl: "http://:8006/", + apiToken: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + serverUrl: z.url(t("common.errmsg.url_invalid")), + apiToken: z.string().nonempty(t("access.form.proxmoxve_api_token.placeholder")), + apiTokenSecret: z.string().nullish(), + allowInsecureConnections: z.boolean().nullish(), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderProxmoxVE, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormQiniuConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderQiniu.tsx similarity index 52% rename from ui/src/components/access/AccessFormQiniuConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderQiniu.tsx index c6faeb1c2..940740c62 100644 --- a/ui/src/components/access/AccessFormQiniuConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderQiniu.tsx @@ -1,31 +1,56 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForQiniu } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormQiniuConfigFieldValues = Nullish; +const AccessConfigFormFieldsProviderQiniu = () => { + const { i18n, t } = useTranslation(); -export interface AccessFormQiniuConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormQiniuConfigFieldValues; - onValuesChange?: (values: AccessFormQiniuConfigFieldValues) => void; -} + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); -const initFormModel = (): AccessFormQiniuConfigFieldValues => { + return ( + <> + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { return { accessKey: "", secretKey: "", }; }; -const AccessFormQiniuConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormQiniuConfigProps) => { - const { t } = useTranslation(); +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; - const formSchema = z.object({ + return z.object({ accessKey: z .string() .min(1, t("access.form.qiniu_access_key.placeholder")) @@ -35,40 +60,11 @@ const AccessFormQiniuConfig = ({ form: formInst, formName, disabled, initialValu .min(1, t("access.form.qiniu_secret_key.placeholder")) .max(64, t("common.errmsg.string_max", { max: 64 })), }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- } - > - - - - } - > - - -
- ); }; -export default AccessFormQiniuConfig; +const _default = Object.assign(AccessConfigFormFieldsProviderQiniu, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/forms/AccessConfigFieldsProviderRainYun.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderRainYun.tsx new file mode 100644 index 000000000..e06b3d10c --- /dev/null +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderRainYun.tsx @@ -0,0 +1,55 @@ +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { useFormNestedFieldsContext } from "./_context"; + +const AccessConfigFormFieldsProviderRainYun = () => { + const { i18n, t } = useTranslation(); + + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); + + return ( + <> + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { + return { + apiKey: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + apiKey: z + .string() + .min(1, t("access.form.rainyun_api_key.placeholder")) + .max(64, t("common.errmsg.string_max", { max: 64 })), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderRainYun, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormRatPanelConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderRatPanel.tsx similarity index 54% rename from ui/src/components/access/AccessFormRatPanelConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderRatPanel.tsx index bfac4ed29..09c4d156b 100644 --- a/ui/src/components/access/AccessFormRatPanelConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderRatPanel.tsx @@ -1,58 +1,34 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input, Switch } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input, Switch } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForRatPanel } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormRatPanelConfigFieldValues = Nullish; - -export interface AccessFormRatPanelConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormRatPanelConfigFieldValues; - onValuesChange?: (values: AccessFormRatPanelConfigFieldValues) => void; -} - -const initFormModel = (): AccessFormRatPanelConfigFieldValues => { - return { - serverUrl: "http://:8888/", - accessTokenId: 1, - accessToken: "", - }; -}; - -const AccessFormRatPanelConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormRatPanelConfigProps) => { - const { t } = useTranslation(); +const AccessConfigFormFieldsProviderRatPanel = () => { + const { i18n, t } = useTranslation(); + const { parentNamePath } = useFormNestedFieldsContext(); const formSchema = z.object({ - serverUrl: z.url(t("common.errmsg.url_invalid")), - accessTokenId: z.preprocess((v) => Number(v), z.number().positive(t("access.form.ratpanel_access_token_id.placeholder"))), - accessToken: z.string().nonempty(t("access.form.ratpanel_access_token.placeholder")), - allowInsecureConnections: z.boolean().nullish(), + [parentNamePath]: getSchema({ i18n }), }); const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; + const initialValues = getInitialValues(); return ( -
- + <> + } @@ -61,7 +37,8 @@ const AccessFormRatPanelConfig = ({ form: formInst, formName, disabled, initialV } @@ -69,14 +46,43 @@ const AccessFormRatPanelConfig = ({ form: formInst, formName, disabled, initialV - + - + ); }; -export default AccessFormRatPanelConfig; +const getInitialValues = (): Nullish>> => { + return { + serverUrl: "http://:8888/", + accessTokenId: 1, + accessToken: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + serverUrl: z.url(t("common.errmsg.url_invalid")), + accessTokenId: z.preprocess((v) => Number(v), z.number().positive(t("access.form.ratpanel_access_token_id.placeholder"))), + accessToken: z.string().nonempty(t("access.form.ratpanel_access_token.placeholder")), + allowInsecureConnections: z.boolean().nullish(), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderRatPanel, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/forms/AccessConfigFieldsProviderSSH.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderSSH.tsx new file mode 100644 index 000000000..28c1e4bcf --- /dev/null +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderSSH.tsx @@ -0,0 +1,309 @@ +import { getI18n, useTranslation } from "react-i18next"; +import { IconCircleArrowDown, IconCircleArrowUp, IconCircleMinus, IconCirclePlus } from "@tabler/icons-react"; +import { Button, Collapse, Form, Input, InputNumber, Radio } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import Show from "@/components/Show"; +import TextFileInput from "@/components/TextFileInput"; +import { validDomainName, validIPv4Address, validIPv6Address, validPortNumber } from "@/utils/validators"; + +import { useFormNestedFieldsContext } from "./_context"; + +const AUTH_METHOD_NONE = "none" as const; +const AUTH_METHOD_PASSWORD = "password" as const; +const AUTH_METHOD_KEY = "key" as const; + +const AccessConfigFormFieldsProviderSSH = ({ disabled }: { disabled?: boolean }) => { + const { i18n, t } = useTranslation(); + + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const formInst = Form.useFormInstance(); + const initialValues = getInitialValues(); + + const fieldAuthMethod = Form.useWatch([parentNamePath, "authMethod"], formInst); + const fieldJumpServers = Form.useWatch([parentNamePath, "jumpServers"], formInst); + + return ( + <> +
+
+ + + +
+ +
+ + + +
+
+ + + ({ + key: s, + label: t(`access.form.ssh_auth_method.option.${s}.label`), + value: s, + }))} + /> + + + + + + + + + + + + + + + + + + + + + + + + + {(fields, { add, remove, move }) => ( +
+ {fields?.length > 0 ? ( + { + const subfieldHost = fieldJumpServers?.[index]?.host; + const subfieldPort = fieldJumpServers?.[index]?.post; + const subfieldAuthMethod = fieldJumpServers?.[index]?.authMethod; + + const subfieldHostAndPort = + !!subfieldHost && !!subfieldPort + ? `${subfieldHost}:${subfieldPort}` + : subfieldHost + ? subfieldHost + : subfieldPort + ? `:${subfieldPort}` + : "unknown"; + + return { + key: key, + forceRender: true, + label: ( + + [{t("access.form.ssh_jump_servers.item.label")} {index + 1}] {subfieldHostAndPort} + + ), + extra: !disabled && ( +
+
+ ), + children: ( + <> +
+
+ + + +
+
+ + + +
+
+ + + ({ + key: s, + label: t(`access.form.ssh_auth_method.option.${s}.label`), + value: s, + }))} + /> + + + + + + + + + + + + + + + + + + + + + + + ), + }; + })} + /> + ) : null} + +
+ )} +
+ + + + ); +}; + +const getInitialValues = (): Nullish>> => { + return { + host: "127.0.0.1", + port: 22, + authMethod: AUTH_METHOD_PASSWORD, + username: "root", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + const baseSchema = z + .object({ + host: z.string().refine((v) => validDomainName(v) || validIPv4Address(v) || validIPv6Address(v), t("common.errmsg.host_invalid")), + port: z.preprocess( + (v) => Number(v), + z + .number() + .int(t("access.form.ssh_port.placeholder")) + .refine((v) => validPortNumber(v), t("common.errmsg.port_invalid")) + ), + authMethod: z.literal([AUTH_METHOD_NONE, AUTH_METHOD_PASSWORD, AUTH_METHOD_KEY], t("access.form.ssh_auth_method.placeholder")), + username: z + .string() + .min(1, t("access.form.ssh_username.placeholder")) + .max(64, t("common.errmsg.string_max", { max: 64 })), + password: z + .string() + .max(64, t("common.errmsg.string_max", { max: 64 })) + .nullish(), + key: z + .string() + .max(20480, t("common.errmsg.string_max", { max: 20480 })) + .nullish(), + keyPassphrase: z + .string() + .max(20480, t("common.errmsg.string_max", { max: 20480 })) + .nullish(), + }) + .superRefine((values, ctx) => { + switch (values.authMethod) { + case AUTH_METHOD_PASSWORD: + { + if (!values.password?.trim()) { + ctx.addIssue({ + code: "custom", + message: t("access.form.ssh_password.placeholder"), + path: ["password"], + }); + } + } + break; + + case AUTH_METHOD_KEY: + { + if (!values.key?.trim()) { + ctx.addIssue({ + code: "custom", + message: t("access.form.ssh_key.placeholder"), + path: ["key"], + }); + } + } + break; + } + }); + + return baseSchema.safeExtend({ + jumpServers: z + .array(baseSchema, t("access.form.ssh_jump_servers.errmsg.invalid")) + .nullish() + .refine((v) => { + if (v == null) return true; + return v.every((item) => baseSchema.safeParse(item).success); + }, t("access.form.ssh_jump_servers.errmsg.invalid")), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderSSH, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormSSLComConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderSSLCom.tsx similarity index 52% rename from ui/src/components/access/AccessFormSSLComConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderSSLCom.tsx index 33cd05b9e..036c5571a 100644 --- a/ui/src/components/access/AccessFormSSLComConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderSSLCom.tsx @@ -1,31 +1,56 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForSSLCom } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormSSLComConfigFieldValues = Nullish; +const AccessConfigFormFieldsProviderSSLCom = () => { + const { i18n, t } = useTranslation(); -export interface AccessFormSSLComConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormSSLComConfigFieldValues; - onValuesChange?: (values: AccessFormSSLComConfigFieldValues) => void; -} + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); -const initFormModel = (): AccessFormSSLComConfigFieldValues => { + return ( + <> + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { return { eabKid: "", eabHmacKey: "", }; }; -const AccessFormSSLComConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormSSLComConfigProps) => { - const { t } = useTranslation(); +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; - const formSchema = z.object({ + return z.object({ eabKid: z .string() .min(1, t("access.form.sslcom_eab_kid.placeholder")) @@ -35,40 +60,11 @@ const AccessFormSSLComConfig = ({ form: formInst, formName, disabled, initialVal .min(1, t("access.form.sslcom_eab_hmac_key.placeholder")) .max(256, t("common.errmsg.string_max", { max: 256 })), }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- } - > - - - - } - > - - -
- ); }; -export default AccessFormSSLComConfig; +const _default = Object.assign(AccessConfigFormFieldsProviderSSLCom, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/forms/AccessConfigFieldsProviderSafeLine.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderSafeLine.tsx new file mode 100644 index 000000000..815b2f63b --- /dev/null +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderSafeLine.tsx @@ -0,0 +1,79 @@ +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input, Switch } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { useFormNestedFieldsContext } from "./_context"; + +const AccessConfigFormFieldsProviderSafeLine = () => { + const { i18n, t } = useTranslation(); + + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); + + return ( + <> + + + + + } + > + + + + + + + + ); +}; + +const getInitialValues = (): Nullish>> => { + return { + serverUrl: "http://:9443/", + apiToken: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + serverUrl: z.url(t("common.errmsg.url_invalid")), + apiToken: z + .string() + .min(1, t("access.form.safeline_api_token.placeholder")) + .max(64, t("common.errmsg.string_max", { max: 64 })), + allowInsecureConnections: z.boolean().nullish(), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderSafeLine, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormSlackBotConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderSlackBot.tsx similarity index 50% rename from ui/src/components/access/AccessFormSlackBotConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderSlackBot.tsx index 1de93876a..142e9d314 100644 --- a/ui/src/components/access/AccessFormSlackBotConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderSlackBot.tsx @@ -1,53 +1,25 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForSlackBot } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormSlackBotConfigFieldValues = Nullish; - -export interface AccessFormSlackBotConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormSlackBotConfigFieldValues; - onValuesChange?: (values: AccessFormSlackBotConfigFieldValues) => void; -} - -const initFormModel = (): AccessFormSlackBotConfigFieldValues => { - return { - botToken: "", - }; -}; - -const AccessFormSlackBotConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormSlackBotConfigProps) => { - const { t } = useTranslation(); +const AccessConfigFormFieldsProviderSlackBot = () => { + const { i18n, t } = useTranslation(); + const { parentNamePath } = useFormNestedFieldsContext(); const formSchema = z.object({ - botToken: z - .string() - .min(1, t("access.form.slackbot_token.placeholder")) - .max(256, t("common.errmsg.string_max", { max: 256 })), - channelId: z.string().nullish(), + [parentNamePath]: getSchema({ i18n }), }); const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; + const initialValues = getInitialValues(); return ( -
+ <> } @@ -56,7 +28,8 @@ const AccessFormSlackBotConfig = ({ form: formInst, formName, disabled, initialV -
+ ); }; -export default AccessFormSlackBotConfig; +const getInitialValues = (): Nullish>> => { + return { + botToken: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + botToken: z + .string() + .min(1, t("access.form.slackbot_token.placeholder")) + .max(256, t("common.errmsg.string_max", { max: 256 })), + channelId: z.string().nullish(), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderSlackBot, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/forms/AccessConfigFieldsProviderSpaceship.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderSpaceship.tsx new file mode 100644 index 000000000..2653c921a --- /dev/null +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderSpaceship.tsx @@ -0,0 +1,64 @@ +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { useFormNestedFieldsContext } from "./_context"; + +const AccessConfigFormFieldsProviderSpaceship = () => { + const { i18n, t } = useTranslation(); + + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); + + return ( + <> + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { + return { + apiKey: "", + apiSecret: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + apiKey: z.string().nonempty(t("access.form.spaceship_api_key.placeholder")), + apiSecret: z.string().nonempty(t("access.form.spaceship_api_secret.placeholder")), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderSpaceship, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormTelegramBotConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderTelegramBot.tsx similarity index 54% rename from ui/src/components/access/AccessFormTelegramBotConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderTelegramBot.tsx index 34ea894f8..1f1f4aa3e 100644 --- a/ui/src/components/access/AccessFormTelegramBotConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderTelegramBot.tsx @@ -1,30 +1,56 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForTelegramBot } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormTelegramBotConfigFieldValues = Nullish; +const AccessConfigFormFieldsProviderTelegramBot = () => { + const { i18n, t } = useTranslation(); -export interface AccessFormTelegramBotConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormTelegramBotConfigFieldValues; - onValuesChange?: (values: AccessFormTelegramBotConfigFieldValues) => void; -} + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); -const initFormModel = (): AccessFormTelegramBotConfigFieldValues => { + return ( + <> + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { return { botToken: "", }; }; -const AccessFormTelegramBotConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormTelegramBotConfigProps) => { - const { t } = useTranslation(); +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; - const formSchema = z.object({ + return z.object({ botToken: z .string() .min(1, t("access.form.telegrambot_token.placeholder")) @@ -38,41 +64,11 @@ const AccessFormTelegramBotConfig = ({ form: formInst, formName, disabled, initi ) .nullish(), }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- } - > - - - - } - > - - -
- ); }; -export default AccessFormTelegramBotConfig; +const _default = Object.assign(AccessConfigFormFieldsProviderTelegramBot, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormTencentCloudConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderTencentCloud.tsx similarity index 52% rename from ui/src/components/access/AccessFormTencentCloudConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderTencentCloud.tsx index e876c1c62..f57e93487 100644 --- a/ui/src/components/access/AccessFormTencentCloudConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderTencentCloud.tsx @@ -1,31 +1,56 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForTencentCloud } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormTencentCloudConfigFieldValues = Nullish; +const AccessConfigFormFieldsProviderTencentCloud = () => { + const { i18n, t } = useTranslation(); -export interface AccessFormTencentCloudConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormTencentCloudConfigFieldValues; - onValuesChange?: (values: AccessFormTencentCloudConfigFieldValues) => void; -} + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); -const initFormModel = (): AccessFormTencentCloudConfigFieldValues => { + return ( + <> + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { return { secretId: "", secretKey: "", }; }; -const AccessFormTencentCloudConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormTencentCloudConfigProps) => { - const { t } = useTranslation(); +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; - const formSchema = z.object({ + return z.object({ secretId: z .string() .min(1, t("access.form.tencentcloud_secret_id.placeholder")) @@ -35,40 +60,11 @@ const AccessFormTencentCloudConfig = ({ form: formInst, formName, disabled, init .min(1, t("access.form.tencentcloud_secret_key.placeholder")) .max(64, t("common.errmsg.string_max", { max: 64 })), }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- } - > - - - - } - > - - -
- ); }; -export default AccessFormTencentCloudConfig; +const _default = Object.assign(AccessConfigFormFieldsProviderTencentCloud, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormUCloudConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderUCloud.tsx similarity index 60% rename from ui/src/components/access/AccessFormUCloudConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderUCloud.tsx index 4604c5306..3b506bdb7 100644 --- a/ui/src/components/access/AccessFormUCloudConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderUCloud.tsx @@ -1,31 +1,66 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForUCloud } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormUCloudConfigFieldValues = Nullish; +const AccessConfigFormFieldsProviderUCloud = () => { + const { i18n, t } = useTranslation(); -export interface AccessFormUCloudConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormUCloudConfigFieldValues; - onValuesChange?: (values: AccessFormUCloudConfigFieldValues) => void; -} + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); -const initFormModel = (): AccessFormUCloudConfigFieldValues => { + return ( + <> + } + > + + + + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { return { privateKey: "", publicKey: "", }; }; -const AccessFormUCloudConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormUCloudConfigProps) => { - const { t } = useTranslation(); +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; - const formSchema = z.object({ + return z.object({ privateKey: z .string() .min(1, t("access.form.ucloud_private_key.placeholder")) @@ -39,49 +74,11 @@ const AccessFormUCloudConfig = ({ form: formInst, formName, disabled, initialVal .max(64, t("common.errmsg.string_max", { max: 64 })) .nullish(), }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- } - > - - - - } - > - - - - } - > - - -
- ); }; -export default AccessFormUCloudConfig; +const _default = Object.assign(AccessConfigFormFieldsProviderUCloud, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/forms/AccessConfigFieldsProviderUniCloud.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderUniCloud.tsx new file mode 100644 index 000000000..56953c3c8 --- /dev/null +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderUniCloud.tsx @@ -0,0 +1,64 @@ +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { useFormNestedFieldsContext } from "./_context"; + +const AccessConfigFormFieldsProviderUniCloud = () => { + const { i18n, t } = useTranslation(); + + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); + + return ( + <> + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { + return { + username: "", + password: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + username: z.string().nonempty(t("access.form.unicloud_username.placeholder")), + password: z.string().nonempty(t("access.form.unicloud_password.placeholder")), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderUniCloud, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormUpyunConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderUpyun.tsx similarity index 52% rename from ui/src/components/access/AccessFormUpyunConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderUpyun.tsx index 10aad03f6..11c18ff45 100644 --- a/ui/src/components/access/AccessFormUpyunConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderUpyun.tsx @@ -1,31 +1,56 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForUpyun } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormUpyunConfigFieldValues = Nullish; +const AccessConfigFormFieldsProviderUpyun = () => { + const { i18n, t } = useTranslation(); -export interface AccessFormUpyunConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormUpyunConfigFieldValues; - onValuesChange?: (values: AccessFormUpyunConfigFieldValues) => void; -} + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); -const initFormModel = (): AccessFormUpyunConfigFieldValues => { + return ( + <> + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { return { username: "", password: "", }; }; -const AccessFormUpyunConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormUpyunConfigProps) => { - const { t } = useTranslation(); +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; - const formSchema = z.object({ + return z.object({ username: z .string() .min(1, t("access.form.upyun_username.placeholder")) @@ -35,40 +60,11 @@ const AccessFormUpyunConfig = ({ form: formInst, formName, disabled, initialValu .min(1, t("access.form.upyun_password.placeholder")) .max(64, t("common.errmsg.string_max", { max: 64 })), }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- } - > - - - - } - > - - -
- ); }; -export default AccessFormUpyunConfig; +const _default = Object.assign(AccessConfigFormFieldsProviderUpyun, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormVercelConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderVercel.tsx similarity index 51% rename from ui/src/components/access/AccessFormVercelConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderVercel.tsx index d982d74e4..4963cfdf3 100644 --- a/ui/src/components/access/AccessFormVercelConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderVercel.tsx @@ -1,30 +1,55 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForVercel } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormVercelConfigFieldValues = Nullish; +const AccessConfigFormFieldsProviderVercel = () => { + const { i18n, t } = useTranslation(); -export interface AccessFormVercelConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormVercelConfigFieldValues; - onValuesChange?: (values: AccessFormVercelConfigFieldValues) => void; -} + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); -const initFormModel = (): AccessFormVercelConfigFieldValues => { + return ( + <> + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { return { apiAccessToken: "", }; }; -const AccessFormVercelConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormVercelConfigProps) => { - const { t } = useTranslation(); +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; - const formSchema = z.object({ + return z.object({ apiAccessToken: z .string() .min(1, t("access.form.vercel_api_access_token.placeholder")) @@ -34,40 +59,11 @@ const AccessFormVercelConfig = ({ form: formInst, formName, disabled, initialVal .max(256, t("common.errmsg.string_max", { max: 256 })) .nullish(), }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- } - > - - - - } - > - - -
- ); }; -export default AccessFormVercelConfig; +const _default = Object.assign(AccessConfigFormFieldsProviderVercel, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormVolcEngineConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderVolcEngine.tsx similarity index 53% rename from ui/src/components/access/AccessFormVolcEngineConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderVolcEngine.tsx index c495420bb..a8330ff62 100644 --- a/ui/src/components/access/AccessFormVolcEngineConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderVolcEngine.tsx @@ -1,31 +1,56 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForVolcEngine } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormVolcEngineConfigFieldValues = Nullish; +const AccessConfigFormFieldsProviderVolcEngine = () => { + const { i18n, t } = useTranslation(); -export interface AccessFormVolcEngineConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormVolcEngineConfigFieldValues; - onValuesChange?: (values: AccessFormVolcEngineConfigFieldValues) => void; -} + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); -const initFormModel = (): AccessFormVolcEngineConfigFieldValues => { + return ( + <> + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { return { accessKeyId: "", secretAccessKey: "", }; }; -const AccessFormVolcEngineConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormVolcEngineConfigProps) => { - const { t } = useTranslation(); +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; - const formSchema = z.object({ + return z.object({ accessKeyId: z .string() .min(1, t("access.form.volcengine_access_key_id.placeholder")) @@ -35,40 +60,11 @@ const AccessFormVolcEngineConfig = ({ form: formInst, formName, disabled, initia .min(1, t("access.form.volcengine_secret_access_key.placeholder")) .max(64, t("common.errmsg.string_max", { max: 64 })), }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- } - > - - - - } - > - - -
- ); }; -export default AccessFormVolcEngineConfig; +const _default = Object.assign(AccessConfigFormFieldsProviderVolcEngine, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormWangsuConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderWangsu.tsx similarity index 60% rename from ui/src/components/access/AccessFormWangsuConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderWangsu.tsx index 23b5fb142..803fb3c44 100644 --- a/ui/src/components/access/AccessFormWangsuConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderWangsu.tsx @@ -1,21 +1,56 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForWangsu } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormWangsuConfigFieldValues = Nullish; +const AccessConfigFormFieldsProviderWangsu = () => { + const { i18n, t } = useTranslation(); -export interface AccessFormWangsuConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormWangsuConfigFieldValues; - onValuesChange?: (values: AccessFormWangsuConfigFieldValues) => void; -} + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); -const initFormModel = (): AccessFormWangsuConfigFieldValues => { + return ( + <> + } + > + + + + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { return { accessKeyId: "", accessKeySecret: "", @@ -23,10 +58,10 @@ const initFormModel = (): AccessFormWangsuConfigFieldValues => { }; }; -const AccessFormWangsuConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange: onValuesChange }: AccessFormWangsuConfigProps) => { - const { t } = useTranslation(); +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; - const formSchema = z.object({ + return z.object({ accessKeyId: z .string() .min(1, t("access.form.wangsu_access_key_id.placeholder")) @@ -40,49 +75,11 @@ const AccessFormWangsuConfig = ({ form: formInst, formName, disabled, initialVal .min(1, t("access.form.wangsu_api_key.placeholder")) .max(256, t("common.errmsg.string_max", { max: 256 })), }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- } - > - - - - } - > - - - - } - > - - -
- ); }; -export default AccessFormWangsuConfig; +const _default = Object.assign(AccessConfigFormFieldsProviderWangsu, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/forms/AccessConfigFieldsProviderWeComBot.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderWeComBot.tsx new file mode 100644 index 000000000..bea9d04d5 --- /dev/null +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderWeComBot.tsx @@ -0,0 +1,52 @@ +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { useFormNestedFieldsContext } from "./_context"; + +const AccessConfigFormFieldsProviderWeComBot = () => { + const { i18n, t } = useTranslation(); + + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); + + return ( + <> + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { + return { + webhookUrl: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + webhookUrl: z.url(t("common.errmsg.url_invalid")), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProviderWeComBot, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormWebhookConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderWebhook.tsx similarity index 80% rename from ui/src/components/access/AccessFormWebhookConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderWebhook.tsx index 7661d95b6..10bda9eee 100644 --- a/ui/src/components/access/AccessFormWebhookConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderWebhook.tsx @@ -1,102 +1,29 @@ -import { useTranslation } from "react-i18next"; +import { getI18n, useTranslation } from "react-i18next"; import { IconChevronDown } from "@tabler/icons-react"; -import { Button, Dropdown, Form, type FormInstance, Input, Select, Switch } from "antd"; +import { Button, Dropdown, Form, Input, Select, Switch } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; import CodeInput from "@/components/CodeInput"; import Show from "@/components/Show"; import Tips from "@/components/Tips"; -import { type AccessConfigForWebhook } from "@/domain/access"; -type AccessFormWebhookConfigFieldValues = Nullish; +import { useFormNestedFieldsContext } from "./_context"; -export interface AccessFormWebhookConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormWebhookConfigFieldValues; +export interface AccessConfigFormFieldsWebhookProps { usage?: "deployment" | "notification" | "none"; - onValuesChange?: (values: AccessFormWebhookConfigFieldValues) => void; } -const initFormModel = (): AccessFormWebhookConfigFieldValues => { - return { - url: "", - method: "POST", - headers: "Content-Type: application/json", - allowInsecureConnections: false, - dataForDeployment: JSON.stringify( - { - name: "${DOMAINS}", - cert: "${CERTIFICATE}", - privkey: "${PRIVATE_KEY}", - }, - null, - 2 - ), - dataForNotification: JSON.stringify( - { - subject: "${SUBJECT}", - message: "${MESSAGE}", - }, - null, - 2 - ), - }; -}; - -const AccessFormWebhookConfig = ({ form: formInst, formName, disabled, initialValues, usage, onValuesChange }: AccessFormWebhookConfigProps) => { - const { t } = useTranslation(); +const AccessConfigFormFieldsProviderWebhook = ({ usage = "none" }: AccessConfigFormFieldsWebhookProps) => { + const { i18n, t } = useTranslation(); + const { parentNamePath } = useFormNestedFieldsContext(); const formSchema = z.object({ - url: z.url(t("common.errmsg.url_invalid")), - method: z.literal(["GET", "POST", "PUT", "PATCH", "DELETE"], t("access.form.webhook_method.placeholder")), - headers: z - .string() - .nullish() - .refine((v) => { - if (!v) return true; - - const lines = v.split(/\r?\n/); - for (const line of lines) { - if (line.split(":").length < 2) { - return false; - } - } - return true; - }, t("access.form.webhook_headers.errmsg.invalid")), - dataForDeployment: z - .string() - .nullish() - .refine((v) => { - if (usage && usage !== "deployment") return true; - if (!v) return true; - - try { - const obj = JSON.parse(v); - return typeof obj === "object" && !Array.isArray(obj); - } catch { - return false; - } - }, t("access.form.webhook_data.errmsg.json_invalid")), - dataForNotification: z - .string() - .nullish() - .refine((v) => { - if (usage && usage !== "notification") return true; - if (!v) return true; - - try { - const obj = JSON.parse(v); - return typeof obj === "object" && !Array.isArray(obj); - } catch { - return false; - } - }, t("access.form.webhook_data.errmsg.json_invalid")), - allowInsecureConnections: z.boolean().nullish(), + [parentNamePath]: getSchema({ i18n }), }); const formRule = createSchemaFieldRule(formSchema); + const formInst = Form.useFormInstance(); + const initialValues = getInitialValues(); const handleWebhookHeadersBlur = () => { let value = formInst.getFieldValue("headers"); @@ -126,7 +53,7 @@ const AccessFormWebhookConfig = ({ form: formInst, formName, disabled, initialVa }; const handlePresetDataForDeploymentClick = () => { - formInst.setFieldValue("dataForDeployment", initFormModel().dataForDeployment); + formInst.setFieldValue("dataForDeployment", getInitialValues().dataForDeployment); }; const handlePresetDataForNotificationClick = (key: string) => { @@ -260,29 +187,18 @@ const AccessFormWebhookConfig = ({ form: formInst, formName, disabled, initialVa default: formInst.setFieldValue("method", "POST"); formInst.setFieldValue("headers", "Content-Type: application/json"); - formInst.setFieldValue("dataForNotification", initFormModel().dataForNotification); + formInst.setFieldValue("dataForNotification", getInitialValues().dataForNotification); break; } }; - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - return ( -
- + <> + - + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { return { username: "", apiPassword: "", }; }; -const AccessFormWestcnConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormWestcnConfigProps) => { - const { t } = useTranslation(); +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; - const formSchema = z.object({ + return z.object({ username: z .string() .min(1, t("access.form.westcn_username.placeholder")) @@ -35,40 +60,11 @@ const AccessFormWestcnConfig = ({ form: formInst, formName, disabled, initialVal .min(1, t("access.form.westcn_api_password.placeholder")) .max(64, t("common.errmsg.string_max", { max: 64 })), }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( - - } - > - - - - } - > - - - - ); }; -export default AccessFormWestcnConfig; +const _default = Object.assign(AccessConfigFormFieldsProviderWestcn, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/AccessFormZeroSSLConfig.tsx b/ui/src/components/access/forms/AccessConfigFieldsProviderZeroSSL.tsx similarity index 52% rename from ui/src/components/access/AccessFormZeroSSLConfig.tsx rename to ui/src/components/access/forms/AccessConfigFieldsProviderZeroSSL.tsx index 37e3b7b61..5d8b75fef 100644 --- a/ui/src/components/access/AccessFormZeroSSLConfig.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProviderZeroSSL.tsx @@ -1,31 +1,56 @@ -import { useTranslation } from "react-i18next"; -import { Form, type FormInstance, Input } from "antd"; +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AccessConfigForZeroSSL } from "@/domain/access"; +import { useFormNestedFieldsContext } from "./_context"; -type AccessFormZeroSSLConfigFieldValues = Nullish; +const AccessConfigFormFieldsProviderZeroSSL = () => { + const { i18n, t } = useTranslation(); -export interface AccessFormZeroSSLConfigProps { - form: FormInstance; - formName: string; - disabled?: boolean; - initialValues?: AccessFormZeroSSLConfigFieldValues; - onValuesChange?: (values: AccessFormZeroSSLConfigFieldValues) => void; -} + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); -const initFormModel = (): AccessFormZeroSSLConfigFieldValues => { + return ( + <> + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { return { eabKid: "", eabHmacKey: "", }; }; -const AccessFormZeroSSLConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormZeroSSLConfigProps) => { - const { t } = useTranslation(); +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; - const formSchema = z.object({ + return z.object({ eabKid: z .string() .min(1, t("access.form.zerossl_eab_kid.placeholder")) @@ -35,40 +60,11 @@ const AccessFormZeroSSLConfig = ({ form: formInst, formName, disabled, initialVa .min(1, t("access.form.zerossl_eab_hmac_key.placeholder")) .max(256, t("common.errmsg.string_max", { max: 256 })), }); - const formRule = createSchemaFieldRule(formSchema); - - const handleFormChange = (_: unknown, values: z.infer) => { - onValuesChange?.(values); - }; - - return ( -
- } - > - - - - } - > - - -
- ); }; -export default AccessFormZeroSSLConfig; +const _default = Object.assign(AccessConfigFormFieldsProviderZeroSSL, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/access/forms/AccessConfigFormProvider1Panel.tsx b/ui/src/components/access/forms/AccessConfigFormProvider1Panel.tsx new file mode 100644 index 000000000..c2e79e451 --- /dev/null +++ b/ui/src/components/access/forms/AccessConfigFormProvider1Panel.tsx @@ -0,0 +1,90 @@ +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input, Select, Switch } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { useFormNestedFieldsContext } from "./_context"; + +const AccessConfigFormFieldsProvider1Panel = () => { + const { i18n, t } = useTranslation(); + + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); + + return ( + <> + + + + + +