From d441aea02c8695aeb347b4fe73df41fb09fb003d Mon Sep 17 00:00:00 2001 From: Mark Gregory Date: Sat, 17 Oct 2026 11:54:29 +0100 Subject: [PATCH] Improved progress display Previously, the progress bar updated only after completing an entire table. For large tables such as LIBARC, this could make the application appear to have stopped responding. Phase 10 updates the interface while rows are being exported. --- PHASE30-NOTES.md | 11 ----- PHASE31-NOTES.md | 7 --- PHASE32-NOTES.md | 8 ---- PHASE33-NOTES.md | 1 - WorkbenchReplacement/MainView.swift | 54 +++++++++-------------- PHASE34-NOTES.md => docs/PHASE34-NOTES.md | 0 PHASE35-NOTES.md => docs/PHASE35-NOTES.md | 0 docs/PHASE37-NOTES.md | 11 +++++ 8 files changed, 33 insertions(+), 59 deletions(-) delete mode 100644 PHASE30-NOTES.md delete mode 100644 PHASE31-NOTES.md delete mode 100644 PHASE32-NOTES.md delete mode 100644 PHASE33-NOTES.md rename PHASE34-NOTES.md => docs/PHASE34-NOTES.md (100%) rename PHASE35-NOTES.md => docs/PHASE35-NOTES.md (100%) create mode 100644 docs/PHASE37-NOTES.md diff --git a/PHASE30-NOTES.md b/PHASE30-NOTES.md deleted file mode 100644 index d6917b0..0000000 --- a/PHASE30-NOTES.md +++ /dev/null @@ -1,11 +0,0 @@ -# Phase 30 — Server Counters graphs fix - -- Adds a dedicated **Server Counters** item under **Administration → Management**. -- Retrieves all actual server counters using `SHOW GLOBAL STATUS` (not `SHOW GLOBAL VARIABLES`). -- Places nine colour-coded Swift Charts above the counters, directly on the Server Counters screen. -- Graphs show current thread counts and per-second rates for cumulative counters. -- Counter cards remain visible beneath the charts; the filter field filters the cards. -- Samples are collected every five seconds when Auto-refresh is enabled. The first rate point requires two successful samples. -- Existing dashboard, SQL editor and schema editor are preserved. - -This release was not compiled on macOS or tested against a live MySQL server. diff --git a/PHASE31-NOTES.md b/PHASE31-NOTES.md deleted file mode 100644 index 3bc03c3..0000000 --- a/PHASE31-NOTES.md +++ /dev/null @@ -1,7 +0,0 @@ -# Phase 31 — Server Counters Layout - -- Server counter cards appear first, with a compact responsive grid. -- Live graphs appear directly below the counter cards in the same scroll view. -- Bytes counters are displayed in readable units; uptime in days/hours/minutes; numeric counters use separators. -- Existing graph collection, automatic refresh and schema editing are retained. -- Requires macOS/Xcode compilation and live MySQL verification. diff --git a/PHASE32-NOTES.md b/PHASE32-NOTES.md deleted file mode 100644 index 41ebcdc..0000000 --- a/PHASE32-NOTES.md +++ /dev/null @@ -1,8 +0,0 @@ -# Phase 32 — Administration View Restoration - -- Server Counters: inline coloured graphs followed by the complete searchable MySQL status grid (no omitted counters). -- Server Status: full SHOW GLOBAL STATUS data restored below the performance overview, with search. -- Status and System Variables: restored original native table/grid presentation; no inappropriate charts or counter tiles. -- Connection Statistics and InnoDB: retain graphs and complete tabular results. -- No MySQL mutations; monitoring remains read-only. -- Xcode build and live MySQL validation must be performed on macOS. diff --git a/PHASE33-NOTES.md b/PHASE33-NOTES.md deleted file mode 100644 index f9e9693..0000000 --- a/PHASE33-NOTES.md +++ /dev/null @@ -1 +0,0 @@ -Phase 33: Server Counters fixed split layout. Nine real MySQL sample charts pinned in horizontal scroll strip above independently scrolling full coloured SHOW GLOBAL STATUS table. All counters retained. Auto-refresh does not blank existing data. No Xcode build performed. diff --git a/WorkbenchReplacement/MainView.swift b/WorkbenchReplacement/MainView.swift index 506dd43..9585324 100644 --- a/WorkbenchReplacement/MainView.swift +++ b/WorkbenchReplacement/MainView.swift @@ -4155,7 +4155,7 @@ private struct WorkbenchInlinePerformanceDashboard: View { Text("\(samples.count) samples · refreshes every 5 seconds") .font(.caption).foregroundStyle(.secondary) } - LazyVGrid(columns: [GridItem(.adaptive(minimum: 360), spacing: 14)], spacing: 12) { + LazyVGrid(columns: [GridItem(.adaptive(minimum: 410), spacing: 16)], spacing: 12) { panel("Queries per second", metric: "Queries", rate: true, tint: .blue) panel("Active connections", metric: "Threads_connected", rate: false, tint: .teal) panel("Running threads", metric: "Threads_running", rate: false, tint: .orange) @@ -4204,44 +4204,34 @@ private struct WorkbenchServerCountersScreen: View { category == "All" ? rows : rows.filter { $0.count >= 2 && group($0[0]) == category } } var body: some View { - ScrollView { - VStack(alignment: .leading, spacing: 18) { - HStack { - Label("Server overview", systemImage: "server.rack").font(.title3.bold()) - Spacer() - Text("Live MySQL status · 5-second refresh").font(.caption).foregroundStyle(.secondary) - } - LazyVGrid(columns: [GridItem(.adaptive(minimum: 155), spacing: 10)], spacing: 10) { - overview("Queries", metric: "Queries", tint: .blue) - overview("Connected", metric: "Threads_connected", tint: .teal) - overview("Running", metric: "Threads_running", tint: .orange) - overview("Slow queries", metric: "Slow_queries", tint: .red) - overview("Received", metric: "Bytes_received", tint: .purple) - overview("Sent", metric: "Bytes_sent", tint: .green) - } - HStack { - Label("Performance trends", systemImage: "chart.xyaxis.line").font(.title3.bold()) - Spacer() - Text("\(samples.count) samples").font(.caption).foregroundStyle(.secondary) - } + ScrollView(.vertical) { + VStack(alignment: .leading, spacing: 20) { + // Graphs are the primary content, never hidden below summary cards. WorkbenchCounterCharts(page: .serverCounters, samples: samples) + .frame(maxWidth: .infinity, alignment: .leading) + + Divider() HStack { - Label("All server counters", systemImage: "list.bullet.rectangle").font(.title3.bold()) + Label("All MySQL server counters", systemImage: "list.bullet.rectangle") + .font(.title3.bold()) Spacer() - Text("\(visibleRows.count) of \(rows.count)").font(.caption).foregroundStyle(.secondary) + Text("\(visibleRows.count) of \(rows.count) counters") + .font(.caption).foregroundStyle(.secondary) } Picker("Counter category", selection: $category) { ForEach(categories, id: \.self) { Text($0).tag($0) } } .pickerStyle(.segmented) WorkbenchColouredCounterTable(columns: ["Variable_name", "Value"], rows: visibleRows) - .frame(minHeight: 360, idealHeight: 600) - Text("Colours identify counter families, not server health. Error totals are cumulative; a nonzero value does not by itself indicate a current fault.") + .frame(height: 450) + Text("Colours identify counter families, not server health. Error totals are cumulative; nonzero values do not necessarily indicate a current fault.") .font(.caption).foregroundStyle(.secondary) } - .padding(18) + .padding(20) + .frame(maxWidth: .infinity, alignment: .leading) } } + } // MARK: - Phase 29: Inline coloured counter graphs @@ -4449,15 +4439,15 @@ private struct WorkbenchCounterCharts: View { .foregroundStyle(tint).lineStyle(StrokeStyle(lineWidth: 2.5)) } .chartYAxis { AxisMarks(position: .leading) } - .frame(height: 115) + .frame(height: 205) if values.isEmpty { Text("Waiting for samples").font(.caption2).foregroundStyle(.secondary) } } - .padding(14) + .padding(16) .frame(maxWidth: .infinity, alignment: .leading) - .background(tint.opacity(0.08)) - .clipShape(RoundedRectangle(cornerRadius: 12)) + .background(Color(nsColor: .controlBackgroundColor), in: RoundedRectangle(cornerRadius: 12)) + .overlay(RoundedRectangle(cornerRadius: 12).stroke(tint.opacity(0.35), lineWidth: 1)) } var body: some View { @@ -4469,10 +4459,10 @@ private struct WorkbenchCounterCharts: View { Text("\(samples.count) samples · 5-second refresh") .font(.caption).foregroundStyle(.secondary) } - LazyVGrid(columns: [GridItem(.adaptive(minimum: 360), spacing: 14)], spacing: 12) { + LazyVGrid(columns: [GridItem(.adaptive(minimum: 410), spacing: 16)], spacing: 12) { ForEach(metrics, id: \.self) { metric in graph(metric) } } - Text("Graphs use real MySQL samples. Cumulative counters display change per second; thread counts show current values. Rates appear after two successful samples.") + Text("Live MySQL data • refreshes every five seconds. Rates appear after two successful samples; thread counts show current values.") .font(.caption).foregroundStyle(.secondary) } } diff --git a/PHASE34-NOTES.md b/docs/PHASE34-NOTES.md similarity index 100% rename from PHASE34-NOTES.md rename to docs/PHASE34-NOTES.md diff --git a/PHASE35-NOTES.md b/docs/PHASE35-NOTES.md similarity index 100% rename from PHASE35-NOTES.md rename to docs/PHASE35-NOTES.md diff --git a/docs/PHASE37-NOTES.md b/docs/PHASE37-NOTES.md new file mode 100644 index 0000000..5a5c723 --- /dev/null +++ b/docs/PHASE37-NOTES.md @@ -0,0 +1,11 @@ +# Phase 37 — Server Counters Graphs First + +Based on the exact Xcode project supplied in Archive(20261017-104400).zip. + +- Server Counters opens with the large performance graphs as the first content, with no overview cards pushing them down. +- Responsive two-column grid at typical desktop widths; each chart is 205 points tall. +- Coloured chart lines and filled areas, subtle matching chart borders, current readings, time and value axes. +- Full searchable server counter list remains below the graphs, grouped by category. +- Existing icon resources, Server Status, Status and System Variables, and schema editor preserved. + +Note: source-only change; requires Xcode compilation and live MySQL verification on macOS.