mirror of
https://github.com/langgenius/dify.git
synced 2026-05-02 08:28:03 +08:00
available nodes
This commit is contained in:
@ -3,23 +3,33 @@ import {
|
||||
useCallback,
|
||||
} from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useNodesInteractions } from '@/app/components/workflow/hooks'
|
||||
import {
|
||||
useNodesExtraData,
|
||||
useNodesInteractions,
|
||||
} from '@/app/components/workflow/hooks'
|
||||
import BlockSelector from '@/app/components/workflow/block-selector'
|
||||
import { Plus } from '@/app/components/base/icons/src/vender/line/general'
|
||||
import type { OnSelectBlock } from '@/app/components/workflow/types'
|
||||
import type {
|
||||
BlockEnum,
|
||||
OnSelectBlock,
|
||||
} from '@/app/components/workflow/types'
|
||||
|
||||
type AddProps = {
|
||||
nodeId: string
|
||||
nodeType: BlockEnum
|
||||
sourceHandle: string
|
||||
branchName?: string
|
||||
}
|
||||
const Add = ({
|
||||
nodeId,
|
||||
nodeType,
|
||||
sourceHandle,
|
||||
branchName,
|
||||
}: AddProps) => {
|
||||
const { t } = useTranslation()
|
||||
const { handleNodeAdd } = useNodesInteractions()
|
||||
const nodesExtraData = useNodesExtraData()
|
||||
const availableNextNodes = nodesExtraData[nodeType].availableNextNodes
|
||||
|
||||
const handleSelect = useCallback<OnSelectBlock>((type, toolDefaultValue) => {
|
||||
handleNodeAdd(
|
||||
@ -65,6 +75,7 @@ const Add = ({
|
||||
offset={0}
|
||||
trigger={renderTrigger}
|
||||
popupClassName='!w-[328px]'
|
||||
availableBlocksTypes={availableNextNodes}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@ -51,6 +51,7 @@ const NextStep = ({
|
||||
!nodeWithBranches && !outgoers.length && (
|
||||
<Add
|
||||
nodeId={selectedNode!.id}
|
||||
nodeType={selectedNode!.data.type}
|
||||
sourceHandle='source'
|
||||
/>
|
||||
)
|
||||
@ -81,6 +82,7 @@ const NextStep = ({
|
||||
<Add
|
||||
key={branch.id}
|
||||
nodeId={selectedNode!.id}
|
||||
nodeType={selectedNode!.data.type}
|
||||
sourceHandle={branch.id}
|
||||
branchName={branch.name}
|
||||
/>
|
||||
|
||||
@ -3,13 +3,17 @@ import {
|
||||
useCallback,
|
||||
} from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { union } from 'lodash-es'
|
||||
import type {
|
||||
CommonNodeType,
|
||||
OnSelectBlock,
|
||||
} from '@/app/components/workflow/types'
|
||||
import BlockIcon from '@/app/components/workflow/block-icon'
|
||||
import BlockSelector from '@/app/components/workflow/block-selector'
|
||||
import { useNodesInteractions } from '@/app/components/workflow/hooks'
|
||||
import {
|
||||
useNodesExtraData,
|
||||
useNodesInteractions,
|
||||
} from '@/app/components/workflow/hooks'
|
||||
import Button from '@/app/components/base/button'
|
||||
|
||||
type ItemProps = {
|
||||
@ -26,6 +30,9 @@ const Item = ({
|
||||
}: ItemProps) => {
|
||||
const { t } = useTranslation()
|
||||
const { handleNodeChange } = useNodesInteractions()
|
||||
const nodesExtraData = useNodesExtraData()
|
||||
const availablePrevNodes = nodesExtraData[data.type].availablePrevNodes
|
||||
const availableNextNodes = nodesExtraData[data.type].availableNextNodes
|
||||
const handleSelect = useCallback<OnSelectBlock>((type, toolDefaultValue) => {
|
||||
handleNodeChange(nodeId, type, sourceHandle, toolDefaultValue)
|
||||
}, [nodeId, sourceHandle, handleNodeChange])
|
||||
@ -68,6 +75,7 @@ const Item = ({
|
||||
}}
|
||||
trigger={renderTrigger}
|
||||
popupClassName='!w-[328px]'
|
||||
availableBlocksTypes={union(availablePrevNodes, availableNextNodes)}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
@ -13,7 +13,10 @@ import { BlockEnum } from '../../../types'
|
||||
import type { Node } from '../../../types'
|
||||
import BlockSelector from '../../../block-selector'
|
||||
import type { ToolDefaultValue } from '../../../block-selector/types'
|
||||
import { useNodesInteractions } from '../../../hooks'
|
||||
import {
|
||||
useNodesExtraData,
|
||||
useNodesInteractions,
|
||||
} from '../../../hooks'
|
||||
import { useStore } from '../../../store'
|
||||
|
||||
type NodeHandleProps = {
|
||||
@ -31,7 +34,10 @@ export const NodeTargetHandle = memo(({
|
||||
}: NodeHandleProps) => {
|
||||
const [open, setOpen] = useState(false)
|
||||
const { handleNodeAdd } = useNodesInteractions()
|
||||
const nodesExtraData = useNodesExtraData()
|
||||
const connected = data._connectedTargetHandleIds?.includes(handleId)
|
||||
const availablePrevNodes = nodesExtraData[data.type].availablePrevNodes
|
||||
const isConnectable = !!availablePrevNodes.length
|
||||
|
||||
const handleOpenChange = useCallback((v: boolean) => {
|
||||
setOpen(v)
|
||||
@ -67,11 +73,11 @@ export const NodeTargetHandle = memo(({
|
||||
${data.type === BlockEnum.Start && 'opacity-0'}
|
||||
${handleClassName}
|
||||
`}
|
||||
isConnectable={data.type !== BlockEnum.Start}
|
||||
isConnectable={isConnectable}
|
||||
onClick={handleHandleClick}
|
||||
>
|
||||
{
|
||||
!connected && data.type !== BlockEnum.Start && (
|
||||
!connected && isConnectable && (
|
||||
<BlockSelector
|
||||
open={open}
|
||||
onOpenChange={handleOpenChange}
|
||||
@ -84,6 +90,7 @@ export const NodeTargetHandle = memo(({
|
||||
group-hover:flex
|
||||
${open && '!flex'}
|
||||
`}
|
||||
availableBlocksTypes={availablePrevNodes}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@ -103,6 +110,9 @@ export const NodeSourceHandle = memo(({
|
||||
const notInitialWorkflow = useStore(s => s.notInitialWorkflow)
|
||||
const [open, setOpen] = useState(false)
|
||||
const { handleNodeAdd } = useNodesInteractions()
|
||||
const nodesExtraData = useNodesExtraData()
|
||||
const availableNextNodes = nodesExtraData[data.type].availableNextNodes
|
||||
const isConnectable = !!availableNextNodes.length
|
||||
const connected = data._connectedSourceHandleIds?.includes(handleId)
|
||||
const handleOpenChange = useCallback((v: boolean) => {
|
||||
setOpen(v)
|
||||
@ -142,10 +152,11 @@ export const NodeSourceHandle = memo(({
|
||||
${!connected && 'after:opacity-0'}
|
||||
${handleClassName}
|
||||
`}
|
||||
isConnectable={isConnectable}
|
||||
onClick={handleHandleClick}
|
||||
>
|
||||
{
|
||||
!connected && (
|
||||
!connected && isConnectable && (
|
||||
<BlockSelector
|
||||
open={open}
|
||||
onOpenChange={handleOpenChange}
|
||||
@ -157,6 +168,7 @@ export const NodeSourceHandle = memo(({
|
||||
group-hover:flex
|
||||
${open && '!flex'}
|
||||
`}
|
||||
availableBlocksTypes={availableNextNodes}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@ -3,20 +3,32 @@ import {
|
||||
useCallback,
|
||||
} from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { union } from 'lodash-es'
|
||||
import BlockSelector from '@/app/components/workflow/block-selector'
|
||||
import { useNodesInteractions } from '@/app/components/workflow/hooks'
|
||||
import type { OnSelectBlock } from '@/app/components/workflow/types'
|
||||
import {
|
||||
useNodesExtraData,
|
||||
useNodesInteractions,
|
||||
} from '@/app/components/workflow/hooks'
|
||||
import type {
|
||||
BlockEnum,
|
||||
OnSelectBlock,
|
||||
} from '@/app/components/workflow/types'
|
||||
|
||||
type ChangeBlockProps = {
|
||||
nodeId: string
|
||||
nodeType: BlockEnum
|
||||
sourceHandle: string
|
||||
}
|
||||
const ChangeBlock = ({
|
||||
nodeId,
|
||||
nodeType,
|
||||
sourceHandle,
|
||||
}: ChangeBlockProps) => {
|
||||
const { t } = useTranslation()
|
||||
const { handleNodeChange } = useNodesInteractions()
|
||||
const nodesExtraData = useNodesExtraData()
|
||||
const availablePrevNodes = nodesExtraData[nodeType].availablePrevNodes
|
||||
const availableNextNodes = nodesExtraData[nodeType].availableNextNodes
|
||||
|
||||
const handleSelect = useCallback<OnSelectBlock>((type, toolDefaultValue) => {
|
||||
handleNodeChange(nodeId, type, sourceHandle, toolDefaultValue)
|
||||
@ -39,6 +51,7 @@ const ChangeBlock = ({
|
||||
}}
|
||||
onSelect={handleSelect}
|
||||
trigger={renderTrigger}
|
||||
availableBlocksTypes={union(availablePrevNodes, availableNextNodes)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@ -129,6 +129,7 @@ const PanelOperator = ({
|
||||
data.type !== BlockEnum.Start && (
|
||||
<ChangeBlock
|
||||
nodeId={id}
|
||||
nodeType={data.type}
|
||||
sourceHandle={edge?.sourceHandle || 'source'}
|
||||
/>
|
||||
)
|
||||
|
||||
@ -20,6 +20,7 @@ import {
|
||||
import BlockIcon from '@/app/components/workflow/block-icon'
|
||||
import {
|
||||
useNodeDataUpdate,
|
||||
useNodesExtraData,
|
||||
useNodesInteractions,
|
||||
} from '@/app/components/workflow/hooks'
|
||||
import { canRunBySingle } from '@/app/components/workflow/utils'
|
||||
@ -27,7 +28,6 @@ import { GitBranch01 } from '@/app/components/base/icons/src/vender/line/develop
|
||||
import { Play } from '@/app/components/base/icons/src/vender/line/mediaAndDevices'
|
||||
import TooltipPlus from '@/app/components/base/tooltip-plus'
|
||||
import type { Node } from '@/app/components/workflow/types'
|
||||
import { BlockEnum } from '@/app/components/workflow/types'
|
||||
|
||||
type BasePanelProps = {
|
||||
children: ReactElement
|
||||
@ -40,6 +40,9 @@ const BasePanel: FC<BasePanelProps> = ({
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const { handleNodeSelect } = useNodesInteractions()
|
||||
const nodesExtraData = useNodesExtraData()
|
||||
const availableNextNodes = nodesExtraData[data.type].availableNextNodes
|
||||
|
||||
const {
|
||||
handleNodeDataUpdate,
|
||||
handleNodeDataUpdateWithSyncDraft,
|
||||
@ -102,7 +105,7 @@ const BasePanel: FC<BasePanelProps> = ({
|
||||
{cloneElement(children, { id, data })}
|
||||
</div>
|
||||
{
|
||||
data.type !== BlockEnum.End && (
|
||||
!!availableNextNodes.length && (
|
||||
<div className='p-4 border-t-[0.5px] border-t-black/5'>
|
||||
<div className='flex items-center mb-1 text-gray-700 text-[13px] font-semibold'>
|
||||
<GitBranch01 className='mr-1 w-4 h-4' />
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import type { NodeDefault } from '../../types'
|
||||
import { BlockEnum, type NodeDefault } from '../../types'
|
||||
import { type IfElseNodeType, LogicalOperator } from './types'
|
||||
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/constants'
|
||||
|
||||
@ -23,7 +23,7 @@ const nodeDefault: NodeDefault<IfElseNodeType> = {
|
||||
},
|
||||
getAvailableNextNodes(isChatMode: boolean) {
|
||||
const nodes = isChatMode ? ALL_CHAT_AVAILABLE_BLOCKS : ALL_COMPLETION_AVAILABLE_BLOCKS
|
||||
return nodes
|
||||
return nodes.filter(type => type !== BlockEnum.VariableAssigner)
|
||||
},
|
||||
checkValid(payload: IfElseNodeType) {
|
||||
let isValid = true
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import type { NodeDefault } from '../../types'
|
||||
import { BlockEnum } from '../../types'
|
||||
import type { QuestionClassifierNodeType } from './types'
|
||||
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/constants'
|
||||
|
||||
@ -21,7 +22,7 @@ const nodeDefault: NodeDefault<QuestionClassifierNodeType> = {
|
||||
},
|
||||
getAvailableNextNodes(isChatMode: boolean) {
|
||||
const nodes = isChatMode ? ALL_CHAT_AVAILABLE_BLOCKS : ALL_COMPLETION_AVAILABLE_BLOCKS
|
||||
return nodes
|
||||
return nodes.filter(type => type !== BlockEnum.VariableAssigner)
|
||||
},
|
||||
checkValid(payload: QuestionClassifierNodeType) {
|
||||
let isValid = true
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { type NodeDefault, VarType } from '../../types'
|
||||
import { BlockEnum } from '../../types'
|
||||
import type { VariableAssignerNodeType } from './types'
|
||||
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/constants'
|
||||
|
||||
@ -9,7 +10,7 @@ const nodeDefault: NodeDefault<VariableAssignerNodeType> = {
|
||||
},
|
||||
getAvailablePrevNodes(isChatMode: boolean) {
|
||||
const nodes = isChatMode ? ALL_CHAT_AVAILABLE_BLOCKS : ALL_COMPLETION_AVAILABLE_BLOCKS
|
||||
return nodes
|
||||
return nodes.filter(type => type !== BlockEnum.IfElse && type !== BlockEnum.QuestionClassifier)
|
||||
},
|
||||
getAvailableNextNodes(isChatMode: boolean) {
|
||||
const nodes = isChatMode ? ALL_CHAT_AVAILABLE_BLOCKS : ALL_COMPLETION_AVAILABLE_BLOCKS
|
||||
|
||||
Reference in New Issue
Block a user