From 9993f84311a3d25a9c71acc322a7a13a78066177 Mon Sep 17 00:00:00 2001 From: Kay Date: Sat, 12 Sep 2026 20:44:47 +0200 Subject: [PATCH] Verbinden-Tab: Sicherung direkt nach dem Verbinden erstellbar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "Jetzt sichern"-Button erscheint sobald verbunden, noch bevor man in den Einrichten-Tab wechselt -- Nutzer-Wunsch, um vor Änderungen ohne Tab-Wechsel sichern zu können. Zeigt zusätzlich "Zuletzt gesichert: ..." für den aktuell verbundenen Host, falls schon eine Sicherung existiert (gefiltert auf den aktuellen Host, damit es bei mehreren Routern nicht verwirrt). Nutzt dieselbe BackupViewModel/BackupService-Logik wie der Sicherungen-Tab, eigene Instanz. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01HReLXMbmPvtQ23p1iWiJNW --- .../Wizard/Steps/Connect/ConnectView.swift | 44 ++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/RouterOSAssistant/Features/Wizard/Steps/Connect/ConnectView.swift b/RouterOSAssistant/Features/Wizard/Steps/Connect/ConnectView.swift index 934996d..cb52351 100644 --- a/RouterOSAssistant/Features/Wizard/Steps/Connect/ConnectView.swift +++ b/RouterOSAssistant/Features/Wizard/Steps/Connect/ConnectView.swift @@ -3,6 +3,7 @@ import SwiftUI struct ConnectView: View { @ObservedObject private var connectionService: ConnectionService @StateObject private var viewModel: ConnectViewModel + @StateObject private var backupViewModel = BackupViewModel() init(connectionService: ConnectionService) { self.connectionService = connectionService @@ -37,7 +38,10 @@ struct ConnectView: View { } detail: { deviceDetail } - .onAppear { viewModel.onAppear() } + .onAppear { + viewModel.onAppear() + backupViewModel.load() + } .alert( "Unbekanntes Zertifikat", isPresented: certificateAlertBinding, @@ -50,6 +54,18 @@ struct ConnectView: View { } message: { fingerprint in Text("Der Router hat sich mit einem unbekannten Zertifikat gemeldet.\nFingerabdruck: \(fingerprint)\n\nNur bestätigen, wenn dies dein eigenes Gerät im lokalen Netzwerk ist.") } + .alert( + "Sicherung fehlgeschlagen", + isPresented: Binding( + get: { backupViewModel.errorMessage != nil }, + set: { _ in backupViewModel.errorMessage = nil } + ), + presenting: backupViewModel.errorMessage + ) { _ in + Button("OK") {} + } message: { message in + Text(message) + } } private var certificateFingerprint: String? { @@ -82,6 +98,32 @@ struct ConnectView: View { Section { Label("Verbunden (\(kind == .rest ? "REST-API" : "SSH"))", systemImage: "checkmark.circle.fill") .foregroundStyle(.green) + + Button { + if let credentials = connectionService.credentials { + backupViewModel.createBackup(for: credentials) + } + } label: { + if backupViewModel.isCreatingBackup { + HStack { + ProgressView() + Text("Sichere…") + } + } else { + Label("Jetzt sichern", systemImage: "square.and.arrow.down") + } + } + .disabled(backupViewModel.isCreatingBackup) + .help("Sichert die aktuelle Router-Konfiguration — sinnvoll direkt nach dem Verbinden, bevor du im Einrichten-Tab etwas änderst.") + + if let lastBackup = backupViewModel.backups.first(where: { $0.host == connectionService.credentials?.host }) { + Label( + "Zuletzt gesichert: \(lastBackup.createdAt.formatted(date: .abbreviated, time: .standard))", + systemImage: "checkmark" + ) + .font(.caption) + .foregroundStyle(.secondary) + } } case .failed(let message): Section {