Work in progress
Frontend for Sobek — Entur's national vehicle registry (Nasjonalt Materiellregister).
↻ Deployment(s) : dev
💡 Sandbox/mind-maps : entur.github.io/hathor
- React 19 + TypeScript
- Vite
- Material UI v7
- GraphQL (
graphql-request) - OIDC authentication (
react-oidc-context)
npm install
npm run dev # Dev server on http://localhost:5000Requires a running Sobek backend (default: http://localhost:37999).
| Command | Description |
|---|---|
npm run dev |
Start dev server (uses dev API) |
npm run local |
Start dev server (uses local Sobek at 127.0.0.1:37999) |
npm run build |
Type-check and build (build/) |
npm run lint |
ESLint |
npm run format |
Prettier auto-format |
npm run e2e |
Playwright tests (mocked GraphQL) |
npm run e2e:local-backend |
Playwright tests against a live local Sobek |
docs/architecture.html is a standalone, interactive diagram of the component architecture — from App.tsx down through the generic wrappers (GenericDataViewPage, GenericDetailsPage) to every feature view. Open it in a browser (it loads D3 from a CDN); click a widget chip to expand its detail.
Keeping it in sync: the diagram is driven by docs/architecture-data.js, a generated metafile. When routes or views change in src/App.tsx, regenerate it with npm run gen:arch. See the RUN section of the JSDoc header in scripts/gen-arch-metafile.mjs for details.
Hathor's src/ mixes two organizational styles. Before adding files, know which one you're touching.
Vertical (feature) folders:
auth/— OIDC bootstrap, ProtectedRoute, login flow, auth utilities.config/— runtime config fetch (fetchConfig.ts).theme/—createThemeFromConfig, MUI theme module augmentation (theme-config.d.ts).data/<feature>/— production domain folders (vehicles/,vehicle-types/,deck-plans/,vehicle-imports/). Each holds the data hook, view config, editor, cells, types, and View + Details components for one entity.graphql/— GraphQL operations grouped by feature.locales/— i18next translation files (en/,nb/).
Horizontal (file-kind) folders:
components/— UI components grouped by sub-area (data/,search/,header/,sidebar/,dialogs/,common/,auth/).hooks/— global hooks shared across features.pages/— generic infrastructure (GenericDataViewPage,GenericDetailsPage) and theHomepage. Entity Views live indata/<feature>/, not here.utils/— domain-neutral helpers (iconLoaderUtils.ts).contexts/— top-level React contexts not yet hosted in feature folders (configContext,CustomizationContext,EditingContext,SessionContext).static/— static assets.
Where new files go:
- New entity (data-table backed) →
data/<feature>/. Data hook, view config, editor, cells, types, and the View component live together. Add a route inApp.tsx. - New non-entity routed page →
pages/. - New hook used by ≥2 features →
hooks/. Single-feature hook → next to its caller indata/<feature>/. - New
*Types.tsfile → next to its primary consumer. Feature types underdata/<feature>/; types that pair with shared infrastructure go with that infra (e.g.pages/viewConfigTypes.ts,graphql/paginationTypes.ts,components/data/dataTableTypes.ts). Don't recreatesrc/types/. - JSX →
.tsx. No JSX →.ts.
Some contexts (configContext, CustomizationContext) and a few hooks haven't migrated to their feature folders yet — see OPEN_QUESTIONS.md for tracked design ambiguities.
Hathor is a fork of Inanna, Entur's React data-registry starter. Extending it — new entity views, theming, custom icons — follows the Inanna extend-fork workflow; see DEV_GUIDE.md for the pointer.
Known design ambiguities are tracked in OPEN_QUESTIONS.md.