import type { TestRunMenuRef, TriggerOption } from './test-run-menu' import type { EventEmitterValue } from '@/context/event-emitter' import { cn } from '@langgenius/dify-ui/cn' import { toast } from '@langgenius/dify-ui/toast' import { useHotkey } from '@tanstack/react-hotkeys' import * as React from 'react' import { useCallback, useRef } from 'react' import { useTranslation } from 'react-i18next' import { trackEvent } from '@/app/components/base/amplitude' import { StopCircle } from '@/app/components/base/icons/src/vender/line/mediaAndDevices' import { useWorkflowRun, useWorkflowRunValidation, useWorkflowStartRun } from '@/app/components/workflow/hooks' import { ShortcutKbd } from '@/app/components/workflow/shortcuts/shortcut-kbd' import { useStore } from '@/app/components/workflow/store/workflow' import { WorkflowRunningStatus } from '@/app/components/workflow/types' import { EVENT_WORKFLOW_STOP } from '@/app/components/workflow/variable-inspect/types' import { useEventEmitterContextContext } from '@/context/event-emitter' import { useDynamicTestRunOptions } from '../hooks/use-dynamic-test-run-options' import { TEST_RUN_MENU_HOTKEY } from './shortcuts' import TestRunMenu, { TriggerType } from './test-run-menu' type RunModeProps = { text?: string } const isWorkflowStopEvent = (value: EventEmitterValue) => typeof value !== 'string' && value.type === EVENT_WORKFLOW_STOP const RunMode = ({ text, }: RunModeProps) => { const { t } = useTranslation() const { handleWorkflowStartRunInWorkflow, handleWorkflowTriggerScheduleRunInWorkflow, handleWorkflowTriggerWebhookRunInWorkflow, handleWorkflowTriggerPluginRunInWorkflow, handleWorkflowRunAllTriggersInWorkflow, } = useWorkflowStartRun() const { handleStopRun } = useWorkflowRun() const { warningNodes } = useWorkflowRunValidation() const workflowRunningData = useStore(s => s.workflowRunningData) const isListening = useStore(s => s.isListening) const status = workflowRunningData?.result.status const isRunning = status === WorkflowRunningStatus.Running || isListening const dynamicOptions = useDynamicTestRunOptions() const testRunMenuRef = useRef(null) const handleToggleTestRunMenu = useCallback(() => { testRunMenuRef.current?.toggle() }, []) useHotkey(TEST_RUN_MENU_HOTKEY, handleToggleTestRunMenu, { ignoreInputs: true, }) const handleStop = useCallback(() => { handleStopRun(workflowRunningData?.task_id || '') }, [handleStopRun, workflowRunningData?.task_id]) const handleTriggerSelect = useCallback((option: TriggerOption) => { // Validate checklist before running any workflow let isValid: boolean = true warningNodes.forEach((node) => { if (node.id === option.nodeId) isValid = false }) if (!isValid) { toast.error(t('panel.checklistTip', { ns: 'workflow' })) return } if (option.type === TriggerType.UserInput) { handleWorkflowStartRunInWorkflow() trackEvent('app_start_action_time', { action_type: 'user_input' }) } else if (option.type === TriggerType.Schedule) { handleWorkflowTriggerScheduleRunInWorkflow(option.nodeId) trackEvent('app_start_action_time', { action_type: 'schedule' }) } else if (option.type === TriggerType.Webhook) { if (option.nodeId) handleWorkflowTriggerWebhookRunInWorkflow({ nodeId: option.nodeId }) trackEvent('app_start_action_time', { action_type: 'webhook' }) } else if (option.type === TriggerType.Plugin) { if (option.nodeId) handleWorkflowTriggerPluginRunInWorkflow(option.nodeId) trackEvent('app_start_action_time', { action_type: 'plugin' }) } else if (option.type === TriggerType.All) { const targetNodeIds = option.relatedNodeIds?.filter(Boolean) if (targetNodeIds && targetNodeIds.length > 0) handleWorkflowRunAllTriggersInWorkflow(targetNodeIds) trackEvent('app_start_action_time', { action_type: 'all' }) } }, [warningNodes, t, handleWorkflowStartRunInWorkflow, handleWorkflowTriggerScheduleRunInWorkflow, handleWorkflowTriggerWebhookRunInWorkflow, handleWorkflowTriggerPluginRunInWorkflow, handleWorkflowRunAllTriggersInWorkflow]) const { eventEmitter } = useEventEmitterContextContext() eventEmitter?.useSubscription((v: EventEmitterValue) => { if (isWorkflowStopEvent(v)) handleStop() }) return (
{ isRunning ? ( ) : ( ) } { isRunning && ( ) }
) } export default React.memo(RunMode)