From 3d5f2f4bfccff80905361410edb13b1a4a7b445d Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Thu, 4 Sep 2025 20:56:58 +0800 Subject: [PATCH] feat(ui): auto set provider access after pick provider --- .../forms/BizDeployNodeConfigForm.tsx | 53 +++++++++++-------- .../forms/BizNotifyNodeConfigForm.tsx | 38 ++++++++----- 2 files changed, 56 insertions(+), 35 deletions(-) diff --git a/ui/src/components/workflow/designer/forms/BizDeployNodeConfigForm.tsx b/ui/src/components/workflow/designer/forms/BizDeployNodeConfigForm.tsx index d88acb81..ce15be7a 100644 --- a/ui/src/components/workflow/designer/forms/BizDeployNodeConfigForm.tsx +++ b/ui/src/components/workflow/designer/forms/BizDeployNodeConfigForm.tsx @@ -11,9 +11,11 @@ import AccessSelect from "@/components/access/AccessSelect"; import DeploymentProviderPicker from "@/components/provider/DeploymentProviderPicker"; import DeploymentProviderSelect from "@/components/provider/DeploymentProviderSelect"; import Show from "@/components/Show"; +import { type AccessModel } from "@/domain/access"; import { ACCESS_USAGES, DEPLOYMENT_PROVIDERS, accessProvidersMap, deploymentProvidersMap } from "@/domain/provider"; import { type WorkflowNodeConfigForBizDeploy, defaultNodeConfigForBizDeploy } from "@/domain/workflow"; -import { useAntdForm } from "@/hooks"; +import { useAntdForm, useZustandShallowSelector } from "@/hooks"; +import { useAccessesStore } from "@/stores/access"; import { getAllPreviousNodes } from "../_util"; import { FormNestedFieldsContextProvider, NodeFormContextProvider } from "./_context"; @@ -126,6 +128,12 @@ const BizDeployNodeConfigForm = ({ node, ...props }: BizDeployNodeConfigFormProp const { token: themeToken } = theme.useToken(); + const { accesses } = useAccessesStore(useZustandShallowSelector("accesses")); + const accessOptionFilter = (_: string, option: AccessModel) => { + if (option.reserve) return false; + return deploymentProvidersMap.get(fieldProvider)?.provider === option.provider; + }; + const initialValues = useMemo(() => { return getNodeForm(node)?.getValueIn("config") as WorkflowNodeConfigForBizDeploy | undefined; }, [node]); @@ -149,6 +157,7 @@ const BizDeployNodeConfigForm = ({ node, ...props }: BizDeployNodeConfigFormProp }); const fieldProvider = Form.useWatch("provider", { form: formInst, preserve: true }); + const fieldProviderAccessId = Form.useWatch("providerAccessId", { form: formInst, preserve: true }); const certificateOutputNodeIdOptions = useMemo(() => { return getAllPreviousNodes(node) @@ -460,6 +469,24 @@ const BizDeployNodeConfigForm = ({ node, ...props }: BizDeployNodeConfigFormProp } }, [fieldProvider]); + useEffect(() => { + // 如果未选择部署目标,则清空授权信息 + if (!fieldProvider && fieldProviderAccessId) { + formInst.setFieldValue("providerAccessId", void 0); + return; + } + + // 如果已选择部署目标只有一个授权信息,则自动选择该授权信息 + if (fieldProvider && !fieldProviderAccessId) { + const availableAccesses = accesses + .filter((access) => accessOptionFilter(access.provider, access)) + .filter((access) => access.provider === deploymentProvidersMap.get(fieldProvider)?.provider); + if (availableAccesses.length === 1) { + formInst.setFieldValue("providerAccessId", availableAccesses[0].id); + } + } + }, [fieldProvider, fieldProviderAccessId]); + const handleProviderPick = (value: string) => { formInst.setFieldValue("provider", value); }; @@ -469,20 +496,7 @@ const BizDeployNodeConfigForm = ({ node, ...props }: BizDeployNodeConfigFormProp if (initialValues?.provider === value) { formInst.resetFields(["providerConfig"]); } else { - const oldValues = formInst.getFieldsValue(); - const newValues: Record = {}; - for (const key in oldValues) { - if (key === "certificateOutputNodeId" || key === "provider" || key === "providerAccessId" || key === "skipOnLastSucceeded") { - newValues[key] = oldValues[key]; - } else { - delete newValues[key]; - } - } - formInst.setFieldsValue(newValues); - - if (deploymentProvidersMap.get(fieldProvider)?.provider !== deploymentProvidersMap.get(value!)?.provider) { - formInst.setFieldValue("providerAccessId", void 0); - } + formInst.setFieldValue("providerConfig", void 0); } }; @@ -532,14 +546,7 @@ const BizDeployNodeConfigForm = ({ node, ...props }: BizDeployNodeConfigFormProp /> - { - if (option.reserve) return false; - return deploymentProvidersMap.get(fieldProvider)?.provider === option.provider; - }} - /> + diff --git a/ui/src/components/workflow/designer/forms/BizNotifyNodeConfigForm.tsx b/ui/src/components/workflow/designer/forms/BizNotifyNodeConfigForm.tsx index 8e7733f6..57c4791d 100644 --- a/ui/src/components/workflow/designer/forms/BizNotifyNodeConfigForm.tsx +++ b/ui/src/components/workflow/designer/forms/BizNotifyNodeConfigForm.tsx @@ -1,4 +1,4 @@ -import { useMemo } from "react"; +import { useEffect, useMemo } from "react"; import { getI18n, useTranslation } from "react-i18next"; import { type FlowNodeEntity, getNodeForm } from "@flowgram.ai/fixed-layout-editor"; import { IconPlus } from "@tabler/icons-react"; @@ -11,6 +11,7 @@ import AccessSelect from "@/components/access/AccessSelect"; import NotificationProviderPicker from "@/components/provider/NotificationProviderPicker"; import NotificationProviderSelect from "@/components/provider/NotificationProviderSelect"; import Show from "@/components/Show"; +import { type AccessModel } from "@/domain/access"; import { ACCESS_USAGES, NOTIFICATION_PROVIDERS, accessProvidersMap, notificationProvidersMap } from "@/domain/provider"; import { type WorkflowNodeConfigForBizNotify, defaultNodeConfigForBizNotify } from "@/domain/workflow"; import { useAntdForm, useZustandShallowSelector } from "@/hooks"; @@ -38,6 +39,10 @@ const BizNotifyNodeConfigForm = ({ node, ...props }: BizNotifyNodeConfigFormProp const { i18n, t } = useTranslation(); const { accesses } = useAccessesStore(useZustandShallowSelector("accesses")); + const accessOptionFilter = (_: string, option: AccessModel) => { + if (option.reserve !== "notif") return false; + return notificationProvidersMap.get(fieldProvider)?.provider === option.provider; + }; const initialValues = useMemo(() => { return getNodeForm(node)?.getValueIn("config") as WorkflowNodeConfigForBizNotify | undefined; @@ -81,6 +86,24 @@ const BizNotifyNodeConfigForm = ({ node, ...props }: BizNotifyNodeConfigFormProp } }, [fieldProvider]); + useEffect(() => { + // 如果未选择通知渠道,则清空授权信息 + if (!fieldProvider && fieldProviderAccessId) { + formInst.setFieldValue("providerAccessId", void 0); + return; + } + + // 如果已选择通知渠道只有一个授权信息,则自动选择该授权信息 + if (fieldProvider && !fieldProviderAccessId) { + const availableAccesses = accesses + .filter((access) => accessOptionFilter(access.provider, access)) + .filter((access) => access.provider === notificationProvidersMap.get(fieldProvider)?.provider); + if (availableAccesses.length === 1) { + formInst.setFieldValue("providerAccessId", availableAccesses[0].id); + } + } + }, [fieldProvider, fieldProviderAccessId]); + const handleProviderPick = (value: string) => { formInst.setFieldValue("provider", value); }; @@ -90,9 +113,7 @@ const BizNotifyNodeConfigForm = ({ node, ...props }: BizNotifyNodeConfigFormProp if (initialValues?.provider === value) { formInst.resetFields(["providerConfig"]); } else { - if (notificationProvidersMap.get(fieldProvider)?.provider !== notificationProvidersMap.get(value!)?.provider) { - formInst.setFieldValue("providerAccessId", void 0); - } + formInst.setFieldValue("providerConfig", void 0); } }; @@ -152,14 +173,7 @@ const BizNotifyNodeConfigForm = ({ node, ...props }: BizNotifyNodeConfigFormProp /> - { - if (option.reserve !== "notif") return false; - return notificationProvidersMap.get(fieldProvider)?.provider === option.provider; - }} - /> +