diff --git a/WorkbenchReplacement/MainView.swift b/WorkbenchReplacement/MainView.swift index b199865..3d9e335 100644 --- a/WorkbenchReplacement/MainView.swift +++ b/WorkbenchReplacement/MainView.swift @@ -2553,15 +2553,52 @@ struct WorkbenchAdministrationView: View { private var resultContent: some View { switch page { case .serverStatus, .dashboard: - // Both destinations are genuine charts-only dashboards. No KPI tile - // view can appear in either route. - ScrollView(.vertical) { - WorkbenchInlinePerformanceDashboard(samples: diagnosticSamples) - .frame(maxWidth: .infinity, alignment: .topLeading) - .padding(18) + // Phase 49: preserve the verified Phase 48 line charts, while + // restoring the server overview in its own scrollable lower pane. + GeometryReader { available in + let chartHeight = min(155.0, max(85.0, (available.size.height - 270.0) / 3.0)) + VStack(alignment: .leading, spacing: 0) { + WorkbenchInlinePerformanceDashboard( + samples: diagnosticSamples, + chartHeight: chartHeight + ) + .padding(.horizontal, 18) + .padding(.top, 12) + .padding(.bottom, 8) + .fixedSize(horizontal: false, vertical: true) + .layoutPriority(1) + .accessibilityIdentifier("live-mysql-line-graphs-phase49") + + Divider() + + ScrollView(.vertical) { + VStack(alignment: .leading, spacing: 14) { + Label("Server overview", systemImage: "server.rack") + .font(.title3.bold()) + WorkbenchServerOverview(rows: filteredRows) + if page == .serverStatus { + Divider() + HStack { + Text("Server status metrics").font(.headline) + Spacer() + Text("\(filteredRows.count) metrics") + .font(.caption).foregroundStyle(.secondary) + } + WorkbenchColouredCounterTable( + columns: ["Metric", "Value"], rows: filteredRows + ) + .frame(height: 300) + } + } + .padding(18) + .frame(maxWidth: .infinity, alignment: .leading) + } + .frame(maxWidth: .infinity, maxHeight: .infinity) + .accessibilityIdentifier("scrollable-server-overview-phase49") + } + .frame(width: available.size.width, height: available.size.height, alignment: .topLeading) } .frame(maxWidth: .infinity, maxHeight: .infinity) - .accessibilityIdentifier("real-live-charts-phase48") case .serverCounters, .connectionStatistics, .innodbMetrics: WorkbenchLiveMonitorScreen( page: page, @@ -4086,6 +4123,7 @@ private struct WorkbenchAccountManagerView: View { private struct WorkbenchInlinePerformanceDashboard: View { let samples: [DiagnosticSample] + var chartHeight: CGFloat = 205 private struct Reading: Identifiable { let id: Int @@ -4137,7 +4175,7 @@ private struct WorkbenchInlinePerformanceDashboard: View { .foregroundStyle(tint) } .chartYAxis { AxisMarks(position: .leading) } - .frame(height: 205) + .frame(height: chartHeight) .accessibilityLabel("Live time-series graph for \(title)") } .padding(14) @@ -4149,7 +4187,7 @@ private struct WorkbenchInlinePerformanceDashboard: View { var body: some View { VStack(alignment: .leading, spacing: 12) { HStack { - Label("Live MySQL Line Graphs · Phase 48", systemImage: "waveform.path.ecg") + Label("Live MySQL Line Graphs", systemImage: "waveform.path.ecg") .font(.title2.bold()) Spacer() Text("\(samples.count) samples · refreshes every 5 seconds") diff --git a/docs/PHASE49-DASHBOARD-AND-STATUS.md b/docs/PHASE49-DASHBOARD-AND-STATUS.md new file mode 100644 index 0000000..4e57c83 --- /dev/null +++ b/docs/PHASE49-DASHBOARD-AND-STATUS.md @@ -0,0 +1,19 @@ +# Phase 49 — Dashboard and Server Status + +The verified Phase 48 Swift Charts line graphs remain in both Dashboard and Server Status. +The six charts are shown first in a responsive grid; the server overview is restored in a separately scrolling lower pane. Server Status also includes a status-metrics table below the overview. + +Graph sampling remains at the existing 5-second refresh interval (up to 60 samples). Rate charts need at least two snapshots. + +## Verification +- Swift parser checked with `swiftc -frontend -parse` in Linux. +- macOS build and UI behaviour have **not** been tested in this environment. + +## Build on macOS + +```sh +cd /Volumes/Developer/Applications/WorkbenchReplacement +pkill -x WorkbenchReplacement 2>/dev/null || true +xcodebuild -project WorkbenchReplacement.xcodeproj -scheme WorkbenchReplacement -configuration Debug -destination 'platform=macOS,arch=arm64' -derivedDataPath ./build clean build +open ./build/Build/Products/Debug/WorkbenchReplacement.app +```