fix(dashboard): UX polish pass 1 for the stakeholder demo
UX polish pass 1 for the stakeholder demo. Seven renderer fixes, all confirmed against the current 1000-user render. Dashboard is the static D3 app in internal/renderer/static/; source JS in src/*.js is concatenated into assets/app.src.js by make static.
Fixes
- I1 Influence ranking percentage clipped (
assets/style.css.influence-score). The influence percentage truncated to one digit ("9" not "97%") at the panel's right edge. Reserve a fixed-width score column (3.25rem) and let the username column absorb the table slack, so the full percentage always fits. - G1 Groups workshop card drops KEY USERS at zero (
src/05-groups.js). KEY USERS was conditionally rendered behindif (groupHighInf > 0), so a zero-key-user card showed only two stats and broke the three-stat grid. Always render the KEY USERS stat, showing0when zero, exactly like HEALTH IMPACT was fixed previously. - T1 IDs/Names toggle first-load race (
src/00-header.js,src/10-ui.js,src/01-core.js).identities.jsonwas fetched by two separate fetches; toggling Names before the fetch resolved did nothing ("works half the time"). Fix: a single fetch (inloadData) storesstate.identities; the toggle's own on-demand fetch is removed; the toggle is disabled until identities load; and a re-apply hook (applyIdentitiesLoaded, called fromonDataReady) re-renders the active views when identities resolve so an early toggle takes effect. The toggle still works after load on all views. - H1 Health pipeline stray selected border (
src/02-health.js). The GROUP card got a default accent border as if selected. Removed the default-active stage logic so all five pipeline cards (COLLECT/PROFILE/IDENTIFY/GROUP/TARGET) render visually equal; only hover gives feedback. - H2 Health uncontained insight paragraph (
src/02-health.js,assets/style.css). The "No trend history yet..." insight rendered as loose floating text. Wrapped it in a carded callout (.pipeline-insight: border, background, border-radius) so it reads as a contained element. - A1 Adoption archetype pill clipping (
assets/style.css, heatmap row label). Widened the heatmap archetype row labels (172px desktop, 132px narrow) and let the pill size to content so the longest labels ("Platform Engineer", "Solo Contributor") are not clipped. - P2 Profiles USER column long-name truncation (
assets/style.css). Confirmed and fixed: the USER column was capped at 140px and ellipsis-truncated the longest usernames (wolfgang_amadeus_mozart, martin_luther_king_jr, napoleon_bonaparte). Widened to 220px.
Deferred
- R5 duplicate Archetype filter (
#archetype-filtervs#enablement-archetype-filter): a cross-view rewire held for pass 2. Not touched.
Tests
Committed structural regression tests in internal/renderer/render_test.go, each fail-on-old:
TestRender_WorkshopCardAlwaysHasKeyUsers— KEY USERS stat emitted unconditionally; theif (groupHighInf > 0)guard is gone.TestRender_IdentitiesSingleFetchWithReapply— exactly oneidentities.jsonfetch;applyIdentitiesLoadedhook defined and called on resolve; the duplicate on-demand fetch branch is gone.TestRender_HealthInsightIsCarded— insight wrapped in.pipeline-insight(defined as a carded callout in CSS); no default-active pipeline stage (H1).
Validation
make static regenerates app.src.js (bundle in sync). make check, go vet ./..., CGO_ENABLED=1 go test -race ./..., golangci-lint run (0 issues) all pass. Coverage 69.9% (>= 65%).