// // SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // "use client" import { useState, useEffect } from "react" import { useDocuments } from "@/contexts/document-context" import { CheckCircle, Loader2, FileText, AlertCircle, X } from "lucide-react" import { Button } from "@/components/ui/button" import { useRouter } from "next/navigation" import { useShiftSelect } from "@/hooks/use-shift-select" export function DocumentSelection() { const { documents, processDocuments, isProcessing } = useDocuments() const [processingStatus, setProcessingStatus] = useState("") const [error, setError] = useState(null) const [forceUpdate, setForceUpdate] = useState(0) const router = useRouter() // Use shift-select hook for document selection const { selectedItems: selectedDocs, setSelectedItems: setSelectedDocs, handleItemClick, handleSelectAll, isSelected } = useShiftSelect({ items: documents, getItemId: (doc) => doc.id, canSelect: (doc) => doc.status === "New" || doc.status === "Processed" || doc.status === "Error", onSelectionChange: (selectedIds) => { // Optional: handle selection change if needed } }) // Add event listener for document status changes useEffect(() => { const handleDocumentStatusChange = () => { console.log("Document status changed, forcing UI refresh"); setForceUpdate(prev => prev + 1); // Increment to force a re-render }; const handleProcessingComplete = () => { console.log("Processing complete event received, resetting UI state"); setProcessingStatus(""); // Clear the processing status message setForceUpdate(prev => prev + 1); // Force a refresh }; window.addEventListener('document-status-changed', handleDocumentStatusChange); window.addEventListener('processing-complete', handleProcessingComplete); return () => { window.removeEventListener('document-status-changed', handleDocumentStatusChange); window.removeEventListener('processing-complete', handleProcessingComplete); }; }, []); // Add automatic UI refresh every second during processing useEffect(() => { let interval: NodeJS.Timeout; if (isProcessing) { interval = setInterval(() => { setForceUpdate(prev => prev + 1); // Force UI refresh }, 1000); } return () => { if (interval) clearInterval(interval); }; }, [isProcessing]); // On component mount, default to select all documents with status "New", "Processed", or "Error" useEffect(() => { const availableDocs = documents .filter(doc => doc.status === "New" || doc.status === "Processed" || doc.status === "Error") .map(doc => doc.id) setSelectedDocs(availableDocs) }, [documents, setSelectedDocs]) const handleTabChange = (tab: string) => { const tabElement = document.querySelector(`[data-value="${tab}"]`) if (tabElement && 'click' in tabElement) { (tabElement as HTMLElement).click() } } const handleProcessDocuments = async () => { if (selectedDocs.length === 0) { setError("Please select at least one document to process") return } setError(null) setProcessingStatus("Preparing documents for processing...") try { // Update the processing status display const docNames = selectedDocs.map(id => documents.find(d => d.id === id)?.name || 'Unknown' ).join(', '); setProcessingStatus(`Processing ${selectedDocs.length} document(s): ${docNames}`); // Call processDocuments with the selected document IDs await processDocuments(selectedDocs, { useLangChain: false, useGraphTransformer: false, promptConfigs: undefined }) // Ensure UI is updated after processing completes setForceUpdate(prev => prev + 1); setProcessingStatus("Processing complete! Navigating to edit view..."); // Short delay before navigation to allow status update to be seen setTimeout(() => { // Navigate to the edit tab after processing handleTabChange("edit") }, 1000); } catch (error) { console.error("Error processing documents:", error) setError("Failed to process documents. Please try again.") } } const handleStopProcessing = async () => { try { // Call the stop processing API const response = await fetch('/api/stop-processing', { method: 'POST', headers: { 'Content-Type': 'application/json', }, }); if (response.ok) { setProcessingStatus("Processing stopped by user"); setError(null); // Force UI refresh to update document statuses setForceUpdate(prev => prev + 1); } else { setError("Failed to stop processing. Please try again."); } } catch (error) { console.error("Error stopping processing:", error); setError("Failed to stop processing. Please try again."); } } return (

Document Selection

Select which documents to process for triple extraction

{error && (

{error}

)}
doc.status === "New" || doc.status === "Processed" || doc.status === "Error").length && documents.filter(doc => doc.status === "New" || doc.status === "Processed" || doc.status === "Error").length > 0} onChange={handleSelectAll} disabled={documents.filter(doc => doc.status === "New" || doc.status === "Processed" || doc.status === "Error").length === 0 || isProcessing} /> {selectedDocs.length > 0 ? ( {selectedDocs.length} selected ) : ( Select all )}
{isProcessing && ( )}
{documents.length === 0 ? (

No documents available for processing

) : ( {documents.map((doc) => ( ))}
handleItemClick(doc, e)} disabled={(doc.status !== "New" && doc.status !== "Processed" && doc.status !== "Error") || isProcessing} /> (doc.status === "New" || doc.status === "Processed" || doc.status === "Error") && !isProcessing && handleItemClick(doc, e)}> {doc.name}
{doc.status === "New" && ( )} {doc.status === "Processing" && ( )} {doc.status === "Processed" && ( )} {doc.status === "Error" && ( )} {doc.status}
{doc.size}
)}
{isProcessing && processingStatus && (
{processingStatus}
)}
) }