feat(workflow): enhance listening functionality with multiple trigger node support

This commit is contained in:
zhsama 2025-10-17 19:09:55 +08:00
parent fbe3df5658
commit d0f357a690
4 changed files with 114 additions and 5 deletions

View File

@ -241,12 +241,23 @@ export const useWorkflowRun = () => {
setIsListening,
setShowVariableInspectPanel,
setListeningTriggerType,
setListeningTriggerNodeIds,
setListeningTriggerIsAll,
setListeningTriggerNodeId,
} = workflowStore.getState()
if (runMode === TriggerType.Webhook || runMode === TriggerType.Plugin || runMode === TriggerType.All) {
setIsListening(true)
setShowVariableInspectPanel(true)
setListeningTriggerIsAll(runMode === TriggerType.All)
if (runMode === TriggerType.All)
setListeningTriggerNodeIds(options?.allNodeIds ?? [])
else if (runMode === TriggerType.Webhook && options?.webhookNodeId)
setListeningTriggerNodeIds([options.webhookNodeId])
else if (runMode === TriggerType.Plugin && options?.pluginNodeId)
setListeningTriggerNodeIds([options.pluginNodeId])
else
setListeningTriggerNodeIds([])
setWorkflowRunningData({
result: {
status: WorkflowRunningStatus.Running,
@ -262,6 +273,8 @@ export const useWorkflowRun = () => {
setIsListening(false)
setListeningTriggerType(null)
setListeningTriggerNodeId(null)
setListeningTriggerNodeIds([])
setListeningTriggerIsAll(false)
setWorkflowRunningData({
result: {
status: WorkflowRunningStatus.Running,
@ -299,6 +312,8 @@ export const useWorkflowRun = () => {
state.setIsListening(false)
state.setListeningTriggerType(null)
state.setListeningTriggerNodeId(null)
state.setListeningTriggerNodeIds([])
state.setListeningTriggerIsAll(false)
}
const wrappedOnError = (params: any) => {

View File

@ -74,6 +74,8 @@ export const useWorkflowStartRun = () => {
setShowEnvPanel,
setListeningTriggerType,
setListeningTriggerNodeId,
setListeningTriggerNodeIds,
setListeningTriggerIsAll,
} = workflowStore.getState()
if (workflowRunningData?.result.status === WorkflowRunningStatus.Running)
@ -97,6 +99,8 @@ export const useWorkflowStartRun = () => {
setListeningTriggerType(BlockEnum.TriggerSchedule)
setListeningTriggerNodeId(nodeId)
setListeningTriggerNodeIds([nodeId])
setListeningTriggerIsAll(false)
await doSyncWorkflowDraft()
handleRun(
@ -123,6 +127,8 @@ export const useWorkflowStartRun = () => {
setShowEnvPanel,
setListeningTriggerType,
setListeningTriggerNodeId,
setListeningTriggerNodeIds,
setListeningTriggerIsAll,
} = workflowStore.getState()
if (workflowRunningData?.result.status === WorkflowRunningStatus.Running)
@ -145,6 +151,8 @@ export const useWorkflowStartRun = () => {
setShowInputsPanel(false)
setListeningTriggerType(BlockEnum.TriggerWebhook)
setListeningTriggerNodeId(nodeId)
setListeningTriggerNodeIds([nodeId])
setListeningTriggerIsAll(false)
await doSyncWorkflowDraft()
handleRun(
@ -168,6 +176,8 @@ export const useWorkflowStartRun = () => {
setShowEnvPanel,
setListeningTriggerType,
setListeningTriggerNodeId,
setListeningTriggerNodeIds,
setListeningTriggerIsAll,
} = workflowStore.getState()
if (workflowRunningData?.result.status === WorkflowRunningStatus.Running)
@ -190,6 +200,8 @@ export const useWorkflowStartRun = () => {
setShowInputsPanel(false)
setListeningTriggerType(BlockEnum.TriggerPlugin)
setListeningTriggerNodeId(nodeId)
setListeningTriggerNodeIds([nodeId])
setListeningTriggerIsAll(false)
await doSyncWorkflowDraft()
handleRun(
@ -211,6 +223,9 @@ export const useWorkflowStartRun = () => {
setShowDebugAndPreviewPanel,
setShowInputsPanel,
setShowEnvPanel,
setListeningTriggerIsAll,
setListeningTriggerNodeIds,
setListeningTriggerNodeId,
} = workflowStore.getState()
if (workflowRunningData?.result.status === WorkflowRunningStatus.Running)
@ -218,6 +233,9 @@ export const useWorkflowStartRun = () => {
setShowEnvPanel(false)
setShowInputsPanel(false)
setListeningTriggerIsAll(true)
setListeningTriggerNodeIds(nodeIds)
setListeningTriggerNodeId(null)
if (!showDebugAndPreviewPanel)
setShowDebugAndPreviewPanel(true)

View File

@ -20,6 +20,10 @@ export type WorkflowSliceShape = {
setListeningTriggerType: (triggerType: TriggerNodeType | null) => void
listeningTriggerNodeId: string | null
setListeningTriggerNodeId: (nodeId: string | null) => void
listeningTriggerNodeIds: string[]
setListeningTriggerNodeIds: (nodeIds: string[]) => void
listeningTriggerIsAll: boolean
setListeningTriggerIsAll: (isAll: boolean) => void
clipboardElements: Node[]
setClipboardElements: (clipboardElements: Node[]) => void
selection: null | { x1: number; y1: number; x2: number; y2: number }
@ -49,6 +53,10 @@ export const createWorkflowSlice: StateCreator<WorkflowSliceShape> = set => ({
setListeningTriggerType: triggerType => set(() => ({ listeningTriggerType: triggerType })),
listeningTriggerNodeId: null,
setListeningTriggerNodeId: nodeId => set(() => ({ listeningTriggerNodeId: nodeId })),
listeningTriggerNodeIds: [],
setListeningTriggerNodeIds: nodeIds => set(() => ({ listeningTriggerNodeIds: nodeIds })),
listeningTriggerIsAll: false,
setListeningTriggerIsAll: isAll => set(() => ({ listeningTriggerIsAll: isAll })),
clipboardElements: [],
setClipboardElements: clipboardElements => set(() => ({ clipboardElements })),
selection: null,

View File

@ -6,7 +6,7 @@ import BlockIcon from '@/app/components/workflow/block-icon'
import { BlockEnum } from '@/app/components/workflow/types'
import { StopCircle } from '@/app/components/base/icons/src/vender/line/mediaAndDevices'
import { useStore } from '../store'
import { useToolIcon } from '@/app/components/workflow/hooks/use-tool-icon'
import { useGetToolIcon } from '@/app/components/workflow/hooks/use-tool-icon'
import type { TFunction } from 'i18next'
const resolveListeningDescription = (
@ -24,6 +24,23 @@ const resolveListeningDescription = (
return t('workflow.debug.variableInspect.listening.tip')
}
const resolveMultipleListeningDescription = (
nodes: Node[],
t: TFunction,
): string => {
if (!nodes.length)
return t('workflow.debug.variableInspect.listening.tip')
const titles = nodes
.map(node => (node.data as { title?: string })?.title)
.filter((title): title is string => Boolean(title))
if (titles.length)
return titles.join(', ')
return t('workflow.debug.variableInspect.listening.tip')
}
export type ListeningProps = {
onStop: () => void
message?: string
@ -39,8 +56,12 @@ const Listening: FC<ListeningProps> = ({
// Get the current trigger type and node ID from store
const listeningTriggerType = useStore(s => s.listeningTriggerType)
const listeningTriggerNodeId = useStore(s => s.listeningTriggerNodeId)
const listeningTriggerNodeIds = useStore(s => s.listeningTriggerNodeIds)
const listeningTriggerIsAll = useStore(s => s.listeningTriggerIsAll)
const triggerType = listeningTriggerType || BlockEnum.TriggerWebhook
const getToolIcon = useGetToolIcon()
// Get the trigger node data to extract icon information
const { getNodes } = store.getState()
const nodes = getNodes()
@ -48,13 +69,60 @@ const Listening: FC<ListeningProps> = ({
? nodes.find(node => node.id === listeningTriggerNodeId)
: undefined
// Use the useToolIcon hook to get the icon for plugin/datasource triggers
const toolIcon = useToolIcon(triggerNode?.data)
const description = resolveListeningDescription(message, triggerNode, t)
let displayNodes: Node[] = []
if (listeningTriggerIsAll) {
if (listeningTriggerNodeIds.length > 0) {
displayNodes = nodes.filter(node => listeningTriggerNodeIds.includes(node.id))
}
else {
displayNodes = nodes.filter((node) => {
const nodeType = (node.data as { type?: BlockEnum })?.type
return nodeType === BlockEnum.TriggerSchedule
|| nodeType === BlockEnum.TriggerWebhook
|| nodeType === BlockEnum.TriggerPlugin
})
}
}
else if (triggerNode) {
displayNodes = [triggerNode]
}
const iconsToRender = displayNodes.map((node) => {
const blockType = (node.data as { type?: BlockEnum })?.type || BlockEnum.TriggerWebhook
const icon = getToolIcon(node.data as any)
return {
key: node.id,
type: blockType,
toolIcon: icon,
}
})
if (iconsToRender.length === 0) {
iconsToRender.push({
key: 'default',
type: listeningTriggerIsAll ? BlockEnum.TriggerWebhook : triggerType,
toolIcon: !listeningTriggerIsAll && triggerNode ? getToolIcon(triggerNode.data as any) : undefined,
})
}
const description = listeningTriggerIsAll
? resolveMultipleListeningDescription(displayNodes, t)
: resolveListeningDescription(message, triggerNode, t)
return (
<div className='flex h-full flex-col gap-4 rounded-xl bg-background-section p-8'>
<BlockIcon type={triggerType} toolIcon={toolIcon} size="md" className="!h-10 !w-10 !rounded-xl [&_svg]:!h-7 [&_svg]:!w-7" />
<div className='flex flex-row flex-wrap items-center gap-3'>
{iconsToRender.map(icon => (
<BlockIcon
key={icon.key}
type={icon.type}
toolIcon={icon.toolIcon}
size="md"
className="!h-10 !w-10 !rounded-xl [&_svg]:!h-7 [&_svg]:!w-7"
/>
))}
</div>
<div className='flex flex-col gap-1'>
<div className='system-sm-semibold text-text-secondary'>{t('workflow.debug.variableInspect.listening.title')}</div>
<div className='system-xs-regular text-text-tertiary'>{description}</div>