Skip to content

Fix #139: keep the PDStatusRollUp pop-over in step with its node - #140

Merged
davidnmbond merged 1 commit into
mainfrom
fix/139-status-rollup-stale-popover
Sep 13, 2026
Merged

davidnmbond merged 1 commit into
mainfrom
fix/139-status-rollup-stale-popover

Conversation

@davidnmbond

Copy link
Copy Markdown
Contributor

Closes #139.

PDStatusRollUp fed its icon and its pop-over from two different points in time. The icon is rendered by Blazor from Node.Status on every render; the pop-over is drawn by the JS module from a snapshot serialized once, in OnAfterRenderAsync(firstRender: true), and never refreshed — the module only exported init and dispose.

Found in the Magic Suite Ops Dashboard, where an environment row showed a red roll-up icon and a pop-over headed with a green tick and "All available checks are healthy". It affects every consumer that rebuilds its node as status changes, which is around 40 components in OpsDashboard alone.

Changes

  • PDStatusRollUp.razor.js — new update(triggerId, nodeJson) export that replaces the stored snapshot. An already-open pop-over is redrawn from the root (closing any drill-down, whose children may no longer exist) so a status that changes while someone is looking at it does not keep showing the superseded verdict.
  • PDStatusRollUp.razor.cs — pushes the node whenever its serialized form changes. It compares JSON rather than the instance, so a consumer that rebuilds an identical node each render does not chatter across interop.
  • Initialisation is now keyed on the first render at which Node is non-null rather than on firstRender. A component first rendered without a node previously never initialised the module, leaving it with no pop-over for the rest of its life even once a node arrived.

Tests

Three new bUnit tests in PDStatusRollUpNodeUpdateTests: a changed node is pushed, an identical rebuilt node is not, and a node arriving after first render still initialises.

Full suite: 476 passed, 0 failed. Release build clean.

Note for maintainers, not part of this change: dotnet test in this repo currently runs zero tests. global.json selects the Microsoft.Testing.Platform runner while PanoramicData.Blazor.Test uses xunit v2 with xunit.runner.visualstudio, which is VSTest-only. It exits non-zero, but reports "Zero tests ran" rather than a failure. I verified the above by temporarily switching the runner to VSTest locally; global.json is unchanged in this PR. Worth a separate issue — either move the project to xunit.v3 or set the runner back.

🤖 Generated with Claude Code

@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 4 complexity · 3 duplication

Metric Results
Complexity 4
Duplication 3

View in Codacy

AI Reviewer: run a review on demand. To trigger the first review automatically, go to your organization or repository integration settings. AI can make mistakes. Always validate suggestions.

Run reviewer

TIP This summary will be updated as you push new changes.

The trigger icon is rendered by Blazor from Node.Status on every render, but the
pop-over is drawn by the JavaScript module from a snapshot that was serialized
once, on first render, and never refreshed. A consumer that rebuilds its node as
status changes - the normal pattern - therefore got a live icon beside a pop-over
frozen at whatever the component first rendered. In the Magic Suite Ops Dashboard
that read as a red environment row whose pop-over insisted "All available checks
are healthy".

OnBeforeExpand was not a way out: with no callback supplied dotNetRef is null and
_maybeExpand returns the stale node immediately, so there was no refresh path at all.

The module gains an update(triggerId, nodeJson) export that replaces the stored
snapshot, redrawing an already-open pop-over from the root so a status that changes
while someone is looking at it is not left showing the superseded verdict.
OnAfterRenderAsync now pushes the node whenever its serialized form changes,
comparing JSON rather than the instance so that a consumer rebuilding an identical
node does not chatter across the interop boundary.

It also no longer keys initialisation on firstRender but on the first render at
which Node is non-null. A component first rendered without a node previously never
initialised the module, and so had no pop-over for the rest of its life even once a
node arrived.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@davidnmbond
davidnmbond force-pushed the fix/139-status-rollup-stale-popover branch from 16551cf to b26fe27 Compare September 13, 2026 20:37
@davidnmbond
davidnmbond merged commit 46ab5de into main Sep 13, 2026
5 checks passed
@davidnmbond
davidnmbond deleted the fix/139-status-rollup-stale-popover branch September 13, 2026 20:44
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.

PDStatusRollUp: pop-over shows the node as it was on first render, not as it is now

1 participant