import { useState, useEffect, useRef } from 'react' import { useTranslation } from 'react-i18next' import { toast } from 'sonner' import { AlignLeft, AlignCenter, AlignRight } from 'lucide-react' import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from '@/components/ui/Dialog' import Button from '@/components/ui/Button' import { getPipelineStatus, PipelineStatusResponse } from '@/api/lightrag' import { errorMessage } from '@/lib/utils' import { cn } from '@/lib/utils' type DialogPosition = 'left' | 'center' | 'right' interface PipelineStatusDialogProps { open: boolean onOpenChange: (open: boolean) => void } export default function PipelineStatusDialog({ open, onOpenChange }: PipelineStatusDialogProps) { const { t } = useTranslation() const [status, setStatus] = useState(null) const [position, setPosition] = useState('center') const [isUserScrolled, setIsUserScrolled] = useState(false) const historyRef = useRef(null) // Reset position when dialog opens useEffect(() => { if (open) { setPosition('center') setIsUserScrolled(false) } }, [open]) // Handle scroll position useEffect(() => { const container = historyRef.current if (!container || isUserScrolled) return container.scrollTop = container.scrollHeight }, [status?.history_messages, isUserScrolled]) const handleScroll = () => { const container = historyRef.current if (!container) return const isAtBottom = Math.abs( (container.scrollHeight - container.scrollTop) - container.clientHeight ) < 1 if (isAtBottom) { setIsUserScrolled(false) } else { setIsUserScrolled(true) } } // Refresh status every 2 seconds useEffect(() => { if (!open) return const fetchStatus = async () => { try { const data = await getPipelineStatus() setStatus(data) } catch (err) { toast.error(t('documentPanel.pipelineStatus.errors.fetchFailed', { error: errorMessage(err) })) } } fetchStatus() const interval = setInterval(fetchStatus, 2000) return () => clearInterval(interval) }, [open, t]) return ( {status?.job_name ? `${t('documentPanel.pipelineStatus.jobName')}: ${status.job_name}, ${t('documentPanel.pipelineStatus.progress')}: ${status.cur_batch}/${status.batchs}` : t('documentPanel.pipelineStatus.noActiveJob') } {t('documentPanel.pipelineStatus.title')} {/* Position control buttons */}
{/* Status Content */}
{/* Pipeline Status */}
{t('documentPanel.pipelineStatus.busy')}:
{t('documentPanel.pipelineStatus.requestPending')}:
{/* Job Information */}
{t('documentPanel.pipelineStatus.jobName')}: {status?.job_name || '-'}
{t('documentPanel.pipelineStatus.startTime')}: {status?.job_start ? new Date(status.job_start).toLocaleString() : '-'} {t('documentPanel.pipelineStatus.progress')}: {status ? `${status.cur_batch}/${status.batchs} ${t('documentPanel.pipelineStatus.unit')}` : '-'}
{/* Latest Message */}
{t('documentPanel.pipelineStatus.latestMessage')}:
{status?.latest_message || '-'}
{/* History Messages */}
{t('documentPanel.pipelineStatus.historyMessages')}:
{status?.history_messages?.length ? ( status.history_messages.map((msg, idx) => (
{msg}
)) ) : '-'}
) }