diff --git a/lightrag_webui/src/features/DocumentManager.tsx b/lightrag_webui/src/features/DocumentManager.tsx index 2ce3daee..1670ddd7 100644 --- a/lightrag_webui/src/features/DocumentManager.tsx +++ b/lightrag_webui/src/features/DocumentManager.tsx @@ -32,7 +32,7 @@ import { errorMessage } from '@/lib/utils' import { toast } from 'sonner' import { useBackendState } from '@/stores/state' -import { RefreshCwIcon, ActivityIcon, ArrowUpIcon, ArrowDownIcon, RotateCcwIcon, CheckSquareIcon, XIcon } from 'lucide-react' +import { RefreshCwIcon, ActivityIcon, ArrowUpIcon, ArrowDownIcon, RotateCcwIcon, CheckSquareIcon, XIcon, AlertTriangle, Info } from 'lucide-react' import PipelineStatusDialog from '@/components/documents/PipelineStatusDialog' type StatusFilter = DocStatus | 'all'; @@ -59,6 +59,26 @@ const getDisplayFileName = (doc: DocStatusResponse, maxLength: number = 20): str : fileName; }; +const formatMetadata = (metadata: Record): string => { + const formattedMetadata = { ...metadata }; + + if (formattedMetadata.processing_start_time && typeof formattedMetadata.processing_start_time === 'number') { + const date = new Date(formattedMetadata.processing_start_time * 1000); + if (!isNaN(date.getTime())) { + formattedMetadata.processing_start_time = date.toLocaleString(); + } + } + + if (formattedMetadata.processing_end_time && typeof formattedMetadata.processing_end_time === 'number') { + const date = new Date(formattedMetadata.processing_end_time * 1000); + if (!isNaN(date.getTime())) { + formattedMetadata.processing_end_time = date.toLocaleString(); + } + } + + return JSON.stringify(formattedMetadata, null, 2); +}; + const pulseStyle = ` /* Tooltip styles */ .tooltip-container { @@ -1168,23 +1188,39 @@ export default function DocumentManager() { - {doc.status === 'processed' && ( - {t('documentPanel.documentManager.status.completed')} - )} - {doc.status === 'processing' && ( - {t('documentPanel.documentManager.status.processing')} - )} - {doc.status === 'pending' && ( - {t('documentPanel.documentManager.status.pending')} - )} - {doc.status === 'failed' && ( - {t('documentPanel.documentManager.status.failed')} - )} - {doc.error_msg && ( - - ⚠️ - - )} +
+ {doc.status === 'processed' && ( + {t('documentPanel.documentManager.status.completed')} + )} + {doc.status === 'processing' && ( + {t('documentPanel.documentManager.status.processing')} + )} + {doc.status === 'pending' && ( + {t('documentPanel.documentManager.status.pending')} + )} + {doc.status === 'failed' && ( + {t('documentPanel.documentManager.status.failed')} + )} + + {/* Icon rendering logic */} + {doc.error_msg ? ( + + ) : (doc.metadata && Object.keys(doc.metadata).length > 0) && ( + + )} + + {/* Tooltip rendering logic */} + {(doc.error_msg || (doc.metadata && Object.keys(doc.metadata).length > 0)) && ( +
+ {doc.error_msg && ( +
{doc.error_msg}
+ )} + {doc.metadata && Object.keys(doc.metadata).length > 0 && ( +
{formatMetadata(doc.metadata)}
+ )} +
+ )} +
{doc.content_length ?? '-'} {doc.chunks_count ?? '-'}