Einrichten-Tab: "Abbrechen"-Button ergänzt
Vorher kein Weg aus dem Wizard außer schrittweise "Zurück" bis zu Modus. Zentral als Toolbar-Button in SetupView (nicht pro Schritt dupliziert), mit Bestätigungsdialog gegen Datenverlust, deaktiviert während eines laufenden Apply. SetupViewModel.finish() in gemeinsame resetToInitialState() plus benannte finish()/cancel()-Wrapper aufgeteilt. Live bestätigt. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+15
@@ -1308,6 +1308,21 @@ später dazukommen könnte, da MikroTik-Router in ärmeren Ländern
|
||||
(Brasilien, spanischsprachige Länder) stark verbreitet sind — siehe
|
||||
Claude-Memory `future-language-support.md` für Details.
|
||||
|
||||
**"Abbrechen"-Button im Einrichten-Tab ergänzt** (2026-09-16, Nutzerwunsch:
|
||||
"mir fehlt im einrichte-tab (einfach und experte) noch ein
|
||||
\"Abbrechen\"-Button") — vorher gab es keinen Weg aus dem Wizard außer
|
||||
sich Schritt für Schritt per "Zurück" bis zu Modus vorzuklicken. Zentral
|
||||
in `SetupView.swift` als Toolbar-Button gelöst (nicht in jedem der sieben
|
||||
Schritt-Views einzeln dupliziert), sichtbar auf jedem Schritt in beiden
|
||||
Modi, mit `.confirmationDialog` ("Einrichten abbrechen?" /
|
||||
"Weiter ausfüllen") gegen versehentlichen Datenverlust bereits
|
||||
eingegebener Werte, deaktiviert während `isApplying` (ein laufendes
|
||||
Apply soll nicht mitten im Ablauf abreißen). `SetupViewModel.finish()`
|
||||
in eine private `resetToInitialState()` plus zwei benannte Wrapper
|
||||
(`finish()`/neues `cancel()`) aufgeteilt — gleicher Reset, aber je nach
|
||||
Aufrufkontext (erfolgreicher Apply vs. Nutzer bricht ab) unter dem
|
||||
passenden Namen lesbar. Live bestätigt ("sieht gut aus").
|
||||
|
||||
## Nächste Schritte
|
||||
|
||||
1. ~~M16: restliche `RouterOSSchemaCatalog.swift`-Sektionen übersetzen~~,
|
||||
|
||||
@@ -764,6 +764,9 @@ enum L10n {
|
||||
"Details anzeigen (RouterOS-Befehle)": "Show Details (RouterOS Commands)",
|
||||
"Vor dem Anwenden wird automatisch eine Sicherung der aktuellen Konfiguration erstellt (Tab \"Sicherungen\"). Ein garantiertes automatisches Zurückrollen bei Verbindungsabbruch gibt es nicht — bei Problemen die Sicherung im Tab \"Sicherungen\" verwenden oder den Router lokal (Ethernet/Konsole) wiederherstellen.":
|
||||
"Before applying, a backup of the current configuration is automatically created (\"Backups\" tab). There's no guaranteed automatic rollback if the connection drops — if there are problems, use the backup in the \"Backups\" tab, or restore the router locally (Ethernet/console).",
|
||||
"Einrichten abbrechen?": "Cancel Setup?",
|
||||
"Weiter ausfüllen": "Keep Going",
|
||||
"Alle in diesem Assistenten eingegebenen Werte gehen verloren.": "All values entered in this wizard will be lost.",
|
||||
"Ablauf": "Progress",
|
||||
"Änderungen erfolgreich angewendet": "Changes Applied Successfully",
|
||||
"Jetzt anwenden": "Apply Now",
|
||||
|
||||
@@ -4,6 +4,7 @@ struct SetupView: View {
|
||||
@ObservedObject var connectionService: ConnectionService
|
||||
@StateObject private var viewModel: SetupViewModel
|
||||
@AppStorage("appLanguage") private var appLanguage: String = "de"
|
||||
@State private var showCancelConfirmation = false
|
||||
|
||||
init(connectionService: ConnectionService) {
|
||||
self.connectionService = connectionService
|
||||
@@ -38,6 +39,28 @@ struct SetupView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
.toolbar {
|
||||
if connectionService.credentials != nil {
|
||||
ToolbarItem(placement: .cancellationAction) {
|
||||
Button(L10n.t("Abbrechen", appLanguage)) {
|
||||
showCancelConfirmation = true
|
||||
}
|
||||
.disabled(viewModel.isApplying)
|
||||
}
|
||||
}
|
||||
}
|
||||
.confirmationDialog(
|
||||
L10n.t("Einrichten abbrechen?", appLanguage),
|
||||
isPresented: $showCancelConfirmation,
|
||||
titleVisibility: .visible
|
||||
) {
|
||||
Button(L10n.t("Abbrechen", appLanguage), role: .destructive) {
|
||||
viewModel.cancel()
|
||||
}
|
||||
Button(L10n.t("Weiter ausfüllen", appLanguage), role: .cancel) {}
|
||||
} message: {
|
||||
Text(L10n.t("Alle in diesem Assistenten eingegebenen Werte gehen verloren.", appLanguage))
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
viewModel.prepareDefaults(from: configurableInterfaces)
|
||||
|
||||
@@ -254,6 +254,19 @@ final class SetupViewModel: ObservableObject {
|
||||
/// LAN afterwards) starts from the router's actual current state rather than this session's
|
||||
/// now-outdated in-memory one.
|
||||
func finish() {
|
||||
resetToInitialState()
|
||||
}
|
||||
|
||||
/// User-initiated abort from any step (per explicit request: no "Abbrechen" button existed
|
||||
/// anywhere in the wizard before this — the only way out was clicking through every remaining
|
||||
/// step to "Zurück" back to Mode, or force-quitting the app). Same reset as `finish()` — the
|
||||
/// distinction is purely which caller/label makes sense in context (a successful apply vs. a
|
||||
/// user backing out mid-way) — kept as separate names so each call site reads correctly.
|
||||
func cancel() {
|
||||
resetToInitialState()
|
||||
}
|
||||
|
||||
private func resetToInitialState() {
|
||||
step = .mode
|
||||
mode = .simple
|
||||
wanConfig = WanConfig(interfaceName: "ether1")
|
||||
|
||||
Reference in New Issue
Block a user