mirror of https://github.com/langgenius/dify.git
feat(trigger): add run all triggers test-run and implement TriggerType enum
This commit is contained in:
parent
bc0d5f4e41
commit
5b884d750f
|
|
@ -69,6 +69,7 @@ const WorkflowMain = ({
|
|||
handleWorkflowTriggerScheduleRunInWorkflow,
|
||||
handleWorkflowTriggerWebhookRunInWorkflow,
|
||||
handleWorkflowTriggerPluginRunInWorkflow,
|
||||
handleWorkflowRunAllTriggersInWorkflow,
|
||||
} = useWorkflowStartRun()
|
||||
const availableNodesMetaData = useAvailableNodesMetaData()
|
||||
const { getWorkflowRunAndTraceUrl } = useGetRunAndTraceUrl()
|
||||
|
|
@ -114,6 +115,7 @@ const WorkflowMain = ({
|
|||
handleWorkflowTriggerScheduleRunInWorkflow,
|
||||
handleWorkflowTriggerWebhookRunInWorkflow,
|
||||
handleWorkflowTriggerPluginRunInWorkflow,
|
||||
handleWorkflowRunAllTriggersInWorkflow,
|
||||
availableNodesMetaData,
|
||||
getWorkflowRunAndTraceUrl,
|
||||
exportCheck,
|
||||
|
|
@ -150,6 +152,7 @@ const WorkflowMain = ({
|
|||
handleWorkflowTriggerScheduleRunInWorkflow,
|
||||
handleWorkflowTriggerWebhookRunInWorkflow,
|
||||
handleWorkflowTriggerPluginRunInWorkflow,
|
||||
handleWorkflowRunAllTriggersInWorkflow,
|
||||
availableNodesMetaData,
|
||||
getWorkflowRunAndTraceUrl,
|
||||
exportCheck,
|
||||
|
|
|
|||
|
|
@ -25,13 +25,15 @@ import { useSetWorkflowVarsWithValue } from '../../workflow/hooks/use-fetch-work
|
|||
import { useConfigsMap } from './use-configs-map'
|
||||
import { API_PREFIX } from '@/config'
|
||||
import { ContentType, getAccessToken, getBaseOptions } from '@/service/fetch'
|
||||
import { TriggerType } from '@/app/components/workflow/header/test-run-menu'
|
||||
|
||||
type HandleRunMode = 'default' | 'schedule' | 'webhook' | 'plugin'
|
||||
type HandleRunMode = TriggerType
|
||||
type HandleRunOptions = {
|
||||
mode?: HandleRunMode
|
||||
scheduleNodeId?: string
|
||||
webhookNodeId?: string
|
||||
pluginNodeId?: string
|
||||
allNodeIds?: string[]
|
||||
}
|
||||
|
||||
export const useWorkflowRun = () => {
|
||||
|
|
@ -126,7 +128,7 @@ export const useWorkflowRun = () => {
|
|||
callback?: IOtherOptions,
|
||||
options?: HandleRunOptions,
|
||||
) => {
|
||||
const runMode: HandleRunMode = options?.mode ?? 'default'
|
||||
const runMode: HandleRunMode = options?.mode ?? TriggerType.UserInput
|
||||
const resolvedParams = params ?? {}
|
||||
const {
|
||||
getNodes,
|
||||
|
|
@ -170,13 +172,20 @@ export const useWorkflowRun = () => {
|
|||
const isInWorkflowDebug = appDetail?.mode === 'workflow'
|
||||
|
||||
let url = ''
|
||||
if (runMode === 'plugin' || runMode === 'webhook' || runMode === 'schedule') {
|
||||
if (runMode === TriggerType.Plugin || runMode === TriggerType.Webhook || runMode === TriggerType.Schedule) {
|
||||
if (!appDetail?.id) {
|
||||
console.error('handleRun: missing app id for trigger plugin run')
|
||||
return
|
||||
}
|
||||
url = `/apps/${appDetail.id}/workflows/draft/trigger/run`
|
||||
}
|
||||
else if (runMode === TriggerType.All) {
|
||||
if (!appDetail?.id) {
|
||||
console.error('handleRun: missing app id for trigger run all')
|
||||
return
|
||||
}
|
||||
url = `/apps/${appDetail.id}/workflows/draft/trigger/run-all`
|
||||
}
|
||||
else if (appDetail?.mode === 'advanced-chat') {
|
||||
url = `/apps/${appDetail.id}/advanced-chat/workflows/draft/run`
|
||||
}
|
||||
|
|
@ -186,36 +195,44 @@ export const useWorkflowRun = () => {
|
|||
|
||||
let requestBody = {}
|
||||
|
||||
if (runMode === 'schedule')
|
||||
if (runMode === TriggerType.Schedule)
|
||||
requestBody = { node_id: options?.scheduleNodeId }
|
||||
|
||||
else if (runMode === 'webhook')
|
||||
else if (runMode === TriggerType.Webhook)
|
||||
requestBody = { node_id: options?.webhookNodeId }
|
||||
|
||||
else if (runMode === 'plugin')
|
||||
else if (runMode === TriggerType.Plugin)
|
||||
requestBody = { node_id: options?.pluginNodeId }
|
||||
|
||||
else if (runMode === TriggerType.All)
|
||||
requestBody = { node_ids: options?.allNodeIds }
|
||||
|
||||
else
|
||||
requestBody = resolvedParams
|
||||
|
||||
if (!url)
|
||||
return
|
||||
|
||||
if (runMode === 'schedule' && !options?.scheduleNodeId) {
|
||||
if (runMode === TriggerType.Schedule && !options?.scheduleNodeId) {
|
||||
console.error('handleRun: schedule trigger run requires node id')
|
||||
return
|
||||
}
|
||||
|
||||
if (runMode === 'webhook' && !options?.webhookNodeId) {
|
||||
if (runMode === TriggerType.Webhook && !options?.webhookNodeId) {
|
||||
console.error('handleRun: webhook trigger run requires node id')
|
||||
return
|
||||
}
|
||||
|
||||
if (runMode === 'plugin' && !options?.pluginNodeId) {
|
||||
if (runMode === TriggerType.Plugin && !options?.pluginNodeId) {
|
||||
console.error('handleRun: plugin trigger run requires node id')
|
||||
return
|
||||
}
|
||||
|
||||
if (runMode === TriggerType.All && !options?.allNodeIds && options?.allNodeIds?.length === 0) {
|
||||
console.error('handleRun: all trigger run requires node ids')
|
||||
return
|
||||
}
|
||||
|
||||
abortControllerRef.current?.abort()
|
||||
abortControllerRef.current = null
|
||||
|
||||
|
|
@ -227,7 +244,7 @@ export const useWorkflowRun = () => {
|
|||
setListeningTriggerNodeId,
|
||||
} = workflowStore.getState()
|
||||
|
||||
if (runMode === 'webhook' || runMode === 'plugin') {
|
||||
if (runMode === TriggerType.Webhook || runMode === TriggerType.Plugin || runMode === TriggerType.All) {
|
||||
setIsListening(true)
|
||||
setShowVariableInspectPanel(true)
|
||||
setWorkflowRunningData({
|
||||
|
|
@ -430,7 +447,7 @@ export const useWorkflowRun = () => {
|
|||
}, { once: true })
|
||||
})
|
||||
|
||||
const runTriggerDebug = async (debugType: 'webhook' | 'plugin') => {
|
||||
const runTriggerDebug = async (debugType: TriggerType.Webhook | TriggerType.Plugin | TriggerType.All) => {
|
||||
const urlWithPrefix = (url.startsWith('http://') || url.startsWith('https://'))
|
||||
? url
|
||||
: `${API_PREFIX}${url.startsWith('/') ? url : `/${url}`}`
|
||||
|
|
@ -438,13 +455,13 @@ export const useWorkflowRun = () => {
|
|||
const controller = new AbortController()
|
||||
abortControllerRef.current = controller
|
||||
|
||||
const controllerKey = debugType === 'webhook'
|
||||
const controllerKey = debugType === TriggerType.Webhook
|
||||
? '__webhookDebugAbortController'
|
||||
: '__pluginDebugAbortController'
|
||||
|
||||
;(window as any)[controllerKey] = controller
|
||||
|
||||
const debugLabel = debugType === 'webhook' ? 'Webhook' : 'Plugin'
|
||||
const debugLabel = debugType === TriggerType.Webhook ? 'Webhook' : debugType === TriggerType.Plugin ? 'Plugin' : 'All'
|
||||
|
||||
const poll = async (): Promise<void> => {
|
||||
try {
|
||||
|
|
@ -559,13 +576,18 @@ export const useWorkflowRun = () => {
|
|||
await poll()
|
||||
}
|
||||
|
||||
if (runMode === 'webhook') {
|
||||
await runTriggerDebug('webhook')
|
||||
if (runMode === TriggerType.Webhook) {
|
||||
await runTriggerDebug(TriggerType.Webhook)
|
||||
return
|
||||
}
|
||||
|
||||
if (runMode === 'plugin') {
|
||||
await runTriggerDebug('plugin')
|
||||
if (runMode === TriggerType.Plugin) {
|
||||
await runTriggerDebug(TriggerType.Plugin)
|
||||
return
|
||||
}
|
||||
|
||||
if (runMode === TriggerType.All) {
|
||||
await runTriggerDebug(TriggerType.All)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import {
|
|||
useNodesSyncDraft,
|
||||
useWorkflowRun,
|
||||
} from '.'
|
||||
import { TriggerType } from '@/app/components/workflow/header/test-run-menu'
|
||||
|
||||
export const useWorkflowStartRun = () => {
|
||||
const store = useStoreApi()
|
||||
|
|
@ -102,7 +103,7 @@ export const useWorkflowStartRun = () => {
|
|||
{},
|
||||
undefined,
|
||||
{
|
||||
mode: 'schedule',
|
||||
mode: TriggerType.Schedule,
|
||||
scheduleNodeId: nodeId,
|
||||
},
|
||||
)
|
||||
|
|
@ -150,7 +151,7 @@ export const useWorkflowStartRun = () => {
|
|||
{ node_id: nodeId },
|
||||
undefined,
|
||||
{
|
||||
mode: 'webhook',
|
||||
mode: TriggerType.Webhook,
|
||||
webhookNodeId: nodeId,
|
||||
},
|
||||
)
|
||||
|
|
@ -195,12 +196,43 @@ export const useWorkflowStartRun = () => {
|
|||
{ node_id: nodeId },
|
||||
undefined,
|
||||
{
|
||||
mode: 'plugin',
|
||||
mode: TriggerType.Plugin,
|
||||
pluginNodeId: nodeId,
|
||||
},
|
||||
)
|
||||
}, [store, workflowStore, handleRun, doSyncWorkflowDraft])
|
||||
|
||||
const handleWorkflowRunAllTriggersInWorkflow = useCallback(async (nodeIds: string[]) => {
|
||||
if (!nodeIds.length)
|
||||
return
|
||||
const {
|
||||
workflowRunningData,
|
||||
showDebugAndPreviewPanel,
|
||||
setShowDebugAndPreviewPanel,
|
||||
setShowInputsPanel,
|
||||
setShowEnvPanel,
|
||||
} = workflowStore.getState()
|
||||
|
||||
if (workflowRunningData?.result.status === WorkflowRunningStatus.Running)
|
||||
return
|
||||
|
||||
setShowEnvPanel(false)
|
||||
setShowInputsPanel(false)
|
||||
|
||||
if (!showDebugAndPreviewPanel)
|
||||
setShowDebugAndPreviewPanel(true)
|
||||
|
||||
await doSyncWorkflowDraft()
|
||||
handleRun(
|
||||
{ node_ids: nodeIds },
|
||||
undefined,
|
||||
{
|
||||
mode: TriggerType.All,
|
||||
allNodeIds: nodeIds,
|
||||
},
|
||||
)
|
||||
}, [store, workflowStore, handleRun, doSyncWorkflowDraft])
|
||||
|
||||
const handleWorkflowStartRunInChatflow = useCallback(async () => {
|
||||
const {
|
||||
showDebugAndPreviewPanel,
|
||||
|
|
@ -235,5 +267,6 @@ export const useWorkflowStartRun = () => {
|
|||
handleWorkflowTriggerScheduleRunInWorkflow,
|
||||
handleWorkflowTriggerWebhookRunInWorkflow,
|
||||
handleWorkflowTriggerPluginRunInWorkflow,
|
||||
handleWorkflowRunAllTriggersInWorkflow,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import cn from '@/utils/classnames'
|
|||
import { RiLoader2Line, RiPlayLargeLine } from '@remixicon/react'
|
||||
import { StopCircle } from '@/app/components/base/icons/src/vender/line/mediaAndDevices'
|
||||
import { useDynamicTestRunOptions } from '../hooks/use-dynamic-test-run-options'
|
||||
import TestRunMenu, { type TestRunMenuRef, type TriggerOption } from './test-run-menu'
|
||||
import TestRunMenu, { type TestRunMenuRef, type TriggerOption, TriggerType } from './test-run-menu'
|
||||
|
||||
type RunModeProps = {
|
||||
text?: string
|
||||
|
|
@ -25,6 +25,7 @@ const RunMode = ({
|
|||
handleWorkflowTriggerScheduleRunInWorkflow,
|
||||
handleWorkflowTriggerWebhookRunInWorkflow,
|
||||
handleWorkflowTriggerPluginRunInWorkflow,
|
||||
handleWorkflowRunAllTriggersInWorkflow,
|
||||
} = useWorkflowStartRun()
|
||||
const { handleStopRun } = useWorkflowRun()
|
||||
const { validateBeforeRun } = useWorkflowRunValidation()
|
||||
|
|
@ -57,20 +58,25 @@ const RunMode = ({
|
|||
if (!validateBeforeRun())
|
||||
return
|
||||
|
||||
if (option.type === 'user_input') {
|
||||
if (option.type === TriggerType.UserInput) {
|
||||
handleWorkflowStartRunInWorkflow()
|
||||
}
|
||||
else if (option.type === 'schedule') {
|
||||
else if (option.type === TriggerType.Schedule) {
|
||||
handleWorkflowTriggerScheduleRunInWorkflow(option.nodeId)
|
||||
}
|
||||
else if (option.type === 'webhook') {
|
||||
else if (option.type === TriggerType.Webhook) {
|
||||
if (option.nodeId)
|
||||
handleWorkflowTriggerWebhookRunInWorkflow({ nodeId: option.nodeId })
|
||||
}
|
||||
else if (option.type === 'plugin') {
|
||||
else if (option.type === TriggerType.Plugin) {
|
||||
if (option.nodeId)
|
||||
handleWorkflowTriggerPluginRunInWorkflow(option.nodeId)
|
||||
}
|
||||
else if (option.type === TriggerType.All) {
|
||||
const targetNodeIds = option.relatedNodeIds?.filter(Boolean)
|
||||
if (targetNodeIds && targetNodeIds.length > 0)
|
||||
handleWorkflowRunAllTriggersInWorkflow(targetNodeIds)
|
||||
}
|
||||
else {
|
||||
// Placeholder for trigger-specific execution logic for schedule, webhook, plugin types
|
||||
console.log('TODO: Handle trigger execution for type:', option.type, 'nodeId:', option.nodeId)
|
||||
|
|
@ -80,6 +86,8 @@ const RunMode = ({
|
|||
handleWorkflowStartRunInWorkflow,
|
||||
handleWorkflowTriggerScheduleRunInWorkflow,
|
||||
handleWorkflowTriggerWebhookRunInWorkflow,
|
||||
handleWorkflowTriggerPluginRunInWorkflow,
|
||||
handleWorkflowRunAllTriggersInWorkflow,
|
||||
])
|
||||
|
||||
const { eventEmitter } = useEventEmitterContextContext()
|
||||
|
|
|
|||
|
|
@ -19,12 +19,21 @@ import {
|
|||
} from '@/app/components/base/portal-to-follow-elem'
|
||||
import ShortcutsName from '../shortcuts-name'
|
||||
|
||||
export enum TriggerType {
|
||||
UserInput = 'user_input',
|
||||
Schedule = 'schedule',
|
||||
Webhook = 'webhook',
|
||||
Plugin = 'plugin',
|
||||
All = 'all',
|
||||
}
|
||||
|
||||
export type TriggerOption = {
|
||||
id: string
|
||||
type: 'user_input' | 'schedule' | 'webhook' | 'plugin' | 'all'
|
||||
type: TriggerType
|
||||
name: string
|
||||
icon: React.ReactNode
|
||||
nodeId?: string
|
||||
relatedNodeIds?: string[]
|
||||
enabled: boolean
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ export type CommonHooksFnMap = {
|
|||
handleWorkflowTriggerScheduleRunInWorkflow: (nodeId?: string) => void
|
||||
handleWorkflowTriggerWebhookRunInWorkflow: (params: { nodeId: string }) => void
|
||||
handleWorkflowTriggerPluginRunInWorkflow: (nodeId?: string) => void
|
||||
handleWorkflowRunAllTriggersInWorkflow: (nodeIds: string[]) => void
|
||||
availableNodesMetaData?: AvailableNodesMetaData
|
||||
getWorkflowRunAndTraceUrl: (runId?: string) => { runUrl: string; traceUrl: string }
|
||||
exportCheck?: () => Promise<void>
|
||||
|
|
@ -93,6 +94,7 @@ export const createHooksStore = ({
|
|||
handleWorkflowTriggerScheduleRunInWorkflow = noop,
|
||||
handleWorkflowTriggerWebhookRunInWorkflow = noop,
|
||||
handleWorkflowTriggerPluginRunInWorkflow = noop,
|
||||
handleWorkflowRunAllTriggersInWorkflow = noop,
|
||||
availableNodesMetaData = {
|
||||
nodes: [],
|
||||
},
|
||||
|
|
@ -134,6 +136,7 @@ export const createHooksStore = ({
|
|||
handleWorkflowTriggerScheduleRunInWorkflow,
|
||||
handleWorkflowTriggerWebhookRunInWorkflow,
|
||||
handleWorkflowTriggerPluginRunInWorkflow,
|
||||
handleWorkflowRunAllTriggersInWorkflow,
|
||||
availableNodesMetaData,
|
||||
getWorkflowRunAndTraceUrl,
|
||||
exportCheck,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { useNodes } from 'reactflow'
|
|||
import { useTranslation } from 'react-i18next'
|
||||
import { BlockEnum, type CommonNodeType } from '../types'
|
||||
import { getWorkflowEntryNode } from '../utils/workflow-entry'
|
||||
import type { TestRunOptions, TriggerOption } from '../header/test-run-menu'
|
||||
import { type TestRunOptions, type TriggerOption, TriggerType } from '../header/test-run-menu'
|
||||
import { TriggerAll } from '@/app/components/base/icons/src/vender/workflow'
|
||||
import BlockIcon from '../block-icon'
|
||||
import { useStore } from '../store'
|
||||
|
|
@ -30,7 +30,7 @@ export const useDynamicTestRunOptions = (): TestRunOptions => {
|
|||
if (nodeData.type === BlockEnum.Start) {
|
||||
userInput = {
|
||||
id: node.id,
|
||||
type: 'user_input',
|
||||
type: TriggerType.UserInput,
|
||||
name: nodeData.title || t('workflow.blocks.start'),
|
||||
icon: (
|
||||
<BlockIcon
|
||||
|
|
@ -45,7 +45,7 @@ export const useDynamicTestRunOptions = (): TestRunOptions => {
|
|||
else if (nodeData.type === BlockEnum.TriggerSchedule) {
|
||||
allTriggers.push({
|
||||
id: node.id,
|
||||
type: 'schedule',
|
||||
type: TriggerType.Schedule,
|
||||
name: nodeData.title || t('workflow.blocks.trigger-schedule'),
|
||||
icon: (
|
||||
<BlockIcon
|
||||
|
|
@ -60,7 +60,7 @@ export const useDynamicTestRunOptions = (): TestRunOptions => {
|
|||
else if (nodeData.type === BlockEnum.TriggerWebhook) {
|
||||
allTriggers.push({
|
||||
id: node.id,
|
||||
type: 'webhook',
|
||||
type: TriggerType.Webhook,
|
||||
name: nodeData.title || t('workflow.blocks.trigger-webhook'),
|
||||
icon: (
|
||||
<BlockIcon
|
||||
|
|
@ -90,7 +90,7 @@ export const useDynamicTestRunOptions = (): TestRunOptions => {
|
|||
|
||||
allTriggers.push({
|
||||
id: node.id,
|
||||
type: 'plugin',
|
||||
type: TriggerType.Plugin,
|
||||
name: nodeData.title || (nodeData as any).plugin_name || t('workflow.blocks.trigger-plugin'),
|
||||
icon,
|
||||
nodeId: node.id,
|
||||
|
|
@ -104,7 +104,7 @@ export const useDynamicTestRunOptions = (): TestRunOptions => {
|
|||
if (startNode && startNode.data?.type === BlockEnum.Start) {
|
||||
userInput = {
|
||||
id: startNode.id,
|
||||
type: 'user_input',
|
||||
type: TriggerType.UserInput,
|
||||
name: (startNode.data as CommonNodeType)?.title || t('workflow.blocks.start'),
|
||||
icon: (
|
||||
<BlockIcon
|
||||
|
|
@ -118,15 +118,20 @@ export const useDynamicTestRunOptions = (): TestRunOptions => {
|
|||
}
|
||||
}
|
||||
|
||||
const runAll: TriggerOption | undefined = allTriggers.length > 1 ? {
|
||||
const triggerNodeIds = allTriggers
|
||||
.map(trigger => trigger.nodeId)
|
||||
.filter((nodeId): nodeId is string => Boolean(nodeId))
|
||||
|
||||
const runAll: TriggerOption | undefined = triggerNodeIds.length > 1 ? {
|
||||
id: 'run-all',
|
||||
type: 'all',
|
||||
type: TriggerType.All,
|
||||
name: t('workflow.common.runAllTriggers'),
|
||||
icon: (
|
||||
<div className="flex h-6 w-6 items-center justify-center rounded-lg border-[0.5px] border-white/2 bg-util-colors-purple-purple-500 text-white shadow-md">
|
||||
<TriggerAll className="h-4.5 w-4.5" />
|
||||
</div>
|
||||
),
|
||||
relatedNodeIds: triggerNodeIds,
|
||||
enabled: true,
|
||||
} : undefined
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ export const useWorkflowStartRun = () => {
|
|||
const handleWorkflowTriggerScheduleRunInWorkflow = useHooksStore(s => s.handleWorkflowTriggerScheduleRunInWorkflow)
|
||||
const handleWorkflowTriggerWebhookRunInWorkflow = useHooksStore(s => s.handleWorkflowTriggerWebhookRunInWorkflow)
|
||||
const handleWorkflowTriggerPluginRunInWorkflow = useHooksStore(s => s.handleWorkflowTriggerPluginRunInWorkflow)
|
||||
|
||||
const handleWorkflowRunAllTriggersInWorkflow = useHooksStore(s => s.handleWorkflowRunAllTriggersInWorkflow)
|
||||
return {
|
||||
handleStartWorkflowRun,
|
||||
handleWorkflowStartRunInWorkflow,
|
||||
|
|
@ -15,5 +15,6 @@ export const useWorkflowStartRun = () => {
|
|||
handleWorkflowTriggerScheduleRunInWorkflow,
|
||||
handleWorkflowTriggerWebhookRunInWorkflow,
|
||||
handleWorkflowTriggerPluginRunInWorkflow,
|
||||
handleWorkflowRunAllTriggersInWorkflow,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue