diff --git a/web/app/components/app/log/list.tsx b/web/app/components/app/log/list.tsx index 47f8c09e39..b04148d484 100644 --- a/web/app/components/app/log/list.tsx +++ b/web/app/components/app/log/list.tsx @@ -470,8 +470,6 @@ function DetailPanel({ detail, onFeedback }: IDetailPanel) { className="py-4" id="scrollableDiv" style={{ - height: 1000, // Specify a value - overflow: 'auto', display: 'flex', flexDirection: 'column-reverse', }}> diff --git a/web/app/components/base/form/components/base/base-form.tsx b/web/app/components/base/form/components/base/base-form.tsx index 3fee80bac1..6911e4d95f 100644 --- a/web/app/components/base/form/components/base/base-form.tsx +++ b/web/app/components/base/form/components/base/base-form.tsx @@ -70,25 +70,33 @@ const BaseForm = ({ return null }, [formSchemas, fieldClassName, labelClassName, inputContainerClassName, inputClassName, disabled]) + const renderFieldWrapper = useCallback((formSchema: FormSchema) => { + const { + name, + } = formSchema + + return ( + + {renderField} + + ) + }, [renderField, form]) + if (!formSchemas?.length) return null return (
{ + e.preventDefault() + form?.handleSubmit() + }} > - { - formSchemas.map((formSchema) => { - return ( - - {renderField} - - ) - }) - } + {formSchemas.map(renderFieldWrapper)}
) } diff --git a/web/app/components/base/form/types.ts b/web/app/components/base/form/types.ts index 9255181518..02a93c3285 100644 --- a/web/app/components/base/form/types.ts +++ b/web/app/components/base/form/types.ts @@ -2,7 +2,10 @@ import type { ForwardedRef, ReactNode, } from 'react' -import type { AnyFormApi } from '@tanstack/react-form' +import type { + AnyFormApi, + FieldValidators, +} from '@tanstack/react-form' export type TypeWithI18N = { en_US: T @@ -52,6 +55,7 @@ export type FormSchema = { placeholder?: string | TypeWithI18N options?: FormOption[] labelClassName?: string + validators?: FieldValidators } export type FormValues = Record diff --git a/web/app/components/plugins/plugin-auth/authorize/add-oauth-button.tsx b/web/app/components/plugins/plugin-auth/authorize/add-oauth-button.tsx index 1372a3a5a8..8e6fc5aa03 100644 --- a/web/app/components/plugins/plugin-auth/authorize/add-oauth-button.tsx +++ b/web/app/components/plugins/plugin-auth/authorize/add-oauth-button.tsx @@ -217,6 +217,7 @@ const AddOAuthButton = ({ disabled={disabled} schemas={memorizedSchemas} onAuth={handleOAuth} + editValues={client_params} /> ) } diff --git a/web/app/components/plugins/plugin-auth/authorize/api-key-modal.tsx b/web/app/components/plugins/plugin-auth/authorize/api-key-modal.tsx index c29e984ae4..5e7f8a7adb 100644 --- a/web/app/components/plugins/plugin-auth/authorize/api-key-modal.tsx +++ b/web/app/components/plugins/plugin-auth/authorize/api-key-modal.tsx @@ -72,13 +72,21 @@ const ApiKeyModal = ({ ...values } = store?.state.values const isPristineSecretInputNames: string[] = [] - formSchemas.forEach((schema) => { + for (let i = 0; i < formSchemas.length; i++) { + const schema = formSchemas[i] + if (schema.required && !values[schema.name]) { + notify({ + type: 'error', + message: t('common.errorMsg.fieldRequired', { field: schema.name }), + }) + return + } if (schema.type === FormTypeEnum.secretInput) { const fieldMeta = form?.getFieldMeta(schema.name) if (fieldMeta?.isPristine) isPristineSecretInputNames.push(schema.name) } - }) + } const transformedValues = transformFormSchemasSecretInput(isPristineSecretInputNames, values) diff --git a/web/app/components/plugins/plugin-auth/authorize/oauth-client-settings.tsx b/web/app/components/plugins/plugin-auth/authorize/oauth-client-settings.tsx index aa9722a1c5..7752d584fb 100644 --- a/web/app/components/plugins/plugin-auth/authorize/oauth-client-settings.tsx +++ b/web/app/components/plugins/plugin-auth/authorize/oauth-client-settings.tsx @@ -53,13 +53,21 @@ const OAuthClientSettings = ({ ...values } = store?.state.values const isPristineSecretInputNames: string[] = [] - schemas.forEach((schema) => { + for (let i = 0; i < schemas.length; i++) { + const schema = schemas[i] + if (schema.required && !values[schema.name]) { + notify({ + type: 'error', + message: t('common.errorMsg.fieldRequired', { field: schema.name }), + }) + return + } if (schema.type === FormTypeEnum.secretInput) { const fieldMeta = form?.getFieldMeta(schema.name) if (fieldMeta?.isPristine) isPristineSecretInputNames.push(schema.name) } - }) + } const transformedValues = transformFormSchemasSecretInput(isPristineSecretInputNames, values) diff --git a/web/app/components/plugins/plugin-auth/authorized/index.tsx b/web/app/components/plugins/plugin-auth/authorized/index.tsx index 5762bad2da..9caef74d95 100644 --- a/web/app/components/plugins/plugin-auth/authorized/index.tsx +++ b/web/app/components/plugins/plugin-auth/authorized/index.tsx @@ -282,8 +282,7 @@ const Authorized = ({ deleteCredentialId && ( diff --git a/web/app/components/plugins/plugin-detail-panel/tool-selector/index.tsx b/web/app/components/plugins/plugin-detail-panel/tool-selector/index.tsx index 5dfb8d0231..9c7c7a0c41 100644 --- a/web/app/components/plugins/plugin-detail-panel/tool-selector/index.tsx +++ b/web/app/components/plugins/plugin-detail-panel/tool-selector/index.tsx @@ -49,7 +49,7 @@ type Props = { value?: ToolValue selectedTools?: ToolValue[] onSelect: (tool: ToolValue) => void - onSelectMultiple: (tool: ToolValue[]) => void + onSelectMultiple?: (tool: ToolValue[]) => void isEdit?: boolean onDelete?: () => void supportEnableSwitch?: boolean @@ -137,7 +137,7 @@ const ToolSelector: FC = ({ } const handleSelectMultipleTool = (tool: ToolDefaultValue[]) => { const toolValues = tool.map(item => getToolValue(item)) - onSelectMultiple(toolValues) + onSelectMultiple?.(toolValues) } const handleDescriptionChange = (e: React.ChangeEvent) => { diff --git a/web/app/components/workflow/nodes/_base/components/agent-strategy.tsx b/web/app/components/workflow/nodes/_base/components/agent-strategy.tsx index 31aa91cfdb..ce9fbb77e1 100644 --- a/web/app/components/workflow/nodes/_base/components/agent-strategy.tsx +++ b/web/app/components/workflow/nodes/_base/components/agent-strategy.tsx @@ -20,7 +20,7 @@ import { useRenderI18nObject } from '@/hooks/use-i18n' import type { NodeOutPutVar } from '../../../types' import type { Node } from 'reactflow' import type { PluginMeta } from '@/app/components/plugins/types' -import { noop } from 'lodash' +import { noop } from 'lodash-es' import { useDocLink } from '@/context/i18n' export type Strategy = { diff --git a/web/app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/hooks.ts b/web/app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/hooks.ts index eb3dff83d8..d11ad92241 100644 --- a/web/app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/hooks.ts +++ b/web/app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/hooks.ts @@ -6,7 +6,7 @@ import type { EditData } from './edit-card' import { ArrayType, type Field, Type } from '../../../types' import Toast from '@/app/components/base/toast' import { findPropertyWithPath } from '../../../utils' -import _ from 'lodash' +import { noop } from 'lodash-es' type ChangeEventParams = { path: string[], @@ -21,7 +21,7 @@ type AddEventParams = { export const useSchemaNodeOperations = (props: VisualEditorProps) => { const { schema: jsonSchema, onChange: doOnChange } = props - const onChange = doOnChange || _.noop + const onChange = doOnChange || noop const backupSchema = useVisualEditorStore(state => state.backupSchema) const setBackupSchema = useVisualEditorStore(state => state.setBackupSchema) const isAddingNewField = useVisualEditorStore(state => state.isAddingNewField)