refactored code structure

This commit is contained in:
Micha
2025-11-17 15:42:55 +01:00
parent 22b2c632a9
commit 4efe1a2324
26 changed files with 417 additions and 29 deletions

View File

@@ -0,0 +1,127 @@
//
// GeneralTab.swift
// iKeyMon
//
// Created by tracer on 30.03.25.
//
import SwiftUI
struct GeneralView: View {
@Binding var server: Server
var body: some View {
GeometryReader { geometry in
ScrollView {
VStack(alignment: .leading, spacing: 6) {
TableRowView {
Text("Hostname")
} value: {
InfoCell(value: [server.hostname])
}
TableRowView {
Text("IP addresses")
} value: {
InfoCell(value: server.info?.ipAddresses ?? [], monospaced: true)
}
TableRowView {
Text("Server time")
} value: {
InfoCell(value: [server.info?.formattedServerTime ?? ""], monospaced: true)
}
TableRowView {
Text("Uptime")
} value: {
InfoCell(value: [server.info?.uptime ?? ""])
}
TableRowView {
Text("KeyHelp version")
} value: {
InfoCell(value: [server.info?.formattedVersion ?? ""], monospaced: true)
}
TableRowView {
Text("Operating system")
} value: {
InfoCell(
value: {
guard let os = server.info?.operatingSystem else { return [] }
var rows: [String] = []
let distro = [os.distribution, os.version]
.filter { !$0.isEmpty }
.joined(separator: " ")
.trimmingCharacters(in: .whitespacesAndNewlines)
var description = os.label.trimmingCharacters(in: .whitespacesAndNewlines)
if description.isEmpty {
description = distro
} else if !distro.isEmpty && distro.caseInsensitiveCompare(description) != .orderedSame {
description += "\(distro)"
}
if !os.architecture.isEmpty {
description += " (\(os.architecture))"
}
if !description.isEmpty {
rows.append(description)
}
if let updates = os.updates {
var updateDescription = "Updates: \(updates.updateCount)"
if updates.securityUpdateCount > 0 {
updateDescription += "\(updates.securityUpdateCount) security"
}
rows.append(updateDescription)
if updates.rebootRequired {
rows.append("Reboot required")
}
}
if os.endOfLife {
rows.append("End-of-life release")
}
return rows
}(),
monospaced: true
)
}
TableRowView {
Text("Sytem PHP version")
} value: {
InfoCell(value: [server.info?.phpVersion ?? ""], monospaced: true)
}
TableRowView(showDivider: false) {
Text("Additional PHP interpreters")
} value: {
InfoCell(
value: server.info?.additionalPHPInterpreters?.map { $0.versionFull } ?? [],
monospaced: true
)
}
}
.padding()
.frame(minHeight: geometry.size.height, alignment: .top)
}
.padding()
.scrollDisabled(true)
}
}
}
#Preview {
struct PreviewWrapper: View {
@State var previewServer = Server(hostname: "example.com", info: .placeholder)
var body: some View {
GeneralView(server: $previewServer)
}
}
return PreviewWrapper()
}

View File

@@ -0,0 +1,116 @@
//
// RecourcesView.swift
// iKeyMon
//
// Created by tracer on 31.03.25.
//
//
// GeneralTab.swift
// iKeyMon
//
// Created by tracer on 30.03.25.
//
import SwiftUI
struct ResourcesView: View {
@Binding var server: Server
var body: some View {
GeometryReader { geometry in
ScrollView {
VStack(alignment: .leading, spacing: 6) {
TableRowView {
Text("CPU Load")
} value: {
LoadBarCell(
percent: (server.info?.load.percent)!,
load1: (server.info?.load.minute1)!,
load5: (server.info?.load.minute5)!,
load15: (server.info?.load.minute15)!
)
}
TableRowView {
Text("Memory")
} value: {
UsageBarCell(
free: (server.info?.memory.free)!,
used: (server.info?.memory.used)!,
total: (server.info?.memory.total)!,
percent: (server.info?.memory.percent)!
)
}
TableRowView {
Text("Swap")
} value: {
UsageBarCell(
free: (server.info?.swap.free)!,
used: (server.info?.swap.used)!,
total: (server.info?.swap.total)!,
percent: (server.info?.swap.percent)!
)
}
TableRowView {
Text("SSD")
} value: {
UsageBarCell(
free: (server.info?.diskSpace.free)!,
used: (server.info?.diskSpace.used)!,
total: (server.info?.diskSpace.total)!,
percent: (server.info?.diskSpace.percent)!
)
}
}
.padding()
.frame(minHeight: geometry.size.height, alignment: .top)
}
}
// VStack(alignment: .leading, spacing: 16) {
// if let info = server.info {
// Text("Server Utilization")
// .font(.headline)
// .padding(.bottom, 4)
//
// ResourceRow(label: "CPU Load", value: "\(info.load.percent)", subtext: info.cpuLoadDetail)
// ResourceRow(label: "Process Count", value: "\(info.processCount)")
//// ResourceRow(label: "Emails in Queue", value: "\(info.emailsInQueue)")
//
// ResourceBarRow(
// label: "Memory",
// free: info.memory.free,
// used: info.memory.used,
// total: info.memory.total,
// percent: info.memory.percent
// )
//
// ResourceBarRow(
// label: "Swap",
// free: info.memory.free,
// used: info.memory.used,
// total: info.memory.total,
// percent: info.memory.percent
// )
//
// Spacer()
// } else {
// Text("No data")
// }
// }
.padding()
.frame(maxWidth: .infinity, alignment: .leading)
}
}
#Preview {
struct PreviewWrapper: View {
@State var previewServer = Server(hostname: "example.com", info: .placeholder)
var body: some View {
ResourcesView(server: $previewServer)
}
}
return PreviewWrapper()
}

View File

@@ -0,0 +1,62 @@
//
// ServicesView.swift
// iKeyMon
//
// Created by tracer on 31.03.25.
//
import SwiftUI
struct ServicesView: View {
@Binding var server: Server
var body: some View {
VStack(alignment: .leading) {
if let ports = server.info?.ports {
Table(ports) {
TableColumn("Service") { port in
Text(port.service)
}
TableColumn("Status") { port in
Text(port.status)
.foregroundColor(
port.status.lowercased() == "online" ? .green : .red
)
}
TableColumn("Port") { port in
Text("\(port.port) \(port.proto.uppercased())")
}
TableColumn("Protocol") { port in
Text("\(port.proto.uppercased())")
.monospacedDigit()
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.padding(0)
} else {
Text("No service information available")
.foregroundColor(.secondary)
.padding()
}
}
.navigationTitle("Service/port monitoring")
}
}
#Preview {
struct PreviewWrapper: View {
@State var previewServer = Server(hostname: "example.com", info: .placeholder)
var body: some View {
ServicesView(server: $previewServer)
}
}
return PreviewWrapper()
}