From abd1a1a9baabbd2300323028855d9efc42d88ab2 Mon Sep 17 00:00:00 2001 From: fdc310 <2213070223@qq.com> Date: Thu, 1 Oct 2026 05:13:21 +0800 Subject: [PATCH] fix(web): hide duplicate connection mode control --- .../home/bots/components/bot-form/BotForm.tsx | 9 +++++++ .../dynamic-form/DynamicFormComponent.tsx | 5 ++++ web/tests/unit/oss-cloud-ui-privacy.test.mjs | 24 +++++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/web/src/app/home/bots/components/bot-form/BotForm.tsx b/web/src/app/home/bots/components/bot-form/BotForm.tsx index d8b6f2123..56bed64af 100644 --- a/web/src/app/home/bots/components/bot-form/BotForm.tsx +++ b/web/src/app/home/bots/components/bot-form/BotForm.tsx @@ -552,6 +552,14 @@ const BotForm = forwardRef(function BotForm( [adapterNameToDynamicConfigMap, currentAdapter], ); + const connectionModeControllerNames = useMemo(() => { + if (supportedConnectionModes.length <= 1) return []; + const webhookField = dynamicFormConfigList.find( + (item) => item.type === DynamicFormItemType.WEBHOOK_URL, + ); + return webhookField?.show_if?.field ? [webhookField.show_if.field] : []; + }, [dynamicFormConfigList, supportedConnectionModes.length]); + const botGuideSteps = useMemo(() => { const steps: GuidedTourStep[] = []; @@ -1140,6 +1148,7 @@ const BotForm = forwardRef(function BotForm(
{ form.setValue('adapter_config', values, { diff --git a/web/src/app/home/components/dynamic-form/DynamicFormComponent.tsx b/web/src/app/home/components/dynamic-form/DynamicFormComponent.tsx index 5ec6eff88..c8d9074fa 100644 --- a/web/src/app/home/components/dynamic-form/DynamicFormComponent.tsx +++ b/web/src/app/home/components/dynamic-form/DynamicFormComponent.tsx @@ -441,6 +441,7 @@ export default function DynamicFormComponent({ systemContext, onValidate, renderItem, + hiddenItemNames, }: { itemConfigList: IDynamicFormItemSchema[]; onSubmit?: (val: object) => unknown; @@ -463,6 +464,8 @@ export default function DynamicFormComponent({ formValues: Record; setFormValue: (name: string, value: unknown) => void; }) => ReactNode | undefined; + /** Fields retained in form state but omitted from the rendered form. */ + hiddenItemNames?: readonly string[]; }) { const isInitialMount = useRef(true); const previousInitialValues = useRef(initialValues); @@ -647,6 +650,8 @@ export default function DynamicFormComponent({ /> {itemConfigList.map((config, index) => { + if (hiddenItemNames?.includes(config.name)) return null; + // Create a normalized config with type converted to frontend format const normalizedConfig = { ...config, diff --git a/web/tests/unit/oss-cloud-ui-privacy.test.mjs b/web/tests/unit/oss-cloud-ui-privacy.test.mjs index 4481aa18f..41a81e375 100644 --- a/web/tests/unit/oss-cloud-ui-privacy.test.mjs +++ b/web/tests/unit/oss-cloud-ui-privacy.test.mjs @@ -17,6 +17,9 @@ const homeSidebarSource = readSource( const botFormSource = readSource( 'src/app/home/bots/components/bot-form/BotForm.tsx', ); +const dynamicFormSource = readSource( + 'src/app/home/components/dynamic-form/DynamicFormComponent.tsx', +); const kbFormSource = readSource( 'src/app/home/knowledge/components/kb-form/KBForm.tsx', ); @@ -52,6 +55,27 @@ test('keeps bot forms spaced with responsive setup and detail columns', () => { assert.match(kbFormSource, / { + assert.match( + botFormSource, + /webhookField\?\.show_if\?\.field\s*\?\s*\[webhookField\.show_if\.field\]/, + ); + assert.match( + botFormSource, + /hiddenItemNames=\{connectionModeControllerNames\}/, + ); + assert.match( + dynamicFormSource, + /if \(hiddenItemNames\?\.includes\(config\.name\)\) return null/, + ); + assert.doesNotMatch( + dynamicFormSource.match( + /const editableItems = useMemo\([\s\S]*?\n \);/, + )?.[0] ?? '', + /hiddenItemNames/, + ); +}); + test('does not expose storage analysis in Cloud settings or via a deep link', () => { assert.match( homeSidebarSource,