mirror of
https://github.com/langgenius/dify.git
synced 2026-01-08 07:14:14 +00:00
feat: support node type filter
This commit is contained in:
@@ -21,7 +21,7 @@ const inputVarTypeToVarType = (type: InputVarType): VarType => {
|
||||
return VarType.string
|
||||
}
|
||||
|
||||
const formatItem = (item: any, isChatMode: boolean): NodeOutPutVar => {
|
||||
const formatItem = (item: any, isChatMode: boolean, varType?: VarType): NodeOutPutVar => {
|
||||
const { id, data } = item
|
||||
const res: NodeOutPutVar = {
|
||||
nodeId: id,
|
||||
@@ -109,9 +109,15 @@ const formatItem = (item: any, isChatMode: boolean): NodeOutPutVar => {
|
||||
break
|
||||
}
|
||||
}
|
||||
if (varType)
|
||||
res.vars = res.vars.filter(v => v.type === varType)
|
||||
|
||||
return res
|
||||
}
|
||||
export const toNodeOutputVars = (nodes: any[], isChatMode: boolean): NodeOutPutVar[] => {
|
||||
return nodes.filter(node => SUPPORT_OUTPUT_VARS_NODE.includes(node.data.type)).map(node => formatItem(node, isChatMode))
|
||||
export const toNodeOutputVars = (nodes: any[], isChatMode: boolean, varType?: VarType): NodeOutPutVar[] => {
|
||||
const res = nodes
|
||||
.filter(node => SUPPORT_OUTPUT_VARS_NODE.includes(node.data.type))
|
||||
.map(node => formatItem(node, isChatMode, varType))
|
||||
.filter(item => item.vars.length > 0)
|
||||
return res
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import React, { useCallback } from 'react'
|
||||
import produce from 'immer'
|
||||
import RemoveButton from '../remove-button'
|
||||
import VarReferencePicker from './var-reference-picker'
|
||||
import { type ValueSelector, type Variable } from '@/app/components/workflow/types'
|
||||
import { type ValueSelector, type VarType, type Variable } from '@/app/components/workflow/types'
|
||||
import { VarType as VarKindType } from '@/app/components/workflow/nodes/tool/types'
|
||||
|
||||
type Props = {
|
||||
@@ -13,6 +13,8 @@ type Props = {
|
||||
list: Variable[]
|
||||
onChange: (list: Variable[]) => void
|
||||
isSupportConstantValue?: boolean
|
||||
onlyLeafNodeVar?: boolean
|
||||
onlyVarType?: VarType
|
||||
}
|
||||
|
||||
const VarList: FC<Props> = ({
|
||||
@@ -21,6 +23,8 @@ const VarList: FC<Props> = ({
|
||||
list,
|
||||
onChange,
|
||||
isSupportConstantValue,
|
||||
onlyLeafNodeVar,
|
||||
onlyVarType,
|
||||
}) => {
|
||||
const handleVarNameChange = useCallback((index: number) => {
|
||||
return (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
@@ -80,6 +84,8 @@ const VarList: FC<Props> = ({
|
||||
isSupportConstantValue={isSupportConstantValue}
|
||||
onChange={handleVarReferenceChange(index)}
|
||||
defaultVarKindType={item.variable_type}
|
||||
onlyLeafNodeVar={onlyLeafNodeVar}
|
||||
onlyVarType={onlyVarType}
|
||||
/>
|
||||
<RemoveButton
|
||||
className='!p-2 !bg-gray-100 hover:!bg-gray-200'
|
||||
|
||||
@@ -33,6 +33,8 @@ type Props = {
|
||||
onChange: (value: ValueSelector | string, varKindType: VarKindType) => void
|
||||
isSupportConstantValue?: boolean
|
||||
defaultVarKindType?: VarKindType
|
||||
onlyLeafNodeVar?: boolean
|
||||
onlyVarType?: VarType
|
||||
}
|
||||
|
||||
export const getNodeInfoById = (nodes: any, id: string) => {
|
||||
@@ -52,13 +54,15 @@ const VarReferencePicker: FC<Props> = ({
|
||||
onChange,
|
||||
isSupportConstantValue,
|
||||
defaultVarKindType = VarKindType.static,
|
||||
onlyLeafNodeVar,
|
||||
onlyVarType,
|
||||
}) => {
|
||||
const isChatMode = useIsChatMode()
|
||||
const [varKindType, setVarKindType] = useState<VarKindType>(defaultVarKindType)
|
||||
const isConstant = isSupportConstantValue && varKindType === VarKindType.static
|
||||
const { getTreeLeafNodes, getBeforeNodesInSameBranch } = useWorkflow()
|
||||
const availableNodes = getBeforeNodesInSameBranch(nodeId)
|
||||
const outputVars = toNodeOutputVars(availableNodes, isChatMode)
|
||||
const availableNodes = onlyLeafNodeVar ? getTreeLeafNodes() : getBeforeNodesInSameBranch(nodeId)
|
||||
const outputVars = toNodeOutputVars(availableNodes, isChatMode, onlyVarType)
|
||||
const [open, setOpen] = useState(false)
|
||||
const hasValue = !isConstant && value.length > 0
|
||||
const outputVarNodeId = hasValue ? value[0] : ''
|
||||
@@ -128,12 +132,13 @@ const VarReferencePicker: FC<Props> = ({
|
||||
onOpenChange={setOpen}
|
||||
placement='bottom-start'
|
||||
>
|
||||
<PortalToFollowElemTrigger onClick={() => !isConstant && setOpen(!open)} className='!flex'>
|
||||
<PortalToFollowElemTrigger onClick={() => !isConstant ? setOpen(!open) : setControlFocus(Date.now())} className='!flex'>
|
||||
<div className={cn((open || isFocus) && 'border border-gray-300', 'flex items-center w-full h-8 p-1 rounded-lg bg-gray-100')}>
|
||||
{isSupportConstantValue
|
||||
? <div onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
setOpen(false)
|
||||
setControlFocus(Date.now())
|
||||
}} className='mr-1 flex items-center space-x-1'>
|
||||
<TypeSelector
|
||||
noLeft
|
||||
|
||||
@@ -3,6 +3,7 @@ import type { FC } from 'react'
|
||||
import React, { useRef } from 'react'
|
||||
import { useHover } from 'ahooks'
|
||||
import cn from 'classnames'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { type NodeOutPutVar, type ValueSelector, type Var, VarType } from '@/app/components/workflow/types'
|
||||
import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development'
|
||||
import { ChevronRight } from '@/app/components/base/icons/src/vender/line/arrows'
|
||||
@@ -90,7 +91,8 @@ const ObjectChildren: FC<ObjectChildrenProps> = ({
|
||||
}}>
|
||||
<div className='flex items-center h-[22px] px-3 text-xs font-normal text-gray-700'><span className='text-gray-500'>{title}.</span>{currObjPath.join('.')}</div>
|
||||
{
|
||||
data?.map((v, i) => (
|
||||
(data && data.length > 0)
|
||||
&& data.map((v, i) => (
|
||||
<Item
|
||||
key={i}
|
||||
nodeId={nodeId}
|
||||
@@ -115,26 +117,30 @@ const VarReferencePopup: FC<Props> = ({
|
||||
onChange,
|
||||
itemWidth,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<div className='p-1 bg-white rounded-lg border border-gray-200 shadow-lg space-y-1' style={{
|
||||
width: itemWidth || 228,
|
||||
}}>
|
||||
{vars.map((item, i) => (
|
||||
<div key={i}>
|
||||
<div className='flex items-center h-[22px] px-3 text-xs font-medium text-gray-500 uppercase'>{item.title}</div>
|
||||
{item.vars.map((v, j) => (
|
||||
<Item
|
||||
key={j}
|
||||
title={item.title}
|
||||
nodeId={item.nodeId}
|
||||
objPath={[]}
|
||||
itemData={v}
|
||||
onChange={onChange}
|
||||
itemWidth={itemWidth}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
{vars.length > 0
|
||||
? vars.map((item, i) => (
|
||||
<div key={i}>
|
||||
<div className='flex items-center h-[22px] px-3 text-xs font-medium text-gray-500 uppercase'>{item.title}</div>
|
||||
{item.vars.map((v, j) => (
|
||||
<Item
|
||||
key={j}
|
||||
title={item.title}
|
||||
nodeId={item.nodeId}
|
||||
objPath={[]}
|
||||
itemData={v}
|
||||
onChange={onChange}
|
||||
itemWidth={itemWidth}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
))
|
||||
: <div className='pl-3 leading-[18px] text-xs font-medium text-gray-500 uppercase'>{t('workflow.common.noVar')}</div>}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import { EndVarType } from './types'
|
||||
import VarList from '@/app/components/workflow/nodes/_base/components/variable/var-list'
|
||||
import Field from '@/app/components/workflow/nodes/_base/components/field'
|
||||
import AddButton from '@/app/components/base/button/add-button'
|
||||
import type { NodePanelProps } from '@/app/components/workflow/types'
|
||||
import { type NodePanelProps } from '@/app/components/workflow/types'
|
||||
|
||||
const i18nPrefix = 'workflow.nodes.end'
|
||||
|
||||
|
||||
@@ -13,9 +13,9 @@ const useConfig = (id: string, payload: EndNodeType) => {
|
||||
setInputs(newInputs)
|
||||
}, [inputs, setInputs])
|
||||
|
||||
const handelPlainTextSelectorChange = useCallback((newList: string[]) => {
|
||||
const handelPlainTextSelectorChange = useCallback((newList: string[] | string) => {
|
||||
const newInputs = produce(inputs, (draft: any) => {
|
||||
draft.outputs.plain_text_selector = newList
|
||||
draft.outputs.plain_text_selector = newList as string[]
|
||||
})
|
||||
setInputs(newInputs)
|
||||
}
|
||||
|
||||
@@ -5,13 +5,15 @@ import React, { useCallback } from 'react'
|
||||
import produce from 'immer'
|
||||
import RemoveButton from '../../../_base/components/remove-button'
|
||||
import VarReferencePicker from '@/app/components/workflow/nodes/_base/components/variable/var-reference-picker'
|
||||
import type { ValueSelector } from '@/app/components/workflow/types'
|
||||
import type { ValueSelector, VarType } from '@/app/components/workflow/types'
|
||||
|
||||
type Props = {
|
||||
readonly: boolean
|
||||
nodeId: string
|
||||
list: ValueSelector[]
|
||||
onChange: (list: ValueSelector[]) => void
|
||||
onlyLeafNodeVar?: boolean
|
||||
onlyVarType?: VarType
|
||||
}
|
||||
|
||||
const VarList: FC<Props> = ({
|
||||
@@ -19,12 +21,14 @@ const VarList: FC<Props> = ({
|
||||
nodeId,
|
||||
list,
|
||||
onChange,
|
||||
onlyLeafNodeVar,
|
||||
onlyVarType,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const handleVarReferenceChange = useCallback((index: number) => {
|
||||
return (value: ValueSelector) => {
|
||||
return (value: ValueSelector | string) => {
|
||||
const newList = produce(list, (draft) => {
|
||||
draft[index] = value
|
||||
draft[index] = value as ValueSelector
|
||||
})
|
||||
onChange(newList)
|
||||
}
|
||||
@@ -58,6 +62,9 @@ const VarList: FC<Props> = ({
|
||||
className='grow'
|
||||
value={item}
|
||||
onChange={handleVarReferenceChange(index)}
|
||||
onlyLeafNodeVar={onlyLeafNodeVar}
|
||||
onlyVarType={onlyVarType}
|
||||
width={350}
|
||||
/>
|
||||
<RemoveButton
|
||||
className='!p-2 !bg-gray-100 hover:!bg-gray-200'
|
||||
|
||||
@@ -34,7 +34,7 @@ const Node: FC<NodeProps<VariableAssignerNodeType>> = (props) => {
|
||||
<>
|
||||
<div className='space-y-0.5'>
|
||||
{variables.map((item, index) => {
|
||||
const node = getNodeInfoById(item[0])
|
||||
const node = getNodeInfoById([], item[0]) // TODO: can not get all nodes
|
||||
const varName = item[item.length - 1]
|
||||
return (
|
||||
<div key={index} className='relative flex items-center h-6 bg-gray-100 rounded-md px-1 text-xs font-normal text-gray-700' >
|
||||
|
||||
@@ -9,6 +9,7 @@ import Selector from '@/app/components/workflow/nodes/_base/components/selector'
|
||||
import AddButton from '@/app/components/base/button/add-button'
|
||||
import { ChevronDown } from '@/app/components/base/icons/src/vender/line/arrows'
|
||||
import type { NodePanelProps } from '@/app/components/workflow/types'
|
||||
import { VarType } from '@/app/components/workflow/types'
|
||||
|
||||
const i18nPrefix = 'workflow.nodes.variableAssigner'
|
||||
const Panel: FC<NodePanelProps<VariableAssignerNodeType>> = ({
|
||||
@@ -26,10 +27,10 @@ const Panel: FC<NodePanelProps<VariableAssignerNodeType>> = ({
|
||||
} = useConfig(id, data)
|
||||
|
||||
const typeOptions = [
|
||||
{ label: t(`${i18nPrefix}.type.string`), value: 'string' },
|
||||
{ label: t(`${i18nPrefix}.type.number`), value: 'number' },
|
||||
{ label: t(`${i18nPrefix}.type.object`), value: 'object' },
|
||||
{ label: t(`${i18nPrefix}.type.array`), value: 'array' },
|
||||
{ label: t(`${i18nPrefix}.type.string`), value: VarType.string },
|
||||
{ label: t(`${i18nPrefix}.type.number`), value: VarType.number },
|
||||
{ label: t(`${i18nPrefix}.type.object`), value: VarType.object },
|
||||
{ label: t(`${i18nPrefix}.type.array`), value: VarType.array },
|
||||
]
|
||||
|
||||
return (
|
||||
@@ -64,6 +65,8 @@ const Panel: FC<NodePanelProps<VariableAssignerNodeType>> = ({
|
||||
nodeId={id}
|
||||
list={inputs.variables}
|
||||
onChange={handleVarListChange}
|
||||
onlyLeafNodeVar
|
||||
onlyVarType={inputs.output_type}
|
||||
/>
|
||||
</Field>
|
||||
</div>
|
||||
|
||||
@@ -23,6 +23,7 @@ const translation = {
|
||||
restore: 'Restore',
|
||||
addTitle: 'Add title...',
|
||||
addDescription: 'Add description...',
|
||||
noVar: 'No variable',
|
||||
},
|
||||
singleRun: {
|
||||
testRun: 'Test Run ',
|
||||
|
||||
@@ -23,6 +23,7 @@ const translation = {
|
||||
restore: '恢复',
|
||||
addTitle: '添加标题...',
|
||||
addDescription: '添加描述...',
|
||||
noVar: '没有变量',
|
||||
},
|
||||
singleRun: {
|
||||
testRun: '测试运行 ',
|
||||
|
||||
Reference in New Issue
Block a user