feat(dashboard): change pages without reloading the dashboard

nav.js (loaded on every signed-in page) follows links and GET forms to
other dashboard pages by fetching the page and swapping in its <main>,
title, page styles and page scripts; the sidebar, top bar and live
WebSocket stay. History entries, back/forward (with scroll positions,
also kept for a reload), deep links, #hash filters and breadcrumbs keep
working. What the old page set up is taken down first: its
document/window listeners, setInterval timers, Live watchers and
topics, DataTables, dialogs and what it appended to <body>. Page
scripts run again in order; DOMContentLoaded/load handlers they add run
once they have all run. A thin bar shows while loading; a failed fetch
shows an inline error with Try again / Open it normally.

Falls back to a normal load for anything that isn't a signed-in
dashboard page, when the account or permissions changed, and for pages
with module scripts or an import map (World 3D, property view and 3D,
UGC server) or data-nav="reload", and when leaving those. Unsaved-change
prompts (beforeunload) are asked before swapping.

Check: click around the sidebar and into accounts/characters: no white
flash, the footer's live indicator stays "live", back/forward return to
the same scroll position, breadcrumbs follow the path (Accounts > an
account > a character). Activity Log links with #search= still filter.
System Log's server picker works. Leaving Settings with a change asks
first. World 3D and a property's 3D view still load (normally). Pages
that poll (Server Health, Instance Load) stop polling once left
(browser network tab). Test: NavRulesJs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-09-29 01:57:06 -05:00
parent f13d15b4dd
commit f58255ab8a
10 changed files with 691 additions and 44 deletions

View File

@@ -363,6 +363,19 @@ Pages update on their own: world servers tell the dashboard (through master) as
and it pushes that to open browsers. Pages about one thing (a character, an account) reload in place when it changes,
unless you're typing, in which case they offer a refresh instead.
Moving between pages doesn't reload the dashboard: the next page is fetched and swapped in, and the menu, the top bar
and the live connection stay. A thin bar at the top shows while it loads; if it can't be fetched, the page says so with
**Try again** and **Open it normally**. Back, forward, reloading, links opened in a new tab and links with a `#` filter
work as before. Pages with a 3D view (World 3D, a property and its 3D view, the UGC server page) and pages reached from
them load normally. Leaving a page with unsaved changes (Settings, Vanity) asks first.
For page scripts (`static/js/nav.js`): listeners a page adds to `document` or `window`, its `setInterval` timers, its
`Live` watchers and its DataTables are removed when another page is swapped in; its scripts run again when it's opened
again, and `DOMContentLoaded`/`load` handlers they add run once they have all run. Elements a page appends to `<body>`
are removed unless marked `data-nav-keep`. `Nav.go(url)` opens a page. `document` gets `dash:page` after a page is
swapped in and `dash:leave` before. A page that must always load on its own adds `data-nav="reload"` to any element; a link with `data-nav="off"`
always loads normally.
View choices you make on the pages (show staff, filters, the 3D viewer's switches, ...) are saved to your account, so
they follow you to other browsers.