| import { |
| memo, |
| useCallback, |
| useMemo, |
| } from 'react' |
| import { useTranslation } from 'react-i18next' |
| import { useNodes } from 'reactflow' |
| import FormItem from '../nodes/_base/components/before-run-form/form-item' |
| import { |
| BlockEnum, |
| InputVarType, |
| WorkflowRunningStatus, |
| } from '../types' |
| import { |
| useStore, |
| useWorkflowStore, |
| } from '../store' |
| import { useWorkflowRun } from '../hooks' |
| import type { StartNodeType } from '../nodes/start/types' |
| import { TransferMethod } from '../../base/text-generation/types' |
| import Button from '@/app/components/base/button' |
| import { useFeatures } from '@/app/components/base/features/hooks' |
| import { |
| getProcessedInputs, |
| } from '@/app/components/base/chat/chat/utils' |
| import { useCheckInputsForms } from '@/app/components/base/chat/chat/check-input-forms-hooks' |
|
|
| type Props = { |
| onRun: () => void |
| } |
|
|
| const InputsPanel = ({ onRun }: Props) => { |
| const { t } = useTranslation() |
| const workflowStore = useWorkflowStore() |
| const fileSettings = useFeatures(s => s.features.file) |
| const nodes = useNodes<StartNodeType>() |
| const inputs = useStore(s => s.inputs) |
| const files = useStore(s => s.files) |
| const workflowRunningData = useStore(s => s.workflowRunningData) |
| const { |
| handleRun, |
| } = useWorkflowRun() |
| const startNode = nodes.find(node => node.data.type === BlockEnum.Start) |
| const startVariables = startNode?.data.variables |
| const { checkInputsForm } = useCheckInputsForms() |
|
|
| const variables = useMemo(() => { |
| const data = startVariables || [] |
| if (fileSettings?.image?.enabled) { |
| return [ |
| ...data, |
| { |
| type: InputVarType.files, |
| variable: '__image', |
| required: false, |
| label: 'files', |
| }, |
| ] |
| } |
|
|
| return data |
| }, [fileSettings?.image?.enabled, startVariables]) |
|
|
| const handleValueChange = (variable: string, v: any) => { |
| const { |
| inputs, |
| setInputs, |
| } = workflowStore.getState() |
| if (variable === '__image') { |
| workflowStore.setState({ |
| files: v, |
| }) |
| } |
| else { |
| setInputs({ |
| ...inputs, |
| [variable]: v, |
| }) |
| } |
| } |
|
|
| const doRun = useCallback(() => { |
| if (!checkInputsForm(inputs, variables as any)) |
| return |
| onRun() |
| handleRun({ inputs: getProcessedInputs(inputs, variables as any), files }) |
| }, [files, handleRun, inputs, onRun, variables, checkInputsForm]) |
|
|
| const canRun = useMemo(() => { |
| if (files?.some(item => (item.transfer_method as any) === TransferMethod.local_file && !item.upload_file_id)) |
| return false |
|
|
| return true |
| }, [files]) |
|
|
| return ( |
| <> |
| <div className='pt-3 px-4 pb-2'> |
| { |
| variables.map((variable, index) => ( |
| <div |
| key={variable.variable} |
| className='mb-2 last-of-type:mb-0' |
| > |
| <FormItem |
| autoFocus={index === 0} |
| className='!block' |
| payload={variable} |
| value={inputs[variable.variable]} |
| onChange={v => handleValueChange(variable.variable, v)} |
| /> |
| </div> |
| )) |
| } |
| </div> |
| <div className='flex items-center justify-between px-4 py-2'> |
| <Button |
| variant='primary' |
| disabled={!canRun || workflowRunningData?.result?.status === WorkflowRunningStatus.Running} |
| className='w-full' |
| onClick={doRun} |
| > |
| {t('workflow.singleRun.startRun')} |
| </Button> |
| </div> |
| </> |
| ) |
| } |
|
|
| export default memo(InputsPanel) |
|
|