Initial commit
BIN
node_modules/node-red-dashboard/nodes/icons/ui_button.png
generated
vendored
Normal file
|
After Width: | Height: | Size: 336 B |
BIN
node_modules/node-red-dashboard/nodes/icons/ui_chart.png
generated
vendored
Normal file
|
After Width: | Height: | Size: 344 B |
BIN
node_modules/node-red-dashboard/nodes/icons/ui_colour_picker.png
generated
vendored
Normal file
|
After Width: | Height: | Size: 650 B |
BIN
node_modules/node-red-dashboard/nodes/icons/ui_date_picker.png
generated
vendored
Normal file
|
After Width: | Height: | Size: 153 B |
BIN
node_modules/node-red-dashboard/nodes/icons/ui_dropdown.png
generated
vendored
Normal file
|
After Width: | Height: | Size: 236 B |
BIN
node_modules/node-red-dashboard/nodes/icons/ui_form.png
generated
vendored
Normal file
|
After Width: | Height: | Size: 232 B |
BIN
node_modules/node-red-dashboard/nodes/icons/ui_gauge.png
generated
vendored
Normal file
|
After Width: | Height: | Size: 507 B |
BIN
node_modules/node-red-dashboard/nodes/icons/ui_numeric.png
generated
vendored
Normal file
|
After Width: | Height: | Size: 407 B |
BIN
node_modules/node-red-dashboard/nodes/icons/ui_slider.png
generated
vendored
Normal file
|
After Width: | Height: | Size: 216 B |
BIN
node_modules/node-red-dashboard/nodes/icons/ui_switch.png
generated
vendored
Normal file
|
After Width: | Height: | Size: 396 B |
BIN
node_modules/node-red-dashboard/nodes/icons/ui_template.png
generated
vendored
Normal file
|
After Width: | Height: | Size: 413 B |
BIN
node_modules/node-red-dashboard/nodes/icons/ui_text.png
generated
vendored
Normal file
|
After Width: | Height: | Size: 409 B |
BIN
node_modules/node-red-dashboard/nodes/icons/ui_toast.png
generated
vendored
Normal file
|
After Width: | Height: | Size: 353 B |
100
node_modules/node-red-dashboard/nodes/locales/de/ui_base.json
generated
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
{
|
||||
"ui_base": {
|
||||
"label": {
|
||||
"dashboard": "Dashboard",
|
||||
"category": "Dashboard",
|
||||
"title": "Titel",
|
||||
"options": "Optionen",
|
||||
"date-format": "Datumsformat",
|
||||
"sizes": "Größen",
|
||||
"horizontal": "Horizontal",
|
||||
"vertical": "Vertikal",
|
||||
"widget-size": "1x1 Widget-Größe",
|
||||
"widget-spacing": "Widget-Abstände",
|
||||
"group-padding": "Gruppenabstände innen",
|
||||
"group-spacing": "Gruppenabstände außen",
|
||||
"layout": "Layout",
|
||||
"angular": "Angular",
|
||||
"theme": "Theme",
|
||||
"site": "Site"
|
||||
},
|
||||
"auto": "Auto",
|
||||
"title": "Node-RED Dashboard",
|
||||
"layout": {
|
||||
"tab-and-link": "Tabs & Links",
|
||||
"tab": "Tab",
|
||||
"link": "Link",
|
||||
"group": "Gruppe",
|
||||
"edit": "Bearbeiten",
|
||||
"spacer": "Abstand",
|
||||
"layout": "Layout",
|
||||
"layout-editor": "Dashboard Layout-Editor",
|
||||
"width": "Breite",
|
||||
"auto": "Automatische Größenanpassung",
|
||||
"manual": "Manuelle Größenanpassung"
|
||||
},
|
||||
"theme": {
|
||||
"style": "Stil",
|
||||
"custom-profile": "Benutzerdefiniertes Profil",
|
||||
"custom-profile-name": "Erscheinungsbild ohne Titel 1",
|
||||
"base-settings": "Basiseinstellungen",
|
||||
"page-settings": "Seiteneinstellungen",
|
||||
"page": {
|
||||
"title": "Hintergrund Titelleiste",
|
||||
"page": "Hintergrund Seite",
|
||||
"side": "Hintergrund Seitenleiste"
|
||||
},
|
||||
"group-settings": "Gruppeneinstellungen",
|
||||
"group": {
|
||||
"text": "Gruppentext",
|
||||
"border": "Gruppenrand",
|
||||
"background": "Gruppenhintergrund"
|
||||
},
|
||||
"widget-settings": "Widget-Einstellungen",
|
||||
"widget": {
|
||||
"text": "Widget-Text",
|
||||
"colour": "Widget-Farbe",
|
||||
"background": "Widget-Hintergrund"
|
||||
}
|
||||
},
|
||||
"style": {
|
||||
"light": "Hell (Standard)",
|
||||
"dark": "Dunkel",
|
||||
"custom": "Benutzerdefiniert",
|
||||
"primary": "Primär",
|
||||
"accents": "Akzente",
|
||||
"background": "Hintergrund",
|
||||
"warnings": "Warnungen",
|
||||
"palette": "Hell / Dunkel"
|
||||
},
|
||||
"base": {
|
||||
"colour": "Farbe",
|
||||
"font": "Schriftart"
|
||||
},
|
||||
"font": {
|
||||
"system": "System-Schriftart (Standard)"
|
||||
},
|
||||
"site": {
|
||||
"title": "Node-RED Dashboard",
|
||||
"date-format": "DD.MM.YYYY"
|
||||
},
|
||||
"title-bar": {
|
||||
"show": "Titelleiste anzeigen",
|
||||
"hide": "Titelleiste verbergen"
|
||||
},
|
||||
"swipe": {
|
||||
"no-swipe": "Kein Wischen zwischen Tabs",
|
||||
"allow-swipe": "Wischen zwischen Tabs zulassen"
|
||||
},
|
||||
"lock": {
|
||||
"clicked": "Klicken, um das Seitenmenü anzuzeigen",
|
||||
"locked": "Seitenmenü immer anzeigen",
|
||||
"locked-icon": "Nur Icons anzeigen"
|
||||
},
|
||||
"temp": {
|
||||
"allow-theme": "Node-RED-Erscheinungsbild",
|
||||
"no-theme": "Angular-Erscheinungsbild in ui_template",
|
||||
"none": "Angular-Erscheinungsbild"
|
||||
}
|
||||
}
|
||||
}
|
||||
24
node_modules/node-red-dashboard/nodes/locales/de/ui_button.json
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"ui_button": {
|
||||
"label": {
|
||||
"group": "Gruppe",
|
||||
"size": "Größe",
|
||||
"icon": "Icon",
|
||||
"optionalIcon": "Optionales Icon",
|
||||
"label": "Beschriftung",
|
||||
"optionalLabel": "Optionale Beschriftung",
|
||||
"tooltip": "Tooltipp",
|
||||
"optionalTooltip": "Optionaler Tooltipp",
|
||||
"color": "Farbe",
|
||||
"optionalColor": "Optionale Text/Icon-Farbe",
|
||||
"background": "Hintergrund",
|
||||
"optionalBackgroundColor": "Optionale Hintergrundfarbe",
|
||||
"whenClicked": "Sende beim Klicken:",
|
||||
"payload": "Payload",
|
||||
"topic": "Topic",
|
||||
"emulateClick": "Emuliere einen Klick bei einer eingehenden Nachricht:",
|
||||
"className": "Klasse",
|
||||
"classNamePlaceholder": "Optionale(r) CSS-Klassenname(n) für das Widget"
|
||||
}
|
||||
}
|
||||
}
|
||||
25
node_modules/node-red-dashboard/nodes/locales/de/ui_chart.html
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<script type="text/html" data-help-name="ui_chart">
|
||||
<p>Zeichnet Eingangswerte in ein Diagramm, welches entweder ein zeitbasiertes Liniendiagramm,
|
||||
ein Balkendiagramm (vertikal oder horizontal) oder ein Kreisdiagramm sein kann.</p>
|
||||
<p>Jede eingehende <code>msg.payload</code>-Nachricht wird in einen Zahlenwert konvertiert.
|
||||
Wenn die Konvertierung fehlschlägt, wird die Nachricht ignoriert.</p>
|
||||
<p>Die Minimum- und Maximum-Werte für die <b>Y-Achse</b> sind optional.
|
||||
Ohne diese wird das Diagramm automatisch anhand aller empfangenen Werte skaliert.</p>
|
||||
<p>Mehrere Serien können im gleichen Diagramm angezeigt werden,
|
||||
indem für jede Eingangsnachricht andere <code>msg.topic</code>-Werte verwendet werden.
|
||||
Mit der Eigenschaft <code>msg.label</code> können mehrere Balken der selben Serie angezeigt werden.</p>
|
||||
<p>Der Wertebereich der <b>X-Achse</b> wird durch ein Zeitfenster oder eine maximale Anzahl anzuzeigender Punkte vorgegeben.
|
||||
Ältere Daten werden automatisch aus dem Diagramm entfernt.
|
||||
Die Achsenbeschriftung kann mittels einer <a href="https://momentjs.com/docs/#/displaying/format/" target="_blank">
|
||||
Moment.js-zeitformatierten</a> Zeichenfolge benutzerdefiniert werden (z.B. D.M.Y für 21.3.2021).</p>
|
||||
<p>Wird eine <code>msg.payload</code>-Nachricht mit einem leeren Array <code>[]</code> an den Eingang gesendet,
|
||||
so wird das Diagramm gelöscht.</p>
|
||||
<p><b><a href="https://github.com/node-red/node-red-dashboard/blob/master/Charts.md" target="_new">Hier</a></b>
|
||||
sind weitere Informationen zum Vorformatieren von Daten verfügbar, um sie als vollständiges Diagramm zu übergeben.</p>
|
||||
<p>Das <b>Leer-Text</b>-Feld kann verwendet werden, um den Text im Diagramm anzuzeigen, bevor gültige Daten empfangen wurden.
|
||||
<p>Der <b>Beschriftung</b> kann auch durch eine Nachrichteneigenschaft festgelegt werden.
|
||||
Dazu muss der Name der Eigenschaft in das Feld eingetragen werden, zum Beispiel <code>{{msg.topic}}</code>.</p>
|
||||
<p>Der Node-Ausgang enthält ein Array des Diagrammstatus, das bei Bedarf gespeichert werden kann.
|
||||
Wird dieses zum <code>ui_chart</code>-Node gesendet, so werden die gespeicherten Daten erneut angezeigt.</p>
|
||||
<p>Wenn eine <b>Klasse</b> angegeben ist, wird sie der übergeordneten Karte hinzugefügt. Auf diese Weise können Sie CSS-Stile auf die ui-card und ihre untergeordneten Elemente anwenden. Die Klasse kann zur Laufzeit festgelegt werden, indem eine Zeichenfolgeneigenschaft <code>msg.className</code> festgelegt wird.</p>
|
||||
</script>
|
||||
56
node_modules/node-red-dashboard/nodes/locales/de/ui_chart.json
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"ui_chart": {
|
||||
"label": {
|
||||
"group": "Gruppe",
|
||||
"size": "Größe",
|
||||
"label": "Beschriftung",
|
||||
"optionalChartTitle": "Optionaler Diagrammtitel",
|
||||
"type": "Typ",
|
||||
"lineChart": "  Liniendiagramm",
|
||||
"barChart": "  Balkendiagramm",
|
||||
"barChartH": "  Balkendiagramm (H)",
|
||||
"pieChart": "  Kreisdiagramm",
|
||||
"polarAreaChart": "  Polargebietskarte",
|
||||
"radarChart": "  Radarkarte",
|
||||
"enlargePoints": "Punkte vergrößern",
|
||||
"xAxis": "X-Achse",
|
||||
"last": "Letzten",
|
||||
"seconds": "Sekunden",
|
||||
"minutes": "Minuten",
|
||||
"hours": "Stunden",
|
||||
"days": "Tage",
|
||||
"weeks": "Wochen",
|
||||
"or": "oder",
|
||||
"points": "Punkte",
|
||||
"xAxisLabel": "X-Beschriftung",
|
||||
"HHmmss": "HH:mm:ss",
|
||||
"HHmm": "HH:mm",
|
||||
"yearMonthDate": "Jahr-Monat-Tag",
|
||||
"dateMonth": "Tag/Monat",
|
||||
"dayHHmm": "Wochentag HH:mm",
|
||||
"custom": "benutzerdefiniert",
|
||||
"automatic": "automatisch",
|
||||
"asUTC": "als UTC",
|
||||
"yAxis": "Y-Achse",
|
||||
"min": "min",
|
||||
"max": "max",
|
||||
"legend": "Legende",
|
||||
"none": "Keine",
|
||||
"show": "Anzeigen",
|
||||
"interpolate": "Interpolation",
|
||||
"linear": "Linear",
|
||||
"step": "Stufen",
|
||||
"bezier": "Bezier",
|
||||
"cubic": "Kubisch",
|
||||
"cubicMono": "Kubisch-Mono",
|
||||
"cutout": "Ausschnitt",
|
||||
"useFirstColourForAllBars": "Erste Farbe für alle Balken verwenden",
|
||||
"seriesColours": "Serienfarben",
|
||||
"blankLabel": "Leer-Text",
|
||||
"displayThisTextBeforeValidDataArrives": "Anzuzeigender Text bevor gültige Daten eintreffen",
|
||||
"useDifferentColor": "Unterschiedliche Farben für Datenserie verwenden",
|
||||
"className": "Klasse",
|
||||
"classNamePlaceholder": "Optionale(r) CSS-Klassenname(n) für das Widget"
|
||||
}
|
||||
}
|
||||
}
|
||||
18
node_modules/node-red-dashboard/nodes/locales/de/ui_form.html
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
<script type="text/html" data-help-name="ui_form">
|
||||
<p>Fügt dem Dashboard ein Eingabeformular hinzu.</p>
|
||||
<p>Der <code>ui_form</code>-Node ermöglicht die Eingabe mehrerer Werte durch den Benutzer.
|
||||
Beim Klicken auf die Schaltfläche <b>Senden</b> wird ein Objekt als <code>msg.payload</code> versendet.</p>
|
||||
<p>Über die Schaltfläche <b>+Element</b> können Eingabeelemente hinzugefügt werden.</p>
|
||||
<p>Jedes Element enthält folgende Einstellmöglichkeiten:</p>
|
||||
<ul>
|
||||
<li><b>Beschriftung:</b> Beschriftung des Elements in der Benutzeroberfläche</li>
|
||||
<li><b>Name:</b> Schlüssel (Variablennamen), mit dem der Eingabewert in <code>msg.payload</code> abgelegt wird</li>
|
||||
<li><b>Typ:</b> Typ des Eingabeelements</li>
|
||||
<li><b>Erforderlich:</b> Markierund des Eingabefeldes als erfolderliche Benutzereingabe</li>
|
||||
<li><b>Zeilen:</b> Zeilenanzahl bei mehrzeiligen Texteingabefeldern</li>
|
||||
<li><b>Entfernen:</b> Entfernung des Elements aus dem Formular</li>
|
||||
</ul>
|
||||
<p>Über <b>Topic</b> kann die Eigenschaft <code>msg.topic</code> optional festgelegt werden.</p>
|
||||
<p>Die Schaltfläche <b>Abbrechen</b> kann ausgeblendet werden, indem sein Feld leer gelassen wird.</p>
|
||||
<p>Wenn eine <b>Klasse</b> angegeben ist, wird sie der übergeordneten Karte hinzugefügt. Auf diese Weise können Sie CSS-Stile auf die ui-card und ihre untergeordneten Elemente anwenden. Die Klasse kann zur Laufzeit festgelegt werden, indem eine Zeichenfolgeneigenschaft <code>msg.className</code> festgelegt wird.</p>
|
||||
</script>
|
||||
35
node_modules/node-red-dashboard/nodes/locales/de/ui_form.json
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"ui_form": {
|
||||
"label": {
|
||||
"group": "Gruppe",
|
||||
"size": "Größe",
|
||||
"label": "Beschriftung",
|
||||
"optionalLabel": "Optionale Beschriftung",
|
||||
"formElements": "Formular- elemente",
|
||||
"type": "Typ",
|
||||
"required": "Erforderlich",
|
||||
"rows": "UiZeilen",
|
||||
"remove": "Entfernen",
|
||||
"egName": "z.B. Name",
|
||||
"egName2": "z.B. Name",
|
||||
"text": "Text",
|
||||
"multiline": "Mehrzeilig",
|
||||
"number": "Zahl",
|
||||
"email": "E-Mail",
|
||||
"password": "Kennwort",
|
||||
"checkbox": "Auswahlkästchen",
|
||||
"switch": "Schalter",
|
||||
"date": "Datum",
|
||||
"time": "Zeit",
|
||||
"element": "Element",
|
||||
"buttons": "Schaltflächen",
|
||||
"submitButtonText": "Text Absenden-Schaltfläche",
|
||||
"cancelButtonText": "Text Abbrechen-Schaltfläche",
|
||||
"topic": "Topic",
|
||||
"optionalMsgTopic": "Optionaler msg.topic",
|
||||
"splitLayout": "Platzieren sie die formularelemente in 2 spalten",
|
||||
"className": "Klasse",
|
||||
"classNamePlaceholder": "Optionale(r) CSS-Klassenname(n) für das Widget"
|
||||
}
|
||||
}
|
||||
}
|
||||
16
node_modules/node-red-dashboard/nodes/locales/de/ui_group.json
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"ui_group": {
|
||||
"label": {
|
||||
"name": "Name",
|
||||
"tab": "Tab",
|
||||
"width": "Breite",
|
||||
"default": "Standard",
|
||||
"group": "Gruppe",
|
||||
"unassigned": "nicht zugewiesen",
|
||||
"className": "Klasse",
|
||||
"classNamePlaceholder": "Optionale(r) CSS-Klassenname(n) für das Widget"
|
||||
},
|
||||
"display-name": "Gruppenname anzeigen",
|
||||
"collapse-name": "Gruppenreduzierung zulassen"
|
||||
}
|
||||
}
|
||||
16
node_modules/node-red-dashboard/nodes/locales/de/ui_link.json
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"ui_link": {
|
||||
"label": {
|
||||
"name": "Name",
|
||||
"link": "Link",
|
||||
"icon": "Icon",
|
||||
"open-in": "Öffnen im",
|
||||
"new-tab": "neuen Tab",
|
||||
"this-tab": "selben Tab",
|
||||
"iframe": "iframe",
|
||||
"className": "Klasse",
|
||||
"classNamePlaceholder": "Optionale(r) CSS-Klassenname(n) für das Widget"
|
||||
},
|
||||
"tip": "Das <b>Icon</b> kann entweder ein <a href=\"https://klarsys.github.io/angular-material-icons/\" target=\"_blank\">Material-Design-Icon</a> (z.B. <code>check</code> oder <code>close</code>), ein <a href=\"https://fontawesome.com/v4.7.0/icons/\" target=\"_blank\">Font-Awesome-Icon</a> (z.B. <code>fa-fire</code>) oder ein <a href=\"https://github.com/Paul-Reed/weather-icons-lite/blob/master/css_mappings.md\" target=\"_blank\">Wetter-Icon</a> (z.B. <code>wi-wu-sunny</code>) sein.</p><p>Des Weiteren können alle Google-Material-Icons verwendet werden, indem dem Icon-Namen <code>mi-</code> vorangestellt wird (z.B. <code>mi-videogame_asset</code>).</p>"
|
||||
}
|
||||
}
|
||||
21
node_modules/node-red-dashboard/nodes/locales/de/ui_tab.json
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"ui_tab": {
|
||||
"label": {
|
||||
"home": "Home",
|
||||
"tab": "Tab",
|
||||
"name": "Name",
|
||||
"icon": "Icon",
|
||||
"state": "Status",
|
||||
"navmenu": "Nav. Menü",
|
||||
"enabled": "Aktiviert",
|
||||
"disabled": "Deaktivert",
|
||||
"visible": "Sichtbar",
|
||||
"hidden": "Versteckt"
|
||||
},
|
||||
"info": {
|
||||
"disabled": " Tab im Dashboard deaktiviert.",
|
||||
"hidden": " Tab im Nav.-Menü versteckt."
|
||||
},
|
||||
"tip": "Das <b>Icon</b> kann entweder ein <a href=\"https://klarsys.github.io/angular-material-icons/\" target=\"_blank\">Material-Design-Icon</a> (z.B. <code>check</code> oder <code>close</code>), ein <a href=\"https://fontawesome.com/v4.7.0/icons/\" target=\"_blank\">Font-Awesome-Icon</a> (z.B. <code>fa-fire</code>) oder ein <a href=\"https://github.com/Paul-Reed/weather-icons-lite/blob/master/css_mappings.md\" target=\"_blank\">Wetter-Icon</a> (z.B. <code>wi-wu-sunny</code>) sein.</p><p>Des Weiteren können alle Google-Material-Icons verwendet werden, indem dem Icon-Namen <code>mi-</code> vorangestellt wird (z.B. <code>mi-videogame_asset</code>).</p>"
|
||||
}
|
||||
}
|
||||
48
node_modules/node-red-dashboard/nodes/locales/de/ui_template.html
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
<script type="text/html" data-help-name="ui_template">
|
||||
<p>Das template-Widget kann alle gültigen HTML- und Angular/Angular-Material-Anweisungen enthalten.</p>
|
||||
<p>Dieser Node kann verwendet werden, um ein dynamisches Benutzeroberflächenelement zu erstellen, dessen Erscheinungsbild
|
||||
basierend auf der Eingangsnachricht geändert wird, und kann Nachrichten an Node-RED zurücksenden.</p>
|
||||
<p><b>Zum Beispiel:</b><br>
|
||||
<pre style="font-size:smaller;">
|
||||
<div layout="row" layout-align="space-between">
|
||||
<p>The number is</p>
|
||||
<font color="{{((msg.payload || 0) % 2 === 0) ? 'green' : 'red'}}">
|
||||
{{(msg.payload || 0) % 2 === 0 ? 'even' : 'odd'}}
|
||||
</font>
|
||||
</div></pre>
|
||||
Wird angezeigt, wenn die als <code>msg.payload</code> empfangene Zahl gerade oder ungerade ist.
|
||||
Es wird auch die Farbe des Textes zu grün geändert, wenn die Zahl gerade ist, oder rot, wenn ungerade.</p>
|
||||
<p>Das nächste Beispiel zeigt, wie eine eindeutige ID für Ihre Vorlage erstellt werden kann,
|
||||
die Standardfarbe fürs Erscheinungsbild ausgewählt wird und wie auf eingehende Nachrichten geprüft werden kann.
|
||||
<pre style="font-size:smaller;">
|
||||
<div id="{{'my_'+$id}}" style="{{'color:'+theme.base_color}}">Some text</div>
|
||||
<script>
|
||||
(function(scope) {
|
||||
scope.$watch('msg', function(msg) {
|
||||
if (msg) {
|
||||
// Do something when msg arrives
|
||||
$("#my_"+scope.$id).html(msg.payload);
|
||||
}
|
||||
});
|
||||
})(scope);
|
||||
</script></pre>
|
||||
Auf diese Weise erstellte Vorlagen können kopiert werden und bleiben unabhängig voneinander.</p>
|
||||
<p><b>Senden einer Nachricht:</b><br>
|
||||
<pre style="font-size:smaller;">
|
||||
<script>
|
||||
var value = "hello world";
|
||||
// or overwrite value in your callback function ...
|
||||
this.scope.action = function() { return value; }
|
||||
</script>
|
||||
<md-button ng-click="send({payload:action()})">
|
||||
Click me to send a hello world
|
||||
</md-button></pre>
|
||||
Zeigt einen Button an, welcher beim Klicken eine Nachricht mit Payload <code>'Hello world'</code> sendet.</p>
|
||||
<p><b>Verwenden von <code>msg.template</code>:</b><br>
|
||||
Der Vorlageninhalt kann auch über <code>msg.template</code> definiert werden.
|
||||
So können beispielsweise externe Dateien verwendet werden.<br>
|
||||
Die Vorlage wird bei eingehenden Nachrichten neu geladen, wenn sie verändert wurde.<br>
|
||||
In das Vorlagefeld geschriebener Code wird ignoriert, wenn <code>msg.template</code> vorhanden ist.</p>
|
||||
<p>Die folgenden Icon-Schriftarten sind verfügbar: <a href=\"https://klarsys.github.io/angular-material-icons/\" target=\"_blank\">Material-Design-Icon</a> (z.B. <code>check</code> oder <code>close</code>), ein <a href=\"https://fontawesome.com/v4.7.0/icons/\" target=\"_blank\">Font-Awesome-Icon</a> (z.B. <code>fa-fire</code>) oder ein <a href=\"https://github.com/Paul-Reed/weather-icons-lite/blob/master/css_mappings.md\" target=\"_blank\">Wetter-Icon</a> (z.B. <code>wi-wu-sunny</code>) sein.</p><p>Des Weiteren können alle Google-Material-Icons verwendet werden, indem dem Icon-Namen <code>mi-</code> vorangestellt wird (z.B. <code>mi-videogame_asset</code>).</p>
|
||||
<p>Wenn eine <b>Klasse</b> angegeben ist, wird sie der übergeordneten Karte hinzugefügt. Auf diese Weise können Sie CSS-Stile auf die ui-card und ihre untergeordneten Elemente anwenden. Die Klasse kann zur Laufzeit festgelegt werden, indem eine Zeichenfolgeneigenschaft <code>msg.className</code> festgelegt wird.</p>
|
||||
</script>
|
||||
19
node_modules/node-red-dashboard/nodes/locales/de/ui_template.json
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"ui_template": {
|
||||
"label": {
|
||||
"type": "Vorlagentyp",
|
||||
"local": "Widget in Gruppe",
|
||||
"global": "Hinzugefügt zur <head>-Sektion der Seite",
|
||||
"group": "Gruppe",
|
||||
"size": "Größe",
|
||||
"name": "Name",
|
||||
"pass-through": "Nachrichten vom Eingang weiterleiten",
|
||||
"store-state": "Ausgehende Nachrichten speichern",
|
||||
"template": "Vorlage",
|
||||
"expand": "Erweitern",
|
||||
"resend": "Letzten Wert beim Aktualisieren neuladen",
|
||||
"className": "Klasse",
|
||||
"classNamePlaceholder": "Optionale(r) CSS-Klassenname(n) für das Widget"
|
||||
}
|
||||
}
|
||||
}
|
||||
29
node_modules/node-red-dashboard/nodes/locales/de/ui_ui_control.html
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
<script type="text/html" data-help-name="ui_ui_control">
|
||||
<p>Ermöglicht die dynamische Steuerung des Dashboards.</p>
|
||||
<p>Die Standardfunktion besteht darin, den aktuell angezeigten Tab zu ändern.
|
||||
<code>msg.payload</code> sollte entweder ein Objekt der Form <code>{"tab":"my_tab_name"}</code> sein,
|
||||
oder einfach der <b>Tab-Name</b> oder ein <b>numerischer Index</b> (ab 0) vom Tab oder Link, der angezeigt werden soll.</p>
|
||||
<p>Das Senden eines leeren Namens "" aktualisiert die aktuell angezeigte Seite.
|
||||
Es kann auch "+1" für den nächsten und "-1" für den vorherigen Tab gesendet werden.</p>
|
||||
<p>Dashboard Seiten (also Tabs) können durch Senden eines <code>msg.payload</code>-Objektes im Format
|
||||
<pre>{"tabs": {"hide": "tab_name_to_hide", "disable": ["secret_tab", "unused_stuff"]}}</pre> gesteuert werden.
|
||||
Es sind zwei Zustände verfügbar: <b>show</b>/<b>hide</b> und <b>enable</b>/<b>disable</b></p>
|
||||
<p>Die Sichtbarkeit von individuellen Widget-Gruppen können durch folgenden Payload gesteuert werden:
|
||||
<pre>{"group": {"hide": ["tab_name_group_name_with_underscores"], "show": ["reveal_another_group"], "focus": true}}</pre>
|
||||
<b>focus</b> ist optional und sorgt dafür, dass zu der richtigen Gruppe gescrollt wird.
|
||||
Es können auch folgende Eigenschafen wie `open` und `close` verwendet werden, um den Status einer Gruppe zu setzen.
|
||||
Die Gruppennamen sind die IDs der Gruppen und setzen sich aus <i>tab name</i> plus <i>group name</i> zusammen,
|
||||
zusammengeschrieben mittels Leerzeichen-ersetzender Unterstriche.</p>
|
||||
<p>Wenn ein Browser die Verbindung aufbaut oder verliert, den Tab wechselt oder eine Gruppe auf- bzw. zuklappt,
|
||||
sendet dieser Node eine <code>msg</code> mit folgendem Inhalt:</p>
|
||||
<ul>
|
||||
<li><code>payload</code> - <i>connect</i>, <i>lost</i>, <i>change</i> oder <i>group</i>
|
||||
<li><code>socketid</code> - die ID des Sockets (dies ändert sich jedes Mal, wenn der Browser die Seite neu lädt)
|
||||
<li><code>socketip</code> - die IP-Adresse, von der die Verbindung stammt
|
||||
<li><code>tab</code> - die Nummer des Tabs (nur für 'change' Ereignisse)
|
||||
<li><code>name</code> - der Name des Tabs (nur für 'change' Ereignisse)
|
||||
<li><code>group</code> - der Name der Gruppe (nur für 'group' Ereignisse)
|
||||
<li><code>open</code> - der Status der Gruppe (nur für 'group' Ereignisse)
|
||||
</ul>
|
||||
<p>Optional - Nur neue Verbindungen melden - nützlich, um ein erneutes Senden von Daten an einen neuen Client auszulösen, ohne dass andere Ereignisse herausgefiltert werden müssen.</p>
|
||||
</script>
|
||||
10
node_modules/node-red-dashboard/nodes/locales/de/ui_ui_control.json
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"ui_ui_control": {
|
||||
"label": {
|
||||
"name": "Name"
|
||||
},
|
||||
"placeholder": {
|
||||
"name": "Name"
|
||||
}
|
||||
}
|
||||
}
|
||||
16
node_modules/node-red-dashboard/nodes/locales/en-US/ui_audio.html
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<script type="text/html" data-help-name="ui_audio">
|
||||
<p>Plays audio or text to speech (TTS) in the dashboard.</p>
|
||||
<p>To work the dashboard web page must be open.</p>
|
||||
<p>Expects <code>msg.payload</code> to contain a buffer of a <b>wav</b> or <b>mp3</b> file.</p>
|
||||
<p>If your browser has native support for Text-to-Speech then a <code>msg.payload</code>
|
||||
can also be a <b>string</b> to be read aloud.</p>
|
||||
<p>Optionally setting <code>msg.level</code> from 0 to 100 will change the volume from 0 to 100%. Default is 100%.
|
||||
In audio mode you can go up to 300, but you may get distortion.</p>
|
||||
<p>When a <code>msg.reset</code> is available with value <code>true</code>, then playback of the current audio fragment will be stopped.</p>
|
||||
<p>The <b>node status</b> reflects the current playback status:
|
||||
<ul>
|
||||
<li><b>started:</b> the audio fragment playback has been started.</li>
|
||||
<li><b>reset:</b> the audio fragment playback has been reset (i.e. stopped before completed).</li>
|
||||
</ul>
|
||||
As soon as the audio fragment playback is completed, the node status will be cleared automatically.</p>
|
||||
</script>
|
||||
2
node_modules/node-red-dashboard/nodes/locales/en-US/ui_base.html
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
<script type="text/html" data-help-name="ui_base">
|
||||
</script>
|
||||
102
node_modules/node-red-dashboard/nodes/locales/en-US/ui_base.json
generated
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
{
|
||||
"ui_base": {
|
||||
"label": {
|
||||
"dashboard": "dashboard",
|
||||
"category": "dashboard",
|
||||
"title": "Title",
|
||||
"options": "Options",
|
||||
"date-format": "Date Format",
|
||||
"sizes": "Sizes",
|
||||
"horizontal": "Horizontal",
|
||||
"vertical": "Vertical",
|
||||
"widget-size": "1x1 Widget Size",
|
||||
"widget-spacing": "Widget Spacing",
|
||||
"group-padding": "Group Padding",
|
||||
"group-spacing": "Group Spacing",
|
||||
"layout": "Layout",
|
||||
"angular": "Angular",
|
||||
"theme": "Theme",
|
||||
"site": "Site"
|
||||
},
|
||||
"auto": "auto",
|
||||
"title": "Node-RED Dashboard",
|
||||
"layout": {
|
||||
"tab-and-link": "Tabs & Links",
|
||||
"tab": "tab",
|
||||
"link": "link",
|
||||
"group": "group",
|
||||
"edit": "edit",
|
||||
"spacer": "spacer",
|
||||
"layout": "layout",
|
||||
"layout-editor": "Dashboard layout editor",
|
||||
"width": "Width",
|
||||
"auto": "auto-sizing",
|
||||
"manual": "manual resize"
|
||||
},
|
||||
"theme": {
|
||||
"style": "Style",
|
||||
"custom-profile": "Custom Profile",
|
||||
"custom-profile-name": "Untitled Theme 1",
|
||||
"base-settings": "Base Settings",
|
||||
"page-settings": "Page Settings",
|
||||
"page": {
|
||||
"title": "Title Bar Background",
|
||||
"page": "Page Background",
|
||||
"side": "Side Bar Background"
|
||||
},
|
||||
"group-settings": "Group Settings",
|
||||
"group": {
|
||||
"text": "Group Text",
|
||||
"border": "Group Border",
|
||||
"background": "Group Background"
|
||||
},
|
||||
"widget-settings": "Widget Settings",
|
||||
"widget": {
|
||||
"text": "Widget Text",
|
||||
"colour": "Widget Colour",
|
||||
"background": "Widget Background"
|
||||
}
|
||||
},
|
||||
"style": {
|
||||
"light": "Light (default)",
|
||||
"dark": "Dark",
|
||||
"custom": "Custom",
|
||||
"primary": "Primary",
|
||||
"accents": "Accents",
|
||||
"background": "Background",
|
||||
"warnings": "Warnings",
|
||||
"palette": "Light / Dark"
|
||||
},
|
||||
"base": {
|
||||
"colour": "Colour",
|
||||
"font": "Font"
|
||||
},
|
||||
"font": {
|
||||
"system": "System Font (default)"
|
||||
},
|
||||
"site": {
|
||||
"title": "Node-RED Dashboard",
|
||||
"date-format": "DD/MM/YYYY"
|
||||
},
|
||||
"title-bar": {
|
||||
"show": "Show the title bar",
|
||||
"hide": "Hide the title bar"
|
||||
},
|
||||
"swipe": {
|
||||
"no-swipe": "No swipe between tabs",
|
||||
"allow-swipe": "Allow swipe between tabs",
|
||||
"allow-swipe-mouse": "Allow swipe (+mouse) between tabs",
|
||||
"show-menu": "Swipe to open/close menu"
|
||||
},
|
||||
"lock": {
|
||||
"clicked": "Click to show side menu",
|
||||
"locked": "Always show side menu",
|
||||
"locked-icon": "Always show icons only"
|
||||
},
|
||||
"temp": {
|
||||
"allow-theme": "Node-RED theme everywhere",
|
||||
"no-theme": "Use Angular theme in ui_template",
|
||||
"none": "Angular theme everywhere"
|
||||
}
|
||||
}
|
||||
}
|
||||
20
node_modules/node-red-dashboard/nodes/locales/en-US/ui_button.html
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<script type="text/html" data-help-name="ui_button">
|
||||
<p>Adds a button to the user interface.</p>
|
||||
<p>Clicking the button generates a message with <code>msg.payload</code> set to the <b>Payload</b> field.
|
||||
If no payload is specified, the node id is used.</p>
|
||||
<p>The <b>Size</b> defaults to 3 by 1.</p>
|
||||
<p>The <b>Icon</b> can be defined, as either a <a href="https://klarsys.github.io/angular-material-icons/" target="_blank">Material Design icon</a>
|
||||
<i>(e.g. 'check', 'close')</i> or a <a href="https://fontawesome.com/v4.7.0/icons/" target="_blank">Font Awesome icon</a>
|
||||
<i>(e.g. 'fa-fire')</i>, or a <a href="https://github.com/Paul-Reed/weather-icons-lite/blob/master/css_mappings.md">Weather icon</a>.
|
||||
You can use the full set of google material icons if you add 'mi-' to the icon name. e.g. 'mi-videogame_asset'.</p>
|
||||
<p>The colours of the text and background may be set. They can also be set by a message property by setting
|
||||
the field to the name of the property, for example <code>{{background}}</code>.
|
||||
You don't need to prepend the <i>msg.</i> part of the property name.</p>
|
||||
<p>The label and icon can also be set by a message property by setting
|
||||
the field to the name of the property, for example <code>{{topic}}</code> or <code>{{myicon}}</code>.</p>
|
||||
<p>If set to pass through mode a message arriving on the input will act like pressing the button.
|
||||
The output payload will be as defined in the node configuration.</p>
|
||||
<p>The incoming <b>topic</b> field can be used to set the <code>msg.topic</code> property that is output.</p>
|
||||
<p>Setting <code>msg.enabled</code> to <code>false</code> will disable the button.</p>
|
||||
<p>If a <b>Class</b> is specified, it will be added to the parent card. This way you can style the card and the elements inside it with custom CSS. The Class can be set at runtime by setting a <code>msg.className</code> string property.</p>
|
||||
</script>
|
||||
24
node_modules/node-red-dashboard/nodes/locales/en-US/ui_button.json
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"ui_button": {
|
||||
"label": {
|
||||
"group": "Group",
|
||||
"size": "Size",
|
||||
"icon": "Icon",
|
||||
"optionalIcon": "optional icon",
|
||||
"label": "Label",
|
||||
"optionalLabel": "optional label",
|
||||
"tooltip": "Tooltip",
|
||||
"optionalTooltip": "optional tooltip",
|
||||
"color": "Color",
|
||||
"optionalColor": "optional text/icon color",
|
||||
"background": "Background",
|
||||
"optionalBackgroundColor": "optional background color",
|
||||
"whenClicked": "When clicked, send:",
|
||||
"payload": "Payload",
|
||||
"topic": "Topic",
|
||||
"emulateClick": "If msg arrives on input, emulate a button click:",
|
||||
"className": "Class",
|
||||
"classNamePlaceholder": "Optional CSS class name(s) for widget"
|
||||
}
|
||||
}
|
||||
}
|
||||
21
node_modules/node-red-dashboard/nodes/locales/en-US/ui_chart.html
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<script type="text/html" data-help-name="ui_chart">
|
||||
<p>Plots the input values on a chart. This can either be a time based line chart, a bar chart (vertical or horizontal),
|
||||
or a pie chart.</p>
|
||||
<p>Each input <code>msg.payload</code> value will be converted to a number. If the
|
||||
conversion fails, the message is ignored.</p>
|
||||
<p>Minimum and Maximum <b>Y</b> axis values are optional. The graph will auto-scale to any values received.</p>
|
||||
<p>Multiple series can be shown on the same chart by using a different <code>msg.topic</code>
|
||||
value on each input message. Multiple bars of the same series can be shown by using the <code>msg.label</code> property.</p>
|
||||
<p>The <b>X</b> axis defines a time window or a maximum number of points to display. Older data will be automatically removed from the graph.
|
||||
The axis labels can be formatted using a <a href="https://momentjs.com/docs/#/displaying/format/" target="_blank">
|
||||
Moment.js time formatted</a> string.</p>
|
||||
<p>Inputting a <code>msg.payload</code> containing a blank array <code>[]</code> will clear the chart.</p>
|
||||
<p>See <b><a href="https://github.com/node-red/node-red-dashboard/blob/master/Charts.md" target="_new">this information</a></b>
|
||||
for how to pre-format data to be passed in as a complete chart.</p>
|
||||
<p>The <b>Blank label</b> field can be used to display some text before any valid data is received.</p>
|
||||
<p>The label can also be set by a message property by setting
|
||||
the field to the name of the property, for example <code>{{msg.topic}}</code>.</p>
|
||||
<p>The node output contains an array of the chart state that can be persisted if needed. This can be passed
|
||||
into the chart node to re-display the persisted data.</p>
|
||||
<p>If a <b>Class</b> is specified, it will be added to the parent card. This way you can style the card and the elements inside it with custom CSS. The Class can be set at runtime by setting a <code>msg.className</code> string property.</p>
|
||||
</script>
|
||||
56
node_modules/node-red-dashboard/nodes/locales/en-US/ui_chart.json
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"ui_chart": {
|
||||
"label": {
|
||||
"group": "Group",
|
||||
"size": "Size",
|
||||
"label": "Label",
|
||||
"optionalChartTitle": "optional chart title",
|
||||
"type": "Type",
|
||||
"lineChart": "  Line chart",
|
||||
"barChart": "  Bar chart",
|
||||
"barChartH": "  Bar chart (H)",
|
||||
"pieChart": "  Pie chart",
|
||||
"polarAreaChart": "  Polar area chart",
|
||||
"radarChart": "  Radar chart",
|
||||
"enlargePoints": "enlarge points",
|
||||
"xAxis": "X-axis",
|
||||
"last": "last",
|
||||
"seconds": "seconds",
|
||||
"minutes": "minutes",
|
||||
"hours": "hours",
|
||||
"days": "days",
|
||||
"weeks": "weeks",
|
||||
"or": "OR",
|
||||
"points": "points",
|
||||
"xAxisLabel": "X-axis Label",
|
||||
"HHmmss": "HH:mm:ss",
|
||||
"HHmm": "HH:mm",
|
||||
"yearMonthDate": "Year-Month-Date",
|
||||
"dateMonth": "Date/Month",
|
||||
"dayHHmm": "Day HH:mm",
|
||||
"custom": "custom",
|
||||
"automatic": "automatic",
|
||||
"asUTC": "as UTC",
|
||||
"yAxis": "Y-axis",
|
||||
"min": "min",
|
||||
"max": "max",
|
||||
"legend": "Legend",
|
||||
"none": "None",
|
||||
"show": "Show",
|
||||
"interpolate": "Interpolate",
|
||||
"linear": "linear",
|
||||
"step": "step",
|
||||
"bezier": "bezier",
|
||||
"cubic": "cubic",
|
||||
"cubicMono": "cubic-mono",
|
||||
"cutout": "Cutout",
|
||||
"useFirstColourForAllBars": "Use first colour for all bars",
|
||||
"seriesColours": "Series Colours",
|
||||
"blankLabel": "Blank label",
|
||||
"displayThisTextBeforeValidDataArrives": "display this text before valid data arrives",
|
||||
"useDifferentColor": "Use different colour for series data",
|
||||
"className": "Class",
|
||||
"classNamePlaceholder": "Optional CSS class name(s) for widget"
|
||||
}
|
||||
}
|
||||
}
|
||||
10
node_modules/node-red-dashboard/nodes/locales/en-US/ui_colour_picker.html
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<script type="text/html" data-help-name="ui_colour_picker">
|
||||
<p>Adds a colour picker to the dashboard.</p>
|
||||
<p>If the group width is 4 or greater then the picker can be set to be visible at all times.</p>
|
||||
<p><b>Format</b> can be rgb, hex, hex8, hsv, or hsl. Transparency is supported for all except hex.</p>
|
||||
<p>If a <b>Topic</b> is specified, it will be added as <code>msg.topic</code>.</p>
|
||||
<p>Setting <code>msg.enabled</code> to <code>false</code> will disable the input.</p>
|
||||
<p>If set to ‘pass through mode’ a message arriving on the input will be evaluated for any colour format available
|
||||
as Format. If the conversion fails #000000 will be used.</p>
|
||||
<p>If a <b>Class</b> is specified, it will be added to the parent card. This way you can style the card and the elements inside it with custom CSS. The Class can be set at runtime by setting a <code>msg.className</code> string property.</p>
|
||||
</script>
|
||||
7
node_modules/node-red-dashboard/nodes/locales/en-US/ui_date_picker.html
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<script type="text/html" data-help-name="ui_date_picker">
|
||||
<p>Adds a date picker widget to the user interface.</p>
|
||||
<p>The date display can be formatted in the Dashboard - Site tab using <a href="https://momentjs.com/docs/#/displaying/">
|
||||
moment.js</a> formatting. For example <code>MM/DD/YYYY</code>, <code>Do MMM YYYY</code> or <code>YYYY-MM-DD</code>.</p>
|
||||
<p>Setting <code>msg.enabled</code> to <code>false</code> will disable the input.</p>
|
||||
<p>If a <b>Class</b> is specified, it will be added to the parent card. This way you can style the card and the elements inside it with custom CSS. The Class can be set at runtime by setting a <code>msg.className</code> string property.</p>
|
||||
</script>
|
||||
17
node_modules/node-red-dashboard/nodes/locales/en-US/ui_dropdown.html
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<script type="text/html" data-help-name="ui_dropdown">
|
||||
<p>Adds a dropdown select box to the user interface.</p>
|
||||
<p>Multiple value / label pairs can be added as required. If the label is not specified the
|
||||
value will be used for both.</p>
|
||||
<p>The configured value of the selected item will be returned as <code>msg.payload</code>.</p>
|
||||
<p>Setting <code>msg.payload</code> to one of the item values will preset the choice in the dropdown.
|
||||
If using the multi-select option then the payload should be an array of values.</p>
|
||||
<p>Optionally the user search term can deleted if the <code>msg.resetSearch</code> property is present and set to <i>true</i>.</p>
|
||||
<p>Optionally the <b>Topic</b> field can be used to set the <code>msg.topic</code> property.</p>
|
||||
<p>The Options may be configured by inputting <code>msg.options</code> containing an array.
|
||||
If just text then the value will be the same as the label, otherwise you can specify both by
|
||||
using an object of <code>"label":"value"</code> pairs :</p>
|
||||
<code>[ "Choice 1", "Choice 2", {"Choice 3":"3"} ]</code>
|
||||
<p></p>
|
||||
<p>If the "Allow multiple selections" output option is enabled - the result will be returned as an array instead of a string.</p>
|
||||
<p>If a <b>Class</b> is specified, it will be added to the parent card. This way you can style the card and the elements inside it with custom CSS. The Class can be set at runtime by setting a <code>msg.className</code> string property.</p>
|
||||
</script>
|
||||
17
node_modules/node-red-dashboard/nodes/locales/en-US/ui_form.html
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<script type="text/html" data-help-name="ui_form">
|
||||
<p>Adds a form to user interface.</p>
|
||||
<p>Helps to collect multiple value from the user on submit button click as an object in <code>msg.payload</code> </p>
|
||||
<p>Multiple input elements can be added using add elements button</p>
|
||||
<p>Each element contains following components:</p>
|
||||
<ul>
|
||||
<li> <b>Label</b> : Value that will be the label of the element in the user interface</li>
|
||||
<li> <b>Name</b> : Represents the key (variable name) in the <code>msg.payload</code> in which the value of the corresponding element present</li>
|
||||
<li> <b>Type</b> : Drop down option to select the type of input element</li>
|
||||
<li> <b>Required</b> : On switching on the user has to supply the value before submitting</li>
|
||||
<li> <b>Rows</b> : number of UI rows for multiline text input</li>
|
||||
<li> <b>Delete</b> : To remove the current element from the form</li>
|
||||
</ul>
|
||||
<p>Optionally the <b>Topic</b> field can be used to set the <code>msg.topic</code> property.</p>
|
||||
<p>The Cancel button can be hidden by setting it's value to be blank "".</p>
|
||||
<p>If a <b>Class</b> is specified, it will be added to the parent card. This way you can style the card and the elements inside it with custom CSS. The Class can be set at runtime by setting a <code>msg.className</code> string property.</p>
|
||||
</script>
|
||||
35
node_modules/node-red-dashboard/nodes/locales/en-US/ui_form.json
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"ui_form": {
|
||||
"label": {
|
||||
"group": "Group",
|
||||
"size": "Size",
|
||||
"label": "Label",
|
||||
"optionalLabel": "optional label",
|
||||
"formElements": "Form elements",
|
||||
"type": "Type",
|
||||
"required": "Required",
|
||||
"rows": "UiRows",
|
||||
"remove": "Remove",
|
||||
"egName": "e.g. Name",
|
||||
"egName2": "e.g. name",
|
||||
"text": "Text",
|
||||
"multiline": "Multiline",
|
||||
"number": "Number",
|
||||
"email": "E-mail",
|
||||
"password": "Password",
|
||||
"checkbox": "Checkbox",
|
||||
"switch": "Switch",
|
||||
"date": "Date",
|
||||
"time": "Time",
|
||||
"element": "element",
|
||||
"buttons": "Buttons",
|
||||
"submitButtonText": "submit button text",
|
||||
"cancelButtonText": "cancel button text",
|
||||
"topic": "Topic",
|
||||
"optionalMsgTopic": "optional msg.topic",
|
||||
"splitLayout":"Place the form elements in two columns",
|
||||
"className": "Class",
|
||||
"classNamePlaceholder": "Optional CSS class name(s) for widget"
|
||||
}
|
||||
}
|
||||
}
|
||||
15
node_modules/node-red-dashboard/nodes/locales/en-US/ui_gauge.html
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
<script type="text/html" data-help-name="ui_gauge">
|
||||
<p>Adds a gauge type widget to the user interface.</p>
|
||||
<p>The <code>msg.payload</code> is searched for a numeric <i>value</i> and is formatted in accordance with
|
||||
the defined <b>Value Format</b>, which can then be formatted using
|
||||
<a href="https://docs.angularjs.org/api/ng/filter" target="_blank">Angular filters</a>.</p>
|
||||
<p>For example : <code>{{value | number:1}}%</code> will round the value to one decimal place and append a % sign.</p>
|
||||
<p>The colours of each of 3 sectors can be specified and the gauge will blend between them.
|
||||
The colours should be specified in hex (#rrggbb) format.</p>
|
||||
<p>If you specify numbers for the sectors then the colours changes per sector.
|
||||
If not specified the colours are blended across the total range.</p>
|
||||
<p>The gauge has several modes. Regular gauge, donut, compass and wave.</p>
|
||||
<p>The label can also be set by a message property by setting
|
||||
the field to the name of the property, for example <code>{{msg.topic}}</code>.</p>
|
||||
<p>If a <b>Class</b> is specified, it will be added to the parent card. This way you can style the card and the elements inside it with custom CSS. The Class can be set at runtime by setting a <code>msg.className</code> string property.</p>
|
||||
</script>
|
||||
4
node_modules/node-red-dashboard/nodes/locales/en-US/ui_group.html
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<script type="text/html" data-help-name="ui_group">
|
||||
<p>Group</p>
|
||||
<p>If a <b>Class</b> is specified, it will be added to the parent card. This way you can style the card and the elements inside it with custom CSS. The Class can be set at runtime by setting a <code>msg.className</code> string property.</p>
|
||||
</script>
|
||||
16
node_modules/node-red-dashboard/nodes/locales/en-US/ui_group.json
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"ui_group" : {
|
||||
"label" : {
|
||||
"name" : "Name",
|
||||
"tab" : "Tab",
|
||||
"width" : "Width",
|
||||
"default" : "Default",
|
||||
"group" : "Group",
|
||||
"unassigned" : "unassigned",
|
||||
"className": "Class",
|
||||
"classNamePlaceholder": "Optional CSS class name(s) for widget"
|
||||
},
|
||||
"display-name" : "Display group name",
|
||||
"collapse-name" : "Allow group to be collapsed"
|
||||
}
|
||||
}
|
||||
8
node_modules/node-red-dashboard/nodes/locales/en-US/ui_link.html
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<script type="text/html" data-help-name="ui_link">
|
||||
<p>The <b>Icon</b> can be defined, as either a <a href="https://klarsys.github.io/angular-material-icons/" target="_blank">Material Design icon</a>
|
||||
<i>(e.g. 'check', 'close')</i> or a <a href="https://fontawesome.com/v4.7.0/icons/" target="_blank">Font Awesome icon</a>
|
||||
<i>(e.g. 'fa-fire')</i>, or a <a href="https://github.com/Paul-Reed/weather-icons-lite/blob/master/css_mappings.md">Weather icon</a>.
|
||||
You can use the full set of google material icons if you add 'mi-' to the icon name. e.g. 'mi-videogame_asset'.</p>
|
||||
<p>The <b>Open in</b> field controls whether the link opens in a <i>New Tab</i>, or if the link is opened within an <i>iframe</i> on the same page. Some sites, including Google, do not allow the rendering of their page inside an iframe. If you select the <i>iframe</i> option and the site does not show, this is simply because that site forbids the use of it inside an iframe.</p>
|
||||
<p>If a <b>Class</b> is specified, it will be added to the parent card. This way you can style the card and the elements inside it with custom CSS. The Class can be set at runtime by setting a <code>msg.className</code> string property.</p>
|
||||
</script>
|
||||
16
node_modules/node-red-dashboard/nodes/locales/en-US/ui_link.json
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"ui_link" : {
|
||||
"label" : {
|
||||
"name" : "Name",
|
||||
"link" : "Link",
|
||||
"icon" : "Icon",
|
||||
"open-in" : "Open in",
|
||||
"new-tab" : "New Tab",
|
||||
"this-tab" : "This Tab",
|
||||
"iframe" : "iframe",
|
||||
"className": "Class",
|
||||
"classNamePlaceholder": "Optional CSS class name(s) for widget"
|
||||
},
|
||||
"tip" : "The <b>Icon</b> field can be either a <a href=\"https://klarsys.github.io/angular-material-icons/\" target=\"_blank\">Material Design icon</a> <i>(e.g. 'check', 'close')</i> or a <a href=\"https://fontawesome.com/v4.7.0/icons/\" target=\"_blank\">Font Awesome icon</a> <i>(e.g. 'fa-fire')</i>, or a <a href=\"https://github.com/Paul-Reed/weather-icons-lite/blob/master/css_mappings.md\" target=\"_blank\">Weather icon</a> <i>(e.g. 'wi-wu-sunny')</i>.</p><p>You can use the full set of google material icons if you add 'mi-' to the icon name. e.g. 'mi-videogame_asset'.</p>"
|
||||
}
|
||||
}
|
||||
17
node_modules/node-red-dashboard/nodes/locales/en-US/ui_numeric.html
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<script type="text/html" data-help-name="ui_numeric">
|
||||
<p>Adds a numeric input widget to the user interface.</p>
|
||||
<p>The user can set the value between
|
||||
the limits (<b>min</b> and <b>max</b>). Each value change will generate a <code>msg.payload</code>.</p>
|
||||
<p>If <b>Topic</b> is specified, it will be added as <code>msg.topic</code>.<p>
|
||||
<p>Any input <code>msg.payload</code> will be converted to a number, the <b>min</b> value will be used if conversion fails,
|
||||
and it will update the user interface. If the value changes, it will also be passed to the output.</p>
|
||||
<p>The <b>Value Format</b> field can be used to change the displayed format. For example, a <b>Value Format</b>
|
||||
of <code>{{value}} %</code>
|
||||
with a value of <b>23</b> will show <b>23 %</b> on the user interface. The <b>Value Format</b> field can contain
|
||||
HTML or Angular filters to format the output (eg: <code>&deg;</code> will show the degree symbol).</p>
|
||||
<p>Setting the Value Format field to <code>{{msg.payload}}</code> will make the input field editable so you can type in a number.</p>
|
||||
<p>The label can also be set by a message property by setting
|
||||
the field to the name of the property, for example <code>{{msg.topic}}</code>.</p>
|
||||
<p>Setting <code>msg.enabled</code> to <code>false</code> will disable the widget output.</p>
|
||||
<p>If a <b>Class</b> is specified, it will be added to the parent card. This way you can style the card and the elements inside it with custom CSS. The Class can be set at runtime by setting a <code>msg.className</code> string property.</p>
|
||||
</script>
|
||||
15
node_modules/node-red-dashboard/nodes/locales/en-US/ui_slider.html
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
<script type="text/html" data-help-name="ui_slider">
|
||||
<p>Adds a slider widget to the user interface.</p>
|
||||
<p>The user can change its value between the limits (<b>min</b> and <b>max</b>). Each value change
|
||||
will generate a message with the value set as <b>payload</b>.</p>
|
||||
<p>A vertical slider can be created by setting the size so that the height is greater than the width.</p>
|
||||
<p>The slider can be reversed by setting the min value larger than the max value. e.g. min 100, max 0.</p>
|
||||
<p>If a <b>Topic</b> is specified, it will be added as <code>msg.topic</code>.</p>
|
||||
<p>An input <code>msg.payload</code> will be converted to a number, and used to preset a value.
|
||||
The <b>min</b> value will be used if conversion fails,
|
||||
and it will update the user interface. If the value changes, it will also be passed to the output.</p>
|
||||
<p>The label can also be set by a message property by setting
|
||||
the field to the name of the property, for example <code>{{msg.topic}}</code>.</p>
|
||||
<p>Setting <code>msg.enabled</code> to <code>false</code> will disable the slider output.</p>
|
||||
<p>If a <b>Class</b> is specified, it will be added to the parent card. This way you can style the card and the elements inside it with custom CSS. The Class can be set at runtime by setting a <code>msg.className</code> string property.</p>
|
||||
</script>
|
||||
3
node_modules/node-red-dashboard/nodes/locales/en-US/ui_spacer.html
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<script type="text/html" data-help-name="ui_spacer">
|
||||
<p>If a <b>Class</b> is specified, it will be added to the parent card. This way you can style the card and the elements inside it with custom CSS. The Class can be set at runtime by setting a <code>msg.className</code> string property.</p>
|
||||
</script>
|
||||
19
node_modules/node-red-dashboard/nodes/locales/en-US/ui_switch.html
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
<script type="text/html" data-help-name="ui_switch">
|
||||
<p>Adds a switch to the user interface.</p>
|
||||
<p>Each change in the state of the switch will generate
|
||||
a <code>msg.payload</code> with the specified <b>On</b> and <b>Off</b> values.</p>
|
||||
<p>The <b>On/Off Color</b> and <b>On/Off Icon</b> are optional fields. If they are all present, the default
|
||||
toggle switch will be replaced with the relevant icons and their respective colors.</p>
|
||||
<p>The <b>On/Off Icon</b> field can be either a <a href="https://klarsys.github.io/angular-material-icons/" target="_blank">Material Design icon</a>
|
||||
<i>(e.g. 'check', 'close')</i> or a <a href="https://fontawesome.com/v4.7.0/icons/" target="_blank">Font Awesome icon</a>
|
||||
<i>(e.g. 'fa-fire')</i>, or a <a href="https://github.com/Paul-Reed/weather-icons-lite/blob/master/css_mappings.md">Weather icon</a>.
|
||||
You can use the full set of google material icons if you add 'mi-' to the icon name. e.g. 'mi-videogame_asset'.</p>
|
||||
<p>In pass through mode the switch state can be updated by an incoming <code>msg.payload</code> with the specified values,
|
||||
that must also match the specified type (number, string, etc). When not in passthrough mode then the icon can either
|
||||
track the state of the output - or the input msg.payload, in order to provide a closed loop feedback.</p>
|
||||
<p>The label can also be set by a message property by setting
|
||||
the field to the name of the property, for example <code>{{msg.topic}}</code>.</p>
|
||||
<p>If a <b>Topic</b> is specified, it will be added to the output as <code>msg.topic</code>.</p>
|
||||
<p>Setting <code>msg.enabled</code> to <code>false</code> will disable the switch widget.</p>
|
||||
<p>If a <b>Class</b> is specified, it will be added to the parent card. This way you can style the card and the elements inside it with custom CSS. The Class can be set at runtime by setting a <code>msg.className</code> string property.</p>
|
||||
</script>
|
||||
13
node_modules/node-red-dashboard/nodes/locales/en-US/ui_tab.html
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
<script type="text/html" data-help-name="ui_tab">
|
||||
<p>Tab configuration for Dashboard</p>
|
||||
<p><b>Disabled</b> pages are not included in the Dashboard app, and are therefore not functional.
|
||||
The tab name still appears in the Navigation Menu (unless it is also hidden).
|
||||
</p>
|
||||
<p><b>Hidden</b> pages are not listed in the Left-hand Navigation Menu.
|
||||
However, they are still active in the Dashboard, and can be shown by using a `ui_control` msg.
|
||||
</p>
|
||||
<p>The <b>Icon</b> field can be either a <a href="https://klarsys.github.io/angular-material-icons/" target="_blank">Material Design icon</a>
|
||||
<i>(e.g. 'check', 'close')</i> or a <a href="https://fontawesome.com/v4.7.0/icons/" target="_blank">Font Awesome icon</a>
|
||||
<i>(e.g. 'fa-fire')</i>, or a <a href="https://github.com/Paul-Reed/weather-icons-lite/blob/master/css_mappings.md">Weather icon</a>.
|
||||
You can use the full set of google material icons if you add 'mi-' to the icon name. e.g. 'mi-videogame_asset'.</p>
|
||||
</script>
|
||||
21
node_modules/node-red-dashboard/nodes/locales/en-US/ui_tab.json
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"ui_tab" : {
|
||||
"label" : {
|
||||
"home" : "Home",
|
||||
"tab" : "Tab",
|
||||
"name" : "Name",
|
||||
"icon" : "Icon",
|
||||
"state" : "State",
|
||||
"navmenu" : "Nav. Menu",
|
||||
"enabled" : "Enabled",
|
||||
"disabled" : "Disabled",
|
||||
"visible" : "Visible",
|
||||
"hidden" : "Hidden"
|
||||
},
|
||||
"info": {
|
||||
"disabled": " Tab is inactive in Dashboard.",
|
||||
"hidden": " Tab is not shown in Navigation Menu."
|
||||
},
|
||||
"tip" : "The <b>Icon</b> field can be either a <a href=\"https://klarsys.github.io/angular-material-icons/\" target=\"_blank\">Material Design icon</a> <i>(e.g. 'check', 'close')</i> or a <a href=\"https://fontawesome.com/v4.7.0/icons/\" target=\"_blank\">Font Awesome icon</a> <i>(e.g. 'fa-fire')</i>, or a <a href=\"https://github.com/Paul-Reed/weather-icons-lite/blob/master/css_mappings.md\" target=\"_blank\">Weather icon</a> <i>(e.g. 'wi-wu-sunny')</i>.</p><p>You can use the full set of google material icons if you add 'mi-' to the icon name. e.g. 'mi-videogame_asset'.</p>"
|
||||
}
|
||||
}
|
||||
49
node_modules/node-red-dashboard/nodes/locales/en-US/ui_template.html
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
<script type="text/html" data-help-name="ui_template">
|
||||
<p>The template widget can contain any valid html and Angular/Angular-Material directives.</p>
|
||||
<p>This node can be used to create a dynamic user interface element that changes its appearance
|
||||
based on the input message and can send back messages to Node-RED.</p>
|
||||
<p><b>For example:</b><br>
|
||||
<pre style="font-size:smaller;"><div layout="row" layout-align="space-between">
|
||||
<p>The number is</p>
|
||||
<font color="{{((msg.payload || 0) % 2 === 0) ? 'green' : 'red'}}">
|
||||
{{(msg.payload || 0) % 2 === 0 ? 'even' : 'odd'}}
|
||||
</font>
|
||||
</div></pre>
|
||||
Will display if the number received as <code>msg.payload</code> is even or odd. It will also
|
||||
change the color of the text to green if the number is even or red if odd.<br/>
|
||||
The next example shows how to set a unique id for your template, pick up the default theme colour,
|
||||
and watch for any incoming message.</p>
|
||||
<pre style="font-size:smaller;">
|
||||
<div id="{{'my_'+$id}}" style="{{'color:'+theme.base_color}}">Some text</div>
|
||||
<script>
|
||||
(function(scope) {
|
||||
scope.$watch('msg', function(msg) {
|
||||
if (msg) {
|
||||
// Do something when msg arrives
|
||||
$("#my_"+scope.$id).html(msg.payload);
|
||||
}
|
||||
});
|
||||
})(scope);
|
||||
</script></pre>
|
||||
<p>Templates made in this way can be copied and remain independent of each other.</p>
|
||||
<p><b>Sending a message:</b><br>
|
||||
<pre style="font-size:smaller;">
|
||||
<script>
|
||||
var value = "hello world";
|
||||
// or overwrite value in your callback function ...
|
||||
this.scope.action = function() { return value; }
|
||||
</script>
|
||||
<md-button ng-click="send({payload:action()})">
|
||||
Click me to send a hello world
|
||||
</md-button></pre>
|
||||
Will display a button that when clicked will send a message with the payload <code>'Hello world'</code>.</p>
|
||||
<p><b>Using <code>msg.template</code>:</b><br>
|
||||
You can also define the template content via <code>msg.template</code>, so you can use external files for example.<br>
|
||||
Template will be reloaded on input if it has changed.<br>
|
||||
Code written in the Template field will be ignored when <code>msg.template</code> is present.</p>
|
||||
<p>The following icon fonts are available: <a href="https://klarsys.github.io/angular-material-icons/" target="_blank">Material Design icon</a>
|
||||
<i>(e.g. 'check', 'close')</i> or a <a href="https://fontawesome.com/v4.7.0/icons/" target="_blank">Font Awesome icon</a>
|
||||
<i>(e.g. 'fa-fire')</i>, or a <a href="https://github.com/Paul-Reed/weather-icons-lite/blob/master/css_mappings.md">Weather icon</a>.
|
||||
You can use the full set of Google material icons if you add 'mi-' to the icon name. e.g. 'mi-videogame_asset'.</p>
|
||||
<p>If a <b>Class</b> is specified, it will be added to the parent card. This way you can style the card and the elements inside it with custom CSS. The Class can be set at runtime by setting a <code>msg.className</code> string property.</p>
|
||||
</script>
|
||||
19
node_modules/node-red-dashboard/nodes/locales/en-US/ui_template.json
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"ui_template": {
|
||||
"label": {
|
||||
"type": "Template type",
|
||||
"local": "Widget in group",
|
||||
"global": "Added to site <head> section",
|
||||
"group": "Group",
|
||||
"size": "Size",
|
||||
"name": "Name",
|
||||
"pass-through": "Pass through messages from input.",
|
||||
"store-state": "Add output messages to stored state.",
|
||||
"template": "Template",
|
||||
"expand": "Expand",
|
||||
"resend": "Reload last value on refresh.",
|
||||
"className": "Class",
|
||||
"classNamePlaceholder": "Optional CSS class name(s) for widget"
|
||||
}
|
||||
}
|
||||
}
|
||||
16
node_modules/node-red-dashboard/nodes/locales/en-US/ui_text.html
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<script type="text/html" data-help-name="ui_text">
|
||||
<p>Will display a non-editable text field on the user interface.</p>
|
||||
<p>Each received <code>msg.payload</code> will update the text based on the provided <b>Value Format</b>.</p>
|
||||
<p>The <b>Value Format</b> field can be used to change the displayed format and can contain valid HTML and
|
||||
<a href="https://scotch.io/tutorials/all-about-the-built-in-angularjs-filters" target="_blank">Angular filters</a>.</p>
|
||||
<p>For example: <code>{{value | uppercase}} &deg;</code> will uppercase the payload text and add the degree symbol.</p>
|
||||
<p>The label can also be set by a message property by setting
|
||||
the field to the name of the property, for example <code>{{msg.topic}}</code>.</p>
|
||||
<p>The following icon fonts are also available: <a href="https://klarsys.github.io/angular-material-icons/" target="_blank">Material Design icon</a>
|
||||
<i>(e.g. 'check', 'close')</i> or a <a href="https://fontawesome.com/v4.7.0/icons/" target="_blank">Font Awesome icon</a>
|
||||
<i>(e.g. 'fa-fire')</i>, or a <a href="https://github.com/Paul-Reed/weather-icons-lite/blob/master/css_mappings.md">Weather icon</a>.
|
||||
You can use the full set of google material icons if you add 'mi-' to the icon name. e.g. 'mi-videogame_asset'.</p>
|
||||
<p>The widget also has a class of <code>nr-dashboard-widget-{the_widget_label_with_underscores}</code> which can be used for additional
|
||||
styling if required. You may need to use the <i>!important</i> flag to override the theme.</p>
|
||||
<p>If a <b>Class</b> is specified, it will be added to the parent card. This way you can style the card and the elements inside it with custom CSS. The Class can be set at runtime by setting a <code>msg.className</code> string property.</p>
|
||||
</script>
|
||||
16
node_modules/node-red-dashboard/nodes/locales/en-US/ui_text_input.html
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<script type="text/html" data-help-name="ui_text_input">
|
||||
<p>Adds a text input field to the user interface. Mode can be regular text, email or color picker.</p>
|
||||
<p>Any input is sent as <code>msg.payload</code>. If set to ‘pass through mode’ an arriving <code>msg.payload</code>
|
||||
will be used if it is different from the existing text in the input field. This allows you to preset
|
||||
the text of the input field.</p>
|
||||
<p>The <b>Delay</b> <i>(default : 300ms)</i> sets the amount of time in milliseconds before the output is sent.
|
||||
Setting to <code>0</code> waits for "Enter" or "Tab" key to send. Enter will send payload but remain in focus.
|
||||
Tab will send payload and move to next field. Clicking elsewhere will also send the payload.</p>
|
||||
<p>The email mode will color in red if it is not a valid address and will return undefined.</p>
|
||||
<p>The time input type returns a number of milliseconds from midnight.</p>
|
||||
<p>Not all browsers support the <i>week</i> and <i>month</i> input types, and may return <i>undefined</i>.
|
||||
Please test your target browser(s) before use.</p>
|
||||
<p>If a <b>Topic</b> is specified, it will be added as <code>msg.topic</code>.</p>
|
||||
<p>Setting <code>msg.enabled</code> to <code>false</code> will disable the input.</p>
|
||||
<p>If a <b>Class</b> is specified, it will be added to the parent card. This way you can style the card and the elements inside it with custom CSS. The Class can be set at runtime by setting a <code>msg.className</code> string property.</p>
|
||||
</script>
|
||||
16
node_modules/node-red-dashboard/nodes/locales/en-US/ui_toast.html
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<script type="text/html" data-help-name="ui_toast">
|
||||
<p>Shows <code>msg.payload</code> as a popup notification or OK / Cancel dialog
|
||||
message on the user interface.</p>
|
||||
<p>If a <code>msg.topic</code> is available it will be used as the title.</p>
|
||||
<p>If you do not set an optional border highlight colour, then it can be set dynamically by <code>msg.highlight</code>.</p>
|
||||
<p>You may also configure the position and duration of the toast notifications. If you leave the timeout blank
|
||||
it can be set by <code>msg.timeout</code>. This does not apply to OK/Cancel dialogs.
|
||||
<p>The dialog returns a <code>msg.payload</code> string of whatever you configure
|
||||
the button label(s) to be. The second (cancel) button is optional, as is the return
|
||||
value of <code>msg.topic</code>.</p>
|
||||
<p>If you select 'OK, Cancel and Input' mode then <code>msg.payload</code> will contain
|
||||
any text input by the user, rather than the OK button text.</p>
|
||||
<p>The OK and Cancel button labels can be replaced by using <code>msg.ok</code> and <code>msg.cancel</code></p>
|
||||
<p>Sending a blank payload will remove any active dialog without sending any data.</p>
|
||||
<p>If a <b>Class</b> is specified, it will be added to the parent element. This way you can style the card and the elements inside it with custom CSS.</p>
|
||||
</script>
|
||||
28
node_modules/node-red-dashboard/nodes/locales/en-US/ui_ui_control.html
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
<script type="text/html" data-help-name="ui_ui_control">
|
||||
<p>Allows dynamic control of the Dashboard.</p>
|
||||
<p>The default function is to change the currently displayed tab. <code>msg.payload</code>
|
||||
should either be an object of the form <code>{"tab":"my_tab_name"}</code>, or just be the <b>tab name</b>
|
||||
or <b>numeric index</b> (from 0) of the tab or link to be displayed.</p>
|
||||
<p>Sending a blank tab name "" will refresh the current page.
|
||||
You can also send "+1" for next tab and "-1" for previous tab.</p>
|
||||
<p>Dashboard pages (i.e. "tabs") can be controlled by sending a <code>msg.payload</code> object with the format
|
||||
<pre>{"tabs": {"hide": "tab_name_to_hide", "disable": ["secret_tab", "unused_stuff"]}}</pre>.
|
||||
There are 2 toggle states available: <b>show</b>/<b>hide</b> and <b>enable</b>/<b>disable</b></p>
|
||||
<p>Visibility of individual groups of widgets can controlled by a payload like
|
||||
<pre>{"group": {"hide": ["tab_name_group_name_with_underscores"], "show": ["reveal_another_group"], "focus": true}}</pre>
|
||||
where <b>focus</b> is optional and will cause the screen to scroll to show that group if required.
|
||||
You can also use properties `open` and `close` to set the state of a group that can be controlled by the user. The group
|
||||
names are the IDs of the groups and are typically formed from the <i>tab name</i> plus <i>group name</i> joined with
|
||||
underscores replacing all spaces.</p>
|
||||
<p>When any browser client connects or loses connection, changes tab, or expands or collapses a group this node will emit a <code>msg</code> containing:</p>
|
||||
<ul>
|
||||
<li><code>payload</code> - <i>connect</i>, <i>lost</i>, <i>change</i>, or <i>group</i>.
|
||||
<li><code>socketid</code> - the ID of the socket (this will change every time the browser reloads the page).
|
||||
<li><code>socketip</code> - the ip address from where the connection originated.
|
||||
<li><code>tab</code> - the number of the tab. (only for 'change' event).
|
||||
<li><code>name</code> - the name of the tab. (only for 'change' event).
|
||||
<li><code>group</code> - the name of the group. (only for 'group' event).
|
||||
<li><code>open</code> - the state of the group. (only for 'group' event).
|
||||
</ul>
|
||||
<p>Optional - report only connect events - useful to use to trigger a resend of data to a new client without needing to filter out other events.</p>
|
||||
</script>
|
||||
16
node_modules/node-red-dashboard/nodes/locales/en-US/ui_ui_control.json
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"ui_ui_control": {
|
||||
"label": {
|
||||
"name": "Name",
|
||||
"output": "Output"
|
||||
},
|
||||
"placeholder": {
|
||||
"name": "Name"
|
||||
},
|
||||
"events": {
|
||||
"all": "Connect, lost, change tab or group events",
|
||||
"change": "Change tab or group events only",
|
||||
"connect": "Connect event only"
|
||||
}
|
||||
}
|
||||
}
|
||||
99
node_modules/node-red-dashboard/nodes/locales/ja/ui_base.json
generated
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
{
|
||||
"ui_base" : {
|
||||
"label" : {
|
||||
"dashboard" : "ダッシュボード",
|
||||
"title" : "タイトル",
|
||||
"options" : "オプション",
|
||||
"date-format" : "日付形式",
|
||||
"sizes" : "サイズ",
|
||||
"horizontal" : "横",
|
||||
"vertical" : "縦",
|
||||
"widget-size" : "最小Widgetサイズ",
|
||||
"widget-spacing" : "Widget間隔",
|
||||
"group-padding" : "グループパディング",
|
||||
"group-spacing" : "グループ間隔",
|
||||
"layout" : "配置",
|
||||
"angular": "Angular",
|
||||
"theme" : "テーマ",
|
||||
"site" : "サイト"
|
||||
},
|
||||
"auto" : "自動",
|
||||
"title" : "Node-REDダッシュボード",
|
||||
"layout" : {
|
||||
"tab-and-link" : "タブ & リンク",
|
||||
"tab" : "タブ",
|
||||
"link" : "リンク",
|
||||
"group" : "グループ",
|
||||
"edit" : "編集",
|
||||
"spacer": "スペーサ",
|
||||
"layout" : "レイアウト",
|
||||
"layout-editor" : "ダッシュボードレイアウトエディタ",
|
||||
"width" : "幅",
|
||||
"auto": "自動サイズ調整",
|
||||
"manual": "手動サイズ変更"
|
||||
},
|
||||
"theme" : {
|
||||
"style" : "スタイル",
|
||||
"custom-profile" : "カスタムプロファイル",
|
||||
"custom-profile-name" : "名称未設定テーマ 1",
|
||||
"base-settings" : "基本設定",
|
||||
"page-settings" : "ページ設定",
|
||||
"page" : {
|
||||
"title" : "タイトルバー背景色",
|
||||
"page" : "ページ背景色",
|
||||
"side" : "サイドバー背景色"
|
||||
},
|
||||
"group-settings" : "グループ設定",
|
||||
"group" : {
|
||||
"text" : "グループ文字色",
|
||||
"border" : "グループボーダー色",
|
||||
"background" : "グループ背景色"
|
||||
},
|
||||
"widget-settings" : "Widget設定",
|
||||
"widget" : {
|
||||
"text" : "Widget文字色",
|
||||
"colour" : "Widget色",
|
||||
"background" : "Widget背景色"
|
||||
}
|
||||
},
|
||||
"style" : {
|
||||
"light" : "ライト (デフォルト)",
|
||||
"dark" : "ダーク",
|
||||
"custom" : "カスタム",
|
||||
"primary" : "プライマリ",
|
||||
"accents" : "アクセント",
|
||||
"background" : "背景",
|
||||
"warnings" : "警告",
|
||||
"palette": "ライト/ダーク"
|
||||
},
|
||||
"base" : {
|
||||
"colour" : "色",
|
||||
"font" : "フォント"
|
||||
},
|
||||
"font" : {
|
||||
"system" : "システムフォント (デフォルト)"
|
||||
},
|
||||
"site" : {
|
||||
"title" : "Node-RED ダッシュボード",
|
||||
"date-format" : "YYYY/MM/DD"
|
||||
},
|
||||
"title-bar" : {
|
||||
"show" : "タイトルバー表示",
|
||||
"hide" : "タイトルバー非表示"
|
||||
},
|
||||
"swipe" : {
|
||||
"no-swipe" : "スワイプによるタブ切り替えをしない",
|
||||
"allow-swipe" : "スワイプによるタブ切り替えをする"
|
||||
},
|
||||
"lock" : {
|
||||
"clicked" : "サイドメニューをクリックで表示",
|
||||
"locked" : "サイドメニューを表示したままにする",
|
||||
"locked-icon": "常にアイコンのみを表示"
|
||||
},
|
||||
"temp" : {
|
||||
"no-theme" : "ui_templateでテーマ設定を許可しない",
|
||||
"allow-theme" : "ui_templateでテーマ設定を許可する",
|
||||
"none" : "Angularテーマを全ての箇所で使用"
|
||||
}
|
||||
}
|
||||
}
|
||||
13
node_modules/node-red-dashboard/nodes/locales/ja/ui_chart.html
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
<script type="text/html" data-help-name="ui_chart">
|
||||
<p>入力値をグラフに出力します。このグラフは、時系列の折れ線グラフ、棒グラフ(縦や横)、円グラフのいずれかです。</p>
|
||||
<p>入力値の<code>msg.payload</code>は、数値に変換されます。もし変換に失敗した場合は、メッセージは無視されます。</p>
|
||||
<p><b>Y</b>軸の最小値と最大値を設定することは任意です。グラフは自動的に受け取った値を用いて自動的に目盛りを調整します。</p>
|
||||
<p>入力メッセージ毎に異なる<code>msg.topic</code>の値を用いることで、1つのグラフに複数の系列を表示できます。<code>msg.label</code>プロパティを用いることで、同じ系列の複数の棒グラフを表示できます。</p>
|
||||
<p><b>X</b>軸には、表示する時間、または最大のポイント数を定義します。古くなったデータは、自動的にグラフから削除されます。軸のラベルは、<a href="https://momentjs.com/docs/#/displaying/format/" target="_blank">Moment.jsの時間フォーマット</a>の文字列を用いて表示できます。</p>
|
||||
<p><code>msg.payload</code>に空の配列<code>[]</code>を含む入力によってグラフを初期化できます。</p>
|
||||
<p>全てのグラフに渡すデータの作成方法については、<b><a href="https://github.com/node-red/node-red-dashboard/blob/master/Charts.md" target="_new">本情報</a></b>を参照してください。</p>
|
||||
<p><b>初期ラベル</b>フィールドを用いることで、有効なデータを受け取る前にテキストを表示しておくことができます。</p>
|
||||
<p>プロパティ名(例えば<code>{{msg.topic}}</code>)をラベル欄に設定しておくことで、ラベルをメッセージのプロパティによって設定できます。</p>
|
||||
<p>本ノードの出力には、必要に応じて保存されたグラフの状態を持つ配列が含まれています。本データをchartノードに渡すことで、保存されたデータを再表示することもできます。</p>
|
||||
<p>クラスが指定されている場合、そのクラスは親要素に追加されます。 このようにして、カスタムCSSを使用して、カードとその中の要素のスタイルを設定できます。 クラスは、<code> msg.className </code>文字列プロパティを設定することで実行時に設定できます。</p>
|
||||
</script>
|
||||
56
node_modules/node-red-dashboard/nodes/locales/ja/ui_chart.json
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"ui_chart": {
|
||||
"label": {
|
||||
"group": "グループ",
|
||||
"size": "サイズ",
|
||||
"label": "ラベル",
|
||||
"optionalChartTitle": "任意のグラフタイトル",
|
||||
"type": "種類",
|
||||
"lineChart": "  折れ線グラフ",
|
||||
"barChart": "  棒グラフ",
|
||||
"barChartH": "  棒グラフ(横)",
|
||||
"pieChart": "  円グラフ",
|
||||
"polarAreaChart": "  鶏頭図",
|
||||
"radarChart": "  レーダーチャート",
|
||||
"enlargePoints": "ポイントを表示",
|
||||
"xAxis": "X軸",
|
||||
"last": "直近",
|
||||
"seconds": "秒",
|
||||
"minutes": "分",
|
||||
"hours": "時間",
|
||||
"days": "日",
|
||||
"weeks": "週",
|
||||
"or": "又は",
|
||||
"points": "ポイント",
|
||||
"xAxisLabel": "X軸ラベル",
|
||||
"HHmmss": "HH:mm:ss",
|
||||
"HHmm": "HH:mm",
|
||||
"yearMonthDate": "年-月-日",
|
||||
"dateMonth": "日/月",
|
||||
"dayHHmm": "曜日 HH:mm",
|
||||
"custom": "カスタム",
|
||||
"automatic": "自動",
|
||||
"asUTC": "UTCを使用",
|
||||
"yAxis": "Y軸",
|
||||
"min": "最小",
|
||||
"max": "最大",
|
||||
"legend": "凡例",
|
||||
"none": "非表示",
|
||||
"show": "表示",
|
||||
"interpolate": "補完",
|
||||
"linear": "直線",
|
||||
"step": "段階",
|
||||
"bezier": "ベジェ",
|
||||
"cubic": "3次補間",
|
||||
"cubicMono": "単調3次補間",
|
||||
"cutout": "中心の切抜き率",
|
||||
"useFirstColourForAllBars": "最初の色を全グラフで使用",
|
||||
"seriesColours": "配色",
|
||||
"blankLabel": "初期ラベル",
|
||||
"displayThisTextBeforeValidDataArrives": "有効なデータが届く前に本文字列を表示",
|
||||
"useDifferentColor": "シリーズに別の色を使用",
|
||||
"className": "種類",
|
||||
"classNamePlaceholder": "ウィジェット用のCSSクラス名(オプション)"
|
||||
}
|
||||
}
|
||||
}
|
||||
17
node_modules/node-red-dashboard/nodes/locales/ja/ui_form.html
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<script type="text/html" data-help-name="ui_form">
|
||||
<p>ユーザインターフェイスにフォームを追加します。</p>
|
||||
<p>ユーザから複数の値を受け付け、送信ボタンのクリックによって、<code>msg.payload</code>のオブジェクトとして値を送信できます。</p>
|
||||
<p>要素ボタンで追加することで、複数の入力向けの要素を追加できます。</p>
|
||||
<p>各要素は、以下の部品を持っています:</p>
|
||||
<ul>
|
||||
<li> <b>ラベル</b> : ユーザインターフェイス上の要素のラベルとなる値</li>
|
||||
<li> <b>名前</b> : 要素と対応する値を格納する<code>msg.payload</code>内のキー(変数名)</li>
|
||||
<li> <b>種類</b> : 入力向けの要素の種類を選択するドロップダウンオプション</li>
|
||||
<li> <b>必須</b> : 有効にするとユーザは送信前に値を埋める必要となる設定</li>
|
||||
<li> <b>行数</b> : 複数行から成るテキスト入力欄UIの行数</li>
|
||||
<li> <b>削除</b> : 現在の要素をフォームから削除</li>
|
||||
</ul>
|
||||
<p><b>Topic</b>欄は任意で<code>msg.topic</code>プロパティを設定するために用いることができます。</p>
|
||||
<p>キャンセルボタンは、値に空白""を設定することで非表示にできます。</p>
|
||||
<p>クラスが指定されている場合、そのクラスは親要素に追加されます。 このようにして、カスタムCSSを使用して、カードとその中の要素のスタイルを設定できます。 クラスは、<code> msg.className </code>文字列プロパティを設定することで実行時に設定できます。</p>
|
||||
</script>
|
||||
35
node_modules/node-red-dashboard/nodes/locales/ja/ui_form.json
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"ui_form": {
|
||||
"label": {
|
||||
"group": "グループ",
|
||||
"size": "サイズ",
|
||||
"label": "ラベル",
|
||||
"optionalLabel": "任意のラベル",
|
||||
"formElements": "フォームの要素",
|
||||
"type": "種類",
|
||||
"required": "必須",
|
||||
"rows": "行数",
|
||||
"remove": "削除",
|
||||
"egName": "例) 名前",
|
||||
"egName2": "例) name",
|
||||
"text": "文字列",
|
||||
"multiline": "複数行",
|
||||
"number": "数値",
|
||||
"email": "E-メール",
|
||||
"password": "パスワード",
|
||||
"checkbox": "チェックボックス",
|
||||
"switch": "スイッチ",
|
||||
"date": "日付",
|
||||
"time": "時間",
|
||||
"element": "要素",
|
||||
"buttons": "ボタン",
|
||||
"submitButtonText": "送信ボタンの文字列",
|
||||
"cancelButtonText": "キャンセルボタンの文字列",
|
||||
"topic": "トピック",
|
||||
"optionalMsgTopic": "任意のmsg.topic",
|
||||
"splitLayout": "フォーム要素を2列に配置",
|
||||
"className": "種類",
|
||||
"classNamePlaceholder": "ウィジェット用のCSSクラス名(オプション)"
|
||||
}
|
||||
}
|
||||
}
|
||||
16
node_modules/node-red-dashboard/nodes/locales/ja/ui_group.json
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"ui_group" : {
|
||||
"label" : {
|
||||
"name" : "名前",
|
||||
"tab" : "タブ",
|
||||
"width" : "幅",
|
||||
"default" : "デフォルト",
|
||||
"group" : "グループ",
|
||||
"unassigned" : "未設定",
|
||||
"className": "種類",
|
||||
"classNamePlaceholder": "ウィジェット用のCSSクラス名(オプション)"
|
||||
},
|
||||
"display-name" : "グループ名を表示する",
|
||||
"collapse-name" : "グループの折りたたみを有効にする"
|
||||
}
|
||||
}
|
||||
16
node_modules/node-red-dashboard/nodes/locales/ja/ui_link.json
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"ui_link" : {
|
||||
"label" : {
|
||||
"name" : "名前",
|
||||
"link" : "リンク",
|
||||
"icon" : "アイコン",
|
||||
"open-in" : "開く方法",
|
||||
"new-tab" : "新規タブ",
|
||||
"this-tab" : "このタブ",
|
||||
"iframe" : "iframe",
|
||||
"className": "種類",
|
||||
"classNamePlaceholder": "ウィジェット用のCSSクラス名(オプション)"
|
||||
},
|
||||
"tip" : "<b>アイコン</b>フィールドには <a href=\"https://klarsys.github.io/angular-material-icons/\" target=\"_blank\">Material Design icon</a> <i>(例: 'check', 'close')</i>、<a href=\"https://fontawesome.com/v4.7.0/icons/\" target=\"_blank\">Font Awesome icon</a> <i>(例: 'fa-fire')</i>、もしくは <a href=\"https://github.com/Paul-Reed/weather-icons-lite/blob/master/css_mappings.md\" target=\"_blank\">Weather icon</a> <i>(例: 'wi-wu-sunny')</i>を指定できます。</p>"
|
||||
}
|
||||
}
|
||||
21
node_modules/node-red-dashboard/nodes/locales/ja/ui_tab.json
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"ui_tab" : {
|
||||
"label" : {
|
||||
"home" : "ホーム",
|
||||
"tab" : "タブ",
|
||||
"name" : "名前",
|
||||
"icon" : "アイコン",
|
||||
"state" : "状態",
|
||||
"navmenu" : "メニュー",
|
||||
"enabled" : "有効",
|
||||
"disabled" : "無効",
|
||||
"visible" : "表示",
|
||||
"hidden" : "非表示"
|
||||
},
|
||||
"info": {
|
||||
"disabled": " タブを無効化します",
|
||||
"hidden": " タブを移動メニューに表示しません"
|
||||
},
|
||||
"tip" : "<b>アイコン</b>フィールドには <a href=\"https://klarsys.github.io/angular-material-icons/\" target=\"_blank\">Material Design icon</a> <i>(例: 'check', 'close')</i>、<a href=\"https://fontawesome.com/v4.7.0/icons/\" target=\"_blank\">Font Awesome icon</a> <i>(例: 'fa-fire')</i>、もしくは <a href=\"https://github.com/Paul-Reed/weather-icons-lite/blob/master/css_mappings.md\" target=\"_blank\">Weather icon</a> <i>(例: 'wi-wu-sunny')</i>を指定できます。</p>"
|
||||
}
|
||||
}
|
||||
44
node_modules/node-red-dashboard/nodes/locales/ja/ui_template.html
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<script type="text/html" data-help-name="ui_template">
|
||||
<p>Template WidgetにはHTMLコードおよびAngular/Angular-Materialディレクティブを指定できます。</p>
|
||||
<p>このノードで動的なユーザインターフェイス要素を作成し、入力によって見た目を変更したり、メッセージをNode-REDに送り返したりできます。</p>
|
||||
<p><b>例:</b><br>
|
||||
<pre style="font-size:smaller;"><div layout="row" layout-align="space-between">
|
||||
<p>数値は</p>
|
||||
<font color="{{((msg.payload || 0) % 2 === 0) ? 'green' : 'red'}}">
|
||||
{{(msg.payload || 0) % 2 === 0 ? '偶数' : '奇数'}}
|
||||
</font>
|
||||
</div></pre>
|
||||
このコードは<code>msg.payload</code>で受け取った数値が偶数か奇数かを表示します。同時に、偶数であれば緑に、奇数であれば赤にテキストの色を変更します。<br/>
|
||||
次は、一意なIDをテンプレートに設定、デフォルトのテーマカラーを設定、入力メッセージの到着を監視する例です。</p>
|
||||
<pre style="font-size:smaller;">
|
||||
<div id="{{'my_'+$id}}" style="{{'color:'+theme.base_color}}">何らかのテキスト</div>
|
||||
<script>
|
||||
(function(scope) {
|
||||
scope.$watch('msg', function(msg) {
|
||||
if (msg) {
|
||||
// メッセージ同着時に適当な処理を実行
|
||||
$("#my_"+scope.$id).html(msg.payload);
|
||||
}
|
||||
});
|
||||
})(scope);
|
||||
</script></pre>
|
||||
<p>この方法で作成したテンプレートはコピー可能です。コピーはそれぞれ独立して利用できます。</p>
|
||||
<p><b>メッセージ送信:</b><br>
|
||||
<pre style="font-size:smaller;">
|
||||
<script>
|
||||
var value = "こんにちは世界";
|
||||
// もしくは、コールバック関数で値を書き換え
|
||||
this.scope.action = function() { return value; }
|
||||
</script>
|
||||
<md-button ng-click="send({payload:action()})">
|
||||
クリックすると「こんにちは世界」を送信します
|
||||
</md-button></pre>
|
||||
この例は、クリックするとペイロードに<code>'こんにちは世界'</code>を持つメッセージを送信するボタンを表示します。</p>
|
||||
<p><b><code>msg.template</code>の使用:</b><br>
|
||||
<code>msg.template</code>によってテンプレートを定義することもできます。例えば、外部ファイルに格納したテンプレートを用いる場合に有用です。<br>
|
||||
テンプレートは入力が変化した場合に再ロードされます。<br>
|
||||
「HTMLコード」フィールドに記述したコードは、<code>msg.template</code>が存在する場合には無視されます。</p>
|
||||
<p>以下のアイコンフォントの利用も可能です: <a href="https://klarsys.github.io/angular-material-icons/" target="_blank">マテリアルデザインアイコン</a><i>(例:'check'、'close')</i>、<a href="https://fontawesome.com/v4.7.0/icons/" target="_blank">Font Awesomeアイコン</a><i>(例:'fa-fire')</i>、<a href="https://github.com/Paul-Reed/weather-icons-lite/blob/master/css_mappings.md">天気アイコン</a>。
|
||||
アイコン名に'mi-’に追加することでGoogleマテリアルアイコン一式を利用できます。例:'mi-videogame_asset'。</p>
|
||||
<p>クラスが指定されている場合、そのクラスは親要素に追加されます。 このようにして、カスタムCSSを使用して、カードとその中の要素のスタイルを設定できます。 クラスは、<code> msg.className </code>文字列プロパティを設定することで実行時に設定できます。</p>
|
||||
</script>
|
||||
19
node_modules/node-red-dashboard/nodes/locales/ja/ui_template.json
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"ui_template" : {
|
||||
"label" : {
|
||||
"type" : "コード種別",
|
||||
"local" : "グループ内のWidget",
|
||||
"global" : "<head>ヘッドセクションへ追加",
|
||||
"group" : "グループ",
|
||||
"size" : "サイズ",
|
||||
"name" : "名前",
|
||||
"pass-through" : "入力メッセージをそのまま渡す",
|
||||
"store-state" : "出力メッセージを状態として保存",
|
||||
"template" : "HTMLコード",
|
||||
"expand": "展開する",
|
||||
"resend": "更新時に最後の値を再度読み込む",
|
||||
"className": "種類",
|
||||
"classNamePlaceholder": "ウィジェット用のCSSクラス名(オプション)"
|
||||
}
|
||||
}
|
||||
}
|
||||
25
node_modules/node-red-dashboard/nodes/locales/ja/ui_ui_control.html
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<script type="text/html" data-help-name="ui_ui_control">
|
||||
<p>ダッシュボードの動的制御を行います</p>
|
||||
<p>表示されているタブの切り替えが可能です。<code>msg.payload</code>に
|
||||
The default function is to change the currently displayed tab. <code>msg.payload</code>に表示対象のタブもしくはリンクの<code>{tab:"タブ名"}</code>、<b>タブ名</b>、もしくは、<b>添字</b> (0起点)を指定します。</p>
|
||||
<p>空のタブ名("")を送信すると、表示されているページを更新します。また、"+1"を送ると次のタブ、"-1"を送ると前のタブに切り替えられます。</p>
|
||||
<p>次の形式のオブジェクトを<code>msg.payload</code>で送付すると
|
||||
ダッシュボードページ(タブ)を制御できます。<pre>{"tabs": {"hide": "非表示タブ", "disable": ["秘密タブ", "未使用"]}}</pre>
|
||||
ここでは、次の2つの状態が利用できます: <b>show</b>/<b>hide</b> および <b>enable</b>/<b>disable</b></p>
|
||||
<p>widgetグループの表示を次のようなペイロードで制御できます。<br/>
|
||||
<pre>{group:{hide:["タブ名_グループ名"], show:["他_グループ_表示"], focus:true}}</pre>
|
||||
<b>focus</b>は、グループが表示されるよう必要に応じて画面をスクロールするためのパラメータで、省略可能です。
|
||||
また、`open`および`close`プロパティを用いてグループの状態をユーザが制御できます。
|
||||
グループ名の指定は<i>タブ名</i>と<i>グループ名</i>を下線(_)で結合したものを用います。空白は下線で置き換えます。</p>
|
||||
<p>クライアントのブラウザが接続もしくは切断した場合、タブが変更された場合、グループを拡大もしくは縮小した場合、次のプロパティを持つメッセージを送信します:</p>
|
||||
<ul>
|
||||
<li><code>payload</code> - <i>connect</i>、<i>lost</i>、<i>change</i>、もしくは<i>group</i>
|
||||
<li><code>socketid</code> - ソケットID(ブラウザがページを再ロードする毎に変化します)
|
||||
<li><code>socketip</code> - 接続元のIPアドレス,
|
||||
<li><code>tab</code> - タブ番号 ('change'イベントのみ)
|
||||
<li><code>name</code> - タブ名 ('change'イベントのみ)
|
||||
<li><code>group</code> - グループ名 ('group'イベントのみ)
|
||||
<li><code>open</code> - グループの状態 ('group'イベントのみ)
|
||||
</ul>
|
||||
<p>追加 - 「Connectイベントのみ」は新しいクライアントへのデータの再送を他のイベントをフィルタしないで行う場合に有用です。</p>
|
||||
</script>
|
||||
16
node_modules/node-red-dashboard/nodes/locales/ja/ui_ui_control.json
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"ui_ui_control" : {
|
||||
"label" : {
|
||||
"name" : "名前",
|
||||
"output": "出力"
|
||||
},
|
||||
"placeholder" : {
|
||||
"name" : "名前"
|
||||
},
|
||||
"events": {
|
||||
"all": "connect, lost, タブ変更もしくはグループイベント",
|
||||
"change": "タブ変更もしくはグループイベントのみ",
|
||||
"connect": "Connectイベントのみ"
|
||||
}
|
||||
}
|
||||
}
|
||||
69
node_modules/node-red-dashboard/nodes/ui_audio.html
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<script type="text/javascript">
|
||||
(function() {
|
||||
var myvoice = 0;
|
||||
var voices;
|
||||
RED.nodes.registerType('ui_audio',{
|
||||
category: RED._("node-red-dashboard/ui_base:ui_base.label.category"),
|
||||
paletteLabel: 'audio out',
|
||||
color: 'rgb(119, 198, 204)',
|
||||
defaults: {
|
||||
name: {value:""},
|
||||
group: {type: 'ui_group', required: true},
|
||||
voice: {value:""},
|
||||
always: {value:""}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:0,
|
||||
icon: "feed.png",
|
||||
align: "right",
|
||||
label: function() { return this.name||"audio out"; },
|
||||
labelStyle: function() { return this.name?"node_label_italic":""; },
|
||||
onpaletteadd: function() {
|
||||
if ('speechSynthesis' in window) { voices = window.speechSynthesis.getVoices(); }
|
||||
},
|
||||
oneditprepare: function() {
|
||||
if ('speechSynthesis' in window) {
|
||||
voices = window.speechSynthesis.getVoices();
|
||||
for (i = 0; i < voices.length ; i++) {
|
||||
//console.log(i,voices[i].name,voices[i].lang,voices[i].voiceURI,voices[i].default);
|
||||
var option = document.createElement('option');
|
||||
option.textContent = i + " : " + voices[i].name + ' (' + voices[i].lang + ')';
|
||||
if (voices[i].default) { option.textContent += ' -- DEFAULT'; }
|
||||
option.setAttribute('value', voices[i].voiceURI);
|
||||
document.getElementById("node-input-voice").appendChild(option);
|
||||
}
|
||||
$('#node-input-voice').val(this.voice || 0);
|
||||
}
|
||||
else {
|
||||
$('#voice-input-row').hide();
|
||||
}
|
||||
|
||||
$("#node-input-voice").on("change", function() {
|
||||
myvoice = this.voice = $("#node-input-voice").val();
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-template-name="ui_audio">
|
||||
<div class="form-row">
|
||||
<label for="node-input-group"><i class="fa fa-table"></i> Group</label>
|
||||
<input type="text" id="node-input-group">
|
||||
</div>
|
||||
<div class="form-row" id="voice-input-row">
|
||||
<label for="node-input-voice"><i class="fa fa-language"></i> TTS Voice</label>
|
||||
<select id="node-input-voice" style="width:70%"></select>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-always"></label>
|
||||
<input type="checkbox" checked id="node-input-always" style="display:inline-block; width:auto; vertical-align:top;">
|
||||
Play audio when window not in focus.
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
</script>
|
||||
49
node_modules/node-red-dashboard/nodes/ui_audio.js
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
module.exports = function(RED) {
|
||||
var ui = require('../ui')(RED);
|
||||
|
||||
function uiAudioNode(config) {
|
||||
RED.nodes.createNode(this,config);
|
||||
this.voice = config.voice;
|
||||
this.group = config.group;
|
||||
this.always = config.always || false;
|
||||
if (this.group && RED.nodes.getNode(this.group).hasOwnProperty("config")) {
|
||||
this.tabname = RED.nodes.getNode(RED.nodes.getNode(this.group).config.tab).name;
|
||||
}
|
||||
var node = this;
|
||||
node.status({});
|
||||
|
||||
this.on('input', function(msg) {
|
||||
if (msg.hasOwnProperty("level") && (isNaN(msg.level) || msg.level > 300 || msg.level < 0)) {
|
||||
delete msg.level;
|
||||
}
|
||||
if (msg.reset == true) {
|
||||
ui.emitSocket('ui-audio', { reset:true, tabname:node.tabname, always:node.always, socketid:msg.socketid });
|
||||
}
|
||||
else if (Buffer.isBuffer(msg.payload)) {
|
||||
ui.emitSocket('ui-audio', { audio:msg.payload, tabname:node.tabname, always:node.always, vol:msg.level, socketid:msg.socketid });
|
||||
}
|
||||
else if (typeof msg.payload === "string") {
|
||||
ui.emitSocket('ui-audio', { tts:msg.payload, voice:(node.voice || msg.voice || 0), tabname:node.tabname, always:node.always, vol:msg.level, socketid:msg.socketid });
|
||||
}
|
||||
});
|
||||
|
||||
var updateStatus = function(audioStatus) {
|
||||
if (audioStatus === "complete") {
|
||||
// When the audio or speech has played completely, clear the node status
|
||||
node.status({});
|
||||
}
|
||||
else if (audioStatus.indexOf("error") === 0) {
|
||||
node.status({shape:"ring",fill:"red",text:audioStatus});
|
||||
}
|
||||
else {
|
||||
node.status({shape:"dot",fill:"blue",text:audioStatus});
|
||||
}
|
||||
};
|
||||
ui.ev.on('audiostatus', updateStatus);
|
||||
|
||||
this.on('close', function() {
|
||||
ui.ev.removeListener('audiostatus', updateStatus);
|
||||
})
|
||||
}
|
||||
RED.nodes.registerType("ui_audio", uiAudioNode);
|
||||
}
|
||||
3401
node_modules/node-red-dashboard/nodes/ui_base.html
generated
vendored
Normal file
125
node_modules/node-red-dashboard/nodes/ui_base.js
generated
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
module.exports = function(RED) {
|
||||
var ui = require('../ui')(RED);
|
||||
var path= require('path');
|
||||
var gsp = require.resolve('gridstack');
|
||||
var node;
|
||||
var uiset = RED.settings.ui || "{}";
|
||||
|
||||
function BaseNode(config) {
|
||||
RED.nodes.createNode(this, config);
|
||||
node = this;
|
||||
var baseFontName = "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif";
|
||||
|
||||
var defaultLightTheme = {
|
||||
baseColor: '#0094CE',
|
||||
baseFont: baseFontName
|
||||
}
|
||||
var defaultDarkTheme = {
|
||||
baseColor: '#097479',
|
||||
baseFont: baseFontName
|
||||
}
|
||||
var defaultCustomTheme = {
|
||||
name: 'Untitled Theme 1',
|
||||
baseColor: defaultLightTheme.baseColor,
|
||||
baseFont: baseFontName
|
||||
}
|
||||
var defaultAngularTheme = {
|
||||
primary:'indigo',
|
||||
accents:'teal',
|
||||
warn: "red",
|
||||
background:'grey',
|
||||
palette:'light'
|
||||
};
|
||||
|
||||
// Setup theme name
|
||||
// First try old format (for upgrading with old flow file)
|
||||
// Then try new format
|
||||
// Else fallback to theme-light
|
||||
var themeName;
|
||||
if (typeof(config.theme) === 'string') { themeName = config.theme; }
|
||||
else { themeName = config.theme.name || "theme-light"; }
|
||||
|
||||
// Setup other styles
|
||||
var defaultThemeState = {}
|
||||
if (themeName === 'theme-light') {
|
||||
defaultThemeState["base-font"] = {value: baseFontName};
|
||||
defaultThemeState["base-color"] = {value: "#0094CE"};
|
||||
defaultThemeState["page-backgroundColor"] = {value: "#fafafa"};
|
||||
defaultThemeState["page-titlebar-backgroundColor"] = {value: "#0094CE"};
|
||||
defaultThemeState["page-sidebar-backgroundColor"] = {value: "#ffffff"};
|
||||
defaultThemeState["group-backgroundColor"] = {value: "#ffffff"};
|
||||
defaultThemeState["group-textColor"] = {value: "#000000"};
|
||||
defaultThemeState["group-borderColor"] = {value: "#ffffff"};
|
||||
defaultThemeState["widget-textColor"] = {value: "#111111"};
|
||||
defaultThemeState["widget-backgroundColor"] = {value: "#0094CE"};
|
||||
}
|
||||
else {
|
||||
defaultThemeState["base-font"] = {value: baseFontName};
|
||||
defaultThemeState["base-color"] = {value: "#097479"};
|
||||
defaultThemeState["page-backgroundColor"] = {value: "#111111"};
|
||||
defaultThemeState["page-titlebar-backgroundColor"] = {value: "#097479"};
|
||||
defaultThemeState["page-sidebar-backgroundColor"] = {value: "#333333"};
|
||||
defaultThemeState["group-backgroundColor"] = {value: "#333333"};
|
||||
defaultThemeState["group-textColor"] = {value: "#10cfd8"};
|
||||
defaultThemeState["group-borderColor"] = {value: "#555555"};
|
||||
defaultThemeState["widget-textColor"] = {value: "#eeeeee"};
|
||||
defaultThemeState["widget-backgroundColor"] = {value: "#097479"};
|
||||
}
|
||||
|
||||
var defaultThemeObject = {
|
||||
name: themeName,
|
||||
lightTheme: config.theme.lightTheme || defaultLightTheme,
|
||||
darkTheme: config.theme.darkTheme || defaultDarkTheme,
|
||||
customTheme: config.theme.customTheme || defaultCustomTheme,
|
||||
angularTheme: config.theme.angularTheme || defaultAngularTheme,
|
||||
themeState: config.theme.themeState || defaultThemeState
|
||||
}
|
||||
|
||||
this.config = {
|
||||
theme: defaultThemeObject,
|
||||
site: config.site
|
||||
}
|
||||
ui.addBaseConfig(this.config);
|
||||
}
|
||||
RED.nodes.registerType("ui_base", BaseNode);
|
||||
|
||||
RED.library.register("themes");
|
||||
|
||||
RED.httpAdmin.get('/uisettings', function(req, res) {
|
||||
res.json(uiset);
|
||||
});
|
||||
|
||||
const optsjs = { root: path.join(__dirname , '../dist/js'), dotfiles: 'deny' };
|
||||
const optscss = { root: path.join(__dirname , '../dist/css'), dotfiles: 'deny' };
|
||||
const optsgs = { root: path.dirname(gsp), dotfiles: 'deny' };
|
||||
|
||||
RED.httpAdmin.get('/ui_base/js/*', function(req, res) {
|
||||
res.sendFile(req.params[0], optsjs, function (err) {
|
||||
if (err) {
|
||||
res.sendStatus(404);
|
||||
if (node) { node.warn("JS File not found."); }
|
||||
else { console.log("ui_base - error:",err); }
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
RED.httpAdmin.get('/ui_base/css/*', function(req, res) {
|
||||
res.sendFile(req.params[0], optscss, function (err) {
|
||||
if (err) {
|
||||
res.sendStatus(404);
|
||||
if (node) { node.warn("CSS File not found."); }
|
||||
else { console.log("ui_base - error:",err); }
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
RED.httpAdmin.get('/ui_base/gs/*', function(req, res) {
|
||||
res.sendFile(req.params[0], optsgs, function (err) {
|
||||
if (err) {
|
||||
res.sendStatus(404);
|
||||
if (node) { node.warn("Gridstack file not found."); }
|
||||
else { console.log("ui_base - error:",err); }
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
116
node_modules/node-red-dashboard/nodes/ui_button.html
generated
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('ui_button',{
|
||||
category: RED._("node-red-dashboard/ui_base:ui_base.label.category"),
|
||||
color: 'rgb(176, 223, 227)',
|
||||
defaults: {
|
||||
name: {value: ''},
|
||||
group: {type: 'ui_group', required: true},
|
||||
order: {value: 0},
|
||||
width: {value: 0, validate: function(v) {
|
||||
var width = v||0;
|
||||
var currentGroup = $('#node-input-group').val()||this.group;
|
||||
var groupNode = RED.nodes.node(currentGroup);
|
||||
var valid = !groupNode || +width <= +groupNode.width;
|
||||
$("#node-input-size").toggleClass("input-error",!valid);
|
||||
return valid;
|
||||
}
|
||||
},
|
||||
height: {value: 0},
|
||||
passthru: {value: false},
|
||||
label: {value: 'button'},
|
||||
tooltip: {value: ''},
|
||||
color: {value: ''},
|
||||
bgcolor: {value: ''},
|
||||
className: {value: ''},
|
||||
icon: {value: ''},
|
||||
payload: {value: '',validate: (RED.validators.hasOwnProperty('typedInput')?RED.validators.typedInput('payloadType'):function(v) { return true})},
|
||||
payloadType: { value: 'str'},
|
||||
topic: {value: 'topic', validate: (RED.validators.hasOwnProperty('typedInput')?RED.validators.typedInput('topicType'):function(v) { return true})},
|
||||
topicType: {value: 'msg'}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:1,
|
||||
outputLabels: function() { if (this.payloadType === "str") {
|
||||
return this.payload;
|
||||
} else {return this.payloadType; } },
|
||||
icon: "ui_button.png",
|
||||
paletteLabel: 'button',
|
||||
label: function() { return this.name || (~this.label.indexOf("{{") ? null : this.label) || 'button'; },
|
||||
labelStyle: function() { return this.name?"node_label_italic":""; },
|
||||
oneditprepare: function() {
|
||||
$("#node-input-size").elementSizer({
|
||||
width: "#node-input-width",
|
||||
height: "#node-input-height",
|
||||
group: "#node-input-group"
|
||||
});
|
||||
$('#node-input-payload').typedInput({
|
||||
default: 'str',
|
||||
typeField: $("#node-input-payloadType"),
|
||||
types: ['str','num','bool','json','bin','date','flow','global']
|
||||
});
|
||||
$('#node-input-topic').typedInput({
|
||||
default: 'str',
|
||||
typeField: $("#node-input-topicType"),
|
||||
types: ['str','msg','flow','global']
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-template-name="ui_button">
|
||||
<div class="form-row">
|
||||
<label for="node-input-group"><i class="fa fa-table"></i> <span data-i18n="ui_button.label.group"></label>
|
||||
<input type="text" id="node-input-group">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label><i class="fa fa-object-group"></i> <span data-i18n="ui_button.label.size"></label>
|
||||
<input type="hidden" id="node-input-width">
|
||||
<input type="hidden" id="node-input-height">
|
||||
<button class="editor-button" id="node-input-size"></button>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-icon"><i class="fa fa-picture-o"></i> <span data-i18n="ui_button.label.icon"></label>
|
||||
<input type="text" id="node-input-icon" data-i18n="[placeholder]ui_button.label.optionalIcon">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-label"><i class="fa fa-i-cursor"></i> <span data-i18n="ui_button.label.label"></label>
|
||||
<input type="text" id="node-input-label" data-i18n="[placeholder]ui_button.label.optionalLabel">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-tooltip"><i class="fa fa-info-circle"></i> <span data-i18n="ui_button.label.tooltip"></label>
|
||||
<input type="text" id="node-input-tooltip" data-i18n="[placeholder]ui_button.label.optionalTooltip">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-color"><i class="fa fa-tint"></i> <span data-i18n="ui_button.label.color"></label>
|
||||
<input type="text" id="node-input-color" data-i18n="[placeholder]ui_button.label.optionalColor">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-bgcolor"><i class="fa fa-tint"></i> <span data-i18n="ui_button.label.background"></label>
|
||||
<input type="text" id="node-input-bgcolor" data-i18n="[placeholder]ui_button.label.optionalBackgroundColor">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label style="width:auto" for="node-input-payload"><i class="fa fa-envelope-o"></i> <span data-i18n="ui_button.label.whenClicked"></label>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-payload" style="padding-left: 25px; margin-right: -25px"><span data-i18n="ui_button.label.payload"></label>
|
||||
<input type="text" id="node-input-payload" style="width:70%">
|
||||
<input type="hidden" id="node-input-payloadType">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-topic" style="padding-left: 25px; margin-right: -25px"><span data-i18n="ui_button.label.topic"></label>
|
||||
<input type="text" id="node-input-topic">
|
||||
<input type="hidden" id="node-input-topicType">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label style="width:auto" for="node-input-passthru"><i class="fa fa-arrow-right"></i> <span data-i18n="ui_button.label.emulateClick"></label>
|
||||
<input type="checkbox" id="node-input-passthru" style="display:inline-block; width:auto; vertical-align:top;">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-className"><i class="fa fa-code"></i> <span data-i18n="ui_button.label.className"></label>
|
||||
<input type="text" id="node-input-className" data-i18n="[placeholder]ui_button.label.classNamePlaceholder"/>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></label>
|
||||
<input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name">
|
||||
</div>
|
||||
</script>
|
||||
91
node_modules/node-red-dashboard/nodes/ui_button.js
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
module.exports = function(RED) {
|
||||
var ui = require('../ui')(RED);
|
||||
|
||||
function ButtonNode(config) {
|
||||
RED.nodes.createNode(this, config);
|
||||
var node = this;
|
||||
|
||||
var group = RED.nodes.getNode(config.group);
|
||||
if (!group) { return; }
|
||||
var tab = RED.nodes.getNode(group.config.tab);
|
||||
if (!tab) { return; }
|
||||
|
||||
var payloadType = config.payloadType;
|
||||
var payload = config.payload;
|
||||
|
||||
if (payloadType === 'flow' || payloadType === 'global') {
|
||||
try {
|
||||
var parts = RED.util.normalisePropertyExpression(payload);
|
||||
if (parts.length === 0) {
|
||||
throw new Error();
|
||||
}
|
||||
}
|
||||
catch(err) {
|
||||
node.warn("Invalid payload property expression - defaulting to node id")
|
||||
payload = node.id;
|
||||
payloadType = 'str';
|
||||
}
|
||||
}
|
||||
else {
|
||||
payload = payload || node.id;
|
||||
}
|
||||
|
||||
node.on("input", function(msg) {
|
||||
try {
|
||||
node.topi = RED.util.evaluateNodeProperty(config.topic,config.topicType || "str",node,msg);
|
||||
}
|
||||
catch(e) { }
|
||||
});
|
||||
|
||||
var done = ui.add({
|
||||
node: node,
|
||||
tab: tab,
|
||||
group: group,
|
||||
emitOnlyNewValues: false,
|
||||
forwardInputMessages: config.passthru || false,
|
||||
storeFrontEndInputAsState: false,
|
||||
control: {
|
||||
type: 'button',
|
||||
label: config.label,
|
||||
tooltip: config.tooltip,
|
||||
color: config.color,
|
||||
bgcolor: config.bgcolor,
|
||||
className: config.className,
|
||||
icon: config.icon,
|
||||
order: config.order,
|
||||
value: payload,
|
||||
format: config.bgcolor,
|
||||
width: config.width || group.config.width || 3,
|
||||
height: config.height || 1
|
||||
},
|
||||
beforeSend: function (msg,m2) {
|
||||
var t = undefined;
|
||||
try {
|
||||
t = RED.util.evaluateNodeProperty(config.topic,config.topicType || "str",node,msg)
|
||||
}
|
||||
catch(e) { }
|
||||
if (typeof t === "undefined") { t = node.topi; }
|
||||
if (t !== undefined) { msg.topic = t; }
|
||||
if (((config.topicType || "str") === "str") && t == "") { delete msg.topic; }
|
||||
if (m2 !== undefined) { msg.event = m2.event; }
|
||||
},
|
||||
convertBack: function (value) {
|
||||
if (payloadType === "date") {
|
||||
value = Date.now();
|
||||
}
|
||||
else {
|
||||
try {
|
||||
value = RED.util.evaluateNodeProperty(payload,payloadType,node);
|
||||
}
|
||||
catch(e) {
|
||||
if (payloadType === "bin") { node.error("Badly formatted buffer"); }
|
||||
else { node.error(e,payload); }
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
});
|
||||
node.on("close", done);
|
||||
}
|
||||
RED.nodes.registerType("ui_button", ButtonNode);
|
||||
};
|
||||
295
node_modules/node-red-dashboard/nodes/ui_chart.html
generated
vendored
Normal file
@@ -0,0 +1,295 @@
|
||||
<style>
|
||||
input.series-color {
|
||||
width: 100px;
|
||||
text-align: center;
|
||||
}
|
||||
input.series-color::-webkit-color-swatch {
|
||||
border: none;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('ui_chart',{
|
||||
category: RED._("node-red-dashboard/ui_base:ui_base.label.category"),
|
||||
color: 'rgb(119, 198, 204)',
|
||||
defaults: {
|
||||
name: {value: ''},
|
||||
group: {type: 'ui_group', required: true},
|
||||
order: {value: 0},
|
||||
width: {value: 0, validate: function(v) {
|
||||
var width = v||0;
|
||||
var currentGroup = $('#node-input-group').val()||this.group;
|
||||
var groupNode = RED.nodes.node(currentGroup);
|
||||
var valid = !groupNode || +width <= +groupNode.width;
|
||||
$("#node-input-size").toggleClass("input-error",!valid);
|
||||
return valid;
|
||||
}},
|
||||
height: {value: 0},
|
||||
label: {value: 'chart'},
|
||||
chartType: {value: 'line'},
|
||||
legend: {value: 'false'},
|
||||
xformat: {value: 'HH:mm:ss'},
|
||||
interpolate: {value: 'linear', required:true},
|
||||
nodata: {value: ''},
|
||||
dot: {value: false},
|
||||
ymin: {value: '', validate:function(value) { return value === '' || RED.validators.number(); }},
|
||||
ymax: {value: '', validate:function(value) { return value === '' || RED.validators.number(); }},
|
||||
removeOlder: {value: 1, validate:RED.validators.number(), required:true},
|
||||
removeOlderPoints: {value: '', validate:function(value) { return value === '' || RED.validators.number(); }},
|
||||
removeOlderUnit: {value: '3600', required:true},
|
||||
cutout: {value: 0},
|
||||
useOneColor: {value: false},
|
||||
useUTC: {value: false},
|
||||
colors: {value: ['#1F77B4', '#AEC7E8', '#FF7F0E', '#2CA02C', '#98DF8A', '#D62728', '#FF9896', '#9467BD', '#C5B0D5']},
|
||||
outputs: {value: 1},
|
||||
useDifferentColor: {value: false},
|
||||
className: {value: ''}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:1,
|
||||
inputLabels: function() { return this.chartType; },
|
||||
outputLabels: ["chart state"],
|
||||
align: "right",
|
||||
icon: "ui_chart.png",
|
||||
paletteLabel: 'chart',
|
||||
label: function() { return this.name || (~this.label.indexOf("{{") ? null : this.label) || 'chart'; },
|
||||
labelStyle: function() { return this.name?"node_label_italic":""; },
|
||||
oneditprepare: function() {
|
||||
var oldouts = this.outputs;
|
||||
if (RED.nodes.filterLinks({source:{id:this.id},sourcePort:1}).length > 0) { this.outputs = 2; }
|
||||
else { this.outputs = 1; }
|
||||
if (this.outputs !== oldouts) { this.changed = true; }
|
||||
if (!$("#node-input-chartType").val()) {
|
||||
$("#node-input-chartType").val("line");
|
||||
}
|
||||
$("#node-input-size").elementSizer({
|
||||
width: "#node-input-width",
|
||||
height: "#node-input-height",
|
||||
group: "#node-input-group"
|
||||
});
|
||||
$("#node-input-chartType").on("change", function() {
|
||||
$("#legend-show").hide();
|
||||
$("#show-useDifferentColor").hide();
|
||||
if ($(this).val() === "horizontalBar") {
|
||||
$("#y-label-show").hide();
|
||||
$("#x-label-show").show();
|
||||
}
|
||||
else {
|
||||
$("#y-label-show").show();
|
||||
$("#x-label-show").hide();
|
||||
}
|
||||
if ($(this).val() === "line") {
|
||||
$("#x-axis-show").show();
|
||||
$("#x-axis-label-show").show();
|
||||
$("#interpolate-show").show();
|
||||
$("#legend-show").show();
|
||||
$("#y-axis-show").show();
|
||||
$("#hole-size-show").hide();
|
||||
$("#show-dot-field").show();
|
||||
$("#show-useOneColor").hide();
|
||||
}
|
||||
else {
|
||||
$("#x-axis-show").hide();
|
||||
$("#x-axis-label-show").hide();
|
||||
$("#interpolate-show").hide();
|
||||
$("#show-dot-field").hide();
|
||||
if (($(this).val() === "bar")||($(this).val() === "horizontalBar")) {
|
||||
$("#show-useOneColor").show();
|
||||
$("#legend-show").show();
|
||||
}
|
||||
else {
|
||||
$("#show-useOneColor").hide();
|
||||
}
|
||||
if ($(this).val() === "pie") {
|
||||
$("#y-axis-show").hide();
|
||||
$("#legend-show").show();
|
||||
$("#hole-size-show").show();
|
||||
}
|
||||
else if ($(this).val() === "polar-area") {
|
||||
$("#y-axis-show").show();
|
||||
$("#legend-show").show();
|
||||
$("#hole-size-show").hide();
|
||||
$("#show-useDifferentColor").show();
|
||||
}
|
||||
else if ($(this).val() === "radar") {
|
||||
$("#y-axis-show").show();
|
||||
$("#legend-show").show();
|
||||
$("#hole-size-show").hide();
|
||||
}
|
||||
else {
|
||||
$("#y-axis-show").show();
|
||||
$("#hole-size-show").hide();
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
var setColour = function(id, value) {
|
||||
$(id).val(value);
|
||||
$(id).css("background-color", value);
|
||||
var rgb = tinycolor(value).toRgb();
|
||||
var level = ((rgb.r*299) + (rgb.g*587) + (rgb.b*114))/1000;
|
||||
var textColor = (level >= 128) ? '#111111' : '#eeeeee';
|
||||
$(id).css("color", textColor);
|
||||
}
|
||||
$(".series-color").on("change", function() {
|
||||
setColour("#"+$(this).attr("id"), $(this).val());
|
||||
});
|
||||
var oval = $("#node-input-xformat").val();
|
||||
if (!oval) { $("#node-input-xformat").val("HH:mm:ss"); }
|
||||
var odef = 'custom';
|
||||
if (oval === "HH:mm:ss") { odef = oval; }
|
||||
if (oval === "HH:mm") { odef = oval; }
|
||||
if (oval === "Y-M-D") { odef = oval; }
|
||||
if (oval === "D/M") { odef = oval; }
|
||||
if (oval === "dd HH:mm") { odef = oval; }
|
||||
if (oval === "auto") { odef = oval; }
|
||||
var ohms = {value: "HH:mm:ss", label: RED._("node-red-dashboard/ui_chart:ui_chart.label.HHmmss"), hasValue: false};
|
||||
var ohm = {value: "HH:mm", label: RED._("node-red-dashboard/ui_chart:ui_chart.label.HHmm"), hasValue: false};
|
||||
var oymd = {value: "Y-M-D", label: RED._("node-red-dashboard/ui_chart:ui_chart.label.yearMonthDate"), hasValue: false};
|
||||
var odm = {value: "D/M", label: RED._("node-red-dashboard/ui_chart:ui_chart.label.dateMonth"), hasValue: false};
|
||||
var oahm = {value: "dd HH:mm", label: RED._("node-red-dashboard/ui_chart:ui_chart.label.dayHHmm"), hasValue: false};
|
||||
var ocus = {value: "custom", label: RED._("node-red-dashboard/ui_chart:ui_chart.label.custom"), icon: "red/images/typedInput/az.png"};
|
||||
var oaut = {value: "auto", label: RED._("node-red-dashboard/ui_chart:ui_chart.label.automatic"), hasValue: false};
|
||||
$("#node-input-xformat").typedInput({
|
||||
default: odef,
|
||||
types:[ ohms, ohm, oahm, odm, oymd, ocus, oaut ]
|
||||
});
|
||||
var defaultColors = ['#1F77B4', '#AEC7E8', '#FF7F0E', '#2CA02C', '#98DF8A', '#D62728', '#FF9896', '#9467BD', '#C5B0D5'];
|
||||
|
||||
if (this.colors) {
|
||||
for (var i=0; i<this.colors.length; i++) {
|
||||
var value = this.colors[i] || defaultColors[i];
|
||||
setColour("#node-input-color"+(i+1), value);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (var c=0; c<defaultColors.length; c++) {
|
||||
setColour("#node-input-color"+(c+1), defaultColors[c]);
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
oneditsave: function() {
|
||||
if ($("#node-input-xformat").typedInput('type') !== 'custom') {
|
||||
$("#node-input-xformat").val($("#node-input-xformat").typedInput('type'));
|
||||
}
|
||||
this.colors = [$("#node-input-color1").val(),$("#node-input-color2").val(),$("#node-input-color3").val(),
|
||||
$("#node-input-color4").val(),$("#node-input-color5").val(),$("#node-input-color6").val(),
|
||||
$("#node-input-color7").val(),$("#node-input-color8").val(),$("#node-input-color9").val()];
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-template-name="ui_chart">
|
||||
<div class="form-row">
|
||||
<label for="node-input-group"><i class="fa fa-table"></i> <span data-i18n="ui_chart.label.group"></label>
|
||||
<input type="text" id="node-input-group">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label><i class="fa fa-object-group"></i> <span data-i18n="ui_chart.label.size"></label>
|
||||
<input type="hidden" id="node-input-width">
|
||||
<input type="hidden" id="node-input-height">
|
||||
<button class="editor-button" id="node-input-size"></button>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-label"><i class="fa fa-i-cursor"></i> <span data-i18n="ui_chart.label.label"></label>
|
||||
<input type="text" id="node-input-label" data-i18n="[placeholder]ui_chart.label.optionalChartTitle">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-removeOlder"><i class="fa fa-line-chart"></i> <span data-i18n="ui_chart.label.type"></label>
|
||||
<select id="node-input-chartType" style="width:159px; font-family:'FontAwesome','Helvetica Neue', Helvetica, Arial, sans-serif">
|
||||
<option value="line" data-i18n="[html]ui_chart.label.lineChart"></option>
|
||||
<option value="bar" data-i18n="[html]ui_chart.label.barChart"></option>
|
||||
<option value="horizontalBar" data-i18n="[html]ui_chart.label.barChartH"></option>
|
||||
<option value="pie" data-i18n="[html]ui_chart.label.pieChart"></option>
|
||||
<option value="polar-area" data-i18n="[html]ui_chart.label.polarAreaChart"></option>
|
||||
<option value="radar" data-i18n="[html]ui_chart.label.radarChart"></option>
|
||||
</select>
|
||||
<div id="show-dot-field" style="display:inline-block;">
|
||||
<input type="checkbox" id="node-input-dot" style="display:inline-block; width:auto; vertical-align:baseline; margin-left:40px; margin-right:5px;"><span data-i18n="ui_chart.label.enlargePoints">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row" id="x-axis-show">
|
||||
<label for="node-input-removeOlder" data-i18n="ui_chart.label.xAxis"></label>
|
||||
<label for="node-input-removeOlder" style="width:auto" data-i18n="ui_chart.label.last"></label>
|
||||
<input type="text" id="node-input-removeOlder" style="width:50px;">
|
||||
<select id="node-input-removeOlderUnit" style="width:80px;">
|
||||
<option value="1" data-i18n="ui_chart.label.seconds"></option>
|
||||
<option value="60" data-i18n="ui_chart.label.minutes"></option>
|
||||
<option value="3600" data-i18n="ui_chart.label.hours"></option>
|
||||
<option value="86400" data-i18n="ui_chart.label.days"></option>
|
||||
<option value="604800" data-i18n="ui_chart.label.weeks"></option>
|
||||
</select>
|
||||
<label for="node-input-removeOlderPoints" style="width:auto; margin-left:10px; margin-right:10px;" data-i18n="ui_chart.label.or"></label>
|
||||
<input type="text" id="node-input-removeOlderPoints" style="width:60px;" placeholder="1000">
|
||||
<span style="margin-left:5px;" data-i18n="ui_chart.label.points"></span>
|
||||
</div>
|
||||
<div class="form-row" id="x-axis-label-show">
|
||||
<label for="node-input-xformat" data-i18n="ui_chart.label.xAxisLabel"></label>
|
||||
<input type="text" id="node-input-xformat" style="width:250px;">
|
||||
<input type="checkbox" id="node-input-useUTC" style="display:inline-block; width:auto; vertical-align:baseline; margin-left:8px; margin-right:4px;"> <span data-i18n="ui_chart.label.asUTC"></span>
|
||||
</div>
|
||||
<div class="form-row" id="y-axis-show">
|
||||
<label id="y-label-show" for="node-input-ymin" data-i18n="ui_chart.label.yAxis"></label>
|
||||
<label id="x-label-show" for="node-input-ymin" data-i18n="ui_chart.label.xAxis"></label>
|
||||
<label for="node-input-ymin" style="width:auto" data-i18n="ui_chart.label.min"></label>
|
||||
<input type="text" id="node-input-ymin" style="width:92px">
|
||||
<label for="node-input-ymax" style="width:auto; margin-left:20px;" data-i18n="ui_chart.label.max"></label>
|
||||
<input type="text" id="node-input-ymax" style="width:92px">
|
||||
</div>
|
||||
<div class="form-row" id="legend-show">
|
||||
<label for="node-input-legend" data-i18n="ui_chart.label.legend"></label>
|
||||
<select id="node-input-legend" style="width:120px;">
|
||||
<option value="false" data-i18n="ui_chart.label.none"></option>
|
||||
<option value="true" data-i18n="ui_chart.label.show"></option>
|
||||
</select>
|
||||
<span id="interpolate-show"> <span data-i18n="ui_chart.label.interpolate"></span>
|
||||
<select id="node-input-interpolate" style="width:120px;">
|
||||
<option value="linear" data-i18n="ui_chart.label.linear"></option>
|
||||
<option value="step" data-i18n="ui_chart.label.step"></option>
|
||||
<option value="bezier" data-i18n="ui_chart.label.bezier"></option>
|
||||
<option value="cubic" data-i18n="ui_chart.label.cubic"></option>
|
||||
<option value="monotone" data-i18n="ui_chart.label.cubicMono"></option>
|
||||
</select>
|
||||
</span>
|
||||
<span id="hole-size-show"> <span data-i18n="ui_chart.label.cutout"></span>
|
||||
<input type="text" id="node-input-cutout" style="width:35px"> %
|
||||
</span>
|
||||
</div>
|
||||
<div id="show-useOneColor" style="display:none; height:24px;">
|
||||
<input type="checkbox" id="node-input-useOneColor" style="display:inline-block; width:auto; vertical-align:baseline; margin-left:105px; margin-right:5px;"><span data-i18n="ui_chart.label.useFirstColourForAllBars"></span>
|
||||
</div>
|
||||
<div class="form-row" id="ui-chart-colours">
|
||||
<label for="node-input-color1" data-i18n="ui_chart.label.seriesColours"></label>
|
||||
<input type="color" id="node-input-color1" class="series-color" style="width:100px;"/>
|
||||
<input type="color" id="node-input-color2" class="series-color" style="width:100px;"/>
|
||||
<input type="color" id="node-input-color3" class="series-color" style="width:100px;"/>
|
||||
<div style="margin-top:5px; margin-left:104px;">
|
||||
<input type="color" id="node-input-color4" class="series-color" style="width:100px;"/>
|
||||
<input type="color" id="node-input-color5" class="series-color" style="width:100px;"/>
|
||||
<input type="color" id="node-input-color6" class="series-color" style="width:100px;"/>
|
||||
</div>
|
||||
<div style="margin-top:5px; margin-left:104px;">
|
||||
<input type="color" id="node-input-color7" class="series-color" style="width:100px;"/>
|
||||
<input type="color" id="node-input-color8" class="series-color" style="width:100px;"/>
|
||||
<input type="color" id="node-input-color9" class="series-color" style="width:100px;"/>
|
||||
</div>
|
||||
</div>
|
||||
<div id="show-useDifferentColor" class="form-row">
|
||||
<label></label>
|
||||
<input type="checkbox" id="node-input-useDifferentColor" style="display:inline-block; width:auto; vertical-align:top;">
|
||||
<span data-i18n="ui_chart.label.useDifferentColor"></span>
|
||||
</input>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-nodata" data-i18n="ui_chart.label.blankLabel"></label>
|
||||
<input type="text" id="node-input-nodata" data-i18n="[placeholder]ui_chart.label.displayThisTextBeforeValidDataArrives">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-className"><i class="fa fa-code"></i> <span data-i18n="ui_chart.label.className"></span></label>
|
||||
<input type="text" id="node-input-className" data-i18n="[placeholder]ui_chart.label.classNamePlaceholder"/>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></label>
|
||||
<input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name">
|
||||
</div>
|
||||
</script>
|
||||
234
node_modules/node-red-dashboard/nodes/ui_chart.js
generated
vendored
Normal file
@@ -0,0 +1,234 @@
|
||||
module.exports = function(RED) {
|
||||
var ui = require('../ui')(RED);
|
||||
var ChartIdList = {};
|
||||
|
||||
function ChartNode(config) {
|
||||
RED.nodes.createNode(this, config);
|
||||
this.chartType = config.chartType || "line";
|
||||
var node = this;
|
||||
var group = RED.nodes.getNode(config.group);
|
||||
if (!group) { return; }
|
||||
var tab = RED.nodes.getNode(group.config.tab);
|
||||
if (!tab) { return; }
|
||||
if (config.width === "0") { delete config.width; }
|
||||
if (config.height === "0") { delete config.height; }
|
||||
// number of pixels wide the chart will be... 43 = sizes.sx - sizes.px
|
||||
//var pixelsWide = ((config.width || group.config.width || 6) - 1) * 43 - 15;
|
||||
if (!tab || !group) { return; }
|
||||
var dnow = Date.now();
|
||||
var options = {
|
||||
emitOnlyNewValues: true,
|
||||
node: node,
|
||||
tab: tab,
|
||||
group: group,
|
||||
control: {
|
||||
type: 'chart',
|
||||
look: node.chartType,
|
||||
order: config.order,
|
||||
label: config.label,
|
||||
legend: config.legend || false,
|
||||
interpolate: config.interpolate,
|
||||
nodata: config.nodata,
|
||||
width: parseInt(config.width || group.config.width || 6),
|
||||
height: parseInt(config.height || group.config.width/2+1 || 4),
|
||||
ymin: config.ymin,
|
||||
ymax: config.ymax,
|
||||
dot: config.dot || false,
|
||||
xformat : config.xformat || "HH:mm:ss",
|
||||
cutout: parseInt(config.cutout || 0),
|
||||
colors: config.colors,
|
||||
useOneColor: config.useOneColor || false,
|
||||
useUTC: config.useUTC || false,
|
||||
animation: false,
|
||||
spanGaps: false,
|
||||
useDifferentColor: config.useDifferentColor || false,
|
||||
options: {},
|
||||
className: config.className || '',
|
||||
},
|
||||
convertBack: function(data) {
|
||||
if (data) {
|
||||
if (data[0] && data[0].hasOwnProperty("values")) {
|
||||
return [data[0].values];
|
||||
}
|
||||
if (data.length == 0) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
convert: function(value, oldValue, msg) {
|
||||
var converted = {};
|
||||
if (ChartIdList.hasOwnProperty(node.id) && ChartIdList[node.id] !== node.chartType) {
|
||||
value = [];
|
||||
}
|
||||
if (this.control.look !== node.chartType) {
|
||||
if ((this.control.look === "line") || (node.chartType === "line")) { value = []; }
|
||||
node.chartType = this.control.look;
|
||||
}
|
||||
ChartIdList[node.id] = node.chartType;
|
||||
if (Array.isArray(value)) {
|
||||
if (value.length === 0) { // reset chart
|
||||
converted.update = false;
|
||||
converted.updatedValues = [];
|
||||
return converted;
|
||||
}
|
||||
if (value[0].hasOwnProperty("series") && value[0].hasOwnProperty("data")) {
|
||||
if (!Array.isArray(value[0].series)) { node.error("series not array",msg); return; }
|
||||
if (!Array.isArray(value[0].data)) { node.error("Data not array",msg); return; }
|
||||
var flag = true;
|
||||
for (var dd = 0; dd < value[0].data.length; dd++ ) {
|
||||
if (!isNaN(value[0].data[dd][0])) { flag = false; }
|
||||
}
|
||||
if (node.chartType === "line") {
|
||||
if (flag) { delete value[0].labels; }
|
||||
if (config.removeOlderPoints) {
|
||||
for (var dl=0; dl < value[0].data.length; dl++ ) {
|
||||
if (value[0].data[dl].length > config.removeOlderPoints) {
|
||||
value[0].data[dl] = value[0].data[dl].slice(-config.removeOlderPoints);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (node.chartType === "bar" || node.chartType === "horizontalBar") {
|
||||
if (flag) {
|
||||
var tmp = [];
|
||||
for (var d=0; d<value[0].data.length; d++) {
|
||||
tmp.push([value[0].data[d]]);
|
||||
}
|
||||
value[0].data = tmp;
|
||||
var tmp2 = value[0].series;
|
||||
value[0].series = value[0].labels;
|
||||
value[0].labels = tmp2;
|
||||
}
|
||||
}
|
||||
value = [{ key:node.id, values:(value[0] || {series:[], data:[], labels:[]}) }];
|
||||
}
|
||||
else {
|
||||
node.warn("Bad data inject");
|
||||
value = oldValue;
|
||||
}
|
||||
converted.update = false;
|
||||
converted.updatedValues = value;
|
||||
}
|
||||
else {
|
||||
if (value === false) { value = null; } // let false also create gaps in chart
|
||||
if (value !== null) { // let null object through for gaps
|
||||
value = parseFloat(value); // only handle numbers
|
||||
if (isNaN(value)) { return; } // return if not a number
|
||||
}
|
||||
converted.newPoint = true;
|
||||
var label = msg.label || " ";
|
||||
var series = msg.series || msg.topic || "";
|
||||
//if (node.chartType === "bar" || node.chartType === "horizontalBar" || node.chartType === "pie") {
|
||||
if (node.chartType !== "line") {
|
||||
if (!msg.series) {
|
||||
label = msg.topic || msg.label || " ";
|
||||
series = msg.series || "";
|
||||
}
|
||||
}
|
||||
if ((!oldValue) || (oldValue.length === 0)) {
|
||||
oldValue = [{ key:node.id, values:{ series:[], data:[], labels:[] } }];
|
||||
}
|
||||
//if (node.chartType === "line" || node.chartType === "pie" || node.chartType === "bar" || node.chartType === "horizontalBar" || node.chartType === "radar") { // Line, Bar and Radar
|
||||
var refill = false;
|
||||
if (node.chartType === "line") { label = ""; }
|
||||
var s = oldValue[0].values.series.indexOf(series);
|
||||
if (!oldValue[0].values.hasOwnProperty("labels")) { oldValue[0].values.labels = []; }
|
||||
var l = oldValue[0].values.labels.indexOf(label);
|
||||
if (s === -1) {
|
||||
oldValue[0].values.series.push(series);
|
||||
s = oldValue[0].values.series.length - 1;
|
||||
oldValue[0].values.data[s] = [];
|
||||
if (l > 0) { refill = true; }
|
||||
}
|
||||
if (l === -1) {
|
||||
oldValue[0].values.labels.push(label);
|
||||
l = oldValue[0].values.labels.length - 1;
|
||||
if (l > 0) { refill = true; }
|
||||
}
|
||||
if (node.chartType === "line") {
|
||||
var time;
|
||||
if (msg.timestamp !== undefined) { time = new Date(msg.timestamp).getTime(); }
|
||||
else { time = new Date().getTime(); }
|
||||
var limitOffsetSec = parseInt(config.removeOlder) * parseInt(config.removeOlderUnit);
|
||||
var limitTime = time - limitOffsetSec * 1000;
|
||||
if (time < limitTime) { return oldValue; } // ignore if too old for window
|
||||
var point = { "x":time, "y":value };
|
||||
oldValue[0].values.data[s].push(point);
|
||||
converted.newPoint = [{ key:node.id, update:true, values:{ series:series, data:point, labels:label } }];
|
||||
var rc = 0;
|
||||
for (var u = 0; u < oldValue[0].values.data[s].length; u++) {
|
||||
if (oldValue[0].values.data[s][u].x >= limitTime) { break; } // stop as soon as we are in time window.
|
||||
else { rc += 1; }
|
||||
}
|
||||
if (rc > 0) { oldValue[0].values.data[s].splice(0,rc); }
|
||||
if (config.removeOlderPoints) {
|
||||
var rc2 = oldValue[0].values.data[s].length-config.removeOlderPoints;
|
||||
if (rc2 > 0) { oldValue[0].values.data[s].splice(0,rc2); rc = rc2;}
|
||||
}
|
||||
if (rc > 0) { converted.newPoint[0].remove = rc; }
|
||||
var swap; // insert correctly if a timestamp was earlier.
|
||||
for (var t = oldValue[0].values.data[s].length-2; t>=0; t--) {
|
||||
if (oldValue[0].values.data[s][t].x <= time) {
|
||||
break; // stop if we are in the right place
|
||||
}
|
||||
else {
|
||||
swap = oldValue[0].values.data[s][t];
|
||||
oldValue[0].values.data[s][t] = oldValue[0].values.data[s][t+1];
|
||||
oldValue[0].values.data[s][t+1] = swap;
|
||||
}
|
||||
}
|
||||
if (swap) { converted.newPoint = true; } // if inserted then update whole chart
|
||||
|
||||
if (Date.now() > (dnow + 60000)) {
|
||||
dnow = Date.now();
|
||||
for (var x = 0; x < oldValue[0].values.data.length; x++) {
|
||||
for (var y = 0; y < oldValue[0].values.data[x].length; y++) {
|
||||
if (oldValue[0].values.data[x][y].x >= limitTime) {
|
||||
break; // stop as soon as we are in time window.
|
||||
}
|
||||
else {
|
||||
oldValue[0].values.data[x].splice(0,1);
|
||||
converted.newPoint = true;
|
||||
y = y - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
oldValue[0].values.data[s][l] = value;
|
||||
if (refill) {
|
||||
for (var i = 0; i < oldValue[0].values.series.length; i++) {
|
||||
for (var k = 0; k < oldValue[0].values.labels.length; k++) {
|
||||
oldValue[0].values.data[i][k] = oldValue[0].values.data[i][k] || null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
converted.update = true;
|
||||
converted.updatedValues = oldValue;
|
||||
}
|
||||
return converted;
|
||||
}
|
||||
};
|
||||
|
||||
var chgtab = function() {
|
||||
node.receive({payload:"R"});
|
||||
};
|
||||
ui.ev.on('changetab', chgtab);
|
||||
|
||||
var done = ui.add(options);
|
||||
|
||||
var st = setTimeout(function() {
|
||||
node.emit("input",{payload:"start"}); // trigger a redraw at start to flush out old data.
|
||||
}, 100);
|
||||
|
||||
node.on("close", function() {
|
||||
if (st) { clearTimeout(st); }
|
||||
ui.ev.removeListener('changetab', chgtab);
|
||||
done();
|
||||
})
|
||||
}
|
||||
RED.nodes.registerType("ui_chart", ChartNode);
|
||||
};
|
||||
163
node_modules/node-red-dashboard/nodes/ui_colour_picker.html
generated
vendored
Normal file
@@ -0,0 +1,163 @@
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('ui_colour_picker',{
|
||||
category: RED._("node-red-dashboard/ui_base:ui_base.label.category"),
|
||||
color: 'rgb(176, 223, 227)',
|
||||
defaults: {
|
||||
name: {value: ''},
|
||||
label: {value: ''},
|
||||
group: {type: 'ui_group', required: true},
|
||||
format: {value: 'hex'},
|
||||
outformat: {value: 'string'},
|
||||
showSwatch: {value: true},
|
||||
showPicker: {value: false},
|
||||
showValue: {value: false},
|
||||
showHue: {value: false},
|
||||
showAlpha: {value: false},
|
||||
showLightness: {value: true},
|
||||
square: {value: "false"},
|
||||
dynOutput: {value: "false"},
|
||||
order: {value: 0},
|
||||
width: {value: 0, validate: function(v) {
|
||||
var width = v||0;
|
||||
var currentGroup = $('#node-input-group').val()||this.group;
|
||||
var groupNode = RED.nodes.node(currentGroup);
|
||||
var valid = !groupNode || +width <= +groupNode.width;
|
||||
$("#node-input-size").toggleClass("input-error",!valid);
|
||||
return valid;
|
||||
}
|
||||
},
|
||||
height: {value: 0},
|
||||
passthru: {value: true},
|
||||
topic: {value: 'topic', validate: (RED.validators.hasOwnProperty('typedInput')?RED.validators.typedInput('topicType'):function(v) { return true})},
|
||||
topicType: {value: 'msg'},
|
||||
className: {value: ''}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:1,
|
||||
outputLabels: function() { return this.format; },
|
||||
icon: "ui_colour_picker.png",
|
||||
paletteLabel: 'colour picker',
|
||||
label: function() { return this.name || (~this.label.indexOf("{{") ? null : this.label) || 'colour picker'; },
|
||||
labelStyle: function() { return this.name?"node_label_italic":""; },
|
||||
oneditprepare: function() {
|
||||
if (this.square === undefined) {
|
||||
this.square = "false";
|
||||
$("#node-input-square").val("false");
|
||||
}
|
||||
$("#node-input-square").on("change", function() {
|
||||
if ($("#node-input-square").val() === "false") {
|
||||
$("#node-input-showLightness").prop('checked', true);
|
||||
$("#node-input-showHue").prop('checked', false);
|
||||
}
|
||||
else {
|
||||
$("#node-input-showLightness").prop('checked', false);
|
||||
$("#node-input-showHue").prop('checked', true);
|
||||
}
|
||||
});
|
||||
$("#node-input-size").elementSizer({
|
||||
width: "#node-input-width",
|
||||
height: "#node-input-height",
|
||||
group: "#node-input-group"
|
||||
});
|
||||
$("#node-input-format").on("change", function() {
|
||||
if ($(this).val() === "hex") {
|
||||
$("#node-alpha-control").hide();
|
||||
}
|
||||
else {
|
||||
$("#node-alpha-control").show();
|
||||
}
|
||||
});
|
||||
$('#node-input-topic').typedInput({
|
||||
default: 'str',
|
||||
typeField: $("#node-input-topicType"),
|
||||
types: ['str','msg','flow','global']
|
||||
});
|
||||
},
|
||||
oneditsave: function() {
|
||||
if (!$("#node-input-showPicker").is(':checked') && !$("#node-input-showValue").is(':checked')) {
|
||||
$("#node-input-showSwatch").prop('checked', true);
|
||||
this.showSwatch = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-template-name="ui_colour_picker">
|
||||
<div class="form-row">
|
||||
<label for="node-input-group"><i class="fa fa-table"></i> Group</label>
|
||||
<input type="text" id="node-input-group">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label><i class="fa fa-object-group"></i> Size</label>
|
||||
<input type="hidden" id="node-input-width">
|
||||
<input type="hidden" id="node-input-height">
|
||||
<button class="editor-button" id="node-input-size"></button>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-label"><i class="fa fa-i-cursor"></i> Label</label>
|
||||
<input type="text" id="node-input-label">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-format"><i class="fa fa-keyboard-o"></i> Format</label>
|
||||
<select id="node-input-format" style="width:156px;">
|
||||
<option value="hex">hex</option>
|
||||
<option value="hex8">hex8</option>
|
||||
<option value="hsl">hsl</option>
|
||||
<option value="hsv">hsv</option>
|
||||
<option value="rgb">rgb</option>
|
||||
</select>
|
||||
<select id="node-input-square" style="width:130px; margin-left:30px">
|
||||
<option value="false">round</option>
|
||||
<option value="true">square</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label> </label> Show hue slider : <input type="checkbox" id="node-input-showHue" style="display:inline-block; width:auto; vertical-align:baseline;">
|
||||
<br/>
|
||||
<label> </label> Show lightness slider : <input type="checkbox" id="node-input-showLightness" style="display:inline-block; width:auto; vertical-align:baseline;">
|
||||
<br/>
|
||||
<span id="node-alpha-control"><label> </label> Show transparency slider : <input type="checkbox" id="node-input-showAlpha" style="display:inline-block; width:auto; vertical-align:baseline;"></span>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
If width is 4 or greater:<br/>
|
||||
<label> </label>
|
||||
Always show swatch : <input type="checkbox" checked id="node-input-showSwatch" style="display:inline-block; width:auto; vertical-align:top;">
|
||||
<br/>
|
||||
<label> </label>
|
||||
Always show picker : <input type="checkbox" checked id="node-input-showPicker" style="display:inline-block; width:auto; vertical-align:top;">
|
||||
<br/>
|
||||
<label> </label>
|
||||
Always show value field : <input type="checkbox" checked id="node-input-showValue" style="display:inline-block; width:auto; vertical-align:top;">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label style="width:auto" for="node-input-passthru"><i class="fa fa-arrow-right"></i> If <code>msg</code> arrives on input, pass through to output: </label>
|
||||
<input type="checkbox" checked id="node-input-passthru" style="display:inline-block; width:auto; vertical-align:top;">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-dynOutput"><i class="fa fa-envelope-o"></i> Send</label>
|
||||
<select id="node-input-dynOutput" style="width:60%">
|
||||
<option value="false">one value when released/closed</option>
|
||||
<option value="true">multiple values during editing</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-outformat" style="padding-left: 25px; margin-right: -25px">Payload</label>
|
||||
<select id="node-input-outformat" style="width:60%">
|
||||
<option value="string">current value as a string</option>
|
||||
<option value="object">current value as an object</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-topic" style="padding-left: 25px; margin-right: -25px">Topic</label>
|
||||
<input type="text" id="node-input-topic" placeholder="optional topic">
|
||||
<input type="hidden" id="node-input-topicType">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-className"><i class="fa fa-code"></i> Class</label>
|
||||
<input type="text" id="node-input-className" placeholder="Optional CSS class name(s) for widget"/>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name">
|
||||
</div>
|
||||
</script>
|
||||
67
node_modules/node-red-dashboard/nodes/ui_colour_picker.js
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
module.exports = function(RED) {
|
||||
var ui = require('../ui')(RED);
|
||||
var tc = require('../dist/js/tinycolor-min');
|
||||
|
||||
function ColourPickerNode(config) {
|
||||
RED.nodes.createNode(this, config);
|
||||
this.format = config.format;
|
||||
this.outformat = config.outformat;
|
||||
var node = this;
|
||||
|
||||
var group = RED.nodes.getNode(config.group);
|
||||
if (!group) { return; }
|
||||
var tab = RED.nodes.getNode(group.config.tab);
|
||||
if (!tab) { return; }
|
||||
|
||||
node.on("input", function(msg) {
|
||||
node.topi = msg.topic;
|
||||
});
|
||||
|
||||
var done = ui.add({
|
||||
node: node,
|
||||
tab: tab,
|
||||
group: group,
|
||||
forwardInputMessages: config.passthru,
|
||||
control: {
|
||||
type: 'colour-picker',
|
||||
label: config.label,
|
||||
format: config.format,
|
||||
showPicker: config.showPicker,
|
||||
showSwatch: config.showSwatch,
|
||||
showValue: config.showValue,
|
||||
showHue: config.showHue,
|
||||
showAlpha: config.showAlpha,
|
||||
showLightness: config.showLightness,
|
||||
square: (config.square == 'true') || false,
|
||||
dynOutput: config.dynOutput,
|
||||
allowEmpty: true,
|
||||
order: config.order,
|
||||
value: '',
|
||||
width: config.width || group.config.width || 6,
|
||||
height: config.height || 1,
|
||||
className: config.className || '',
|
||||
},
|
||||
beforeSend: function (msg) {
|
||||
if (node.outformat === 'object') {
|
||||
var pay = tc(msg.payload);
|
||||
if (node.format === 'rgb') { msg.payload = pay.toRgb(); }
|
||||
if (node.format === 'hsl') { msg.payload = pay.toHsl(); }
|
||||
if (node.format === 'hsv') { msg.payload = pay.toHsv(); }
|
||||
}
|
||||
var t = undefined;
|
||||
try {
|
||||
t = RED.util.evaluateNodeProperty(config.topic,config.topicType || "str",node,msg) || node.topi;
|
||||
}
|
||||
catch(e) { }
|
||||
if (t !== undefined) { msg.topic = t; }
|
||||
},
|
||||
convert: function(p,o,m) {
|
||||
if (m.payload === undefined || m.payload === null) { return; }
|
||||
var colour = tc(m.payload);
|
||||
return colour.toString(config.format);
|
||||
}
|
||||
});
|
||||
node.on("close", done);
|
||||
}
|
||||
RED.nodes.registerType("ui_colour_picker", ColourPickerNode);
|
||||
};
|
||||
86
node_modules/node-red-dashboard/nodes/ui_date_picker.html
generated
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('ui_date_picker',{
|
||||
category: RED._("node-red-dashboard/ui_base:ui_base.label.category"),
|
||||
color: 'rgb(176, 223, 227)',
|
||||
defaults: {
|
||||
name: {value: ''},
|
||||
label: {value: 'date'},
|
||||
group: {type: 'ui_group', required: true},
|
||||
order: {value: 0},
|
||||
width: {value: 0, validate: function(v) {
|
||||
var width = v||0;
|
||||
var currentGroup = $('#node-input-group').val()||this.group;
|
||||
var groupNode = RED.nodes.node(currentGroup);
|
||||
var valid = !groupNode || +width <= +groupNode.width;
|
||||
$("#node-input-size").toggleClass("input-error",!valid);
|
||||
return valid;
|
||||
}
|
||||
},
|
||||
height: {value: 0},
|
||||
passthru: {value: true},
|
||||
topic: {value: 'topic', validate: (RED.validators.hasOwnProperty('typedInput')?RED.validators.typedInput('topicType'):function(v) { return true})},
|
||||
topicType: {value: 'msg'},
|
||||
className: {value: ''}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:1,
|
||||
outputLabels: ["epoch mS"],
|
||||
icon: "ui_date_picker.png",
|
||||
paletteLabel: 'date picker',
|
||||
label: function() { return this.name || (~this.label.indexOf("{{") ? null : this.label) || 'date picker'; },
|
||||
labelStyle: function() { return this.name?"node_label_italic":""; },
|
||||
oneditprepare: function() {
|
||||
$("#node-input-size").elementSizer({
|
||||
width: "#node-input-width",
|
||||
height: "#node-input-height",
|
||||
group: "#node-input-group"
|
||||
});
|
||||
$('#node-input-topic').typedInput({
|
||||
default: 'str',
|
||||
typeField: $("#node-input-topicType"),
|
||||
types: ['str','msg','flow','global']
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-template-name="ui_date_picker">
|
||||
<div class="form-row">
|
||||
<label for="node-input-group"><i class="fa fa-table"></i> Group</label>
|
||||
<input type="text" id="node-input-group">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label><i class="fa fa-object-group"></i> Size</label>
|
||||
<input type="hidden" id="node-input-width">
|
||||
<input type="hidden" id="node-input-height">
|
||||
<button class="editor-button" id="node-input-size"></button>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-label"><i class="fa fa-i-cursor"></i> Label</label>
|
||||
<input type="text" id="node-input-label">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label style="width:auto" for="node-input-passthru"><i class="fa fa-arrow-right"></i> If <code>msg</code> arrives on input, pass through to output: </label>
|
||||
<input type="checkbox" checked id="node-input-passthru" style="display:inline-block; width:auto; vertical-align:top;">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label style="width:auto" for="node-input-payload"><i class="fa fa-envelope-o"></i> When changed, send:</label>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label style="padding-left:25px; margin-right:-25px">Payload</label>
|
||||
<label style="width:auto">Current value</label>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-topic" style="padding-left:25px; margin-right:-25px">Topic</label>
|
||||
<input type="text" id="node-input-topic">
|
||||
<input type="hidden" id="node-input-topicType">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-className"><i class="fa fa-code"></i> Class</label>
|
||||
<input type="text" id="node-input-className" placeholder="Optional CSS class name(s) for widget"/>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name">
|
||||
</div>
|
||||
</script>
|
||||
54
node_modules/node-red-dashboard/nodes/ui_date_picker.js
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
module.exports = function(RED) {
|
||||
var ui = require('../ui')(RED);
|
||||
|
||||
function DatePickerNode(config) {
|
||||
RED.nodes.createNode(this, config);
|
||||
var node = this;
|
||||
|
||||
var group = RED.nodes.getNode(config.group);
|
||||
if (!group) { return; }
|
||||
var tab = RED.nodes.getNode(group.config.tab);
|
||||
if (!tab) { return; }
|
||||
|
||||
node.on("input", function(msg) {
|
||||
node.topi = msg.topic;
|
||||
});
|
||||
|
||||
var done = ui.add({
|
||||
node: node,
|
||||
tab: tab,
|
||||
group: group,
|
||||
forwardInputMessages: config.passthru,
|
||||
emitOnlyNewValues: false,
|
||||
control: {
|
||||
type: 'date-picker',
|
||||
label: config.label,
|
||||
order: config.order,
|
||||
ddd : new Date().setUTCHours(0,0,0,0),
|
||||
width: config.width || group.config.width || 6,
|
||||
height: config.height || 1,
|
||||
className: config.className || '',
|
||||
},
|
||||
convert: function (p,o,m) {
|
||||
var d = new Date(m.payload);
|
||||
this.control.ddd = d;
|
||||
return m.payload;
|
||||
},
|
||||
beforeEmit: function (msg, value) {
|
||||
if (value === undefined) { return; }
|
||||
value = new Date(value);
|
||||
return { msg:msg, value:value };
|
||||
},
|
||||
convertBack: function (value) {
|
||||
var d = new Date(value).valueOf();
|
||||
return d;
|
||||
},
|
||||
beforeSend: function (msg) {
|
||||
var t = RED.util.evaluateNodeProperty(config.topic,config.topicType || "str",node,msg) || node.topi;
|
||||
if (t !== undefined) { msg.topic = t; }
|
||||
}
|
||||
});
|
||||
node.on("close", done);
|
||||
}
|
||||
RED.nodes.registerType("ui_date_picker", DatePickerNode);
|
||||
};
|
||||
179
node_modules/node-red-dashboard/nodes/ui_dropdown.html
generated
vendored
Normal file
@@ -0,0 +1,179 @@
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('ui_dropdown',{
|
||||
category: RED._("node-red-dashboard/ui_base:ui_base.label.category"),
|
||||
color: 'rgb(176, 223, 227)',
|
||||
defaults: {
|
||||
name: {value: ''},
|
||||
label: {value: ''},
|
||||
tooltip: {value: ''},
|
||||
place: {value: 'Select option'},
|
||||
group: {type: 'ui_group', required:true},
|
||||
order: {value: 0},
|
||||
width: {value: 0, validate: function(v) {
|
||||
var width = v||0;
|
||||
var currentGroup = $('#node-input-group').val()||this.group;
|
||||
var groupNode = RED.nodes.node(currentGroup);
|
||||
var valid = !groupNode || +width <= +groupNode.width;
|
||||
$("#node-input-size").toggleClass("input-error",!valid);
|
||||
return valid;
|
||||
}
|
||||
},
|
||||
height: {value: 0},
|
||||
passthru: {value: true},
|
||||
multiple: {value: false},
|
||||
options: {value:[{value: '', label : ''}],
|
||||
validate:function(v) {
|
||||
var unique = new Set(v.map(function(o) {return o.value;}));
|
||||
return v.length == unique.size;
|
||||
}},
|
||||
payload: {value: ''},
|
||||
topic: {value: 'topic', validate: (RED.validators.hasOwnProperty('typedInput')?RED.validators.typedInput('topicType'):function(v) { return true})},
|
||||
topicType: {value: 'msg'},
|
||||
className: {value: ''}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:1,
|
||||
icon: "ui_dropdown.png",
|
||||
paletteLabel: 'dropdown',
|
||||
label: function() { return this.name || (~this.label.indexOf("{{") ? null : this.label) || 'dropdown'; },
|
||||
labelStyle: function() { return this.name?"node_label_italic":""; },
|
||||
oneditprepare: function() {
|
||||
if (this.multiple === undefined) {
|
||||
$("#node-input-multiple").prop('checked', false);;
|
||||
}
|
||||
$("#node-input-size").elementSizer({
|
||||
width: "#node-input-width",
|
||||
height: "#node-input-height",
|
||||
group: "#node-input-group"
|
||||
});
|
||||
var un = new Set(this.options.map(function(o) {return o.value}));
|
||||
if (this.options.length == un.size) { $("#valWarning").hide(); }
|
||||
else { $("#valWarning").show(); }
|
||||
|
||||
function generateOption(i, option) {
|
||||
var container = $('<li/>',{style:"background: var(--red-ui-secondary-background, #fff); margin:0; padding:8px 0px 0px; border-bottom: 1px solid var(--red-ui-form-input-border-color, #ccc);"});
|
||||
var row = $('<div/>').appendTo(container);
|
||||
var row2 = $('<div/>',{style:"padding-top:5px; padding-left:175px;"}).appendTo(container);
|
||||
var row3 = $('<div/>',{style:"padding-top:5px; padding-left:120px;"}).appendTo(container);
|
||||
|
||||
$('<i style="color: var(--red-ui-form-text-color, #eee); cursor:move; margin-left:3px;" class="node-input-option-handle fa fa-bars"></i>').appendTo(row);
|
||||
|
||||
var valueField = $('<input/>',{class:"node-input-option-value",type:"text",style:"margin-left:7px; width:calc(50% - 32px);", placeholder: 'Value',value:option.value}).appendTo(row).typedInput({default:option.type||'str',types:['str','num','bool']});
|
||||
var labelField = $('<input/>',{class:"node-input-option-label",type:"text",style:"margin-left:7px; width:calc(50% - 32px);", placeholder: 'Label', value:option.label}).appendTo(row);
|
||||
|
||||
var finalspan = $('<span/>',{style:"float:right; margin-right:8px;"}).appendTo(row);
|
||||
var deleteButton = $('<a/>',{href:"#",class:"editor-button editor-button-small", style:"margin-top:7px; margin-left:5px;"}).appendTo(finalspan);
|
||||
$('<i/>',{class:"fa fa-remove"}).appendTo(deleteButton);
|
||||
|
||||
deleteButton.click(function() {
|
||||
container.css({"background":"var(--red-ui-secondary-background-inactive, #fee)"});
|
||||
container.fadeOut(300, function() {
|
||||
$(this).remove();
|
||||
});
|
||||
});
|
||||
|
||||
$("#node-input-option-container").append(container);
|
||||
}
|
||||
|
||||
$("#node-input-add-option").click(function() {
|
||||
generateOption($("#node-input-option-container").children().length+1, {});
|
||||
$("#node-input-option-container-div").scrollTop($("#node-input-option-container-div").get(0).scrollHeight);
|
||||
});
|
||||
|
||||
for (var i=0; i<this.options.length; i++) {
|
||||
var option = this.options[i];
|
||||
generateOption(i+1,option);
|
||||
}
|
||||
|
||||
$( "#node-input-option-container" ).sortable({
|
||||
axis: "y",
|
||||
handle:".node-input-option-handle",
|
||||
cursor: "move"
|
||||
});
|
||||
|
||||
$('#node-input-topic').typedInput({
|
||||
default: 'str',
|
||||
typeField: $("#node-input-topicType"),
|
||||
types: ['str','msg','flow','global']
|
||||
});
|
||||
},
|
||||
oneditsave: function() {
|
||||
var options = $("#node-input-option-container").children();
|
||||
var node = this;
|
||||
node.options = [];
|
||||
options.each(function(i) {
|
||||
var option = $(this);
|
||||
var o = {
|
||||
label: option.find(".node-input-option-label").val(),
|
||||
value: option.find(".node-input-option-value").typedInput('value'),
|
||||
type: option.find(".node-input-option-value").typedInput('type')
|
||||
};
|
||||
if (option.find(".node-input-option-value").typedInput('type') === "num") {
|
||||
o.value = Number(o.value);
|
||||
}
|
||||
if (option.find(".node-input-option-value").typedInput('type') === "bool") {
|
||||
o.value = (o.value == "true");
|
||||
}
|
||||
node.options.push(o);
|
||||
});
|
||||
},
|
||||
oneditresize: function() {
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-template-name="ui_dropdown">
|
||||
<div class="form-row">
|
||||
<label for="node-input-group"><i class="fa fa-table"></i> Group</label>
|
||||
<input type="text" id="node-input-group">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label><i class="fa fa-object-group"></i> Size</label>
|
||||
<input type="hidden" id="node-input-width">
|
||||
<input type="hidden" id="node-input-height">
|
||||
<button class="editor-button" id="node-input-size"></button>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-label"><i class="fa fa-tag"></i> Label</label>
|
||||
<input type="text" id="node-input-label" placeholder="optional label">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-tooltip"><i class="fa fa-info-circle"></i> Tooltip</label>
|
||||
<input type="text" id="node-input-tooltip" placeholder="optional tooltip">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-place"><i class="fa fa-tag"></i> Placeholder</label>
|
||||
<input type="text" id="node-input-place" placeholder="optional placeholder">
|
||||
</div>
|
||||
<div class="form-row node-input-option-container-row" style="margin-bottom: 0px;width: 100%">
|
||||
<label for="node-input-width" style="vertical-align:top"><i class="fa fa-list-alt"></i> Options</label>
|
||||
<div id="node-input-option-container-div" style="box-sizing:border-box; border-radius:5px; height:257px; padding:5px; border:1px solid var(--red-ui-form-input-border-color, #ccc); overflow-y:scroll; display:inline-block; width:calc(70% + 15px);">
|
||||
<span id="valWarning" style="color: var(--red-ui-text-color-error, #910000)"><b>All Values must be unique.</b></span>
|
||||
<ol id="node-input-option-container" style="list-style-type:none; margin:0;"></ol>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<a href="#" class="editor-button editor-button-small" id="node-input-add-option" style="margin-top:4px; margin-left:103px;"><i class="fa fa-plus"></i> <span>option</span></a>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label style="width:auto" for="node-input-multiple"><i class="fa fa-th-list"></i> Allow multiple selections from list: </label>
|
||||
<input type="checkbox" checked id="node-input-multiple" style="display:inline-block; width:auto; vertical-align:top;">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label style="width:auto" for="node-input-passthru"><i class="fa fa-arrow-right"></i> If <code>msg</code> arrives on input, pass through to output: </label>
|
||||
<input type="checkbox" checked id="node-input-passthru" style="display:inline-block; width:auto; vertical-align:top;">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-topic"><i class="fa fa-tasks"></i> Topic</label>
|
||||
<input type="text" id="node-input-topic" placeholder="optional msg.topic">
|
||||
<input type="hidden" id="node-input-topicType">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-className"><i class="fa fa-code"></i> Class</label>
|
||||
<input type="text" id="node-input-className" placeholder="Optional CSS class name(s) for widget"/>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name">
|
||||
</div>
|
||||
</script>
|
||||
221
node_modules/node-red-dashboard/nodes/ui_dropdown.js
generated
vendored
Normal file
@@ -0,0 +1,221 @@
|
||||
module.exports = function(RED) {
|
||||
var ui = require('../ui')(RED);
|
||||
|
||||
function DropdownNode(config) {
|
||||
RED.nodes.createNode(this, config);
|
||||
this.pt = config.passthru;
|
||||
this.multiple = config.multiple || false;
|
||||
this.state = [" "," "];
|
||||
var node = this;
|
||||
node.status({});
|
||||
|
||||
var group = RED.nodes.getNode(config.group);
|
||||
if (!group) { return; }
|
||||
var tab = RED.nodes.getNode(group.config.tab);
|
||||
if (!tab) { return; }
|
||||
|
||||
var control = {
|
||||
type: 'dropdown',
|
||||
multiple: config.multiple,
|
||||
label: config.label,
|
||||
tooltip: config.tooltip,
|
||||
place: config.place,
|
||||
order: config.order,
|
||||
value: config.payload || node.id,
|
||||
width: config.width || group.config.width || 6,
|
||||
height: config.height || 1,
|
||||
className: config.className || '',
|
||||
};
|
||||
|
||||
for (var o=0; o<config.options.length; o++) {
|
||||
config.options[o].label = config.options[o].label || config.options[o].value;
|
||||
}
|
||||
control.options = config.options;
|
||||
|
||||
var emitOptions = { value:undefined };
|
||||
|
||||
node.on("input", function(msg) {
|
||||
node.topi = msg.topic;
|
||||
});
|
||||
|
||||
var done = ui.add({
|
||||
node: node,
|
||||
tab: tab,
|
||||
group: group,
|
||||
forwardInputMessages: config.passthru,
|
||||
control: control,
|
||||
|
||||
convert: function (payload, oldValue, msg) {
|
||||
// convert msg
|
||||
// as of now, only allow a full replacement of options
|
||||
// beforeEmit is only called when a node linked to us sends a msg
|
||||
// we are expecting to receive an "update options" msg
|
||||
// which we expect to be an array of new options
|
||||
|
||||
// for convenience, we pass an indication to the node connected to this dropdown
|
||||
// that this is an "update options" message coming from the input sender
|
||||
// 'beforeEmit' is called before 'beforeSend', so we may pass in that info
|
||||
// otherwise that convenience info would not be sent (would not cause any problems)...
|
||||
|
||||
emitOptions = {isOptionsValid:false, value:undefined, newOptions:undefined};
|
||||
do {
|
||||
if (!msg.options) { break; }
|
||||
if (typeof msg.options === "string" ) { msg.options = [ msg.options ]; }
|
||||
if (!Array.isArray(msg.options)) { break; }
|
||||
emitOptions.newOptions = [];
|
||||
if (msg.options.length === 0) {
|
||||
emitOptions.isOptionsValid = true;
|
||||
break;
|
||||
}
|
||||
// could check whether or not all members have same type
|
||||
for (var i = 0; i < msg.options.length; i++) {
|
||||
var opt = msg.options[i];
|
||||
if (opt === undefined || opt === null) { continue; }
|
||||
switch (typeof opt) {
|
||||
case 'number': {
|
||||
opt = "" + opt;
|
||||
emitOptions.newOptions.push({label:opt, value:opt, type:"number"});
|
||||
break;
|
||||
}
|
||||
case 'string': {
|
||||
emitOptions.newOptions.push({label:opt, value:opt, type:"string"});
|
||||
break;
|
||||
}
|
||||
case 'object': {
|
||||
// assuming object of {label:value}
|
||||
for (var m in opt) {
|
||||
if (opt.hasOwnProperty(m)) {
|
||||
emitOptions.newOptions.push({label:m, value:opt[m], type:typeof(opt[m])});
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// do nothing, just continue with next option
|
||||
}
|
||||
}
|
||||
// send null object on change of menu list
|
||||
if (emitOptions.newOptions.length > 0) { emitOptions.value = null; }
|
||||
// or send the preselected value
|
||||
if (msg.payload) { emitOptions.value = msg.payload; }
|
||||
emitOptions.isOptionsValid = true;
|
||||
} while (false);
|
||||
// finally adjust msg to reflect the input
|
||||
msg._dontSend = true;
|
||||
if (emitOptions.isOptionsValid) {
|
||||
control.options = emitOptions.newOptions;
|
||||
control.value = emitOptions.value;
|
||||
}
|
||||
else {
|
||||
if (msg.options) {
|
||||
node.error("ERR: Invalid Options", msg);
|
||||
}
|
||||
}
|
||||
if (msg.hasOwnProperty("resetSearch") && msg.resetSearch) {
|
||||
emitOptions.resetSearch = true;
|
||||
}
|
||||
if (msg.hasOwnProperty("payload")) {
|
||||
if (node.multiple) {
|
||||
if (typeof msg.payload === "string") {
|
||||
msg.payload = msg.payload.split(',');
|
||||
}
|
||||
}
|
||||
emitOptions.value = msg.payload;
|
||||
control.value = emitOptions.value;
|
||||
delete msg._dontSend;
|
||||
return emitOptions;
|
||||
}
|
||||
// we do not overide payload here due to 'opt.emitOnlyNewValues' in ui.js
|
||||
// when undefined is returned, msg will not be forwarded
|
||||
return emitOptions.isOptionsValid ? emitOptions : undefined; // always pass entire object (newValue == oldValue)
|
||||
},
|
||||
|
||||
beforeEmit: function (msg, newValue) {
|
||||
if (msg.socketid) { emitOptions.socketid = msg.socketid; }
|
||||
return emitOptions;
|
||||
},
|
||||
|
||||
convertBack: function (msg) {
|
||||
var val = node.multiple ? [] : "";
|
||||
var m = RED.util.cloneMessage(msg);
|
||||
var mm = (m.hasOwnProperty("id") && m.hasOwnProperty("value")) ? m.value : m;
|
||||
for (var i=0; i<control.options.length; i++) {
|
||||
if (!node.multiple) {
|
||||
delete m["$$mdSelectId"];
|
||||
if (JSON.stringify(control.options[i].value) == JSON.stringify(mm)) {
|
||||
val = control.options[i].value;
|
||||
if (typeof val === "string" && control.options[i].type.indexOf("str") !== 0) {
|
||||
try { val = JSON.parse(val); }
|
||||
catch(e) {}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (node.multiple && mm !== null) {
|
||||
if (!Array.isArray(mm)) {
|
||||
if (mm.hasOwnProperty("value")) { mm = mm.value; }
|
||||
// if (typeof m === "string") { m = [ m ]; }
|
||||
if (mm == null) { mm = []; }
|
||||
else { mm = [ mm ]; }
|
||||
}
|
||||
mm.map(x => delete x["$$mdSelectId"])
|
||||
for (var j = 0; j < mm.length; j++) {
|
||||
if (JSON.stringify(control.options[i].value) === JSON.stringify(mm[j])) {
|
||||
var v = control.options[i].value;
|
||||
if (typeof v === "string" && control.options[i].type !== "string") {
|
||||
try { v = JSON.parse(v); }
|
||||
catch(e) {}
|
||||
}
|
||||
val.push(v);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return val;
|
||||
},
|
||||
|
||||
beforeSend: function (msg) {
|
||||
if (msg.payload === undefined) { msg.payload = []; }
|
||||
if (msg.payload === "") { msg._dontSend = true; }
|
||||
if (msg._dontSend) {
|
||||
delete msg.options;
|
||||
msg.payload = emitOptions.value;
|
||||
}
|
||||
var t = undefined;
|
||||
try {
|
||||
t = RED.util.evaluateNodeProperty(config.topic,config.topicType || "str",node,msg) || node.topi;
|
||||
}
|
||||
catch(e) { }
|
||||
if (t !== undefined) { msg.topic = t; }
|
||||
if (msg.payload === null || msg._dontSend) { node.status({}); }
|
||||
else {
|
||||
var stat = "";
|
||||
if (Array.isArray(msg.payload)) { stat = msg.payload.length + " items"; }
|
||||
else {
|
||||
if (typeof msg.payload === "object") { stat = JSON.stringify(msg.payload); }
|
||||
else { stat = msg.payload.toString(); }
|
||||
if (stat.length > 32) { stat = stat.substr(0,31)+"..."; }
|
||||
}
|
||||
if (node.pt) {
|
||||
node.status({shape:"dot",fill:"grey",text:stat});
|
||||
}
|
||||
else {
|
||||
node.state[1] = stat;
|
||||
node.status({shape:"dot",fill:"grey",text:node.state[1] + " | " + node.state[1]});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (!node.pt) {
|
||||
node.on("input", function(msg) {
|
||||
node.state[0] = msg.payload;
|
||||
node.status({shape:"dot",fill:"grey",text:node.state[0] + " | " + node.state[1]});
|
||||
});
|
||||
}
|
||||
|
||||
node.on("close", done);
|
||||
}
|
||||
RED.nodes.registerType("ui_dropdown", DropdownNode);
|
||||
};
|
||||
317
node_modules/node-red-dashboard/nodes/ui_form.html
generated
vendored
Normal file
@@ -0,0 +1,317 @@
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('ui_form',{
|
||||
category: RED._("node-red-dashboard/ui_base:ui_base.label.category"),
|
||||
color: 'rgb(176, 223, 227)',
|
||||
defaults: {
|
||||
name: {value: ''},
|
||||
label: {value: ''},
|
||||
group: {type: 'ui_group', required: true},
|
||||
order: {value: 0},
|
||||
width: {value: 0, validate: function(v) {
|
||||
var width = v||0;
|
||||
var currentGroup = $('#node-input-group').val()||this.group;
|
||||
var groupNode = RED.nodes.node(currentGroup);
|
||||
var valid = !groupNode || +width <= +groupNode.width;
|
||||
$("#node-input-size").toggleClass("input-error",!valid);
|
||||
return valid;
|
||||
}
|
||||
},
|
||||
height: {value: 0},
|
||||
options: {value:[{value:'', label :'', type:'', required:true}], validate:function(value) {
|
||||
if (value.length ) {
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
if (!value[i].value) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}, required:true},
|
||||
formValue:{value:{}},
|
||||
payload: {value: ''},
|
||||
submit: {value: "submit"},
|
||||
cancel: {value: "cancel"},
|
||||
topic: {value: 'topic', validate: (RED.validators.hasOwnProperty('typedInput')?RED.validators.typedInput('topicType'):function(v) { return true})},
|
||||
topicType: {value: 'msg'},
|
||||
splitLayout: {value:''},
|
||||
className: {value: ''}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:1,
|
||||
icon: "ui_form.png",
|
||||
paletteLabel: 'form',
|
||||
label: function() { return this.name || this.label || 'form'; },
|
||||
labelStyle: function() { return this.name?"node_label_italic":""; },
|
||||
oneditprepare: function() {
|
||||
if ($("#node-input-submit").val() === null) { $("#node-input-submit").val("submit"); }
|
||||
if ($("#node-input-cancel").val() === null) { $("#node-input-cancel").val("cancel"); }
|
||||
$("#node-input-size").elementSizer({
|
||||
width: "#node-input-width",
|
||||
height: "#node-input-height",
|
||||
group: "#node-input-group"
|
||||
});
|
||||
|
||||
this.resizeRule = function(option,newWidth) {
|
||||
//option.find(".node-input-option-type").width(newWidth);
|
||||
// option.find(".node-input-option-label").width(newWidth);
|
||||
// option.find(".node-input-option-value").width(newWidth);
|
||||
}
|
||||
|
||||
function generateOption(i, option) {
|
||||
var container = $('<li/>',{style:"margin:0; padding:8px 0px 0px; border-bottom:1px solid var(--red-ui-form-input-border-color, #ccc);"});
|
||||
var row = $('<div/>').appendTo(container);
|
||||
var row2 = $('<div/>',{style:"padding-top:5px; padding-left:175px;"}).appendTo(container);
|
||||
var row3 = $('<div/>',{style:"padding-top:5px; padding-left:120px;"}).appendTo(container);
|
||||
|
||||
$('<i style="cursor:move; margin-left:3px;" class="node-input-option-handle fa fa-bars"></i>').appendTo(row);
|
||||
|
||||
var labelField = $('<input/>',{class:"node-input-option-label", type:"text", style:"margin-left:7px; width:20%;", placeholder: RED._("node-red-dashboard/ui_form:ui_form.label.egName"), value:option.label}).appendTo(row);//.typedInput({default:'str',types:['str', 'num']});
|
||||
var valueClass ="node-input-option-value"
|
||||
if (!option.value) { valueClass ="node-input-option-value input-error"; }
|
||||
var valueField = $('<input/>',{class:valueClass, type:"text", style:"margin-left:7px; width:20%;", placeholder: RED._("node-red-dashboard/ui_form:ui_form.label.egName2"), value:option.value}).appendTo(row);//.typedInput({default:'str',types:['str','num','bool']});
|
||||
valueField.keyup(function() {
|
||||
if ($(this).val() && $(this).hasClass('input-error')) {
|
||||
$(this).removeClass('input-error')
|
||||
}
|
||||
else {
|
||||
if (!$(this).val()) {
|
||||
$(this).addClass('input-error')
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
// var typeField = $('<input/>',{class:"node-input-option-type",type:"text",style:"margin-left: 7px; width: 135px;", placeholder: 'Type', value:option.type}).appendTo(row).typedInput({default:'str',types:['str', 'num']});
|
||||
var typeField = $('<select/>',{class:"node-input-option-type",type:"text",style:"margin-left:7px; width:16%"}).appendTo(row);//.typedInput({default:'str',types:['str', 'num']});
|
||||
|
||||
var arr = [
|
||||
{val : "text", text: RED._("node-red-dashboard/ui_form:ui_form.label.text")},
|
||||
{val : "multiline", text: RED._("node-red-dashboard/ui_form:ui_form.label.multiline")},
|
||||
{val : "number", text: RED._("node-red-dashboard/ui_form:ui_form.label.number")},
|
||||
{val : "email", text: RED._("node-red-dashboard/ui_form:ui_form.label.email")},
|
||||
{val : "password", text: RED._("node-red-dashboard/ui_form:ui_form.label.password")},
|
||||
{val : "checkbox", text: RED._("node-red-dashboard/ui_form:ui_form.label.checkbox")},
|
||||
{val : "switch", text: RED._("node-red-dashboard/ui_form:ui_form.label.switch")},
|
||||
{val : "date", text: RED._("node-red-dashboard/ui_form:ui_form.label.date")},
|
||||
{val : "time", text: RED._("node-red-dashboard/ui_form:ui_form.label.time")}
|
||||
];
|
||||
|
||||
//var sel = $('<select>').appendTo('body');
|
||||
$(arr).each(function() {
|
||||
var isSelected= false;
|
||||
if (option.type == this.val) {
|
||||
isSelected = true;
|
||||
}
|
||||
typeField.append($("<option>").attr('value',this.val).text(this.text).prop('selected',isSelected));
|
||||
});
|
||||
|
||||
//var labelForRequried = $('<span/>',{style:"margin: 10px;"}).text('Required').appendTo(row);
|
||||
var requiredContainer= $('<div/>',{style:"display:inline-block; height:34px; width:13%; vertical-align: middle"}).appendTo(row);
|
||||
var requiredInnerContainer= $('<div/>',{style:"left:35%; position:relative; width:30px"}).appendTo(requiredContainer);
|
||||
var reqRow=$("<label />",{class:"switch",style:"top:10px; width:30px;"}).appendTo(requiredInnerContainer);
|
||||
//var required = $('<input/>',{class:"node-input-option-required",style:"margin: 5px;width:19%",type:"checkbox", checked:option.required}).appendTo(row);//labelForRequried);//.typedInput({default:'str',types:['str', 'num']});
|
||||
var required = $('<input/>',{class:"node-input-option-required", type:"checkbox", checked:option.required, style:"vertical-align:top;"}).appendTo(reqRow);//labelForRequried);//.typedInput({default:'str',types:['str', 'num']});
|
||||
var reqDiv=$("<div />",{class:"slider round"}).appendTo(reqRow);
|
||||
var vis = option.rows ? 'visible' : 'hidden';
|
||||
var rowsField = $('<input/>',{class:"node-input-option-rows", type:"number", style:"width:10%;", placeholder:'Rows', value:option.rows }).css('visibility',vis).appendTo(row);
|
||||
|
||||
var finalspan = $('<div/>',{style:"display:inline-block; width:5%;"}).appendTo(row);
|
||||
var deleteButton = $('<a/>',{href:"#",class:"editor-button", style:"font-size:1.3em; left:45%; position:relative;"}).appendTo(finalspan);
|
||||
$('<i/>',{class:"fa fa-trash-o"}).appendTo(deleteButton);
|
||||
|
||||
typeField.change(function(e){
|
||||
if (e.target.value != 'multiline') {
|
||||
rowsField.val(undefined)
|
||||
option.rows = null;
|
||||
rowsField.css('visibility','hidden')
|
||||
} else {
|
||||
rowsField.css('visibility','visible')
|
||||
if (!rowsField[0].value) rowsField[0].value = 3;
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
deleteButton.click(function() {
|
||||
container.find(".node-input-option-value").removeAttr('required')
|
||||
container.css({"background":"var(--red-ui-secondary-background-inactive, #fee)"});
|
||||
container.fadeOut(300, function() {
|
||||
$(this).remove();
|
||||
});
|
||||
});
|
||||
|
||||
$("#node-input-option-container").append(container);
|
||||
}
|
||||
|
||||
$("#node-input-add-option").click(function() {
|
||||
generateOption($("#node-input-option-container").children().length+1, {});
|
||||
$("#node-input-option-container-div").scrollTop($("#node-input-option-container-div").get(0).scrollHeight);
|
||||
});
|
||||
|
||||
for (var i=0; i<this.options.length; i++) {
|
||||
var option = this.options[i];
|
||||
generateOption(i+1,option);
|
||||
}
|
||||
|
||||
$('#node-input-topic').typedInput({
|
||||
default: 'str',
|
||||
typeField: $("#node-input-topicType"),
|
||||
types: ['str','msg','flow','global']
|
||||
});
|
||||
|
||||
$( "#node-input-option-container" ).sortable({
|
||||
axis: "y",
|
||||
handle:".node-input-option-handle",
|
||||
cursor: "move"
|
||||
});
|
||||
},
|
||||
oneditsave: function() {
|
||||
var options = $("#node-input-option-container").children();
|
||||
var node = this;
|
||||
node.options = [];
|
||||
node.formValue = {};
|
||||
options.each(function(i) {
|
||||
var option = $(this);
|
||||
var o = {
|
||||
label: option.find(".node-input-option-label").val(),//typedInput('value'),
|
||||
value: option.find(".node-input-option-value").val(),//typedInput('value'),
|
||||
type: option.find(".node-input-option-type").val(),//typedInput('value')
|
||||
required: option.find(".node-input-option-required").is(':checked'),
|
||||
rows: parseInt(option.find(".node-input-option-rows").val())
|
||||
};
|
||||
// o.value= o.value||o.label||(o.type+"_"+i);
|
||||
node.formValue[o.value]= o.type == "checkbox" || o.type == "switch" ? false : "";
|
||||
node.options.push(o);
|
||||
});
|
||||
},
|
||||
oneditresize: function() {
|
||||
var options = $("#node-input-option-container").children();
|
||||
var newWidth = ($("#node-input-option-container").width() - 175)/2;
|
||||
var node = this;
|
||||
options.each(function(i) {
|
||||
node.resizeRule($(this),newWidth);
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<script type="text/html" data-template-name="ui_form">
|
||||
|
||||
<style>
|
||||
.switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 30px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.switch input {display:none;}
|
||||
|
||||
.slider {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: var(--red-ui-tertiary-border-color, #ccc);
|
||||
-webkit-transition: .4s;
|
||||
transition: .4s;
|
||||
}
|
||||
|
||||
.slider:before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 15px;
|
||||
width: 15px;
|
||||
left: 2px;
|
||||
bottom: 2px;
|
||||
background-color: var(--red-ui-secondary-background, white);
|
||||
-webkit-transition: .4s;
|
||||
transition: .4s;
|
||||
}
|
||||
|
||||
input:checked + .slider {
|
||||
background-color: #910000;
|
||||
}
|
||||
|
||||
input:focus + .slider {
|
||||
box-shadow: 0 0 1px #2196F3;
|
||||
}
|
||||
|
||||
input:checked + .slider:before {
|
||||
-webkit-transform: translateX(11px);
|
||||
-ms-transform: translateX(11px);
|
||||
transform: translateX(11px);
|
||||
}
|
||||
|
||||
/* Rounded sliders */
|
||||
.slider.round {
|
||||
border-radius: 34px;
|
||||
}
|
||||
|
||||
.slider.round:before {
|
||||
border-radius: 50%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="form-row">
|
||||
<label for="node-input-group"><i class="fa fa-table"></i> <span data-i18n="ui_form.label.group"></label>
|
||||
<input type="text" id="node-input-group">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label><i class="fa fa-object-group"></i> <span data-i18n="ui_form.label.size"></label>
|
||||
<input type="hidden" id="node-input-width">
|
||||
<input type="hidden" id="node-input-height">
|
||||
<button class="editor-button" id="node-input-size"></button>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-label"><i class="fa fa-tag"></i> <span data-i18n="ui_form.label.label"></label>
|
||||
<input type="text" id="node-input-label" data-i18n="[placeholder]ui_form.label.optionalLabel">
|
||||
</div>
|
||||
<div class="form-row node-input-option-container-row" style="margin-bottom:0px; width:100%; min-width:520px">
|
||||
<label style="vertical-align:top;"><i class="fa fa-list-alt"></i> <span data-i18n="ui_form.label.formElements"></label>
|
||||
<div style="display:inline-block; width:78%; border:1px solid var(--red-ui-form-input-border-color, #ccc); border-radius:5px; box-sizing:border-box;">
|
||||
<div class="red-ui-tray-header" style="width:100%; display: inline-block; padding-top:10px; padding-bottom:10px; border-top:0px solid; border-radius:5px 5px 0 0; border-bottom:1px solid var(--red-ui-form-input-border-color, #ccc);">
|
||||
<div style="width:94%; display:inline-block; margin-left:27px">
|
||||
<div style="width:20%; text-align:center; float:left;" data-i18n="ui_form.label.label"></span></div>
|
||||
<div style="width:20%; text-align:center; float:left; margin-left:9px" data-i18n="node-red:common.label.name"></div>
|
||||
<div style="margin-left:7px; width:16%; text-align:center; float:left; margin-left:9px" data-i18n="ui_form.label.type"></div>
|
||||
<div style="width:16%; text-align:center; float:left;" data-i18n="ui_form.label.required"></div>
|
||||
<div style="width:10%; text-align:center; float:left;" data-i18n="ui_form.label.rows"></div>
|
||||
<div style="width:12%; text-align:center; float:left;" data-i18n="ui_form.label.remove"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="node-input-option-container-div" style=" height: 257px; padding: 5px; overflow-y:scroll;">
|
||||
<ol id="node-input-option-container" style=" list-style-type:none; margin: 0;"></ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<a href="#" class="editor-button editor-button-small" id="node-input-add-option" style="margin-top: 4px; margin-left: 103px;"><i class="fa fa-plus"></i> <span data-i18n="ui_form.label.element"></span></a>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-submit"><i class="fa fa-square"></i> <span data-i18n="ui_form.label.buttons"></label>
|
||||
<i class="fa fa-thumbs-o-up"></i> <input type="text" id="node-input-submit" data-i18n="[placeholder]ui_form.label.submitButtonText" style="width:35%;">
|
||||
<span style="margin-left:16px"><i class="fa fa-thumbs-o-down"></i></span>
|
||||
<input type="text" id="node-input-cancel" data-i18n="[placeholder]ui_form.label.cancelButtonText" style="width:35%;">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-splitLayout"></label>
|
||||
<input type="checkbox" id="node-input-splitLayout" style="display:inline-block; width:auto; vertical-align:top;">
|
||||
<span data-i18n="ui_form.label.splitLayout">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-topic"><i class="fa fa-tasks"></i> <span data-i18n="ui_form.label.topic"></label>
|
||||
<input type="text" id="node-input-topic" data-i18n="[placeholder]ui_form.label.optionalMsgTopic">
|
||||
<input type="hidden" id="node-input-topicType">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-className"><i class="fa fa-code"></i> <span data-i18n="ui_form.label.className"></label>
|
||||
<input type="text" id="node-input-className" data-i18n="[placeholder]ui_form.label.classNamePlaceholder"/>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></label>
|
||||
<input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name">
|
||||
</div>
|
||||
</script>
|
||||
50
node_modules/node-red-dashboard/nodes/ui_form.js
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
module.exports = function(RED) {
|
||||
var ui = require('../ui')(RED);
|
||||
|
||||
function FormNode(config) {
|
||||
RED.nodes.createNode(this, config);
|
||||
var node = this;
|
||||
var group = RED.nodes.getNode(config.group);
|
||||
if (!group) { return; }
|
||||
var tab = RED.nodes.getNode(group.config.tab);
|
||||
if (!tab) { return; }
|
||||
|
||||
node.on("input", function(msg) {
|
||||
node.topi = msg.topic;
|
||||
});
|
||||
|
||||
var done = ui.add({
|
||||
node: node,
|
||||
tab: tab,
|
||||
group: group,
|
||||
forwardInputMessages: false,
|
||||
storeFrontEndInputAsState: false,
|
||||
control: {
|
||||
type: 'form',
|
||||
label: config.label,
|
||||
order: config.order,
|
||||
value: config.payload || node.id,
|
||||
width: config.width || group.config.width || 6,
|
||||
height: config.height || config.splitLayout == true ? Math.ceil(config.options.length/2) : config.options.length,
|
||||
options: config.options,
|
||||
formValue: config.formValue,
|
||||
submit: config.submit,
|
||||
cancel: config.cancel,
|
||||
splitLayout: config.splitLayout || false,
|
||||
sy: ui.getSizes().sy,
|
||||
cy: ui.getSizes().cy,
|
||||
className: config.className || '',
|
||||
},
|
||||
beforeSend: function (msg) {
|
||||
var t = undefined;
|
||||
try {
|
||||
t = RED.util.evaluateNodeProperty(config.topic,config.topicType || "str",node,msg) || node.topi;
|
||||
}
|
||||
catch(e) { }
|
||||
if (t !== undefined) { msg.topic = t; }
|
||||
}
|
||||
});
|
||||
node.on("close", done);
|
||||
}
|
||||
RED.nodes.registerType("ui_form", FormNode);
|
||||
};
|
||||
176
node_modules/node-red-dashboard/nodes/ui_gauge.html
generated
vendored
Normal file
@@ -0,0 +1,176 @@
|
||||
<style>
|
||||
input.gauge-color {
|
||||
width: 100px;
|
||||
text-align: center;
|
||||
}
|
||||
input.gauge-color::-webkit-color-swatch {
|
||||
border: none;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('ui_gauge',{
|
||||
category: RED._("node-red-dashboard/ui_base:ui_base.label.category"),
|
||||
color: 'rgb(119, 198, 204)',
|
||||
defaults: {
|
||||
name: {value: ''},
|
||||
group: {type: 'ui_group', required: true},
|
||||
order: {value: 0},
|
||||
width: {value: 0, validate: function(v) {
|
||||
var width = v || 0;
|
||||
var currentGroup = $('#node-input-group').val() || this.group;
|
||||
var groupNode = RED.nodes.node(currentGroup);
|
||||
var valid = !groupNode || +width <= +groupNode.width;
|
||||
$("#node-input-size").toggleClass("input-error",!valid);
|
||||
return valid;
|
||||
}
|
||||
},
|
||||
height: {value: 0},
|
||||
gtype: {value: 'gage'},
|
||||
title: {value: 'gauge'},
|
||||
label: {value: 'units'},
|
||||
format: {value: '{{value}}'},
|
||||
min: {value: 0, required: true, validate: RED.validators.number()},
|
||||
max: {value: 10, required: true, validate: RED.validators.number()},
|
||||
colors: {value: ["#00B500","#E6E600","#CA3838"]},
|
||||
seg1: {value: ""},
|
||||
seg2: {value: ""},
|
||||
diff: {value: false},
|
||||
className: {value: ''}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:0,
|
||||
inputLabels: function() { return this.min+" - "+this.max; },
|
||||
align: "right",
|
||||
icon: "ui_gauge.png",
|
||||
paletteLabel: 'gauge',
|
||||
label: function() { return this.name || (~this.title.indexOf("{{") ? null : this.title) || ((this.gtype === "gage") ? "gauge" : this.gtype) || 'gauge'; },
|
||||
labelStyle: function() { return this.name?"node_label_italic":""; },
|
||||
oneditprepare: function() {
|
||||
var setColour = function(id, value) {
|
||||
$(id).val(value);
|
||||
$(id).css("background-color", value);
|
||||
var rgb = tinycolor(value).toRgb();
|
||||
var level = ((rgb.r*299) + (rgb.g*587) + (rgb.b*114))/1000;
|
||||
var textColor = (level >= 128) ? '#111111' : '#eeeeee';
|
||||
$(id).css("color", textColor);
|
||||
}
|
||||
$(".gauge-color").on("change", function() {
|
||||
setColour("#"+$(this).attr("id"), $(this).val());
|
||||
});
|
||||
|
||||
var defaultColors = ['#00B500', '#E6E600', '#CA3838'];
|
||||
|
||||
if (this.colors) {
|
||||
for (var i=0; i<this.colors.length; i++) {
|
||||
var value = this.colors[i] || defaultColors[i];
|
||||
setColour("#node-input-color"+(i+1), value);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (var j=0; j<defaultColors.length; j++) {
|
||||
setColour("#node-input-color"+(j+1), defaultColors[j]);
|
||||
}
|
||||
}
|
||||
if (this.gtype === undefined) {
|
||||
this.gtype = "gage";
|
||||
$("#node-input-gtype").val("gage");
|
||||
}
|
||||
$("#node-input-size").elementSizer({
|
||||
width: "#node-input-width",
|
||||
height: "#node-input-height",
|
||||
group: "#node-input-group"
|
||||
});
|
||||
$("#node-input-gtype").on("change", function() {
|
||||
if (($(this).val() === "compass") || ($(this).val() === "wave")) {
|
||||
$("#ui-gauge-colours").hide();
|
||||
$("#ui-gauge-segments").hide();
|
||||
}
|
||||
else {
|
||||
$("#ui-gauge-colours").show();
|
||||
$("#ui-gauge-segments").show();
|
||||
}
|
||||
if ($(this).val() === "gage") {
|
||||
$("#ui-gauge-diff").show();
|
||||
}
|
||||
else { $("#ui-gauge-diff").hide(); }
|
||||
});
|
||||
$("#node-input-min").on("change", function() {
|
||||
$("#seg-min").text($(this).val());
|
||||
});
|
||||
$("#node-input-max").on("change", function() {
|
||||
$("#seg-max").text($(this).val());
|
||||
});
|
||||
},
|
||||
oneditsave: function() {
|
||||
this.colors = [$("#node-input-color1").val(),$("#node-input-color2").val(),$("#node-input-color3").val()];
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-template-name="ui_gauge">
|
||||
<div class="form-row">
|
||||
<label for="node-input-group"><i class="fa fa-table"></i> Group</label>
|
||||
<input type="text" id="node-input-group">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label><i class="fa fa-object-group"></i> Size</label>
|
||||
<input type="hidden" id="node-input-width">
|
||||
<input type="hidden" id="node-input-height">
|
||||
<button class="editor-button" id="node-input-size"></button>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-gtype"><i class="fa fa-list"></i> Type</label>
|
||||
<select id="node-input-gtype" style="width:150px">
|
||||
<option value="gage">Gauge</option>
|
||||
<option value="donut">Donut</option>
|
||||
<option value="compass">Compass</option>
|
||||
<option value="wave">Level</option>
|
||||
</select>
|
||||
</div>
|
||||
<div id="ui-gauge-labels">
|
||||
<div class="form-row">
|
||||
<label for="node-input-title"><i class="fa fa-i-cursor"></i> Label</label>
|
||||
<input type="text" id="node-input-title">
|
||||
</div>
|
||||
<div class="form-row" id="ui-gauge-format">
|
||||
<label for="node-input-format"><i class="fa fa-i-cursor"></i> Value format</label>
|
||||
<input type="text" id="node-input-format" placeholder="{{value}}">
|
||||
</div>
|
||||
<div class="form-row" id="ui-gauge-units">
|
||||
<label for="node-input-label"><i class="fa fa-i-cursor"></i> Units</label>
|
||||
<input type="text" id="node-input-label" placeholder="optional sub-label">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-min">Range</label>
|
||||
<span for="node-input-min">min</span>
|
||||
<input type="text" id="node-input-min" style="width:80px">
|
||||
<span for="node-input-max" style="margin-left:20px;">max</span>
|
||||
<input type="text" id="node-input-max" style="width:80px">
|
||||
</div>
|
||||
<div class="form-row" id="ui-gauge-colours">
|
||||
<label for="node-input-color1">Colour gradient</label>
|
||||
<input type="color" id="node-input-color1" class="gauge-color" style="width:100px;"/>
|
||||
<input type="color" id="node-input-color2" class="gauge-color" style="width:100px;"/>
|
||||
<input type="color" id="node-input-color3" class="gauge-color" style="width:100px;"/>
|
||||
</div>
|
||||
<div class="form-row" id="ui-gauge-segments">
|
||||
<label>Sectors</label>
|
||||
<span id="seg-min" style="display:inline-block; width:40px;">0</span>...
|
||||
<input type="text" id="node-input-seg1" style="text-align:center; width:87px;" placeholder="optional"> ...
|
||||
<input type="text" id="node-input-seg2" style="text-align:center; width:87px;" placeholder="optional"> ...
|
||||
<span id="seg-max" style="display:inline-block; width:40px; text-align:right">10</span>
|
||||
</div>
|
||||
<div class="form-row" id="ui-gauge-diff">
|
||||
<label></label> Fill gauge from centre.
|
||||
<input type="checkbox" id="node-input-diff" style="display:inline-block; width:auto; vertical-align:top;">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-className"><i class="fa fa-code"></i> Class</label>
|
||||
<input type="text" id="node-input-className" placeholder="Optional CSS class name(s) for widget"/>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name">
|
||||
</div>
|
||||
</script>
|
||||
90
node_modules/node-red-dashboard/nodes/ui_gauge.js
generated
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
module.exports = function (RED) {
|
||||
var ui = require('../ui')(RED);
|
||||
|
||||
function GaugeNode(config) {
|
||||
RED.nodes.createNode(this, config);
|
||||
this.colors = config.colors || ["#00B500","#E6E600","#CA3838"];
|
||||
var node = this;
|
||||
|
||||
var group = RED.nodes.getNode(config.group);
|
||||
if (!group) { return; }
|
||||
var tab = RED.nodes.getNode(group.config.tab);
|
||||
if (!tab) { return; }
|
||||
|
||||
if (config.width === "0") { delete config.width; }
|
||||
if (config.height === "0") { delete config.height; }
|
||||
if (config.height === "1") { config.hideMinMax = true; }
|
||||
node.autoheight = parseInt(group.config.width*0.5+1.5) || 4;
|
||||
if (config.gtype && config.gtype === "wave") { node.autoheight = parseInt(group.config.width*0.75+0.5); }
|
||||
if (config.gtype && config.gtype === "donut") { node.autoheight = parseInt(group.config.width -1); }
|
||||
if (config.gtype && config.gtype === "compass") { node.autoheight = parseInt(group.config.width -1); }
|
||||
|
||||
var sizes = ui.getSizes();
|
||||
var theme = ui.getTheme();
|
||||
|
||||
if (theme === undefined) {
|
||||
theme = {"group-textColor":{value:"#000"}};
|
||||
theme["widget-textColor"] = {value:"#000"};
|
||||
theme["widget-backgroundColor"] = {value:'#1784be'};
|
||||
}
|
||||
|
||||
var gageoptions = {};
|
||||
gageoptions.lineWidth = {'theme-dark':0.75};
|
||||
gageoptions.pointerOptions = {'theme-dark':{color:'#8e8e93'}, 'theme-custom':theme["group-textColor"].value};
|
||||
gageoptions.backgroundColor = {'theme-dark':'#515151', 'theme-custom':theme["widget-textColor"].value };
|
||||
gageoptions.compassColor = {'theme-dark':theme["widget-backgroundColor"].value, 'theme-light':theme["widget-backgroundColor"].value, 'theme-custom':theme["widget-backgroundColor"].value};
|
||||
gageoptions.valueFontColor = {'theme-dark':'#eee', 'theme-light':'#111', 'theme-custom':theme["widget-textColor"].value};
|
||||
|
||||
var waveoptions = {};
|
||||
waveoptions.circleColor = {'theme-dark':theme["widget-backgroundColor"].value, 'theme-light':theme["widget-backgroundColor"].value, 'theme-custom':theme["widget-backgroundColor"].value};
|
||||
waveoptions.waveColor = {'theme-dark':theme["widget-backgroundColor"].value, 'theme-light':theme["widget-backgroundColor"].value, 'theme-custom':theme["widget-backgroundColor"].value};
|
||||
waveoptions.textColor = {'theme-dark':theme["widget-textColor"].value, 'theme-light':theme["widget-textColor"].value, 'theme-custom':theme["widget-textColor"].value};
|
||||
waveoptions.waveTextColor = {'theme-dark':theme["widget-textColor"].value, 'theme-light':theme["widget-textColor"].value, 'theme-custom':theme["widget-textColor"].value};
|
||||
|
||||
var done = ui.add({
|
||||
node: node,
|
||||
tab: tab,
|
||||
group: group,
|
||||
emitOnlyNewValues: false,
|
||||
control: {
|
||||
type: 'gauge',
|
||||
name: config.name,
|
||||
label: config.title,
|
||||
units: config.label,
|
||||
order: config.order,
|
||||
value: config.min,
|
||||
format: config.format,
|
||||
gtype: config.gtype || 'gage',
|
||||
min: (parseFloat(config.min) < parseFloat(config.max)) ? parseFloat(config.min) : parseFloat(config.max),
|
||||
seg1: (parseFloat(config.seg1) < parseFloat(config.seg2)) ? parseFloat(config.seg1) : parseFloat(config.seg2),
|
||||
seg2: (parseFloat(config.seg1) < parseFloat(config.seg2)) ? parseFloat(config.seg2) : parseFloat(config.seg1),
|
||||
max: (parseFloat(config.min) < parseFloat(config.max)) ? parseFloat(config.max) : parseFloat(config.min),
|
||||
reverse: (parseFloat(config.max) < parseFloat(config.min)) ? true : false,
|
||||
sizes: sizes,
|
||||
hideMinMax: config.hideMinMax,
|
||||
width: config.width || group.config.width || 6,
|
||||
height: config.height || node.autoheight,
|
||||
colors: node.colors,
|
||||
diff: config.diff || false,
|
||||
gageoptions: gageoptions,
|
||||
waveoptions: waveoptions,
|
||||
options: null,
|
||||
className: config.className || '',
|
||||
},
|
||||
convert: function(p,o,m) {
|
||||
var form = config.format.replace(/{{/g,"").replace(/}}/g,"").replace(/\s/g,"") || "_zzz_zzz_zzz_";
|
||||
form = form.split('|')[0];
|
||||
var value = RED.util.getMessageProperty(m,form);
|
||||
if (value !== undefined) {
|
||||
if (!isNaN(parseFloat(value))) { value = parseFloat(value); }
|
||||
return value;
|
||||
}
|
||||
if (!isNaN(parseFloat(p))) { p = parseFloat(p); }
|
||||
return p;
|
||||
//return ui.toFloat.bind(this, config);
|
||||
}
|
||||
});
|
||||
node.on("close", done);
|
||||
}
|
||||
RED.nodes.registerType("ui_gauge", GaugeNode);
|
||||
};
|
||||
87
node_modules/node-red-dashboard/nodes/ui_group.html
generated
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
<script type="text/javascript">
|
||||
// convert to i18 text
|
||||
function c_ui_group(x) {
|
||||
return RED._("node-red-dashboard/ui_group:ui_group."+x);
|
||||
}
|
||||
|
||||
RED.nodes.registerType('ui_group',{
|
||||
category: 'config',
|
||||
defaults: {
|
||||
name: {value: c_ui_group("label.default")},
|
||||
tab: {type:"ui_tab", required: true },
|
||||
order: {value: 0},
|
||||
disp: {value: true},
|
||||
width: {value: 6},
|
||||
collapse: {value: false},
|
||||
disabled: {value: false},
|
||||
hidden: {value: false},
|
||||
className: {value: ''},
|
||||
},
|
||||
sort: function(A,B) {
|
||||
if (A.tab !== B.tab) {
|
||||
var tabA = RED.nodes.node(A.tab);
|
||||
var tabB = RED.nodes.node(B.tab);
|
||||
if (!tabA && tabB) {
|
||||
return -1;
|
||||
}
|
||||
else if (tabA && !tabB) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return tabA.order - tabB.order;
|
||||
}
|
||||
}
|
||||
return A.order - B.order;
|
||||
},
|
||||
paletteLabel: 'dashboard group',
|
||||
label: function() {
|
||||
var tabNode = RED.nodes.node(this.tab);
|
||||
if (tabNode) {
|
||||
return "["+(tabNode.name||c_ui_group("label.tab"))+"] " + (this.name || c_ui_group("label.group"));
|
||||
}
|
||||
return "["+c_ui_group("label.unassigned")+"] " + (this.name || c_ui_group("label.group"));
|
||||
},
|
||||
labelStyle: function() { return this.name?"node_label_italic":""; },
|
||||
oneditprepare: function() {
|
||||
$("#node-input-size").elementSizer({
|
||||
width: "#node-config-input-width",
|
||||
auto: false
|
||||
});
|
||||
$("#node-config-input-disp").on("change", function() {
|
||||
if ($("#node-config-input-disp").is(":checked")) {
|
||||
$("#group-collapse-flag").show();
|
||||
}
|
||||
else {
|
||||
$("#group-collapse-flag").hide();
|
||||
$("#node-config-input-collapse").prop("checked",false);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-template-name="ui_group">
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-name"><i class="fa fa-tag"></i> <span data-i18n="ui_group.label.name"></span></label>
|
||||
<input type="text" id="node-config-input-name">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-tab"><i class="fa fa-table"></i> <span data-i18n="ui_group.label.tab"></span></label>
|
||||
<input type="text" id="node-config-input-tab">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-className"><i class="fa fa-code"></i> <span data-i18n="ui_group.label.className"></label>
|
||||
<input type="text" id="node-config-input-className" data-i18n="[placeholder]ui_group.label.classNamePlaceholder"/>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-width"><i class="fa fa-arrows-h"></i> <span data-i18n="ui_group.label.width"></span></label>
|
||||
<input type="hidden" id="node-config-input-width">
|
||||
<button class="editor-button" id="node-input-size"></button>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<input style="margin:8px 0 10px 102px; width:20px;" type="checkbox" checked id="node-config-input-disp"> <label style="width:auto" for="node-config-input-disp"><span data-i18n="ui_group.display-name"></span></label>
|
||||
</div>
|
||||
<div class="form-row" id="group-collapse-flag">
|
||||
<input style="margin:8px 0 10px 102px; width:20px;" type="checkbox" id="node-config-input-collapse"> <label style="width:auto" for="node-config-input-collapse"><span data-i18n="ui_group.collapse-name"></span></label>
|
||||
</div>
|
||||
</script>
|
||||
20
node_modules/node-red-dashboard/nodes/ui_group.js
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
module.exports = function(RED) {
|
||||
|
||||
function GroupNode(config) {
|
||||
RED.nodes.createNode(this, config);
|
||||
this.config = {
|
||||
name: config.name,
|
||||
disp: config.disp,
|
||||
width: config.width,
|
||||
order: config.order,
|
||||
tab: config.tab,
|
||||
collapse: config.collapse || false,
|
||||
className: config.className || ''
|
||||
};
|
||||
if (!this.config.hasOwnProperty("disp")) { this.config.disp = true; }
|
||||
if (this.config.disp !== false) { this.config.disp = true; }
|
||||
if (!this.config.hasOwnProperty("collapse")) { this.config.collapse = false; }
|
||||
}
|
||||
|
||||
RED.nodes.registerType("ui_group", GroupNode);
|
||||
};
|
||||
65
node_modules/node-red-dashboard/nodes/ui_link.html
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('ui_link',{
|
||||
category: 'config',
|
||||
color: 'rgb( 63, 173, 181)',
|
||||
defaults: {
|
||||
name: {value: 'Google'},
|
||||
link: {value: 'https://www.google.com'},
|
||||
icon: {value: 'open_in_browser'},
|
||||
target: {value: 'newtab', validate :function() { return true; }},
|
||||
order: {value: 0},
|
||||
className: {value: ''}
|
||||
},
|
||||
inputs:0,
|
||||
outputs:0,
|
||||
hasUsers: false,
|
||||
align: "right",
|
||||
icon: "ui_link.png",
|
||||
paletteLabel: 'link',
|
||||
label: function() { return this.name || 'link'; },
|
||||
labelStyle: function() { return this.name?"node_label_italic":""; },
|
||||
oneditprepare: function() {
|
||||
document.getElementById('node-config-input-target-opentab').checked = (this.target === 'newtab');
|
||||
document.getElementById('node-config-input-target-openiframe').checked = (this.target === 'iframe');
|
||||
document.getElementById('node-config-input-target-openthis').checked = (this.target === 'thistab');
|
||||
},
|
||||
oneditsave : function () {
|
||||
var t = 'iframe';
|
||||
if (document.getElementById('node-config-input-target-opentab').checked) { t = 'newtab'; }
|
||||
if (document.getElementById('node-config-input-target-openthis').checked) { t = 'thistab'; }
|
||||
this.target = t;
|
||||
},
|
||||
onadd: function() {
|
||||
//console.log("PING");
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-template-name="ui_link">
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-name"><i class="fa fa-tag"></i> <span data-i18n="ui_link.label.name"></span></label>
|
||||
<input type="text" id="node-config-input-name">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-className"><i class="fa fa-code"></i> <span data-i18n="ui_link.label.className"></label>
|
||||
<input type="text" id="node-input-className" data-i18n="[placeholder]ui_link.label.classNamePlaceholder"/>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-link"><i class="fa fa-link"></i> <span data-i18n="ui_link.label.link"></span></label>
|
||||
<input type="text" id="node-config-input-link">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-icon"><i class="fa fa-image"></i> <span data-i18n="ui_link.label.icon"></span></label>
|
||||
<input type="text" id="node-config-input-icon">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label><i class="fa fa-link"></i> <span data-i18n="ui_link.label.open-in"></span></label>
|
||||
<input type="radio" id="node-config-input-target-opentab" name="open-link-method" style="width:20px; margin-top:0px; margin-bottom:5px" checked>
|
||||
<label for="node-config-input-target-opentab" data-i18n="ui_link.label.new-tab"></label><br/>
|
||||
<input type="radio" id="node-config-input-target-openthis" name="open-link-method" style="width:20px; margin-left:104px; margin-top:0px; margin-bottom:5px">
|
||||
<label for="node-config-input-target-openthis" data-i18n="ui_link.label.this-tab"></label><br/>
|
||||
<input type="radio" id="node-config-input-target-openiframe" name="open-link-method" style="width:20px; margin-left:104px; margin-top:0px; margin-bottom:5px">
|
||||
<label for="node-config-input-target-openiframe" data-i18n="ui_link.label.iframe"></label>
|
||||
</div>
|
||||
<div class="form-tips" data-i18n="[html]ui_link.tip"></div>
|
||||
</script>
|
||||
12
node_modules/node-red-dashboard/nodes/ui_link.js
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
module.exports = function(RED) {
|
||||
var ui = require('../ui')(RED);
|
||||
|
||||
function LinkNode(config) {
|
||||
RED.nodes.createNode(this, config);
|
||||
var node = this;
|
||||
var done = ui.addLink(config.name, config.link, config.icon, config.order, config.target, config.className);
|
||||
node.on("close", done);
|
||||
}
|
||||
|
||||
RED.nodes.registerType("ui_link", LinkNode);
|
||||
};
|
||||
113
node_modules/node-red-dashboard/nodes/ui_numeric.html
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('ui_numeric',{
|
||||
category: RED._("node-red-dashboard/ui_base:ui_base.label.category"),
|
||||
color: 'rgb(176, 223, 227)',
|
||||
defaults: {
|
||||
name: {value: ''},
|
||||
label: {value: 'numeric'},
|
||||
tooltip: {value: ''},
|
||||
group: {type: 'ui_group', required: true},
|
||||
order: {value: 0},
|
||||
width: {value: 0, validate: function(v) {
|
||||
var width = v||0;
|
||||
var currentGroup = $('#node-input-group').val()||this.group;
|
||||
var groupNode = RED.nodes.node(currentGroup);
|
||||
var valid = !groupNode || +width <= +groupNode.width;
|
||||
$("#node-input-size").toggleClass("input-error",!valid);
|
||||
return valid;
|
||||
}
|
||||
},
|
||||
height: {value: 0},
|
||||
wrap: {value: false},
|
||||
passthru: {value: true},
|
||||
topic: {value: 'topic', validate: (RED.validators.hasOwnProperty('typedInput')?RED.validators.typedInput('topicType'):function(v) { return true})},
|
||||
topicType: {value: 'msg'},
|
||||
format: {value: '{{value}}'},
|
||||
min: {value: 0, required: true, validate: RED.validators.number()},
|
||||
max: {value: 10, required: true, validate: RED.validators.number()},
|
||||
step: {value: 1},
|
||||
className: {value: ''}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:1,
|
||||
outputLabels: function() { return this.min+" - "+this.max; },
|
||||
icon: "ui_numeric.png",
|
||||
paletteLabel: 'numeric',
|
||||
label: function() { return this.name || (~this.label.indexOf("{{") ? null : this.label) || 'numeric'; },
|
||||
labelStyle: function() { return this.name?"node_label_italic":""; },
|
||||
oneditprepare: function() {
|
||||
$("#node-input-size").elementSizer({
|
||||
width: "#node-input-width",
|
||||
height: "#node-input-height",
|
||||
group: "#node-input-group"
|
||||
});
|
||||
$('#node-input-topic').typedInput({
|
||||
default: 'str',
|
||||
typeField: $("#node-input-topicType"),
|
||||
types: ['str','msg','flow','global']
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-template-name="ui_numeric">
|
||||
<div class="form-row">
|
||||
<label for="node-input-group"><i class="fa fa-table"></i> Group</label>
|
||||
<input type="text" id="node-input-group">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label><i class="fa fa-object-group"></i> Size</label>
|
||||
<input type="hidden" id="node-input-width">
|
||||
<input type="hidden" id="node-input-height">
|
||||
<button class="editor-button" id="node-input-size"></button>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-label"><i class="fa fa-i-cursor"></i> Label</label>
|
||||
<input type="text" id="node-input-label">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-tooltip"><i class="fa fa-info-circle"></i> Tooltip</label>
|
||||
<input type="text" id="node-input-tooltip" placeholder="optional tooltip">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-format"><i class="fa fa-i-cursor"></i> Value Format</label>
|
||||
<input type="text" id="node-input-format" placeholder="{{value}}">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-min"><i class="fa fa-arrows-h"></i> Range</label>
|
||||
<span for="node-input-min">min</span>
|
||||
<input type="text" id="node-input-min" style="width:60px">
|
||||
<span for="not-input-max" style="margin-left:22px;">max</span>
|
||||
<input type="text" id="node-input-max" style="width:60px">
|
||||
<span for="not-input-step" style="margin-left:22px;">step</span>
|
||||
<input type="text" id="node-input-step" style="width:60px">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label style="width:auto" for="node-input-wrap"><i class="fa fa-refresh"></i> Wrap value from max to min and min to max.</label>
|
||||
<input type="checkbox" id="node-input-wrap" style="display:inline-block; width:auto; vertical-align:top;">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label style="width:auto" for="node-input-passthru"><i class="fa fa-arrow-right"></i> If <code>msg</code> arrives on input, pass through to output: </label>
|
||||
<input type="checkbox" checked id="node-input-passthru" style="display:inline-block; width:auto; vertical-align:top;">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label style="width:auto" for="node-input-payload"><i class="fa fa-envelope-o"></i> When changed, send:</label>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label style="padding-left:25px; margin-right:-25px">Payload</label>
|
||||
<label style="width:auto">Current value</label>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-topic" style="padding-left:25px; margin-right:-25px">Topic</label>
|
||||
<input type="text" id="node-input-topic">
|
||||
<input type="hidden" id="node-input-topicType">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-className"><i class="fa fa-code"></i> Class</label>
|
||||
<input type="text" id="node-input-className" placeholder="Optional CSS class name(s) for widget"/>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name">
|
||||
</div>
|
||||
</script>
|
||||
70
node_modules/node-red-dashboard/nodes/ui_numeric.js
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
module.exports = function(RED) {
|
||||
var ui = require('../ui')(RED);
|
||||
|
||||
function NumericNode(config) {
|
||||
RED.nodes.createNode(this, config);
|
||||
this.pt = config.passthru;
|
||||
this.state = [" "," "];
|
||||
var node = this;
|
||||
node.status({});
|
||||
|
||||
var group = RED.nodes.getNode(config.group);
|
||||
if (!group) { return; }
|
||||
var tab = RED.nodes.getNode(group.config.tab);
|
||||
if (!tab) { return; }
|
||||
|
||||
node.on("input", function(msg) {
|
||||
node.topi = msg.topic;
|
||||
});
|
||||
|
||||
var done = ui.add({
|
||||
node: node,
|
||||
tab: tab,
|
||||
group: group,
|
||||
forwardInputMessages: config.passthru,
|
||||
control: {
|
||||
type: 'numeric',
|
||||
label: config.label,
|
||||
tooltip: config.tooltip,
|
||||
order: config.order,
|
||||
format: config.format,
|
||||
pre: config.format.split('{{')[0] || "",
|
||||
post: config.format.split('}}')[1] || "",
|
||||
value: Number(config.min),
|
||||
min: Number(config.min),
|
||||
max: Number(config.max),
|
||||
step: Number(config.step || 1),
|
||||
wrap: config.wrap || false,
|
||||
width: config.width || group.config.width || 6,
|
||||
height: config.height || 1,
|
||||
ed: (config.format.includes("value") ? false : true),
|
||||
className: config.className || '',
|
||||
},
|
||||
beforeSend: function (msg) {
|
||||
msg.payload = parseFloat(msg.payload);
|
||||
var t = undefined;
|
||||
try {
|
||||
t = RED.util.evaluateNodeProperty(config.topic,config.topicType || "str",node,msg) || node.topi;
|
||||
}
|
||||
catch(e) { }
|
||||
if (t !== undefined) { msg.topic = t; }
|
||||
if (node.pt) {
|
||||
node.status({shape:"dot",fill:"grey",text:msg.payload});
|
||||
}
|
||||
else {
|
||||
node.state[1] = msg.payload;
|
||||
node.status({shape:"dot",fill:"grey",text:node.state[1] + " | " + node.state[1]});
|
||||
}
|
||||
},
|
||||
convert: ui.toFloat.bind(this, config)
|
||||
});
|
||||
if (!node.pt) {
|
||||
node.on("input", function(msg) {
|
||||
node.state[0] = msg.payload;
|
||||
node.status({shape:"dot",fill:"grey",text:node.state[0] + " | " + node.state[1]});
|
||||
});
|
||||
}
|
||||
node.on("close", done);
|
||||
}
|
||||
RED.nodes.registerType("ui_numeric", NumericNode);
|
||||
};
|
||||
112
node_modules/node-red-dashboard/nodes/ui_slider.html
generated
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('ui_slider',{
|
||||
category: RED._("node-red-dashboard/ui_base:ui_base.label.category"),
|
||||
color: 'rgb(176, 223, 227)',
|
||||
defaults: {
|
||||
name: {value: ''},
|
||||
label: {value: 'slider'},
|
||||
tooltip: {value: ''},
|
||||
group: {type: 'ui_group', required: true},
|
||||
order: {value: 0},
|
||||
width: {value: 0, validate: function(v) {
|
||||
var width = v||0;
|
||||
var currentGroup = $('#node-input-group').val()||this.group;
|
||||
var groupNode = RED.nodes.node(currentGroup);
|
||||
var valid = !groupNode || +width <= +groupNode.width;
|
||||
$("#node-input-size").toggleClass("input-error",!valid);
|
||||
return valid;
|
||||
}
|
||||
},
|
||||
height: {value: 0},
|
||||
passthru: {value: true},
|
||||
outs: {value: 'all'},
|
||||
topic: {value: 'topic', validate: (RED.validators.hasOwnProperty('typedInput')?RED.validators.typedInput('topicType'):function(v) { return true})},
|
||||
topicType: {value: 'msg'},
|
||||
min: {value: 0, required:true, validate:RED.validators.number()},
|
||||
max: {value: 10, required:true, validate:RED.validators.number()},
|
||||
step: {value: 1},
|
||||
className: {value: ''}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:1,
|
||||
outputLabels: function() { return this.min+" - "+this.max; },
|
||||
icon: "ui_slider.png",
|
||||
paletteLabel: 'slider',
|
||||
label: function() { return this.name || (~this.label.indexOf("{{") ? null : this.label) || 'slider'; },
|
||||
labelStyle: function() { return this.name?"node_label_italic":""; },
|
||||
oneditprepare: function() {
|
||||
$("#node-input-size").elementSizer({
|
||||
width: "#node-input-width",
|
||||
height: "#node-input-height",
|
||||
group: "#node-input-group"
|
||||
});
|
||||
$('#node-input-topic').typedInput({
|
||||
default: 'str',
|
||||
typeField: $("#node-input-topicType"),
|
||||
types: ['str','msg','flow','global']
|
||||
});
|
||||
if (!$("#node-input-outs").val()) { $("#node-input-outs").val("all") }
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-template-name="ui_slider">
|
||||
<div class="form-row">
|
||||
<label for="node-input-group"><i class="fa fa-table"></i> Group</label>
|
||||
<input type="text" id="node-input-group">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label><i class="fa fa-object-group"></i> Size</label>
|
||||
<input type="hidden" id="node-input-width">
|
||||
<input type="hidden" id="node-input-height">
|
||||
<button class="editor-button" id="node-input-size"></button>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-label"><i class="fa fa-i-cursor"></i> Label</label>
|
||||
<input type="text" id="node-input-label">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-tooltip"><i class="fa fa-info-circle"></i> Tooltip</label>
|
||||
<input type="text" id="node-input-tooltip" placeholder="optional tooltip">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-min"><i class="fa fa-arrows-h"></i> Range</label>
|
||||
<span for="node-input-min">min</span>
|
||||
<input type="text" id="node-input-min" style="width:60px">
|
||||
<span for="not-input-max" style="margin-left:22px;">max</span>
|
||||
<input type="text" id="node-input-max" style="width:60px">
|
||||
<span for="not-input-step" style="margin-left:22px;">step</span>
|
||||
<input type="text" id="node-input-step" style="width:60px">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-outs"><i class="fa fa-sign-out"></i> Output</label>
|
||||
<select id="node-input-outs" style="width:204px">
|
||||
<option value="all">continuously while sliding</option>
|
||||
<option value="end">only on release</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label style="width:auto" for="node-input-passthru"><i class="fa fa-arrow-right"></i> If <code>msg</code> arrives on input, pass through to output: </label>
|
||||
<input type="checkbox" checked id="node-input-passthru" style="display:inline-block; width:auto; vertical-align:top;">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label style="width:auto" for="node-input-payload"><i class="fa fa-envelope-o"></i> When changed, send:</label>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label style="padding-left:25px; margin-right:-25px">Payload</label>
|
||||
<label style="width:auto">Current value</label>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-topic" style="padding-left:25px; margin-right:-25px">Topic</label>
|
||||
<input type="text" id="node-input-topic">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-className"><i class="fa fa-code"></i> Class</label>
|
||||
<input type="text" id="node-input-className" placeholder="Optional CSS class name(s) for widget"/>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name">
|
||||
<input type="hidden" id="node-input-topicType">
|
||||
</div>
|
||||
</script>
|
||||
71
node_modules/node-red-dashboard/nodes/ui_slider.js
generated
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
module.exports = function(RED) {
|
||||
var ui = require('../ui')(RED);
|
||||
|
||||
function SliderNode(config) {
|
||||
RED.nodes.createNode(this, config);
|
||||
this.pt = config.passthru;
|
||||
this.state = [" "," "];
|
||||
var node = this;
|
||||
node.status({});
|
||||
|
||||
var group = RED.nodes.getNode(config.group);
|
||||
if (!group) { return; }
|
||||
var tab = RED.nodes.getNode(group.config.tab);
|
||||
if (!tab) { return; }
|
||||
|
||||
node.on("input", function(msg) {
|
||||
node.topi = msg.topic;
|
||||
});
|
||||
|
||||
var done = ui.add({
|
||||
node: node,
|
||||
tab: tab,
|
||||
group: group,
|
||||
forwardInputMessages: config.passthru,
|
||||
control: {
|
||||
type: 'slider',
|
||||
label: config.label,
|
||||
tooltip: config.tooltip,
|
||||
order: config.order,
|
||||
value: config.min,
|
||||
min: Math.min(config.min, config.max),
|
||||
max: Math.max(config.max, config.min),
|
||||
invert: (parseFloat(config.min) > parseFloat(config.max)) ? true : undefined,
|
||||
step: Math.abs(config.step) || 1,
|
||||
outs: config.outs || "all",
|
||||
width: config.width || group.config.width || 6,
|
||||
height: config.height || 1,
|
||||
className: config.className || '',
|
||||
},
|
||||
beforeSend: function (msg) {
|
||||
var t = undefined;
|
||||
try {
|
||||
t = RED.util.evaluateNodeProperty(config.topic,config.topicType || "str",node,msg) || node.topi;
|
||||
}
|
||||
catch(e) { }
|
||||
if (t !== undefined) { msg.topic = t; }
|
||||
if (node.pt) {
|
||||
node.status({shape:"dot",fill:"grey",text:msg.payload});
|
||||
}
|
||||
else {
|
||||
node.state[1] = msg.payload;
|
||||
node.status({shape:"dot",fill:"grey",text:node.state[1] + " | " + node.state[1]});
|
||||
}
|
||||
},
|
||||
convert: ui.toFloat.bind(this, config)
|
||||
});
|
||||
if (!node.pt) {
|
||||
node.on("input", function(msg) {
|
||||
node.state[0] = msg.payload;
|
||||
node.status({shape:"dot",fill:"grey",text:node.state[0] + " | " + node.state[1]});
|
||||
});
|
||||
}
|
||||
else if (node._wireCount === 0) {
|
||||
node.on("input", function(msg) {
|
||||
node.status({shape:"dot",fill:"grey",text:msg.payload});
|
||||
});
|
||||
}
|
||||
node.on("close", done);
|
||||
}
|
||||
RED.nodes.registerType("ui_slider", SliderNode);
|
||||
};
|
||||
58
node_modules/node-red-dashboard/nodes/ui_spacer.html
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('ui_spacer', {
|
||||
category: 'config',
|
||||
color: '#D4F0F8',
|
||||
defaults: {
|
||||
name: {value: "spacer"},
|
||||
group: {type: 'ui_group', required:true},
|
||||
order: {value: 0},
|
||||
width: {value: 0, validate: function(v) {
|
||||
var width = v||0;
|
||||
var currentGroup = $('#node-input-group').val()||this.group;
|
||||
var groupNode = RED.nodes.node(currentGroup);
|
||||
var valid = !groupNode || +width <= +groupNode.width;
|
||||
$("#node-input-size").toggleClass("input-error",!valid);
|
||||
return valid;
|
||||
}
|
||||
},
|
||||
height: {value: 0},
|
||||
className: {value: ''}
|
||||
},
|
||||
z: RED.workspaces.active(),
|
||||
inputs:0,
|
||||
outputs:0,
|
||||
hasUsers: false,
|
||||
icon: "ui_spacer.png",
|
||||
paletteLabel: 'spacer',
|
||||
label: function() { return this.name + " " + this.width + "x" + this.height; },
|
||||
labelStyle: function() { return this.name?"node_label_italic":""; },
|
||||
oneditprepare: function() {
|
||||
$("#node-input-size").elementSizer({
|
||||
width: "#node-input-width",
|
||||
height: "#node-input-height",
|
||||
group: "#node-input-group"
|
||||
});
|
||||
},
|
||||
oneditsave: function() {
|
||||
this.width = $("#node-input-width").val();
|
||||
this.height = $("#node-input-height").val();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-template-name="ui_spacer">
|
||||
<div class="form-row">
|
||||
<label for="node-input-group"><i class="fa fa-table"></i> Group</label>
|
||||
<input type="text" id="node-input-group">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label><i class="fa fa-object-group"></i> Size</label>
|
||||
<input type="hidden" id="node-input-width">
|
||||
<input type="hidden" id="node-input-height">
|
||||
<button class="editor-button" id="node-input-size"></button>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-className"><i class="fa fa-code"></i> Class</label>
|
||||
<input type="text" id="node-input-className" placeholder="Optional CSS class name(s) for widget"/>
|
||||
</div>
|
||||
</script>
|
||||
28
node_modules/node-red-dashboard/nodes/ui_spacer.js
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
module.exports = function(RED) {
|
||||
var ui = require('../ui')(RED);
|
||||
|
||||
function SpacerNode(config) {
|
||||
RED.nodes.createNode(this, config);
|
||||
var node = this;
|
||||
|
||||
var group = RED.nodes.getNode(config.group);
|
||||
if (!group) { return; }
|
||||
var tab = RED.nodes.getNode(group.config.tab);
|
||||
if (!tab) { return; }
|
||||
|
||||
var done = ui.add({
|
||||
node: node,
|
||||
tab: tab,
|
||||
group: group,
|
||||
control: {
|
||||
type: 'spacer',
|
||||
order: config.order,
|
||||
width: config.width || group.config.width || 6,
|
||||
height: config.height || 1,
|
||||
className: config.className || ''
|
||||
}
|
||||
});
|
||||
node.on("close", done);
|
||||
}
|
||||
RED.nodes.registerType("ui_spacer", SpacerNode);
|
||||
};
|
||||
182
node_modules/node-red-dashboard/nodes/ui_switch.html
generated
vendored
Normal file
@@ -0,0 +1,182 @@
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('ui_switch',{
|
||||
category: RED._("node-red-dashboard/ui_base:ui_base.label.category"),
|
||||
color: 'rgb(176, 223, 227)',
|
||||
defaults: {
|
||||
name: {value: ''},
|
||||
label: {value: 'switch'},
|
||||
tooltip: {value: ''},
|
||||
group: {type: 'ui_group', required: true},
|
||||
order: {value: 0},
|
||||
width: {value: 0, validate: function(v) {
|
||||
var width = v||0;
|
||||
var currentGroup = $('#node-input-group').val()||this.group;
|
||||
var groupNode = RED.nodes.node(currentGroup);
|
||||
var valid = !groupNode || +width <= +groupNode.width;
|
||||
$("#node-input-size").toggleClass("input-error",!valid);
|
||||
return valid;
|
||||
}
|
||||
},
|
||||
height: {value: 0},
|
||||
passthru: {value: true},
|
||||
decouple: {value: "false"},
|
||||
topic: {value: 'topic', validate: (RED.validators.hasOwnProperty('typedInput')?RED.validators.typedInput('topicType'):function(v) { return true})},
|
||||
topicType: {value: 'msg'},
|
||||
style: {value: ''},
|
||||
onvalue: {value: true, required:true, validate: (RED.validators.hasOwnProperty('typedInput')?RED.validators.typedInput('onvalueType'):function(v) { return true})},
|
||||
onvalueType: {value: 'bool'},
|
||||
onicon: {value: '' },
|
||||
oncolor: {value: ''},
|
||||
offvalue: {value: false, required:true, validate: (RED.validators.hasOwnProperty('typedInput')?RED.validators.typedInput('offvalueType'):function(v) { return true})},
|
||||
offvalueType: {value: 'bool'},
|
||||
officon: {value: ''},
|
||||
offcolor: {value: ''},
|
||||
animate: {value: false},
|
||||
className: {value: ''}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:1,
|
||||
icon: "ui_switch.png",
|
||||
paletteLabel: 'switch',
|
||||
label: function() { return this.name || (~this.label.indexOf("{{") ? null : this.label) || 'switch'; },
|
||||
labelStyle: function() { return this.name?"node_label_italic":""; },
|
||||
oneditprepare: function() {
|
||||
$("#node-input-size").elementSizer({
|
||||
width: "#node-input-width",
|
||||
height: "#node-input-height",
|
||||
group: "#node-input-group"
|
||||
});
|
||||
$('#node-input-custom-icons').on("change", function() {
|
||||
if ($('#node-input-custom-icons').val() === "default") {
|
||||
$(".form-row-custom-icons").hide();
|
||||
}
|
||||
else {
|
||||
$(".form-row-custom-icons").show();
|
||||
}
|
||||
});
|
||||
|
||||
if (this.onicon !== "" || this.oncolor !== "" || this.officon !=="" || this.offcolor !== "") {
|
||||
$('#node-input-custom-icons').val('custom');
|
||||
}
|
||||
else {
|
||||
$(".form-row-custom-icons").hide();
|
||||
$('#node-input-custom-icons').change();
|
||||
}
|
||||
|
||||
$('#node-input-onvalue').typedInput({
|
||||
default: 'str',
|
||||
typeField: $("#node-input-onvalueType"),
|
||||
types: ['str','num','bool','json','bin','date','flow','global']
|
||||
});
|
||||
|
||||
$('#node-input-offvalue').typedInput({
|
||||
default: 'str',
|
||||
typeField: $("#node-input-offvalueType"),
|
||||
types: ['str','num','bool','json','bin','date','flow','global']
|
||||
});
|
||||
|
||||
$('#node-input-topic').typedInput({
|
||||
default: 'str',
|
||||
typeField: $("#node-input-topicType"),
|
||||
types: ['str','msg','flow','global']
|
||||
});
|
||||
|
||||
$('#node-input-passthru').on("change", function() {
|
||||
if (this.checked) {
|
||||
$('.form-row-decouple').hide();
|
||||
$('#node-input-decouple').val("false");
|
||||
}
|
||||
else {
|
||||
$('.form-row-decouple').show();
|
||||
}
|
||||
});
|
||||
},
|
||||
oneditsave: function() {
|
||||
if ($('#node-input-custom-icons').val() === 'default') {
|
||||
$('#node-input-onicon').val('');
|
||||
$('#node-input-officon').val('');
|
||||
$('#node-input-oncolor').val('');
|
||||
$('#node-input-offcolor').val('');
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-template-name="ui_switch">
|
||||
<div class="form-row">
|
||||
<label for="node-input-group"><i class="fa fa-table"></i> Group</label>
|
||||
<input type="text" id="node-input-group">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label><i class="fa fa-object-group"></i> Size</label>
|
||||
<input type="hidden" id="node-input-width">
|
||||
<input type="hidden" id="node-input-height">
|
||||
<button class="editor-button" id="node-input-size"></button>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-label"><i class="fa fa-i-cursor"></i> Label</label>
|
||||
<input type="text" id="node-input-label">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-tooltip"><i class="fa fa-info-circle"></i> Tooltip</label>
|
||||
<input type="text" id="node-input-tooltip" placeholder="optional tooltip">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-custom-icons"><i class="fa fa-picture-o"></i> Icon</label>
|
||||
<select id="node-input-custom-icons" style="width:35%">
|
||||
<option value="default">Default</option>
|
||||
<option value="custom">Custom</option>
|
||||
</select>
|
||||
<span style="width:auto; padding-left:20px" class="form-row-custom-icons" for="node-input-animate"> Animate
|
||||
<input type="checkbox" checked id="node-input-animate" style="display:inline-block; width:auto; vertical-align:baseline;"></span>
|
||||
</div>
|
||||
<div class="form-row form-row-custom-icons">
|
||||
<label for="node-input-onicon" style="text-align:right;"><i class="fa fa-toggle-on"></i> On Icon</label>
|
||||
<input type="text" id="node-input-onicon" style="width:120px">
|
||||
<label for="node-input-oncolor" style="width:50px; text-align:right;">Colour</label>
|
||||
<input type="text" id="node-input-oncolor" style="width:120px">
|
||||
</div>
|
||||
<div class="form-row form-row-custom-icons">
|
||||
<label for="node-input-officon" style="text-align:right;"><i class="fa fa-toggle-off"></i> Off Icon</label>
|
||||
<input type="text" id="node-input-officon" style="width:120px">
|
||||
<label for="node-input-offcolor" style="width:50px; text-align:right;">Colour</label>
|
||||
<input type="text" id="node-input-offcolor" style="width:120px">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label style="width:auto" for="node-input-passthru"><i class="fa fa-arrow-right"></i> Pass through <code>msg</code> if payload matches valid state: </label>
|
||||
<input type="checkbox" checked id="node-input-passthru" style="display:inline-block; width:auto; vertical-align:top;">
|
||||
</div>
|
||||
<div class="form-row form-row-decouple">
|
||||
<label for="node-input-decouple"><i class="fa fa-toggle-on"></i> Indicator</label>
|
||||
<select id="node-input-decouple" style="display: inline-block; vertical-align: middle; width:70%;">
|
||||
<option value="false">Switch icon shows state of the output</option>
|
||||
<option value="true">Switch icon shows state of the input</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label style="width:auto" for="node-input-onvalue"><i class="fa fa-envelope-o"></i> When clicked, send:</label>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-onvalue" style="padding-left:25px; margin-right:-25px">On Payload</label>
|
||||
<input type="text" id="node-input-onvalue" style="width:70%">
|
||||
<input type="hidden" id="node-input-onvalueType">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-offvalue" style="padding-left:25px; margin-right:-25px">Off Payload</label>
|
||||
<input type="text" id="node-input-offvalue" style="width:70%">
|
||||
<input type="hidden" id="node-input-offvalueType">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-topic" style="padding-left:25px; margin-right:-25px">Topic</label>
|
||||
<input type="text" id="node-input-topic">
|
||||
<input type="hidden" id="node-input-topicType">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-className"><i class="fa fa-code"></i> Class</label>
|
||||
<input type="text" id="node-input-className" placeholder="Optional CSS class name(s) for widget"/>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name">
|
||||
</div>
|
||||
</script>
|
||||
158
node_modules/node-red-dashboard/nodes/ui_switch.js
generated
vendored
Normal file
@@ -0,0 +1,158 @@
|
||||
module.exports = function(RED) {
|
||||
var ui = require('../ui')(RED);
|
||||
|
||||
function validateSwitchValue(node,property,type,payload) {
|
||||
if (payloadType === 'flow' || payloadType === 'global') {
|
||||
try {
|
||||
var parts = RED.util.normalisePropertyExpression(payload);
|
||||
if (parts.length === '') {
|
||||
throw new Error();
|
||||
}
|
||||
} catch(err) {
|
||||
node.warn("Invalid payload property expression - defaulting to node id")
|
||||
payload = node.id;
|
||||
payloadType = 'str';
|
||||
}
|
||||
}
|
||||
else {
|
||||
payload = payload || node.id;
|
||||
}
|
||||
}
|
||||
function SwitchNode(config) {
|
||||
RED.nodes.createNode(this, config);
|
||||
this.pt = config.passthru;
|
||||
this.state = ["off"," "];
|
||||
this.decouple = (config.decouple === "true") ? false : true;
|
||||
var node = this;
|
||||
node.status({});
|
||||
|
||||
var group = RED.nodes.getNode(config.group);
|
||||
if (!group) { return; }
|
||||
var tab = RED.nodes.getNode(group.config.tab);
|
||||
if (!tab) { return; }
|
||||
|
||||
var parts;
|
||||
var onvalue = config.onvalue;
|
||||
var onvalueType = config.onvalueType;
|
||||
if (onvalueType === 'flow' || onvalueType === 'global') {
|
||||
try {
|
||||
parts = RED.util.normalisePropertyExpression(onvalue);
|
||||
if (parts.length === 0) {
|
||||
throw new Error();
|
||||
}
|
||||
} catch(err) {
|
||||
node.warn("Invalid onvalue property expression - defaulting to true")
|
||||
onvalue = true;
|
||||
onvalueType = 'bool';
|
||||
}
|
||||
}
|
||||
var offvalue = config.offvalue;
|
||||
var offvalueType = config.offvalueType;
|
||||
if (offvalueType === 'flow' || offvalueType === 'global') {
|
||||
try {
|
||||
parts = RED.util.normalisePropertyExpression(offvalue);
|
||||
if (parts.length === 0) {
|
||||
throw new Error();
|
||||
}
|
||||
} catch(err) {
|
||||
node.warn("Invalid offvalue property expression - defaulting to false")
|
||||
offvalue = false;
|
||||
offvalueType = 'bool';
|
||||
}
|
||||
}
|
||||
|
||||
node.on("input", function(msg) {
|
||||
node.topi = msg.topic;
|
||||
});
|
||||
|
||||
var done = ui.add({
|
||||
node: node,
|
||||
tab: tab,
|
||||
group: group,
|
||||
emitOnlyNewValues: false,
|
||||
forwardInputMessages: config.passthru,
|
||||
storeFrontEndInputAsState: (config.decouple === "true") ? false : true, //config.passthru,
|
||||
state: false,
|
||||
control: {
|
||||
type: 'switch' + (config.style ? '-' + config.style : ''),
|
||||
label: config.label,
|
||||
tooltip: config.tooltip,
|
||||
order: config.order,
|
||||
value: false,
|
||||
onicon: config.onicon,
|
||||
officon: config.officon,
|
||||
oncolor: config.oncolor,
|
||||
offcolor: config.offcolor,
|
||||
animate: config.animate?"flip-icon":"",
|
||||
width: config.width || group.config.width || 6,
|
||||
height: config.height || 1,
|
||||
className: config.className || '',
|
||||
},
|
||||
convert: function (payload, oldval, msg) {
|
||||
var myOnValue,myOffValue;
|
||||
|
||||
if (onvalueType === "date") { myOnValue = Date.now(); }
|
||||
else { myOnValue = RED.util.evaluateNodeProperty(onvalue,onvalueType,node); }
|
||||
|
||||
if (offvalueType === "date") { myOffValue = Date.now(); }
|
||||
else { myOffValue = RED.util.evaluateNodeProperty(offvalue,offvalueType,node); }
|
||||
|
||||
if (!this.forwardInputMessages && this.storeFrontEndInputAsState) {
|
||||
if (myOnValue === oldval) { return true; }
|
||||
if (oldval === true) { return true; }
|
||||
else { return false; }
|
||||
}
|
||||
|
||||
if (RED.util.compareObjects(myOnValue,msg.payload)) { node.state[0] = "on"; return true; }
|
||||
else if (RED.util.compareObjects(myOffValue,msg.payload)) { node.state[0] = "off"; return false; }
|
||||
else { return oldval; }
|
||||
},
|
||||
convertBack: function (value) {
|
||||
node.state[1] = value?"on":"off";
|
||||
if (node.pt) {
|
||||
node.status({fill:(value?"green":"red"),shape:(value?"dot":"ring"),text:value?"on":"off"});
|
||||
}
|
||||
else {
|
||||
var col = (node.decouple) ? ((node.state[1]=="on")?"green":"red") : ((node.state[0]=="on")?"green":"red");
|
||||
var shp = (node.decouple) ? ((node.state[1]=="on")?"dot":"ring") : ((node.state[0]=="on")?"dot":"ring");
|
||||
var txt = (node.decouple) ? (node.state[0] +" | "+node.state[1].toUpperCase()) : (node.state[0].toUpperCase() +" | "+node.state[1])
|
||||
node.status({fill:col, shape:shp, text:txt});
|
||||
}
|
||||
var payload = value ? onvalue : offvalue;
|
||||
var payloadType = value ? onvalueType : offvalueType;
|
||||
|
||||
if (payloadType === "date") { value = Date.now(); }
|
||||
else {
|
||||
try {
|
||||
value = RED.util.evaluateNodeProperty(payload,payloadType,node);
|
||||
}
|
||||
catch(e) {
|
||||
if (payloadType === "bin") { node.error("Badly formatted buffer"); }
|
||||
else { node.error(e,payload); }
|
||||
}
|
||||
}
|
||||
return value;
|
||||
},
|
||||
beforeSend: function (msg) {
|
||||
var t = undefined;
|
||||
try {
|
||||
t = RED.util.evaluateNodeProperty(config.topic,config.topicType || "str",node,msg) || node.topi;
|
||||
}
|
||||
catch(e) { }
|
||||
if (t !== undefined) { msg.topic = t; }
|
||||
}
|
||||
});
|
||||
|
||||
if (!node.pt) {
|
||||
node.on("input", function() {
|
||||
var col = (node.state[0]=="on") ? "green" : "red";
|
||||
var shp = (node.state[0]=="on") ? "dot" : "ring";
|
||||
var txt = (node.decouple) ? (node.state[0] +" | "+node.state[1].toUpperCase()) : (node.state[0].toUpperCase() +" | "+node.state[1])
|
||||
node.status({fill:col, shape:shp, text:txt});
|
||||
});
|
||||
}
|
||||
|
||||
node.on("close", done);
|
||||
}
|
||||
RED.nodes.registerType("ui_switch", SwitchNode);
|
||||
};
|
||||
91
node_modules/node-red-dashboard/nodes/ui_tab.html
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
<script type="text/javascript">
|
||||
// convert to i18 text
|
||||
function c_ui_tab(x) {
|
||||
return RED._("node-red-dashboard/ui_tab:ui_tab."+x);
|
||||
}
|
||||
|
||||
RED.nodes.registerType('ui_tab',{
|
||||
category: 'config',
|
||||
defaults: {
|
||||
name: {value: c_ui_tab("label.home")},
|
||||
icon: {value: 'dashboard'},
|
||||
order: {value: 0},
|
||||
disabled: {value: false},
|
||||
hidden: {value: false}
|
||||
},
|
||||
paletteLabel: 'dashboard tab',
|
||||
label: function() { return this.name || c_ui_tab("label.tab"); },
|
||||
sort: function(A,B) {
|
||||
return A.order - B.order;
|
||||
},
|
||||
oneditprepare: function() {
|
||||
$("#node-config-input-disabled-btn").on("click", function(e) {
|
||||
var i = $(this).find("i");
|
||||
var active = i.hasClass("fa-toggle-on");
|
||||
var newCls = "fa fa-toggle-" + (active ? "off" : "on");
|
||||
i.attr("class", newCls);
|
||||
$("#node-config-input-disabled").prop('checked',active);
|
||||
|
||||
var newTxt = c_ui_tab(active ? "label.disabled" : "label.enabled");
|
||||
$("#node-config-input-disabled-label").text(newTxt);
|
||||
|
||||
var info = $("#node-config-input-disabled-info");
|
||||
var done = active ? info.show() : info.hide();
|
||||
});
|
||||
if (this.disabled) {
|
||||
$("#node-config-input-disabled-btn").click();
|
||||
}
|
||||
else {
|
||||
$("#node-config-input-disabled-label").text(c_ui_tab("label.enabled"));
|
||||
}
|
||||
|
||||
$("#node-config-input-hidden-btn").on("click", function(e) {
|
||||
var i = $(this).find("i");
|
||||
var active = i.hasClass("fa-toggle-on");
|
||||
var newCls = "fa fa-toggle-" + (active ? "off" : "on");
|
||||
i.attr("class", newCls);
|
||||
$("#node-config-input-hidden").prop('checked',active);
|
||||
|
||||
var newTxt = c_ui_tab(active ? "label.hidden" : "label.visible");
|
||||
$("#node-config-input-hidden-label").text(newTxt);
|
||||
|
||||
var info = $("#node-config-input-hidden-info");
|
||||
var done = active ? info.show() : info.hide();
|
||||
});
|
||||
if (this.hidden) {
|
||||
$("#node-config-input-hidden-btn").click();
|
||||
}
|
||||
else {
|
||||
$("#node-config-input-hidden-label").text(c_ui_tab("label.visible"));
|
||||
}
|
||||
},
|
||||
oneditsave: function() {
|
||||
this.disabled = $("#node-config-input-disabled").prop("checked");
|
||||
this.hidden = $("#node-config-input-hidden").prop("checked");
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-template-name="ui_tab">
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-name"><i class="fa fa-tag"></i> <span data-i18n="ui_tab.label.name"></span></label>
|
||||
<input type="text" id="node-config-input-name">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-icon"><i class="fa fa-file-image-o"></i> <span data-i18n="ui_tab.label.icon"></span></label>
|
||||
<input type="text" id="node-config-input-icon">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-disabled-btn"><i class="fa fa-ban"></i> <span data-i18n="ui_tab.label.state"></span></label>
|
||||
<button id="node-config-input-disabled-btn" class="editor-button" style="width:100px; margin-right:6px;"><i class="fa fa-toggle-on"></i> <span id="node-config-input-disabled-label"></span></button>
|
||||
<input type="checkbox" id="node-config-input-disabled" style="display:none;"/>
|
||||
<span id="node-config-input-disabled-info" data-i18n="[html]ui_tab.info.disabled" style="display:none;"></span>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-hidden-btn"><i class="fa fa-eye-slash"></i> <span data-i18n="ui_tab.label.navmenu"></span></label>
|
||||
<button id="node-config-input-hidden-btn" class="editor-button" style="width:100px; margin-right:6px;"><i class="fa fa-toggle-on"></i> <span id="node-config-input-hidden-label"></span></button>
|
||||
<input type="checkbox" id="node-config-input-hidden" style="display:none;"/>
|
||||
<span id="node-config-input-hidden-info" data-i18n="[html]ui_tab.info.hidden" style="display:none;"></span>
|
||||
</div>
|
||||
<div class="form-tips" data-i18n="[html]ui_tab.tip"></div>
|
||||
</script>
|
||||
15
node_modules/node-red-dashboard/nodes/ui_tab.js
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
module.exports = function(RED) {
|
||||
|
||||
function TabNode(config) {
|
||||
RED.nodes.createNode(this, config);
|
||||
this.config = {
|
||||
name: config.name,
|
||||
order: config.order || 0,
|
||||
icon: config.icon || '',
|
||||
disabled: config.disabled || false,
|
||||
hidden: config.hidden || false
|
||||
};
|
||||
}
|
||||
|
||||
RED.nodes.registerType("ui_tab", TabNode);
|
||||
};
|
||||