@flowfuse/node-red-dashboard 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +53 -0
  3. package/dist/css/app.d047b42b.css +1 -0
  4. package/dist/css/chunk-vendors.2378ce49.css +24 -0
  5. package/dist/fonts/materialdesignicons-webfont.3de8526e.woff +0 -0
  6. package/dist/fonts/materialdesignicons-webfont.477c6ab0.woff2 +0 -0
  7. package/dist/fonts/materialdesignicons-webfont.48a1ce0c.eot +0 -0
  8. package/dist/fonts/materialdesignicons-webfont.dfd403cf.ttf +0 -0
  9. package/dist/index.html +1 -0
  10. package/dist/js/app.854a8cd5.js +2 -0
  11. package/dist/js/app.854a8cd5.js.map +1 -0
  12. package/dist/js/chunk-vendors.174e8921.js +43 -0
  13. package/dist/js/chunk-vendors.174e8921.js.map +1 -0
  14. package/nodes/config/locales/en-US/ui_base.json +19 -0
  15. package/nodes/config/locales/en-US/ui_group.html +4 -0
  16. package/nodes/config/locales/en-US/ui_group.json +16 -0
  17. package/nodes/config/ui_base.html +807 -0
  18. package/nodes/config/ui_base.js +678 -0
  19. package/nodes/config/ui_group.html +55 -0
  20. package/nodes/config/ui_group.js +34 -0
  21. package/nodes/config/ui_page.html +84 -0
  22. package/nodes/config/ui_page.js +33 -0
  23. package/nodes/config/ui_theme.html +101 -0
  24. package/nodes/config/ui_theme.js +15 -0
  25. package/nodes/store/index.js +34 -0
  26. package/nodes/utils/index.js +35 -0
  27. package/nodes/widgets/locales/en-US/ui_button.html +7 -0
  28. package/nodes/widgets/locales/en-US/ui_button.json +24 -0
  29. package/nodes/widgets/locales/en-US/ui_chart.html +41 -0
  30. package/nodes/widgets/locales/en-US/ui_chart.json +17 -0
  31. package/nodes/widgets/locales/en-US/ui_dropdown.html +24 -0
  32. package/nodes/widgets/locales/en-US/ui_form.html +16 -0
  33. package/nodes/widgets/locales/en-US/ui_form.json +36 -0
  34. package/nodes/widgets/locales/en-US/ui_markdown.html +10 -0
  35. package/nodes/widgets/locales/en-US/ui_slider.html +9 -0
  36. package/nodes/widgets/locales/en-US/ui_switch.html +32 -0
  37. package/nodes/widgets/locales/en-US/ui_template.html +59 -0
  38. package/nodes/widgets/locales/en-US/ui_template.json +18 -0
  39. package/nodes/widgets/locales/en-US/ui_text.html +16 -0
  40. package/nodes/widgets/locales/en-US/ui_text_input.html +19 -0
  41. package/nodes/widgets/ui_button.html +146 -0
  42. package/nodes/widgets/ui_button.js +65 -0
  43. package/nodes/widgets/ui_chart.html +314 -0
  44. package/nodes/widgets/ui_chart.js +195 -0
  45. package/nodes/widgets/ui_dropdown.html +199 -0
  46. package/nodes/widgets/ui_dropdown.js +19 -0
  47. package/nodes/widgets/ui_form.html +368 -0
  48. package/nodes/widgets/ui_form.js +18 -0
  49. package/nodes/widgets/ui_markdown.html +134 -0
  50. package/nodes/widgets/ui_markdown.js +14 -0
  51. package/nodes/widgets/ui_notification.html +139 -0
  52. package/nodes/widgets/ui_notification.js +14 -0
  53. package/nodes/widgets/ui_radio_group.html +186 -0
  54. package/nodes/widgets/ui_radio_group.js +20 -0
  55. package/nodes/widgets/ui_slider.html +162 -0
  56. package/nodes/widgets/ui_slider.js +31 -0
  57. package/nodes/widgets/ui_switch.html +194 -0
  58. package/nodes/widgets/ui_switch.js +98 -0
  59. package/nodes/widgets/ui_table.html +149 -0
  60. package/nodes/widgets/ui_table.js +16 -0
  61. package/nodes/widgets/ui_template.html +283 -0
  62. package/nodes/widgets/ui_template.js +19 -0
  63. package/nodes/widgets/ui_text.html +358 -0
  64. package/nodes/widgets/ui_text.js +98 -0
  65. package/nodes/widgets/ui_text_input.html +141 -0
  66. package/nodes/widgets/ui_text_input.js +37 -0
  67. package/package.json +114 -0
@@ -0,0 +1,55 @@
1
+ <script type="text/javascript">
2
+ RED.nodes.registerType('ui-group', {
3
+ category: 'config',
4
+ defaults: {
5
+ name: {
6
+ value: 'Group Name',
7
+ required: true
8
+ },
9
+ page: { type: 'ui-page', required: true },
10
+ width: { value: 6 },
11
+ height: { value: 1 },
12
+ order: { value: -1 },
13
+ disp: { value: true }, // show title on group card
14
+ className: { value: '' }
15
+ },
16
+ label: function () {
17
+ const page = RED.nodes.node(this.page)?.name || ''
18
+ return `${this.name} [${page}]` || 'UI Group'
19
+ },
20
+ oneditprepare: function () {
21
+ $('#node-config-input-size').elementSizer({
22
+ width: '#node-config-input-width',
23
+ height: '#node-config-input-height',
24
+ auto: false
25
+ })
26
+ }
27
+ })
28
+ </script>
29
+
30
+ <script type="text/html" data-template-name="ui-group">
31
+ <div class="form-row">
32
+ <label for="node-config-input-name"><i class="fa fa-bookmark"></i> Name</label>
33
+ <input type="text" id="node-config-input-name">
34
+ </div>
35
+ <div class="form-row">
36
+ <label for="node-config-input-page"><i class="fa fa-bookmark"></i> Page</label>
37
+ <input type="text" id="node-config-input-page">
38
+ </div>
39
+ <div class="form-row">
40
+ <label for="node-config-input-size"><i class="fa fa-arrows-h"></i> Size</label>
41
+ <input type="hidden" id="node-config-input-width">
42
+ <input type="hidden" id="node-config-input-height">
43
+ <button class="editor-button" id="node-config-input-size"></button>
44
+ </div>
45
+ <div class="form-row">
46
+ <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>
47
+ </div>
48
+ <div class="form-row" id="text-row-class">
49
+ <label for="node-config-input-className"><i class="fa fa-code"></i> Class</label>
50
+ <input type="text" id="node-config-input-className" placeholder="Optional CSS class name(s) for group"/>
51
+ </div>
52
+ <div class="form-row">
53
+ <button onclick="RED.sidebar.show('dashboard-2.0')" class="editor-button editor-button-small">Open Dashboard 2.0 Sidebar</button>
54
+ </div>
55
+ </script>
@@ -0,0 +1,34 @@
1
+ module.exports = function (RED) {
2
+ /**
3
+ *
4
+ * @param {*} config
5
+ */
6
+ function UIGroupNode (config) {
7
+ RED.nodes.createNode(this, config)
8
+ const node = this
9
+
10
+ node.on('close', function (removed, done) {
11
+ node.deregister() // deregister self
12
+ done()
13
+ })
14
+
15
+ /**
16
+ * Function for widgets to register themselves with this page
17
+ * Calls the parent UI Base "register" function and registers this page,
18
+ * along with the widget
19
+ * @param {*} widget
20
+ */
21
+ node.register = function (widgetNode, widgetConfig, widgetEvents) {
22
+ const page = RED.nodes.getNode(config.page)
23
+ const group = config
24
+ page.register(group, widgetNode, widgetConfig, widgetEvents)
25
+ }
26
+
27
+ node.deregister = function (widgetNode) {
28
+ const page = RED.nodes.getNode(config.page)
29
+ const group = config
30
+ page.deregister(group, widgetNode)
31
+ }
32
+ }
33
+ RED.nodes.registerType('ui-group', UIGroupNode)
34
+ }
@@ -0,0 +1,84 @@
1
+ <script type="text/javascript">
2
+ RED.nodes.registerType('ui-page', {
3
+ category: 'config',
4
+ defaults: {
5
+ name: {
6
+ value: 'Page Name',
7
+ required: true
8
+ },
9
+ ui: {
10
+ type: 'ui-base',
11
+ value: '',
12
+ required: true
13
+ },
14
+ path: {
15
+ value: '/',
16
+ required: false
17
+ },
18
+ layout: {
19
+ value: '',
20
+ required: true
21
+ },
22
+ theme: {
23
+ type: 'ui-theme',
24
+ value: 'default',
25
+ required: true
26
+ },
27
+ order: {
28
+ value: -1
29
+ },
30
+ className: { value: '' }
31
+ },
32
+ oneditprepare: function () {
33
+ $('#node-config-input-layout').typedInput({
34
+ type: 'layout',
35
+ types: [{
36
+ value: 'layout',
37
+ options: [
38
+ { value: 'grid', label: 'Grid' },
39
+ { value: 'flex', label: 'Fixed' },
40
+ { value: 'notebook', label: 'Notebook' }
41
+ ]
42
+ }],
43
+ typeField: '#node-input-layoutType'
44
+ })
45
+ },
46
+ label: function () {
47
+ const baseNode = RED.nodes.node(this.ui)
48
+ const base = baseNode ? baseNode.path : '/'
49
+ const path = this.path || ''
50
+ return `${this.name} [${base}${path}]` || 'UI Page'
51
+ }
52
+ })
53
+ </script>
54
+
55
+ <script type="text/html" data-template-name="ui-page">
56
+ <div class="form-row">
57
+ <label for="node-config-input-name"><i class="fa fa-bookmark"></i> Name</label>
58
+ <input type="text" id="node-config-input-name">
59
+ </div>
60
+ <div class="form-row">
61
+ <label for="node-config-input-ui"><i class="fa fa-bookmark"></i> UI</label>
62
+ <input type="text" id="node-config-input-ui">
63
+ </div>
64
+ <div class="form-row">
65
+ <label for="node-config-input-path"><i class="fa fa-bookmark"></i> Path</label>
66
+ <input type="text" id="node-config-input-path">
67
+ </div>
68
+ <div class="form-row">
69
+ <label for="node-config-input-theme"><i class="fa fa-bookmark"></i> Theme</label>
70
+ <input type="text" id="node-config-input-theme">
71
+ </div>
72
+ <div class="form-row">
73
+ <label for="node-config-input-layout"><i class="fa fa-bookmark"></i> Layout</label>
74
+ <input type="text" id="node-config-input-layout">
75
+ <input type="hidden" id="node-config-input-layoutType">
76
+ </div>
77
+ <div class="form-row" id="text-row-class">
78
+ <label for="node-config-input-className"><i class="fa fa-code"></i> Class</label>
79
+ <input type="text" id="node-config-input-className" placeholder="Optional CSS class name(s) for page"/>
80
+ </div>
81
+ <div class="form-row">
82
+ <button onclick="RED.sidebar.show('dashboard-2.0')" class="editor-button editor-button-small">Open Dashboard 2.0 Sidebar</button>
83
+ </div>
84
+ </script>
@@ -0,0 +1,33 @@
1
+ module.exports = function (RED) {
2
+ /**
3
+ *
4
+ * @param {*} config
5
+ */
6
+ function UIPageNode (config) {
7
+ RED.nodes.createNode(this, config)
8
+ const node = this
9
+
10
+ node.on('close', function (removed, done) {
11
+ node.deregister() // deregister self
12
+ done()
13
+ })
14
+
15
+ /**
16
+ * Function for widgets to register themselves with this page
17
+ * Calls the parent UI Base "register" function and registers this page,
18
+ * along with the widget
19
+ * @param {*} widget
20
+ */
21
+ node.register = function (group, widgetNode, widgetConfig, widgetEvents) {
22
+ const ui = RED.nodes.getNode(config.ui)
23
+ const page = config
24
+ ui.register(page, group, widgetNode, widgetConfig, widgetEvents)
25
+ }
26
+ node.deregister = function (group, widgetNode) {
27
+ const ui = RED.nodes.getNode(config.ui)
28
+ const page = config
29
+ ui.deregister(page, group, widgetNode)
30
+ }
31
+ }
32
+ RED.nodes.registerType('ui-page', UIPageNode)
33
+ }
@@ -0,0 +1,101 @@
1
+ <script type="text/javascript">
2
+ RED.nodes.registerType('ui-theme', {
3
+ category: 'config',
4
+ defaults: {
5
+ name: {
6
+ value: 'Theme Name',
7
+ required: true
8
+ },
9
+ // colors
10
+ colors: {
11
+ value: null
12
+ }
13
+ },
14
+ oneditprepare: function () {
15
+ if (!this.colors) {
16
+ this.colors = {}
17
+ // set default values
18
+ this.colors.surface = '#ffffff'
19
+ this.colors.primary = '#0094CE'
20
+ // pages
21
+ this.colors.bgPage = '#eeeeee'
22
+ // groups
23
+ this.colors.groupBg = '#ffffff'
24
+ this.colors.groupOutline = '#cccccc'
25
+ }
26
+
27
+ // loop over keys in this.colors
28
+ Object.keys(this.colors).forEach((color) => {
29
+ // get the value of the key
30
+ const value = this.colors[color]
31
+ // set the value of the input
32
+ $('#node-config-input-' + color).val(value)
33
+ })
34
+
35
+ // update label b/g to match the colour input values
36
+ // this provides nicer styling than the default browser styling
37
+ const colorWrappers = $('.color-picker-wrapper')
38
+ colorWrappers.each(function (i) {
39
+ const wrapper = $(this)
40
+ const colorPicker = wrapper.children("input[type='color']").eq(0)
41
+ colorPicker.on('change', () => {
42
+ wrapper.css('background-color', colorPicker.val())
43
+ })
44
+ wrapper.css('background-color', colorPicker.val())
45
+ })
46
+ },
47
+ oneditsave: function () {
48
+ // update our config values from the input values
49
+ Object.keys(this.colors).forEach((color) => {
50
+ // set the value of the input
51
+ this.colors[color] = $('#node-config-input-' + color).val()
52
+ })
53
+ },
54
+ label: function () {
55
+ return `${this.name}` || 'UI Theme'
56
+ }
57
+ })
58
+ </script>
59
+
60
+ <script type="text/html" data-template-name="ui-theme">
61
+ <div class="form-row">
62
+ <label for="node-config-input-name"><i class="fa fa-bookmark"></i> Name</label>
63
+ <input type="text" id="node-config-input-name">
64
+ </div>
65
+ <div class="form-row">
66
+ <label><i class="fa fa-bookmark"></i> Surface</label>
67
+ <label class="color-picker-wrapper" for="node-config-input-primary" style="width: 100px; height: 32px; border-radius: 6px; border: 1px solid #ccc">
68
+ <input type="color" id="node-config-input-surface" style="opacity: 0; width: 100%;"/>
69
+ </label>
70
+ </div>
71
+ <div class="form-row">
72
+ <label><i class="fa fa-bookmark"></i> Primary</label>
73
+ <label class="color-picker-wrapper" for="node-config-input-primary" style="width: 100px; height: 32px; border-radius: 6px; border: 1px solid #ccc">
74
+ <input type="color" id="node-config-input-primary" style="opacity: 0; width: 100%;"/>
75
+ </label>
76
+ </div>
77
+ <div class="form-row">
78
+ <h4 style="margin-bottom: 0;">Pages</h4>
79
+ </div>
80
+ <div class="form-row">
81
+ <label><i class="fa fa-bookmark"></i> Background</label>
82
+ <label class="color-picker-wrapper" for="node-config-input-background" style="width: 100px; height: 32px; border-radius: 6px; border: 1px solid #ccc">
83
+ <input type="color" id="node-config-input-bgPage" style="opacity: 0; width: 100%;"/>
84
+ </label>
85
+ </div>
86
+ <div class="form-row">
87
+ <h4 style="margin-bottom: 0;">Groups</h4>
88
+ </div>
89
+ <div class="form-row">
90
+ <label><i class="fa fa-bookmark"></i> Background</label>
91
+ <label class="color-picker-wrapper" for="node-config-input-background" style="width: 100px; height: 32px; border-radius: 6px; border: 1px solid #ccc">
92
+ <input type="color" id="node-config-input-groupBg" style="opacity: 0; width: 100%;"/>
93
+ </label>
94
+ </div>
95
+ <div class="form-row">
96
+ <label><i class="fa fa-bookmark"></i> Outline</label>
97
+ <label class="color-picker-wrapper" for="node-config-input-background" style="width: 100px; height: 32px; border-radius: 6px; border: 1px solid #ccc">
98
+ <input type="color" id="node-config-input-groupOutline" style="opacity: 0; width: 100%;"/>
99
+ </label>
100
+ </div>
101
+ </script>
@@ -0,0 +1,15 @@
1
+ module.exports = function (RED) {
2
+ /**
3
+ *
4
+ * @param {*} config
5
+ */
6
+ function UIThemeNode (config) {
7
+ RED.nodes.createNode(this, config)
8
+ const node = this
9
+
10
+ // eslint-disable-next-line no-unused-vars
11
+ const { id, name, type, _users, ...rest } = config
12
+ node.colors = { ...rest.colors }
13
+ }
14
+ RED.nodes.registerType('ui-theme', UIThemeNode)
15
+ }
@@ -0,0 +1,34 @@
1
+ const data = {}
2
+
3
+ const getters = {
4
+ // given a widget id, return the latest msg received
5
+ msg (id) {
6
+ return data[id]
7
+ }
8
+ }
9
+
10
+ const setters = {
11
+ // remove data associated to a given widget
12
+ clear (id) {
13
+ delete data[id]
14
+ },
15
+ // given a widget id, and msg, store that latest value
16
+ save (id, msg) {
17
+ data[id] = msg
18
+ },
19
+ // given a widget id, and msg, store in an array of history of values
20
+ // useful for charting widgets
21
+ append (id, msg) {
22
+ if (!data[id]) {
23
+ data[id] = []
24
+ }
25
+ data[id].push(msg)
26
+ }
27
+ }
28
+
29
+ module.exports = {
30
+ get: getters.msg,
31
+ save: setters.save,
32
+ append: setters.append,
33
+ clear: setters.clear
34
+ }
@@ -0,0 +1,35 @@
1
+ function asyncEvaluateNodeProperty (RED, value, type, node, msg) {
2
+ return new Promise(function (resolve, reject) {
3
+ RED.util.evaluateNodeProperty(value, type, node, msg, function (e, r) {
4
+ if (e) {
5
+ reject(e)
6
+ } else {
7
+ resolve(r)
8
+ }
9
+ })
10
+ })
11
+ }
12
+
13
+ async function appendTopic (RED, config, wNode, msg) {
14
+ // populate topic if the node specifies one
15
+ if (config.topic || config.topicType) {
16
+ try {
17
+ msg.topic = await asyncEvaluateNodeProperty(RED, config.topic, config.topicType || 'str', wNode, msg) || ''
18
+ } catch (_err) {
19
+ // do nothing
20
+ console.error(_err)
21
+ }
22
+ }
23
+
24
+ // ensure we have a topic property in the msg, even if it's an empty string
25
+ if (!('topic' in msg)) {
26
+ msg.topic = ''
27
+ }
28
+
29
+ return msg
30
+ }
31
+
32
+ module.exports = {
33
+ asyncEvaluateNodeProperty,
34
+ appendTopic
35
+ }
@@ -0,0 +1,7 @@
1
+ <script type="text/html" data-help-name="ui-button">
2
+ <p>Adds a button to the user interface.</p>
3
+ <p>
4
+ Clicking the button generates a message with <code>msg.payload</code>
5
+ set to the <b>Payload</b> field, and <code>msg.topic</code> to the <b>Topic</b> field.
6
+ </p>
7
+ </script>
@@ -0,0 +1,24 @@
1
+ {
2
+ "ui-button": {
3
+ "label": {
4
+ "group": "Group",
5
+ "size": "Size",
6
+ "icon": "Icon",
7
+ "optionalIcon": "optional icon",
8
+ "label": "Label",
9
+ "optionalLabel": "optional label",
10
+ "tooltip": "Tooltip",
11
+ "optionalTooltip": "optional tooltip",
12
+ "color": "Color",
13
+ "optionalColor": "optional text/icon color",
14
+ "background": "Background",
15
+ "optionalBackgroundColor": "optional background color",
16
+ "whenClicked": "When clicked, send:",
17
+ "payload": "Payload",
18
+ "topic": "Topic",
19
+ "emulateClick": "If msg arrives on input, emulate a button click:",
20
+ "className": "Class",
21
+ "classNamePlaceholder": "Optional CSS class name(s) for widget"
22
+ }
23
+ }
24
+ }
@@ -0,0 +1,41 @@
1
+
2
+ <script type="text/html" data-help-name="ui-chart">
3
+ <h3>Properties</h3>
4
+ <dl class="message-properties">
5
+ <dt>Label <span class="property-type">str</span></dt>
6
+ <dd>Text shown above the rendered chart in the Dashboard.</dd>
7
+ <dt>Type <span class="property-type">line | bar | scatter</span></dt>
8
+ <dd>Choose the type of graph that you wish to render data with. Note
9
+ that different data structures are accepted for different chart types.</dd>
10
+ <dt>Show Legend <span class="property-type">bool</span></dt>
11
+ <dd>Defines whether or not a legend is shown between the title and the chart. Each label is driven by <code>msg.topic</code>.</dd>
12
+ <dt>X-Axis Type <span class="property-type">linear | categorical | time</span></dt>
13
+ <dd>
14
+ For charts with an x-axis, this option allows customisation
15
+ of the type of axis to render.
16
+ </dd>
17
+ <dt>Properties <span class="property-type">string</span></dt>
18
+ <dd>
19
+ <p><b>Series:</b> Controls how you want to set the Series of data stream into this widget. The default is <code>msg.topic</code>, where separate topics will render to a new line/bar in their respective plots.</p>
20
+ <p><b>X:</b> Only available for Line & Scatter Charts. This defines the key (which can be nested) of the value that should be plotted onto the x-axis. If left blank, the x-value will be calculated as the current timestamp.</p>
21
+ <p><b>Y:</b> Defines the key (which can be nested, e.g. <code>'nested.value'</code>) of the value that should be plotted onto the x-axis. This value is ignored if injecting single numerical values into the chart.</p>
22
+ </dd>
23
+ </dl>
24
+ <h3>Input</h3>
25
+ <p>Data can be passed into the Chart node in a variety of formats,
26
+ depending on the "X-Axis Type" (e.g. linear, categorical, time).</p>
27
+ <dl class="message-properties">
28
+ <dt>Numerical <span class="property-type">linear | categorical | time</span></dt>
29
+ <dd><pre>msg.payload = 5</pre> A single value, that will be plotted
30
+ in the y-axis, and the current time of injection as the x-value.</dd>
31
+ <dt>Series <span class="property-type">linear | categorical | time</span></dt>
32
+ <dd><pre>msg.topic = 'Series 1'</pre> Multiple series can
33
+ be shown on the same chart by using a different msg.topic value on each
34
+ input message.</dd>
35
+ <dt>Object <span class="property-type">linear</span></dt>
36
+ <dd><pre>msg.payload = {x: 10, y: 15}</pre>This type of data is only
37
+ supported on linear plots, e.g. "Line" or "Scatter" charts.</dd>
38
+ </dl>
39
+ <h3>Details</h3>
40
+ <p></p>
41
+ </script>
@@ -0,0 +1,17 @@
1
+ {
2
+ "ui-chart": {
3
+ "label": {
4
+ "seriesColors": "Series Colors",
5
+ "seconds": "Seconds",
6
+ "minutes": "Minutes",
7
+ "hours": "Hours",
8
+ "days": "Days",
9
+ "weeks": "Weeks",
10
+ "or": "OR",
11
+ "points": "points",
12
+ "xLimit": "X-Axis Limit",
13
+ "xType": "X-Axis Type",
14
+ "last": "last"
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,24 @@
1
+ <script type="text/html" data-help-name="ui-dropdown">
2
+ <p>
3
+ Adds a dropdown to your dashboard that will emit values
4
+ in Node-RED under `msg.payload` anytime it's value is changed.
5
+ </p>
6
+ <p>
7
+ In the case where a single option is selected, returns the object detailing that selection.
8
+ If "Allow multiple selections" is enabled, returns an array of objects detailing the selections.
9
+ </p>
10
+ <h3>Selecting Options via <code>msg.</code></h3>
11
+ <p>
12
+ You can dynamically make selections for this dropdown by passing in the respective <code>value</code> to <code>msg.payload</code>.
13
+ </p>
14
+ <p>
15
+ To make a single selection, pass in the <code>value</code> of the option as <code>msg.payload</code>, e.g. <code>msg.payload = "option1"</code>.
16
+ </p>
17
+ <p>
18
+ To make a multi-selection selection, you must first have "Allow Multiple" enabled on the node, you can then
19
+ pass an Array of <code>value</code> of the respective options as <code>msg.payload</code>, e.g. <code>msg.payload = ["option1", "option2"]</code>.
20
+ </p>
21
+ <p>
22
+ To clear any selection for a dropdown, pass an empty array <code>[]</code> as <code>msg.payload</code>.
23
+ </p>
24
+ </script>
@@ -0,0 +1,16 @@
1
+ <script type="text/html" data-help-name="ui-form">
2
+ <p>Adds a form to user interface.</p>
3
+ <p>Helps to collect multiple value from the user on submit button click as an object in <code>msg.payload</code> </p>
4
+ <p>Multiple input elements can be added using add elements button</p>
5
+ <p>Each element contains following components:</p>
6
+ <ul>
7
+ <li> <b>Label</b> : Value that will be the label of the element in the user interface</li>
8
+ <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>
9
+ <li> <b>Type</b> : Drop down option to select the type of input element</li>
10
+ <li> <b>Required</b> : On switching on the user has to supply the value before submitting</li>
11
+ <li> <b>Rows</b> : number of UI rows for multiline text input</li>
12
+ <li> <b>Delete</b> : To remove the current element from the form</li>
13
+ </ul>
14
+ <p>Optionally the <b>Topic</b> field can be used to set the <code>msg.topic</code> property.</p>
15
+ <p>The Cancel button can be hidden by setting it's value to be blank "".</p>
16
+ </script>
@@ -0,0 +1,36 @@
1
+ {
2
+ "ui-form": {
3
+ "label": {
4
+ "group": "Group",
5
+ "size": "Size",
6
+ "label": "Label",
7
+ "optionalLabel": "optional label",
8
+ "formElements": "Form elements",
9
+ "type": "Type",
10
+ "required": "Required",
11
+ "rows": "Rows",
12
+ "remove": "Remove",
13
+ "egName": "e.g. Name",
14
+ "egName2": "e.g. name",
15
+ "text": "Text",
16
+ "multiline": "Multiline",
17
+ "number": "Number",
18
+ "email": "E-mail",
19
+ "password": "Password",
20
+ "checkbox": "Checkbox",
21
+ "switch": "Switch",
22
+ "date": "Date",
23
+ "time": "Time",
24
+ "element": "element",
25
+ "buttons": "Buttons",
26
+ "submitButtonText": "submit button text",
27
+ "cancelButtonText": "cancel button text",
28
+ "topic": "Topic",
29
+ "optionalMsgTopic": "optional msg.topic",
30
+ "splitLayout":"Place the form elements in two columns",
31
+ "resetOnSubmit":"Reset the form when submitted",
32
+ "className": "Class",
33
+ "classNamePlaceholder": "Optional CSS class name(s) for widget"
34
+ }
35
+ }
36
+ }
@@ -0,0 +1,10 @@
1
+ <script type="text/html" data-help-name="ui-text">
2
+ <p>
3
+ Converts markdown to rendered HTML int the Dashboard.
4
+ </p>
5
+ <p>
6
+ Can be use for rendering labels, headers or even full blog articles. If you're
7
+ looking for a quick cheat sheet on how to write Markdown, you can check out
8
+ FlowFuse's guide <a href="https://flowfuse.com/handbook/development/markdown-how-to/#markdown-how-to" target="_blank">here</a>.
9
+ </p>
10
+ </script>
@@ -0,0 +1,9 @@
1
+
2
+ <script type="text/html" data-help-name="ui-slider">
3
+ <p>Adds a slider widget to the user interface.</p>
4
+ <p>
5
+ The user can change its value between the limits (<b>min</b> and <b>max</b>).
6
+ Each value change will generate a message with the value set as <b>payload</b>.
7
+ </p>
8
+ <p>The slider can be reversed by setting the min value larger than the max value. e.g. min 100, max 0.</p>
9
+ </script>
@@ -0,0 +1,32 @@
1
+ <script type="text/html" data-help-name="ui-switch">
2
+ <p>
3
+ Adds a toggle switch to the user interface.
4
+ </p>
5
+ <p>
6
+ Each change in the state of the switch will generate
7
+ a <code>msg.payload</code> with the specified <b>On</b> and <b>Off</b> values.
8
+ </p>
9
+ <p>
10
+ The <b>On/Off Color</b> and <b>On/Off Icon</b> are optional fields. If the icons are present, the default
11
+ toggle switch will be replaced with the relevant icons and their respective colors (if defined).
12
+ </p>
13
+ <p>
14
+ 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>
15
+ <i>(e.g. 'check', 'close')</i> or a <a href="https://fontawesome.com/v4.7.0/icons/" target="_blank">Font Awesome icon</a>
16
+ <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>.
17
+ You can use the full set of google material icons if you add 'mi-' to the icon name. e.g. 'mi-videogame_asset'.
18
+ </p>
19
+ <p>
20
+ The switch state can be updated by an incoming <code>msg.payload</code>. The values must either be <code>true</code>/<code>false</code>
21
+ or match the specified type (number, string, etc) in the node's configuration.</p>
22
+ <!-- <p>
23
+ The label can also be set by a message property by setting
24
+ the field to the name of the property, for example <code>{{msg.topic}}</code>.</p>
25
+ <p>If a <b>Topic</b> is specified, it will be added to the output as <code>msg.topic</code>.</p> -->
26
+ <!-- <p>Setting <code>msg.enabled</code> to <code>false</code> will disable the switch widget.</p> -->
27
+ <!-- <p>
28
+ If a <b>Class</b> is specified, it will be added to the parent card. This way you can style the card
29
+ and the elements inside it with custom CSS. The Class can be set at runtime by setting a
30
+ <code>msg.className</code> string property.
31
+ </p> -->
32
+ </script>