Refactor signature model; update EnvelopeViewer UI
Refactored `_capturedSignature` to `SignatureCaptureDto`, a sealed record with required and optional properties for better type safety and clarity. Updated components to use the new model and demonstrated initialization with object initializers. Enhanced `EnvelopeViewer` with modern UI features, including HiDPI/Retina support, configurable zoom options, smooth zoom transitions, and improved thumbnail sidebar functionality. Updated `Applied Signature` HTML overlay to support dynamic positioning for rendering signatures at specific coordinates. Revised documentation in `COPILOT_CONTEXT_EN.md` to reflect changes in the signature data structure and usage. Noted that current implementation provides visual overlays only, with future consideration for actual PDF stamping using PSPDFKit.
This commit is contained in:
@@ -397,57 +397,6 @@ Our use case is **visual/image stamping** at specific page coordinates
|
||||
|
||||
---
|
||||
|
||||
## Change Log
|
||||
|
||||
| Session | Date | Change |
|
||||
|---|---|---|
|
||||
| 1–3 | — | Core infrastructure: services, YARP proxy, JS overlay, signature pad |
|
||||
| 4 | — | `AddSignatureAtAnnotation` with BottomMarginBand — ? repeated on all pages |
|
||||
| 5 | — | `BeforePrint` + `e.Graph?.PrintingSystem` — ? compile error |
|
||||
| 6 | — | BeforePrint counter — ? correct pattern, wrong band |
|
||||
| 7 | — | Switched to DetailBand — ? correct band |
|
||||
| 8 | — | `(page-1)*1169+Y` offset — ? 35?140 page inflation |
|
||||
| 9 | — | Fixed: `BoundsF.Y = ann.Y` + counter; created COPILOT_CONTEXT.md |
|
||||
| 10 | — | Investigated DevExpress article — not applicable to our case |
|
||||
| 10 | — | Added iText7 to ReceiverUI; implemented `StampSignaturesOnPdf` — ? deterministic coordinates, no page count side effects |
|
||||
| 10 | — | Split COPILOT_CONTEXT.md into COPILOT_CONTEXT_EN.md and COPILOT_CONTEXT_TR.md |
|
||||
| **11** | **2025-01-XX** | **Created EnvelopeViewer.razor with PDF.js 3.11.174 + modern UI** |
|
||||
| **11** | **2025-01-XX** | **Implemented configurable quality system (PdfViewerOptions + appsettings.json)** |
|
||||
| **11** | **2025-01-XX** | **Added HiDPI/Retina support (4x quality on Retina displays)** |
|
||||
| **11** | **2025-01-XX** | **Implemented thumbnail sidebar with resizable splitter (150-400px, localStorage)** |
|
||||
| **11** | **2025-01-XX** | **Added smooth zoom transitions with configurable opacity and duration** |
|
||||
| **11** | **2025-01-XX** | **Made zoom step configurable (buttons, Ctrl+Wheel, slider use same step)** |
|
||||
| **11** | **2025-01-XX** | **Fixed thumbnail canvas alignment (object-fit: contain)** |
|
||||
| **11** | **2025-01-XX** | **Fixed thumbnail re-rendering on sidebar toggle** |
|
||||
| **12** | **2025-01-XX** | **Fixed coordinate system documentation: Database stores INCHES (not DX units)** |
|
||||
| **12** | **2025-01-XX** | **Updated XML documentation in SignatureDto, AnnotationDto, AnnotationCreateDto** |
|
||||
| **13** | **2025-01-XX** | **Added SenderAppType enum to SignatureDto for Legacy/Blazor app differentiation** |
|
||||
| **13** | **2025-01-XX** | **Implemented signature overlay rendering in PDF.js viewer (INCHES ? normalized ? pixels)** |
|
||||
| **13** | **2025-01-XX** | **Added automatic overlay re-rendering on page change, zoom, and initial load** |
|
||||
| **13** | **2025-01-XX** | **Added clickable signature buttons on PDF canvas (Sign/Unterschreiben)** |
|
||||
| **13** | **2025-01-XX** | **Signature buttons: 150px×60px, purple gradient, pen icon, hover effects** |
|
||||
| **13** | **2025-01-XX** | **JavaScript: `pdfViewer.renderSignatureButtons()` and `pdfViewer.clearSignatureButtons()`** |
|
||||
| **14** | **2025-01-26** | **Added signature creation popup (DxPopup) - opens automatically on page load** |
|
||||
| **14** | **2025-01-26** | **Popup features: 3 tabs (Draw/Text/Image), required fields (Name, Place), optional Position** |
|
||||
| **14** | **2025-01-26** | **Popup: No close button (X), no ESC/outside-click - only saves with validation** |
|
||||
| **14** | **2025-01-26** | **Modern, clean popup design matching EnvelopeViewer theme (purple gradients, rounded inputs)** |
|
||||
| **14** | **2025-01-26** | **Implemented German-style professional signature rendering on PDF canvas** |
|
||||
| **14** | **2025-01-26** | **Click "Unterschreiben" button ? removes button, renders applied signature** |
|
||||
| **14** | **2025-01-26** | **Signature layout: Image + separator line + Name (bold) + Position + Place, Date** |
|
||||
| **14** | **2025-01-26** | **JavaScript: `pdfViewer.applySignature()` creates HTML overlay (230px box, #f8f9fa background)** |
|
||||
| **14** | **2025-01-26** | **German date format: dd.MM.yyyy (e.g., 26.01.2025) via `toLocaleDateString('de-DE')`** |
|
||||
| **14** | **2025-01-26** | **XSS protection: `escapeHtml()` function sanitizes user-provided text** |
|
||||
| **15** | **2025-01-26** | **Fixed: Applied signatures now only visible on their respective pages (display: none on other pages)** |
|
||||
| **15** | **2025-01-26** | **Fixed: `clearSignatureButtons()` now hides/shows applied signatures based on current page** |
|
||||
| **15** | **2025-01-26** | **Added signature navigation toolbar: "Nächste Unterschrift" / "Vorherige Unterschrift" buttons** |
|
||||
| **15** | **2025-01-26** | **Signature counter displays total/signed/unsigned counts (e.g., "2 / 5" with "3 offen" badge)** |
|
||||
| **15** | **2025-01-26** | **Implemented cross-page signature navigation (auto page change + scroll to signature)** |
|
||||
| **15** | **2025-01-26** | **JavaScript: `goToNextSignature()` and `goToPreviousSignature()` with Blazor callbacks** |
|
||||
| **15** | **2025-01-26** | **Fixed: `renderSignatureButtons()` now filters out already-applied signatures** |
|
||||
| **15** | **2025-01-26** | **Blazor callback: `OnPageChangedBySignatureNav()` triggers signature button re-rendering** |
|
||||
|
||||
---
|
||||
|
||||
## Layout Architecture (EnvelopeViewer)
|
||||
|
||||
### HTML Structure
|
||||
@@ -685,14 +634,28 @@ button.style.left/top
|
||||
|
||||
### Signature Data Structure
|
||||
|
||||
**Captured Signature (`_capturedSignature`):**
|
||||
**Captured Signature (`SignatureCaptureDto`):**
|
||||
```csharp
|
||||
record SignatureCapture(
|
||||
string DataUrl, // base64 PNG: "data:image/png;base64,iVBORw0KG..."
|
||||
string FullName, // Required: "Max Mustermann"
|
||||
string Position, // Optional: "Geschäftsführer" (can be empty)
|
||||
string Place // Required: "Berlin"
|
||||
);
|
||||
// Model: EnvelopeGenerator.ReceiverUI/Models/SignatureCaptureDto.cs
|
||||
public sealed record SignatureCaptureDto
|
||||
{
|
||||
public required string DataUrl { get; init; } // base64 PNG: "data:image/png;base64,iVBORw0KG..."
|
||||
public required string FullName { get; init; } // Required: "Max Mustermann"
|
||||
public string Position { get; init; } = string.Empty; // Optional: "Geschäftsführer"
|
||||
public required string Place { get; init; } // Required: "Berlin"
|
||||
}
|
||||
|
||||
// Usage in components:
|
||||
SignatureCaptureDto? _capturedSignature;
|
||||
|
||||
// Initialization with object initializer (required properties):
|
||||
_capturedSignature = new SignatureCaptureDto
|
||||
{
|
||||
DataUrl = signatureDataUrl,
|
||||
FullName = _signerFullName.Trim(),
|
||||
Position = _signerPosition.Trim(),
|
||||
Place = _signaturePlace.Trim()
|
||||
};
|
||||
```
|
||||
|
||||
**Applied Signature (HTML Overlay):**
|
||||
|
||||
Reference in New Issue
Block a user