diff --git a/lightrag_webui/src/features/DocumentManager.tsx b/lightrag_webui/src/features/DocumentManager.tsx index 02e1fa77..2bc1bddb 100644 --- a/lightrag_webui/src/features/DocumentManager.tsx +++ b/lightrag_webui/src/features/DocumentManager.tsx @@ -47,6 +47,14 @@ const getDisplayFileName = (doc: DocStatusResponse, maxLength: number = 20): str }; const pulseStyle = ` +/* Custom tooltip styles */ +.tooltip-top { + bottom: 100% !important; + top: auto !important; + margin-bottom: 0.25rem !important; + margin-top: 0 !important; +} + @keyframes pulse { 0% { background-color: rgb(255 0 0 / 0.1); @@ -115,6 +123,39 @@ export default function DocumentManager() { } }, []) + // Add tooltip position adjustment based on mouse position + useEffect(() => { + if (!docs) return; + + // Function to handle mouse movement + const handleMouseMove = (event: MouseEvent) => { + const cardContent = document.querySelector('.flex-1.relative.p-0'); + if (!cardContent) return; + + const cardRect = cardContent.getBoundingClientRect(); + const cardMiddleY = cardRect.top + cardRect.height / 2; + + // Get all visible tooltips + const visibleTooltips = document.querySelectorAll('.group:hover > div[class*="invisible group-hover:visible absolute"]'); + + visibleTooltips.forEach(tooltip => { + // If mouse is in the bottom half of the card, show tooltip above + if (event.clientY > cardMiddleY) { + tooltip.classList.add('tooltip-top'); + } else { + tooltip.classList.remove('tooltip-top'); + } + }); + }; + + // Add mouse move listener to the document + document.addEventListener('mousemove', handleMouseMove); + + return () => { + document.removeEventListener('mousemove', handleMouseMove); + }; + }, [docs]); + const fetchDocuments = useCallback(async () => { try { const docs = await getDocuments() @@ -193,12 +234,12 @@ export default function DocumentManager() { }, [health, fetchDocuments, t, currentTab]) return ( - - + + {t('documentPanel.documentManager.title')} - -
+ +
- - + +
{t('documentPanel.documentManager.uploadedTitle')}
@@ -253,92 +294,100 @@ export default function DocumentManager() { - + {!docs && ( - +
+ +
)} {docs && ( - - - - {t('documentPanel.documentManager.columns.id')} - {t('documentPanel.documentManager.columns.summary')} - {t('documentPanel.documentManager.columns.status')} - {t('documentPanel.documentManager.columns.length')} - {t('documentPanel.documentManager.columns.chunks')} - {t('documentPanel.documentManager.columns.created')} - {t('documentPanel.documentManager.columns.updated')} - - - - {Object.entries(docs.statuses).map(([status, documents]) => - documents.map((doc) => ( - - - {showFileName ? ( - <> -
-
- {getDisplayFileName(doc, 35)} +
+
+
+
+ + + {t('documentPanel.documentManager.columns.id')} + {t('documentPanel.documentManager.columns.summary')} + {t('documentPanel.documentManager.columns.status')} + {t('documentPanel.documentManager.columns.length')} + {t('documentPanel.documentManager.columns.chunks')} + {t('documentPanel.documentManager.columns.created')} + {t('documentPanel.documentManager.columns.updated')} + + + + {Object.entries(docs.statuses).map(([status, documents]) => + documents.map((doc) => ( + + + {showFileName ? ( + <> +
+
+ {getDisplayFileName(doc, 35)} +
+
+ {doc.file_path} +
+
+
{doc.id}
+ + ) : ( +
+
+ {doc.id} +
+
+ {doc.file_path} +
+
+ )} +
+ +
+
+ {doc.content_summary} +
+
+ {doc.content_summary} +
-
- {doc.file_path} -
- -
{doc.id}
- - ) : ( -
-
- {doc.id} -
-
- {doc.file_path} -
-
- )} -
- -
-
- {doc.content_summary} -
-
- {doc.content_summary} -
-
-
- - {status === 'processed' && ( - {t('documentPanel.documentManager.status.completed')} - )} - {status === 'processing' && ( - {t('documentPanel.documentManager.status.processing')} - )} - {status === 'pending' && {t('documentPanel.documentManager.status.pending')}} - {status === 'failed' && {t('documentPanel.documentManager.status.failed')}} - {doc.error && ( - - ⚠️ - - )} - - {doc.content_length ?? '-'} - {doc.chunks_count ?? '-'} - - {new Date(doc.created_at).toLocaleString()} - - - {new Date(doc.updated_at).toLocaleString()} - -
- )) - )} -
-
+ + + {status === 'processed' && ( + {t('documentPanel.documentManager.status.completed')} + )} + {status === 'processing' && ( + {t('documentPanel.documentManager.status.processing')} + )} + {status === 'pending' && {t('documentPanel.documentManager.status.pending')}} + {status === 'failed' && {t('documentPanel.documentManager.status.failed')}} + {doc.error && ( + + ⚠️ + + )} + + {doc.content_length ?? '-'} + {doc.chunks_count ?? '-'} + + {new Date(doc.created_at).toLocaleString()} + + + {new Date(doc.updated_at).toLocaleString()} + + + )) + )} + + +
+
+
)}