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:
@@ -159,18 +159,29 @@
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
@* PDF Upload *@
|
@* PDF Upload *@
|
||||||
<label class="pdf-toolbar__btn"
|
@if (_isPageReady)
|
||||||
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;">
|
<label class="pdf-toolbar__btn"
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" viewBox="0 0 16 16">
|
title='@L("UploadPdf", "PDF hochladen")'
|
||||||
<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" />
|
style="cursor: pointer; display: inline-flex; align-items: center; gap: 0.3rem; padding: 0.3rem 0.75rem; font-size: 0.75rem; font-weight: 500;">
|
||||||
<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 xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" viewBox="0 0 16 16">
|
||||||
</svg>
|
<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" />
|
||||||
@L("UploadPdf", "PDF hochladen")
|
<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" />
|
||||||
<InputFile OnChange="OnPdfFileSelectedAsync"
|
</svg>
|
||||||
accept=".pdf"
|
@L("UploadPdf", "PDF hochladen")
|
||||||
style="display: none;" />
|
<InputFile OnChange="OnPdfFileSelectedAsync"
|
||||||
</label>
|
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)
|
@if (_pdfLoaded && _signatureFields.Count > 0)
|
||||||
{
|
{
|
||||||
@@ -256,14 +267,24 @@
|
|||||||
<p class="text-white mb-4" style="opacity: 0.75; font-size: 0.85rem;">
|
<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.")
|
@L("SenderEditor_UploadPdfToPlaceFields", "Laden Sie eine PDF-Datei hoch, um Signaturfelder zu platzieren.")
|
||||||
</p>
|
</p>
|
||||||
<label class="btn btn-light btn-sm" style="cursor: pointer; font-weight: 500;">
|
@if (_isPageReady)
|
||||||
<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" />
|
<label class="btn btn-light btn-sm" style="cursor: pointer; font-weight: 500;">
|
||||||
<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 xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" class="me-1" viewBox="0 0 16 16">
|
||||||
</svg>
|
<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" />
|
||||||
@L("UploadPdf", "PDF hochladen")
|
<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" />
|
||||||
<InputFile OnChange="OnPdfFileSelectedAsync" accept=".pdf" style="display: none;" />
|
</svg>
|
||||||
</label>
|
@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>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@@ -468,6 +489,7 @@
|
|||||||
|
|
||||||
// ── State ──
|
// ── State ──
|
||||||
bool _pdfLoaded = false;
|
bool _pdfLoaded = false;
|
||||||
|
bool _isPageReady;
|
||||||
string _fileName = string.Empty;
|
string _fileName = string.Empty;
|
||||||
string? _errorMessage;
|
string? _errorMessage;
|
||||||
byte[]? _originalPdfBytes; // Pristine upload — never modified, used as base for redraw
|
byte[]? _originalPdfBytes; // Pristine upload — never modified, used as base for redraw
|
||||||
@@ -534,6 +556,17 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override Task OnAfterRenderAsync(bool firstRender)
|
||||||
|
{
|
||||||
|
if (firstRender)
|
||||||
|
{
|
||||||
|
_isPageReady = true;
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
async Task LoadEnvelopeForEditAsync(int envelopeId)
|
async Task LoadEnvelopeForEditAsync(int envelopeId)
|
||||||
{
|
{
|
||||||
if (_isLoadingEnvelopeForEdit)
|
if (_isLoadingEnvelopeForEdit)
|
||||||
@@ -622,6 +655,9 @@
|
|||||||
// ── PDF upload ──
|
// ── PDF upload ──
|
||||||
async Task OnPdfFileSelectedAsync(InputFileChangeEventArgs e)
|
async Task OnPdfFileSelectedAsync(InputFileChangeEventArgs e)
|
||||||
{
|
{
|
||||||
|
if (!_isPageReady)
|
||||||
|
return;
|
||||||
|
|
||||||
_errorMessage = null;
|
_errorMessage = null;
|
||||||
var file = e.File;
|
var file = e.File;
|
||||||
if (file is null) return;
|
if (file is null) return;
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ EndProject
|
|||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EnvelopeGenerator.Server", "EnvelopeGenerator.Server", "{BF1700D5-592E-4FFA-84E8-5480E289A1F0}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EnvelopeGenerator.Server", "EnvelopeGenerator.Server", "{BF1700D5-592E-4FFA-84E8-5480E289A1F0}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
EnvelopeGenerator.Server\publish.bat = EnvelopeGenerator.Server\publish.bat
|
EnvelopeGenerator.Server\publish.bat = EnvelopeGenerator.Server\publish.bat
|
||||||
|
SENDER_SAVE_EDIT_MIGRATION_PLAN.md = SENDER_SAVE_EDIT_MIGRATION_PLAN.md
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EnvelopeGenerator.Server", "EnvelopeGenerator.Server\EnvelopeGenerator.Server\EnvelopeGenerator.Server.csproj", "{4E6C54DA-576D-0955-2564-9EC890BB8279}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EnvelopeGenerator.Server", "EnvelopeGenerator.Server\EnvelopeGenerator.Server\EnvelopeGenerator.Server.csproj", "{4E6C54DA-576D-0955-2564-9EC890BB8279}"
|
||||||
|
|||||||
Reference in New Issue
Block a user