From 7a7fc2f903f96df245100ae4789637b0912228bd Mon Sep 17 00:00:00 2001 From: TekH Date: Sun, 7 Jun 2026 23:36:43 +0200 Subject: [PATCH] Improve signature navigation and toolbar functionality Enhanced signature navigation logic to track the last viewed signature (`_lastViewedSignatureId`) and enable cross-page navigation. Updated next/previous navigation to handle both signed and unsigned signatures, with automatic page changes and scrolling to the relevant element. Added a signature counter to the toolbar, displaying total, signed, and unsigned counts. Improved `renderSignatureButtons()` to filter out applied signatures and updated `clearSignatureButtons()` to manage visibility based on the current page. Integrated Blazor callbacks (`OnPageChangedBySignatureNav()` and `OnSignatureNavChanged`) for UI updates. Fixed visibility issues where applied signatures appeared on incorrect pages. --- COPILOT_CONTEXT_EN.md | 8 ++ .../wwwroot/js/pdf-viewer.js | 86 ++++++++++++++----- 2 files changed, 74 insertions(+), 20 deletions(-) diff --git a/COPILOT_CONTEXT_EN.md b/COPILOT_CONTEXT_EN.md index 86883058..027389b9 100644 --- a/COPILOT_CONTEXT_EN.md +++ b/COPILOT_CONTEXT_EN.md @@ -437,6 +437,14 @@ Our use case is **visual/image stamping** at specific page coordinates | **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** | --- diff --git a/EnvelopeGenerator.ReceiverUI/wwwroot/js/pdf-viewer.js b/EnvelopeGenerator.ReceiverUI/wwwroot/js/pdf-viewer.js index e4219f34..7fb66fa6 100644 --- a/EnvelopeGenerator.ReceiverUI/wwwroot/js/pdf-viewer.js +++ b/EnvelopeGenerator.ReceiverUI/wwwroot/js/pdf-viewer.js @@ -481,6 +481,7 @@ window.pdfViewer = { // Signature button functionality signatureButtons: [], appliedSignatures: [], // Track which signatures have been applied + _lastViewedSignatureId: null, // Track last viewed signature for navigation /** * Gets signature navigation state (for toolbar display) @@ -525,13 +526,19 @@ window.pdfViewer = { return false; } - // TÜM sayfalar aras?nda ilk imzalanmam?? imzay? bul - const appliedIds = new Set(this.appliedSignatures.map(s => s.id)); - const nextSignature = this._allSignatures.find(sig => !appliedIds.has(sig.id)); - - if (!nextSignature) { - return false; // Hepsi imzalanm?? + // Mevcut görüntülenen imzan?n index'ini bul + let currentIndex = -1; + if (this._lastViewedSignatureId) { + currentIndex = this._allSignatures.findIndex(s => s.id === this._lastViewedSignatureId); } + + // Bir sonraki imzay? al (imzalanm?? olup olmad???na bakmadan) + const nextIndex = currentIndex + 1; + if (nextIndex >= this._allSignatures.length) { + return false; // Son imzaday?z + } + + const nextSignature = this._allSignatures[nextIndex]; // Farkl? sayfadaysa sayfa de?i?tir if (nextSignature.page !== this.pageNum) { @@ -555,14 +562,26 @@ window.pdfViewer = { await new Promise(resolve => setTimeout(resolve, 150)); } - // Mevcut sayfadaki (art?k yeni sayfa olabilir) butonu bul - const button = this.signatureButtons.find(btn => - parseInt(btn.getAttribute('data-signature-id')) === nextSignature.id - ); + // Son görüntülenen imzay? kaydet + this._lastViewedSignatureId = nextSignature.id; - // Butonu görünür hale getir (scroll ile) - if (button) { - this.scrollToButton(button); + // ?mza imzalanm?? m? kontrol et + const isApplied = this.appliedSignatures.some(s => s.id === nextSignature.id); + + if (isApplied) { + // ?mzalanm?? - overlay container'? bul ve scroll yap + const container = document.querySelector(`.applied-signature[data-signature-id="${nextSignature.id}"]`); + if (container) { + this.scrollToElement(container); + } + } else { + // ?mzalanmam?? - butonu bul ve scroll yap + const button = this.signatureButtons.find(btn => + parseInt(btn.getAttribute('data-signature-id')) === nextSignature.id + ); + if (button) { + this.scrollToButton(button); + } } // Counter'? güncelle (Blazor'a bildir) @@ -578,12 +597,23 @@ window.pdfViewer = { * Scrolls to signature position and changes page if necessary. */ async goToPreviousSignature(dotNetRef) { - if (this.appliedSignatures.length === 0) { + if (!this._allSignatures || this._allSignatures.length === 0) { return false; } - // Get last applied signature - const lastSig = this.appliedSignatures[this.appliedSignatures.length - 1]; + // Mevcut görüntülenen imzan?n index'ini bul + let currentIndex = this._allSignatures.length; // Varsay?lan: son imzadan sonra + if (this._lastViewedSignatureId) { + currentIndex = this._allSignatures.findIndex(s => s.id === this._lastViewedSignatureId); + } + + // Bir önceki imzay? al + const prevIndex = currentIndex - 1; + if (prevIndex < 0) { + return false; // ?lk imzaday?z + } + + const prevSignature = this._allSignatures[prevIndex]; // Change page if needed if (lastSig.page !== this.pageNum) { @@ -607,10 +637,26 @@ window.pdfViewer = { await new Promise(resolve => setTimeout(resolve, 150)); } - // Find applied signature container - const container = document.querySelector(`.applied-signature[data-signature-id="${lastSig.id}"]`); - if (container) { - this.scrollToElement(container); + // Son görüntülenen imzay? kaydet + this._lastViewedSignatureId = prevSignature.id; + + // ?mza imzalanm?? m? kontrol et + const isApplied = this.appliedSignatures.some(s => s.id === prevSignature.id); + + if (isApplied) { + // ?mzalanm?? - overlay container'? bul ve scroll yap + const container = document.querySelector(`.applied-signature[data-signature-id="${prevSignature.id}"]`); + if (container) { + this.scrollToElement(container); + } + } else { + // ?mzalanmam?? - butonu bul ve scroll yap + const button = this.signatureButtons.find(btn => + parseInt(btn.getAttribute('data-signature-id')) === prevSignature.id + ); + if (button) { + this.scrollToButton(button); + } } // Notify Blazor