Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions hub/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ The in-repo JupyterHub image (`mddash-hub`) powering MDDash's hub: stock `quay.i
- **`window.appConfig` injection**: each entry HTML has an inline `<script>` with Jinja `| tojson` expressions that JupyterHub renders per request. It MUST be a plain inline script (no `type=`) so Vite preserves it verbatim. In `vite dev` the script is invalid JS (Jinja braces) and `window.appConfig` stays undefined — pages fall back to production-realistic defaults from `src/lib/config.ts`.
- **Data flow**: pages call the Hub REST API (`/hub/api/…`) with the rendered `xsrf` token in the `X-XSRFToken` header; spawn progress uses `EventSource` on `progress_url` with bounded reconnect/backoff (`src/lib/progress.ts`). The OAuth consent page is a plain HTML form POST (the hub consumes form data).
- **Build validation**: `pnpm run build` also runs `scripts/validate-build.mjs`, which asserts all 12 entries exist in `dist/`, carry the appConfig injection, and reference assets only under `/hub/static/hub-ui/`.
- **Page chrome is shared, never inlined**: status pages compose their hero markup from `ui/src/components/Hero.tsx` and card pages from `IconCard.tsx`. Duplicating that markup in a page is forbidden — extend the shared components instead.
- **`not_running` is a dispatcher, not the stopped-server page**: the hub's Python handlers always render `not_running.html` for `/user/:name` with no server, so the stopped state can't be a hub route — our template client-side redirects to `/hub/home` and only renders the two states home can't model (failed spawn, implicit-spawn countdown).

## Non-Obvious Gotchas

Expand Down
2 changes: 1 addition & 1 deletion hub/ui/admin.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
userName: {{ user.name | tojson }},
xsrf: {{ xsrf_token | default("") | tojson }},
logoutUrl: {{ logout_url | default("") | tojson }},
adminAccess: {{ admin_access | default(false) | tojson }},
adminAccess: {{ admin_access | default(user.admin) | default(false) | tojson }},
announcement: {{ announcement | default(none) | tojson }},
apiPageLimit: {{ api_page_limit | default(500) | tojson }}
};
Expand Down
2 changes: 1 addition & 1 deletion hub/ui/home.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
userName: {{ user.name | tojson }},
xsrf: {{ xsrf_token | default("") | tojson }},
logoutUrl: {{ logout_url | default("") | tojson }},
adminAccess: {{ admin_access | default(false) | tojson }},
adminAccess: {{ admin_access | default(user.admin) | default(false) | tojson }},
{% if announcement_home is string %}
announcement: {{ announcement_home | default(none) | tojson }},
{% else %}
Expand Down
2 changes: 1 addition & 1 deletion hub/ui/not_running.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
baseUrl: {{ base_url | default("") | tojson }},
userName: {{ user.name | tojson }},
logoutUrl: {{ logout_url | default("") | tojson }},
adminAccess: {{ admin_access | default(false) | tojson }},
adminAccess: {{ admin_access | default(user.admin) | default(false) | tojson }},
announcement: {{ announcement | default(none) | tojson }},
failed: {{ failed | default(false) | tojson }},
serverName: {{ server_name | default("") | tojson }},
Expand Down
2 changes: 1 addition & 1 deletion hub/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"format:check": "prettier --check \"src/**/*.{ts,tsx,css}\""
},
"dependencies": {
"@e-infra/design-system": "^0.1.8",
"@e-infra/design-system": "^0.1.9",
"lucide-react": "^1.16.0",
"react": "^19.2.5",
"react-dom": "^19.2.5",
Expand Down
Loading