import SwiftUI struct MonitorMenuView: View { @ObservedObject var monitor: ServerMonitor @Environment(\.openWindow) private var openWindow var body: some View { VStack(alignment: .leading, spacing: 0) { HStack { VStack(alignment: .leading, spacing: 5) { Label("PEGASUS MONITOR", systemImage: "server.rack").font(.headline) Label(monitor.status.title, systemImage: monitor.status.symbol) .foregroundStyle(monitor.status.color) } Spacer() if monitor.offlineCount > 0 { Text("\(monitor.offlineCount) offline").foregroundStyle(.red).font(.caption.bold()) } }.padding(14) Divider() Text("SERVERS").font(.caption.bold()).foregroundStyle(.secondary).padding(.horizontal, 14).padding(.top, 12) ScrollView { LazyVStack(spacing: 2) { ForEach(monitor.servers) { server in Button { monitor.select(server.id) } label: { HStack { Image(systemName: monitor.results[server.id]?.status.symbol ?? "circle.dotted") .foregroundStyle(server.enabled ? (monitor.results[server.id]?.status.color ?? .secondary) : .gray) VStack(alignment: .leading, spacing: 2) { Text(server.name).fontWeight(server.id == monitor.selectedID ? .bold : .regular) Text(server.host).font(.caption2).foregroundStyle(.secondary) } Spacer() if monitor.results[server.id]?.refreshing == true { ProgressView().controlSize(.mini) } else if let report = monitor.results[server.id]?.report { Text("\(report.counts.ok) OK").font(.caption2).foregroundStyle(.secondary) } if server.id == monitor.selectedID { Image(systemName: "checkmark") } }.padding(.horizontal, 14).padding(.vertical, 8) .contentShape(Rectangle()) }.buttonStyle(.plain) } } }.frame(maxHeight: 175) Divider() if let selected = monitor.selected { HStack { Text(selected.name.uppercased()).font(.caption.bold()) Spacer() Button { Task { await monitor.refreshSelected() } } label: { Image(systemName: "arrow.clockwise") } .buttonStyle(.plain) }.padding(.horizontal, 14).padding(.vertical, 10) ScrollView { LazyVStack(alignment: .leading, spacing: 0) { if let report = monitor.report { if !monitor.selectedServices.isEmpty { Text("SERVICES") .font(.caption.bold()).foregroundStyle(.secondary) .padding(.horizontal, 14).padding(.vertical, 8) ForEach(monitor.selectedServices) { service in HStack(spacing: 8) { Image(systemName: service.symbol).foregroundStyle(service.color) Text(service.name).font(.system(size: 12)) Spacer() if selected.requiredServices.contains(service.name) { Text("REQUIRED").font(.system(size: 9, weight: .bold)).foregroundStyle(.orange) } Text(service.title).font(.caption).foregroundStyle(.secondary) } .padding(.horizontal, 14).padding(.vertical, 5) } Divider() Text("HEALTH GROUPS") .font(.caption.bold()).foregroundStyle(.secondary) .padding(.horizontal, 14).padding(.vertical, 8) } ForEach(report.groups) { group in HStack { Text(group.name).font(.system(size: 12, weight: .medium)) Spacer() Label(group.status.title, systemImage: group.status.symbol) .foregroundStyle(group.status.color).font(.caption) }.padding(.horizontal, 14).padding(.vertical, 8) Divider().padding(.leading, 14) } } else { Text(monitor.selectedResult?.error ?? "Waiting for health data…") .font(.caption).foregroundStyle(.secondary).padding(14) } } }.frame(height: 300) } Divider() let totals = monitor.aggregate Text("ALL SERVERS: \(totals.ok) OK · \(totals.warn) WARN · \(totals.fail) FAIL") .font(.caption.bold()).padding(14) if let error = monitor.selectedResult?.error { Text(error).foregroundStyle(.red).font(.caption).textSelection(.enabled) .padding(.horizontal, 14).padding(.bottom, 8) } Divider() HStack { Button("Refresh All") { Task { await monitor.refreshAll() } } Spacer() Button("Diagnostics") { openWindow(id: "monitor-diagnostics") } Button("Settings") { openWindow(id: "monitor-settings") } Button("Quit") { NSApp.terminate(nil) } }.buttonStyle(.borderless).padding(14) }.frame(width: 410) } } struct DiagnosticsView: View { @ObservedObject var monitor: ServerMonitor var body: some View { VStack(alignment: .leading, spacing: 12) { Text("\(monitor.selected?.name ?? "Server") — Diagnostics").font(.title2.bold()) Text("Select a server in the menu bar to change this report.").font(.caption).foregroundStyle(.secondary) ScrollView { LazyVStack(alignment: .leading, spacing: 10) { ForEach(monitor.report?.checks ?? []) { check in HStack(alignment: .top) { Image(systemName: check.status.symbol).foregroundStyle(check.status.color) VStack(alignment: .leading, spacing: 2) { Text(check.name).fontWeight(.medium) Text(check.detail).font(.caption).foregroundStyle(.secondary) } Spacer() } } } }.textSelection(.enabled) }.padding(20).frame(minWidth: 650, minHeight: 450) } }