mirror of
https://github.com/langgenius/dify.git
synced 2026-05-05 09:58:04 +08:00
feat(trigger): add support for trigger nodes and user input node management in workflow components
This commit is contained in:
@ -5,6 +5,7 @@ import {
|
||||
} from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { intersection } from 'lodash-es'
|
||||
import { useNodes } from 'reactflow'
|
||||
import BlockSelector from '@/app/components/workflow/block-selector'
|
||||
import {
|
||||
useAvailableBlocks,
|
||||
@ -13,9 +14,17 @@ import {
|
||||
} from '@/app/components/workflow/hooks'
|
||||
import { useHooksStore } from '@/app/components/workflow/hooks-store'
|
||||
import type {
|
||||
CommonNodeType,
|
||||
Node,
|
||||
OnSelectBlock,
|
||||
} from '@/app/components/workflow/types'
|
||||
import { BlockEnum } from '@/app/components/workflow/types'
|
||||
|
||||
const TRIGGER_NODE_TYPES: BlockEnum[] = [
|
||||
BlockEnum.TriggerSchedule,
|
||||
BlockEnum.TriggerWebhook,
|
||||
BlockEnum.TriggerPlugin,
|
||||
]
|
||||
import { FlowType } from '@/types/common'
|
||||
|
||||
type ChangeBlockProps = {
|
||||
@ -30,6 +39,7 @@ const ChangeBlock = ({
|
||||
}: ChangeBlockProps) => {
|
||||
const { t } = useTranslation()
|
||||
const { handleNodeChange } = useNodesInteractions()
|
||||
const nodes = useNodes<CommonNodeType>()
|
||||
const {
|
||||
availablePrevBlocks,
|
||||
availableNextBlocks,
|
||||
@ -37,6 +47,30 @@ const ChangeBlock = ({
|
||||
const isChatMode = useIsChatMode()
|
||||
const flowType = useHooksStore(s => s.configsMap?.flowType)
|
||||
const showStartTab = flowType !== FlowType.ragPipeline && !isChatMode
|
||||
// Count total trigger nodes
|
||||
const totalTriggerNodes = useMemo(() => (
|
||||
nodes.filter(node => TRIGGER_NODE_TYPES.includes(node.data.type as BlockEnum)).length
|
||||
), [nodes])
|
||||
// Check if there is a User Input node
|
||||
const hasUserInputNode = useMemo(() => (
|
||||
nodes.some(node => node.data.type === BlockEnum.Start)
|
||||
), [nodes])
|
||||
// Check if the current node is a trigger node
|
||||
const isTriggerNode = TRIGGER_NODE_TYPES.includes(nodeData.type as BlockEnum)
|
||||
// Force enabling Start tab regardless of existing trigger/user input nodes (e.g., when changing Start node type).
|
||||
const forceEnableStartTab = isTriggerNode || nodeData.type === BlockEnum.Start
|
||||
// Only allow converting a trigger into User Input when it's the sole trigger and no User Input exists yet.
|
||||
const canChangeTriggerToUserInput = isTriggerNode && !hasUserInputNode && totalTriggerNodes === 1
|
||||
// Ignore current node when it's a trigger so the Start tab logic doesn't treat it as existing trigger.
|
||||
const ignoreNodeIds = useMemo(() => {
|
||||
if (TRIGGER_NODE_TYPES.includes(nodeData.type as BlockEnum))
|
||||
return [nodeId]
|
||||
return undefined
|
||||
}, [nodeData.type, nodeId])
|
||||
// Determine user input selection based on node type and trigger/user input node presence.
|
||||
const allowUserInputSelection = forceEnableStartTab
|
||||
? (nodeData.type === BlockEnum.Start ? false : canChangeTriggerToUserInput)
|
||||
: undefined
|
||||
|
||||
const availableNodes = useMemo(() => {
|
||||
if (availablePrevBlocks.length && availableNextBlocks.length)
|
||||
@ -71,6 +105,10 @@ const ChangeBlock = ({
|
||||
popupClassName='min-w-[240px]'
|
||||
availableBlocksTypes={availableNodes}
|
||||
showStartTab={showStartTab}
|
||||
ignoreNodeIds={ignoreNodeIds}
|
||||
// When changing Start/Trigger nodes, force-enable Start tab to allow switching among entry nodes.
|
||||
forceEnableStartTab={forceEnableStartTab}
|
||||
allowUserInputSelection={allowUserInputSelection}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user