mirror of
https://github.com/usual2970/certimate.git
synced 2025-06-07 21:19:51 +00:00
refactor(ui): MultipleSplitValueInput
This commit is contained in:
parent
71c093c042
commit
b798b824db
108
ui/src/components/MultipleSplitValueInput.tsx
Normal file
108
ui/src/components/MultipleSplitValueInput.tsx
Normal file
@ -0,0 +1,108 @@
|
||||
import { type ChangeEvent, useEffect } from "react";
|
||||
import { FormOutlined as FormOutlinedIcon } from "@ant-design/icons";
|
||||
import { nanoid } from "@ant-design/pro-components";
|
||||
import { useControllableValue } from "ahooks";
|
||||
import { Button, Form, Input, type InputProps, Space } from "antd";
|
||||
|
||||
import { useAntdForm } from "@/hooks";
|
||||
import ModalForm from "./ModalForm";
|
||||
import MultipleInput from "./MultipleInput";
|
||||
|
||||
type SplitOptions = {
|
||||
removeEmpty?: boolean;
|
||||
trim?: boolean;
|
||||
};
|
||||
|
||||
export type MultipleSplitValueInputProps = Omit<InputProps, "count" | "defaultValue" | "showCount" | "value" | "onChange"> & {
|
||||
defaultValue?: string;
|
||||
delimiter?: string;
|
||||
maxCount?: number;
|
||||
minCount?: number;
|
||||
modalTitle?: string;
|
||||
modalWidth?: number;
|
||||
placeholderInModal?: string;
|
||||
showSortButton?: boolean;
|
||||
splitOptions?: SplitOptions;
|
||||
value?: string[];
|
||||
onChange?: (value: string) => void;
|
||||
};
|
||||
|
||||
const DEFAULT_DELIMITER = ";";
|
||||
|
||||
const MultipleSplitValueInput = ({
|
||||
className,
|
||||
style,
|
||||
delimiter = DEFAULT_DELIMITER,
|
||||
disabled,
|
||||
maxCount,
|
||||
minCount,
|
||||
modalTitle,
|
||||
modalWidth = 480,
|
||||
placeholder,
|
||||
placeholderInModal,
|
||||
showSortButton = true,
|
||||
splitOptions = {},
|
||||
onClear,
|
||||
...props
|
||||
}: MultipleSplitValueInputProps) => {
|
||||
const [value, setValue] = useControllableValue<string>(props, {
|
||||
valuePropName: "value",
|
||||
defaultValuePropName: "defaultValue",
|
||||
trigger: "onChange",
|
||||
});
|
||||
|
||||
const { form: formInst, formProps } = useAntdForm({
|
||||
name: "componentMultipleSplitValueInput_" + nanoid(),
|
||||
initialValues: { value: value?.split(delimiter) },
|
||||
onSubmit: (values) => {
|
||||
const temp = values.value ?? [];
|
||||
if (splitOptions.trim) {
|
||||
temp.map((e) => e.trim());
|
||||
}
|
||||
if (splitOptions.removeEmpty) {
|
||||
temp.filter((e) => !!e);
|
||||
}
|
||||
|
||||
setValue(temp.join(delimiter));
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
formInst.setFieldValue("value", value?.split(delimiter));
|
||||
}, [delimiter, value]);
|
||||
|
||||
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
|
||||
setValue(e.target.value);
|
||||
};
|
||||
|
||||
const handleClear = () => {
|
||||
setValue("");
|
||||
onClear?.();
|
||||
};
|
||||
|
||||
return (
|
||||
<Space.Compact className={className} style={{ width: "100%", ...style }}>
|
||||
<Input {...props} disabled={disabled} placeholder={placeholder} value={value} onChange={handleChange} onClear={handleClear} />
|
||||
<ModalForm
|
||||
{...formProps}
|
||||
layout="vertical"
|
||||
form={formInst}
|
||||
modalProps={{ destroyOnHidden: true }}
|
||||
title={modalTitle}
|
||||
trigger={
|
||||
<Button disabled={disabled}>
|
||||
<FormOutlinedIcon />
|
||||
</Button>
|
||||
}
|
||||
validateTrigger="onSubmit"
|
||||
width={modalWidth}
|
||||
>
|
||||
<Form.Item name="value" noStyle>
|
||||
<MultipleInput minCount={minCount} maxCount={maxCount} placeholder={placeholderInModal ?? placeholder} showSortButton={showSortButton} />
|
||||
</Form.Item>
|
||||
</ModalForm>
|
||||
</Space.Compact>
|
||||
);
|
||||
};
|
||||
|
||||
export default MultipleSplitValueInput;
|
@ -1,12 +1,7 @@
|
||||
import { forwardRef, memo, useEffect, useImperativeHandle, useMemo, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link } from "react-router";
|
||||
import {
|
||||
FormOutlined as FormOutlinedIcon,
|
||||
PlusOutlined as PlusOutlinedIcon,
|
||||
QuestionCircleOutlined as QuestionCircleOutlinedIcon,
|
||||
RightOutlined as RightOutlinedIcon,
|
||||
} from "@ant-design/icons";
|
||||
import { PlusOutlined as PlusOutlinedIcon, QuestionCircleOutlined as QuestionCircleOutlinedIcon, RightOutlined as RightOutlinedIcon } from "@ant-design/icons";
|
||||
import { useControllableValue } from "ahooks";
|
||||
import {
|
||||
AutoComplete,
|
||||
@ -19,7 +14,6 @@ import {
|
||||
Input,
|
||||
InputNumber,
|
||||
Select,
|
||||
Space,
|
||||
Switch,
|
||||
Tooltip,
|
||||
Typography,
|
||||
@ -29,8 +23,7 @@ import { z } from "zod";
|
||||
|
||||
import AccessEditModal from "@/components/access/AccessEditModal";
|
||||
import AccessSelect from "@/components/access/AccessSelect";
|
||||
import ModalForm from "@/components/ModalForm";
|
||||
import MultipleInput from "@/components/MultipleInput";
|
||||
import MultipleSplitValueInput from "@/components/MultipleSplitValueInput";
|
||||
import ACMEDns01ProviderSelect from "@/components/provider/ACMEDns01ProviderSelect";
|
||||
import CAProviderSelect from "@/components/provider/CAProviderSelect";
|
||||
import Show from "@/components/Show";
|
||||
@ -152,11 +145,9 @@ const ApplyNodeConfigForm = forwardRef<ApplyNodeConfigFormInstance, ApplyNodeCon
|
||||
initialValues: initialValues ?? initFormModel(),
|
||||
});
|
||||
|
||||
const fieldDomains = Form.useWatch<string>("domains", formInst);
|
||||
const fieldProvider = Form.useWatch<string>("provider", { form: formInst, preserve: true });
|
||||
const fieldProviderAccessId = Form.useWatch<string>("providerAccessId", formInst);
|
||||
const fieldCAProvider = Form.useWatch<string>("caProvider", formInst);
|
||||
const fieldNameservers = Form.useWatch<string>("nameservers", formInst);
|
||||
|
||||
const [showProvider, setShowProvider] = useState(false);
|
||||
useEffect(() => {
|
||||
@ -294,25 +285,17 @@ const ApplyNodeConfigForm = forwardRef<ApplyNodeConfigFormInstance, ApplyNodeCon
|
||||
<Form.Provider onFormChange={handleFormProviderChange}>
|
||||
<Form className={className} style={style} {...formProps} disabled={disabled} layout="vertical" scrollToFirstError onValuesChange={handleFormChange}>
|
||||
<Form.Item
|
||||
name="domains"
|
||||
label={t("workflow_node.apply.form.domains.label")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.apply.form.domains.tooltip") }}></span>}
|
||||
>
|
||||
<Space.Compact style={{ width: "100%" }}>
|
||||
<Form.Item name="domains" noStyle rules={[formRule]}>
|
||||
<Input placeholder={t("workflow_node.apply.form.domains.placeholder")} />
|
||||
</Form.Item>
|
||||
<DomainsModalInput
|
||||
value={fieldDomains}
|
||||
trigger={
|
||||
<Button disabled={disabled}>
|
||||
<FormOutlinedIcon />
|
||||
</Button>
|
||||
}
|
||||
onChange={(v) => {
|
||||
formInst.setFieldValue("domains", v);
|
||||
}}
|
||||
/>
|
||||
</Space.Compact>
|
||||
<MultipleSplitValueInput
|
||||
modalTitle={t("workflow_node.apply.form.domains.multiple_input_modal.title")}
|
||||
placeholder={t("workflow_node.apply.form.domains.placeholder")}
|
||||
placeholderInModal={t("workflow_node.apply.form.domains.multiple_input_modal.placeholder")}
|
||||
splitOptions={{ trim: true, removeEmpty: true }}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
@ -497,36 +480,17 @@ const ApplyNodeConfigForm = forwardRef<ApplyNodeConfigFormInstance, ApplyNodeCon
|
||||
|
||||
<Form className={className} style={style} {...formProps} disabled={disabled} layout="vertical" scrollToFirstError onValuesChange={handleFormChange}>
|
||||
<Form.Item
|
||||
name="nameservers"
|
||||
label={t("workflow_node.apply.form.nameservers.label")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.apply.form.nameservers.tooltip") }}></span>}
|
||||
>
|
||||
<Space.Compact style={{ width: "100%" }}>
|
||||
<Form.Item name="nameservers" noStyle rules={[formRule]}>
|
||||
<Input
|
||||
allowClear
|
||||
disabled={disabled}
|
||||
value={fieldNameservers}
|
||||
placeholder={t("workflow_node.apply.form.nameservers.placeholder")}
|
||||
onChange={(e) => {
|
||||
formInst.setFieldValue("nameservers", e.target.value);
|
||||
}}
|
||||
onClear={() => {
|
||||
formInst.setFieldValue("nameservers", undefined);
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
<NameserversModalInput
|
||||
value={fieldNameservers}
|
||||
trigger={
|
||||
<Button disabled={disabled}>
|
||||
<FormOutlinedIcon />
|
||||
</Button>
|
||||
}
|
||||
onChange={(value) => {
|
||||
formInst.setFieldValue("nameservers", value);
|
||||
}}
|
||||
/>
|
||||
</Space.Compact>
|
||||
<MultipleSplitValueInput
|
||||
modalTitle={t("workflow_node.apply.form.nameservers.multiple_input_modal.title")}
|
||||
placeholder={t("workflow_node.apply.form.nameservers.placeholder")}
|
||||
placeholderInModal={t("workflow_node.apply.form.nameservers.multiple_input_modal.placeholder")}
|
||||
splitOptions={{ trim: true, removeEmpty: true }}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
@ -678,84 +642,4 @@ const EmailInput = memo(
|
||||
}
|
||||
);
|
||||
|
||||
const DomainsModalInput = memo(({ value, trigger, onChange }: { value?: string; trigger?: React.ReactNode; onChange?: (value: string) => void }) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const formSchema = z.object({
|
||||
domains: z.array(z.string()).refine((v) => {
|
||||
return v.every((e) => !e?.trim() || validDomainName(e.trim(), { allowWildcard: true }));
|
||||
}, t("common.errmsg.domain_invalid")),
|
||||
});
|
||||
const formRule = createSchemaFieldRule(formSchema);
|
||||
const { form: formInst, formProps } = useAntdForm({
|
||||
name: "workflowNodeApplyConfigFormDomainsModalInput",
|
||||
initialValues: { domains: value?.split(MULTIPLE_INPUT_DELIMITER) },
|
||||
onSubmit: (values) => {
|
||||
onChange?.(
|
||||
values.domains
|
||||
.map((e) => e.trim())
|
||||
.filter((e) => !!e)
|
||||
.join(MULTIPLE_INPUT_DELIMITER)
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<ModalForm
|
||||
{...formProps}
|
||||
layout="vertical"
|
||||
form={formInst}
|
||||
modalProps={{ destroyOnHidden: true }}
|
||||
title={t("workflow_node.apply.form.domains.multiple_input_modal.title")}
|
||||
trigger={trigger}
|
||||
validateTrigger="onSubmit"
|
||||
width={480}
|
||||
>
|
||||
<Form.Item name="domains" rules={[formRule]}>
|
||||
<MultipleInput placeholder={t("workflow_node.apply.form.domains.multiple_input_modal.placeholder")} />
|
||||
</Form.Item>
|
||||
</ModalForm>
|
||||
);
|
||||
});
|
||||
|
||||
const NameserversModalInput = memo(({ trigger, value, onChange }: { trigger?: React.ReactNode; value?: string; onChange?: (value: string) => void }) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const formSchema = z.object({
|
||||
nameservers: z.array(z.string()).refine((v) => {
|
||||
return v.every((e) => !e?.trim() || validIPv4Address(e) || validIPv6Address(e) || validDomainName(e));
|
||||
}, t("common.errmsg.domain_invalid")),
|
||||
});
|
||||
const formRule = createSchemaFieldRule(formSchema);
|
||||
const { form: formInst, formProps } = useAntdForm({
|
||||
name: "workflowNodeApplyConfigFormNameserversModalInput",
|
||||
initialValues: { nameservers: value?.split(MULTIPLE_INPUT_DELIMITER) },
|
||||
onSubmit: (values) => {
|
||||
onChange?.(
|
||||
values.nameservers
|
||||
.map((e) => e.trim())
|
||||
.filter((e) => !!e)
|
||||
.join(MULTIPLE_INPUT_DELIMITER)
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<ModalForm
|
||||
{...formProps}
|
||||
layout="vertical"
|
||||
form={formInst}
|
||||
modalProps={{ destroyOnHidden: true }}
|
||||
title={t("workflow_node.apply.form.nameservers.multiple_input_modal.title")}
|
||||
trigger={trigger}
|
||||
validateTrigger="onSubmit"
|
||||
width={480}
|
||||
>
|
||||
<Form.Item name="nameservers" rules={[formRule]}>
|
||||
<MultipleInput placeholder={t("workflow_node.apply.form.nameservers.multiple_input_modal.placeholder")} />
|
||||
</Form.Item>
|
||||
</ModalForm>
|
||||
);
|
||||
});
|
||||
|
||||
export default memo(ApplyNodeConfigForm);
|
||||
|
@ -1,13 +1,9 @@
|
||||
import { memo } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { FormOutlined as FormOutlinedIcon } from "@ant-design/icons";
|
||||
import { Alert, Button, Form, type FormInstance, Input, Space } from "antd";
|
||||
import { Alert, Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod";
|
||||
|
||||
import ModalForm from "@/components/ModalForm";
|
||||
import MultipleInput from "@/components/MultipleInput";
|
||||
import { useAntdForm } from "@/hooks";
|
||||
import MultipleSplitValueInput from "@/components/MultipleSplitValueInput";
|
||||
|
||||
type DeployNodeConfigFormAliyunCASDeployConfigFieldValues = Nullish<{
|
||||
region: string;
|
||||
@ -61,9 +57,6 @@ const DeployNodeConfigFormAliyunCASDeployConfig = ({
|
||||
});
|
||||
const formRule = createSchemaFieldRule(formSchema);
|
||||
|
||||
const fieldResourceIds = Form.useWatch<string>("resourceIds", formInst);
|
||||
const fieldContactIds = Form.useWatch<string>("contactIds", formInst);
|
||||
|
||||
const handleFormChange = (_: unknown, values: z.infer<typeof formSchema>) => {
|
||||
onValuesChange?.(values);
|
||||
};
|
||||
@ -87,69 +80,31 @@ const DeployNodeConfigFormAliyunCASDeployConfig = ({
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="resourceIds"
|
||||
label={t("workflow_node.deploy.form.aliyun_cas_deploy_resource_ids.label")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.aliyun_cas_deploy_resource_ids.tooltip") }}></span>}
|
||||
>
|
||||
<Space.Compact style={{ width: "100%" }}>
|
||||
<Form.Item name="resourceIds" noStyle rules={[formRule]}>
|
||||
<Input
|
||||
allowClear
|
||||
disabled={disabled}
|
||||
value={fieldResourceIds}
|
||||
placeholder={t("workflow_node.deploy.form.aliyun_cas_deploy_resource_ids.placeholder")}
|
||||
onChange={(e) => {
|
||||
formInst.setFieldValue("resourceIds", e.target.value);
|
||||
}}
|
||||
onClear={() => {
|
||||
formInst.setFieldValue("resourceIds", "");
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
<ResourceIdsModalInput
|
||||
value={fieldResourceIds}
|
||||
trigger={
|
||||
<Button disabled={disabled}>
|
||||
<FormOutlinedIcon />
|
||||
</Button>
|
||||
}
|
||||
onChange={(value) => {
|
||||
formInst.setFieldValue("resourceIds", value);
|
||||
}}
|
||||
/>
|
||||
</Space.Compact>
|
||||
<MultipleSplitValueInput
|
||||
modalTitle={t("workflow_node.deploy.form.aliyun_cas_deploy_resource_ids.multiple_input_modal.title")}
|
||||
placeholder={t("workflow_node.deploy.form.aliyun_cas_deploy_resource_ids.placeholder")}
|
||||
placeholderInModal={t("workflow_node.deploy.form.aliyun_cas_deploy_resource_ids.multiple_input_modal.placeholder")}
|
||||
splitOptions={{ trim: true, removeEmpty: true }}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="contactIds"
|
||||
label={t("workflow_node.deploy.form.aliyun_cas_deploy_contact_ids.label")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.aliyun_cas_deploy_contact_ids.tooltip") }}></span>}
|
||||
>
|
||||
<Space.Compact style={{ width: "100%" }}>
|
||||
<Form.Item name="contactIds" noStyle rules={[formRule]}>
|
||||
<Input
|
||||
allowClear
|
||||
disabled={disabled}
|
||||
value={fieldContactIds}
|
||||
placeholder={t("workflow_node.deploy.form.aliyun_cas_deploy_contact_ids.placeholder")}
|
||||
onChange={(e) => {
|
||||
formInst.setFieldValue("contactIds", e.target.value);
|
||||
}}
|
||||
onClear={() => {
|
||||
formInst.setFieldValue("contactIds", "");
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
<ContactIdsModalInput
|
||||
value={fieldContactIds}
|
||||
trigger={
|
||||
<Button disabled={disabled}>
|
||||
<FormOutlinedIcon />
|
||||
</Button>
|
||||
}
|
||||
onChange={(value) => {
|
||||
formInst.setFieldValue("contactIds", value);
|
||||
}}
|
||||
/>
|
||||
</Space.Compact>
|
||||
<MultipleSplitValueInput
|
||||
modalTitle={t("workflow_node.deploy.form.aliyun_cas_deploy_contact_ids.multiple_input_modal.title")}
|
||||
placeholder={t("workflow_node.deploy.form.aliyun_cas_deploy_contact_ids.placeholder")}
|
||||
placeholderInModal={t("workflow_node.deploy.form.aliyun_cas_deploy_contact_ids.multiple_input_modal.placeholder")}
|
||||
splitOptions={{ trim: true, removeEmpty: true }}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item>
|
||||
@ -159,84 +114,4 @@ const DeployNodeConfigFormAliyunCASDeployConfig = ({
|
||||
);
|
||||
};
|
||||
|
||||
const ResourceIdsModalInput = memo(({ value, trigger, onChange }: { value?: string; trigger?: React.ReactNode; onChange?: (value: string) => void }) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const formSchema = z.object({
|
||||
resourceIds: z.array(z.string()).refine((v) => {
|
||||
return v.every((e) => !e?.trim() || /^[1-9]\d*$/.test(e));
|
||||
}, t("workflow_node.deploy.form.aliyun_cas_deploy_resource_ids.errmsg.invalid")),
|
||||
});
|
||||
const formRule = createSchemaFieldRule(formSchema);
|
||||
const { form: formInst, formProps } = useAntdForm({
|
||||
name: "workflowNodeDeployConfigFormAliyunCASResourceIdsModalInput",
|
||||
initialValues: { resourceIds: value?.split(MULTIPLE_INPUT_DELIMITER) },
|
||||
onSubmit: (values) => {
|
||||
onChange?.(
|
||||
values.resourceIds
|
||||
.map((e) => e.trim())
|
||||
.filter((e) => !!e)
|
||||
.join(MULTIPLE_INPUT_DELIMITER)
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<ModalForm
|
||||
{...formProps}
|
||||
layout="vertical"
|
||||
form={formInst}
|
||||
modalProps={{ destroyOnHidden: true }}
|
||||
title={t("workflow_node.deploy.form.aliyun_cas_deploy_resource_ids.multiple_input_modal.title")}
|
||||
trigger={trigger}
|
||||
validateTrigger="onSubmit"
|
||||
width={480}
|
||||
>
|
||||
<Form.Item name="resourceIds" rules={[formRule]}>
|
||||
<MultipleInput placeholder={t("workflow_node.deploy.form.aliyun_cas_deploy_resource_ids.multiple_input_modal.placeholder")} />
|
||||
</Form.Item>
|
||||
</ModalForm>
|
||||
);
|
||||
});
|
||||
|
||||
const ContactIdsModalInput = memo(({ value, trigger, onChange }: { value?: string; trigger?: React.ReactNode; onChange?: (value: string) => void }) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const formSchema = z.object({
|
||||
contactIds: z.array(z.string()).refine((v) => {
|
||||
return v.every((e) => !e?.trim() || /^[1-9]\d*$/.test(e));
|
||||
}, t("workflow_node.deploy.form.aliyun_cas_deploy_contact_ids.errmsg.invalid")),
|
||||
});
|
||||
const formRule = createSchemaFieldRule(formSchema);
|
||||
const { form: formInst, formProps } = useAntdForm({
|
||||
name: "workflowNodeDeployConfigFormAliyunCASDeploymentJobContactIdsModalInput",
|
||||
initialValues: { contactIds: value?.split(MULTIPLE_INPUT_DELIMITER) },
|
||||
onSubmit: (values) => {
|
||||
onChange?.(
|
||||
values.contactIds
|
||||
.map((e) => e.trim())
|
||||
.filter((e) => !!e)
|
||||
.join(MULTIPLE_INPUT_DELIMITER)
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<ModalForm
|
||||
{...formProps}
|
||||
layout="vertical"
|
||||
form={formInst}
|
||||
modalProps={{ destroyOnHidden: true }}
|
||||
title={t("workflow_node.deploy.form.aliyun_cas_deploy_contact_ids.multiple_input_modal.title")}
|
||||
trigger={trigger}
|
||||
validateTrigger="onSubmit"
|
||||
width={480}
|
||||
>
|
||||
<Form.Item name="contactIds" rules={[formRule]}>
|
||||
<MultipleInput placeholder={t("workflow_node.deploy.form.aliyun_cas_deploy_contact_ids.multiple_input_modal.placeholder")} />
|
||||
</Form.Item>
|
||||
</ModalForm>
|
||||
);
|
||||
});
|
||||
|
||||
export default DeployNodeConfigFormAliyunCASDeployConfig;
|
||||
|
@ -1,14 +1,10 @@
|
||||
import { memo } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { FormOutlined as FormOutlinedIcon } from "@ant-design/icons";
|
||||
import { Button, Form, type FormInstance, Input, Select, Space } from "antd";
|
||||
import { Form, type FormInstance, Input, Select } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod";
|
||||
|
||||
import ModalForm from "@/components/ModalForm";
|
||||
import MultipleInput from "@/components/MultipleInput";
|
||||
import MultipleSplitValueInput from "@/components/MultipleSplitValueInput";
|
||||
import Show from "@/components/Show";
|
||||
import { useAntdForm } from "@/hooks";
|
||||
|
||||
type DeployNodeConfigFormBaotaPanelSiteConfigFieldValues = Nullish<{
|
||||
siteType: string;
|
||||
@ -71,7 +67,6 @@ const DeployNodeConfigFormBaotaPanelSiteConfig = ({
|
||||
const formRule = createSchemaFieldRule(formSchema);
|
||||
|
||||
const fieldSiteType = Form.useWatch<string>("siteType", formInst);
|
||||
const fieldSiteNames = Form.useWatch<string>("siteNames", formInst);
|
||||
|
||||
const handleFormChange = (_: unknown, values: z.infer<typeof formSchema>) => {
|
||||
onValuesChange?.(values);
|
||||
@ -110,80 +105,21 @@ const DeployNodeConfigFormBaotaPanelSiteConfig = ({
|
||||
|
||||
<Show when={fieldSiteType === SITE_TYPE_OTHER}>
|
||||
<Form.Item
|
||||
name="siteNames"
|
||||
label={t("workflow_node.deploy.form.baotapanel_site_names.label")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.baotapanel_site_names.tooltip") }}></span>}
|
||||
>
|
||||
<Space.Compact style={{ width: "100%" }}>
|
||||
<Form.Item name="siteNames" noStyle rules={[formRule]}>
|
||||
<Input
|
||||
allowClear
|
||||
disabled={disabled}
|
||||
value={fieldSiteNames}
|
||||
placeholder={t("workflow_node.deploy.form.baotapanel_site_names.placeholder")}
|
||||
onChange={(e) => {
|
||||
formInst.setFieldValue("siteNames", e.target.value);
|
||||
}}
|
||||
onClear={() => {
|
||||
formInst.setFieldValue("siteNames", "");
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
<SiteNamesModalInput
|
||||
value={fieldSiteNames}
|
||||
trigger={
|
||||
<Button disabled={disabled}>
|
||||
<FormOutlinedIcon />
|
||||
</Button>
|
||||
}
|
||||
onChange={(value) => {
|
||||
formInst.setFieldValue("siteNames", value);
|
||||
}}
|
||||
/>
|
||||
</Space.Compact>
|
||||
<MultipleSplitValueInput
|
||||
modalTitle={t("workflow_node.deploy.form.baotapanel_site_names.multiple_input_modal.title")}
|
||||
placeholder={t("workflow_node.deploy.form.baotapanel_site_names.placeholder")}
|
||||
placeholderInModal={t("workflow_node.deploy.form.baotapanel_site_names.multiple_input_modal.placeholder")}
|
||||
splitOptions={{ trim: true, removeEmpty: true }}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Show>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
const SiteNamesModalInput = memo(({ value, trigger, onChange }: { value?: string; trigger?: React.ReactNode; onChange?: (value: string) => void }) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const formSchema = z.object({
|
||||
siteNames: z.array(z.string()).refine((v) => {
|
||||
return v.every((e) => !!e?.trim());
|
||||
}, t("workflow_node.deploy.form.baotapanel_site_names.errmsg.invalid")),
|
||||
});
|
||||
const formRule = createSchemaFieldRule(formSchema);
|
||||
const { form: formInst, formProps } = useAntdForm({
|
||||
name: "workflowNodeDeployConfigFormBaotaPanelSiteNamesModalInput",
|
||||
initialValues: { siteNames: value?.split(MULTIPLE_INPUT_DELIMITER) },
|
||||
onSubmit: (values) => {
|
||||
onChange?.(
|
||||
values.siteNames
|
||||
.map((e) => e.trim())
|
||||
.filter((e) => !!e)
|
||||
.join(MULTIPLE_INPUT_DELIMITER)
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<ModalForm
|
||||
{...formProps}
|
||||
layout="vertical"
|
||||
form={formInst}
|
||||
modalProps={{ destroyOnHidden: true }}
|
||||
title={t("workflow_node.deploy.form.baotapanel_site_names.multiple_input_modal.title")}
|
||||
trigger={trigger}
|
||||
validateTrigger="onSubmit"
|
||||
width={480}
|
||||
>
|
||||
<Form.Item name="siteNames" rules={[formRule]}>
|
||||
<MultipleInput placeholder={t("workflow_node.deploy.form.baotapanel_site_names.multiple_input_modal.placeholder")} />
|
||||
</Form.Item>
|
||||
</ModalForm>
|
||||
);
|
||||
});
|
||||
|
||||
export default DeployNodeConfigFormBaotaPanelSiteConfig;
|
||||
|
@ -1,13 +1,9 @@
|
||||
import { memo } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { FormOutlined as FormOutlinedIcon } from "@ant-design/icons";
|
||||
import { Alert, AutoComplete, Button, Form, type FormInstance, Input, Space } from "antd";
|
||||
import { Alert, AutoComplete, Form, type FormInstance, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod";
|
||||
|
||||
import ModalForm from "@/components/ModalForm";
|
||||
import MultipleInput from "@/components/MultipleInput";
|
||||
import { useAntdForm } from "@/hooks";
|
||||
import MultipleSplitValueInput from "@/components/MultipleSplitValueInput";
|
||||
|
||||
type DeployNodeConfigFormTencentCloudSSLDeployConfigFieldValues = Nullish<{
|
||||
region: string;
|
||||
@ -56,8 +52,6 @@ const DeployNodeConfigFormTencentCloudSSLDeployConfig = ({
|
||||
});
|
||||
const formRule = createSchemaFieldRule(formSchema);
|
||||
|
||||
const fieldResourceIds = Form.useWatch<string>("resourceIds", formInst);
|
||||
|
||||
const handleFormChange = (_: unknown, values: z.infer<typeof formSchema>) => {
|
||||
onValuesChange?.(values);
|
||||
};
|
||||
@ -94,36 +88,17 @@ const DeployNodeConfigFormTencentCloudSSLDeployConfig = ({
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="resourceIds"
|
||||
label={t("workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.label")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.tooltip") }}></span>}
|
||||
>
|
||||
<Space.Compact style={{ width: "100%" }}>
|
||||
<Form.Item name="resourceIds" noStyle rules={[formRule]}>
|
||||
<Input
|
||||
allowClear
|
||||
disabled={disabled}
|
||||
value={fieldResourceIds}
|
||||
placeholder={t("workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.placeholder")}
|
||||
onChange={(e) => {
|
||||
formInst.setFieldValue("resourceIds", e.target.value);
|
||||
}}
|
||||
onClear={() => {
|
||||
formInst.setFieldValue("resourceIds", "");
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
<ResourceIdsModalInput
|
||||
value={fieldResourceIds}
|
||||
trigger={
|
||||
<Button disabled={disabled}>
|
||||
<FormOutlinedIcon />
|
||||
</Button>
|
||||
}
|
||||
onChange={(value) => {
|
||||
formInst.setFieldValue("resourceIds", value);
|
||||
}}
|
||||
/>
|
||||
</Space.Compact>
|
||||
<MultipleSplitValueInput
|
||||
modalTitle={t("workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.multiple_input_modal.title")}
|
||||
placeholder={t("workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.placeholder")}
|
||||
placeholderInModal={t("workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.multiple_input_modal.placeholder")}
|
||||
splitOptions={{ trim: true, removeEmpty: true }}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item>
|
||||
@ -133,44 +108,4 @@ const DeployNodeConfigFormTencentCloudSSLDeployConfig = ({
|
||||
);
|
||||
};
|
||||
|
||||
const ResourceIdsModalInput = memo(({ value, trigger, onChange }: { value?: string; trigger?: React.ReactNode; onChange?: (value: string) => void }) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const formSchema = z.object({
|
||||
resourceIds: z.array(z.string()).refine((v) => {
|
||||
return v.every((e) => !e?.trim() || /^[A-Za-z0-9*._-|]+$/.test(e));
|
||||
}, t("workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.errmsg.invalid")),
|
||||
});
|
||||
const formRule = createSchemaFieldRule(formSchema);
|
||||
const { form: formInst, formProps } = useAntdForm({
|
||||
name: "workflowNodeDeployConfigFormTencentCloudSSLDeployResourceIdsModalInput",
|
||||
initialValues: { resourceIds: value?.split(MULTIPLE_INPUT_DELIMITER) },
|
||||
onSubmit: (values) => {
|
||||
onChange?.(
|
||||
values.resourceIds
|
||||
.map((e) => e.trim())
|
||||
.filter((e) => !!e)
|
||||
.join(MULTIPLE_INPUT_DELIMITER)
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<ModalForm
|
||||
{...formProps}
|
||||
layout="vertical"
|
||||
form={formInst}
|
||||
modalProps={{ destroyOnHidden: true }}
|
||||
title={t("workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.multiple_input_modal.title")}
|
||||
trigger={trigger}
|
||||
validateTrigger="onSubmit"
|
||||
width={480}
|
||||
>
|
||||
<Form.Item name="resourceIds" rules={[formRule]}>
|
||||
<MultipleInput placeholder={t("workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.multiple_input_modal.placeholder")} />
|
||||
</Form.Item>
|
||||
</ModalForm>
|
||||
);
|
||||
});
|
||||
|
||||
export default DeployNodeConfigFormTencentCloudSSLDeployConfig;
|
||||
|
@ -1,13 +1,9 @@
|
||||
import { memo } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { FormOutlined as FormOutlinedIcon } from "@ant-design/icons";
|
||||
import { Button, Form, type FormInstance, Input, Space } from "antd";
|
||||
import { Form, type FormInstance } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod";
|
||||
|
||||
import ModalForm from "@/components/ModalForm";
|
||||
import MultipleInput from "@/components/MultipleInput";
|
||||
import { useAntdForm } from "@/hooks";
|
||||
import MultipleSplitValueInput from "@/components/MultipleSplitValueInput";
|
||||
import { validDomainName } from "@/utils/validators";
|
||||
|
||||
type DeployNodeConfigFormWangsuCDNConfigFieldValues = Nullish<{
|
||||
@ -52,8 +48,6 @@ const DeployNodeConfigFormWangsuCDNConfig = ({
|
||||
});
|
||||
const formRule = createSchemaFieldRule(formSchema);
|
||||
|
||||
const fieldDomains = Form.useWatch<string>("domains", formInst);
|
||||
|
||||
const handleFormChange = (_: unknown, values: z.infer<typeof formSchema>) => {
|
||||
onValuesChange?.(values);
|
||||
};
|
||||
@ -68,79 +62,20 @@ const DeployNodeConfigFormWangsuCDNConfig = ({
|
||||
onValuesChange={handleFormChange}
|
||||
>
|
||||
<Form.Item
|
||||
name="domains"
|
||||
label={t("workflow_node.deploy.form.wangsu_cdn_domains.label")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.wangsu_cdn_domains.tooltip") }}></span>}
|
||||
>
|
||||
<Space.Compact style={{ width: "100%" }}>
|
||||
<Form.Item name="domains" noStyle rules={[formRule]}>
|
||||
<Input
|
||||
allowClear
|
||||
disabled={disabled}
|
||||
value={fieldDomains}
|
||||
placeholder={t("workflow_node.deploy.form.wangsu_cdn_domains.placeholder")}
|
||||
onChange={(e) => {
|
||||
formInst.setFieldValue("domains", e.target.value);
|
||||
}}
|
||||
onClear={() => {
|
||||
formInst.setFieldValue("domains", "");
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
<SiteNamesModalInput
|
||||
value={fieldDomains}
|
||||
trigger={
|
||||
<Button disabled={disabled}>
|
||||
<FormOutlinedIcon />
|
||||
</Button>
|
||||
}
|
||||
onChange={(value) => {
|
||||
formInst.setFieldValue("domains", value);
|
||||
}}
|
||||
/>
|
||||
</Space.Compact>
|
||||
<MultipleSplitValueInput
|
||||
modalTitle={t("workflow_node.deploy.form.wangsu_cdn_domains.multiple_input_modal.title")}
|
||||
placeholder={t("workflow_node.deploy.form.wangsu_cdn_domains.placeholder")}
|
||||
placeholderInModal={t("workflow_node.deploy.form.wangsu_cdn_domains.multiple_input_modal.placeholder")}
|
||||
splitOptions={{ trim: true, removeEmpty: true }}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
const SiteNamesModalInput = memo(({ value, trigger, onChange }: { value?: string; trigger?: React.ReactNode; onChange?: (value: string) => void }) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const formSchema = z.object({
|
||||
domains: z.array(z.string()).refine((v) => {
|
||||
return v.every((e) => validDomainName(e));
|
||||
}, t("workflow_node.deploy.form.wangsu_cdn_domains.errmsg.invalid")),
|
||||
});
|
||||
const formRule = createSchemaFieldRule(formSchema);
|
||||
const { form: formInst, formProps } = useAntdForm({
|
||||
name: "workflowNodeDeployConfigFormWangsuCDNNamesModalInput",
|
||||
initialValues: { domains: value?.split(MULTIPLE_INPUT_DELIMITER) },
|
||||
onSubmit: (values) => {
|
||||
onChange?.(
|
||||
values.domains
|
||||
.map((e) => e.trim())
|
||||
.filter((e) => !!e)
|
||||
.join(MULTIPLE_INPUT_DELIMITER)
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<ModalForm
|
||||
{...formProps}
|
||||
layout="vertical"
|
||||
form={formInst}
|
||||
modalProps={{ destroyOnHidden: true }}
|
||||
title={t("workflow_node.deploy.form.wangsu_cdn_domains.multiple_input_modal.title")}
|
||||
trigger={trigger}
|
||||
validateTrigger="onSubmit"
|
||||
width={480}
|
||||
>
|
||||
<Form.Item name="domains" rules={[formRule]}>
|
||||
<MultipleInput placeholder={t("workflow_node.deploy.form.wangsu_cdn_domains.multiple_input_modal.placeholder")} />
|
||||
</Form.Item>
|
||||
</ModalForm>
|
||||
);
|
||||
});
|
||||
|
||||
export default DeployNodeConfigFormWangsuCDNConfig;
|
||||
|
@ -1,9 +1,11 @@
|
||||
{
|
||||
"workflow_node.action.configure_node": "Configure node",
|
||||
"workflow_node.action.add_node": "Add node",
|
||||
"workflow_node.action.duplicate_node": "Duplicate node",
|
||||
"workflow_node.action.rename_node": "Rename node",
|
||||
"workflow_node.action.remove_node": "Delete node",
|
||||
"workflow_node.action.add_branch": "Add branch",
|
||||
"workflow_node.action.duplicate_branch": "Duplicate branch",
|
||||
"workflow_node.action.rename_branch": "Rename branch",
|
||||
"workflow_node.action.remove_branch": "Delete branch",
|
||||
|
||||
|
@ -1,9 +1,11 @@
|
||||
{
|
||||
"workflow_node.action.configure_node": "配置节点",
|
||||
"workflow_node.branch.add_node": "添加节点",
|
||||
"workflow_node.action.duplicate_node": "复制节点",
|
||||
"workflow_node.action.rename_node": "重命名",
|
||||
"workflow_node.action.remove_node": "删除节点",
|
||||
"workflow_node.action.add_branch": "添加并行分支",
|
||||
"workflow_node.action.duplicate_branch": "复制分支",
|
||||
"workflow_node.action.rename_branch": "重命名",
|
||||
"workflow_node.action.remove_branch": "删除分支",
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user