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:
@@ -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>
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user