forked from kay/RouterOS
M9: Einrichten-Wizard bekommt einen Einfach/Experte-Modusschalter (ModeStepView). Einfach überspringt VLAN, erlaubt nur ein LAN-Netzwerk ohne Isolation, Firewall-Grundschutz fest an. M10: neuer "Experte"-Tab mit generischem Motor (RouterOSMenuItem, RouterOSCommand.remove, ConnectionService.fetchMenuItems, freies "eigener Menüpfad"-Feld) plus kuratierten Formularen mit Tooltips (RouterOSSchemaCatalog) für Firewall/NAT/Mangle/Raw/Adress-Listen, Interfaces, IP, VPN, WLAN, Queues, System, Werkzeuge. Live gegen einen hEX-Testrouter verifiziert (erst per SSH, dann vom Nutzer selbst in der App), dabei 7 reale Bugs gefunden und gefixt — der wichtigste: RouterOS' SSH-CLI gibt bei fehlgeschlagenen Befehlen Exit-Code 0 zurück, wodurch apply() app-weit Fehler verschluckte statt sie zu melden. Danach ergänzt: Bestätigungsdialog vor Anlegen/Ändern + Auto-Backup vor dem ersten Experte-Tab-Schreibvorgang je Sitzung (Angleichung an den Wizard), sowie ein Dauer-Editor (Tage/Std/Min/Sek) für Lease-/Ablaufzeit-Felder statt Freitext. Details zu allen Bugs/Fixes: HANDOFF.md, CHATLOG.md. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EW3r6rW1xCf6UT5jNvt6rn
78 lines
3.6 KiB
Swift
78 lines
3.6 KiB
Swift
import SwiftUI
|
|
|
|
struct LanStepView: View {
|
|
@ObservedObject var viewModel: SetupViewModel
|
|
let availableInterfaces: [NetworkInterface]
|
|
|
|
var body: some View {
|
|
Form {
|
|
ForEach($viewModel.lanConfigs) { $config in
|
|
Section("Netzwerk auf \(config.interfaceName)") {
|
|
Picker("Anschluss/Bridge", selection: $config.interfaceName) {
|
|
ForEach(availableInterfaces) { interface in
|
|
Text(interface.name).tag(interface.name)
|
|
}
|
|
}
|
|
.help("Der interne Netzwerk-Anschluss, an dem deine Geräte hängen (dein lokales Netzwerk, LAN).")
|
|
TextField("Router-Adresse (z.B. 192.168.88.1/24)", text: $config.routerAddress)
|
|
.help("Die Adresse, unter der der Router selbst in diesem Netzwerk erreichbar ist.")
|
|
TextField("Netzwerk (z.B. 192.168.88.0/24)", text: $config.networkAddress)
|
|
.help("Der komplette Adressbereich dieses Netzwerks (z.B. /24 erlaubt bis zu 254 Geräte).")
|
|
TextField("Automatische Adressvergabe von", text: $config.poolRangeStart)
|
|
.help("Ab welcher Adresse der Router automatisch Adressen an Geräte in diesem Netzwerk vergibt.")
|
|
TextField("bis", text: $config.poolRangeEnd)
|
|
.help("Bis zu welcher Adresse der Router automatisch Adressen an Geräte in diesem Netzwerk vergibt.")
|
|
Stepper(
|
|
"Adresse behalten für \(config.leaseTimeHours) Stunden",
|
|
value: $config.leaseTimeHours,
|
|
in: 1...168
|
|
)
|
|
.help("Wie lange ein Gerät seine zugewiesene Adresse behält, bevor sie erneuert werden muss.")
|
|
TextField("DNS-Server", text: $config.dnsServers)
|
|
.help("Welcher Server Geräten in diesem Netzwerk Internetadressen in Namen übersetzt (z.B. www.google.de). Meist der Router selbst.")
|
|
|
|
if viewModel.mode == .expert {
|
|
Toggle("Von anderen Netzwerken isolieren", isOn: $config.isolated)
|
|
.help("Verhindert Datenverkehr zwischen diesem und allen anderen konfigurierten LAN-/VLAN-Netzwerken. Der Internetzugriff bleibt erhalten. Wird im Firewall-Schritt umgesetzt.")
|
|
|
|
if viewModel.lanConfigs.count > 1 {
|
|
Button("Netzwerk entfernen", role: .destructive) {
|
|
viewModel.removeLan(config.id)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if viewModel.mode == .expert {
|
|
Section {
|
|
Button("Weiteres LAN-Netzwerk hinzufügen") {
|
|
viewModel.addLan()
|
|
}
|
|
}
|
|
}
|
|
|
|
Section {
|
|
HStack {
|
|
Button("Zurück") { viewModel.goBack() }
|
|
Spacer()
|
|
Button("Weiter") { viewModel.goNext() }
|
|
.disabled(!isStepValid)
|
|
}
|
|
}
|
|
}
|
|
.formStyle(.grouped)
|
|
.navigationTitle("Heimnetzwerk einrichten")
|
|
}
|
|
|
|
private var isStepValid: Bool {
|
|
viewModel.lanConfigs.allSatisfy { config in
|
|
!config.interfaceName.isEmpty
|
|
&& !config.routerAddress.isEmpty
|
|
&& !config.networkAddress.isEmpty
|
|
&& !config.poolRangeStart.isEmpty
|
|
&& !config.poolRangeEnd.isEmpty
|
|
}
|
|
}
|
|
}
|