mirror of
https://github.com/langgenius/dify.git
synced 2026-04-27 19:27:23 +08:00
feat: enhance input field management with internationalization support and improved state handling
This commit is contained in:
parent
7e31da7882
commit
97ec855df4
@ -3,20 +3,30 @@ import DialogWrapper from '../dialog-wrapper'
|
|||||||
import type { InputVar } from '@/app/components/workflow/types'
|
import type { InputVar } from '@/app/components/workflow/types'
|
||||||
import InputFieldForm from './form'
|
import InputFieldForm from './form'
|
||||||
import { convertToInputFieldFormData } from './utils'
|
import { convertToInputFieldFormData } from './utils'
|
||||||
|
import { useCallback } from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
type InputFieldEditorProps = {
|
type InputFieldEditorProps = {
|
||||||
show: boolean
|
show: boolean
|
||||||
onClose: () => void
|
onClose: () => void
|
||||||
|
onSubmit: (data: InputVar) => void
|
||||||
initialData?: InputVar
|
initialData?: InputVar
|
||||||
}
|
}
|
||||||
|
|
||||||
const InputFieldEditor = ({
|
const InputFieldEditor = ({
|
||||||
show,
|
show,
|
||||||
onClose,
|
onClose,
|
||||||
|
onSubmit,
|
||||||
initialData,
|
initialData,
|
||||||
}: InputFieldEditorProps) => {
|
}: InputFieldEditorProps) => {
|
||||||
|
const { t } = useTranslation()
|
||||||
const formData = convertToInputFieldFormData(initialData)
|
const formData = convertToInputFieldFormData(initialData)
|
||||||
|
|
||||||
|
const handleSubmit = useCallback((value: InputVar) => {
|
||||||
|
onSubmit(value)
|
||||||
|
onClose()
|
||||||
|
}, [onSubmit, onClose])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DialogWrapper
|
<DialogWrapper
|
||||||
show={show}
|
show={show}
|
||||||
@ -26,7 +36,7 @@ const InputFieldEditor = ({
|
|||||||
>
|
>
|
||||||
<div className='relative flex h-fit flex-col'>
|
<div className='relative flex h-fit flex-col'>
|
||||||
<div className='system-xl-semibold flex items-center pb-1 pl-4 pr-11 pt-3.5 text-text-primary'>
|
<div className='system-xl-semibold flex items-center pb-1 pl-4 pr-11 pt-3.5 text-text-primary'>
|
||||||
Add Input Field
|
{initialData ? t('datasetPipeline.inputFieldPanel.editInputField') : t('datasetPipeline.inputFieldPanel.addInputField')}
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
type='button'
|
type='button'
|
||||||
@ -39,10 +49,7 @@ const InputFieldEditor = ({
|
|||||||
initialData={formData}
|
initialData={formData}
|
||||||
supportFile
|
supportFile
|
||||||
onCancel={onClose}
|
onCancel={onClose}
|
||||||
onSubmit={(value) => {
|
onSubmit={handleSubmit}
|
||||||
console.log('submit', value)
|
|
||||||
onClose()
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</DialogWrapper>
|
</DialogWrapper>
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import cn from '@/utils/classnames'
|
|||||||
import { useCallback, useMemo, useState } from 'react'
|
import { useCallback, useMemo, useState } from 'react'
|
||||||
import InputFieldEditor from '../editor'
|
import InputFieldEditor from '../editor'
|
||||||
import { ReactSortable } from 'react-sortablejs'
|
import { ReactSortable } from 'react-sortablejs'
|
||||||
|
import produce from 'immer'
|
||||||
|
|
||||||
type FieldListProps = {
|
type FieldListProps = {
|
||||||
LabelRightContent: React.ReactNode
|
LabelRightContent: React.ReactNode
|
||||||
@ -22,6 +23,8 @@ const FieldList = ({
|
|||||||
labelClassName,
|
labelClassName,
|
||||||
}: FieldListProps) => {
|
}: FieldListProps) => {
|
||||||
const [showInputFieldEditor, setShowInputFieldEditor] = useState(false)
|
const [showInputFieldEditor, setShowInputFieldEditor] = useState(false)
|
||||||
|
const [currentIndex, setCurrentIndex] = useState<number>(-1)
|
||||||
|
const [currentInputField, setCurrentInputField] = useState<InputVar>()
|
||||||
|
|
||||||
const optionList = useMemo(() => {
|
const optionList = useMemo(() => {
|
||||||
return inputFields.map((content, index) => {
|
return inputFields.map((content, index) => {
|
||||||
@ -45,12 +48,23 @@ const FieldList = ({
|
|||||||
}, [handleInputFieldsChange, inputFields])
|
}, [handleInputFieldsChange, inputFields])
|
||||||
|
|
||||||
const handleAddField = () => {
|
const handleAddField = () => {
|
||||||
|
setCurrentIndex(-1)
|
||||||
|
setCurrentInputField(undefined)
|
||||||
setShowInputFieldEditor(true)
|
setShowInputFieldEditor(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleEditField = useCallback((index: number) => {
|
const handleEditField = useCallback((index: number) => {
|
||||||
|
setCurrentIndex(index)
|
||||||
|
setCurrentInputField(inputFields[index])
|
||||||
setShowInputFieldEditor(true)
|
setShowInputFieldEditor(true)
|
||||||
}, [])
|
}, [inputFields])
|
||||||
|
|
||||||
|
const handleSubmitChange = useCallback((data: InputVar) => {
|
||||||
|
const newInputFields = produce(inputFields, (draft) => {
|
||||||
|
draft[currentIndex] = data
|
||||||
|
})
|
||||||
|
handleInputFieldsChange(newInputFields)
|
||||||
|
}, [currentIndex, handleInputFieldsChange, inputFields])
|
||||||
|
|
||||||
const handleCloseEditor = useCallback(() => {
|
const handleCloseEditor = useCallback(() => {
|
||||||
setShowInputFieldEditor(false)
|
setShowInputFieldEditor(false)
|
||||||
@ -94,6 +108,8 @@ const FieldList = ({
|
|||||||
{showInputFieldEditor && (
|
{showInputFieldEditor && (
|
||||||
<InputFieldEditor
|
<InputFieldEditor
|
||||||
show={showInputFieldEditor}
|
show={showInputFieldEditor}
|
||||||
|
initialData={currentInputField}
|
||||||
|
onSubmit={handleSubmitChange}
|
||||||
onClose={handleCloseEditor}
|
onClose={handleCloseEditor}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -1,65 +1,69 @@
|
|||||||
import {
|
import {
|
||||||
memo,
|
memo,
|
||||||
useCallback,
|
useCallback,
|
||||||
useState,
|
useMemo,
|
||||||
} from 'react'
|
} from 'react'
|
||||||
import { useStore } from '@/app/components/workflow/store'
|
import { useStore } from '@/app/components/workflow/store'
|
||||||
import { RiCloseLine } from '@remixicon/react'
|
import { RiCloseLine } from '@remixicon/react'
|
||||||
import { Jina } from '@/app/components/base/icons/src/public/llm'
|
import { BlockEnum, type InputVar } from '@/app/components/workflow/types'
|
||||||
import type { InputVar } from '@/app/components/workflow/types'
|
|
||||||
import { InputVarType } from '@/app/components/workflow/types'
|
|
||||||
import Tooltip from '@/app/components/base/tooltip'
|
|
||||||
import DialogWrapper from './dialog-wrapper'
|
import DialogWrapper from './dialog-wrapper'
|
||||||
import FieldList from './field-list'
|
import FieldList from './field-list'
|
||||||
import FooterTip from './footer-tip'
|
import FooterTip from './footer-tip'
|
||||||
|
import SharedInputs from './label-right-content/shared-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 produce from 'immer'
|
||||||
|
|
||||||
type InputFieldDialogProps = {
|
type InputFieldDialogProps = {
|
||||||
readonly?: boolean
|
readonly?: boolean
|
||||||
initialInputFieldsMap?: Record<string, InputVar[]>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const InputFieldDialog = ({
|
const InputFieldDialog = ({
|
||||||
readonly = false,
|
readonly = false,
|
||||||
initialInputFieldsMap,
|
|
||||||
}: InputFieldDialogProps) => {
|
}: InputFieldDialogProps) => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
const nodes = useNodes<DataSourceNodeType>()
|
||||||
const showInputFieldDialog = useStore(state => state.showInputFieldDialog)
|
const showInputFieldDialog = useStore(state => state.showInputFieldDialog)
|
||||||
const setShowInputFieldDialog = useStore(state => state.setShowInputFieldDialog)
|
const setShowInputFieldDialog = useStore(state => state.setShowInputFieldDialog)
|
||||||
// TODO: delete mock data
|
const ragPipelineVariables = useStore(state => state.ragPipelineVariables)
|
||||||
const [inputFieldsMap, setInputFieldsMap] = useState(initialInputFieldsMap || {
|
const setRagPipelineVariables = useStore(state => state.setRagPipelineVariables)
|
||||||
jina: [{
|
|
||||||
variable: 'name',
|
const datasourceTitleMap = useMemo(() => {
|
||||||
label: 'name',
|
const datasourceNameMap: Record<string, string> = {}
|
||||||
type: InputVarType.textInput,
|
const datasourceNodes = nodes.filter(node => node.data.type === BlockEnum.DataSource)
|
||||||
required: true,
|
datasourceNodes.forEach((node) => {
|
||||||
max_length: 12,
|
const { id, data } = node
|
||||||
}, {
|
if (data?.title)
|
||||||
variable: 'num',
|
datasourceNameMap[id] = data.title
|
||||||
label: 'num',
|
})
|
||||||
type: InputVarType.number,
|
return datasourceNameMap
|
||||||
required: true,
|
}, [nodes])
|
||||||
}],
|
|
||||||
firecrawl: [{
|
const inputFieldsMap = useMemo(() => {
|
||||||
variable: 'name',
|
const inputFieldsMap: Record<string, InputVar[]> = {}
|
||||||
label: 'name',
|
ragPipelineVariables?.forEach((variable) => {
|
||||||
type: InputVarType.textInput,
|
const { nodeId, variables } = variable
|
||||||
required: true,
|
if (nodeId)
|
||||||
max_length: 12,
|
inputFieldsMap[nodeId] = variables
|
||||||
}],
|
else
|
||||||
shared: [{
|
inputFieldsMap.shared = variables
|
||||||
variable: 'name',
|
})
|
||||||
label: 'name',
|
return inputFieldsMap
|
||||||
type: InputVarType.textInput,
|
}, [ragPipelineVariables])
|
||||||
required: true,
|
|
||||||
max_length: 12,
|
const datasourceKeys = useMemo(() => {
|
||||||
}],
|
return Object.keys(inputFieldsMap).filter(key => key !== 'shared')
|
||||||
})
|
}, [inputFieldsMap])
|
||||||
|
|
||||||
const updateInputFields = useCallback((key: string, value: InputVar[]) => {
|
const updateInputFields = useCallback((key: string, value: InputVar[]) => {
|
||||||
setInputFieldsMap(prev => ({
|
const newRagPipelineVariables = produce(ragPipelineVariables!, (draft) => {
|
||||||
...prev,
|
const index = draft.findIndex(variable => variable.nodeId === key)
|
||||||
[key]: value,
|
draft[index].variables = value
|
||||||
}))
|
})
|
||||||
}, [])
|
setRagPipelineVariables?.(newRagPipelineVariables)
|
||||||
|
}, [ragPipelineVariables, setRagPipelineVariables])
|
||||||
|
|
||||||
const closePanel = useCallback(() => {
|
const closePanel = useCallback(() => {
|
||||||
setShowInputFieldDialog?.(false)
|
setShowInputFieldDialog?.(false)
|
||||||
@ -72,9 +76,8 @@ const InputFieldDialog = ({
|
|||||||
>
|
>
|
||||||
<div className='flex grow flex-col'>
|
<div className='flex grow flex-col'>
|
||||||
<div className='flex items-center p-4 pb-0'>
|
<div className='flex items-center p-4 pb-0'>
|
||||||
{/* // TODO: i18n */}
|
|
||||||
<div className='system-xl-semibold grow'>
|
<div className='system-xl-semibold grow'>
|
||||||
User input fields
|
{t('datasetPipeline.inputFieldPanel.title')}
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
type='button'
|
type='button'
|
||||||
@ -85,54 +88,31 @@ const InputFieldDialog = ({
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className='system-sm-regular px-4 py-1 text-text-tertiary'>
|
<div className='system-sm-regular px-4 py-1 text-text-tertiary'>
|
||||||
User input fields are used to define and collect variables required during the pipeline execution process. Users can customize the field type and flexibly configure the input value to meet the needs of different data sources or document processing steps.
|
{t('datasetPipeline.inputFieldPanel.description')}
|
||||||
</div>
|
</div>
|
||||||
<div className='flex grow flex-col overflow-y-auto'>
|
<div className='flex grow flex-col overflow-y-auto'>
|
||||||
{/* Jina Reader Field List */}
|
{/* Datasources Inputs */}
|
||||||
<FieldList
|
{
|
||||||
LabelRightContent={(
|
datasourceKeys.map((key) => {
|
||||||
<div className='flex items-center gap-x-1.5'>
|
const inputFields = inputFieldsMap[key] || []
|
||||||
<div className='flex size-5 items-center justify-center rounded-md border-[0.5px] border-components-panel-border-subtle bg-background-default'>
|
return (
|
||||||
<Jina className='size-3.5' />
|
<FieldList
|
||||||
</div>
|
LabelRightContent={<Datasource title={datasourceTitleMap[key]} />}
|
||||||
<span className='system-sm-medium text-text-secondary'>Jina Reader</span>
|
inputFields={inputFields}
|
||||||
</div>
|
readonly={readonly}
|
||||||
)}
|
labelClassName='pt-2 pb-1'
|
||||||
inputFields={inputFieldsMap.jina}
|
handleInputFieldsChange={updateInputFields.bind(null, key)}
|
||||||
readonly={readonly}
|
/>
|
||||||
labelClassName='pt-2 pb-1'
|
)
|
||||||
handleInputFieldsChange={updateInputFields.bind(null, 'jina')}
|
})
|
||||||
/>
|
}
|
||||||
{/* Firecrawl Field List */}
|
|
||||||
<FieldList
|
|
||||||
LabelRightContent={(
|
|
||||||
<div className='flex items-center gap-x-1.5'>
|
|
||||||
<div className='flex size-5 items-center justify-center rounded-md border-[0.5px] border-components-panel-border-subtle bg-background-default'>
|
|
||||||
<span className='text-[14px] leading-[14px]'>🔥</span>
|
|
||||||
</div>
|
|
||||||
<span className='system-sm-medium text-text-secondary'>Firecrawl</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
inputFields={inputFieldsMap.firecrawl}
|
|
||||||
readonly={readonly}
|
|
||||||
labelClassName='pt-2 pb-1'
|
|
||||||
handleInputFieldsChange={updateInputFields.bind(null, 'firecrawl')}
|
|
||||||
/>
|
|
||||||
{/* Shared Inputs */}
|
{/* Shared Inputs */}
|
||||||
<FieldList
|
<FieldList
|
||||||
LabelRightContent={(
|
LabelRightContent={<SharedInputs />}
|
||||||
<div className='flex items-center gap-x-1'>
|
inputFields={inputFieldsMap.shared || []}
|
||||||
<span className='system-sm-medium text-text-secondary'>SHARED INPUTS</span>
|
|
||||||
<Tooltip
|
|
||||||
popupContent='Shared Inputs are available to all downstream nodes across data sources. For example, variables like delimiter and maximum chunk length can be uniformly applied when processing documents from multiple sources.'
|
|
||||||
popupClassName='!w-[300px]'
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
inputFields={inputFieldsMap.shared}
|
|
||||||
readonly={readonly}
|
readonly={readonly}
|
||||||
labelClassName='pt-1 pb-2'
|
labelClassName='pt-1 pb-2'
|
||||||
handleInputFieldsChange={updateInputFields.bind(null, 'shared')}
|
handleInputFieldsChange={updateInputFields.bind(null, '')}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<FooterTip />
|
<FooterTip />
|
||||||
|
|||||||
@ -0,0 +1,21 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { RiDatabase2Fill } from '@remixicon/react'
|
||||||
|
|
||||||
|
type DatasourceProps = {
|
||||||
|
title: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const Datasource = ({
|
||||||
|
title,
|
||||||
|
}: DatasourceProps) => {
|
||||||
|
return (
|
||||||
|
<div className='flex items-center gap-x-1.5'>
|
||||||
|
<div className='flex size-5 items-center justify-center rounded-md border-[0.5px] border-components-panel-border-subtle bg-background-default'>
|
||||||
|
<RiDatabase2Fill className='size-3.5 text-text-secondary' />
|
||||||
|
</div>
|
||||||
|
<span className='system-sm-medium text-text-secondary'>{title}</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default React.memo(Datasource)
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
import Tooltip from '@/app/components/base/tooltip'
|
||||||
|
import React from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
|
const SharedInputs = () => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='flex items-center gap-x-1'>
|
||||||
|
<span className='system-sm-semibold-uppercase text-text-secondary'>
|
||||||
|
{t('datasetPipeline.inputFieldPanel.sharedInputs.title')}
|
||||||
|
</span>
|
||||||
|
<Tooltip
|
||||||
|
popupContent={t('datasetPipeline.inputFieldPanel.sharedInputs.tooltip')}
|
||||||
|
popupClassName='!w-[300px]'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default React.memo(SharedInputs)
|
||||||
@ -128,7 +128,7 @@ const TestRunPanel = () => {
|
|||||||
|
|
||||||
const { handleRun } = useWorkflowRun()
|
const { handleRun } = useWorkflowRun()
|
||||||
|
|
||||||
const handleProcess = useCallback(() => {
|
const handleProcess = useCallback((data: Record<string, any>) => {
|
||||||
const datasourceInfo: Record<string, any> = {}
|
const datasourceInfo: Record<string, any> = {}
|
||||||
if (datasource.type === DataSourceType.FILE)
|
if (datasource.type === DataSourceType.FILE)
|
||||||
datasourceInfo.fileId = fileList.map(file => file.fileID)
|
datasourceInfo.fileId = fileList.map(file => file.fileID)
|
||||||
@ -145,8 +145,9 @@ const TestRunPanel = () => {
|
|||||||
datasourceInfo.jobId = websiteCrawlJobId
|
datasourceInfo.jobId = websiteCrawlJobId
|
||||||
datasourceInfo.result = websitePages
|
datasourceInfo.result = websitePages
|
||||||
}
|
}
|
||||||
|
// todo: TBD
|
||||||
handleRun({
|
handleRun({
|
||||||
inputs: {},
|
inputs: data,
|
||||||
datasource_type: datasource,
|
datasource_type: datasource,
|
||||||
datasource_info: datasourceInfo,
|
datasource_info: datasourceInfo,
|
||||||
})
|
})
|
||||||
|
|||||||
@ -2,8 +2,10 @@ import Button from '@/app/components/base/button'
|
|||||||
import { InputField } from '@/app/components/base/icons/src/vender/pipeline'
|
import { InputField } from '@/app/components/base/icons/src/vender/pipeline'
|
||||||
import { useStore } from '@/app/components/workflow/store'
|
import { useStore } from '@/app/components/workflow/store'
|
||||||
import { useCallback } from 'react'
|
import { useCallback } from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
const InputFieldButton = () => {
|
const InputFieldButton = () => {
|
||||||
|
const { t } = useTranslation()
|
||||||
const setShowInputFieldDialog = useStore(state => state.setShowInputFieldDialog)
|
const setShowInputFieldDialog = useStore(state => state.setShowInputFieldDialog)
|
||||||
const handleClick = useCallback(() => {
|
const handleClick = useCallback(() => {
|
||||||
setShowInputFieldDialog?.(true)
|
setShowInputFieldDialog?.(true)
|
||||||
@ -16,8 +18,7 @@ const InputFieldButton = () => {
|
|||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
>
|
>
|
||||||
<InputField className='h-4 w-4' />
|
<InputField className='h-4 w-4' />
|
||||||
{/* // TODO: i18n */}
|
<span className='px-0.5'>{t('datasetPipeline.inputField')}</span>
|
||||||
<span className='px-0.5'>Input Field</span>
|
|
||||||
</Button>
|
</Button>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
|
import type { RAGPipelineVariables } from '@/models/pipeline'
|
||||||
import type { StateCreator } from 'zustand'
|
import type { StateCreator } from 'zustand'
|
||||||
|
import { InputVarType } from '../../workflow/types'
|
||||||
|
|
||||||
export type RagPipelineSliceShape = {
|
export type RagPipelineSliceShape = {
|
||||||
pipelineId: string
|
pipelineId: string
|
||||||
@ -6,6 +8,8 @@ export type RagPipelineSliceShape = {
|
|||||||
setShowInputFieldDialog: (showInputFieldPanel: boolean) => void
|
setShowInputFieldDialog: (showInputFieldPanel: boolean) => void
|
||||||
nodesDefaultConfigs: Record<string, any>
|
nodesDefaultConfigs: Record<string, any>
|
||||||
setNodesDefaultConfigs: (nodesDefaultConfigs: Record<string, any>) => void
|
setNodesDefaultConfigs: (nodesDefaultConfigs: Record<string, any>) => void
|
||||||
|
ragPipelineVariables: RAGPipelineVariables
|
||||||
|
setRagPipelineVariables: (ragPipelineVariables: RAGPipelineVariables) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CreateRagPipelineSliceSlice = StateCreator<RagPipelineSliceShape>
|
export type CreateRagPipelineSliceSlice = StateCreator<RagPipelineSliceShape>
|
||||||
@ -15,4 +19,35 @@ export const createRagPipelineSliceSlice: StateCreator<RagPipelineSliceShape> =
|
|||||||
setShowInputFieldDialog: showInputFieldDialog => set(() => ({ showInputFieldDialog })),
|
setShowInputFieldDialog: showInputFieldDialog => set(() => ({ showInputFieldDialog })),
|
||||||
nodesDefaultConfigs: {},
|
nodesDefaultConfigs: {},
|
||||||
setNodesDefaultConfigs: nodesDefaultConfigs => set(() => ({ nodesDefaultConfigs })),
|
setNodesDefaultConfigs: nodesDefaultConfigs => set(() => ({ nodesDefaultConfigs })),
|
||||||
|
ragPipelineVariables: [{
|
||||||
|
// TODO: delete mock data
|
||||||
|
nodeId: '123',
|
||||||
|
variables: [{
|
||||||
|
variable: 'name',
|
||||||
|
label: 'name',
|
||||||
|
type: InputVarType.textInput,
|
||||||
|
required: true,
|
||||||
|
max_length: 12,
|
||||||
|
}, {
|
||||||
|
variable: 'num',
|
||||||
|
label: 'num',
|
||||||
|
type: InputVarType.number,
|
||||||
|
required: true,
|
||||||
|
}],
|
||||||
|
}, {
|
||||||
|
nodeId: '',
|
||||||
|
variables: [{
|
||||||
|
variable: 'name',
|
||||||
|
label: 'name',
|
||||||
|
type: InputVarType.textInput,
|
||||||
|
required: true,
|
||||||
|
max_length: 12,
|
||||||
|
}, {
|
||||||
|
variable: 'num',
|
||||||
|
label: 'num',
|
||||||
|
type: InputVarType.number,
|
||||||
|
required: true,
|
||||||
|
}],
|
||||||
|
}],
|
||||||
|
setRagPipelineVariables: (ragPipelineVariables: RAGPipelineVariables) => set(() => ({ ragPipelineVariables })),
|
||||||
})
|
})
|
||||||
|
|||||||
@ -55,6 +55,17 @@ const translation = {
|
|||||||
localFiles: 'Local Files',
|
localFiles: 'Local Files',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
inputField: 'Input Field',
|
||||||
|
inputFieldPanel: {
|
||||||
|
title: 'User Input Fields',
|
||||||
|
description: 'User input fields are used to define and collect variables required during the pipeline execution process. Users can customize the field type and flexibly configure the input value to meet the needs of different data sources or document processing steps.',
|
||||||
|
sharedInputs: {
|
||||||
|
title: 'Shared Inputs',
|
||||||
|
tooltip: 'Shared Inputs are available to all downstream nodes across data sources. For example, variables like delimiter and maximum chunk length can be uniformly applied when processing documents from multiple sources.',
|
||||||
|
},
|
||||||
|
addInputField: 'Add Input Field',
|
||||||
|
editInputField: 'Edit Input Field',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export default translation
|
export default translation
|
||||||
|
|||||||
@ -54,6 +54,17 @@ const translation = {
|
|||||||
dataSource: {
|
dataSource: {
|
||||||
localFiles: '本地文件',
|
localFiles: '本地文件',
|
||||||
},
|
},
|
||||||
|
inputField: '输入字段',
|
||||||
|
inputFieldPanel: {
|
||||||
|
title: '用户输入字段',
|
||||||
|
description: '用户输入字段用于定义和收集流水线执行过程中所需的变量,用户可以自定义字段类型,并灵活配置输入,以满足不同数据源或文档处理的需求。',
|
||||||
|
sharedInputs: {
|
||||||
|
title: '共享输入',
|
||||||
|
tooltip: '共享输入可被数据源中的所有下游节点使用。例如,在处理来自多个来源的文档时,delimiter(分隔符)和 maximum chunk length(最大分块长度)等变量可以统一应用。',
|
||||||
|
},
|
||||||
|
addInputField: '添加输入字段',
|
||||||
|
editInputField: '编辑输入字段',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import type { InputVarType } from '@/app/components/workflow/types'
|
import type { InputVar, InputVarType } from '@/app/components/workflow/types'
|
||||||
import type { DSLImportMode, DSLImportStatus } from './app'
|
import type { DSLImportMode, DSLImportStatus } from './app'
|
||||||
import type { ChunkingMode, IconInfo } from './datasets'
|
import type { ChunkingMode, IconInfo } from './datasets'
|
||||||
import type { Dependency } from '@/app/components/plugins/types'
|
import type { Dependency } from '@/app/components/plugins/types'
|
||||||
@ -85,3 +85,10 @@ export type Variables = {
|
|||||||
export type PipelineProcessingParamsResponse = {
|
export type PipelineProcessingParamsResponse = {
|
||||||
variables: Variables[]
|
variables: Variables[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type RAGPipelineVariable = InputVar
|
||||||
|
|
||||||
|
export type RAGPipelineVariables = Array<{
|
||||||
|
nodeId: string
|
||||||
|
variables: RAGPipelineVariable[]
|
||||||
|
}>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user