import { forwardRef, memo, useEffect, useImperativeHandle, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; import { PlusOutlined as PlusOutlinedIcon, QuestionCircleOutlined as QuestionCircleOutlinedIcon } from "@ant-design/icons"; import { Alert, Button, Divider, Flex, Form, type FormInstance, Select, Switch, Tooltip, Typography } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; import AccessEditModal from "@/components/access/AccessEditModal"; import AccessSelect from "@/components/access/AccessSelect"; import DeploymentProviderPicker from "@/components/provider/DeploymentProviderPicker.tsx"; import DeploymentProviderSelect from "@/components/provider/DeploymentProviderSelect.tsx"; import Show from "@/components/Show"; import { ACCESS_USAGES, DEPLOYMENT_PROVIDERS, accessProvidersMap, deploymentProvidersMap } from "@/domain/provider"; import { type WorkflowNode, type WorkflowNodeConfigForDeploy } from "@/domain/workflow"; import { useAntdForm, useAntdFormName, useZustandShallowSelector } from "@/hooks"; import { useWorkflowStore } from "@/stores/workflow"; import DeployNodeConfigForm1PanelConsoleConfig from "./DeployNodeConfigForm1PanelConsoleConfig"; import DeployNodeConfigForm1PanelSiteConfig from "./DeployNodeConfigForm1PanelSiteConfig"; import DeployNodeConfigFormAliyunALBConfig from "./DeployNodeConfigFormAliyunALBConfig"; import DeployNodeConfigFormAliyunAPIGWConfig from "./DeployNodeConfigFormAliyunAPIGWConfig"; import DeployNodeConfigFormAliyunCASConfig from "./DeployNodeConfigFormAliyunCASConfig"; import DeployNodeConfigFormAliyunCASDeployConfig from "./DeployNodeConfigFormAliyunCASDeployConfig"; import DeployNodeConfigFormAliyunCDNConfig from "./DeployNodeConfigFormAliyunCDNConfig"; import DeployNodeConfigFormAliyunCLBConfig from "./DeployNodeConfigFormAliyunCLBConfig"; import DeployNodeConfigFormAliyunDCDNConfig from "./DeployNodeConfigFormAliyunDCDNConfig"; import DeployNodeConfigFormAliyunESAConfig from "./DeployNodeConfigFormAliyunESAConfig"; import DeployNodeConfigFormAliyunFCConfig from "./DeployNodeConfigFormAliyunFCConfig"; import DeployNodeConfigFormAliyunLiveConfig from "./DeployNodeConfigFormAliyunLiveConfig"; import DeployNodeConfigFormAliyunNLBConfig from "./DeployNodeConfigFormAliyunNLBConfig"; import DeployNodeConfigFormAliyunOSSConfig from "./DeployNodeConfigFormAliyunOSSConfig"; import DeployNodeConfigFormAliyunVODConfig from "./DeployNodeConfigFormAliyunVODConfig"; import DeployNodeConfigFormAliyunWAFConfig from "./DeployNodeConfigFormAliyunWAFConfig"; import DeployNodeConfigFormAWSACMConfig from "./DeployNodeConfigFormAWSACMConfig"; import DeployNodeConfigFormAWSCloudFrontConfig from "./DeployNodeConfigFormAWSCloudFrontConfig"; import DeployNodeConfigFormAzureKeyVaultConfig from "./DeployNodeConfigFormAzureKeyVaultConfig"; import DeployNodeConfigFormBaiduCloudAppBLBConfig from "./DeployNodeConfigFormBaiduCloudAppBLBConfig"; import DeployNodeConfigFormBaiduCloudBLBConfig from "./DeployNodeConfigFormBaiduCloudBLBConfig"; import DeployNodeConfigFormBaiduCloudCDNConfig from "./DeployNodeConfigFormBaiduCloudCDNConfig"; import DeployNodeConfigFormBaishanCDNConfig from "./DeployNodeConfigFormBaishanCDNConfig"; import DeployNodeConfigFormBaotaPanelConsoleConfig from "./DeployNodeConfigFormBaotaPanelConsoleConfig"; import DeployNodeConfigFormBaotaPanelSiteConfig from "./DeployNodeConfigFormBaotaPanelSiteConfig"; import DeployNodeConfigFormBunnyCDNConfig from "./DeployNodeConfigFormBunnyCDNConfig.tsx"; import DeployNodeConfigFormBytePlusCDNConfig from "./DeployNodeConfigFormBytePlusCDNConfig"; import DeployNodeConfigFormCdnflyConfig from "./DeployNodeConfigFormCdnflyConfig"; import DeployNodeConfigFormDogeCloudCDNConfig from "./DeployNodeConfigFormDogeCloudCDNConfig"; import DeployNodeConfigFormEdgioApplicationsConfig from "./DeployNodeConfigFormEdgioApplicationsConfig"; import DeployNodeConfigFormGcoreCDNConfig from "./DeployNodeConfigFormGcoreCDNConfig"; import DeployNodeConfigFormHuaweiCloudCDNConfig from "./DeployNodeConfigFormHuaweiCloudCDNConfig"; import DeployNodeConfigFormHuaweiCloudELBConfig from "./DeployNodeConfigFormHuaweiCloudELBConfig"; import DeployNodeConfigFormHuaweiCloudWAFConfig from "./DeployNodeConfigFormHuaweiCloudWAFConfig"; import DeployNodeConfigFormJDCloudALBConfig from "./DeployNodeConfigFormJDCloudALBConfig"; import DeployNodeConfigFormJDCloudCDNConfig from "./DeployNodeConfigFormJDCloudCDNConfig"; import DeployNodeConfigFormJDCloudLiveConfig from "./DeployNodeConfigFormJDCloudLiveConfig"; import DeployNodeConfigFormJDCloudVODConfig from "./DeployNodeConfigFormJDCloudVODConfig"; import DeployNodeConfigFormKubernetesSecretConfig from "./DeployNodeConfigFormKubernetesSecretConfig"; import DeployNodeConfigFormLocalConfig from "./DeployNodeConfigFormLocalConfig"; import DeployNodeConfigFormQiniuCDNConfig from "./DeployNodeConfigFormQiniuCDNConfig"; import DeployNodeConfigFormQiniuKodoConfig from "./DeployNodeConfigFormQiniuKodoConfig"; import DeployNodeConfigFormQiniuPiliConfig from "./DeployNodeConfigFormQiniuPiliConfig"; import DeployNodeConfigFormRainYunRCDNConfig from "./DeployNodeConfigFormRainYunRCDNConfig"; import DeployNodeConfigFormSafeLineConfig from "./DeployNodeConfigFormSafeLineConfig"; import DeployNodeConfigFormSSHConfig from "./DeployNodeConfigFormSSHConfig.tsx"; import DeployNodeConfigFormTencentCloudCDNConfig from "./DeployNodeConfigFormTencentCloudCDNConfig.tsx"; import DeployNodeConfigFormTencentCloudCLBConfig from "./DeployNodeConfigFormTencentCloudCLBConfig.tsx"; import DeployNodeConfigFormTencentCloudCOSConfig from "./DeployNodeConfigFormTencentCloudCOSConfig.tsx"; import DeployNodeConfigFormTencentCloudCSSConfig from "./DeployNodeConfigFormTencentCloudCSSConfig.tsx"; import DeployNodeConfigFormTencentCloudECDNConfig from "./DeployNodeConfigFormTencentCloudECDNConfig.tsx"; import DeployNodeConfigFormTencentCloudEOConfig from "./DeployNodeConfigFormTencentCloudEOConfig.tsx"; import DeployNodeConfigFormTencentCloudSCFConfig from "./DeployNodeConfigFormTencentCloudSCFConfig"; import DeployNodeConfigFormTencentCloudSSLDeployConfig from "./DeployNodeConfigFormTencentCloudSSLDeployConfig"; import DeployNodeConfigFormTencentCloudVODConfig from "./DeployNodeConfigFormTencentCloudVODConfig"; import DeployNodeConfigFormTencentCloudWAFConfig from "./DeployNodeConfigFormTencentCloudWAFConfig"; import DeployNodeConfigFormUCloudUCDNConfig from "./DeployNodeConfigFormUCloudUCDNConfig.tsx"; import DeployNodeConfigFormUCloudUS3Config from "./DeployNodeConfigFormUCloudUS3Config.tsx"; import DeployNodeConfigFormUpyunCDNConfig from "./DeployNodeConfigFormUpyunCDNConfig.tsx"; import DeployNodeConfigFormUpyunFileConfig from "./DeployNodeConfigFormUpyunFileConfig.tsx"; import DeployNodeConfigFormVolcEngineALBConfig from "./DeployNodeConfigFormVolcEngineALBConfig.tsx"; import DeployNodeConfigFormVolcEngineCDNConfig from "./DeployNodeConfigFormVolcEngineCDNConfig.tsx"; import DeployNodeConfigFormVolcEngineCertCenterConfig from "./DeployNodeConfigFormVolcEngineCertCenterConfig.tsx"; import DeployNodeConfigFormVolcEngineCLBConfig from "./DeployNodeConfigFormVolcEngineCLBConfig.tsx"; import DeployNodeConfigFormVolcEngineDCDNConfig from "./DeployNodeConfigFormVolcEngineDCDNConfig.tsx"; import DeployNodeConfigFormVolcEngineImageXConfig from "./DeployNodeConfigFormVolcEngineImageXConfig.tsx"; import DeployNodeConfigFormVolcEngineLiveConfig from "./DeployNodeConfigFormVolcEngineLiveConfig.tsx"; import DeployNodeConfigFormVolcEngineTOSConfig from "./DeployNodeConfigFormVolcEngineTOSConfig.tsx"; import DeployNodeConfigFormWangsuCDNProConfig from "./DeployNodeConfigFormWangsuCDNProConfig.tsx"; import DeployNodeConfigFormWebhookConfig from "./DeployNodeConfigFormWebhookConfig.tsx"; type DeployNodeConfigFormFieldValues = Partial; export type DeployNodeConfigFormProps = { className?: string; style?: React.CSSProperties; disabled?: boolean; initialValues?: DeployNodeConfigFormFieldValues; nodeId: string; onValuesChange?: (values: DeployNodeConfigFormFieldValues) => void; }; export type DeployNodeConfigFormInstance = { getFieldsValue: () => ReturnType["getFieldsValue"]>; resetFields: FormInstance["resetFields"]; validateFields: FormInstance["validateFields"]; }; const initFormModel = (): DeployNodeConfigFormFieldValues => { return { skipOnLastSucceeded: true, }; }; const DeployNodeConfigForm = forwardRef( ({ className, style, disabled, initialValues, nodeId, onValuesChange }, ref) => { const { t } = useTranslation(); const { getWorkflowOuptutBeforeId } = useWorkflowStore(useZustandShallowSelector(["updateNode", "getWorkflowOuptutBeforeId"])); // TODO: 优化此处逻辑 const [previousNodes, setPreviousNodes] = useState([]); useEffect(() => { const previousNodes = getWorkflowOuptutBeforeId(nodeId, "certificate"); setPreviousNodes(previousNodes); }, [nodeId]); const formSchema = z.object({ certificate: z .string({ message: t("workflow_node.deploy.form.certificate.placeholder") }) .nonempty(t("workflow_node.deploy.form.certificate.placeholder")), provider: z.string({ message: t("workflow_node.deploy.form.provider.placeholder") }).nonempty(t("workflow_node.deploy.form.provider.placeholder")), providerAccessId: z .string({ message: t("workflow_node.deploy.form.provider_access.placeholder") }) .nullish() .refine((v) => { if (!fieldProvider) return true; const provider = deploymentProvidersMap.get(fieldProvider); return !!provider?.builtin || !!v; }, t("workflow_node.deploy.form.provider_access.placeholder")), providerConfig: z.any().nullish(), skipOnLastSucceeded: z.boolean().nullish(), }); const formRule = createSchemaFieldRule(formSchema); const { form: formInst, formProps } = useAntdForm({ name: "workflowNodeDeployConfigForm", initialValues: initialValues ?? initFormModel(), }); const fieldProvider = Form.useWatch("provider", { form: formInst, preserve: true }); const [showProviderAccess, setShowProviderAccess] = useState(false); useEffect(() => { // 内置的部署提供商(如本地部署)无需显示授权信息字段 if (fieldProvider) { const provider = deploymentProvidersMap.get(fieldProvider); setShowProviderAccess(!provider?.builtin); } else { setShowProviderAccess(false); } }, [fieldProvider]); const [nestedFormInst] = Form.useForm(); const nestedFormName = useAntdFormName({ form: nestedFormInst, name: "workflowNodeDeployConfigFormProviderConfigForm" }); const nestedFormEl = useMemo(() => { const nestedFormProps = { form: nestedFormInst, formName: nestedFormName, disabled: disabled, initialValues: initialValues?.providerConfig, }; /* 注意:如果追加新的子组件,请保持以 ASCII 排序。 NOTICE: If you add new child component, please keep ASCII order. */ switch (fieldProvider) { case DEPLOYMENT_PROVIDERS["1PANEL_CONSOLE"]: return ; case DEPLOYMENT_PROVIDERS["1PANEL_SITE"]: return ; case DEPLOYMENT_PROVIDERS.ALIYUN_ALB: return ; case DEPLOYMENT_PROVIDERS.ALIYUN_APIGW: return ; case DEPLOYMENT_PROVIDERS.ALIYUN_CAS: return ; case DEPLOYMENT_PROVIDERS.ALIYUN_CAS_DEPLOY: return ; case DEPLOYMENT_PROVIDERS.ALIYUN_CLB: return ; case DEPLOYMENT_PROVIDERS.ALIYUN_CDN: return ; case DEPLOYMENT_PROVIDERS.ALIYUN_DCDN: return ; case DEPLOYMENT_PROVIDERS.ALIYUN_ESA: return ; case DEPLOYMENT_PROVIDERS.ALIYUN_FC: return ; case DEPLOYMENT_PROVIDERS.ALIYUN_LIVE: return ; case DEPLOYMENT_PROVIDERS.ALIYUN_NLB: return ; case DEPLOYMENT_PROVIDERS.ALIYUN_OSS: return ; case DEPLOYMENT_PROVIDERS.ALIYUN_VOD: return ; case DEPLOYMENT_PROVIDERS.ALIYUN_WAF: return ; case DEPLOYMENT_PROVIDERS.AWS_ACM: return ; case DEPLOYMENT_PROVIDERS.AWS_CLOUDFRONT: return ; case DEPLOYMENT_PROVIDERS.AZURE_KEYVAULT: return ; case DEPLOYMENT_PROVIDERS.BAIDUCLOUD_APPBLB: return ; case DEPLOYMENT_PROVIDERS.BAIDUCLOUD_BLB: return ; case DEPLOYMENT_PROVIDERS.BAIDUCLOUD_CDN: return ; case DEPLOYMENT_PROVIDERS.BAISHAN_CDN: return ; case DEPLOYMENT_PROVIDERS.BAOTAPANEL_CONSOLE: return ; case DEPLOYMENT_PROVIDERS.BAOTAPANEL_SITE: return ; case DEPLOYMENT_PROVIDERS.BUNNY_CDN: return ; case DEPLOYMENT_PROVIDERS.BYTEPLUS_CDN: return ; case DEPLOYMENT_PROVIDERS.CDNFLY: return ; case DEPLOYMENT_PROVIDERS.DOGECLOUD_CDN: return ; case DEPLOYMENT_PROVIDERS.EDGIO_APPLICATIONS: return ; case DEPLOYMENT_PROVIDERS.GCORE_CDN: return ; case DEPLOYMENT_PROVIDERS.HUAWEICLOUD_CDN: return ; case DEPLOYMENT_PROVIDERS.HUAWEICLOUD_ELB: return ; case DEPLOYMENT_PROVIDERS.HUAWEICLOUD_WAF: return ; case DEPLOYMENT_PROVIDERS.JDCLOUD_ALB: return ; case DEPLOYMENT_PROVIDERS.JDCLOUD_CDN: return ; case DEPLOYMENT_PROVIDERS.JDCLOUD_LIVE: return ; case DEPLOYMENT_PROVIDERS.JDCLOUD_VOD: return ; case DEPLOYMENT_PROVIDERS.KUBERNETES_SECRET: return ; case DEPLOYMENT_PROVIDERS.LOCAL: return ; case DEPLOYMENT_PROVIDERS.QINIU_CDN: return ; case DEPLOYMENT_PROVIDERS.QINIU_KODO: return ; case DEPLOYMENT_PROVIDERS.QINIU_PILI: return ; case DEPLOYMENT_PROVIDERS.RAINYUN_RCDN: return ; case DEPLOYMENT_PROVIDERS.SAFELINE: return ; case DEPLOYMENT_PROVIDERS.SSH: return ; case DEPLOYMENT_PROVIDERS.TENCENTCLOUD_CDN: return ; case DEPLOYMENT_PROVIDERS.TENCENTCLOUD_CLB: return ; case DEPLOYMENT_PROVIDERS.TENCENTCLOUD_COS: return ; case DEPLOYMENT_PROVIDERS.TENCENTCLOUD_CSS: return ; case DEPLOYMENT_PROVIDERS.TENCENTCLOUD_ECDN: return ; case DEPLOYMENT_PROVIDERS.TENCENTCLOUD_EO: return ; case DEPLOYMENT_PROVIDERS.TENCENTCLOUD_SCF: return ; case DEPLOYMENT_PROVIDERS.TENCENTCLOUD_SSL_DEPLOY: return ; case DEPLOYMENT_PROVIDERS.TENCENTCLOUD_VOD: return ; case DEPLOYMENT_PROVIDERS.TENCENTCLOUD_WAF: return ; case DEPLOYMENT_PROVIDERS.UCLOUD_UCDN: return ; case DEPLOYMENT_PROVIDERS.UCLOUD_US3: return ; case DEPLOYMENT_PROVIDERS.UPYUN_CDN: return ; case DEPLOYMENT_PROVIDERS.UPYUN_FILE: return ; case DEPLOYMENT_PROVIDERS.VOLCENGINE_ALB: return ; case DEPLOYMENT_PROVIDERS.VOLCENGINE_CDN: return ; case DEPLOYMENT_PROVIDERS.VOLCENGINE_CERTCENTER: return ; case DEPLOYMENT_PROVIDERS.VOLCENGINE_CLB: return ; case DEPLOYMENT_PROVIDERS.VOLCENGINE_DCDN: return ; case DEPLOYMENT_PROVIDERS.VOLCENGINE_IMAGEX: return ; case DEPLOYMENT_PROVIDERS.VOLCENGINE_LIVE: return ; case DEPLOYMENT_PROVIDERS.VOLCENGINE_TOS: return ; case DEPLOYMENT_PROVIDERS.WANGSU_CDNPRO: return ; case DEPLOYMENT_PROVIDERS.WEBHOOK: return ; } }, [disabled, initialValues?.providerConfig, fieldProvider, nestedFormInst, nestedFormName]); const handleProviderPick = (value: string) => { formInst.setFieldValue("provider", value); onValuesChange?.(formInst.getFieldsValue(true)); }; const handleProviderSelect = (value?: string | undefined) => { // 切换部署目标时重置表单,避免其他部署目标的配置字段影响当前部署目标 if (initialValues?.provider === value) { formInst.resetFields(); } else { const oldValues = formInst.getFieldsValue(); const newValues: Record = {}; for (const key in oldValues) { if (key === "provider" || key === "providerAccessId" || key === "certificate" || key === "skipOnLastSucceeded") { newValues[key] = oldValues[key]; } else { newValues[key] = undefined; } } formInst.setFieldsValue(newValues); if (deploymentProvidersMap.get(fieldProvider)?.provider !== deploymentProvidersMap.get(value!)?.provider) { formInst.setFieldValue("providerAccessId", undefined); onValuesChange?.(formInst.getFieldsValue(true)); } } }; const handleFormProviderChange = (name: string) => { if (name === nestedFormName) { formInst.setFieldValue("providerConfig", nestedFormInst.getFieldsValue()); onValuesChange?.(formInst.getFieldsValue(true)); } }; const handleFormChange = (_: unknown, values: z.infer) => { onValuesChange?.(values as DeployNodeConfigFormFieldValues); }; useImperativeHandle(ref, () => { return { getFieldsValue: () => { const values = formInst.getFieldsValue(true); values.providerConfig = nestedFormInst.getFieldsValue(); return values; }, resetFields: (fields) => { formInst.resetFields(fields); if (!!fields && fields.includes("providerConfig")) { nestedFormInst.resetFields(fields); } }, validateFields: (nameList, config) => { const t1 = formInst.validateFields(nameList, config); const t2 = nestedFormInst.validateFields(undefined, config); return Promise.all([t1, t2]).then(() => t1); }, } as DeployNodeConfigFormInstance; }); return (
} > } /> } >