import { useState, useEffect, useCallback } from 'react' import Button from '@/components/ui/Button' import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/Table' import { Card, CardHeader, CardTitle, CardContent, CardDescription } from '@/components/ui/Card' import EmptyCard from '@/components/ui/EmptyCard' import Text from '@/components/ui/Text' import UploadDocumentsDialog from '@/components/documents/UploadDocumentsDialog' import ClearDocumentsDialog from '@/components/documents/ClearDocumentsDialog' import { getDocuments, scanNewDocuments, DocsStatusesResponse } from '@/api/lightrag' import { errorMessage } from '@/lib/utils' import { toast } from 'sonner' import { useBackendState } from '@/stores/state' import { RefreshCwIcon } from 'lucide-react' export default function DocumentManager() { const health = useBackendState.use.health() const [docs, setDocs] = useState(null) const fetchDocuments = useCallback(async () => { try { const docs = await getDocuments() if (docs && docs.statuses) { // compose all documents count const numDocuments = Object.values(docs.statuses).reduce( (acc, status) => acc + status.length, 0 ) if (numDocuments > 0) { setDocs(docs) } else { setDocs(null) } // console.log(docs) } else { setDocs(null) } } catch (err) { toast.error('Failed to load documents\n' + errorMessage(err)) } }, [setDocs]) useEffect(() => { fetchDocuments() }, []) // eslint-disable-line react-hooks/exhaustive-deps const scanDocuments = useCallback(async () => { try { const { status } = await scanNewDocuments() toast.message(status) } catch (err) { toast.error('Failed to load documents\n' + errorMessage(err)) } }, []) useEffect(() => { const interval = setInterval(async () => { if (!health) { return } try { await fetchDocuments() } catch (err) { toast.error('Failed to get scan progress\n' + errorMessage(err)) } }, 5000) return () => clearInterval(interval) }, [health, fetchDocuments]) return ( Document Management
Uploaded documents view the uploaded documents here {!docs && ( )} {docs && ( ID Summary Status Length Chunks Created Updated Metadata {Object.entries(docs.statuses).map(([status, documents]) => documents.map((doc) => ( {doc.id} {status === 'processed' && ( Completed )} {status === 'processing' && ( Processing )} {status === 'pending' && Pending} {status === 'failed' && Failed} {doc.error && ( ⚠️ )} {doc.content_length ?? '-'} {doc.chunks_count ?? '-'} {new Date(doc.created_at).toLocaleString()} {new Date(doc.updated_at).toLocaleString()} {doc.metadata ? JSON.stringify(doc.metadata) : '-'} )) )}
)}
) }