Dashboard host contract
Ta treść nie jest jeszcze dostępna w Twoim języku.
A dashboard is a React module that the host loads into the workspace page, next to the sidebar. This page lists what the module must export and what the host gives it. For the steps to write one, see Develop a dashboard locally. The catalog fields and API procedures are in Dashboard procedures.
The default export is a React component that receives DashboardRootProps from
@overvis/hmi-shared/dashboard:
type DashboardTheme = "light" | "dark";type AppLocale = "en" | "pl" | "de" | "uk" | "ru";
interface DashboardRootProps { configuration: Record<string, unknown>; theme: DashboardTheme; locale: AppLocale; workspaceId: string; dashboardId: string;}configurationis the dashboard’s configuration, validated againstdashboardConfigTypebefore mount.parseDashboardConfiguration(type, configuration)narrows it to the static type.themeis"light"or"dark", with the system setting already resolved. Host tokens such astext-foregroundandbg-primaryfollow the theme without the prop.localeis the active UI language when the module’ssupportedLocaleslists it, and English otherwise; see Dashboards internationalization.workspaceIdis the open workspace, for workspace procedures such asparameter.listInventory. Entity procedures such asreport.preset.gettake only{ id }.dashboardIdis the dashboard’s own ID, for settings and diagnostic links.
The props change while the dashboard stays mounted, for example when the operator switches theme or language.
Module exports
Section titled “Module exports”| Export | Required | Content |
|---|---|---|
| default | Yes | React component that accepts DashboardRootProps |
dashboardConfigType | Yes | TypeBox type of the configuration, defined in config.ts |
supportedLocales | No | Literal array of the languages the copy implements, with English |
pages | No | Fixed pages in tab order, each a path and a name (a string or a per-language map) |
supportedLocales and pages are declared in manifest.ts and re-exported from the entry. A
module without supportedLocales is treated as supporting en, pl, uk, and ru. pages uses
the DashboardPage type of @overvis/hmi-shared/dashboard, with the home page / first. The
build records both, so tools that list dashboards show the same tab names.
The dashboard’s settings in Setup validate the configuration against dashboardConfigType and
block saving while it does not match, naming each problem by its path. Configuration schema in
the settings shows the schema the build writes from it, so describe each key in the type.
Minimal module
Section titled “Minimal module”A module with a config.ts and an entry:
import Type from "typebox";export const dashboardConfigType = Type.Object( { title: Type.Optional(Type.String()) }, { additionalProperties: false },);import { parseDashboardConfiguration, type DashboardRootProps,} from "@overvis/hmi-shared/dashboard";import { dashboardConfigType } from "./config.ts";export { dashboardConfigType } from "./config.ts";
export default function MyDashboard(props: DashboardRootProps) { const configuration = parseDashboardConfiguration(dashboardConfigType, props.configuration); return <div data-theme={props.theme}>{configuration.title ?? "Dashboard"}</div>;}Source files
Section titled “Source files”The Empty template starts a dashboard with these files:
src/dashboards/<dashboard-uuid>/ index.tsx # entry: re-exports the root component, dashboardConfigType, supportedLocales dashboard.tsx # default-exported root component config.ts # dashboardConfigType (required) manifest.ts # supportedLocales and optional pages config.schema.json # written by the buildThe entry is the first existing file of index.tsx, index.ts, index.jsx, and index.js; it
can define the default export itself or re-export it. manifest.ts holds literals and type imports
only, because the build evaluates it on its own.
Dashboards are styled with Tailwind classes in the dashboard folder’s .ts, .tsx, .js, and
.jsx files; any class works, including arbitrary values such as h-[80svh]. Classes in shared
folders such as src/lib are not picked up. The build writes the dashboard’s stylesheet itself and
takes no .css files or CSS imports. The host provides the workspace-ui base styles; see
styling.
Imports
Section titled “Imports”Dashboards share one React, one copy of @overvis/hmi-workspace-ui, and one TypeBox with the host.
The host supplies these packages at run time, so the dashboard’s build does not include them:
| Import | Content |
|---|---|
react, react-dom, and their jsx-runtime and client | React |
@overvis/hmi-shared and its subpaths | Props and other types, locales, formatters, schemas |
@overvis/hmi-workspace-ui | Live values, forms, report widgets, graphics, maps, trpc |
@overvis/hmi-workspace-ui/ui | shadcn UI primitives, charts, cn, toasts |
@overvis/hmi-workspace-ui/i18n | useTranslation and useLocale for the host’s UI messages |
typebox | Configuration types |
These are bundled with the dashboard:
lucide-reacticons, tree-shaken to the icons the dashboard uses;- other packages installed in the workspace project, such as
@vis.gl/react-google-mapsfor maps; - the dashboard’s own files under
src/dashboards/<id>/. A lazyimport()of its own modules works withReact.lazyandSuspense.
@overvis/hmi-workspace-ui/host is the application shell and is not available to dashboards. The
contents of each package are in @overvis/hmi-shared and
@overvis/hmi-workspace-ui.
Builds
Section titled “Builds”hmi build, which hmi push runs, writes per dashboard an ES module bundle with source maps, a
utilities-only stylesheet scoped to the dashboard, config.schema.json (the JSON Schema of
dashboardConfigType), and the hmi-dashboard.json manifest with the contract version,
supportedLocales, and pages. See the CLI reference.
The build fails, and nothing is published, when:
config.tsor thedashboardConfigTypeexport is missing;manifest.tsdeclares invalidsupportedLocalesorpages(duplicate paths, or not/first), or the entry does not re-export them directly from./manifest.ts;- type checking finds undefined names or a default component whose props do not match, reported with file and line;
- a local import or a workspace symbol cannot be resolved.
A successful build does not check rendering or live device behavior. Builds read no environment
variables or .env files, because published bundles reach every viewer of the workspace; pass
settings through the configuration. Scripts can run the same build with
@overvis/hmi-cli/dashboard-build.
When the host contract changes incompatibly, a dashboard built with older tools shows Dashboard needs a rebuild instead of loading. Update the HMI packages and push again.
Loading
Section titled “Loading”The cloud app runs a dashboard’s published build, from the moment the dashboard is created from its template and after each successful push. The local host runs its source and reloads it as you edit.
Before mounting, the host checks that the module has a default React component and the
dashboardConfigType export, and validates the configuration against it. While loading, the page
shows a skeleton. A failed load shows an error notice with Retry; for a configuration that fails
validation, editors, admins, and owners also get a link to the dashboard’s settings. The component
is then mounted inside the live-value provider with the props above.
A browser keeps a loaded dashboard for the rest of its session. Publishing through the assistant and reverting to a checkpoint reload open dashboards. After a push from the CLI or a Setup edit, a browser that already loaded the dashboard keeps the old build until the page is refreshed.
Navigation and subpages
Section titled “Navigation and subpages”A dashboard can own any number of pages under /workspace/<workspaceId>/d/<dashboardId>/.... The
cloud and local hosts accept the same deep links. The dashboard module, configuration, and
live-value provider stay mounted when its path, query, or anchor changes. All pages share one
dashboard’s access, source, configuration, and publication. The host adds no tabs, menus,
breadcrumbs, or page registry.
useDashboardNavigation and DashboardLink come from @overvis/hmi-workspace-ui. The hook
returns location, href(target), and navigate(target, { replace?, keepScroll? }).
location.path is relative to the dashboard root and starts with /; the root is /.
location.search is the query string, including ? when present, with every value kept as a
string. location.hash has no leading #. Path and anchor stay percent-encoded as in the URL, so
a location passes back to href or navigate unchanged.
const navigation = useDashboardNavigation();const filters = new URLSearchParams(navigation.location.search);const stationLocation = { path: `/stations/${stationId}`, search: filters.toString(), hash: `pump-${pumpId}`,};
<DashboardLink to={stationLocation}>Open station</DashboardLink>;// For an action that is not a link:await navigation.navigate(stationLocation);Targets accept optional path, search, and hash. An omitted path means /; an omitted query
and anchor are cleared. Query and anchor accept values with or without their leading punctuation.
Paths cannot contain dot segments, including encoded ones, or leave the dashboard; malformed
percent escapes, backslashes, and control characters are rejected. href returns a copyable URL.
DashboardLink is a real anchor that keeps modified clicks and new tabs; replace adds no history
entry. Navigation respects unsaved-change prompts.
A new path opens at the top of the page, as in a browser, and a query change on the same path keeps
the scroll position. A link with an anchor scrolls to that anchor instead. keepScroll keeps the
position on a new path too, for example for a detail overlay at its own path over the page the user
was reading; Back and Forward between the two keep it as well.
<DashboardLink to={{ path: `/pumps/${pumpId}`, search: navigation.location.search }} keepScroll> {pumpName}</DashboardLink>dashboardPageAt(paths, location.path) returns the page whose path matches, ignoring a trailing
slash. DashboardPageTabs links the pages as tabs with the current one marked, and
DashboardPageNotFound links an unknown path back to a chosen page. The host does not scroll to an
anchor whose element appears only after data loads; useAnchorScroll does.
Routes
Section titled “Routes”| Path | Page |
|---|---|
/workspace/$workspaceId | Opens the first enabled dashboard |
…/d/$dashboardId | The dashboard |
…/setup/dashboards | Catalog list; a name opens /d/$dashboardId |
…/setup/dashboards/new | Create dialog over the list |
…/setup/dashboards/new-from-report | Create dialog that picks a permanent report |
…/setup/dashboards/$dashboardId | Settings dialog over the list |
The sidebar lists enabled dashboards in the catalog order. The local host uses the same paths. Workspace pages describes each page.
Local host
Section titled “Local host”In a pulled workspace, pnpm dev runs the local host, LocalWorkspaceApp, with the workspace API
key that the pull created. It has the same workspace pages as the cloud app, without the assistant
panel. A dashboard loads from its source and updates as you edit while the page stays mounted. A
dashboard whose source is not pulled yet runs its published build with a warning. The props of
LocalWorkspaceApp are in @overvis/hmi-workspace-ui.
Assistant
Section titled “Assistant”In the cloud app, the assistant can point at an element of a running dashboard. It reads
data-context-* attributes, such as data-context-widget="pump-start" and
data-context-label="Start", from the picked element and its ancestors. Put them on the widgets
operators ask about. data-overvis-dashboard is reserved for the host.
Assistant draft preview
Section titled “Assistant draft preview”When the assistant creates or edits dashboard code, it checks its unpublished draft in a preview that shows the saved configuration and live equipment readings. The monitor icon (Watch assistant preview) in the assistant chat header shows that preview; the viewer is read-only, and Stop in the chat interrupts the assistant and keeps the draft.
In the preview, the assistant can navigate, open dialogs, fill forms, and try different screen sizes. Device writes and other lasting changes are refused there; readings come from real equipment. The preview loads Google Maps; other internet-hosted maps, images, and fonts are missing there, so build dashboards from the installed packages and workspace assets. If the preview stays unavailable, the assistant keeps the draft unpublished, and the chat offers a retry or publishing without the visual check. Build and render errors always block publishing.
Access
Section titled “Access”A dashboard runs with the workspace access of the signed-in user, or of the workspace API key in a local host. Writes go through the live-value procedures, which check permissions and writability on the server.