Verbinden-Tab: Sicherung direkt nach dem Verbinden erstellbar
"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 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HReLXMbmPvtQ23p1iWiJNW
This commit is contained in:
@@ -3,6 +3,7 @@ import SwiftUI
|
|||||||
struct ConnectView: View {
|
struct ConnectView: View {
|
||||||
@ObservedObject private var connectionService: ConnectionService
|
@ObservedObject private var connectionService: ConnectionService
|
||||||
@StateObject private var viewModel: ConnectViewModel
|
@StateObject private var viewModel: ConnectViewModel
|
||||||
|
@StateObject private var backupViewModel = BackupViewModel()
|
||||||
|
|
||||||
init(connectionService: ConnectionService) {
|
init(connectionService: ConnectionService) {
|
||||||
self.connectionService = connectionService
|
self.connectionService = connectionService
|
||||||
@@ -37,7 +38,10 @@ struct ConnectView: View {
|
|||||||
} detail: {
|
} detail: {
|
||||||
deviceDetail
|
deviceDetail
|
||||||
}
|
}
|
||||||
.onAppear { viewModel.onAppear() }
|
.onAppear {
|
||||||
|
viewModel.onAppear()
|
||||||
|
backupViewModel.load()
|
||||||
|
}
|
||||||
.alert(
|
.alert(
|
||||||
"Unbekanntes Zertifikat",
|
"Unbekanntes Zertifikat",
|
||||||
isPresented: certificateAlertBinding,
|
isPresented: certificateAlertBinding,
|
||||||
@@ -50,6 +54,18 @@ struct ConnectView: View {
|
|||||||
} message: { fingerprint in
|
} 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.")
|
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? {
|
private var certificateFingerprint: String? {
|
||||||
@@ -82,6 +98,32 @@ struct ConnectView: View {
|
|||||||
Section {
|
Section {
|
||||||
Label("Verbunden (\(kind == .rest ? "REST-API" : "SSH"))", systemImage: "checkmark.circle.fill")
|
Label("Verbunden (\(kind == .rest ? "REST-API" : "SSH"))", systemImage: "checkmark.circle.fill")
|
||||||
.foregroundStyle(.green)
|
.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):
|
case .failed(let message):
|
||||||
Section {
|
Section {
|
||||||
|
|||||||
Reference in New Issue
Block a user