diff --git a/web/app/components/workflow/nodes/_base/components/form-input-item.tsx b/web/app/components/workflow/nodes/_base/components/form-input-item.tsx new file mode 100644 index 0000000000..32114a7f2c --- /dev/null +++ b/web/app/components/workflow/nodes/_base/components/form-input-item.tsx @@ -0,0 +1,133 @@ +'use client' +import type { FC } from 'react' +import type { ToolVarInputs } from '@/app/components/workflow/nodes/tool/types' +import type { CredentialFormSchema } from '@/app/components/header/account-setting/model-provider-page/declarations' +import { useLanguage } from '@/app/components/header/account-setting/model-provider-page/hooks' +import { FormTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations' +import { VarType as VarKindType } from '@/app/components/workflow/nodes/tool/types' +import { VarType } from '@/app/components/workflow/types' + +import type { ValueSelector } from '@/app/components/workflow/types' +import FormInputTypeSwitch from './form-input-type-switch' +import Input from '@/app/components/base/input' +import VarReferencePicker from '@/app/components/workflow/nodes/_base/components/variable/var-reference-picker' +// import cn from '@/utils/classnames' + +type Props = { + readOnly: boolean + nodeId: string + schema: CredentialFormSchema + value: ToolVarInputs + onChange: (value: any) => void + onOpen?: (index: number) => void + hideTypeSwitch?: boolean +} + +const FormInputItem: FC = ({ + readOnly, + nodeId, + schema, + value, + onChange, + hideTypeSwitch, +}) => { + const { + placeholder, + variable, + type, + default: defaultValue, + // scope, + } = schema as any + const language = useLanguage() + const varInput = value[variable] + const isString = type === FormTypeEnum.textInput || type === FormTypeEnum.secretInput + const isNumber = type === FormTypeEnum.textNumber + const isBoolean = type === FormTypeEnum.boolean + const isSelect = type === FormTypeEnum.select + const isFile = type === FormTypeEnum.file || type === FormTypeEnum.files + const isAppSelector = type === FormTypeEnum.appSelector + const isModelSelector = type === FormTypeEnum.modelSelector + const isObject = type === FormTypeEnum.object + const isArray = type === FormTypeEnum.array + + const showTypeSwitch = isNumber || isObject || isArray + + const handleTypeChange = (newType: string) => { + if (newType === VarKindType.variable) { + onChange({ + ...value, + [variable]: { + ...varInput, + type: VarKindType.variable, + value: '', + }, + }) + } + else { + onChange({ + ...value, + [variable]: { + ...varInput, + type: VarKindType.constant, + value: defaultValue, + }, + }) + } + } + + const handleValueChange = (newValue: any) => { + onChange({ + ...value, + [variable]: { + ...varInput, + type: varInput.type, + value: newValue, + }, + }) + } + + const handleVariableSelectorChange = (newValue: ValueSelector | string, variable: string) => { + onChange({ + ...value, + [variable]: { + ...varInput, + type: VarKindType.variable, + value: newValue || '', + }, + }) + } + + return ( +
+ {showTypeSwitch && !hideTypeSwitch && ( + + )} + {isNumber && varInput.type === VarKindType.constant && ( + handleValueChange(e.target.value)} + placeholder={placeholder?.[language] || placeholder?.en_US} + /> + )} + {isNumber && varInput.type === VarKindType.variable && ( + handleVariableSelectorChange(value, variable)} + filterVar={varPayload => varPayload.type === VarType.number} + schema={schema} + valueTypePlaceHolder={VarType.number} + /> + )} + {!isNumber && ( +
+ )} +
+ ) +} +export default FormInputItem diff --git a/web/app/components/workflow/nodes/_base/components/form-input-type-switch.tsx b/web/app/components/workflow/nodes/_base/components/form-input-type-switch.tsx new file mode 100644 index 0000000000..30df5839bd --- /dev/null +++ b/web/app/components/workflow/nodes/_base/components/form-input-type-switch.tsx @@ -0,0 +1,47 @@ +'use client' +import type { FC } from 'react' +import { useTranslation } from 'react-i18next' +import { + RiEditLine, +} from '@remixicon/react' +import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development' +import Tooltip from '@/app/components/base/tooltip' +import { VarType } from '@/app/components/workflow/nodes/tool/types' +import cn from '@/utils/classnames' + +type Props = { + value: string + onChange: (value: string) => void +} + +const FormInputTypeSwitch: FC = ({ + value, + onChange, +}) => { + const { t } = useTranslation() + return ( +
+ +
onChange(VarType.variable)} + > + +
+
+ +
onChange(VarType.constant)} + > + +
+
+
+ ) +} +export default FormInputTypeSwitch diff --git a/web/app/components/workflow/nodes/tool/components/tool-form/index.tsx b/web/app/components/workflow/nodes/tool/components/tool-form/index.tsx new file mode 100644 index 0000000000..10157861c7 --- /dev/null +++ b/web/app/components/workflow/nodes/tool/components/tool-form/index.tsx @@ -0,0 +1,47 @@ +'use client' +import type { FC } from 'react' +import React, { useCallback } from 'react' +import type { ToolVarInputs } from '../../types' +import type { CredentialFormSchema } from '@/app/components/header/account-setting/model-provider-page/declarations' +import { noop } from 'lodash-es' +import ToolFormItem from './item' + +type Props = { + readOnly: boolean + nodeId: string + schema: CredentialFormSchema[] + value: ToolVarInputs + onChange: (value: ToolVarInputs) => void + onOpen?: (index: number) => void +} + +const ToolForm: FC = ({ + readOnly, + nodeId, + schema, + value, + onChange, + onOpen = noop, +}) => { + const handleOpen = useCallback((index: number) => { + return () => onOpen(index) + }, [onOpen]) + return ( +
+ { + schema.map((schema, index) => ( + + )) + } +
+ ) +} +export default ToolForm diff --git a/web/app/components/workflow/nodes/tool/components/tool-form/item.tsx b/web/app/components/workflow/nodes/tool/components/tool-form/item.tsx new file mode 100644 index 0000000000..0e0ef65acb --- /dev/null +++ b/web/app/components/workflow/nodes/tool/components/tool-form/item.tsx @@ -0,0 +1,83 @@ +'use client' +import type { FC } from 'react' +import { + RiBracesLine, +} from '@remixicon/react' +import type { ToolVarInputs } from '../../types' +import type { CredentialFormSchema } from '@/app/components/header/account-setting/model-provider-page/declarations' +import { FormTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations' +import { useLanguage } from '@/app/components/header/account-setting/model-provider-page/hooks' +import Button from '@/app/components/base/button' +import Tooltip from '@/app/components/base/tooltip' +import FormInputItem from '@/app/components/workflow/nodes/_base/components/form-input-item' + +type Props = { + readOnly: boolean + nodeId: string + schema: CredentialFormSchema + value: ToolVarInputs + onChange: (value: ToolVarInputs) => void + onOpen?: (index: number) => void + showDescription?: boolean +} + +const ToolFormItem: FC = ({ + readOnly, + nodeId, + schema, + value, + onChange, + showDescription, +}) => { + const language = useLanguage() + const { label, type, required, tooltip } = schema + const showSchemaButton = type === FormTypeEnum.object || type === FormTypeEnum.array + + return ( +
+
+
+
{label[language] || label.en_US}
+ {required && ( +
*
+ )} + {!showDescription && tooltip && ( + + {tooltip[language] || tooltip.en_US} +
} + triggerClassName='ml-1 w-4 h-4' + asChild={false} + /> + )} + {showSchemaButton && ( + <> +
·
+ + + )} +
+ {showDescription && tooltip && ( +
{tooltip[language] || tooltip.en_US}
+ )} +
+ + + ) +} +export default ToolFormItem diff --git a/web/app/components/workflow/nodes/tool/panel.tsx b/web/app/components/workflow/nodes/tool/panel.tsx index 85966443d5..c532fd79dd 100644 --- a/web/app/components/workflow/nodes/tool/panel.tsx +++ b/web/app/components/workflow/nodes/tool/panel.tsx @@ -5,10 +5,11 @@ import Split from '../_base/components/split' import type { ToolNodeType } from './types' import useConfig from './use-config' import InputVarList from './components/input-var-list' +import ToolForm from './components/tool-form' import Button from '@/app/components/base/button' import Field from '@/app/components/workflow/nodes/_base/components/field' import type { NodePanelProps } from '@/app/components/workflow/types' -import Form from '@/app/components/header/account-setting/model-provider-page/model-modal/Form' +// import Form from '@/app/components/header/account-setting/model-provider-page/model-modal/Form' import ConfigCredential from '@/app/components/tools/setting/build-in/config-credentials' import Loading from '@/app/components/base/loading' import BeforeRunForm from '@/app/components/workflow/nodes/_base/components/before-run-form' @@ -63,6 +64,8 @@ const Panel: FC> = ({ return formatToTracingNodeList([runResult], t)[0] }, [runResult, t]) + const [collapsed, setCollapsed] = React.useState(false) + if (isLoading) { return
@@ -84,10 +87,11 @@ const Panel: FC> = ({
)} - {!isShowAuthBtn && <> -
+ {!isShowAuthBtn && ( +
{toolInputVarSchema.length > 0 && ( > = ({ isSupportConstantValue onOpen={handleOnVarOpen} /> + {/* */} )} @@ -107,21 +119,39 @@ const Panel: FC> = ({ )} -
+ {toolSettingSchema.length > 0 && ( + <> + + {/* */} + + + + + )}
- } + )} {showSetAuth && (