Refactor PDF editor UI and improve PDF loading logic

Simplify and restructure conditional logic in `SenderPdfImageEditor.razor` for better readability and maintainability. Merge redundant `else` blocks and reorganize rendering logic for page previews and fields.

Enhance PDF loading and page preview generation in `SenderEditorPage.razor`. Add error handling for failed page rendering, log warnings, and ensure consistent `_pageCount` initialization based on available data.

These changes improve code clarity, robustness, and maintainability.
This commit is contained in:
2026-10-02 11:51:14 +02:00
parent 0eaa9ff08f
commit f86588551c
2 changed files with 77 additions and 58 deletions

View File

@@ -47,9 +47,7 @@
{ {
<div class="sender-image-editor__empty">@L("SenderEditor_NoPagesToDisplay", "Keine Seiten zur Anzeige verfügbar.")</div> <div class="sender-image-editor__empty">@L("SenderEditor_NoPagesToDisplay", "Keine Seiten zur Anzeige verfügbar.")</div>
} }
else else if (Pages.Count == 0 && !string.IsNullOrWhiteSpace(PdfDataUrl))
{
@if (Pages.Count == 0 && !string.IsNullOrWhiteSpace(PdfDataUrl))
{ {
<div class="sender-image-editor__native-preview" style="@GetZoomStyle()"> <div class="sender-image-editor__native-preview" style="@GetZoomStyle()">
<iframe class="sender-image-editor__native-frame" <iframe class="sender-image-editor__native-frame"
@@ -57,59 +55,60 @@
title="PDF Preview"></iframe> title="PDF Preview"></iframe>
</div> </div>
} }
else
{
<div class="sender-image-editor__pages" style="@GetZoomStyle()">
@for (var pageIndex = 0; pageIndex < PageCount; pageIndex++)
{
var pagePreview = pageIndex < Pages.Count ? Pages[pageIndex] : null;
var pageNumber = pagePreview?.PageNumber ?? (pageIndex + 1);
var widthPt = pagePreview?.WidthPt ?? 595.0;
var heightPt = pagePreview?.HeightPt ?? 842.0;
<div class="sender-image-editor__pages" style="@GetZoomStyle()"> <div class="sender-image-editor__page-block"
@for (var pageIndex = 0; pageIndex < PageCount; pageIndex++) data-editor-page="@pageNumber"
{ data-page-width-pt="@widthPt"
var pagePreview = pageIndex < Pages.Count ? Pages[pageIndex] : null; data-page-height-pt="@heightPt">
var pageNumber = pagePreview?.PageNumber ?? (pageIndex + 1); <div class="sender-image-editor__page-canvas"
var widthPt = pagePreview?.WidthPt ?? 595.0; data-editor-page-canvas="@pageNumber"
var heightPt = pagePreview?.HeightPt ?? 842.0; style="@GetPageCanvasStyle(widthPt, heightPt)">
@if (!string.IsNullOrWhiteSpace(pagePreview?.ImageDataUrl))
{
<img class="sender-image-editor__page-image"
src="@(pagePreview!.ImageDataUrl)"
alt="PDF Page @pageNumber"
draggable="false" />
}
else
{
<div class="sender-image-editor__page-placeholder">@L("SenderEditor_PageLabel", "Seite") @pageNumber</div>
}
<div class="sender-image-editor__page-block" @foreach (var field in Fields.Where(f => f.Page == pageNumber))
data-editor-page="@pageNumber" {
data-page-width-pt="@widthPt" <div class="sender-image-editor__field"
data-page-height-pt="@heightPt"> style="@GetFieldStyle(field, widthPt, heightPt)"
<div class="sender-image-editor__page-canvas" title="@field.ReceiverName"
data-editor-page-canvas="@pageNumber" @onmousedown="args => OnFieldMouseDownAsync(args, field)"
style="@GetPageCanvasStyle(widthPt, heightPt)"> @onmousedown:preventDefault="true"
@if (!string.IsNullOrWhiteSpace(pagePreview?.ImageDataUrl)) @onclick:stopPropagation="true">
{ <span class="sender-image-editor__field-label">@field.ReceiverName</span>
<img class="sender-image-editor__page-image" <button type="button"
src="@(pagePreview!.ImageDataUrl)" class="sender-image-editor__field-remove"
alt="PDF Page @pageNumber" title='@L("Delete", "Löschen")'
draggable="false" /> draggable="false"
} @onclick:stopPropagation="true"
else @onclick="() => RemoveField.InvokeAsync(field.Index)">
{ <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 16 16" fill="none" aria-hidden="true">
<div class="sender-image-editor__page-placeholder">@L("SenderEditor_PageLabel", "Seite") @pageNumber</div> <path d="M4 4L12 12M12 4L4 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" />
} </svg>
</button>
@foreach (var field in Fields.Where(f => f.Page == pageNumber)) </div>
{ }
<div class="sender-image-editor__field" </div>
style="@GetFieldStyle(field, widthPt, heightPt)"
title="@field.ReceiverName"
@onmousedown="args => OnFieldMouseDownAsync(args, field)"
@onmousedown:preventDefault="true"
@onclick:stopPropagation="true">
<span class="sender-image-editor__field-label">@field.ReceiverName</span>
<button type="button"
class="sender-image-editor__field-remove"
title='@L("Delete", "Löschen")'
draggable="false"
@onclick:stopPropagation="true"
@onclick="() => RemoveField.InvokeAsync(field.Index)">
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 16 16" fill="none" aria-hidden="true">
<path d="M4 4L12 12M12 4L4 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" />
</svg>
</button>
</div>
}
</div> </div>
</div> }
} </div>
</div>
} }
</div> </div>
</div> </div>

View File

@@ -826,11 +826,31 @@
_originalPdfBytes = document?.ByteData; _originalPdfBytes = document?.ByteData;
_pdfLoaded = _originalPdfBytes is { Length: > 0 }; _pdfLoaded = _originalPdfBytes is { Length: > 0 };
_pagePreviews = [];
_pageCount = _pagePreviews.Count > 0 if (_pdfLoaded)
? _pagePreviews.Count {
: EstimatePdfPageCount(_originalPdfBytes) try
?? Math.Max(1, _signatureFields.Select(f => f.Page).DefaultIfEmpty(1).Max()); {
_pagePreviews = (await PdfRenderService.RenderPagesAsync(_originalPdfBytes!))
.OrderBy(p => p.PageNumber)
.ToList();
}
catch (Exception renderEx)
{
Logger.LogWarning(renderEx, "Failed to render PDF page previews for envelope {EnvelopeId}. Falling back to native preview.", envelopeId);
_pagePreviews = [];
}
_pageCount = _pagePreviews.Count > 0
? _pagePreviews.Count
: 1;
}
else
{
_pagePreviews = [];
_pageCount = Math.Max(1, _signatureFields.Select(f => f.Page).DefaultIfEmpty(1).Max());
}
_fileName = $"Envelope-{envelopeId}.pdf"; _fileName = $"Envelope-{envelopeId}.pdf";
_pendingReceiverForPlacement = null; _pendingReceiverForPlacement = null;
_loadedEnvelopeId = envelopeId; _loadedEnvelopeId = envelopeId;