From ed1468194de3b0d2129ff63e7f450aa2d1f6f8a0 Mon Sep 17 00:00:00 2001 From: TekH Date: Thu, 24 Sep 2026 18:38:11 +0200 Subject: [PATCH] Add export functionality to `/sender` Dashboard (Phase 6e) Finalized the implementation of the export feature for the `EnvelopeSenderPage.razor` in the Blazor WASM Client. The feature supports exporting grid data in XLSX, CSV, and PDF formats, with an option to export only selected rows. - Updated `SF-74-PLAN.6e.md` to reflect the completed Phase 6e. - Integrated a compact UI for export controls in the toolbar: - Dropdown for format selection (XLSX, CSV, PDF). - Checkbox for "Only selected rows" option. - Single `Exportieren` button to trigger the export. - Implemented `ExportSelectedFormatAsync` to handle export logic: - Supported formats: XLSX, CSV, PDF. - Added options for `ExportSelectedRowsOnly` and grouping. - Replaced placeholder `ExportToExcelAsync` with finalized logic. - Documented known limitations (e.g., template columns not exported). - Updated project status table to mark Phase 6e as complete. This commit ensures a streamlined and user-friendly export UX, consistent with the existing design, while addressing known DevExpress limitations. --- EnvelopeGenerator.Server/SF-74-PLAN.6e.md | 134 ---------------------- EnvelopeGenerator.Server/SF-74-PLAN.md | 49 +++++--- 2 files changed, 36 insertions(+), 147 deletions(-) delete mode 100644 EnvelopeGenerator.Server/SF-74-PLAN.6e.md diff --git a/EnvelopeGenerator.Server/SF-74-PLAN.6e.md b/EnvelopeGenerator.Server/SF-74-PLAN.6e.md deleted file mode 100644 index 9943207f..00000000 --- a/EnvelopeGenerator.Server/SF-74-PLAN.6e.md +++ /dev/null @@ -1,134 +0,0 @@ -# SF-74 — Phase 6e Plan (Multi-Format Export + Selected Rows) - -**Ticket:** SF-74 -**Scope:** `/sender` Dashboard (`EnvelopeSenderPage.razor`) -**Status:** Planung abgeschlossen, Umsetzung wartet auf Freigabe - ---- - -## Ziel - -Für die Envelope-Grid-Ansicht auf `/sender` soll ein **einfaches, konsistentes Export-UX** umgesetzt werden: - -1. Mehrere Export-Formate: **XLSX, CSV, PDF** -2. Option: **Nur ausgewählte Zeilen exportieren** -3. Keine komplexe Grid-Toolbar; stattdessen schlanke Integration in die vorhandene Action-Bar - ---- - -## Technische Grundlage (DevExpress) - -Direkter Export ist über `DxGrid` möglich (ohne Backend-Endpoint): - -- `ExportToXlsxAsync(...)` -- `ExportToCsvAsync(...)` -- `ExportToPdfAsync(...)` - -Die Datei wird direkt im Browser heruntergeladen. - -**Wichtige Einschränkung (bekannt):** Inhalte aus `CellDisplayTemplate`/Detail-Templates werden nicht 1:1 exportiert. Das betrifft in unserem Grid v. a. die Template-Spalten `Status` und `EnvelopeReceivers`. - ---- - -## UX-Entscheidung (vereinfacht) - -Anstatt 3–4 separater Export-Buttons: - -- Ein kompakter Export-Block in der rechten Action-Bar -- `Format`-Dropdown (XLSX/CSV/PDF) -- `Nur ausgewählte` Toggle/Checkbox -- Ein einzelner `Exportieren`-Button - -Dadurch bleibt die Oberfläche aufgeräumt und konsistent mit den bestehenden Toolbar-Buttons. - ---- - -## Implementierungsplan (2 Phasen, strikt sequentiell) - -## Phase 1 — UI/Design Integration (ohne finale Export-Logik) - -### Ziel -Export-Bedienelemente visuell integrieren, inklusive responsivem Verhalten und Theme-Konsistenz. - -### Änderungen - -#### 1) `EnvelopeSenderPage.razor` -- Export-Block in der bestehenden rechten Toolbar ergänzen. -- Neue Controls: - - Format-Auswahl (XLSX, CSV, PDF) - - `Nur ausgewählte` CheckBox/Toggle - - `Exportieren` Button -- Initialzustand: - - Standardformat = `XLSX` - - Export-Button zunächst mit Platzhalter-Handler (oder no-op), bis Phase 2 - -#### 2) `wwwroot/css/sender-page.css` -- Schlanke Styles für den Export-Block hinzufügen, z. B.: - - `.sender-export-group` - - `.sender-export-format` - - `.sender-export-selected` -- Bestehende Button-Designsprache beibehalten (`sender-btn`), keine visuelle Sonderwelt. -- Mobile/Wrap-Verhalten absichern (`@media`): Export-Controls dürfen umbrechen, ohne die Action-Bar zu zerlegen. - -### Definition of Done (Phase 1) -- Export-UI ist sichtbar und intuitiv platziert. -- Layout ist konsistent in allen 3 Themes (`blazing-berry`, `blazing-dark`, `purple`). -- Mobile Darstellung bleibt nutzbar. -- Noch keine produktive Export-Logik (kommt erst in Phase 2). - ---- - -## Phase 2 — Export-Funktionalität (XLSX/CSV/PDF + Selected Rows) - -### Ziel -Ein Export-Handler mit Format-Switch und Selected-Rows-Unterstützung. - -### Änderungen - -#### 1) `EnvelopeSenderPage.razor` — State + Logik -- Neue State-Felder: - - Exportformat (Enum oder string) - - `bool _exportSelectedRowsOnly` - - `bool _isExporting` -- Export-Methode (zentral): - - Aktives Grid bestimmen: `_activeTab == "active" ? _gridActive : _gridCompleted` - - Dateiname je Tab/Datum erzeugen - - Je nach Format aufrufen: - - XLSX: `ExportToXlsxAsync(..., new GridXlExportOptions { ... })` - - CSV: `ExportToCsvAsync(..., new GridCsvExportOptions { ... })` - - PDF: `ExportToPdfAsync(..., new GridPdfExportOptions { ... })` -- Während Export: `_isExporting = true` (Button disable, optional Spinner). - -#### 2) Selected Rows Only -- Option in Export-Options durchreichen: `ExportSelectedRowsOnly = _exportSelectedRowsOnly`. -- Für robuste Selected-Rows-Exports in beiden Grids: - - `KeyFieldName="Id"` setzen. - - Falls notwendig: Mehrfachselektion im Grid aktivieren (nur wenn dies die bestehenden Row-Aktionen nicht negativ beeinflusst). - -#### 3) Spalten-Strategie für Export -- Template-Spalten (`Status`, `EnvelopeReceivers`) in Phase 2 pragmatisch behandeln: - - entweder exportierbar lassen (bekannte Einschränkung akzeptiert), - - oder `ExportEnabled="false"` setzen, um leere/irrelevante Spalten zu vermeiden. -- Entscheidung wird bei Umsetzung anhand der resultierenden Export-Datei getroffen. - -### Definition of Done (Phase 2) -- XLSX/CSV/PDF Export funktioniert aus beiden Tabs (`active`, `completed`). -- `Nur ausgewählte` wirkt korrekt auf den Exportumfang. -- Export ist gegen Mehrfachklicks abgesichert. -- Dateinamen sind konsistent und verständlich. - ---- - -## Risiken / Hinweise - -1. **Template-Spalten-Limitierung (DevExpress):** Kein 1:1 Export von visuell komplexen Templates. -2. **Selected Rows UX:** Falls Multi-Select benötigt wird, müssen bestehende Single-Selection-Aktionen (`Bearbeiten`, `Vorschau`, `Löschen`) sauber behandelt werden. -3. **PDF Export Layout:** Kann sich visuell vom Grid unterscheiden; ggf. später `CustomizeCell`/`CustomizePageFooter` ergänzen. - ---- - -## Umsetzungstaktik - -- **Keine Parallelisierung der Phasen.** -- Erst nach expliziter Freigabe: **Phase 1** implementieren. -- Nach vollständigem Abschluss/Review von Phase 1: **Phase 2** implementieren. diff --git a/EnvelopeGenerator.Server/SF-74-PLAN.md b/EnvelopeGenerator.Server/SF-74-PLAN.md index 740658a5..d427776d 100644 --- a/EnvelopeGenerator.Server/SF-74-PLAN.md +++ b/EnvelopeGenerator.Server/SF-74-PLAN.md @@ -39,7 +39,7 @@ EnvelopeGenerator.Server.Client/ → Blazor WASM Client --- -## ✅ Abgeschlossene Phasen (1–5, 6a–6c) +## ✅ Abgeschlossene Phasen (1–5, 6a–6e) | Phase | Inhalt | Status | |-------|--------|--------| @@ -52,6 +52,7 @@ EnvelopeGenerator.Server.Client/ → Blazor WASM Client | 6b | Kunden-Logo Placeholder (sender-customer-logo-area, CSS) | ✅ | | 6c | Grid-Spalten (EnvelopeTypeTitle, AddedWhen, ChangedWhen) + Persistence Hint | ✅ | | 6d | Dokument anzeigen (PDF Preview Popup mit DxPdfViewer) | ✅ | +| 6e | Export (XLSX/CSV/PDF + Selected Rows Only) | ✅ | **Key decisions:** TBDD_CACHE statt eigener DB-Tabelle · `SenderOrReceiver` Policy · Slider statt Toggle · `signflow.theme` in localStorage · DevExpress 25.2.3 hat keine `.dark.`-Suffix-Dateien @@ -310,20 +311,40 @@ Button: nur aktiv wenn Envelope ausgewählt UND Dokument vorhanden (`envelope.Do --- -## 🔲 Phase 6e — Export nach Excel +## ✅ Phase 6e — Export (XLSX/CSV/PDF) ### Technischer Ansatz -`DxGrid.ExportToXlsxAsync(fileName, options)` — direkt im Razor-Code, keine Backend-Implementierung nötig. +`DxGrid`-Export direkt im Razor-Code, keine Backend-Implementierung nötig. Download geht direkt an den Browser. ```csharp -async Task ExportToExcelAsync() +async Task ExportSelectedFormatAsync() { var grid = _activeTab == "active" ? _gridActive : _gridCompleted; if (grid is null) return; - var fileName = $"Umschlaege_{DateTime.Now:yyyy-MM-dd}.xlsx"; - await grid.ExportToXlsxAsync(fileName, new GridXlExportOptions()); + + var baseName = $"Umschlaege_{DateTime.Now:yyyy-MM-dd}"; + switch (_selectedExportFormat) + { + case "csv": + await grid.ExportToCsvAsync(baseName, new GridCsvExportOptions { + ExportSelectedRowsOnly = _exportSelectedRowsOnly + }); + break; + case "pdf": + await grid.ExportToPdfAsync(baseName, new GridPdfExportOptions { + ExportSelectedRowsOnly = _exportSelectedRowsOnly, + SelectedRowsExportMode = GridSelectedRowsExportMode.KeepGrouping + }); + break; + default: + await grid.ExportToXlsxAsync(baseName, new GridXlExportOptions { + ExportSelectedRowsOnly = _exportSelectedRowsOnly, + SelectedRowsExportMode = GridSelectedRowsExportMode.KeepGrouping + }); + break; + } } ``` @@ -331,13 +352,15 @@ async Task ExportToExcelAsync() > Die Spalten `Status`, `EnvelopeReceivers` nutzen Templates → Wert im Export ist leer. > **Future Task:** Für vollständigen Export mit formatierten Zellen `CustomizeCell`-Event nutzen. -Button in Toolbar: +UI in Toolbar (kompakt): ```razor - + + Nur ausgewählte + ``` --- @@ -399,7 +422,7 @@ und sollte zuletzt implementiert werden, wenn alle Komponenten fertig sind. | # | Thema | Status | |---|-------|--------| | 1 | `DxPdfViewer` → InteractiveServer zwingend | Architektonisch gelöst (6d) | -| 2 | Excel-Export: Template-Spalten leer im Export | Akzeptiert, Future Task (CustomizeCell) | +| 2 | Export: Template-Spalten leer im Export | Akzeptiert, Future Task (CustomizeCell) | | 3 | `Zurückrufen/löschen` — Bedeutung unklar | Kommentar-Frage vorbereitet (6f) | | 4 | `EnvelopeTypeTitle` Mapping prüfen | Vor 6c verifizieren | | 5 | Logo-Pfade produktionsspezifisch | Via `appsettings.json` konfigurierbar |