CRLF→LF
parent
292566b121
commit
bb100e8228
@ -1,173 +1,173 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import type { FC } from 'react'
|
import type { FC } from 'react'
|
||||||
import React, { useCallback, useMemo } from 'react'
|
import React, { useCallback, useMemo } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import produce from 'immer'
|
import produce from 'immer'
|
||||||
import RemoveButton from '../remove-button'
|
import RemoveButton from '../remove-button'
|
||||||
import VarReferencePicker from './var-reference-picker'
|
import VarReferencePicker from './var-reference-picker'
|
||||||
import Input from '@/app/components/base/input'
|
import Input from '@/app/components/base/input'
|
||||||
import type { ValueSelector, Var, Variable } from '@/app/components/workflow/types'
|
import type { ValueSelector, Var, Variable } from '@/app/components/workflow/types'
|
||||||
import { VarType as VarKindType } from '@/app/components/workflow/nodes/tool/types'
|
import { VarType as VarKindType } from '@/app/components/workflow/nodes/tool/types'
|
||||||
import { checkKeys, replaceSpaceWithUnderscreInVarNameInput } from '@/utils/var'
|
import { checkKeys, replaceSpaceWithUnderscreInVarNameInput } from '@/utils/var'
|
||||||
import Toast from '@/app/components/base/toast'
|
import Toast from '@/app/components/base/toast'
|
||||||
import { ReactSortable } from 'react-sortablejs'
|
import { ReactSortable } from 'react-sortablejs'
|
||||||
import { v4 as uuid4 } from 'uuid'
|
import { v4 as uuid4 } from 'uuid'
|
||||||
import { RiDraggable } from '@remixicon/react'
|
import { RiDraggable } from '@remixicon/react'
|
||||||
import cn from '@/utils/classnames'
|
import cn from '@/utils/classnames'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
nodeId: string
|
nodeId: string
|
||||||
readonly: boolean
|
readonly: boolean
|
||||||
list: Variable[]
|
list: Variable[]
|
||||||
onChange: (list: Variable[]) => void
|
onChange: (list: Variable[]) => void
|
||||||
onVarNameChange?: (oldName: string, newName: string) => void
|
onVarNameChange?: (oldName: string, newName: string) => void
|
||||||
isSupportConstantValue?: boolean
|
isSupportConstantValue?: boolean
|
||||||
onlyLeafNodeVar?: boolean
|
onlyLeafNodeVar?: boolean
|
||||||
filterVar?: (payload: Var, valueSelector: ValueSelector) => boolean
|
filterVar?: (payload: Var, valueSelector: ValueSelector) => boolean
|
||||||
isSupportFileVar?: boolean
|
isSupportFileVar?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const VarList: FC<Props> = ({
|
const VarList: FC<Props> = ({
|
||||||
nodeId,
|
nodeId,
|
||||||
readonly,
|
readonly,
|
||||||
list,
|
list,
|
||||||
onChange,
|
onChange,
|
||||||
onVarNameChange,
|
onVarNameChange,
|
||||||
isSupportConstantValue,
|
isSupportConstantValue,
|
||||||
onlyLeafNodeVar,
|
onlyLeafNodeVar,
|
||||||
filterVar,
|
filterVar,
|
||||||
isSupportFileVar = true,
|
isSupportFileVar = true,
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
const listWithIds = useMemo(() => list.map((item) => {
|
const listWithIds = useMemo(() => list.map((item) => {
|
||||||
const id = uuid4()
|
const id = uuid4()
|
||||||
return {
|
return {
|
||||||
id,
|
id,
|
||||||
variable: { ...item },
|
variable: { ...item },
|
||||||
}
|
}
|
||||||
}), [list])
|
}), [list])
|
||||||
|
|
||||||
const handleVarNameChange = useCallback((index: number) => {
|
const handleVarNameChange = useCallback((index: number) => {
|
||||||
return (e: React.ChangeEvent<HTMLInputElement>) => {
|
return (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
replaceSpaceWithUnderscreInVarNameInput(e.target)
|
replaceSpaceWithUnderscreInVarNameInput(e.target)
|
||||||
|
|
||||||
const newKey = e.target.value
|
const newKey = e.target.value
|
||||||
const { isValid, errorKey, errorMessageKey } = checkKeys([newKey], true)
|
const { isValid, errorKey, errorMessageKey } = checkKeys([newKey], true)
|
||||||
if (!isValid) {
|
if (!isValid) {
|
||||||
Toast.notify({
|
Toast.notify({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
message: t(`appDebug.varKeyError.${errorMessageKey}`, { key: errorKey }),
|
message: t(`appDebug.varKeyError.${errorMessageKey}`, { key: errorKey }),
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (list.map(item => item.variable?.trim()).includes(newKey.trim())) {
|
if (list.map(item => item.variable?.trim()).includes(newKey.trim())) {
|
||||||
Toast.notify({
|
Toast.notify({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
message: t('appDebug.varKeyError.keyAlreadyExists', { key: newKey }),
|
message: t('appDebug.varKeyError.keyAlreadyExists', { key: newKey }),
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
onVarNameChange?.(list[index].variable, newKey)
|
onVarNameChange?.(list[index].variable, newKey)
|
||||||
const newList = produce(list, (draft) => {
|
const newList = produce(list, (draft) => {
|
||||||
draft[index].variable = newKey
|
draft[index].variable = newKey
|
||||||
})
|
})
|
||||||
onChange(newList)
|
onChange(newList)
|
||||||
}
|
}
|
||||||
}, [list, onVarNameChange, onChange])
|
}, [list, onVarNameChange, onChange])
|
||||||
|
|
||||||
const handleVarReferenceChange = useCallback((index: number) => {
|
const handleVarReferenceChange = useCallback((index: number) => {
|
||||||
return (value: ValueSelector | string, varKindType: VarKindType, varInfo?: Var) => {
|
return (value: ValueSelector | string, varKindType: VarKindType, varInfo?: Var) => {
|
||||||
const newList = produce(list, (draft) => {
|
const newList = produce(list, (draft) => {
|
||||||
if (!isSupportConstantValue || varKindType === VarKindType.variable) {
|
if (!isSupportConstantValue || varKindType === VarKindType.variable) {
|
||||||
draft[index].value_selector = value as ValueSelector
|
draft[index].value_selector = value as ValueSelector
|
||||||
draft[index].value_type = varInfo?.type
|
draft[index].value_type = varInfo?.type
|
||||||
if (isSupportConstantValue)
|
if (isSupportConstantValue)
|
||||||
draft[index].variable_type = VarKindType.variable
|
draft[index].variable_type = VarKindType.variable
|
||||||
|
|
||||||
if (!draft[index].variable) {
|
if (!draft[index].variable) {
|
||||||
const variables = draft.map(v => v.variable)
|
const variables = draft.map(v => v.variable)
|
||||||
let newVarName = value[value.length - 1]
|
let newVarName = value[value.length - 1]
|
||||||
let count = 1
|
let count = 1
|
||||||
while (variables.includes(newVarName)) {
|
while (variables.includes(newVarName)) {
|
||||||
newVarName = `${value[value.length - 1]}_${count}`
|
newVarName = `${value[value.length - 1]}_${count}`
|
||||||
count++
|
count++
|
||||||
}
|
}
|
||||||
draft[index].variable = newVarName
|
draft[index].variable = newVarName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
draft[index].variable_type = VarKindType.constant
|
draft[index].variable_type = VarKindType.constant
|
||||||
draft[index].value_selector = value as ValueSelector
|
draft[index].value_selector = value as ValueSelector
|
||||||
draft[index].value = value as string
|
draft[index].value = value as string
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
onChange(newList)
|
onChange(newList)
|
||||||
}
|
}
|
||||||
}, [isSupportConstantValue, list, onChange])
|
}, [isSupportConstantValue, list, onChange])
|
||||||
|
|
||||||
const handleVarRemove = useCallback((index: number) => {
|
const handleVarRemove = useCallback((index: number) => {
|
||||||
return () => {
|
return () => {
|
||||||
const newList = produce(list, (draft) => {
|
const newList = produce(list, (draft) => {
|
||||||
draft.splice(index, 1)
|
draft.splice(index, 1)
|
||||||
})
|
})
|
||||||
onChange(newList)
|
onChange(newList)
|
||||||
}
|
}
|
||||||
}, [list, onChange])
|
}, [list, onChange])
|
||||||
|
|
||||||
const varCount = list.length
|
const varCount = list.length
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ReactSortable
|
<ReactSortable
|
||||||
className='space-y-2'
|
className='space-y-2'
|
||||||
list={listWithIds}
|
list={listWithIds}
|
||||||
setList={(list) => { onChange(list.map(item => item.variable)) }}
|
setList={(list) => { onChange(list.map(item => item.variable)) }}
|
||||||
handle='.handle'
|
handle='.handle'
|
||||||
ghostClass='opacity-50'
|
ghostClass='opacity-50'
|
||||||
animation={150}
|
animation={150}
|
||||||
>
|
>
|
||||||
{listWithIds.map((item, index) => {
|
{listWithIds.map((item, index) => {
|
||||||
const canDrag = (() => {
|
const canDrag = (() => {
|
||||||
if (readonly)
|
if (readonly)
|
||||||
return false
|
return false
|
||||||
return varCount > 1
|
return varCount > 1
|
||||||
})()
|
})()
|
||||||
const variable = item.variable
|
const variable = item.variable
|
||||||
return (
|
return (
|
||||||
<div className={cn('flex items-center space-x-1', 'group relative')} key={index}>
|
<div className={cn('flex items-center space-x-1', 'group relative')} key={index}>
|
||||||
<Input
|
<Input
|
||||||
wrapperClassName='w-[120px]'
|
wrapperClassName='w-[120px]'
|
||||||
disabled={readonly}
|
disabled={readonly}
|
||||||
value={variable.variable}
|
value={variable.variable}
|
||||||
onChange={handleVarNameChange(index)}
|
onChange={handleVarNameChange(index)}
|
||||||
placeholder={t('workflow.common.variableNamePlaceholder')!}
|
placeholder={t('workflow.common.variableNamePlaceholder')!}
|
||||||
/>
|
/>
|
||||||
<VarReferencePicker
|
<VarReferencePicker
|
||||||
nodeId={nodeId}
|
nodeId={nodeId}
|
||||||
readonly={readonly}
|
readonly={readonly}
|
||||||
isShowNodeName
|
isShowNodeName
|
||||||
className='grow'
|
className='grow'
|
||||||
value={variable.variable_type === VarKindType.constant ? (variable.value || '') : (variable.value_selector || [])}
|
value={variable.variable_type === VarKindType.constant ? (variable.value || '') : (variable.value_selector || [])}
|
||||||
isSupportConstantValue={isSupportConstantValue}
|
isSupportConstantValue={isSupportConstantValue}
|
||||||
onChange={handleVarReferenceChange(index)}
|
onChange={handleVarReferenceChange(index)}
|
||||||
defaultVarKindType={variable.variable_type}
|
defaultVarKindType={variable.variable_type}
|
||||||
onlyLeafNodeVar={onlyLeafNodeVar}
|
onlyLeafNodeVar={onlyLeafNodeVar}
|
||||||
filterVar={filterVar}
|
filterVar={filterVar}
|
||||||
isSupportFileVar={isSupportFileVar}
|
isSupportFileVar={isSupportFileVar}
|
||||||
/>
|
/>
|
||||||
{!readonly && (
|
{!readonly && (
|
||||||
<RemoveButton onClick={handleVarRemove(index)}/>
|
<RemoveButton onClick={handleVarRemove(index)}/>
|
||||||
)}
|
)}
|
||||||
{canDrag && <RiDraggable className={cn(
|
{canDrag && <RiDraggable className={cn(
|
||||||
'handle absolute -left-4 top-3 hidden h-3 w-3 cursor-pointer text-text-quaternary',
|
'handle absolute -left-4 top-3 hidden h-3 w-3 cursor-pointer text-text-quaternary',
|
||||||
'group-hover:block',
|
'group-hover:block',
|
||||||
)} />}
|
)} />}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</ReactSortable>
|
</ReactSortable>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
export default React.memo(VarList)
|
export default React.memo(VarList)
|
||||||
|
|||||||
Loading…
Reference in New Issue