From 278b15fe43ad469bc0d37e74e0815ae58631ed92 Mon Sep 17 00:00:00 2001 From: Erik Darling <2136037+erikdarlingdata@users.noreply.github.com> Date: Fri, 24 Apr 2026 15:07:31 -0400 Subject: [PATCH] Collapsible Wait Stats section (#215 E12) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wait Stats card now uses
/ and defaults to closed so it doesn't push improvement items below the fold on 1080p monitors. - Web viewer (Index.razor): insight-card switches to
element. app.css styles .insight-card > summary the same as h4, hides the native disclosure marker, and shows ▸ / ▾ chevrons tied to the [open] attribute. - HTML export (HtmlExporter.cs): same pattern on the .card.waits card. Keeps the chart as a complementary view (Joe's earlier preference) — just out of the way by default. Click the header to expand. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/PlanViewer.Core/Output/HtmlExporter.cs | 16 +++++++++++----- src/PlanViewer.Web/Pages/Index.razor | 10 +++++----- src/PlanViewer.Web/wwwroot/css/app.css | 19 ++++++++++++++++++- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/PlanViewer.Core/Output/HtmlExporter.cs b/src/PlanViewer.Core/Output/HtmlExporter.cs index 3102c10..5d87f26 100644 --- a/src/PlanViewer.Core/Output/HtmlExporter.cs +++ b/src/PlanViewer.Core/Output/HtmlExporter.cs @@ -109,10 +109,15 @@ .statement h2 { /* Insights grid */ .insights { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 0.75rem; margin-bottom: 0.75rem; } .card { border-radius: 6px; border: 1px solid var(--border); overflow: hidden; } -.card h3 { +.card h3, .card > summary { padding: 0.4rem 0.75rem; font-size: 0.8rem; font-weight: 500; border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 0.5rem; + list-style: none; cursor: pointer; } +.card > summary::-webkit-details-marker { display: none; } +.card > summary::before { content: ""\25B8""; font-size: 0.7rem; color: var(--text-muted); width: 0.7rem; } +details.card[open] > summary::before { content: ""\25BE""; } +.card.waits summary { color: #2a4365; } .card-body { padding: 0.5rem 0.75rem; font-size: 0.8rem; } .card.runtime { background: var(--card-runtime); border-color: var(--card-runtime-border); } .card.runtime h3 { color: #2c5282; } @@ -432,11 +437,12 @@ private static void WriteParametersCard(StringBuilder sb, StatementResult stmt) private static void WriteWaitStatsCard(StringBuilder sb, StatementResult stmt, bool hasActualStats) { - sb.AppendLine("
"); - sb.Append("

Wait Stats"); + // Collapsible (#215 E12): default-closed so improvement items aren't pushed below the fold. + sb.AppendLine("
"); + sb.Append("Wait Stats"); if (stmt.WaitStats.Count > 0) sb.Append($" {stmt.WaitStats.Sum(w => w.WaitTimeMs):N0} ms"); - sb.AppendLine("

"); + sb.AppendLine("
"); sb.AppendLine("
"); if (stmt.WaitStats.Count > 0) { @@ -464,7 +470,7 @@ private static void WriteWaitStatsCard(StringBuilder sb, StatementResult stmt, b sb.AppendLine($"
{(hasActualStats ? "No waits recorded" : "Estimated plan — no wait stats")}
"); } sb.AppendLine("
"); - sb.AppendLine(""); + sb.AppendLine("
"); } private static void WriteWarnings(StringBuilder sb, StatementResult stmt) diff --git a/src/PlanViewer.Web/Pages/Index.razor b/src/PlanViewer.Web/Pages/Index.razor index 5d46382..652583c 100644 --- a/src/PlanViewer.Web/Pages/Index.razor +++ b/src/PlanViewer.Web/Pages/Index.razor @@ -299,14 +299,14 @@ else - @* Wait Stats *@ -
-

Wait Stats + @* Wait Stats — collapsible (#215 E12): default-closed so it doesn't push improvement items below the fold *@ +
+ Wait Stats @if (ActiveStmt!.WaitStats.Count > 0) { @ActiveStmt!.WaitStats.Sum(w => w.WaitTimeMs).ToString("N0") ms } -

+
@if (ActiveStmt!.WaitStats.Count > 0) { @@ -336,7 +336,7 @@ else
@(result.Summary.HasActualStats ? "No waits recorded" : "Estimated plan — no wait stats")
}
-
+ @* Warnings strip *@ diff --git a/src/PlanViewer.Web/wwwroot/css/app.css b/src/PlanViewer.Web/wwwroot/css/app.css index 8c13d50..b44467c 100644 --- a/src/PlanViewer.Web/wwwroot/css/app.css +++ b/src/PlanViewer.Web/wwwroot/css/app.css @@ -541,7 +541,8 @@ textarea::placeholder { overflow: hidden; } -.insight-card h4 { +.insight-card h4, +.insight-card > summary { padding: 0.4rem 0.75rem; font-size: 0.8rem; font-weight: 500; @@ -549,8 +550,24 @@ textarea::placeholder { display: flex; align-items: center; gap: 0.5rem; + list-style: none; + cursor: pointer; +} + +.insight-card > summary::-webkit-details-marker { display: none; } + +.insight-card > summary::before { + content: "\25B8"; + font-size: 0.7rem; + color: var(--text-muted); + transition: transform 0.15s ease; + width: 0.7rem; } +.insight-card[open] > summary::before { content: "\25BE"; } + +details.insight-card:not([open]) { border-bottom: 1px solid var(--border); } + .insight-body { padding: 0.5rem 0.75rem; font-size: 0.8rem;