App shell & providers
This page covers how the application boots, wraps itself in providers, gates on authentication, and routes between workspaces and views.
Bootstrap flow
Entry points
- src/main.tsx —
mounts the React 19 root and wraps the app in
<BrowserRouter>. - src/App.tsx —
the router orchestrator. It composes
<AppProviders>, gates on auth status, guards routes, and loads the active workspace from the URL. - src/app/AppShell.tsx —
the authenticated container for a single workspace. It keeps the route params
(
workspaceId,viewId) in sync withWorkspacesContext, and renders the canvas, dialogs, and controls.
Provider composition
All providers are composed in a single place, src/app/providers/AppProviders.tsx:
<AuthProviderComponent>
<WorkspacesProvider>{children}</WorkspacesProvider>
</AuthProviderComponent>
The order matters: WorkspacesProvider is nested inside the auth provider so
that workspace state can be scoped to the signed-in user.id and so the auth
provider's live ArcGIS portal can be injected into the persistence layer.
Auth gate
The app has no anonymous access. App.tsx reads useAuth().status:
loading→ a loading state while the provider initializes.unauthenticated/error→ theSignInPanel.authenticated→ the routed application.
Routing
Routing is handled by React Router DOM 6. The main routes are:
| Path | Purpose |
|---|---|
/workspaces | The workspaces index (list, create, delete). |
/workspaces/:workspaceId/edit/views/:viewId | Edit a view (place, move, resize, configure). |
/workspaces/:workspaceId/views/:viewId | View a view (read-only). |
AppShell accepts a mode: "edit" \| "view" prop. The WorkspaceMode type
("edit" \| "view") flows through to the canvas, which disables dragging,
resizing, and configuration in view mode.
Header & About dialog
The header's profile dropdown (UserMenu) hosts workspace switching, connection
management, sign-out, and an About item. About opens a small dialog
(AboutDialog) that reports the deployed build identity — version, git
commit, and build time — alongside runtime diagnostics read from the browser
(display scale / device pixel ratio, viewport and screen size, language, and
platform). A one-click Copy diagnostics button copies all of it plus the URL
and full user-agent. This is the quickest way to confirm exactly which build a
tester is running and the display environment behind a rendering issue — display
scale and viewport in particular drive the canvas grid maths, so they often
explain scaling-related bugs.
The build identity is injected at build time via Vite define (see
vite.config.ts) and read through src/lib/version.ts:
| Constant | Source |
|---|---|
APP_VERSION | version in package.json |
GIT_SHA | git rev-parse --short HEAD at build ("unknown" outside a checkout) |
BUILD_TIME | build timestamp (ISO 8601) |
Because the bundle is built locally by deploy.sh, the commit + build time
uniquely identify what is live — more reliable than the semver alone, which is
bumped manually.
Read next
- State management — what
WorkspacesProviderexposes. - Authentication — the auth provider contract.