import { cn } from '@langgenius/dify-ui/cn' import { Popover, PopoverContent, PopoverTrigger } from '@langgenius/dify-ui/popover' import { Tooltip, TooltipContent, TooltipTrigger } from '@langgenius/dify-ui/tooltip' import { memo, useState } from 'react' import { useTranslation } from 'react-i18next' import Loading from '@/app/components/base/loading' import { useInputFieldPanel } from '@/app/components/rag-pipeline/hooks' import { useStore, useWorkflowStore } from '@/app/components/workflow/store' import { useFormatTimeFromNow } from '@/hooks/use-format-time-from-now' import { useWorkflowRunHistory } from '@/service/use-workflow' import { useIsChatMode, useNodesInteractions, useWorkflowInteractions, useWorkflowRun, } from '../hooks' import { ControlMode, WorkflowRunningStatus } from '../types' import { formatWorkflowRunIdentifier } from '../utils' export type ViewHistoryProps = { withText?: boolean onClearLogAndMessageModal?: () => void historyUrl?: string } const ViewHistory = ({ withText, onClearLogAndMessageModal, historyUrl }: ViewHistoryProps) => { const { t } = useTranslation() const isChatMode = useIsChatMode() const [open, setOpen] = useState(false) const { formatTimeFromNow } = useFormatTimeFromNow() const { handleNodesCancelSelected } = useNodesInteractions() const { handleCancelDebugAndPreviewPanel } = useWorkflowInteractions() const workflowStore = useWorkflowStore() const setControlMode = useStore((s) => s.setControlMode) const historyWorkflowData = useStore((s) => s.historyWorkflowData) const { handleBackupDraft } = useWorkflowRun() const { closeAllInputFieldPanels } = useInputFieldPanel() const shouldFetchHistory = open && !!historyUrl const { data, isLoading } = useWorkflowRunHistory(historyUrl, shouldFetchHistory) return ( {withText ? ( $['common.showRunHistory'], { ns: 'workflow' })} className={cn( 'flex h-8 items-center rounded-lg border-[0.5px] border-components-button-secondary-border bg-components-button-secondary-bg px-3 shadow-xs', 'cursor-pointer text-[13px] font-medium text-components-button-secondary-text hover:bg-components-button-secondary-bg-hover', 'data-popup-open:bg-components-button-secondary-bg-hover', )} > {t(($) => $['common.showRunHistory'], { ns: 'workflow' })} } /> ) : ( }> $['common.viewRunHistory'], { ns: 'workflow' })} className="group flex size-7 cursor-pointer items-center justify-center rounded-md hover:bg-state-accent-hover data-popup-open:bg-state-accent-hover" onClick={() => { onClearLogAndMessageModal?.() }} > } /> {t(($) => $['common.viewRunHistory'], { ns: 'workflow' })} )}
{t(($) => $['common.runHistory'], { ns: 'workflow' })}
{isLoading && (
)} {!isLoading && (
{!data?.data.length && (
{t(($) => $['common.notRunning'], { ns: 'workflow' })}
)} {data?.data.map((item) => (
{ workflowStore.setState({ historyWorkflowData: item, showInputsPanel: false, showEnvPanel: false, }) closeAllInputFieldPanels() handleBackupDraft() setOpen(false) handleNodesCancelSelected() handleCancelDebugAndPreviewPanel() setControlMode(ControlMode.Hand) }} > {!isChatMode && [WorkflowRunningStatus.Stopped, WorkflowRunningStatus.Paused].includes( item.status, ) && ( )} {!isChatMode && item.status === WorkflowRunningStatus.Failed && ( )} {!isChatMode && item.status === WorkflowRunningStatus.Succeeded && ( )}
{`Test ${isChatMode ? 'Chat' : 'Run'}${formatWorkflowRunIdentifier(item.finished_at, item.status)}`}
{item.created_by_account?.name} ยท {formatTimeFromNow((item.finished_at || item.created_at) * 1000)}
))}
)}
) } export default memo(ViewHistory)