48 lines
3.4 KiB
Swift
48 lines
3.4 KiB
Swift
import SwiftUI
|
|
|
|
struct SettingsView: View {
|
|
@EnvironmentObject var vm: OrionVMController
|
|
@State private var selection: UUID?
|
|
@State private var editing: ServerDefinition?
|
|
var body: some View {
|
|
HStack(spacing: 0) {
|
|
List(selection: $selection) { ForEach(vm.servers) { s in Label(s.name, systemImage: vm.status(for: s).symbolName).tag(s.id) } }
|
|
.frame(width: 190)
|
|
Divider()
|
|
VStack(alignment: .leading, spacing: 14) {
|
|
if let id = selection, let server = vm.servers.first(where: { $0.id == id }) {
|
|
Text(server.name).font(.title2).fontWeight(.semibold)
|
|
LabeledContent("Parallels VM", value: server.vmName); LabeledContent("Host", value: server.host); LabeledContent("SSH user", value: server.sshUser); LabeledContent("SSH port", value: String(server.sshPort)); LabeledContent("SSH key", value: server.sshIdentityFile.isEmpty ? "Default SSH configuration" : server.sshIdentityFile); LabeledContent("Mailpit", value: server.mailpitPort.map(String.init) ?? "Disabled")
|
|
HStack { Button("Edit…") { editing = server }; Button("Force Stop", role: .destructive) { vm.forceStop(server) }.disabled(vm.status(for: server) == .stopped) }
|
|
Spacer()
|
|
} else { ContentUnavailableView("Select a Server", systemImage: "server.rack") }
|
|
Divider()
|
|
HStack { Button("Add Server…", systemImage: "plus") { editing = ServerDefinition(name: "New Server", vmName: "", host: "", sshUser: "sysadmin", sshPort: 22, sshIdentityFile: "", mailpitPort: nil) }; Spacer(); Button("Delete", role: .destructive) { if let id = selection, let i = vm.servers.firstIndex(where: {$0.id == id}) { vm.delete(at: IndexSet(integer: i)); selection = nil } }.disabled(selection == nil) }
|
|
}.padding(20)
|
|
}.frame(width: 650, height: 380)
|
|
.sheet(item: $editing) { server in ServerEditor(server: server, isNew: !vm.servers.contains(where: {$0.id == server.id})) { value, isNew in if isNew { vm.add(value) } else { vm.update(value) }; selection = value.id } }
|
|
}
|
|
}
|
|
|
|
struct ServerEditor: View {
|
|
@Environment(\.dismiss) private var dismiss
|
|
@State var server: ServerDefinition
|
|
let isNew: Bool
|
|
let save: (ServerDefinition, Bool) -> Void
|
|
var body: some View {
|
|
VStack(alignment: .leading, spacing: 14) {
|
|
Text(isNew ? "Add Server" : "Edit Server").font(.title2).fontWeight(.semibold)
|
|
Form {
|
|
TextField("Display name", text: $server.name)
|
|
TextField("Parallels VM name", text: $server.vmName)
|
|
TextField("IP address / host", text: $server.host)
|
|
TextField("SSH user", text: $server.sshUser)
|
|
TextField("SSH port", value: $server.sshPort, format: .number)
|
|
TextField("SSH identity file (optional)", text: $server.sshIdentityFile, prompt: Text("~/.ssh/id_ed25519"))
|
|
TextField("Mailpit port (optional)", text: Binding(get: { server.mailpitPort.map(String.init) ?? "" }, set: { server.mailpitPort = Int($0) }))
|
|
}
|
|
HStack { Spacer(); Button("Cancel") { dismiss() }; Button("Save") { save(server, isNew); dismiss() }.keyboardShortcut(.defaultAction).disabled(server.name.isEmpty || server.vmName.isEmpty || server.host.isEmpty || server.sshUser.isEmpty || server.sshPort < 1 || server.sshPort > 65535) }
|
|
}.padding(20).frame(width: 470)
|
|
}
|
|
}
|