- Update all submodule URLs from gitea.centraal.wbd-rd.nl to gitea.wbd-rd.nl - Add settler as proper submodule in .gitmodules - Add agent skills, function anchors, decisions, and improvements - Add Docker configuration and scripts - Add manuals and third_party docs - Update .gitignore with secrets and build artifacts - Remove stale .tgz build artifact Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
113 lines
3.1 KiB
Markdown
113 lines
3.1 KiB
Markdown
# FlowFuse `ui-template` Manual (EVOLV Reference)
|
|
|
|
Source: https://dashboard.flowfuse.com/nodes/widgets/ui-template.html
|
|
|
|
## Purpose
|
|
|
|
Custom Vue 3 / Vuetify / HTML widget. Full scripting, scoped CSS, send/receive messages.
|
|
|
|
## Scopes
|
|
|
|
| Scope | Renders | Use Case |
|
|
|-------|---------|----------|
|
|
| Widget (Group) | Inside a ui-group | Custom gauges, tables, controls |
|
|
| Widget (Page) | On page, outside groups | Floating overlays, full-width banners |
|
|
| Widget (UI) | On every page | Global headers, footers |
|
|
| CSS (All Pages) | N/A — injects `<style>` | Global CSS overrides |
|
|
| CSS (Single Page) | N/A — injects `<style>` | Page-specific CSS |
|
|
|
|
## Properties
|
|
|
|
| Property | Type | Dynamic | Notes |
|
|
|----------|------|---------|-------|
|
|
| `group` | ref | No | Parent ui-group (Group scope) |
|
|
| `page` | ref | No | Parent ui-page (Page scope) |
|
|
| `width` | int | No | Columns |
|
|
| `height` | int | No | Row units |
|
|
| `format` | string | Yes | Vue template string |
|
|
| `storeOutMessages` | bool | No | Persist last output for late joiners |
|
|
| `passthru` | bool | No | Forward input to output |
|
|
| `templateScope` | string | No | `"widget:group"`, `"widget:page"`, `"widget:ui"`, `"page:style"`, `"site:style"` |
|
|
|
|
## Template Structure
|
|
|
|
```html
|
|
<template>
|
|
<v-btn @click="send({payload: 'clicked'})">Click</v-btn>
|
|
<p>Value: {{ msg.payload }}</p>
|
|
</template>
|
|
<script>
|
|
export default {
|
|
data() { return { local: 0 }; },
|
|
watch: {
|
|
msg(val) { this.local = val.payload; }
|
|
},
|
|
methods: {
|
|
doSend() { this.send({payload: this.local}); }
|
|
},
|
|
mounted() { /* one-time setup */ },
|
|
unmounted() { /* cleanup */ }
|
|
};
|
|
</script>
|
|
<style scoped>
|
|
p { color: #2196f3; }
|
|
</style>
|
|
```
|
|
|
|
## Built-in Variables
|
|
|
|
| Variable | Description |
|
|
|----------|-------------|
|
|
| `id` | This node's unique ID |
|
|
| `msg` | Latest received message (reactive) |
|
|
| `$socket` | Socket.io client for custom events |
|
|
|
|
## Sending Messages
|
|
|
|
```js
|
|
this.send({ payload: 42, topic: "my-topic" });
|
|
this.submit(); // sends FormData from <form>
|
|
```
|
|
|
|
## Receiving Messages
|
|
|
|
**Option A** — Vue `watch`:
|
|
```js
|
|
watch: { msg(newMsg) { /* react */ } }
|
|
```
|
|
|
|
**Option B** — Socket listener:
|
|
```js
|
|
mounted() {
|
|
this.$socket.on('msg-input:' + this.id, (msg) => { /* handle */ });
|
|
}
|
|
```
|
|
|
|
## Teleports (inject into dashboard chrome)
|
|
|
|
```html
|
|
<Teleport to="#app-bar-actions">
|
|
<v-btn>Custom Button</v-btn>
|
|
</Teleport>
|
|
```
|
|
|
|
Targets: `#app-bar-title`, `#app-bar-actions`.
|
|
|
|
## Vuetify Components
|
|
|
|
All Vuetify 3 components are available without import: `<v-btn>`, `<v-card>`, `<v-slider>`, `<v-data-table>`, etc.
|
|
|
|
## Dynamic Properties (`msg.ui_update`)
|
|
|
|
```js
|
|
msg.ui_update = { format: "<p>New template content</p>" };
|
|
```
|
|
|
|
## EVOLV Key Rules
|
|
|
|
1. Use templates sparingly — prefer built-in widgets when they fit.
|
|
2. For complex custom visualizations (SVG P&ID, animated schematics), template is the right choice.
|
|
3. Always use `<style scoped>` to avoid leaking CSS to other widgets.
|
|
4. Prefer `watch: { msg }` over socket listeners for simpler code.
|
|
5. Keep templates under 100 lines — split complex UIs into multiple template nodes.
|