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 (
- {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)