mirror of https://github.com/langgenius/dify.git
refactor: replace TRIGGER_NODE_TYPES with isTriggerNode utility for improved node type checks across workflow components
This commit is contained in:
parent
6d3fb9b769
commit
c37cce000f
|
|
@ -23,10 +23,12 @@ import { useFeatures } from '@/app/components/base/features/hooks'
|
|||
import type {
|
||||
CommonEdgeType,
|
||||
CommonNodeType,
|
||||
Node,
|
||||
} from '@/app/components/workflow/types'
|
||||
import {
|
||||
BlockEnum,
|
||||
InputVarType,
|
||||
isTriggerNode,
|
||||
} from '@/app/components/workflow/types'
|
||||
import { useToastContext } from '@/app/components/base/toast'
|
||||
import { useInvalidateAppWorkflow, usePublishWorkflow, useResetWorkflowVersionHistory } from '@/service/use-workflow'
|
||||
|
|
@ -36,15 +38,8 @@ import { fetchAppDetail } from '@/service/apps'
|
|||
import { useStore as useAppStore } from '@/app/components/app/store'
|
||||
import useTheme from '@/hooks/use-theme'
|
||||
import cn from '@/utils/classnames'
|
||||
import { useIsChatMode } from '../../hooks'
|
||||
import { useIsChatMode } from '@/app/components/workflow/hooks'
|
||||
import type { StartNodeType } from '@/app/components/workflow/nodes/start/types'
|
||||
import type { Node } from '@/app/components/workflow/types'
|
||||
|
||||
const TRIGGER_NODE_TYPES: BlockEnum[] = [
|
||||
BlockEnum.TriggerSchedule,
|
||||
BlockEnum.TriggerWebhook,
|
||||
BlockEnum.TriggerPlugin,
|
||||
]
|
||||
|
||||
const FeaturesTrigger = () => {
|
||||
const { t } = useTranslation()
|
||||
|
|
@ -97,7 +92,7 @@ const FeaturesTrigger = () => {
|
|||
}, [edges, startNodeIds])
|
||||
// Track trigger presence so the publisher can adjust UI (e.g. hide missing start section).
|
||||
const hasTriggerNode = useMemo(() => (
|
||||
nodes.some(node => TRIGGER_NODE_TYPES.includes(node.data.type as BlockEnum))
|
||||
nodes.some(node => isTriggerNode(node.data.type as BlockEnum))
|
||||
), [nodes])
|
||||
|
||||
const resetWorkflowVersionHistory = useResetWorkflowVersionHistory()
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import type {
|
|||
OnSelectBlock,
|
||||
ToolWithProvider,
|
||||
} from '../types'
|
||||
import { BlockEnum } from '../types'
|
||||
import { BlockEnum, isTriggerNode } from '../types'
|
||||
import Tabs from './tabs'
|
||||
import { TabsEnum } from './types'
|
||||
import { useTabs } from './hooks'
|
||||
|
|
@ -35,12 +35,6 @@ import {
|
|||
} from '@/app/components/base/icons/src/vender/line/general'
|
||||
import SearchBox from '@/app/components/plugins/marketplace/search-box'
|
||||
|
||||
const TRIGGER_NODE_TYPES: BlockEnum[] = [
|
||||
BlockEnum.TriggerSchedule,
|
||||
BlockEnum.TriggerWebhook,
|
||||
BlockEnum.TriggerPlugin,
|
||||
]
|
||||
|
||||
export type NodeSelectorProps = {
|
||||
open?: boolean
|
||||
onOpenChange?: (open: boolean) => void
|
||||
|
|
@ -115,7 +109,7 @@ const NodeSelector: FC<NodeSelectorProps> = ({
|
|||
continue
|
||||
if (nodeType === BlockEnum.Start)
|
||||
result.hasUserInputNode = true
|
||||
if (TRIGGER_NODE_TYPES.includes(nodeType))
|
||||
if (isTriggerNode(nodeType))
|
||||
result.hasTriggerNode = true
|
||||
if (result.hasTriggerNode && result.hasUserInputNode)
|
||||
break
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { useCallback } from 'react'
|
||||
import { useStoreApi } from 'reactflow'
|
||||
import type { Node } from '../types'
|
||||
import { BlockEnum, TRIGGER_NODE_TYPES } from '../types'
|
||||
import { BlockEnum, isTriggerNode } from '../types'
|
||||
import { useWorkflowStore } from '../store'
|
||||
|
||||
// Entry node (Start/Trigger) wrapper offsets
|
||||
|
|
@ -18,7 +18,7 @@ export const useHelpline = () => {
|
|||
|
||||
// Check if a node is an entry node (Start or Trigger)
|
||||
const isEntryNode = useCallback((node: Node): boolean => {
|
||||
return TRIGGER_NODE_TYPES.includes(node.data.type as any) || node.data.type === BlockEnum.Start
|
||||
return isTriggerNode(node.data.type as any) || node.data.type === BlockEnum.Start
|
||||
}, [])
|
||||
|
||||
// Get the actual alignment position of a node (accounting for wrapper offset)
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import {
|
|||
} from 'reactflow'
|
||||
import type { PluginDefaultValue } from '../block-selector/types'
|
||||
import type { Edge, Node, OnNodeAdd } from '../types'
|
||||
import { BlockEnum, TRIGGER_NODE_TYPES } from '../types'
|
||||
import { BlockEnum, isTriggerNode } from '../types'
|
||||
import { useWorkflowStore } from '../store'
|
||||
import {
|
||||
CUSTOM_EDGE,
|
||||
|
|
@ -148,12 +148,12 @@ export const useNodesInteractions = () => {
|
|||
const currentNode = draft.find(n => n.id === node.id)!
|
||||
|
||||
// Check if current dragging node is an entry node
|
||||
const isCurrentEntryNode = TRIGGER_NODE_TYPES.includes(node.data.type as any) || node.data.type === BlockEnum.Start
|
||||
const isCurrentEntryNode = isTriggerNode(node.data.type as any) || node.data.type === BlockEnum.Start
|
||||
|
||||
// X-axis alignment with offset consideration
|
||||
if (showVerticalHelpLineNodesLength > 0) {
|
||||
const targetNode = showVerticalHelpLineNodes[0]
|
||||
const isTargetEntryNode = TRIGGER_NODE_TYPES.includes(targetNode.data.type as any) || targetNode.data.type === BlockEnum.Start
|
||||
const isTargetEntryNode = isTriggerNode(targetNode.data.type as any) || targetNode.data.type === BlockEnum.Start
|
||||
|
||||
// Calculate the wrapper position needed to align the inner nodes
|
||||
// Target inner position = target.position + target.offset
|
||||
|
|
@ -177,7 +177,7 @@ export const useNodesInteractions = () => {
|
|||
// Y-axis alignment with offset consideration
|
||||
if (showHorizontalHelpLineNodesLength > 0) {
|
||||
const targetNode = showHorizontalHelpLineNodes[0]
|
||||
const isTargetEntryNode = TRIGGER_NODE_TYPES.includes(targetNode.data.type as any) || targetNode.data.type === BlockEnum.Start
|
||||
const isTargetEntryNode = isTriggerNode(targetNode.data.type as any) || targetNode.data.type === BlockEnum.Start
|
||||
|
||||
const targetOffset = isTargetEntryNode ? ENTRY_NODE_WRAPPER_OFFSET.y : 0
|
||||
const currentOffset = isCurrentEntryNode ? ENTRY_NODE_WRAPPER_OFFSET.y : 0
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue