Skip to content

feat: single-page reshape with drilldown nav + shared world-map#18

Merged
AquiGorka merged 8 commits into
mainfrom
feat/single-page-hero-expanded-sketch
May 21, 2026
Merged

feat: single-page reshape with drilldown nav + shared world-map#18
AquiGorka merged 8 commits into
mainfrom
feat/single-page-hero-expanded-sketch

Conversation

@AquiGorka
Copy link
Copy Markdown
Contributor

Summary

Full SPA reshape against the v2 network-dashboard-platform backend (moonlight.network.v2 subprotocol) and the new @moonlight/ui/world-map shared component. Closes the old PR #17 (which diverged from the locked sketch).

What ships

  • Single-page layout below a @moonlight/ui brand nav. Dark theme via the upstream tokens, no inline color hardcoding except the per-event-kind accents.
  • Counter strip (6 tiles): COUNCILS / ACTIVE PPs / EVENTS-24h / ASSETS / THROUGHPUT / LATENCY. Repaints on every live event via the new LiveFrame.counters field — no more snapshot-only updates.
  • 3×3 detail grid below the counters:
    • Map (2×2 block) using the shared @moonlight/ui/world-map@v0.3.2 component. Hover-driven popover (countries sharing a council with the hovered one are highlighted; non-council countries dim everything).
    • CountryDetails (top-right): on map click, lists councils operating in that country with clickable rows.
    • CouncilDetails (middle-right): on council click, shows council metadata + member PPs.
    • ProviderDetails (bottom-right): on PP click, shows the PP's pubkey, label, cross-council membership, and recent bundle count.
    • ActivityFeed (bottom 2 cols): 6+1 event-kind cards, 5-min TTL, 10 visible, colour-coded by kind.
  • Sparklines + asset breakdown row below the grid.
  • Drop topology view — visual real estate replaced by the more useful drilldown chain (country → council → PP).

Commits

  1. feat: 5-section single-page reshape against network-dashboard-platform v2
  2. feat(ui): restore @moonlight/ui nav + dark-theme tokens
  3. chore: refresh deno.lock for @moonlight/ui nav + layout imports
  4. feat(world-map): migrate §5 to @moonlight/ui/world-map@v0.3.2 with hover popover
  5. feat(activity-feed): card TTL 8s → 5 min, max-visible 5 → 10
  6. refactor(layout): drop topology, add Country + Provider details drilldown in a 3x3 grid
  7. feat: repaint counter strip on every live event
  8. chore: release v0.2.12

Test plan

  • deno fmt --check clean
  • deno lint clean
  • deno task check clean
  • deno task test — 13 passed
  • deno task build clean (dev + production)
  • Smoke against a populated local stack: dashboard at :3040 renders all sections, counter strip updates live, drilldown chain works end-to-end (country click → council list → PP card), world map highlights reachable jurisdictions on hover, sparklines + asset breakdown populated, activity feed paints all 7 event kinds

Dependencies

  • Requires network-dashboard-platform (companion PR) to be deployed first — frontend assumes LiveFrame.counters is present.
  • Consumes @moonlight/ui@v0.3.2 (already released).

Awaiting PM review + merge.

AquiGorka added 8 commits May 19, 2026 11:12
…m v2

Replaces the v0.2.10 multi-page Map/Councils/Council-detail/Transactions
architecture with a single-page hero layout per the locked sketch:

  §1 Counter strip (6 tiles)
  §2 Topology + Activity feed (side-by-side, click council to expand §3)
  §3 Council details panel (collapsed until topology click)
  §4 Sparklines (60m) + Asset breakdown (24h) side-by-side
  §5 World map

WebSocket-driven (no HTTP polling). Wire subprotocol bumped to
moonlight.network.v2 in step with the backend. World-map SVG +
jurisdiction-by-geo logic carried forward from v0.2.10.

Drops obsolete modules: router, nav, stellar lib, version-check, plus
the four removed multi-page views. CSP simplified — public anonymous
dashboard, no auth boundary, 'unsafe-inline' on style-src is acceptable.
Wraps the 5-section dashboard in @moonlight/ui's renderNav + pageLayout
(same pattern as provider-console / council-console) so the brand label
'Network Dashboard · v${version}' + nav strip live above the content.
build.ts again concatenates tokens.css + base-styles.css + nav.css from
the pinned @moonlight/ui@v0.3.1 tag.

app-styles.css rewritten to consume the upstream dark tokens (--bg /
--surface / --border / --text / --text-muted / --primary / --active /
--pending / --inactive) instead of the ad-hoc light palette. Event-kind
accents move from background fills to left-border + glyph-coloured
accents so cards read against the dark surface. World-map land paths
get a CSS override (`fill: var(--border) !important`) to match the
theme.
…ver popover

Replaces the local lib/world-map.ts with the shared component and reworks
views/world-map.ts into a thin section wrapper that drives the new
generic onHover + setSlot surface:

  - hovered country → `hovered` slot (highlighted)
  - countries sharing a council with the hovered one → `reachable` slot
  - everything else → `dimmed` slot
  - a cursor-tracked popover lists each council in the hovered country
    (name + provider count) or 'No councils' when the country has none

The map component stays agnostic — it only fires onHover and exposes
setSlot. All council-shaped reasoning lives in this view. CSS for the
three slots + the popover ships in app-styles.css.

Build pipeline pulls world-map/world-map.css from the shared
@moonlight/ui@v0.3.2 tag alongside tokens / base-styles / nav.

Drops the now-redundant lib/world-map.ts + lib/geo_test.ts.
Cards now stay long enough to read in the new trio layout instead of
flicking past in a few seconds, and the visible cap grew to keep
recent history available across the longer TTL.
…down in a 3x3 grid

The topology view added little beyond what the world map + per-country
council list already convey, so it's removed entirely.

New layout below the counter strip is a single 3x3 grid:

  +-----+-----+--------------+
  | map | map |   countries  |  <- CountryDetails (click a country)
  +-----+-----+--------------+
  | map | map |   councils   |  <- CouncilDetails
  +-----+-----+--------------+
  | events events| providers |  <- ActivityFeed + ProviderDetails
  +--------------+-----------+

Drilldown chain wired in app.ts:

  click country on map -> CountryDetails lists the councils there ->
  click a council in that list -> CouncilDetails populates ->
  click a PP in CouncilDetails -> ProviderDetails populates

Each grid cell scrolls vertically when content overflows its row
height; section headers stay put. The Country / Council / Provider
panels get `overflow-y: auto` on their inner content lists; the
activity feed list already had it.

WorldMap exposes `setOnCountryClick` + `setSelectedCountry` so the
clicked-country highlight is persistent (independent of the hover
state that drives the popover + reachable highlight). CouncilDetails
exposes `setOnPpClick`. CountryDetails exposes `setOnCouncilClick`.
App.ts wires them together in one place.
LiveFrame mirror gains the new `counters` field. ws-client passes it
through to the onEvent handler. app.ts calls `counters.render(live)`
instead of the old `bumpFromLiveEvent()` hack that only ticked
eventsLast24h.

All 6 counter tiles (COUNCILS / ACTIVE PPs / EVENTS-24h / ASSETS /
THROUGHPUT / LATENCY) now update in real time without waiting for a
fresh snapshot.
@AquiGorka AquiGorka merged commit fef64ca into main May 21, 2026
5 checks passed
@AquiGorka AquiGorka deleted the feat/single-page-hero-expanded-sketch branch May 21, 2026 13:25
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