Frontend reference¶
Midsummer has two separate Angular single-page apps. They are different projects with different framework versions and do not share component code.
App |
Dir |
Framework |
Purpose |
|---|---|---|---|
Main event SPA |
|
Angular 21.x + PrimeNG 21.x (+ Kendo) |
register, vendors, schedule, staff, shop, dashboard, displays |
Tenant admin SPA |
|
Angular 19.x + PrimeNG 19.x |
org-level: events, settings, domains, memberships, api-tokens, stripe-keys, billing, connections |
Both use TailwindCSS 4.x with the Aura preset (indigo primary). Built assets
are served from front/static/ui/ via WhiteNoise.
Main SPA (ui/) layout¶
ui/src/app/
apps/<module>/ feature components per Django app:
register, vendors, schedule, staff, shop, dashboard, displays
register-form-components/ the form builder (see custom-form-system)
primatives/ one folder per field type
*-components.ts the registries
register-form-component-factory/ the dynamic renderer
services/ REST + shared services (rest, qr-scanner, jury-websocket,
reports, registration-association, schedule-*, ...)
shared/, components/ reusable UI (app-title-bar, nice-error)
guards/, pipes/ route guards, custom pipes
app.routes.ts route table (/register, /vendors, /schedule, /staff, /shop, /displays)
app.config.ts standalone bootstrap + PrimeNG theme provider
ui/public/data/ static assets (e.g. previous-years registration reference data)
How Django serves the SPA¶
The Angular apps are compiled into Django static files by the render scripts
(render-ui-elements.sh, render-tenant-ui-elements.sh), then Django serves a
thin shell template via midsummer.common.views.angular_page /
angular_page_event_protected that boots the named app. Per-module page routes
are permission-gated in Python before the shell is served.
See Request resolution.
The form system on the frontend¶
The frontend half of the JSON form builder lives entirely under
ui/src/app/apps/register/register-form-components/ — including the vendor,
schedule, and shop form components (historically colocated there). See
the custom form system for the full theory.
Notable components (high level)¶
register: checkin, rapid-checkin (+ display), merch-pick, merch-summary, merch-adjustment, metrics2, reports, badge settings, audit-log, staff-management-ping, name-watch-list, checkin-kiosks, stripe-transactions, and the form editor + all form primitives.
vendors: vendor-detail, vendor-display, vendor-checkin-form-viewer, vendor-jury-display, vendor-ping-conversations, vendor-task-component.
schedule: schedule-index, editor/editor2 (Kendo), form-editor, slot-editor, digital-signage, panel-details, responses, import/export, rooms/categories/tracks.
staff: staff-index, staff-hr (+ title dialogs), roster/shifts.
shop: items, cart, fulfillment terminals.
shared: app-title-bar, nice-error.
Services of note¶
rest (HTTP), qr-scanner, jury-websocket, register-reports,
registration-association, rapid-checkin, schedule-display,
schedule-edit, schedule, register-metrics2, registration-edit-log.
Build & type-check¶
# After editing, rebuild the SPA into Django static files:
./render-ui-elements.sh # ui/
./render-tenant-ui-elements.sh # tenantui/
# Fast type-check during iteration:
cd ui && npx ngc --noEmit -p tsconfig.app.json
# Full build:
cd ui && npx ng build
Exit 0 = pass. See First steps → Build & test gates.
Deep dive¶
The exhaustive component-by-component listing lives in
documentation/frontend-structure.md (maintained by the syncer workflow).