Skip to Content
Low-CodeUse CasesUser Interfaces erstellen

User Interfaces erstellen

Mit Dashboard-2 (@flowfuse/node-red-dashboard) erstellen Sie direkt aus Ihren Flows moderne, responsive Web-Oberflächen. LowCode erweitert Dashboard-2 um spezielle Widgets für die Arbeit mit der Engine, wie Dynamic Forms und Dynamic Tables.

Dashboard-2 Grundlagen

Dashboard-2 organisiert die Oberfläche in einer klaren Hierarchie:

EbeneBeschreibungKonfiguration
UI BaseDie gesamte Dashboard-AnwendungTheme, Titel, Pfad
UI PageEine einzelne Seite/RouteName, Icon, Pfad
UI GroupEin Container auf der SeiteName, Breite, Seite
UI WidgetEin einzelnes UI-ElementTyp, Gruppe, Optionen

Aufbau einer Seite

Jedes Widget wird einer Group zugeordnet, jede Group einer Page, und jede Page gehört zur UI Base:

UI Base: "Meine App" (/dashboard) ├── Page: "Startseite" (/dashboard/home) │ ├── Group: "Übersicht" │ │ ├── Widget: ui-text (Willkommen) │ │ └── Widget: ui-chart (Statistiken) │ └── Group: "Aktionen" │ └── Widget: ui-button (Neuer Vorgang) └── Page: "Aufgaben" (/dashboard/tasks) └── Group: "Offene Aufgaben" └── Widget: ui-table (Aufgabenliste)

Wichtige Widgets

ui-text — Texte anzeigen

Zeigt dynamischen Text an, der sich bei neuen Messages aktualisiert:

// Function Node: Text vorbereiten msg.payload = `Aktuell ${flow.get("openTasks") || 0} offene Aufgaben`; return msg;

ui-button — Aktionen auslösen

Buttons senden beim Klick eine Message an den nächsten Node:

[ui-button: "Prozess starten"] → [fn: prepareStart] → [process-start: MyProcess] → [fn: showResult] → [ui-notification: "Prozess gestartet"]

ui-form — Formulare

Formulare sammeln strukturierte Eingaben vom Benutzer:

Konfiguration des ui-form Nodes:

Formular-Elemente: - Name (Text, required) - E-Mail (Email, required) - Abteilung (Dropdown: IT, HR, Finance) - Priorität (Dropdown: Hoch, Mittel, Niedrig) - Beschreibung (Multiline Text)

Verarbeitung der Formulardaten:

// Function Node: Formulardaten verarbeiten const formData = msg.payload; // Formulardaten stehen als Objekt zur Verfügung const request = { name: formData.Name, email: formData["E-Mail"], department: formData.Abteilung, priority: formData.Priorität, description: formData.Beschreibung, createdAt: new Date().toISOString() }; msg.payload = request; return msg;

ui-table — Tabellen

Zeigt Daten in tabellarischer Form mit Sortierung und Paginierung:

// Function Node: Tabellendaten vorbereiten const tasks = flow.get("tasks") || []; msg.payload = tasks.map(t => ({ "Aufgabe": t.name, "Status": t.state === "running" ? "Offen" : "Erledigt", "Erstellt": new Date(t.createdAt).toLocaleDateString("de-DE"), "Priorität": t.priority })); return msg;

ui-chart — Diagramme

Erstellt Linien-, Balken- und Kreisdiagramme:

// Function Node: Chartdaten vorbereiten (Balkendiagramm) msg.payload = [ { x: "Montag", y: 12 }, { x: "Dienstag", y: 8 }, { x: "Mittwoch", y: 15 }, { x: "Donnerstag", y: 6 }, { x: "Freitag", y: 10 } ]; msg.topic = "Erledigte Aufgaben"; return msg;

ProcessCube®-spezifische Widgets

Das Enterprise Image enthält spezialisierte Widgets für die Arbeit mit der Engine.

Dynamic Form

Der Dynamic Form-Widget rendert Formulare dynamisch basierend auf den FormFields eines UserTasks. Die Formularstruktur wird direkt aus dem BPMN-Prozess abgeleitet.

[usertask-event-listener: userTaskCreated] → [fn: prepareFormData] → [ui-dynamic-form: Formular anzeigen] → [fn: processResult] → [usertask-output: UserTask beenden]
// Function Node: prepareFormData const userTask = msg.payload; // Die FormFields des UserTasks werden automatisch als Formular gerendert msg.userTaskConfig = { userTaskInstanceId: userTask.id, processInstanceId: userTask.processInstanceId, formFields: userTask.formFields }; return msg;

Dynamic Table

Der Dynamic Table-Widget zeigt tabellarische Daten mit konfigurierbaren Spalten, Filterung und Aktionen an:

// Function Node: Dynamic Table konfigurieren msg.payload = { columns: [ { key: "name", label: "Name", sortable: true }, { key: "status", label: "Status", sortable: true }, { key: "date", label: "Datum", type: "date" }, { key: "actions", label: "Aktionen", type: "actions" } ], data: flow.get("processInstances") || [], pagination: { page: 1, pageSize: 10 } }; return msg;

UI Page Navigation

Der UI Page Navigation-Widget ermöglicht das programmgesteuerte Navigieren zwischen Dashboard-Seiten:

// Function Node: Zur Detailseite navigieren msg.payload = { page: "/dashboard/task-detail", params: { taskId: msg.taskId } }; return msg;

Vollständiges Dashboard-Beispiel

Das folgende Beispiel zeigt ein komplettes Task-Management-Dashboard mit Übersicht, Formular und Detail-Ansicht.

Seite 1: Aufgaben-Übersicht

Page: "Aufgaben" (/dashboard/tasks) Group: "Statistiken" (Breite: 6) [inject: Alle 30s] → [fn: loadStats] → [ui-text: Offene Tasks] [inject: Alle 30s] → [fn: loadStats] → [ui-chart: Tasks pro Tag] Group: "Aufgabenliste" (Breite: 6) [inject: Alle 10s] → [fn: loadTasks] → [ui-table: Aufgaben] [ui-table: Klick] → [fn: navigateToDetail] → [ui-page-navigation]
// Function Node: loadStats const tasks = flow.get("tasks") || []; const openCount = tasks.filter(t => t.state === "running").length; const doneCount = tasks.filter(t => t.state === "finished").length; msg.payload = `${openCount} offen / ${doneCount} erledigt`; return msg;
// Function Node: loadTasks const tasks = flow.get("tasks") || []; msg.payload = tasks .filter(t => t.state === "running") .sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt)) .map(t => ({ "ID": t.id.substring(0, 8), "Aufgabe": t.name, "Prozess": t.processModelId, "Erstellt": new Date(t.createdAt).toLocaleDateString("de-DE") })); return msg;

Seite 2: Neue Aufgabe erstellen

Page: "Neue Aufgabe" (/dashboard/new-task) Group: "Aufgabe erfassen" (Breite: 6) [ui-form: Aufgabenformular] → [fn: validateInput] → [process-start: CreateTask] → [fn: showSuccess] → [ui-notification: "Aufgabe erstellt"]
// Function Node: validateInput const formData = msg.payload; if (!formData.Titel || formData.Titel.length < 3) { msg.error = "Titel muss mindestens 3 Zeichen lang sein"; node.warn(msg.error); return null; // Flow stoppen } // Daten für Prozessstart vorbereiten msg.processModelId = "CreateTask_v1"; msg.payload = { title: formData.Titel, description: formData.Beschreibung || "", priority: formData.Priorität || "Mittel", assignee: formData.Verantwortlich }; return msg;

Responsive Design

Dashboard-2 unterstützt responsive Layouts. Die Breite einer Group wird in Grid-Einheiten angegeben (1-12, analog zu CSS Grid):

BreiteDesktopTabletMobil
12Volle BreiteVolle BreiteVolle Breite
6Halbe BreiteHalbe BreiteVolle Breite
4Ein DrittelHalbe BreiteVolle Breite
3Ein ViertelHalbe BreiteVolle Breite

Empfohlene Layouts

  • Formulare: Breite 6 (halbe Seite auf Desktop)
  • Tabellen: Breite 12 (volle Breite)
  • Statistik-Kacheln: Breite 3 (vier nebeneinander)
  • Charts: Breite 6 (zwei nebeneinander)

Theming

Dashboard-2 unterstützt Light Mode und Dark Mode. Das Theme wird in der UI-Base konfiguriert:

Standard-Farben anpassen

In den Dashboard-2 Einstellungen können Sie die Hauptfarben anpassen:

EigenschaftProcessCube® StandardBeschreibung
Primary#f7a823Hauptfarbe (ProcessCube® Orange)
Accent#333333Akzentfarbe
Background#ffffff / #1a1a1aHintergrund (Light/Dark)
Surface#f5f5f5 / #2d2d2dOberflächen (Light/Dark)

Eigenes CSS

Für fortgeschrittene Anpassungen können Sie Custom CSS über einen ui-template-Node einbinden:

<style> /* ProcessCube® Branding */ .v-toolbar { background-color: #f7a823 !important; } .v-btn--variant-elevated { background-color: #f7a823 !important; color: #000000 !important; } </style>

Best Practices

1. Daten serverseitig filtern

Senden Sie nur die Daten an das Dashboard, die tatsächlich angezeigt werden:

// Korrekt: Gefilterte Daten senden msg.payload = allTasks.filter(t => t.state === "running").slice(0, 50);

2. Updates begrenzen

Vermeiden Sie zu häufige Updates, um die Performance zu schonen:

[inject: Alle 10s] → [fn: loadData] → [ui-table]

3. Feedback geben

Zeigen Sie dem Benutzer immer Feedback nach Aktionen:

// ui-notification Node für Bestätigungen msg.payload = "Aufgabe erfolgreich erstellt"; msg.topic = "success"; // success, info, warning, error return msg;

4. Navigation konsistent halten

Verwenden Sie eine einheitliche Seitenstruktur mit klarer Navigation. Die Sidebar wird automatisch aus den konfigurierten Pages generiert.

Nächste Schritte