@flowfuse/node-red-dashboard 1.16.1-ee4508a-202409161000.0 → 1.17.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.
- package/dist/apple-touch-icon.png +0 -0
- package/dist/assets/Tableau10-B-NsZVaP.js +1 -0
- package/dist/assets/array-BKyUJesY.js +1 -0
- package/dist/assets/blockDiagram-9f4a6865-BY3wYgfY.js +118 -0
- package/dist/assets/c4Diagram-ae766693-B-AG7NIy.js +10 -0
- package/dist/assets/channel-C_v5mHlo.js +1 -0
- package/dist/assets/classDiagram-fb54d2a0-Cve0-MS1.js +2 -0
- package/dist/assets/classDiagram-v2-a2b738ad-DikSiPRc.js +2 -0
- package/dist/assets/clone-BXaIEimD.js +1 -0
- package/dist/assets/createText-ca0c5216-DvPZ4lSa.js +7 -0
- package/dist/assets/edges-066a5561-DMO7edq0.js +4 -0
- package/dist/assets/erDiagram-09d1c15f-C8g8w-fe.js +51 -0
- package/dist/assets/flowDb-c1833063-ByiZML3Q.js +10 -0
- package/dist/assets/flowDiagram-b222e15a-B7kVs9sh.js +4 -0
- package/dist/assets/flowDiagram-v2-13329dc7-BQ7oM3Wh.js +1 -0
- package/dist/assets/flowchart-elk-definition-ae0efee6-CAWlGS57.js +139 -0
- package/dist/assets/ganttDiagram-b62c793e-cVXtk4xr.js +257 -0
- package/dist/assets/gitGraphDiagram-942e62fe-ytnvaJ2O.js +70 -0
- package/dist/assets/graph-Bq9AO4pT.js +1 -0
- package/dist/assets/index--pBozGw-.js +245 -0
- package/dist/assets/index-01f381cb-CuQuHO3g.js +1 -0
- package/dist/assets/index-40_V--R5.css +13 -0
- package/dist/assets/infoDiagram-94cd232f-D3qHX83u.js +7 -0
- package/dist/assets/init-Gi6I4Gst.js +1 -0
- package/dist/assets/journeyDiagram-6625b456-DrDjeExJ.js +139 -0
- package/dist/assets/katex-CvgdMzdh.js +261 -0
- package/dist/assets/layout-dTROeK7M.js +1 -0
- package/dist/assets/line--V00syVo.js +1 -0
- package/dist/assets/linear-C2oDpuMJ.js +1 -0
- package/dist/assets/logo-DIAzbBuw.png +0 -0
- package/dist/assets/materialdesignicons-webfont-B7mPwVP_.ttf +0 -0
- package/dist/assets/materialdesignicons-webfont-CSr8KVlo.eot +0 -0
- package/dist/assets/materialdesignicons-webfont-Dp5v-WZN.woff2 +0 -0
- package/dist/assets/materialdesignicons-webfont-PXm3-2wK.woff +0 -0
- package/dist/assets/mindmap-definition-307c710a-CMUeraG8.js +110 -0
- package/dist/assets/ordinal-Cboi1Yqb.js +1 -0
- package/dist/assets/pieDiagram-bb1d19e5-P5mFu8pA.js +35 -0
- package/dist/assets/quadrantDiagram-c759a472-DRSID9uQ.js +7 -0
- package/dist/assets/requirementDiagram-87253d64-98AMKGz3.js +52 -0
- package/dist/assets/sankeyDiagram-707fac0f-c6m9e_oG.js +8 -0
- package/dist/assets/sequenceDiagram-6894f283-z-gVG6uq.js +122 -0
- package/dist/assets/stateDiagram-5dee940d-DWfP8BzL.js +1 -0
- package/dist/assets/stateDiagram-v2-1992cada-DBpwYzQS.js +1 -0
- package/dist/assets/styles-0784dbeb-DIb0daye.js +207 -0
- package/dist/assets/styles-483fbfea-DqDTwju_.js +116 -0
- package/dist/assets/styles-b83b31c9-CSuCi6iq.js +160 -0
- package/dist/assets/svgDrawCommon-5e1cfd1d-CDAD6QkU.js +1 -0
- package/dist/assets/timeline-definition-bf702344-Dv2jO1Md.js +61 -0
- package/dist/assets/workbox-window.prod.es5-D5gOYdM7.js +2 -0
- package/dist/assets/xychartDiagram-f11f50a6-CEl6xRTu.js +7 -0
- package/dist/favicon.ico +0 -0
- package/dist/favicon.svg +482 -0
- package/dist/index.html +22 -0
- package/dist/logo-512x512.png +0 -0
- package/dist/logo.svg +482 -0
- package/dist/manifest.webmanifest +1 -0
- package/dist/maskable-icon-512x512.png +0 -0
- package/dist/pwa-192x192.png +0 -0
- package/dist/pwa-512x512.png +0 -0
- package/dist/pwa-64x64.png +0 -0
- package/dist/sw.js +2 -0
- package/nodes/config/locales/en-US/ui_page.html +7 -0
- package/nodes/config/locales/en-US/ui_page.json +5 -0
- package/nodes/config/ui_page.html +260 -96
- package/nodes/config/ui_page.js +9 -0
- package/nodes/widgets/locales/en-US/ui_gauge.html +4 -2
- package/nodes/widgets/locales/en-US/ui_gauge.json +2 -1
- package/nodes/widgets/locales/en-US/ui_number_input.html +21 -10
- package/nodes/widgets/locales/en-US/ui_table.html +8 -3
- package/nodes/widgets/locales/en-US/ui_table.json +4 -1
- package/nodes/widgets/ui_gauge.html +251 -232
- package/nodes/widgets/ui_gauge.js +9 -2
- package/nodes/widgets/ui_number_input.html +21 -2
- package/nodes/widgets/ui_number_input.js +33 -0
- package/nodes/widgets/ui_table.html +13 -1
- package/nodes/widgets/ui_table.js +21 -3
- package/package.json +5 -4
|
@@ -9,63 +9,75 @@
|
|
|
9
9
|
</style>
|
|
10
10
|
|
|
11
11
|
<script type="text/javascript">
|
|
12
|
-
function
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
12
|
+
(function () {
|
|
13
|
+
function validateGaugeSegments (segments) {
|
|
14
|
+
$('#node-input-validation-segments').hide()
|
|
15
|
+
const min = parseFloat(this.min)
|
|
16
|
+
const max = parseFloat(this.max)
|
|
17
|
+
|
|
18
|
+
// check we have a segment covering the smallest values of the gauge
|
|
19
|
+
let minCovered = false
|
|
20
|
+
for (let i = 0; i < segments.length; i++) {
|
|
21
|
+
const from = parseFloat(segments[i].from)
|
|
22
|
+
if (from <= min) {
|
|
23
|
+
minCovered = true
|
|
24
|
+
}
|
|
23
25
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
$('#node-input-validation-segments').text("It's advised to make sure your first segment's 'from' value and the gauge's 'min' value are the same.").show()
|
|
27
|
-
}
|
|
28
|
-
// check if we have any extra, unneccessary, segments
|
|
29
|
-
let extras = false
|
|
30
|
-
for (let i = 0; i < segments.length; i++) {
|
|
31
|
-
const from = parseFloat(segments[i].from)
|
|
32
|
-
if (from > max) {
|
|
33
|
-
extras = true
|
|
26
|
+
if (!minCovered) {
|
|
27
|
+
$('#node-input-validation-segments').text("It's advised to make sure your first segment's 'from' value and the gauge's 'min' value are the same.").show()
|
|
34
28
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
RED.nodes.registerType('ui-gauge', {
|
|
42
|
-
category: RED._('@flowfuse/node-red-dashboard/ui-base:ui-base.label.category'),
|
|
43
|
-
color: RED._('@flowfuse/node-red-dashboard/ui-base:ui-base.colors.medium'),
|
|
44
|
-
defaults: {
|
|
45
|
-
name: { value: '' },
|
|
46
|
-
group: { type: 'ui-group', required: true },
|
|
47
|
-
order: { value: 0 },
|
|
48
|
-
width: {
|
|
49
|
-
value: 3,
|
|
50
|
-
validate: function (v) {
|
|
51
|
-
const width = v || 0
|
|
52
|
-
const currentGroup = $('#node-input-group').val() || this.group
|
|
53
|
-
const groupNode = RED.nodes.node(currentGroup)
|
|
54
|
-
const valid = !groupNode || +width <= +groupNode.width
|
|
55
|
-
$('#node-input-size').toggleClass('input-error', !valid)
|
|
56
|
-
return valid
|
|
29
|
+
// check if we have any extra, unneccessary, segments
|
|
30
|
+
let extras = false
|
|
31
|
+
for (let i = 0; i < segments.length; i++) {
|
|
32
|
+
const from = parseFloat(segments[i].from)
|
|
33
|
+
if (from > max) {
|
|
34
|
+
extras = true
|
|
57
35
|
}
|
|
36
|
+
}
|
|
37
|
+
if (extras) {
|
|
38
|
+
$('#node-input-validation-segments').text('You have segments defined outside of the min/max range of your gauge').show()
|
|
39
|
+
}
|
|
40
|
+
const unique = new Set(this.segments.map(function (o) { return o.from }))
|
|
41
|
+
if (this.segments.length === unique.size) { $('#valWarning').hide() } else { $('#valWarning').show() }
|
|
42
|
+
return minCovered && !extras && this.segments.length === unique.size
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const DEFAULTS = {
|
|
46
|
+
'gauge-tank': {
|
|
47
|
+
min: 0,
|
|
48
|
+
max: 100,
|
|
49
|
+
segments: [{
|
|
50
|
+
color: '#A8F5FF',
|
|
51
|
+
from: 0
|
|
52
|
+
}, {
|
|
53
|
+
color: '#55DBEC',
|
|
54
|
+
from: 15
|
|
55
|
+
}, {
|
|
56
|
+
color: '#53B4FD',
|
|
57
|
+
from: 35
|
|
58
|
+
}, {
|
|
59
|
+
color: '#2397D1',
|
|
60
|
+
from: 50
|
|
61
|
+
}]
|
|
58
62
|
},
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
63
|
+
'gauge-battery': {
|
|
64
|
+
min: 0,
|
|
65
|
+
max: 100,
|
|
66
|
+
segments: [{
|
|
67
|
+
color: '#EA5353',
|
|
68
|
+
from: 0
|
|
69
|
+
}, {
|
|
70
|
+
color: '#FFC800',
|
|
71
|
+
from: 40
|
|
72
|
+
}, {
|
|
73
|
+
color: '#5CD65C',
|
|
74
|
+
from: 70
|
|
75
|
+
}]
|
|
76
|
+
},
|
|
77
|
+
'gauge-tile': {
|
|
78
|
+
min: 0,
|
|
79
|
+
max: 10,
|
|
80
|
+
segments: [{
|
|
69
81
|
color: '#5CD65C',
|
|
70
82
|
from: 0
|
|
71
83
|
}, {
|
|
@@ -74,209 +86,215 @@
|
|
|
74
86
|
}, {
|
|
75
87
|
color: '#EA5353',
|
|
76
88
|
from: 7
|
|
77
|
-
}]
|
|
78
|
-
validate: validateGaugeSegments
|
|
79
|
-
},
|
|
80
|
-
min: { value: 0, required: true, validate: RED.validators.number() },
|
|
81
|
-
max: { value: 10, required: true, validate: RED.validators.number() },
|
|
82
|
-
// sizes
|
|
83
|
-
sizeThickness: { value: 16, validate: RED.validators.number() },
|
|
84
|
-
sizeGap: { value: 4, validate: RED.validators.number() },
|
|
85
|
-
sizeKeyThickness: { value: 8, validate: RED.validators.number() },
|
|
86
|
-
// style
|
|
87
|
-
styleRounded: { value: true },
|
|
88
|
-
styleGlow: { value: false },
|
|
89
|
-
// CSS
|
|
90
|
-
className: { value: '' }
|
|
91
|
-
},
|
|
92
|
-
inputs: 1,
|
|
93
|
-
outputs: 0,
|
|
94
|
-
inputLabels: function () { return this.min + ' - ' + this.max },
|
|
95
|
-
align: 'right',
|
|
96
|
-
icon: 'ui-gauge.svg',
|
|
97
|
-
paletteLabel: 'gauge',
|
|
98
|
-
label: function () { return this.name || this.title || this.gtype },
|
|
99
|
-
labelStyle: function () { return this.name ? 'node_label_italic' : '' },
|
|
100
|
-
oneditprepare: function () {
|
|
101
|
-
// store reference to initial gtype so we can check if it's changed
|
|
102
|
-
const initGType = this.gtype
|
|
103
|
-
|
|
104
|
-
// if this groups parent is a subflow template, set the node-config-input-width and node-config-input-height up
|
|
105
|
-
// as typedInputs and hide the elementSizer (as it doesn't make sense for subflow templates)
|
|
106
|
-
if (RED.nodes.subflow(this.z)) {
|
|
107
|
-
// change inputs from hidden to text & display them
|
|
108
|
-
$('#node-input-width').attr('type', 'text')
|
|
109
|
-
$('#node-input-height').attr('type', 'text')
|
|
110
|
-
$('div.form-row.nr-db-ui-element-sizer-row').hide()
|
|
111
|
-
$('div.form-row.nr-db-ui-manual-size-row').show()
|
|
112
|
-
} else {
|
|
113
|
-
// not in a subflow, use the elementSizer
|
|
114
|
-
$('div.form-row.nr-db-ui-element-sizer-row').show()
|
|
115
|
-
$('div.form-row.nr-db-ui-manual-size-row').hide()
|
|
116
|
-
$('#node-input-size').elementSizer({
|
|
117
|
-
width: '#node-input-width',
|
|
118
|
-
height: '#node-input-height',
|
|
119
|
-
group: '#node-input-group'
|
|
120
|
-
})
|
|
89
|
+
}]
|
|
121
90
|
}
|
|
91
|
+
}
|
|
92
|
+
DEFAULTS['gauge-34'] = DEFAULTS['gauge-tile']
|
|
93
|
+
DEFAULTS['gauge-half'] = DEFAULTS['gauge-tile']
|
|
122
94
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
95
|
+
function isDefault (gtype) {
|
|
96
|
+
// get min, max and segments from UI and check if they are different from the defaults
|
|
97
|
+
const min = +$('#node-input-min').val()
|
|
98
|
+
const max = +$('#node-input-max').val()
|
|
99
|
+
const segments = $('#node-input-segments-container').children()
|
|
100
|
+
gtype = gtype || $('#node-input-gtype').val()
|
|
101
|
+
const defaults = DEFAULTS[gtype]
|
|
102
|
+
if (!defaults) {
|
|
103
|
+
return false
|
|
104
|
+
}
|
|
105
|
+
if (min !== defaults.min || max !== defaults.max || segments.length !== defaults.segments.length) {
|
|
106
|
+
return false
|
|
107
|
+
}
|
|
108
|
+
for (let i = 0; i < segments.length; i++) {
|
|
109
|
+
const segment = $(segments[i])
|
|
110
|
+
const from = +segment.find('.node-input-segment-from').val()
|
|
111
|
+
const color = segment.find('.node-input-segment-color').val()
|
|
112
|
+
if (from !== defaults.segments[i].from || (color + '').toLowerCase() !== defaults.segments[i].color.toLowerCase()) {
|
|
113
|
+
return false
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return true
|
|
117
|
+
}
|
|
126
118
|
|
|
127
|
-
|
|
119
|
+
RED.nodes.registerType('ui-gauge', {
|
|
120
|
+
category: RED._('@flowfuse/node-red-dashboard/ui-base:ui-base.label.category'),
|
|
121
|
+
color: RED._('@flowfuse/node-red-dashboard/ui-base:ui-base.colors.medium'),
|
|
122
|
+
defaults: {
|
|
123
|
+
name: { value: '' },
|
|
124
|
+
group: { type: 'ui-group', required: true },
|
|
125
|
+
order: { value: 0 },
|
|
126
|
+
width: {
|
|
127
|
+
value: 3,
|
|
128
|
+
validate: function (v) {
|
|
129
|
+
const width = v || 0
|
|
130
|
+
const currentGroup = $('#node-input-group').val() || this.group
|
|
131
|
+
const groupNode = RED.nodes.node(currentGroup)
|
|
132
|
+
const valid = !groupNode || +width <= +groupNode.width
|
|
133
|
+
$('#node-input-size').toggleClass('input-error', !valid)
|
|
134
|
+
return valid
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
height: { value: 3 },
|
|
138
|
+
gtype: { value: 'gauge-half' },
|
|
139
|
+
gstyle: { value: 'needle' },
|
|
140
|
+
title: { value: 'gauge' },
|
|
141
|
+
units: { value: 'units' },
|
|
142
|
+
icon: { value: '' },
|
|
143
|
+
prefix: { value: '' },
|
|
144
|
+
suffix: { value: '' },
|
|
145
|
+
segments: {
|
|
146
|
+
value: [...DEFAULTS['gauge-half'].segments],
|
|
147
|
+
validate: validateGaugeSegments
|
|
148
|
+
},
|
|
149
|
+
min: { value: DEFAULTS['gauge-half'].min, required: true, validate: RED.validators.number() },
|
|
150
|
+
max: { value: DEFAULTS['gauge-half'].max, required: true, validate: RED.validators.number() },
|
|
151
|
+
// sizes
|
|
152
|
+
sizeThickness: { value: 16, validate: RED.validators.number() },
|
|
153
|
+
sizeGap: { value: 4, validate: RED.validators.number() },
|
|
154
|
+
sizeKeyThickness: { value: 8, validate: RED.validators.number() },
|
|
155
|
+
// style
|
|
156
|
+
styleRounded: { value: true },
|
|
157
|
+
styleGlow: { value: false },
|
|
158
|
+
// CSS
|
|
159
|
+
className: { value: '' }
|
|
160
|
+
},
|
|
161
|
+
inputs: 1,
|
|
162
|
+
outputs: 0,
|
|
163
|
+
inputLabels: function () { return this.min + ' - ' + this.max },
|
|
164
|
+
align: 'right',
|
|
165
|
+
icon: 'ui-gauge.svg',
|
|
166
|
+
paletteLabel: 'gauge',
|
|
167
|
+
label: function () { return this.name || this.title || this.gtype },
|
|
168
|
+
labelStyle: function () { return this.name ? 'node_label_italic' : '' },
|
|
169
|
+
oneditprepare: function () {
|
|
170
|
+
let isInitialised = false
|
|
171
|
+
let currentType = this.gtype
|
|
172
|
+
// if this groups parent is a subflow template, set the node-config-input-width and node-config-input-height up
|
|
173
|
+
// as typedInputs and hide the elementSizer (as it doesn't make sense for subflow templates)
|
|
174
|
+
if (RED.nodes.subflow(this.z)) {
|
|
175
|
+
// change inputs from hidden to text & display them
|
|
176
|
+
$('#node-input-width').attr('type', 'text')
|
|
177
|
+
$('#node-input-height').attr('type', 'text')
|
|
178
|
+
$('div.form-row.nr-db-ui-element-sizer-row').hide()
|
|
179
|
+
$('div.form-row.nr-db-ui-manual-size-row').show()
|
|
180
|
+
} else {
|
|
181
|
+
// not in a subflow, use the elementSizer
|
|
182
|
+
$('div.form-row.nr-db-ui-element-sizer-row').show()
|
|
183
|
+
$('div.form-row.nr-db-ui-manual-size-row').hide()
|
|
184
|
+
$('#node-input-size').elementSizer({
|
|
185
|
+
width: '#node-input-width',
|
|
186
|
+
height: '#node-input-height',
|
|
187
|
+
group: '#node-input-group'
|
|
188
|
+
})
|
|
189
|
+
}
|
|
128
190
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
191
|
+
function generateSegment (i, segment) {
|
|
192
|
+
const 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);' })
|
|
193
|
+
const row = $('<div/>').appendTo(container)
|
|
194
|
+
$('<div/>', { style: 'padding-top:5px; padding-left:175px;' }).appendTo(container)
|
|
195
|
+
$('<div/>', { style: 'padding-top:5px; padding-left:120px;' }).appendTo(container)
|
|
134
196
|
|
|
135
|
-
|
|
197
|
+
$('<i style="color: var(--red-ui-form-text-color, #eee); cursor:move; margin-left:3px;" class="node-input-segment-handle fa fa-bars"></i>').appendTo(row)
|
|
136
198
|
|
|
137
|
-
|
|
138
|
-
|
|
199
|
+
$('<input/>', { class: 'node-input-segment-color', type: 'color', style: 'margin-left:7px; width: 50px;', placeholder: 'Color', value: segment.color }).appendTo(row)
|
|
200
|
+
$('<input/>', { class: 'node-input-segment-from', type: 'text', style: 'margin-left:7px; width:calc(100% - 175px);', placeholder: 'From', value: segment.from }).appendTo(row)
|
|
139
201
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
202
|
+
const finalSpan = $('<span/>', { style: 'float:right; margin-right:8px;' }).appendTo(row)
|
|
203
|
+
const deleteButton = $('<a/>', { href: '#', class: 'editor-button editor-button-small', style: 'margin-top:7px; margin-left:5px;' }).appendTo(finalSpan)
|
|
204
|
+
$('<i/>', { class: 'fa fa-remove' }).appendTo(deleteButton)
|
|
143
205
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
206
|
+
deleteButton.click(function () {
|
|
207
|
+
container.css({ background: 'var(--red-ui-secondary-background-inactive, #fee)' })
|
|
208
|
+
container.fadeOut(300, function () {
|
|
209
|
+
$(this).remove()
|
|
210
|
+
})
|
|
148
211
|
})
|
|
149
|
-
})
|
|
150
|
-
|
|
151
|
-
$('#node-input-segments-container').append(container)
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
$('#node-input-add-segment').click(function () {
|
|
155
|
-
generateSegment($('#node-input-segments-container').children().length + 1, {})
|
|
156
|
-
$('#node-input-segments-container-div').scrollTop($('#node-input-segments-container-div').get(0).scrollHeight)
|
|
157
|
-
})
|
|
158
212
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
handle: '.node-input-segment-handle',
|
|
162
|
-
cursor: 'move'
|
|
163
|
-
})
|
|
164
|
-
|
|
165
|
-
for (let i = 0; i < this.segments.length; i++) {
|
|
166
|
-
const segment = this.segments[i]
|
|
167
|
-
generateSegment(i + 1, segment)
|
|
168
|
-
}
|
|
213
|
+
$('#node-input-segments-container').append(container)
|
|
214
|
+
}
|
|
169
215
|
|
|
170
|
-
|
|
216
|
+
function showTypeOptions (type) {
|
|
217
|
+
const isChanging = currentType !== type
|
|
218
|
+
const oldType = currentType
|
|
219
|
+
currentType = type
|
|
220
|
+
if (type === 'gauge-tile' || type === 'gauge-battery' || type === 'gauge-tank') {
|
|
221
|
+
$('#node-input-container-sizes').hide()
|
|
222
|
+
$('#node-input-container-gstyle').hide()
|
|
223
|
+
$('#node-input-container-label-extras').hide()
|
|
224
|
+
} else {
|
|
225
|
+
$('#node-input-container-sizes').show()
|
|
226
|
+
$('#node-input-container-gstyle').show()
|
|
227
|
+
$('#node-input-container-label-extras').show()
|
|
228
|
+
}
|
|
171
229
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
$('#node-input-container-label-extras').hide()
|
|
177
|
-
} else {
|
|
178
|
-
$('#node-input-container-sizes').show()
|
|
179
|
-
$('#node-input-container-gstyle').show()
|
|
180
|
-
$('#node-input-container-label-extras').show()
|
|
230
|
+
if (isInitialised && isChanging && isDefault(oldType)) {
|
|
231
|
+
const defaults = DEFAULTS[currentType]
|
|
232
|
+
setup(defaults?.segments, defaults?.min, defaults?.max)
|
|
233
|
+
}
|
|
181
234
|
}
|
|
182
235
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
$('#node-input-
|
|
186
|
-
$('#node-input-max').val(100)
|
|
187
|
-
|
|
188
|
-
// set some sensible segments
|
|
189
|
-
const segments = [{
|
|
190
|
-
color: '#A8F5FF',
|
|
191
|
-
from: 0
|
|
192
|
-
}, {
|
|
193
|
-
color: '#55DBEC',
|
|
194
|
-
from: 15
|
|
195
|
-
}, {
|
|
196
|
-
color: '#53B4FD',
|
|
197
|
-
from: 35
|
|
198
|
-
}, {
|
|
199
|
-
color: '#2397D1',
|
|
200
|
-
from: 50
|
|
201
|
-
}]
|
|
202
|
-
// clear existing segments
|
|
236
|
+
function setup (segments, min, max) {
|
|
237
|
+
$('#node-input-min').val(min)
|
|
238
|
+
$('#node-input-max').val(max)
|
|
203
239
|
$('#node-input-segments-container').empty()
|
|
204
|
-
// add the new "defaults" for this gType
|
|
205
240
|
for (let i = 0; i < segments.length; i++) {
|
|
206
241
|
const segment = segments[i]
|
|
207
242
|
generateSegment(i + 1, segment)
|
|
208
243
|
}
|
|
209
|
-
}
|
|
210
|
-
// set new min/max
|
|
211
|
-
$('#node-input-min').val(0)
|
|
212
|
-
$('#node-input-max').val(100)
|
|
244
|
+
}
|
|
213
245
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
246
|
+
$('#node-input-add-segment').click(function () {
|
|
247
|
+
generateSegment($('#node-input-segments-container').children().length + 1, {})
|
|
248
|
+
$('#node-input-segments-container-div').scrollTop($('#node-input-segments-container-div').get(0).scrollHeight)
|
|
249
|
+
})
|
|
250
|
+
|
|
251
|
+
$('#node-input-segments-container').sortable({
|
|
252
|
+
axis: 'y',
|
|
253
|
+
handle: '.node-input-segment-handle',
|
|
254
|
+
cursor: 'move'
|
|
255
|
+
})
|
|
256
|
+
|
|
257
|
+
// set default segments based on the current gauge type
|
|
258
|
+
$('#node-input-get-defaults').click(function () {
|
|
259
|
+
const selectedType = $('#node-input-gtype').val()
|
|
260
|
+
const defaults = DEFAULTS[selectedType]
|
|
261
|
+
if (defaults) {
|
|
262
|
+
setup(defaults.segments, defaults.min, defaults.max)
|
|
231
263
|
}
|
|
232
|
-
}
|
|
233
|
-
// we've actually changed type, not just being triggered by the initial NR load of palette
|
|
234
|
-
|
|
235
|
-
// set new min/max
|
|
236
|
-
$('#node-input-min').val(0)
|
|
237
|
-
$('#node-input-max').val(10)
|
|
264
|
+
})
|
|
238
265
|
|
|
239
|
-
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
266
|
+
$('#node-input-gtype').change((data) => {
|
|
267
|
+
const gType = $('#node-input-gtype').val()
|
|
268
|
+
showTypeOptions(gType)
|
|
269
|
+
})
|
|
270
|
+
|
|
271
|
+
// now event handlers are set up, set the initial state of the form
|
|
272
|
+
setup(this.segments, this.min, this.max)
|
|
273
|
+
|
|
274
|
+
// trigger the change event to show the correct options
|
|
275
|
+
$('#node-input-gtype').change()
|
|
276
|
+
|
|
277
|
+
// validate the segments
|
|
278
|
+
validateGaugeSegments.call(this, this.segments)
|
|
279
|
+
|
|
280
|
+
isInitialised = true
|
|
281
|
+
},
|
|
282
|
+
oneditsave: function () {
|
|
283
|
+
const segments = $('#node-input-segments-container').children()
|
|
284
|
+
|
|
285
|
+
const node = this
|
|
286
|
+
node.segments = []
|
|
287
|
+
segments.each(function (i) {
|
|
288
|
+
const segment = $(this)
|
|
289
|
+
const s = {
|
|
290
|
+
from: segment.find('.node-input-segment-from').val(),
|
|
291
|
+
color: segment.find('.node-input-segment-color').val()
|
|
256
292
|
}
|
|
257
|
-
|
|
293
|
+
node.segments.push(s)
|
|
294
|
+
})
|
|
258
295
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
const gType = $('#node-input-gtype').val()
|
|
262
|
-
showTypeOptions(gType)
|
|
263
|
-
})
|
|
264
|
-
},
|
|
265
|
-
oneditsave: function () {
|
|
266
|
-
const segments = $('#node-input-segments-container').children()
|
|
267
|
-
|
|
268
|
-
const node = this
|
|
269
|
-
node.segments = []
|
|
270
|
-
segments.each(function (i) {
|
|
271
|
-
const segment = $(this)
|
|
272
|
-
const s = {
|
|
273
|
-
from: segment.find('.node-input-segment-from').val(),
|
|
274
|
-
color: segment.find('.node-input-segment-color').val()
|
|
275
|
-
}
|
|
276
|
-
node.segments.push(s)
|
|
277
|
-
})
|
|
278
|
-
}
|
|
279
|
-
})
|
|
296
|
+
})
|
|
297
|
+
})()
|
|
280
298
|
</script>
|
|
281
299
|
|
|
282
300
|
<script type="text/html" data-template-name="ui-gauge">
|
|
@@ -348,6 +366,7 @@
|
|
|
348
366
|
</div>
|
|
349
367
|
<div class="form-row">
|
|
350
368
|
<a href="#" class="editor-button editor-button-small" id="node-input-add-segment" style="margin-top:4px; margin-left:103px;"><i class="fa fa-plus"></i> <span data-i18n="ui-gauge.label.segment"></span></a>
|
|
369
|
+
<a href="#" class="editor-button editor-button-small" id="node-input-get-defaults" style="margin-top:4px;"><span data-i18n="ui-gauge.label.defaults"></span></a>
|
|
351
370
|
</div>
|
|
352
371
|
<div class="form-row">
|
|
353
372
|
<h3 data-i18n="ui-gauge.label.labelling"></h3>
|
|
@@ -13,9 +13,16 @@ module.exports = function (RED) {
|
|
|
13
13
|
beforeSend: async function (msg) {
|
|
14
14
|
const updates = msg.ui_update
|
|
15
15
|
if (updates) {
|
|
16
|
-
|
|
16
|
+
const hasLabelKey = Object.keys(updates).includes('label')
|
|
17
|
+
const hasTitleKey = Object.keys(updates).includes('title')
|
|
18
|
+
|
|
19
|
+
if (!hasLabelKey && hasTitleKey) {
|
|
20
|
+
updates.label = updates.title
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (typeof updates.label !== 'undefined') {
|
|
17
24
|
// dynamically set "label" property
|
|
18
|
-
statestore.set(group.getBase(), node, msg, '
|
|
25
|
+
statestore.set(group.getBase(), node, msg, 'label', updates.label)
|
|
19
26
|
}
|
|
20
27
|
if (typeof updates.gtype !== 'undefined') {
|
|
21
28
|
// dynamically set "gauge type" property
|
|
@@ -27,7 +27,14 @@
|
|
|
27
27
|
topicType: { value: 'msg' },
|
|
28
28
|
min: { value: 0, required: true, validate: RED.validators.number() },
|
|
29
29
|
max: { value: 10, required: true, validate: RED.validators.number() },
|
|
30
|
-
step: {
|
|
30
|
+
step: {
|
|
31
|
+
value: 1,
|
|
32
|
+
validate: function (v) {
|
|
33
|
+
const isValid = RED.validators.number()(v) && v > 0
|
|
34
|
+
$('#node-input-step').toggleClass('input-error', !isValid)
|
|
35
|
+
return isValid
|
|
36
|
+
}
|
|
37
|
+
},
|
|
31
38
|
tooltip: { value: '' },
|
|
32
39
|
passthru: { value: true },
|
|
33
40
|
sendOnBlur: { value: true },
|
|
@@ -36,7 +43,8 @@
|
|
|
36
43
|
clearable: { value: false },
|
|
37
44
|
icon: { value: '' },
|
|
38
45
|
iconPosition: { value: 'left' },
|
|
39
|
-
iconInnerPosition: { value: 'inside' }
|
|
46
|
+
iconInnerPosition: { value: 'inside' },
|
|
47
|
+
spinner: { value: 'default' }
|
|
40
48
|
},
|
|
41
49
|
inputs: 1,
|
|
42
50
|
outputs: 1,
|
|
@@ -101,6 +109,10 @@
|
|
|
101
109
|
if (!this.iconInnerPosition) {
|
|
102
110
|
$('#node-input-iconInnerPosition').val('inside')
|
|
103
111
|
}
|
|
112
|
+
|
|
113
|
+
if (!this.spinner) {
|
|
114
|
+
$('#node-input-spinner').val('default')
|
|
115
|
+
}
|
|
104
116
|
},
|
|
105
117
|
label: function () {
|
|
106
118
|
return this.name || (~this.label.indexOf('{' + '{') ? null : this.label) || this.mode + ' input'
|
|
@@ -164,6 +176,13 @@
|
|
|
164
176
|
</div>
|
|
165
177
|
</div>
|
|
166
178
|
</div>
|
|
179
|
+
<div class="form-row">
|
|
180
|
+
<label for="node-input-spinner">Spinner</label>
|
|
181
|
+
<select id="node-input-spinner">
|
|
182
|
+
<option value="default">Inline</option>
|
|
183
|
+
<option value="stacked">Stacked</option>
|
|
184
|
+
</select>
|
|
185
|
+
</div>
|
|
167
186
|
<div class="form-row">
|
|
168
187
|
<label for="node-input-className"><i class="fa fa-code"></i> Class</label>
|
|
169
188
|
<div style="display: inline;">
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
const datastore = require('../store/data.js')
|
|
2
|
+
const statestore = require('../store/state.js')
|
|
3
|
+
const { appendTopic } = require('../utils/index.js')
|
|
2
4
|
|
|
3
5
|
module.exports = function (RED) {
|
|
4
6
|
function NumberInputNode (config) {
|
|
@@ -15,6 +17,37 @@ module.exports = function (RED) {
|
|
|
15
17
|
|
|
16
18
|
const evts = {
|
|
17
19
|
onChange: true,
|
|
20
|
+
beforeSend: async function (msg) {
|
|
21
|
+
const updates = msg.ui_update
|
|
22
|
+
if (updates) {
|
|
23
|
+
if (typeof updates.label !== 'undefined') {
|
|
24
|
+
// dynamically set "label" property
|
|
25
|
+
statestore.set(group.getBase(), node, msg, 'label', updates.label)
|
|
26
|
+
}
|
|
27
|
+
if (typeof updates.clearable !== 'undefined') {
|
|
28
|
+
// dynamically set "clearable" property
|
|
29
|
+
statestore.set(group.getBase(), node, msg, 'clearable', updates.clearable)
|
|
30
|
+
}
|
|
31
|
+
if (typeof updates.icon !== 'undefined') {
|
|
32
|
+
// dynamically set "icon" property
|
|
33
|
+
statestore.set(group.getBase(), node, msg, 'icon', updates.icon)
|
|
34
|
+
}
|
|
35
|
+
if (typeof updates.iconPosition !== 'undefined') {
|
|
36
|
+
// dynamically set "iconPosition" property
|
|
37
|
+
statestore.set(group.getBase(), node, msg, 'iconPosition', updates.iconPosition)
|
|
38
|
+
}
|
|
39
|
+
if (typeof updates.iconInnerPosition !== 'undefined') {
|
|
40
|
+
// dynamically set "iconInnerPosition" property
|
|
41
|
+
statestore.set(group.getBase(), node, msg, 'iconInnerPosition', updates.iconInnerPosition)
|
|
42
|
+
}
|
|
43
|
+
if (typeof updates.spinner !== 'undefined') {
|
|
44
|
+
// dynamically set "spinner" property
|
|
45
|
+
statestore.set(group.getBase(), node, msg, 'spinner', updates.spinner)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
msg = await appendTopic(RED, config, node, msg)
|
|
49
|
+
return msg
|
|
50
|
+
},
|
|
18
51
|
onInput: function (msg, send) {
|
|
19
52
|
// store the latest msg passed to node
|
|
20
53
|
datastore.save(group.getBase(), node, msg)
|