refactor: replace TRIGGER_NODE_TYPES with isTriggerNode utility for improved node type checks across workflow components

This commit is contained in:
zhsama
2025-11-11 16:46:13 +08:00
parent 6d3fb9b769
commit c37cce000f
6 changed files with 27 additions and 73 deletions

View File

@ -5,7 +5,6 @@ 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,
@ -14,17 +13,11 @@ 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'
import { BlockEnum, isTriggerNode } from '@/app/components/workflow/types'
const TRIGGER_NODE_TYPES: BlockEnum[] = [
BlockEnum.TriggerSchedule,
BlockEnum.TriggerWebhook,
BlockEnum.TriggerPlugin,
]
import { FlowType } from '@/types/common'
type ChangeBlockProps = {
@ -39,7 +32,6 @@ const ChangeBlock = ({
}: ChangeBlockProps) => {
const { t } = useTranslation()
const { handleNodeChange } = useNodesInteractions()
const nodes = useNodes<CommonNodeType>()
const {
availablePrevBlocks,
availableNextBlocks,
@ -47,30 +39,11 @@ 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))
if (isTriggerNode(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)
@ -106,9 +79,7 @@ const ChangeBlock = ({
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}
forceEnableStartTab={nodeData.type === BlockEnum.Start}
/>
)
}

View File

@ -16,24 +16,18 @@ import {
RiLoader2Line,
} from '@remixicon/react'
import { useTranslation } from 'react-i18next'
import type { NodeProps } from '../../types'
import type { NodeProps } from '@/app/components/workflow/types'
import {
BlockEnum,
NodeRunningStatus,
TRIGGER_NODE_TYPES,
} from '../../types'
import {
useNodesReadOnly,
useToolIcon,
} from '../../hooks'
import {
hasErrorHandleNode,
hasRetryNode,
} from '../../utils'
import { useNodeIterationInteractions } from '../iteration/use-interactions'
import { useNodeLoopInteractions } from '../loop/use-interactions'
import type { IterationNodeType } from '../iteration/types'
import CopyID from '../tool/components/copy-id'
isTriggerNode,
} from '@/app/components/workflow/types'
import { useNodesReadOnly, useToolIcon } from '@/app/components/workflow/hooks'
import { hasErrorHandleNode, hasRetryNode } from '@/app/components/workflow/utils'
import { useNodeIterationInteractions } from '@/app/components/workflow/nodes/iteration/use-interactions'
import { useNodeLoopInteractions } from '@/app/components/workflow/nodes/loop/use-interactions'
import type { IterationNodeType } from '@/app/components/workflow/nodes/iteration/types'
import CopyID from '@/app/components/workflow/nodes/tool/components/copy-id'
import {
NodeSourceHandle,
NodeTargetHandle,
@ -47,8 +41,8 @@ import EntryNodeContainer, { StartNodeTypeEnum } from './components/entry-node-c
import cn from '@/utils/classnames'
import BlockIcon from '@/app/components/workflow/block-icon'
import Tooltip from '@/app/components/base/tooltip'
import useInspectVarsCrud from '../../hooks/use-inspect-vars-crud'
import { ToolTypeEnum } from '../../block-selector/types'
import useInspectVarsCrud from '@/app/components/workflow/hooks/use-inspect-vars-crud'
import { ToolTypeEnum } from '@/app/components/workflow/block-selector/types'
type NodeChildProps = {
id: string
@ -354,7 +348,7 @@ const BaseNode: FC<BaseNodeProps> = ({
)
const isStartNode = data.type === BlockEnum.Start
const isEntryNode = TRIGGER_NODE_TYPES.includes(data.type as any) || isStartNode
const isEntryNode = isTriggerNode(data.type as any) || isStartNode
return isEntryNode ? (
<EntryNodeContainer