Skip to content

Port Lite chart/tab polish to Dashboard + LSP diagnostics cleanup#863

Merged
erikdarlingdata merged 1 commit into
devfrom
chore/lsp-diagnostics-cleanup
Apr 19, 2026
Merged

Port Lite chart/tab polish to Dashboard + LSP diagnostics cleanup#863
erikdarlingdata merged 1 commit into
devfrom
chore/lsp-diagnostics-cleanup

Conversation

@erikdarlingdata
Copy link
Copy Markdown
Owner

Summary

Two pieces of work bundled on the chore/lsp-diagnostics-cleanup branch:

Dashboard polish (ports items already merged to Lite in #862)

  • New Dashboard/Helpers/AxesExtensions.cs with DateTimeTicksBottomDateChange() — culture-aware (en-GB dd/MM, de-DE dd.MM, 24-hour clocks, etc.). All 52 call sites of DateTimeTicksBottom() across 10 Dashboard files swapped to use it: dates now print on the first tick and on rollover ticks only; time-only on the rest.
  • Chart tick font bumped from 12 → 13 in TabHelpers.ApplyTheme and ReapplyAxisColors for readability.
  • SubTabItemStyle added to all three themes (Dark / Light / CoolBreeze): thin accent underline + transparent background instead of filled cyan. Wired via ItemContainerStyle on 11 sub-TabControls: Overview's inner tabs, Collection Health's inner tabs, Locking, ConfigChanges, CurrentConfig, FinOps, Memory, ResourceMetrics (×2), SystemEvents, QueryPerformance.

LSP diagnostics cleanup

  • Small nullability / warning fixes across Dashboard and Lite services, analysis helpers, and BenefitScorer / PlanAnalyzer.

Test plan

  • Launch Dashboard in Dark / Light / CoolBreeze themes; verify sub-tabs render with accent underline, main tabs still filled
  • View any trend chart that spans < 24 hours — date shows only on first tick, time-only on the rest
  • View a chart spanning midnight — date line appears again at rollover
  • Switch to en-GB / de-DE locale and verify date format + 24-hour times
  • Verify Overview → Resource Overview, Queries, Memory, Resource Metrics, System Events all render ticks correctly
  • dotnet build clean with no regressions from the LSP cleanup edits

🤖 Generated with Claude Code

Dashboard polish (ports the same items merged to Lite in #862):
- New Dashboard/Helpers/AxesExtensions.cs with DateTimeTicksBottomDateChange(),
  culture-aware (dd/MM for en-GB, dd.MM for de-DE, 24h clocks, etc.). All 52
  call sites of DateTimeTicksBottom() across 10 files swapped to use it.
- TabHelpers.ApplyTheme + ReapplyAxisColors bump chart tick label font from
  12 to 13 so numbers read cleaner on wide charts.
- SubTabItemStyle added to Dark / Light / CoolBreeze themes: thin accent
  underline + transparent background instead of filled cyan, so sub-tabs
  don't look identical to main tabs when selected. Wired via
  ItemContainerStyle on 11 sub-TabControls (Overview's inner tabs,
  Collection Health's inner tabs, Locking, ConfigChanges, CurrentConfig,
  FinOps, Memory, ResourceMetrics ×2, SystemEvents, QueryPerformance).

LSP diagnostics cleanup (tracked work from chore/lsp-diagnostics-cleanup):
- Small nullability/warning fixes across Dashboard and Lite services,
  analysis helpers, and BenefitScorer / PlanAnalyzer.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@erikdarlingdata erikdarlingdata merged commit 02db6b5 into dev Apr 19, 2026
3 checks passed
@erikdarlingdata erikdarlingdata deleted the chore/lsp-diagnostics-cleanup branch April 19, 2026 00:07
Copy link
Copy Markdown
Owner Author

@erikdarlingdata erikdarlingdata left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review summary

What this does
Ports the chart-axis + sub-tab polish from Lite PR #862 into Dashboard, plus a round of LSP/nullability cleanup across both apps.

  • New Dashboard/Helpers/AxesExtensions.cs mirroring the Lite helper from #862; 52 call sites of DateTimeTicksBottom() swapped to the new DateTimeTicksBottomDateChange() across 10 Dashboard files.
  • SubTabItemStyle added to Dark / Light / CoolBreeze themes; wired via ItemContainerStyle on 11 sub-TabControls in ServerTab.xaml, MemoryContent.xaml, QueryPerformanceContent.xaml, ResourceMetricsContent.xaml, SystemEventsContent.xaml, ConfigChangesContent.xaml, CurrentConfigContent.xaml, FinOpsContent.xaml.
  • Tick font 12 → 13 in Dashboard/Helpers/TabHelpers.cs:203,205,239,241.
  • Null-guards and StringComparison.Ordinal fixes across PlanAnalyzer, BenefitScorer, SqlServerBaselineProvider, CorrelatedCrosshairManager, RemoteCollectorService.QueryStore.

Good

  • Base branch is dev. ✓
  • Lite-first ordering honored — Dashboard catches up to Lite, not the other way around. ✓
  • PlanAnalyzer.cs rule bodies (Rule 12 hasRecompile, Rule 28 Row Count Spool, implicit-conversion warning promotion) changed identically in both Dashboard and Lite copies. ✓
  • BenefitScorer.cs StringComparison.Ordinal cleanup is byte-for-byte identical across both copies. ✓
  • No SQL / schema changes — no upgrade-script concerns.
  • No .github/workflows/build.yml changes — SignPath stays on test-signing.

Needs attention

  • PlanAnalyzer sync drift (minor): Dashboard/Services/PlanAnalyzer.cs:1831 is now private sealed record ScanImpact(...) but Lite/Services/PlanAnalyzer.cs:1828 is still private record ScanImpact(...). Mirror the sealed change into Lite (or drop it from Dashboard) to keep the two copies aligned per the sync rule. Inline comment left.
  • AxesExtensions.MonthDayPattern is culture-snapshot-once at static init — stale if the UI culture changes at runtime. Inherited from Lite's #862 copy, not introduced here, but worth a follow-up. Inline comment left.
  • AxesExtensions.DateTimeTicksBottomDateChange relies on the tick formatter being invoked in tick order. Fragile if ScottPlot reorders calls during pan/zoom redraws. Worth a manual pan+zoom verification on a chart crossing midnight. Inline comment left.
  • RemoteCollectorService.QueryStore.cs:225 null-propagation silently downgrades engine detection when serverStatus is null. Matches line 33's pattern, so consistent — but see inline comment for the tradeoff.
  • No tests touched. AxesExtensions.BuildMonthDayPattern is a pure string function and would be trivial to cover in Dashboard.Tests / Lite.Tests (en-US, en-GB, de-DE, ja-JP at minimum). Consider adding a small fixture.

Not blocking anything — comments only.


Generated by Claude Code

}

private record ScanImpact(double CostPct, double ElapsedPct, string? Summary);
private sealed record ScanImpact(double CostPct, double ElapsedPct, string? Summary);
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ScanImpact was changed to sealed record here, but the mirrored Lite/Services/PlanAnalyzer.cs:1828 still has private record ScanImpact(...) (unsealed). Per the PlanAnalyzer sync rule, either seal it in Lite too or leave both alone — the two copies should stay byte-for-byte equivalent (minus namespace/using).


Generated by Claude Code

{
/// <summary>Culture's short-date pattern with the year component removed (e.g. "M/d" en-US, "dd/MM" en-GB, "dd.MM" de-DE).</summary>
private static readonly string MonthDayPattern = BuildMonthDayPattern();

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MonthDayPattern is a static readonly resolved once at type-init against CultureInfo.CurrentCulture. If the user changes locale mid-session (or the UI thread runs under a different culture than the static init thread), the pattern will be stale. Not a blocker — this mirrors Lite's copy from #862 — but worth a TODO to either recompute per-call or cache by culture.


Generated by Claude Code

var time = dt.ToString("t", culture);
if (lastDate is null || dt.Date != lastDate.Value)
{
lastDate = dt.Date;
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The lastDate closure variable assumes the LabelFormatter delegate is invoked in left-to-right tick order within a render pass. If ScottPlot ever reorders tick-label resolution (zoom/pan/redraw), date labels can print on the wrong ticks or the first tick may lose its date line on redraw. Worth verifying with a pan+zoom test in the test plan — again, inherited from Lite, so fine to port as-is, but a known fragility.


Generated by Claude Code

}

bool isNew = productVersion > 13 || serverStatus.SqlEngineEdition == 5 || serverStatus.SqlEngineEdition == 8;
bool isNew = productVersion > 13 || serverStatus?.SqlEngineEdition == 5 || serverStatus?.SqlEngineEdition == 8;
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Behavior change: when serverStatus is null, isNew now silently falls through to productVersion > 13. That matches line 33's null-propagation pattern, so it's consistent — but note that a null serverStatus on Azure SQL DB (engine 5) previously threw NRE, and now quietly reports isNew=false if the product-version probe also failed. If serverStatus is never expected to be null post-connect, an early guard upstream would express that intent more clearly than silently downgrading the engine detection.


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant