Migrate PDF.js to DevExpress DxPdfViewer

Transitioned PDF rendering in `EnvelopeReceiverPage.razor`
from `PDF.js` to `DevExpress DxPdfViewer`. Updated code
and documentation to reflect the verified API of
`DevExpress.Blazor.PdfViewer` v25.2.3, addressing its
limitations (e.g., lack of `GoToPageAsync`, `PageNumberChanged`).

Implemented `CustomizeToolbar` for navigation/zoom controls
and manual state tracking for `_currentPage` and `_viewerZoomLevel`.
Replaced JavaScript interop for page count with the `PageCount`
property. Retained the custom thumbnail sidebar due to API
constraints.

Added temporary debug tools for DOM analysis and navigation
testing. Updated `TESTING_CHECKLIST.md` and added
`DEVEXPRESS_V25_LIMITATIONS.md` to document the new strategy,
API limitations, and testing scenarios. Cross-page signature
navigation implemented with state updates, though visible
page changes remain manual.

Prepared for future improvements while ensuring functional
migration to `DxPdfViewer`.
This commit is contained in:
2026-06-30 16:12:05 +02:00
parent a10ee590c9
commit 99fbb33f1c
5 changed files with 1009 additions and 23 deletions

161
TESTING_CHECKLIST.md Normal file
View File

@@ -0,0 +1,161 @@
# DevExpress v25.2.3 - Testing Checklist
> **Important:** This checklist has been updated according to the verified real API for v25.2.3.
> `GoToPageAsync()`, `PageNumberChanged`, `ZoomLevelChanged`, `ToolbarVisible` do NOT exist.
## Build Status
- **Build:** Successful
- **DevExpress Version:** 25.2.3
- **Strategy:** `CustomizeToolbar` + manual state tracking
---
## Test Scenarios
### 1. PDF Loading
- [ ] PDF document loads successfully
- [ ] DevExpress PdfViewer displays the document
- [ ] `_pdfViewer.PageCount > 0` check passes
- [ ] `_totalPages = _pdfViewer.PageCount` gets correct value (no JS call needed)
- [ ] `_pdfLoaded = true` is set
- [ ] Toolbar is visible and shows correct page count (e.g., "Page 1 / 5")
- [ ] Zoom level displays correctly (e.g., "150%") if `_viewerZoomLevel = 1.5`
### 2. CustomizeToolbar Navigation
- [ ] **Previous Page button** (◀) works and updates page counter
- [ ] **Next Page button** (▶) works and updates page counter
- [ ] Previous button is **disabled on page 1**
- [ ] Next button is **disabled on last page**
- [ ] Page counter updates correctly (e.g., "Page 2 / 5")
- [ ] Each navigation button's Click handler calls `RenderSignatureButtonsAsync()`
### 3. CustomizeToolbar Zoom
- [ ] **Zoom In button** (+) increases zoom
- [ ] **Zoom Out button** () decreases zoom
- [ ] `_viewerZoomLevel = _currentZoom / 100d` is calculated (150 → 1.5)
- [ ] Viewer does NOT display **"15000%"** (incorrect value detection)
- [ ] Zoom is constrained to 50% - 300% range
- [ ] PDF viewer zoom level changes visually
### 4. Signature Overlay Rendering
- [ ] **Signature placeholders** appear on correct pages
- [ ] Overlays are positioned correctly over the PDF
- [ ] Overlays **re-render after page changes**
- [ ] Overlays **re-render after zoom changes**
- [ ] Overlay sizes scale with zoom level
### 5. Signature Navigation
- [ ] Custom signature toolbar is visible (if signatures exist)
- [ ] Previous/Next signature buttons work
- [ ] Signature counter shows correct values (e.g., "0 / 3")
- [ ] "X open" badge shows unsigned count
- [ ] **Cross-page navigation:** `_currentPage` updates and overlays refresh
- [ ]**Known limitation:** DxPdfViewer visible page cannot be changed programmatically
### 6. Thumbnail Sidebar
- [ ] Thumbnails render (may take a few seconds)
- [ ] Thumbnail click **updates `_currentPage` state**
- [ ] Thumbnail click **refreshes overlays**
- [ ]**Known limitation:** Thumbnail click does not navigate DevExpress viewer
- [ ] Active thumbnail is highlighted correctly
### 7. Signature Capture & Application
- [ ] Signature popup opens on first load (if no cache)
- [ ] Draw signature works
- [ ] Text signature works
- [ ] Image upload signature works
- [ ] Clicking signature placeholder applies signature
- [ ] Applied signature overlays are positioned correctly
- [ ] Counter updates after signature applied (e.g., "1 / 3")
### 8. Known Limitations (v25.2.3 API Limit)
- [ ]**User cannot scroll PDF to change pages** (only CustomizeToolbar buttons)
- [ ] ⚠ Thumbnail clicks do not navigate viewer (only update state)
- [ ] ⚠ Browser zoom gestures do not trigger overlay updates
- [ ] ✓ Custom toolbar buttons correctly trigger overlay updates
- [ ]`_pdfViewer.PageCount` eliminates need for JS `getTotalPages()` call
- [ ]`ZoomLevel = _currentZoom / 100d` calculates correct zoom factor
---
## Common Issues
### Issue: Toolbar not visible
**Reason:** `_pdfLoaded = false` or `_totalPages = 0`
**Solution:** In `OnAfterRenderAsync`, check `_pdfViewer.PageCount > 0`, set `_pdfLoaded = true`
```csharp
if (_pdfViewer is not null && _pdfViewer.PageCount > 0)
{
_totalPages = _pdfViewer.PageCount; // no JS call needed
_pdfLoaded = true;
await InvokeAsync(StateHasChanged);
}
```
### Issue: Signature overlays not visible
**Reason:** `RenderSignatureButtonsAsync()` not called after page/zoom change
**Solution:** Verify each button Click handler in `OnCustomizeToolbar` calls `RenderSignatureButtonsAsync()`
### Issue: Page navigation not working
**Reason:** `OnCustomizeToolbar` button Click lambdas not updating `_currentPage`
**Solution:** Check that each button updates `_currentPage` and calls `StateHasChanged()` and `RenderSignatureButtonsAsync()`
### Issue: Zoom not working or showing "15000%"
**Reason:** Incorrect value assigned to `_viewerZoomLevel`
**Solution:** `_viewerZoomLevel = _currentZoom / 100d` ZoomLevel takes **factor**, not percentage
```csharp
// CORRECT
_currentZoom = 150; // UI display: "150%"
_viewerZoomLevel = 150 / 100d; // Pass to DxPdfViewer: 1.5
// WRONG
_viewerZoomLevel = 150; // DxPdfViewer displays "15000%"
```
### Issue: Total page count is 0
**Reason:** JS call made before timing or fails
**Solution:** Use `_pdfViewer.PageCount` directly, no need for `pdfViewer.getTotalPages()` JS call
---
## Success Criteria
**Minimum working functionality:**
- PDF loads and displays
- `_totalPages = _pdfViewer.PageCount` gets correct page count
- Custom toolbar navigation works (previous/next/zoom)
- Signature overlays render on current page
- Signature capture and application works
- Overlays update after navigation/zoom
**Known acceptable limitations (v25.2.3 API limit):**
- Thumbnail clicks do not navigate viewer (only update state)
- User scroll/native toolbar navigation does not update C# state
- Cross-page signature navigation is limited
---
## Next Steps If All Tests Pass
1. Remove debug toolbar button (if present)
2. Clean up unused code comments
3. Update user documentation about navigation limitations
---
## Architecture Reference: Verified v25.2.3 API
| Property | Access | Usage |
|----------|--------|-------|
| `DocumentContent` | `[Parameter]` GET/SET | Feed PDF with `byte[]` |
| `ZoomLevel` | `[Parameter]` GET/SET | **Factor**: `_currentZoom / 100d` |
| `IsSinglePagePreview` | `[Parameter]` GET/SET | `true` = single page mode |
| `PageCount` | GET only | Total pages no JS needed |
| `ActivePageIndex` | GET only | Active page index (0-based) no SET |
| `CssClass` | `[Parameter]` GET/SET | Assign CSS class |
| `SizeMode` | `[Parameter]` GET/SET | `Small` / `Medium` / `Large` |
| `DocumentName` | `[Parameter]` GET/SET | Download filename |
**Not available:** `GoToPageAsync()`, `PageNumberChanged`, `ZoomLevelChanged`, `ToolbarVisible`