Add export feature UI to EnvelopeSenderPage (placeholder)

Introduced a new export feature to the EnvelopeSenderPage, including a dropdown for selecting export formats (XLSX, CSV, PDF) and a checkbox to export only selected rows. Added a placeholder export button ("Exportieren") that is currently disabled, with export logic to be implemented in a future phase.

Added private fields `_selectedExportFormat` and `_exportSelectedRowsOnly` to manage the export state. Implemented `IsExportDisabled()` to control button availability and a placeholder method `ExportSelectedFormatPlaceholderAsync()`.

Updated `sender-page.css` to style the export feature, including the export button, dropdown, and checkbox. Added theme-specific styles for "purple" and "blazing-dark" themes. Adjusted toolbar element order to position the export group before the logout button.
This commit is contained in:
2026-09-24 18:11:37 +02:00
parent b15f95755c
commit 18df6221c9
2 changed files with 139 additions and 1 deletions

View File

@@ -104,6 +104,31 @@
Vorschau
</button>
<div class="sender-export-group" title="Export der aktuellen Tabellenansicht">
<label class="sender-export-label" for="sender-export-format">Format</label>
<select id="sender-export-format" class="sender-export-format" @bind="_selectedExportFormat" aria-label="Exportformat auswählen">
<option value="xlsx">XLSX</option>
<option value="csv">CSV</option>
<option value="pdf">PDF</option>
</select>
<label class="sender-export-selected">
<input type="checkbox" @bind="_exportSelectedRowsOnly" />
<span>Nur ausgewählte</span>
</label>
<button class="sender-btn sender-btn--export"
@onclick="ExportSelectedFormatPlaceholderAsync"
disabled="@IsExportDisabled()"
title="Export wird in Phase 2 aktiviert">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M.5 9.9a.5.5 0 0 1 .5.5V13a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.6a.5.5 0 0 1 1 0V13a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2.6a.5.5 0 0 1 .5-.5z" />
<path d="M5.354 6.146a.5.5 0 0 1 .707 0L7.5 7.586V.5a.5.5 0 0 1 1 0v7.086l1.439-1.44a.5.5 0 0 1 .707.708l-2.293 2.293a.5.5 0 0 1-.707 0L5.354 6.854a.5.5 0 0 1 0-.708z" />
</svg>
Exportieren
</button>
</div>
<button class="sender-btn sender-btn--logout" @onclick="LogoutAsync" disabled="@_isLoggingOut" title="Abmelden">
@if (_isLoggingOut)
{
@@ -514,6 +539,10 @@
private byte[]? _previewPdfBytes = null;
private string? _previewErrorMessage = null;
// Phase 6e (step 1): UI state only. Export logic is added in step 2.
private string _selectedExportFormat = "xlsx";
private bool _exportSelectedRowsOnly = false;
// Stable keys used to store/restore each grid's layout in UserPreferences.GridLayouts
private const string GridKeyActive = "sender.active-envelopes";
private const string GridKeyCompleted = "sender.completed-envelopes";
@@ -572,6 +601,19 @@
await LoadEnvelopesAsync();
}
bool IsExportDisabled()
{
if (_isLoading)
return true;
return _exportSelectedRowsOnly && _selectedEnvelope is null;
}
Task ExportSelectedFormatPlaceholderAsync()
{
return Task.CompletedTask;
}
void CreateEnvelope()
{
Navigation.NavigateTo("/sender/editor");
@@ -753,4 +795,4 @@
var json = JsonSerializer.Serialize(e.Layout);
await UserPreferencesService.SaveGridLayoutAsync(GridKeyCompleted, json);
}
}
}

View File

@@ -136,6 +136,59 @@
min-width: 38px;
}
.sender-btn--export {
padding-inline: 0.875rem;
}
.sender-export-group {
display: inline-flex;
align-items: center;
gap: 0.45rem;
padding: 0.35rem 0.5rem;
border: 1px solid rgba(126, 34, 206, 0.18);
border-radius: 10px;
background: rgba(126, 34, 206, 0.04);
}
.sender-export-label {
font-size: 0.72rem;
font-weight: 700;
color: #4b5563;
letter-spacing: 0.01em;
white-space: nowrap;
}
.sender-export-format {
height: 32px;
min-width: 84px;
padding: 0 0.5rem;
border: 1px solid rgba(126, 34, 206, 0.25);
border-radius: 8px;
background: #fff;
color: #1e293b;
font-size: 0.8rem;
font-weight: 600;
outline: none;
}
.sender-export-format:focus {
border-color: rgba(126, 34, 206, 0.55);
box-shadow: 0 0 0 2px rgba(126, 34, 206, 0.12);
}
.sender-export-selected {
display: inline-flex;
align-items: center;
gap: 0.35rem;
font-size: 0.74rem;
color: #4b5563;
white-space: nowrap;
}
.sender-export-selected input[type="checkbox"] {
margin: 0;
}
.sender-content {
flex: 1;
min-height: 0;
@@ -314,6 +367,14 @@
justify-content: flex-start;
}
.sender-export-group {
order: 98;
}
.sender-btn--logout {
order: 99;
}
.sender-title {
font-size: 1.125rem;
}
@@ -373,6 +434,20 @@
box-shadow: 0 4px 12px rgba(147, 51, 234, 0.22);
}
[data-sf-theme="purple"] .sender-export-group {
border-color: rgba(147, 51, 234, 0.28);
background: rgba(147, 51, 234, 0.08);
}
[data-sf-theme="purple"] .sender-export-format {
border-color: rgba(147, 51, 234, 0.36);
}
[data-sf-theme="purple"] .sender-export-format:focus {
border-color: rgba(147, 51, 234, 0.6);
box-shadow: 0 0 0 2px rgba(147, 51, 234, 0.14);
}
[data-sf-theme="purple"] .sender-tabs {
border-bottom-color: rgba(147, 51, 234, 0.12);
}
@@ -445,6 +520,27 @@
border-color: transparent;
}
[data-sf-theme="blazing-dark"] .sender-export-group {
border-color: rgba(129, 140, 248, 0.26);
background: rgba(99, 102, 241, 0.08);
}
[data-sf-theme="blazing-dark"] .sender-export-label,
[data-sf-theme="blazing-dark"] .sender-export-selected {
color: rgba(255, 255, 255, 0.72);
}
[data-sf-theme="blazing-dark"] .sender-export-format {
background: rgba(255, 255, 255, 0.08);
color: rgba(255, 255, 255, 0.9);
border-color: rgba(129, 140, 248, 0.35);
}
[data-sf-theme="blazing-dark"] .sender-export-format:focus {
border-color: rgba(129, 140, 248, 0.58);
box-shadow: 0 0 0 2px rgba(129, 140, 248, 0.16);
}
[data-sf-theme="blazing-dark"] .sender-grid-container {
background: rgba(15, 20, 40, 0.95);
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.06);