Add conditional rendering for PDF upload readiness

Introduced `_isPageReady` state to manage page readiness and conditionally render the PDF upload button. Disabled the upload functionality and added a loading spinner when the page is not ready. Updated `OnPdfFileSelectedAsync` to prevent uploads before readiness.

Modified the "No Document Loaded" section to use `_isPageReady` for conditional rendering. Added `SENDER_SAVE_EDIT_MIGRATION_PLAN.md` to the solution. Improved user experience with better feedback during loading states.
This commit is contained in:
2026-09-29 21:41:03 +02:00
parent 776700b247
commit 2434f67627
2 changed files with 57 additions and 20 deletions

View File

@@ -159,18 +159,29 @@
</button>
@* PDF Upload *@
<label class="pdf-toolbar__btn"
title='@L("UploadPdf", "PDF hochladen")'
style="cursor: pointer; display: inline-flex; align-items: center; gap: 0.3rem; padding: 0.3rem 0.75rem; font-size: 0.75rem; font-weight: 500;">
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" viewBox="0 0 16 16">
<path d="M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2.5a.5.5 0 0 1 .5-.5z" />
<path d="M7.646 1.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1-.708.708L8.5 2.707V11.5a.5.5 0 0 1-1 0V2.707L5.354 4.854a.5.5 0 1 1-.708-.708l3-3z" />
</svg>
@L("UploadPdf", "PDF hochladen")
<InputFile OnChange="OnPdfFileSelectedAsync"
accept=".pdf"
style="display: none;" />
</label>
@if (_isPageReady)
{
<label class="pdf-toolbar__btn"
title='@L("UploadPdf", "PDF hochladen")'
style="cursor: pointer; display: inline-flex; align-items: center; gap: 0.3rem; padding: 0.3rem 0.75rem; font-size: 0.75rem; font-weight: 500;">
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" viewBox="0 0 16 16">
<path d="M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2.5a.5.5 0 0 1 .5-.5z" />
<path d="M7.646 1.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1-.708.708L8.5 2.707V11.5a.5.5 0 0 1-1 0V2.707L5.354 4.854a.5.5 0 1 1-.708-.708l3-3z" />
</svg>
@L("UploadPdf", "PDF hochladen")
<InputFile OnChange="OnPdfFileSelectedAsync"
accept=".pdf"
style="display: none;" />
</label>
}
else
{
<span class="pdf-toolbar__btn"
style="opacity:0.6; cursor:not-allowed; display: inline-flex; align-items: center; gap: 0.3rem; padding: 0.3rem 0.75rem; font-size: 0.75rem; font-weight: 500;">
<span class="spinner-border spinner-border-sm" role="status" style="width:0.8rem;height:0.8rem;border-width:2px;"></span>
@L("Loading", "Wird geladen")…
</span>
}
@if (_pdfLoaded && _signatureFields.Count > 0)
{
@@ -256,14 +267,24 @@
<p class="text-white mb-4" style="opacity: 0.75; font-size: 0.85rem;">
@L("SenderEditor_UploadPdfToPlaceFields", "Laden Sie eine PDF-Datei hoch, um Signaturfelder zu platzieren.")
</p>
<label class="btn btn-light btn-sm" style="cursor: pointer; font-weight: 500;">
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" class="me-1" viewBox="0 0 16 16">
<path d="M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2.5a.5.5 0 0 1 .5-.5z" />
<path d="M7.646 1.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1-.708.708L8.5 2.707V11.5a.5.5 0 0 1-1 0V2.707L5.354 4.854a.5.5 0 1 1-.708-.708l3-3z" />
</svg>
@L("UploadPdf", "PDF hochladen")
<InputFile OnChange="OnPdfFileSelectedAsync" accept=".pdf" style="display: none;" />
</label>
@if (_isPageReady)
{
<label class="btn btn-light btn-sm" style="cursor: pointer; font-weight: 500;">
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" class="me-1" viewBox="0 0 16 16">
<path d="M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2.5a.5.5 0 0 1 .5-.5z" />
<path d="M7.646 1.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1-.708.708L8.5 2.707V11.5a.5.5 0 0 1-1 0V2.707L5.354 4.854a.5.5 0 1 1-.708-.708l3-3z" />
</svg>
@L("UploadPdf", "PDF hochladen")
<InputFile OnChange="OnPdfFileSelectedAsync" accept=".pdf" style="display: none;" />
</label>
}
else
{
<button class="btn btn-light btn-sm" type="button" disabled>
<span class="spinner-border spinner-border-sm me-1" role="status" style="width:0.8rem;height:0.8rem;border-width:2px;"></span>
@L("Loading", "Wird geladen")…
</button>
}
</div>
</div>
}
@@ -468,6 +489,7 @@
// ── State ──
bool _pdfLoaded = false;
bool _isPageReady;
string _fileName = string.Empty;
string? _errorMessage;
byte[]? _originalPdfBytes; // Pristine upload — never modified, used as base for redraw
@@ -534,6 +556,17 @@
return;
}
protected override Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
_isPageReady = true;
StateHasChanged();
}
return Task.CompletedTask;
}
async Task LoadEnvelopeForEditAsync(int envelopeId)
{
if (_isLoadingEnvelopeForEdit)
@@ -622,6 +655,9 @@
// ── PDF upload ──
async Task OnPdfFileSelectedAsync(InputFileChangeEventArgs e)
{
if (!_isPageReady)
return;
_errorMessage = null;
var file = e.File;
if (file is null) return;