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