'use client' import type { FC } from 'react' import { useMemo } from 'react' import { useTranslation } from 'react-i18next' import Indicator from '@/app/components/header/indicator' import StatusContainer from '@/app/components/workflow/run/status-container' import { useDocLink } from '@/context/i18n' import { useWorkflowPausedDetails } from '@/service/use-log' import { cn } from '@/utils/classnames' type ResultProps = { status: string time?: number tokens?: number error?: string exceptionCounts?: number isListening?: boolean workflowRunId?: string } const StatusPanel: FC = ({ status, time, tokens, error, exceptionCounts, isListening = false, workflowRunId, }) => { const { t } = useTranslation() const docLink = useDocLink() const { data: pausedDetails } = useWorkflowPausedDetails({ workflowRunId: workflowRunId || '', enabled: status === 'paused', }) const pausedReasons = useMemo(() => { const reasons: string[] = [] if (!pausedDetails) return reasons const hasHumanInputNode = pausedDetails.paused_nodes.some( node => node.pause_type.type === 'human_input', ) if (hasHumanInputNode) { reasons.push(t('nodes.humanInput.log.reasonContent', { ns: 'workflow' })) } return reasons }, [pausedDetails, t]) const pausedInputURLs = useMemo(() => { const inputURLs: string[] = [] if (!pausedDetails) return inputURLs const { paused_nodes } = pausedDetails const hasHumanInputNode = paused_nodes.some( node => node.pause_type.type === 'human_input', ) if (hasHumanInputNode) { paused_nodes.forEach((node) => { if (node.pause_type.type === 'human_input') { inputURLs.push(node.pause_type.backstage_input_url) } }) } return inputURLs }, [pausedDetails]) return (
{t('resultPanel.status', { ns: 'runLog' })}
{status === 'running' && ( <> {isListening ? 'Listening' : 'Running'} )} {status === 'succeeded' && ( <> SUCCESS )} {status === 'partial-succeeded' && ( <> PARTIAL SUCCESS )} {status === 'exception' && ( <> EXCEPTION )} {status === 'failed' && ( <> FAIL )} {status === 'stopped' && ( <> STOP )} {status === 'paused' && ( <> PENDING )}
{t('resultPanel.time', { ns: 'runLog' })}
{(status === 'running' || status === 'paused') && (
)} {status !== 'running' && status !== 'paused' && ( {time ? `${time?.toFixed(3)}s` : '-'} )}
{t('resultPanel.tokens', { ns: 'runLog' })}
{(status === 'running' || status === 'paused') && (
)} {status !== 'running' && status !== 'paused' && ( {`${tokens || 0} Tokens`} )}
{status === 'failed' && error && ( <>
{error}
{ !!exceptionCounts && ( <>
{t('nodes.common.errorHandle.partialSucceeded.tip', { ns: 'workflow', num: exceptionCounts })}
) } )} { status === 'partial-succeeded' && !!exceptionCounts && ( <>
{t('nodes.common.errorHandle.partialSucceeded.tip', { ns: 'workflow', num: exceptionCounts })}
) } { status === 'exception' && ( <>
) } {status === 'paused' && ( <>
{t('nodes.humanInput.log.reason', { ns: 'workflow' })}
{ pausedReasons.length > 0 ? pausedReasons.map(reason => (
{reason}
)) : (
) }
{pausedInputURLs.length > 0 && (
{t('nodes.humanInput.log.backstageInputURL', { ns: 'workflow' })}
{pausedInputURLs.map(url => ( {url} ))}
)}
)} ) } export default StatusPanel