This commit is contained in:
Mark Gregory
2026-10-23 09:28:19 +01:00
parent 965ddf8e2c
commit 415dba0344
7 changed files with 696 additions and 24 deletions
+55
View File
@@ -24,6 +24,8 @@ struct OrionMenuView: View {
Divider()
ScrollView {
VStack(alignment: .leading, spacing: 10) {
runningSection
Divider()
Text("PARALLELS VIRTUAL MACHINES").font(.caption.bold()).foregroundStyle(.secondary)
if vm.discoveredVMs.isEmpty {
Text(vm.discovering ? "Discovering virtual machines…" : "No VMs found. Use Refresh to try again.")
@@ -84,6 +86,51 @@ struct OrionMenuView: View {
message: { Text(vm.lastError ?? "") }
}
private var runningSection: some View {
VStack(alignment: .leading, spacing: 8) {
HStack {
Label("RUNNING VIRTUAL MACHINES", systemImage: "play.circle.fill")
.font(.caption.bold())
Spacer()
Text("\(vm.runningVMs.count) running")
.font(.caption)
.foregroundStyle(.secondary)
}
if vm.runningVMs.isEmpty {
Text("No running VMs detected")
.font(.caption)
.foregroundStyle(.secondary)
.padding(.vertical, 8)
}
ForEach(vm.runningVMs) { machine in
VStack(alignment: .leading, spacing: 6) {
HStack {
vmIcon(machine)
VStack(alignment: .leading, spacing: 2) {
Text(machine.name).fontWeight(.medium)
Text("Running").font(.caption).foregroundStyle(.green)
}
Spacer()
if vm.busyVMIDs.contains(machine.id) {
ProgressView().controlSize(.small)
}
}
HStack {
Button("Stop") { vm.operate(machine, action: "stop") }
Button("Restart") { vm.operate(machine, action: "restart") }
Button("Force Stop", role: .destructive) {
vm.operate(machine, action: "force-stop")
}
}
.controlSize(.small)
.disabled(vm.busyVMIDs.contains(machine.id))
}
.padding(9)
.background(.quaternary.opacity(0.3), in: RoundedRectangle(cornerRadius: 8))
}
}
}
private func vmRow(_ machine: ParallelsVM) -> some View {
HStack(spacing: 9) {
Toggle("", isOn: Binding(
@@ -107,6 +154,9 @@ struct OrionMenuView: View {
Button("Stop") { vm.operate(machine, action: "stop") }
} else if machine.status == "suspended" {
Button("Resume") { vm.operate(machine, action: "resume") }
} else {
Button("Start") { vm.operate(machine, action: "start") }
.help("Try starting VM (Parallels reports: \(machine.status))")
}
if vm.isIntegrated(machine) {
Image(systemName: "checkmark.circle.fill").foregroundStyle(.green).help("Integrated")
@@ -155,6 +205,11 @@ struct OrionMenuView: View {
.disabled(status != .running || server.host.isEmpty || server.sshUser.isEmpty)
Button("Mailpit") { vm.openMailpit(server) }
.disabled(status != .running || server.host.isEmpty || server.mailpitPort == nil)
Button("Remove", role: .destructive) {
expandedServers.remove(server.id)
vm.removeDefinition(server)
}
.help("Remove integration only; the VM is not deleted")
}.padding(.leading, 30)
}
}.padding(.vertical, 4)