openvidu/openvidu-dashboard/dashboard-ce/frontend/AGENTS.md

65 lines
4.8 KiB
Markdown
Raw Normal View History

# Frontend (`@openvidu-dashboard/frontend` and `@openvidu-dashboard/ui`)
Angular 22 standalone, zoneless and signals: OnPush is the default (do not set it), `inject()` instead of constructor
injection, `@Service()` for root services, Signal Forms for forms. All UI lives in the library
`projects/dashboard-ui` (`src/lib/`: `core/` services by concern (`auth/`, `http/`, `state/`, `refresh/`,
`preferences/`, `ui/`), `shell/`, `components/` building blocks, `charts/`, `format/`, `routing/`, `features/<area>/`
pages with their data services and helpers, `routes.ts`); its README describes composition and the extension points.
Behaviour is specified in `openspec/specs/ui-*` and the `*-ui` specs.
A component with a template or style file has a folder of its own, named after it; small components that belong
together (badges, feedback, locks, search, tiles, zone) share a folder and its spec.
## Routes and pages
- Routes are `DashboardRoute` configs in `src/lib/routes.ts` (`DASHBOARD_ROUTES`) whose `data` carries `navigation`,
`page` (`liveCapable`, `rangeScoped`, `timed`, `feature`), `breadcrumb` and `entity`; applications pass them to
`composeRoutes()`, where a later config replaces a route by path. Pages are lazy and never exported from
`public-api.ts`, or the library build folds them into the initial chunk.
- The library holds what CE renders, locks included. What only an extending edition renders lives in its own
application: its pages replace the locked CE routes and its pieces of CE pages fill the extension points of the
library README. `features/analytics/` holds the Analytics page with the locks of its PRO strip.
## State and data
- The URL is the single source of a page's state through `QueryStateService` (drops `cursor` and `page` on any other
change; `keepCursor` for panel parameters). Relative times are resolved to ISO in `tz` before calling the API; the zone
is one per session (`SessionZoneService`), written into the URL of `timed` pages by `ListStateService`.
- HTTP only through `HttpService` (paths relative to `api/v1/`, errors as `ApiRequestError`); browser storage only
through `StorageService`.
- Pages load through `injectListLoader()` or `injectRefreshScheduler()` (`manual` for on-demand pages, `paused` with a
reason); `injectLiveCounters()` polls the overview counters outside the header control. The shell polls
`GET /api/v1/status` through `injectServerStatusPoll()` into `ServerStatusService`, the one source of the status
banners, the live chip and the Data pipeline card; `InfoService` holds edition, features, retention and limits.
- Freshness is judged at the last response (`generatedAt`) with the typings `freshnessWindows()`, never extrapolated by
the ticker; running durations render with `ovd-duration`, never `Date.now()` in templates.
## Building blocks
- Cards, sections, charts and empty states take a `heading` input, never `title` (Angular would render it as a native
tooltip over the whole host).
- A term a newcomer would not understand gets an info tip through the `info` input of tiles, cards, charts,
`TableColumn` and `EntityFact`, with its text in `INFO_TEXTS` (`format/info-texts.ts`); labels carry no hover text of
their own.
- Charts: bucket and zone in the `note` (`seriesNote()`), options merged into the kept instance (`bindChartOptions()`),
colours from `chartSlots()`, no zoom on wheel.
- Identifiers appear once, with `ovd-copy-button` beside the visible value; navigation uses links, never row clicks.
- Lists use `ovd-list-search` inside `.ovd-filter-bar`, `ovd-room-chip` for the room filter, ranked sorts from
`rankedSortReasons()` and `ovd-data-table`.
- Messages use `ovd-notice` (`ovd-error-banner` for errors with Retry) and enum labels `enumLabel()`
(`format/labels.ts`).
- Icons are Material Symbols Rounded listed in `projects/dashboard-ui/icons.json` and compiled by
`scripts/icons.mjs build`, which also takes the manifests of an extending application; lint fails on an icon used but
unlisted, listed but unused, or unknown. Theme tokens are `light-dark()` pairs in
`projects/dashboard-ui/styles/_tokens.scss`.
## Builds and tests
- Gzip budgets checked after `ng build` (`scripts/check-bundle-size.mjs`): 400 kB initial, 150 kB per lazy chunk, 250 kB
for the ECharts chunk.
- Unit tests: `pnpm exec ng test dashboard-ui --watch=false` (Vitest, jsdom; `--include=<spec>` for one file). `vitest-base.config.mts` adds the `source` condition;
`projects/dashboard-ui/src/testing/` holds setup, shared providers and fixtures.
- `vitest-base.config.mts` turns off Vitest's file system module cache, which would serve modules compiled from older
sources to the Angular builder. When the demo goes blank after a typings change ("does not provide an export named"),
delete `.angular/cache/*/frontend/vite` and restart it.