Skip to content

fix(ui): adopt AnalyticsCardShell in five hand-rolled analytics cards - #6472

Closed
nghetienhiep wants to merge 1 commit into
JSONbored:mainfrom
nghetienhiep:fix/issue-6175
Closed

fix(ui): adopt AnalyticsCardShell in five hand-rolled analytics cards#6472
nghetienhiep wants to merge 1 commit into
JSONbored:mainfrom
nghetienhiep:fix/issue-6175

Conversation

@nghetienhiep

Copy link
Copy Markdown
Contributor

Summary

  • Migrated the five analytics cards that hand-rolled the shared "titled card with loading/empty/ready" chrome — cycle-time-card, gate-precision-card, reversal-health-card, gate-outcome-card, slop-duplicate-trend-card — to render through AnalyticsCardShell (#2200), matching how acceptance-rate-card/queue-health-card already use it.
  • Fixes the user-visible bug in CycleTimeCard: its no-samples branch rendered a bare <p> instead of the shared EmptyState every adopted sibling gets. Routing it through the shell with state="empty" now shows the standard EmptyState.
  • Gave AnalyticsCardShell an optional action header slot so each card keeps its existing header signal (status pill, public boundary badge, freshness stamp) across every state — the header already reserved the right-hand space via justify-between.
  • Data-fetching logic and ready-state content are unchanged; only the chrome/state-handling wrapper moved. GatePrecisionCard keeps its documented "render nothing when there are no evaluated rows" behavior.

Scope

  • The PR title follows type(scope): short summary Conventional Commit format.
  • This PR is focused (UI-only, under apps/loopover-ui/**) and does not mix unrelated backend, MCP, docs, or deploy changes.
  • This follows CONTRIBUTING.md and does not reintroduce GitHub Pages, VitePress, site/, or CNAME.
  • Linked open issue: Closes #6175.

Validation

  • npm run ui:typecheck — clean
  • npm run ui:lint (eslint + prettier) — clean
  • npm run ui:test — 277 passing (34 across the six changed/adjacent card suites)
  • npm run ui:build — succeeds
  • git diff --check — clean
  • No generated-artifact drift (ui:openapi regenerates nothing)

apps/** is excluded from Codecov, so this UI-only change carries no codecov/patch obligation; tests are still added for the shell's new action slot and updated for the CycleTimeCard empty-state fix.

Safety

  • No secrets, wallets, hotkeys, trust scores, private rankings, or reward values are exposed. The cards remain public-safe aggregates only.
  • UI states use real empty/ready rendering, not production mock/demo fallbacks.
  • Visible UI change — UI Evidence below with GitHub-hosted PNG thumbnails.

UI Evidence

Screenshots rendered from vite dev against mocked operator/maintainer dashboard payloads.

State / title Evidence
CycleTimeCard — empty state fixed (now the shared EmptyState, was a bare paragraph) Cycle time empty state
CycleTimeCard — ready state (unchanged content, shell chrome + pill) Cycle time ready state
GatePrecisionCard — ready Gate precision ready state
ReversalHealthCard — ready Reversal health ready state
GateOutcomeCard — ready (public boundary badge preserved via action) Gate outcome ready state
SlopDuplicateTrendCard — ready (pill + freshness stamp preserved via action) Slop + duplicate trend ready state

Notes

  • reversal-health-card and gate-outcome-card always show their stat grid with an inner EmptyState for a sub-section (targets list / outcome-mix bar), so they adopt the shell as state="ready" and keep that inner empty treatment — the migration unifies their header chrome (including gate-outcome's border-hairline bg-card → the shell's border).

Closes #6175

@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@loopover-orb loopover-orb Bot added the gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. label Jul 16, 2026
@nghetienhiep
nghetienhiep force-pushed the fix/issue-6175 branch 3 times, most recently from af48625 to fa3f9f4 Compare July 16, 2026 09:35
The cycle-time, gate-precision, reversal-health, gate-outcome, and
slop-duplicate-trend cards each re-implemented the shared "titled card
with loading/empty/ready" chrome (JSONbored#2200) instead of rendering through
AnalyticsCardShell like acceptance-rate and queue-health already do.

The root-cause symptom was CycleTimeCard's no-samples branch: it rendered
a bare paragraph instead of the shared EmptyState every adopted sibling
gets for free. Routing it through the shell with state="empty" fixes that
and gives the whole folder one loading/empty/ready implementation.

To keep each card's header signal (status pill, public boundary badge,
freshness stamp) the shell gains an optional `action` slot rendered in the
header across every state — the header already reserved the right-hand
space via justify-between. Data-fetching and ready-state content are
unchanged; only the chrome/state wrapper moved.

Closes JSONbored#6175
@loopover-orb

loopover-orb Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Caution

🛑 LoopOver review result - reject/close recommended

Review updated: 2026-07-16 09:51:53 UTC

8 files · 1 AI reviewer · 1 blocker · CI green · clean

🛑 Suggested Action - Reject/Close

Review summary
This PR migrates five hand-rolled analytics cards to the shared AnalyticsCardShell, adds an optional `action` header slot to the shell, and fixes CycleTimeCard's empty state to use the shared EmptyState instead of a bare `<p>`. The refactor is mechanically clean — each card's ready-state content and data logic are untouched, only chrome moved — and the shell change is additive/backward-compatible with new tests covering the action slot across states. The 'magic numbers' flagged in the brief are just issue-reference comments (`#2200`), not real magic numbers.

Blockers

  • CI shows validate, validate-code, validate-tests, and the UI preview build all FAILED on this commit, which is inconsistent with the PR's claimed clean typecheck/lint/test/build results — this needs to be resolved or explained before merge.
Nits — 5 non-blocking
  • gate-outcome-card.tsx and reversal-health-card.tsx still hardcode `state="ready"` even though they have their own internal EmptyState branching for sub-sections — consider whether the shell's `state` prop should reflect the overall data availability for consistency with cycle-time-card and slop-duplicate-trend-card, or note why it's intentionally different.
  • gate-precision-card.tsx keeps its early `return null` outside the shell entirely, which is a third distinct empty-handling pattern among the five migrated cards (shell state="empty", shell state="ready" with inline EmptyState, and pre-shell null) — worth a one-line note on why precision alone renders nothing.
  • The `action` prop type is `ReactNode` with no guidance on layout when multiple actions are passed (slop-duplicate-trend-card wraps two children in a fragment) — the shell's `flex flex-wrap items-center gap-2` wrapper handles this, but it'd help to document that expectation in the prop comment.
  • Confirm the CI failures (validate/validate-code/validate-tests/build) are addressed or are known-flaky/unrelated before merge — the PR checklist claims clean local runs that don't match the reported CI status.
  • Consider standardizing whether cards with partial-empty sub-sections (gate-outcome, reversal-health) should pass `state="empty"` to the shell when their primary list is empty, for visual consistency with cycle-time-card and slop-duplicate-trend-card.

Why this is blocked

  • CI shows validate, validate-code, validate-tests, and the UI preview build all FAILED on this commit, which is inconsistent with the PR's claimed clean typecheck/lint/test/build results — this needs to be resolved or explained before merge.
📋 Copy for AI agents — paste into your coding agent
Fix the following blocker(s) from this PR review:

1. CI shows validate, validate-code, validate-tests, and the UI preview build all FAILED on this commit, which is inconsistent with the PR's claimed clean typecheck/lint/test/build results — this needs to be resolved or explained before merge.

Decision drivers

  • ❌ Code review — 1 blocker (1 reviewer)
  • ❌ Gate result — Blocking (Repo-configured hard blocker found.)
Context & advisory signals — never blocks the verdict
Signal Result Evidence
Linked issue ✅ Linked #6175
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ❌ 8/20 High review scope from cached public metadata (1 linked issue).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 135 registered-repo PR(s), 79 merged, 0 issue(s).
Contributor context ✅ Confirmed Gittensor contributor nghetienhiep; Gittensor profile; 135 PR(s), 0 issue(s).
Improvement ✅ Minor risk: clean · value: minor · LLM: moderate
Review context
  • Author: nghetienhiep
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: Python, Vue, C#, JavaScript, C, C++, Go, Objective-C
  • Official Gittensor activity: 135 PR(s), 0 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Start here: Add a concise scope and risk note.
  • Then work through the remaining 1 step in the Signals table above.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.
🧪 Chat with LoopOver

Ask LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.

  • @loopover ask &lt;question&gt; answers contribution-quality Q&A with source citations and freshness.
  • @loopover chat &lt;question&gt; answers in natural prose from cached decision-pack facts via local inference (maintainer/collaborator; read-only).
  • A plain-language @loopover mention with a real question is routed to the closest matching read-only command automatically — no exact syntax required.

Full command reference: https://loopover.ai/docs/loopover-commands

🧪 Experimental — new and may change.

Visual preview
Route Viewport Before (production) After (this PR's preview) Diff
/ desktop before /
before /
after /
after /
/ mobile before / (mobile)
before / (mobile)
after / (mobile)
after / (mobile)

Click any thumbnail to open the full-size screenshot. Before = production · After = this PR's preview deploy.

🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed


💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →.

Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.

  • Re-run LoopOver review

@loopover-orb loopover-orb Bot added the manual-review Gittensor contributor context label Jul 16, 2026
@loopover-orb

loopover-orb Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

LoopOver is closing this pull request on the maintainer's behalf (AI reviewers agree on a likely critical defect: CI shows validate, validate-code, validate-tests, and the UI preview build all FAILED on this commit, which is inconsistent with the PR's claimed clean typecheck/lint/test/build results — this needs to be resolved or explained before merge.). This is an automated maintenance action — to pursue this change, please open a new pull request with the issues resolved. Closed PRs may be analyzed later to improve review accuracy, but they are not automatically reopened or re-reviewed.

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

Labels

gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. manual-review Gittensor contributor context

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(ui): adopt AnalyticsCardShell in 5 analytics cards that hand-roll their own chrome (fixes CycleTimeCard's broken empty state)

1 participant