import { memo, useCallback, useMemo, useRef, useState, } from 'react' import { useStore } from '@/app/components/workflow/store' import { RiCloseLine, RiEyeLine } from '@remixicon/react' import type { Node } from '@/app/components/workflow/types' import { BlockEnum } from '@/app/components/workflow/types' import DialogWrapper from './dialog-wrapper' import FieldList from './field-list' import FooterTip from './footer-tip' import GlobalInputs from './label-right-content/global-inputs' import Datasource from './label-right-content/datasource' import { useNodes } from 'reactflow' import type { DataSourceNodeType } from '@/app/components/workflow/nodes/data-source/types' import { useTranslation } from 'react-i18next' import { useNodesSyncDraft } from '@/app/components/workflow/hooks' import type { InputVar, RAGPipelineVariables } from '@/models/pipeline' import Button from '@/app/components/base/button' import Divider from '@/app/components/base/divider' import Tooltip from '@/app/components/base/tooltip' import cn from '@/utils/classnames' import PreviewPanel from './preview' type InputFieldDialogProps = { readonly?: boolean } const InputFieldDialog = ({ readonly = false, }: InputFieldDialogProps) => { const { t } = useTranslation() const nodes = useNodes() const showInputFieldDialog = useStore(state => state.showInputFieldDialog) const setShowInputFieldDialog = useStore(state => state.setShowInputFieldDialog) const ragPipelineVariables = useStore(state => state.ragPipelineVariables) const setRagPipelineVariables = useStore(state => state.setRagPipelineVariables) const [previewPanelOpen, setPreviewPanelOpen] = useState(false) const getInputFieldsMap = () => { const inputFieldsMap: Record = {} ragPipelineVariables?.forEach((variable) => { const { belong_to_node_id: nodeId, ...varConfig } = variable if (inputFieldsMap[nodeId]) inputFieldsMap[nodeId].push(varConfig) else inputFieldsMap[nodeId] = [varConfig] }) return inputFieldsMap } const inputFieldsMap = useRef(getInputFieldsMap()) const { handleSyncWorkflowDraft } = useNodesSyncDraft() const datasourceNodeDataMap = useMemo(() => { const datasourceNodeDataMap: Record = {} const datasourceNodes: Node[] = nodes.filter(node => node.data.type === BlockEnum.DataSource) datasourceNodes.forEach((node) => { const { id, data } = node datasourceNodeDataMap[id] = data }) return datasourceNodeDataMap }, [nodes]) const updateInputFields = useCallback(async (key: string, value: InputVar[]) => { inputFieldsMap.current[key] = value const datasourceNodeInputFields: RAGPipelineVariables = [] const globalInputFields: RAGPipelineVariables = [] Object.keys(inputFieldsMap.current).forEach((key) => { const inputFields = inputFieldsMap.current[key] inputFields.forEach((inputField) => { if (key === 'shared') { globalInputFields.push({ ...inputField, belong_to_node_id: key, }) } else { datasourceNodeInputFields.push({ ...inputField, belong_to_node_id: key, }) } }) }) // Datasource node input fields come first, then global input fields const newRagPipelineVariables = [...datasourceNodeInputFields, ...globalInputFields] setRagPipelineVariables?.(newRagPipelineVariables) handleSyncWorkflowDraft() }, [setRagPipelineVariables, handleSyncWorkflowDraft]) const closePanel = useCallback(() => { setShowInputFieldDialog?.(false) }, [setShowInputFieldDialog]) const togglePreviewPanel = useCallback(() => { setPreviewPanelOpen(prev => !prev) }, []) const allVariableNames = useMemo(() => { return ragPipelineVariables?.map(variable => variable.variable) || [] }, [ragPipelineVariables]) return ( <>
{t('datasetPipeline.inputFieldPanel.title')}
{t('datasetPipeline.inputFieldPanel.description')}
{/* Unique Inputs for Each Entrance */}
{t('datasetPipeline.inputFieldPanel.uniqueInputs.title')}
{ Object.keys(datasourceNodeDataMap).map((key) => { const inputFields = inputFieldsMap.current[key] || [] return ( } inputFields={inputFields} readonly={readonly} labelClassName='pt-1 pb-1' handleInputFieldsChange={updateInputFields} allVariableNames={allVariableNames} /> ) }) }
{/* Global Inputs */} } inputFields={inputFieldsMap.current.shared || []} readonly={readonly} labelClassName='pt-2 pb-1' handleInputFieldsChange={updateInputFields} allVariableNames={allVariableNames} />
{previewPanelOpen && ( )} ) } export default memo(InputFieldDialog)