feat(site/src/modules/dashboard/Navbar): replace proxy emoji with latency radio icon in trigger - #28128
feat(site/src/modules/dashboard/Navbar): replace proxy emoji with latency radio icon in trigger#28128tracyjohnsonux wants to merge 7 commits into
Conversation
…ency radio icon in trigger
… trigger to match navbar placement
|
/coder-agents-review |
|
Chat: Review posted | View chat Review history
deep-review v0.9.0 | Round 5 | Last posted: Round 5, 9 findings (1 P2, 4 P3, 2 Nit, 2 Note), APPROVE. Review Finding inventoryFinding inventory - PR #28128Findings
Contested and acknowledgedCRF-4 (Nit, ProxyMenu.tsx:85) - Duplicated RadioIcon + getLatencyColor + neutral-text pattern
CRF-5 (Note, ProxyMenu.tsx:83) - Collapsed trigger loses visible proxy identity
CRF-6 (Note, ProxyMenu.stories.tsx:116) - Story latencies coupled to level thresholds without enforcement
Round logRound 1Panel. Netero + 12 panel reviewers. 1 P2, 2 P3, 1 Nit, 2 Notes. Reviewed against 48e1e28..732942e. Round 2Churn guard PROCEED (3 addressed, 3 acknowledged, 0 contested/silent). Panel re-review against 48e1e28..c1a5ea3. Netero R2 verified all three R1 fixes and found no new findings. Panel raised 2 new P3 findings, both mobile-only asymmetries with the R2 fixes. Round 3 updateBLOCKED. All open findings (CRF-7, CRF-8) silent since R2. Head SHA unchanged ( Round 4Churn guard PROCEED (2 addressed, 0 silent). Panel re-review against 48e1e28..4c229e9. Netero R4 verified both R2 fixes and found no new findings. Panel raised 1 new Nit (mobile className gate predicate drift; Mafuuu; noted-but-not-raised by Pariston and Knov, higher severity wins). Round 5Churn guard PROCEED (1 addressed, 0 silent). Panel re-review against 48e1e28..0ceeed3. About deep-reviewCRF = Coder Review Finding (P0-P4, Nit, Note)
|
There was a problem hiding this comment.
Small, focused swap: proxy emoji out, latency-colored RadioIcon in, expanded lists untouched. The pieces that worked: getLatencyColor(loading ? undefined : latency) at ProxyMenu.tsx:87 mirrors Latency.tsx:25 so both surfaces share the same loading-vs-value rule; twMerge collapses text-content-primary over the internal latencyColor in Latency's number branch exactly as intended; story latencies (224, 471) land inside the real getLatencyLevel bands with margin; and the mobile row deliberately guards <Latency> with latency && ... to sidestep the CircleHelpIcon fallback.
What needs attention: 1 P2, 2 P3, 1 Nit, 2 Notes.
- P2 The mobile trigger row loses the selected proxy's name from the accessible name. The removed
<ExternalImage alt={selectedProxy.name}>was carrying that identity; the desktop trigger keeps the equivalent via ansr-onlyspan, but the mobile row was left without one. - P3 In the unknown-latency state,
<Latency className="text-content-primary">erases the muted color thatCircleHelpIconuses to signal "no data", so the fallback icon renders bright next to a mutedRadioIcon. Reachable when the selected proxy has no latency entry (unhealthy, pending, etc.). - P3 The new loading-branch ternary (
proxyLatencyLoading ? undefined : latencyMS) has no story: Chromatic sees good, warning, and critical, never the loading gray. Break the ternary and no visual test catches it.
One quote worth keeping, from Pariston on the mismatched icons: "the class override strips the color from the icon that's supposed to carry it (CircleHelpIcon is the icon here, and its 'muted' is the unknown signal), and leaves the sibling RadioIcon muted alongside a bright question mark."
🤖 This review was automatically generated with Coder Agents.
…tency icon states - Restore proxy name in the mobile proxy row's accessible name via an sr-only span, matching the desktop trigger. - Apply the text-content-primary override only when a latency value is shown, so the unknown-latency CircleHelpIcon keeps its muted color. - Add a ClosedNoLatency story covering the unknown icon color state.
|
/coder-agents-review |
1 similar comment
|
/coder-agents-review |
There was a problem hiding this comment.
R1 findings addressed. All three fixes verified against c1a5ea3413:
- CRF-1 Mobile sr-only span is placed above the
aria-hiddenRadioIcon; screen readers now name the selected proxy on the mobile trigger row. - CRF-2
text-content-primaryoverride is guarded bylatencies?.[selectedProxy.id]?.latencyMS, so theCircleHelpIconfallback keeps its mutedtext-content-secondaryalongside the mutedRadioIcon. - CRF-3
ClosedNoLatencystory exercisesgetLatencyColor(undefined)on the selected proxy by filtering its entry out ofMockProxyLatencies.
CRF-4, CRF-5, CRF-6 acknowledged as author-scoped; author responses match each finding's own hedges.
Two new P3 findings, both mobile-only asymmetries opened by (or missed by) the R1 fixes:
- P3 [CRF-7] Mobile's new sr-only "Latency for {name}" promises latency information that the pre-existing
{latency && <Latency ...>}guard withholds when the selected proxy has no latency entry. Desktop's<Latency>rendersCircleHelpIconwitharia-label="Latency not available"in the same state; mobile falls silent. - P3 [CRF-8] Mobile trigger uses the same
getLatencyColor(latency?.latencyMS)pattern as desktop but noMobileMenu.stories.tsxstory exercises warning, critical, or no-latency bands.MockProxyLatenciescaps at 250 ms and puts the primary proxy in the good band, so mobile ships with only the good-band render covered.
One quote worth keeping, from Razor on the a11y regression: "This is a fresh gap opened by the R2 fix for CRF-1: the new sr-only span promises latency information without changing the sibling conditional that decides whether the status ever gets rendered."
🤖 This review was automatically generated with Coder Agents.
…and cover mobile icon states - Render Latency unconditionally in the mobile proxy row so screen readers hear "Latency not available" instead of silence, matching the desktop trigger. - Add warning, critical, and no-latency MobileMenu stories mirroring the desktop trigger coverage.
|
/coder-agents-review |
There was a problem hiding this comment.
Blocked. Head SHA is unchanged since round 2 (c1a5ea341302), and both open P3 findings from that round have no author response, no linked ticket, and no code change.
Unaddressed:
- P3 [CRF-7]
MobileMenu.tsx:144- sr-only "Latency for {name}" (added by the CRF-1 fix) is followed by silence when the selected proxy has no latency entry; desktop announces "Latency not available." via<Latency>'sCircleHelpIconfallback. Reachable during initial load and for any selected proxy without a latency entry. - P3 [CRF-8]
MobileMenu.tsx:140- mobile trigger renders the same latency-coloredRadioIconas desktop but noMobileMenu.stories.tsxstory exercises the warning, critical, or no-latency bands. Asymmetric with the R1 CRF-3 fix on desktop.
Further review is blocked until the author responds on each thread or pushes fixes. A response can be a fix in this PR, a linked follow-up issue, or a technical rationale for why the finding should not be fixed. A bare "won't fix" is not a resolution.
Separately, CI is failing on this head (test-e2e, required); worth investigating independently of the review findings.
🤖 This review was automatically generated with Coder Agents.
There was a problem hiding this comment.
R2 findings addressed. Both fixes verified against 4c229e9efaff:
- CRF-7 Mobile now renders
<Latency>unconditionally, soLatency's built-inCircleHelpIconfallback (witharia-label="Latency not available") closes the sr-only sentence in the no-latency state. Screen readers hear "Latency for {name}. Latency not available." mirroring desktop. - CRF-8
MobileMenu.stories.tsxgainsProxyWarningLatency(224 ms),ProxyCriticalLatency(471 ms), andProxyNoLatencyonMockPrimaryWorkspaceProxy.id. Coverage now matches the desktop trio.defaultProxyContextValuewas hoisted out ofmeta.argscleanly so the new stories can spread it.
One new Nit [CRF-9] noticed while verifying CRF-2's pattern across the two triggers: mobile's className gate tests the report object (latency ? ... : undefined), desktop's tests the number (latencies?.[selectedProxy.id]?.latencyMS ? ...). Divergent predicate for the same class-of-bug fix. Not observable today because ProxyLatencyReport.latencyMS: number never comes back as 0 in practice, but the safety argument travels with the desktop shape.
One quote worth keeping, from Pariston verifying the fix depth: "The chain reads symptom (silent screen reader) → visible cause (guard-only rendering of <Latency>) → actual cause (mobile did not adopt the 'always render <Latency>' shape that desktop had). The fix is at the actual cause."
🤖 This review was automatically generated with Coder Agents.
…rride on latencyMS
|
/coder-agents-review |
There was a problem hiding this comment.
R4 finding addressed. CRF-9 verified against 0ceeed37fa.
All findings across 5 rounds are now either author-fixed or author-accepted with reasoning:
- CRF-1, CRF-2, CRF-3, CRF-7, CRF-8, CRF-9: author-fixed and verified.
- CRF-4, CRF-5, CRF-6: author-accepted with proportional reasoning.
One verification detail worth noting: while confirming CRF-9, Netero traced ProxyLatencyReport.latencyMS: number and observed the value is initialized to 0 and populated from responseStart - requestStart or entry.duration in useProxyLatency.ts:163-183, so latencyMS === 0 is actually reachable in practice. CRF-9's original framing hedged it as "not observable today"; the fix turns out to have been more consequential than the Nit severity suggested. Filing this as an observation, not a re-classification: the code is right, the pattern is now consistent across triggers, and the class-of-bug fix is complete.
One quote worth keeping, from Hisoka on the fix depth: "The predicate also aligns with the Latency component's own !latency gate that swaps in CircleHelpIcon. Same falsy shape at both layers: when Latency would render the help icon, the caller no longer paints it text-content-primary. That is the whole beauty of the fix."
Approving.
🤖 This review was automatically generated with Coder Agents.
Updates the latency dropdown's collapsed views in the navbar:
ExternalImage) from the desktop trigger and the mobile "Workspace proxy settings" row.RadioIconinstead, colored viagetLatencyColor(matching the loading state used by theLatencycomponent on desktop).content-primary; only the icon carries the latency color.The expanded proxy lists are unchanged (they keep the proxy icon and colored latency text).
Story changes:
ClosedWarningLatencyandClosedCriticalLatencyto cover the icon color per latency level.