From dccda35f65a9b41e841da01e690c9e3263627e89 Mon Sep 17 00:00:00 2001 From: chanx <1243304602@qq.com> Date: Mon, 29 Dec 2025 17:38:01 +0800 Subject: [PATCH] Fix: S3 parameter error (#12290) ### What problem does this PR solve? Fix: S3 parameter error ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue) --------- Co-authored-by: Kevin Hu --- web/src/components/dynamic-form.tsx | 88 +++++++++++++++++-- .../data-source/constant/index.tsx | 1 - .../data-source/constant/s3-constant.tsx | 20 ++--- 3 files changed, 89 insertions(+), 20 deletions(-) diff --git a/web/src/components/dynamic-form.tsx b/web/src/components/dynamic-form.tsx index 2bf30605d..402d5d283 100644 --- a/web/src/components/dynamic-form.tsx +++ b/web/src/components/dynamic-form.tsx @@ -1,6 +1,7 @@ import { zodResolver } from '@hookform/resolvers/zod'; import { forwardRef, + useCallback, useEffect, useImperativeHandle, useMemo, @@ -44,6 +45,11 @@ const getNestedValue = (obj: any, path: string) => { }, obj); }; +/** + * Properties of this field will be treated as static attributes and will be filtered out during form submission. + */ +export const FilterFormField = 'RAG_DY_STATIC'; + // Field type enumeration export enum FormFieldType { Text = 'text', @@ -660,7 +666,6 @@ const DynamicForm = { useMemo(() => { setFields(originFields); }, [originFields]); - const schema = useMemo(() => generateSchema(fields), [fields]); const defaultValues = useMemo(() => { const value = { @@ -729,7 +734,6 @@ const DynamicForm = { ...fieldErrors, } as any; - console.log('combinedErrors', combinedErrors); for (const key in combinedErrors) { if (Array.isArray(combinedErrors[key])) { combinedErrors[key] = combinedErrors[key][0]; @@ -777,11 +781,61 @@ const DynamicForm = { }; }, [fields, form]); + const filterActiveValues = useCallback( + (allValues: any) => { + const filteredValues: any = {}; + + fields.forEach((field) => { + if ( + !field.shouldRender || + (field.shouldRender(allValues) && + field.name?.indexOf(FilterFormField) < 0) + ) { + const keys = field.name.split('.'); + let current = allValues; + let exists = true; + + for (const key of keys) { + if (current && current[key] !== undefined) { + current = current[key]; + } else { + exists = false; + break; + } + } + + if (exists) { + let target = filteredValues; + for (let i = 0; i < keys.length - 1; i++) { + const key = keys[i]; + if (!target[key]) { + target[key] = {}; + } + target = target[key]; + } + target[keys[keys.length - 1]] = getNestedValue( + allValues, + field.name, + ); + } + } + }); + + return filteredValues; + }, + [fields], + ); + // Expose form methods via ref useImperativeHandle( ref, () => ({ - submit: form.handleSubmit(onSubmit), + submit: () => { + form.handleSubmit((values) => { + const filteredValues = filterActiveValues(values); + onSubmit(filteredValues); + })(); + }, getValues: form.getValues, reset: (values?: T) => { if (values) { @@ -824,9 +878,9 @@ const DynamicForm = { // }, 0); }, }), - [form], + [form, onSubmit, filterActiveValues], ); - + (form as any).filterActiveValues = filterActiveValues; useEffect(() => { if (formDefaultValues && Object.keys(formDefaultValues).length > 0) { form.reset({ @@ -848,7 +902,10 @@ const DynamicForm = { className={`space-y-6 ${className}`} onSubmit={(e) => { e.preventDefault(); - form.handleSubmit(onSubmit)(e); + form.handleSubmit((values) => { + const filteredValues = filterActiveValues(values); + onSubmit(filteredValues); + })(e); }} > <> @@ -897,10 +954,23 @@ const DynamicForm = { try { let beValid = await form.formControl.trigger(); console.log('form valid', beValid, form, form.formControl); - if (beValid) { + // if (beValid) { + // form.handleSubmit(async (values) => { + // console.log('form values', values); + // submitFunc?.(values); + // })(); + // } + + if (beValid && submitFunc) { form.handleSubmit(async (values) => { - console.log('form values', values); - submitFunc?.(values); + const filteredValues = (form as any).filterActiveValues + ? (form as any).filterActiveValues(values) + : values; + console.log( + 'filtered form values in saving button', + filteredValues, + ); + submitFunc(filteredValues); })(); } } catch (e) { diff --git a/web/src/pages/user-setting/data-source/constant/index.tsx b/web/src/pages/user-setting/data-source/constant/index.tsx index 33b3c1d47..cd482735b 100644 --- a/web/src/pages/user-setting/data-source/constant/index.tsx +++ b/web/src/pages/user-setting/data-source/constant/index.tsx @@ -747,7 +747,6 @@ export const DataSourceFormDefaultValues = { config: { bucket_name: '', bucket_type: 's3', - authMode: 'access_key', prefix: '', credentials: { aws_access_key_id: '', diff --git a/web/src/pages/user-setting/data-source/constant/s3-constant.tsx b/web/src/pages/user-setting/data-source/constant/s3-constant.tsx index 93ebda7a1..597e76644 100644 --- a/web/src/pages/user-setting/data-source/constant/s3-constant.tsx +++ b/web/src/pages/user-setting/data-source/constant/s3-constant.tsx @@ -1,4 +1,4 @@ -import { FormFieldType } from '@/components/dynamic-form'; +import { FilterFormField, FormFieldType } from '@/components/dynamic-form'; import { TFunction } from 'i18next'; import { BedrockRegionList } from '../../setting-model/constant'; @@ -50,7 +50,7 @@ export const S3Constant = (t: TFunction) => [ }, { label: 'Authentication', - name: 'config.authMode', + name: 'config.credentials.authentication_method', type: FormFieldType.Segmented, options: [ { label: 'Access Key', value: 'access_key' }, @@ -67,7 +67,7 @@ export const S3Constant = (t: TFunction) => [ label: 'AWS Access Key ID', type: FormFieldType.Text, customValidate: (val: string, formValues: any) => { - const authMode = formValues?.config?.authMode; + const authMode = formValues?.config?.credentials?.authentication_method; const bucketType = formValues?.config?.bucket_type; console.log('authMode', authMode, val); if ( @@ -79,7 +79,7 @@ export const S3Constant = (t: TFunction) => [ return true; }, shouldRender: (formValues: any) => { - const authMode = formValues?.config?.authMode; + const authMode = formValues?.config?.credentials?.authentication_method; const bucketType = formValues?.config?.bucket_type; return authMode === 'access_key' || bucketType === 's3_compatible'; }, @@ -89,7 +89,7 @@ export const S3Constant = (t: TFunction) => [ label: 'AWS Secret Access Key', type: FormFieldType.Password, customValidate: (val: string, formValues: any) => { - const authMode = formValues?.config?.authMode; + const authMode = formValues?.config?.credentials?.authentication_method; const bucketType = formValues?.config?.bucket_type; if (authMode === 'access_key' || bucketType === 's3_compatible') { return Boolean(val) || '"AWS Secret Access Key" is required'; @@ -97,7 +97,7 @@ export const S3Constant = (t: TFunction) => [ return true; }, shouldRender: (formValues: any) => { - const authMode = formValues?.config?.authMode; + const authMode = formValues?.config?.credentials?.authentication_method; const bucketType = formValues?.config?.bucket_type; return authMode === 'access_key' || bucketType === 's3_compatible'; }, @@ -109,7 +109,7 @@ export const S3Constant = (t: TFunction) => [ type: FormFieldType.Text, placeholder: 'arn:aws:iam::123456789012:role/YourRole', customValidate: (val: string, formValues: any) => { - const authMode = formValues?.config?.authMode; + const authMode = formValues?.config?.credentials?.authentication_method; const bucketType = formValues?.config?.bucket_type; if (authMode === 'iam_role' || bucketType === 's3') { return Boolean(val) || '"AWS Secret Access Key" is required'; @@ -117,17 +117,17 @@ export const S3Constant = (t: TFunction) => [ return true; }, shouldRender: (formValues: any) => { - const authMode = formValues?.config?.authMode; + const authMode = formValues?.config?.credentials?.authentication_method; const bucketType = formValues?.config?.bucket_type; return authMode === 'iam_role' && bucketType === 's3'; }, }, { - name: 'static.tip', + name: FilterFormField + '.tip', label: ' ', type: FormFieldType.Custom, shouldRender: (formValues: any) => { - const authMode = formValues?.config?.authMode; + const authMode = formValues?.config?.credentials?.authentication_method; const bucketType = formValues?.config?.bucket_type; return authMode === 'assume_role' && bucketType === 's3'; },