Phase 3: Avalonia-Bedienhuelle fuer Windows und Linux
Neues Projekt Predictalytics.Shell (Avalonia 12.1.1, net10.0) als plattformuebergreifender Ersatz fuer den WinForms-Host. Setzt auf dem in Phase 2 extrahierten Predictalytics.Hosting auf. Oberflaeche: - MainWindow mit Menue, Werkzeugleiste, Terminal-Tab, Einstellungen-Tab und Statusleiste. Die feste Fenstergroesse von 1886x1088 ist aufgeloest. - Terminal als ListBox ueber ObservableCollection mit Einfaerbung nach Loglevel. Ringpuffer statt des bisherigen kompletten Leerens bei 500 Zeilen. - Einstellungsansicht handgeschrieben als Ersatz fuer den PropertyGrid, den es in Avalonia nicht gibt: vier Gruppen, Passwortfelder, mehrzeiliges Textfeld fuer die Egress-Kanaele, ComboBox fuer den SSL-Modus. Gespeichert wird explizit statt bei jeder Einzeloperation. - LicenseWindow ersetzt den WinForms-LicenseDialog. - Dialogs.cs als schlanker Ersatz fuer MessageBox.Show, ohne Drittanbieter. Headless-Modus (--headless) im selben Binary: fuer Linux-Server ohne Desktop-Session. Die Argumentauswertung steht vor jeder Avalonia- Initialisierung, sonst stirbt der Prozess ohne X11 bevor der Schalter greift. Lizenz ueber PREDICTALYTICS_LICENSE_KEY statt Dialog, SIGTERM und SIGINT ueber PosixSignalRegistration fuer sauberes systemd-Stop. Exit-Codes: 0 planmaessig, 2 keine nutzbare Lizenz, 3 Fehler. Plattformdetails: Schrift-Fallbackkette fuers Terminal, Avalonia.Fonts.Inter als mitgelieferte UI-Schrift, UTF-8 fuer die Windows-Konsole im Headless-Modus. Die Avalonia-Basisklasse wird als global::Avalonia.Application angegeben: innerhalb von Predictalytics.* loest der kurze Name auf den eigenen Namespace Predictalytics.Application auf. Build: 0 Fehler, 0 Warnungen. Tests: 100 bestanden. Verifiziert: --headless laeuft bis zur Lizenzschranke und beendet sich mit Exit-Code 2; GUI startet und zeigt das Lizenzfenster. Das Hauptfenster konnte nicht geprueft werden, weil die hinterlegte Lizenz abgelaufen ist. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -298,7 +298,68 @@ ausschließlich UI-Code. `Predictalytics.Hosting` baut ohne Windows-Referenzen.
|
||||
|
||||
---
|
||||
|
||||
## 5. Phase 3 — Avalonia-Bedienhülle (4–6 PT)
|
||||
## 5. Phase 3 — Avalonia-Bedienhülle ✅ **erledigt (2026-08-07)**
|
||||
|
||||
**Abnahme:** `dotnet build` → 0 Fehler, 0 Warnungen. `dotnet test` → 100 bestanden.
|
||||
Beide Betriebsarten laufen an:
|
||||
|
||||
| Prüfung | Ergebnis |
|
||||
|---|---|
|
||||
| `Predictalytics.Shell.exe --headless` | Logging läuft, Lizenzprüfung greift, sauberer Abbruch mit **Exit-Code 2** und handlungsfähiger Meldung |
|
||||
| `Predictalytics.Shell.exe` (GUI) | startet, Lizenzfenster erscheint, kein Absturz |
|
||||
| Konsolen-Kodierung | UTF-8 explizit gesetzt — ohne das zeigt die Windows-Konsole nur Fragezeichen statt Rahmen und Emoji |
|
||||
|
||||
### ⚠️ Nicht verifiziert: das Hauptfenster
|
||||
|
||||
Die hinterlegte Lizenz ist **abgelaufen** (`Expired: License has expired`). Beide
|
||||
Betriebsarten bleiben deshalb an der Lizenzschranke stehen — `MainWindow`, Terminal,
|
||||
Einstellungsansicht und die Wartungsaktionen sind compilergeprüft, aber **noch nie
|
||||
angezeigt worden**. Nach Erneuerung der Lizenz nachzuholen.
|
||||
|
||||
### Umsetzung
|
||||
|
||||
| Datei | Zweck |
|
||||
|---|---|
|
||||
| `Program.cs` | Einstiegspunkt. Argumentauswertung **vor** jeder Avalonia-Initialisierung — sonst stirbt der Prozess auf einem Server ohne X11, bevor `--headless` greift. |
|
||||
| `App.axaml(.cs)` | Lizenzschranke, dann Hauptfenster. `ShutdownMode.OnExplicitShutdown` während der Aktivierung, danach `OnMainWindowClose`. |
|
||||
| `ViewModels/MainWindowViewModel.cs` | Bindungsziel, `CommunityToolkit.Mvvm`-Quellgeneratoren, kapselt `PredictalyticsHost` |
|
||||
| `ViewModels/LogLine.cs` | Terminalzeile mit Einfärbung nach Loglevel (Farbschema aus WinForms übernommen) |
|
||||
| `Views/MainWindow.axaml` | Menü, Werkzeugleiste, Terminal-Tab, Einstellungen-Tab, Statusleiste |
|
||||
| `Views/LicenseWindow.axaml` | Aktivierungsfenster, ersetzt `LicenseDialog` |
|
||||
| `Views/Dialogs.cs` | Ersatz für `MessageBox.Show` — im Code aufgebaut, kein Drittanbieterpaket |
|
||||
| `Services/HeadlessRunner.cs` | AP 3.4: Betrieb ohne Oberfläche |
|
||||
| `Services/ConsoleAttach.cs` | Windows-Konsole anhängen + UTF-8 |
|
||||
|
||||
### Abweichungen und Entscheidungen
|
||||
|
||||
* **`PropertyGrid`-Ersatz handgeschrieben**, wie empfohlen. Vier Gruppen als
|
||||
`HeaderedContentControl`, Passwortfelder mit `PasswordChar`, **echtes mehrzeiliges
|
||||
Textfeld** für die Egress-Kanäle (besser als das in Phase 2 entfallene `[Editor]`-Attribut).
|
||||
SSL-Modus als `ComboBox`; bewusst nur `None`/`Preferred`/`Required` — `VerifyCA`/`VerifyFull`
|
||||
bräuchten hinterlegte Zertifikate und würden hier nur zu Fehlkonfiguration einladen.
|
||||
* **Speichern ist jetzt explizit** („Speichern & übernehmen") statt wie beim `PropertyGrid`
|
||||
bei jeder Einzeländerung. Klarer, und erspart `INotifyPropertyChanged` auf `PredictalyticsOptions`.
|
||||
* **Feste Fenstergröße aufgelöst** (vorher `1886×1088` fix): jetzt `MinWidth`/`MinHeight`
|
||||
mit skalierendem `DockPanel`/`Grid`.
|
||||
* **Schrift-Fallbackkette** `Cascadia Code, DejaVu Sans Mono, Liberation Mono, Consolas, monospace`
|
||||
fürs Terminal; `Avalonia.Fonts.Inter` als mitgelieferte UI-Schrift, weil Linux-Distributionen
|
||||
sehr unterschiedliche Standardfonts haben.
|
||||
* **Ringpuffer statt Leeren**: die WinForms-Fassung verwarf bei 500 Zeilen das gesamte
|
||||
Terminal (`rtb.Clear()`), jetzt fällt jeweils nur die älteste Zeile heraus.
|
||||
* **`Avalonia.Diagnostics` nicht referenziert** — gibt es nur bis 11.3.18, nicht für 12.x.
|
||||
* **`global::Avalonia.Application`**: innerhalb von `Predictalytics.*` löst der kurze Name
|
||||
`Application` auf den eigenen Namespace `Predictalytics.Application` auf. Betrifft jede
|
||||
künftige Avalonia-Klasse in diesem Projekt.
|
||||
* **`Microsoft.NET.Sdk` statt `Sdk.Web`**, wie in Phase 2 gelernt (Static-Web-Assets-Kollision
|
||||
mit dem `wwwroot`-Content-Eintrag).
|
||||
|
||||
### Headless-Betrieb
|
||||
|
||||
Lizenz über `PREDICTALYTICS_LICENSE_KEY`; ohne nutzbare Lizenz Abbruch mit Exit-Code 2
|
||||
statt eines Dialogs, den niemand sieht. `SIGTERM` und `SIGINT` werden über
|
||||
`PosixSignalRegistration` abgefangen, damit systemd sauber stoppen kann.
|
||||
|
||||
Exit-Codes: `0` planmäßig beendet · `2` keine nutzbare Lizenz · `3` Abbruch mit Fehler.
|
||||
|
||||
### AP 3.1 — Projekt `Predictalytics.Shell`
|
||||
```xml
|
||||
|
||||
Reference in New Issue
Block a user