4.8 KiB
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
DashboardRouteconfigs insrc/lib/routes.ts(DASHBOARD_ROUTES) whosedatacarriesnavigation,page(liveCapable,rangeScoped,timed,feature),breadcrumbandentity; applications pass them tocomposeRoutes(), where a later config replaces a route by path. Pages are lazy and never exported frompublic-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(dropscursorandpageon any other change;keepCursorfor panel parameters). Relative times are resolved to ISO intzbefore calling the API; the zone is one per session (SessionZoneService), written into the URL oftimedpages byListStateService. - HTTP only through
HttpService(paths relative toapi/v1/, errors asApiRequestError); browser storage only throughStorageService. - Pages load through
injectListLoader()orinjectRefreshScheduler()(manualfor on-demand pages,pausedwith a reason);injectLiveCounters()polls the overview counters outside the header control. The shell pollsGET /api/v1/statusthroughinjectServerStatusPoll()intoServerStatusService, the one source of the status banners, the live chip and the Data pipeline card;InfoServiceholds edition, features, retention and limits. - Freshness is judged at the last response (
generatedAt) with the typingsfreshnessWindows(), never extrapolated by the ticker; running durations render withovd-duration, neverDate.now()in templates.
Building blocks
- Cards, sections, charts and empty states take a
headinginput, nevertitle(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
infoinput of tiles, cards, charts,TableColumnandEntityFact, with its text inINFO_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 fromchartSlots(), no zoom on wheel. - Identifiers appear once, with
ovd-copy-buttonbeside the visible value; navigation uses links, never row clicks. - Lists use
ovd-list-searchinside.ovd-filter-bar,ovd-room-chipfor the room filter, ranked sorts fromrankedSortReasons()andovd-data-table. - Messages use
ovd-notice(ovd-error-bannerfor errors with Retry) and enum labelsenumLabel()(format/labels.ts). - Icons are Material Symbols Rounded listed in
projects/dashboard-ui/icons.jsonand compiled byscripts/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 arelight-dark()pairs inprojects/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.mtsadds thesourcecondition;projects/dashboard-ui/src/testing/holds setup, shared providers and fixtures. vitest-base.config.mtsturns 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/viteand restart it.