diff --git a/frontend/.env b/frontend/.env index 4b5cf4e..e5771d2 100644 --- a/frontend/.env +++ b/frontend/.env @@ -1 +1 @@ -VITE_GATEWAY_URL=https://pdfapi-dev.maskantech.in +VITE_GATEWAY_URL=http://127.0.0.1:8765 diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 08ef2f3..b2b28e0 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -88,14 +88,34 @@ function App() { reorderPage?: (fromIndex: number, toIndex: number) => void; } | null>(null); + const [mergeInitialFile, setMergeInitialFile] = useState(null); + + const urlParams = new URLSearchParams(window.location.search); + const isRemote = urlParams.has('stream_url') && urlParams.has('upload_url') && urlParams.has('token'); + const urlToken = urlParams.get('token') || undefined; + useEffect(() => { if (activeTool === 'create_pdf') { setCreatePdfModalOpen(true); } else if (activeTool === 'merge_pdf') { - setMergeModalOpen(true); - setActiveTool('select'); + const handleMergeOpen = async () => { + if (isRemote && activeDoc && selectedDocId) { + try { + const blob = await gatewayService.exportDocumentBlob(selectedDocId); + setMergeInitialFile(new File([blob], activeDoc.filename || 'current_document.pdf', { type: 'application/pdf' })); + } catch (err) { + console.error('Failed to fetch initial blob for merge', err); + setMergeInitialFile(null); + } + } else { + setMergeInitialFile(null); + } + setMergeModalOpen(true); + setActiveTool('select'); + }; + handleMergeOpen(); } - }, [activeTool]); + }, [activeTool, isRemote, activeDoc, selectedDocId]); const [annotations, setAnnotations] = useState([]); const [metadata, setMetadata] = useState(null); @@ -167,10 +187,6 @@ function App() { setHist({ stack: [id], index: 0 }); }, []); - const urlParams = new URLSearchParams(window.location.search); - const isRemote = urlParams.has('stream_url') && urlParams.has('upload_url') && urlParams.has('token'); - const urlToken = urlParams.get('token') || undefined; - const hasUnsavedChanges = useCallback(() => { if (activeTool === 'create_pdf' || createPdfModalOpen) { return Boolean(creatorActions?.canUndo); @@ -1206,7 +1222,7 @@ function App() { }} onUnlock={() => selectedDocId && setUnlockModalState({ documentId: selectedDocId, filename: activeDoc?.filename || 'Document.pdf' })} onCompare={handleOpenCompareModal} - onMergePDF={() => setMergeModalOpen(true)} + onMergePDF={() => setActiveTool('merge_pdf')} isEncrypted={activeDoc?.permissions?.isEncrypted ?? false} canPrint={(activeTool === 'create_pdf' || createPdfModalOpen) ? true : can('canPrint')} canExport={(activeTool === 'create_pdf' || createPdfModalOpen) ? true : can('canCopy')} @@ -1223,6 +1239,7 @@ function App() { totalPages={activeDoc?.totalPages || 1} onGoToPage={(p) => viewerRef.current?.scrollToPage(p)} onSave={handleSave} + isRemote={isRemote} />
@@ -1235,6 +1252,7 @@ function App() { disabledTools={disabledTools} onRunOCR={handleRunOCR} isOCRLoading={isOCRLoading} + isRemote={isRemote} />
@@ -1611,6 +1629,7 @@ function App() { onClose={() => setMergeModalOpen(false)} onMergeComplete={handleMergeCompleted} apiBaseUrl={import.meta.env.VITE_GATEWAY_URL || 'http://localhost:8000'} + initialFile={mergeInitialFile} />
); diff --git a/frontend/src/components/MergePDFModal.tsx b/frontend/src/components/MergePDFModal.tsx index 3abc5a3..5c6aafa 100644 --- a/frontend/src/components/MergePDFModal.tsx +++ b/frontend/src/components/MergePDFModal.tsx @@ -15,6 +15,7 @@ interface MergePDFModalProps { onClose: () => void; onMergeComplete: (docInfo: any) => void; apiBaseUrl?: string; + initialFile?: File | null; } export const MergePDFModal: React.FC = ({ @@ -22,6 +23,7 @@ export const MergePDFModal: React.FC = ({ onClose, onMergeComplete, apiBaseUrl = 'http://localhost:8000', + initialFile = null, }) => { const [files, setFiles] = useState([]); const [outputFilename, setOutputFilename] = useState('merged_document.pdf'); @@ -30,6 +32,25 @@ export const MergePDFModal: React.FC = ({ const [mergedResult, setMergedResult] = useState(null); const fileInputRef = useRef(null); + React.useEffect(() => { + if (isOpen) { + if (initialFile) { + setFiles([{ + id: `initial-${Date.now()}`, + file: initialFile, + pagesMode: 'all', + customPages: '', + }]); + } else { + setFiles([]); + } + setOutputFilename('merged_document.pdf'); + setError(null); + setMergedResult(null); + setIsMerging(false); + } + }, [isOpen, initialFile]); + if (!isOpen) return null; const handleAddFiles = (selectedFiles: FileList | null) => { diff --git a/frontend/src/components/ToolRail.tsx b/frontend/src/components/ToolRail.tsx index eb883cf..dfc6025 100644 --- a/frontend/src/components/ToolRail.tsx +++ b/frontend/src/components/ToolRail.tsx @@ -112,6 +112,7 @@ interface ToolRailProps { disabledTools?: Set; onRunOCR?: () => void; isOCRLoading?: boolean; + isRemote?: boolean; } const RailButton: React.FC<{ t: ToolDef; active: boolean; disabled?: boolean; isLoading?: boolean; onClick: () => void }> = ({ t, active, disabled, isLoading, onClick }) => ( @@ -139,7 +140,7 @@ const RailButton: React.FC<{ t: ToolDef; active: boolean; disabled?: boolean; is ); -export const ToolRail: React.FC = ({ activeTool, onToolChange, hasSignature, onOpenSignature, onOpenAbout, disabledTools, onRunOCR, isOCRLoading }) => { +export const ToolRail: React.FC = ({ activeTool, onToolChange, hasSignature, onOpenSignature, onOpenAbout, disabledTools, onRunOCR, isOCRLoading, isRemote }) => { const pickTool = (id: ToolId) => { if (disabledTools?.has(id)) { return; @@ -151,7 +152,7 @@ export const ToolRail: React.FC = ({ activeTool, onToolChange, ha return (