Skip to main content

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 with WorkspacesContext, 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 → the SignInPanel.
  • authenticated → the routed application.

Routing

Routing is handled by React Router DOM 6. The main routes are:

PathPurpose
/workspacesThe workspaces index (list, create, delete).
/workspaces/:workspaceId/edit/views/:viewIdEdit a view (place, move, resize, configure).
/workspaces/:workspaceId/views/:viewIdView 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:

ConstantSource
APP_VERSIONversion in package.json
GIT_SHAgit rev-parse --short HEAD at build ("unknown" outside a checkout)
BUILD_TIMEbuild 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.