diff --git a/frontend/src/components/tools/sign/SignSettings.tsx b/frontend/src/components/tools/sign/SignSettings.tsx index a141c2a0f..ef6f3b907 100644 --- a/frontend/src/components/tools/sign/SignSettings.tsx +++ b/frontend/src/components/tools/sign/SignSettings.tsx @@ -461,6 +461,7 @@ const SignSettings = ({ parameters, onParameterChange, disabled = false, onActiv /> + {/* Signature Creation based on type */} {parameters.signatureType === 'canvas' && ( diff --git a/frontend/src/components/viewer/LocalEmbedPDF.tsx b/frontend/src/components/viewer/LocalEmbedPDF.tsx index 1fc183fe7..435519de5 100644 --- a/frontend/src/components/viewer/LocalEmbedPDF.tsx +++ b/frontend/src/components/viewer/LocalEmbedPDF.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useMemo, useState } from 'react'; +import React, { useEffect, useMemo, useState, useRef } from 'react'; import { createPluginRegistration } from '@embedpdf/core'; import { EmbedPDF } from '@embedpdf/core/react'; import { usePdfiumEngine } from '@embedpdf/engines/react'; @@ -46,6 +46,7 @@ interface LocalEmbedPDFProps { export function LocalEmbedPDF({ file, url, enableSignature = false, onSignatureAdded, signatureApiRef }: LocalEmbedPDFProps) { const [pdfUrl, setPdfUrl] = useState(null); + const [annotations, setAnnotations] = useState>([]); // Convert File to URL if needed useEffect(() => { @@ -217,14 +218,34 @@ export function LocalEmbedPDF({ file, url, enableSignature = false, onSignatureA }, }); - // Listen for annotation events to notify parent component - if (onSignatureAdded) { - annotationApi.onAnnotationEvent((event: any) => { - if (event.type === 'create' && event.committed) { + // Listen for annotation events to track annotations and notify parent + annotationApi.onAnnotationEvent((event: any) => { + if (event.type === 'create' && event.committed) { + // Add to annotations list + setAnnotations(prev => [...prev, { + id: event.annotation.id, + pageIndex: event.pageIndex, + rect: event.annotation.rect + }]); + + + // Notify parent if callback provided + if (onSignatureAdded) { onSignatureAdded(event.annotation); } - }); - } + } else if (event.type === 'delete' && event.committed) { + // Remove from annotations list + setAnnotations(prev => prev.filter(ann => ann.id !== event.annotation.id)); + } else if (event.type === 'loaded') { + // Handle initial load of annotations + const loadedAnnotations = event.annotations || []; + setAnnotations(loadedAnnotations.map((ann: any) => ({ + id: ann.id, + pageIndex: ann.pageIndex || 0, + rect: ann.rect + }))); + } + }); } : undefined} > @@ -297,6 +318,7 @@ export function LocalEmbedPDF({ file, url, enableSignature = false, onSignatureA )} /> + diff --git a/frontend/src/components/viewer/SignatureAPIBridge.tsx b/frontend/src/components/viewer/SignatureAPIBridge.tsx index f27ea6d85..6a0d2ebe2 100644 --- a/frontend/src/components/viewer/SignatureAPIBridge.tsx +++ b/frontend/src/components/viewer/SignatureAPIBridge.tsx @@ -9,6 +9,8 @@ export interface SignatureAPI { addTextSignature: (text: string, x: number, y: number, pageIndex: number) => void; activateDrawMode: () => void; activateSignaturePlacementMode: () => void; + activateDeleteMode: () => void; + deleteAnnotation: (annotationId: string, pageIndex: number) => void; updateDrawSettings: (color: string, size: number) => void; deactivateTools: () => void; applySignatureFromParameters: (params: SignParameters) => void; @@ -20,6 +22,30 @@ export const SignatureAPIBridge = forwardRef { + if (!annotationApi) return; + + const handleKeyDown = (event: KeyboardEvent) => { + if (event.key === 'Delete' || event.key === 'Backspace') { + const selectedAnnotation = annotationApi.getSelectedAnnotation?.(); + + if (selectedAnnotation) { + const annotation = selectedAnnotation as any; + const pageIndex = annotation.object?.pageIndex || 0; + const id = annotation.object?.id; + + if (id) { + annotationApi.deleteAnnotation(pageIndex, id); + } + } + } + }; + + document.addEventListener('keydown', handleKeyDown); + return () => document.removeEventListener('keydown', handleKeyDown); + }, [annotationApi]); + useImperativeHandle(ref, () => ({ addImageSignature: (signatureData: string, x: number, y: number, width: number, height: number, pageIndex: number) => { if (!annotationApi) return; @@ -183,6 +209,19 @@ export const SignatureAPIBridge = forwardRef { + if (!annotationApi) return; + // Activate selection tool to allow selecting and deleting annotations + // Users can click annotations to select them, then press Delete key or right-click to delete + annotationApi.setActiveTool('select'); + }, + + deleteAnnotation: (annotationId: string, pageIndex: number) => { + if (!annotationApi) return; + // Delete specific annotation by ID + annotationApi.deleteAnnotation(pageIndex, annotationId); + }, + deactivateTools: () => { if (!annotationApi) return; annotationApi.setActiveTool(null); @@ -208,6 +247,11 @@ export const SignatureAPIBridge = forwardRef { + annotationApi.setActiveTool('select'); + }, 100); } break; @@ -231,6 +275,11 @@ export const SignatureAPIBridge = forwardRef { + annotationApi.setActiveTool('select'); + }, 100); } break; diff --git a/frontend/src/contexts/SignatureContext.tsx b/frontend/src/contexts/SignatureContext.tsx index 1590579bc..c64ff4a5a 100644 --- a/frontend/src/contexts/SignatureContext.tsx +++ b/frontend/src/contexts/SignatureContext.tsx @@ -17,6 +17,7 @@ interface SignatureActions { activateDrawMode: () => void; deactivateDrawMode: () => void; activateSignaturePlacementMode: () => void; + activateDeleteMode: () => void; updateDrawSettings: (color: string, size: number) => void; } @@ -86,6 +87,13 @@ export const SignatureProvider: React.FC<{ children: ReactNode }> = ({ children } }, [state.signatureConfig, setPlacementMode]); + const activateDeleteMode = useCallback(() => { + if (signatureApiRef.current) { + signatureApiRef.current.activateDeleteMode(); + setPlacementMode(true); + } + }, [setPlacementMode]); + const updateDrawSettings = useCallback((color: string, size: number) => { if (signatureApiRef.current) { signatureApiRef.current.updateDrawSettings(color, size); @@ -103,6 +111,7 @@ export const SignatureProvider: React.FC<{ children: ReactNode }> = ({ children activateDrawMode, deactivateDrawMode, activateSignaturePlacementMode, + activateDeleteMode, updateDrawSettings, };