feat: add summary dashboard history charts

This commit is contained in:
2026-04-21 18:03:51 +02:00
parent 0bb4be861c
commit 44f4206f34
12 changed files with 790 additions and 81 deletions

View File

@@ -20,30 +20,34 @@ struct ServerDetailView: View {
var isRestarting: Bool = false
var onRestart: (() async -> ServerActionFeedback)? = nil
@AppStorage("showIntervalIndicator") private var showIntervalIndicator: Bool = true
@AppStorage("refreshInterval") private var refreshInterval: Int = 60
private var showPlaceholder: Bool {
server.info == nil
}
@State private var progress: Double = 0
@State private var showRestartSheet = false
@State private var restartFeedback: ServerActionFeedback?
private let indicatorTimer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
var body: some View {
VStack(spacing: 0) {
if showIntervalIndicator {
ProgressView(value: progress)
.progressViewStyle(LinearProgressViewStyle())
.padding(.horizontal)
.frame(height: 2)
RefreshIntervalIndicator()
}
ZStack(alignment: .topTrailing) {
VStack(spacing: 0) {
Spacer().frame(height: 6)
TabView {
SummaryView(
server: resolvedBinding,
canRestart: canRestart,
isRestarting: isRestarting
) {
showRestartSheet = true
}
.tabItem {
Text("Summary").unredacted()
}
GeneralView(
server: resolvedBinding,
canRestart: canRestart,
@@ -85,21 +89,6 @@ struct ServerDetailView: View {
.padding()
}
}
.onReceive(indicatorTimer) { _ in
guard showIntervalIndicator else { return }
withAnimation(.linear(duration: 1)) {
progress += 1.0 / Double(refreshInterval)
if progress >= 1 { progress = 0 }
}
}
.onChange(of: refreshInterval) { _, _ in
progress = 0
}
.onChange(of: showIntervalIndicator) { _, isVisible in
if !isVisible {
progress = 0
}
}
.sheet(isPresented: $showRestartSheet) {
RestartConfirmationSheet(
hostname: server.hostname,
@@ -133,6 +122,30 @@ struct ServerDetailView: View {
}
}
private struct RefreshIntervalIndicator: View {
@AppStorage("refreshInterval") private var refreshInterval: Int = 60
@State private var progress: Double = 0
private let indicatorTimer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
var body: some View {
ProgressView(value: progress)
.progressViewStyle(LinearProgressViewStyle())
.padding(.horizontal)
.frame(height: 2)
.onReceive(indicatorTimer) { _ in
withAnimation(.linear(duration: 1)) {
progress += 1.0 / Double(max(refreshInterval, 1))
if progress >= 1 {
progress = 0
}
}
}
.onChange(of: refreshInterval) { _, _ in
progress = 0
}
}
}
#Preview {
ServerDetailView(
server: .constant(Server(id: UUID(), hostname: "preview.example.com", info: ServerInfo.placeholder)),