()
| 369 | }; |
| 370 | |
| 371 | export default function DocumentManager() { |
| 372 | // Track component mount status |
| 373 | const isMountedRef = useRef(true); |
| 374 | |
| 375 | // Set up mount/unmount status tracking. Pending throttle/probe timers are NOT |
| 376 | // explicitly cleared on unmount — every timer callback checks isMountedRef |
| 377 | // before doing any work, so a stray fire is a no-op. |
| 378 | useEffect(() => { |
| 379 | isMountedRef.current = true; |
| 380 | |
| 381 | // Handle page reload/unload |
| 382 | const handleBeforeUnload = () => { |
| 383 | isMountedRef.current = false; |
| 384 | }; |
| 385 | |
| 386 | window.addEventListener('beforeunload', handleBeforeUnload); |
| 387 | |
| 388 | return () => { |
| 389 | isMountedRef.current = false; |
| 390 | window.removeEventListener('beforeunload', handleBeforeUnload); |
| 391 | }; |
| 392 | }, []); |
| 393 | |
| 394 | const [showPipelineStatus, setShowPipelineStatus] = useState(false) |
| 395 | const { t, i18n } = useTranslation() |
| 396 | const health = useBackendState.use.health() |
| 397 | const pipelineActive = useBackendState.use.pipelineActive() |
| 398 | |
| 399 | // Legacy state for backward compatibility |
| 400 | const [docs, setDocs] = useState<DocsStatusesResponse | null>(null) |
| 401 | |
| 402 | const currentTab = useSettingsStore.use.currentTab() |
| 403 | const showFileName = useSettingsStore.use.showFileName() |
| 404 | const setShowFileName = useSettingsStore.use.setShowFileName() |
| 405 | const documentsPageSize = useSettingsStore.use.documentsPageSize() |
| 406 | const setDocumentsPageSize = useSettingsStore.use.setDocumentsPageSize() |
| 407 | |
| 408 | // New pagination state |
| 409 | const [currentPageDocs, setCurrentPageDocs] = useState<DocStatusResponse[]>([]) |
| 410 | const [pagination, setPagination] = useState<PaginationInfo>({ |
| 411 | page: 1, |
| 412 | page_size: documentsPageSize, |
| 413 | total_count: 0, |
| 414 | total_pages: 0, |
| 415 | has_next: false, |
| 416 | has_prev: false |
| 417 | }) |
| 418 | const [statusCounts, setStatusCounts] = useState<Record<string, number>>({ all: 0 }) |
| 419 | // Mirror statusCounts in a ref so async callbacks (e.g. activity probe ticks) |
| 420 | // can read the latest value without being tied to the closure captured at |
| 421 | // schedule time. Synced via useEffect to satisfy react-hooks/refs. |
| 422 | const statusCountsRef = useRef(statusCounts) |
| 423 | useEffect(() => { |
| 424 | statusCountsRef.current = statusCounts |
| 425 | }, [statusCounts]) |
| 426 | const [isRefreshing, setIsRefreshing] = useState(false) |
| 427 | |
| 428 | // Sort state |
nothing calls this directly
no test coverage detected