diff --git a/frontend/src/components/layout/Workbench.tsx b/frontend/src/components/layout/Workbench.tsx index 974ca294c..d07c6c96c 100644 --- a/frontend/src/components/layout/Workbench.tsx +++ b/frontend/src/components/layout/Workbench.tsx @@ -1,10 +1,11 @@ -import React, { useState } from 'react'; +import React from 'react'; import { Box } from '@mantine/core'; import { useRainbowThemeContext } from '../shared/RainbowThemeProvider'; import { useToolWorkflow } from '../../contexts/ToolWorkflowContext'; import { useFileHandler } from '../../hooks/useFileHandler'; import { useFileState } from '../../contexts/FileContext'; import { useNavigationState, useNavigationActions } from '../../contexts/NavigationContext'; +import { useViewer } from '../../contexts/ViewerContext'; import './Workbench.css'; import TopControls from '../shared/TopControls'; @@ -26,7 +27,6 @@ export default function Workbench() { const { actions: navActions } = useNavigationActions(); const setCurrentView = navActions.setWorkbench; const activeFiles = selectors.getFiles(); - const [activeFileIndex, setActiveFileIndex] = useState(0); const { previewFile, pageEditorFunctions, @@ -46,6 +46,9 @@ export default function Workbench() { const selectedTool = selectedToolId ? toolRegistry[selectedToolId] : null; const { addFiles } = useFileHandler(); + // Get active file index from ViewerContext + const { activeFileIndex, setActiveFileIndex } = useViewer(); + const handlePreviewClose = () => { setPreviewFile(null); const previousMode = sessionStorage.getItem('previousMode'); diff --git a/frontend/src/contexts/ViewerContext.tsx b/frontend/src/contexts/ViewerContext.tsx index 895776f96..e3aa94487 100644 --- a/frontend/src/contexts/ViewerContext.tsx +++ b/frontend/src/contexts/ViewerContext.tsx @@ -132,6 +132,10 @@ interface ViewerContextType { setAnnotationMode: (enabled: boolean) => void; toggleAnnotationMode: () => void; + // Active file index for multi-file viewing + activeFileIndex: number; + setActiveFileIndex: (index: number) => void; + // State getters - read current state from bridges getScrollState: () => ScrollState; getZoomState: () => ZoomState; @@ -219,6 +223,7 @@ export const ViewerProvider: React.FC = ({ children }) => { const [isThumbnailSidebarVisible, setIsThumbnailSidebarVisible] = useState(false); const [isAnnotationsVisible, setIsAnnotationsVisible] = useState(true); const [isAnnotationMode, setIsAnnotationModeState] = useState(false); + const [activeFileIndex, setActiveFileIndex] = useState(0); // Get current navigation state to check if we're in sign mode useNavigation(); @@ -577,6 +582,10 @@ export const ViewerProvider: React.FC = ({ children }) => { setAnnotationMode, toggleAnnotationMode, + // Active file index + activeFileIndex, + setActiveFileIndex, + // State getters getScrollState, getZoomState, diff --git a/frontend/src/tools/Sign.tsx b/frontend/src/tools/Sign.tsx index f76621895..477bf657f 100644 --- a/frontend/src/tools/Sign.tsx +++ b/frontend/src/tools/Sign.tsx @@ -17,7 +17,7 @@ const Sign = (props: BaseToolProps) => { const { setWorkbench } = useNavigation(); const { setSignatureConfig, activateDrawMode, activateSignaturePlacementMode, deactivateDrawMode, updateDrawSettings, undo, redo, signatureApiRef, getImageData, setSignaturesApplied } = useSignature(); const { consumeFiles, selectors } = useFileContext(); - const { exportActions, getScrollState } = useViewer(); + const { exportActions, getScrollState, activeFileIndex, setActiveFileIndex } = useViewer(); const { setHasUnsavedChanges, unregisterUnsavedChangesChecker } = useNavigation(); // Track which signature mode was active for reactivation after save @@ -75,19 +75,15 @@ const Sign = (props: BaseToolProps) => { unregisterUnsavedChangesChecker(); setHasUnsavedChanges(false); - // Get the original file - let originalFile = null; - if (base.selectedFiles.length > 0) { - originalFile = base.selectedFiles[0]; - } else { - const allFileIds = selectors.getAllFileIds(); - if (allFileIds.length > 0) { - const stirlingFile = selectors.getFile(allFileIds[0]); - if (stirlingFile) { - originalFile = stirlingFile; - } - } - } + // Get the original file from FileContext using activeFileIndex + // The viewer displays files from FileContext, not from base.selectedFiles + const allFiles = selectors.getFiles(); + const fileIndex = activeFileIndex < allFiles.length ? activeFileIndex : 0; + const originalFile = allFiles[fileIndex]; + + console.log('[Sign] Active file index:', activeFileIndex); + console.log('[Sign] All files:', allFiles.map(f => ({ name: f.name, id: f.fileId }))); + console.log('[Sign] Selected file for signing:', { name: originalFile?.name, id: originalFile?.fileId }); if (!originalFile) { console.error('No file available to replace'); @@ -101,10 +97,14 @@ const Sign = (props: BaseToolProps) => { exportActions, selectors, originalFile, - getScrollState + getScrollState, + activeFileIndex }); if (flattenResult) { + console.log('[Sign] About to consume - input IDs:', flattenResult.inputFileIds); + console.log('[Sign] About to consume - output file:', { name: flattenResult.outputStirlingFile.name, id: flattenResult.outputStirlingFile.fileId }); + // Now consume the files - this triggers the viewer reload await consumeFiles( flattenResult.inputFileIds, @@ -112,6 +112,25 @@ const Sign = (props: BaseToolProps) => { [flattenResult.outputStub] ); + // Find the new file's position in the updated file list and update activeFileIndex + const updatedFiles = selectors.getFiles(); + console.log('[Sign] After consume - updated files:', updatedFiles.map(f => ({ name: f.name, id: f.fileId }))); + console.log('[Sign] Looking for file ID:', flattenResult.outputStirlingFile.fileId); + + const newFileIndex = updatedFiles.findIndex(f => { + console.log('[Sign] Comparing:', f.fileId, 'with', flattenResult.outputStirlingFile.fileId, 'match:', f.fileId === flattenResult.outputStirlingFile.fileId); + return f.fileId === flattenResult.outputStirlingFile.fileId; + }); + console.log('[Sign] New file index:', newFileIndex); + + if (newFileIndex !== -1) { + setActiveFileIndex(newFileIndex); + console.log('[Sign] Set active file index to:', newFileIndex); + } else { + console.error('[Sign] Failed to find new file in updated list! Defaulting to index 0'); + setActiveFileIndex(0); + } + // Mark signatures as applied setSignaturesApplied(true); @@ -125,7 +144,7 @@ const Sign = (props: BaseToolProps) => { } catch (error) { console.error('Error saving signed document:', error); } - }, [exportActions, base.selectedFiles, selectors, consumeFiles, signatureApiRef, getImageData, setWorkbench, activateDrawMode, setSignaturesApplied, getScrollState, handleDeactivateSignature, setHasUnsavedChanges, unregisterUnsavedChangesChecker]); + }, [exportActions, base.selectedFiles, selectors, consumeFiles, signatureApiRef, getImageData, setWorkbench, activateDrawMode, setSignaturesApplied, getScrollState, handleDeactivateSignature, setHasUnsavedChanges, unregisterUnsavedChangesChecker, activeFileIndex, setActiveFileIndex]); const getSteps = () => { const steps = []; diff --git a/frontend/src/utils/signatureFlattening.ts b/frontend/src/utils/signatureFlattening.ts index 1ff343155..4ed63c29b 100644 --- a/frontend/src/utils/signatureFlattening.ts +++ b/frontend/src/utils/signatureFlattening.ts @@ -19,6 +19,7 @@ interface SignatureFlatteningOptions { selectors: MinimalFileContextSelectors; originalFile?: StirlingFile; getScrollState: () => { currentPage: number; totalPages: number }; + activeFileIndex?: number; } export interface SignatureFlatteningResult { @@ -28,7 +29,7 @@ export interface SignatureFlatteningResult { } export async function flattenSignatures(options: SignatureFlatteningOptions): Promise { - const { signatureApiRef, getImageData, exportActions, selectors, originalFile, getScrollState } = options; + const { signatureApiRef, getImageData, exportActions, selectors, originalFile, getScrollState, activeFileIndex } = options; try { // Step 1: Extract all annotations from EmbedPDF before export @@ -104,10 +105,12 @@ export async function flattenSignatures(options: SignatureFlatteningOptions): Pr if (!currentFile) { const allFileIds = selectors.getAllFileIds(); if (allFileIds.length > 0) { - const fileStub = selectors.getStirlingFileStub(allFileIds[0]); - const fileObject = selectors.getFile(allFileIds[0]); + // Use activeFileIndex if provided, otherwise default to 0 + const fileIndex = activeFileIndex !== undefined && activeFileIndex < allFileIds.length ? activeFileIndex : 0; + const fileStub = selectors.getStirlingFileStub(allFileIds[fileIndex]); + const fileObject = selectors.getFile(allFileIds[fileIndex]); if (fileStub && fileObject) { - currentFile = createStirlingFile(fileObject, allFileIds[0] as FileId); + currentFile = createStirlingFile(fileObject, allFileIds[fileIndex] as FileId); } } } @@ -287,6 +290,9 @@ export async function flattenSignatures(options: SignatureFlatteningOptions): Pr // Prepare input file data for replacement const inputFileIds: FileId[] = [currentFile.fileId]; + console.log('[flattenSignatures] Current file:', { name: currentFile.name, id: currentFile.fileId }); + console.log('[flattenSignatures] Input file IDs to consume:', inputFileIds); + const record = selectors.getStirlingFileStub(currentFile.fileId); if (!record) { console.error('No file record found for:', currentFile.fileId);