ui: declarative per-page tab titles via definePage title
This commit is contained in:
+6
-1
@@ -522,6 +522,9 @@ Define a page component with reactive state and rendering. Pages access data thr
|
||||
|
||||
```javascript
|
||||
export default definePage({
|
||||
// Browser tab title — applied to document.title on mount
|
||||
title: 'Zones - Vacuum Wall',
|
||||
|
||||
// Return initial state — models are obtained via getModel()
|
||||
init() {
|
||||
return {
|
||||
@@ -560,6 +563,7 @@ Pages get data from models reactive — they never call `apiFetch` in `load()`.
|
||||
|
||||
| Property | Required | Description |
|
||||
|---|---|---|
|
||||
| `title` | No | Full browser tab title, applied to `document.title` when the page mounts. Declare on every routed page so the tab title tracks navigation. |
|
||||
| `init()` | Yes | Returns initial state object. Wrapped with `reactive()` by `definePage`. Call `getModel(name)` here to access model data. |
|
||||
| `load(state)` | No | Optional one-time setup called on mount. Not used for data loading — use model layer instead. |
|
||||
| `render(state)` | Yes | Returns VNode(s) for the page. Read model data from `state.<model>.data`. |
|
||||
@@ -567,7 +571,7 @@ Pages get data from models reactive — they never call `apiFetch` in `load()`.
|
||||
|
||||
### Page Lifecycle
|
||||
|
||||
1. **Mount**: `init()` creates state → `load()` fires if defined → component tracked by key.
|
||||
1. **Mount**: `init()` creates state → tab title set from `title` (if declared) → `load()` fires if defined → component tracked by key.
|
||||
2. **Update**: Reactive state change (from model data update, navigation, etc.) → `render()` re-executes → VDOM diff patches DOM.
|
||||
3. **WS stream**: A `snapshot`/`versions`/`tick` message arrives → `modelSet()` patches the matching model in place → `model.data` update → reactivity triggers `render()`.
|
||||
4. **Unmount**: `onUnmount()` called if defined → component entry destroyed.
|
||||
@@ -1446,6 +1450,7 @@ Dev mode (`VACUUM_WALL_DEV` set) disables aggressive static asset caching.
|
||||
## Conventions
|
||||
|
||||
- **Pages** export `definePage({ … })` as default. Each page in `webui/static/pages/`.
|
||||
- **Tab title**: Pages declare `title: '<Page> - Vacuum Wall'`; `component.js` applies it to `document.title` on mount. No page should set `document.title` directly.
|
||||
- **Model-first data loading**: Pages get data from `getModel(name)` in `init()`. State-backed models are populated by the WebSocket (snapshot + per-subsystem deltas → `modelSet`); `modelFetch` is the HTTP fallback and the path for non-state models. Pages never call `apiFetch` in `load()`.
|
||||
- **Render pattern**: `renderGuard` early return → data rendering. Always return VNode array or single VNode.
|
||||
- **Multi-model pages**: Use `renderGuardMulti(title, subtitle, ...models)` for combined loading/error guard. `collectLoadingModels` is still exported for edge cases needing raw flags.
|
||||
|
||||
Reference in New Issue
Block a user