@devicechain/widgets 0.23.0 → 0.24.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/README.md +8 -3
- package/dist/aggregate-fold.d.ts +3 -2
- package/dist/aggregate-strings.d.ts +1 -0
- package/dist/alarm-strings.d.ts +18 -0
- package/dist/binding-policy.d.ts +4 -0
- package/dist/bound-devices-notice.d.ts +30 -0
- package/dist/builtin-descriptors.d.ts +290 -249
- package/dist/builtin-option-docs.d.ts +2 -0
- package/dist/builtin-registry.d.ts +249 -226
- package/dist/category-geometry.d.ts +1 -0
- package/dist/chunks/{aggregate-feed-BD3CHNFU.js → aggregate-feed-4FSBQYJL.js} +39 -11
- package/dist/chunks/aggregate-feed-4FSBQYJL.js.map +7 -0
- package/dist/chunks/{aggregate-widgets-HZQI5HTX.js → aggregate-widgets-2ZQBW3YF.js} +376 -182
- package/dist/chunks/aggregate-widgets-2ZQBW3YF.js.map +7 -0
- package/dist/chunks/alarm-widgets-X4PX5MYJ.js +72 -0
- package/dist/chunks/alarm-widgets-X4PX5MYJ.js.map +7 -0
- package/dist/chunks/chunk-546TK2QG.js +722 -0
- package/dist/chunks/chunk-546TK2QG.js.map +7 -0
- package/dist/chunks/{chunk-WBKHYZU2.js → chunk-62CHYCHI.js} +6 -62
- package/dist/chunks/chunk-62CHYCHI.js.map +7 -0
- package/dist/chunks/chunk-BMFQOTYG.js +41 -0
- package/dist/chunks/chunk-BMFQOTYG.js.map +7 -0
- package/dist/chunks/{chunk-2D7JNKFE.js → chunk-JFH4QMLA.js} +28 -4
- package/dist/chunks/chunk-JFH4QMLA.js.map +7 -0
- package/dist/chunks/chunk-QMGKB6J3.js +84 -0
- package/dist/chunks/chunk-QMGKB6J3.js.map +7 -0
- package/dist/chunks/chunk-XNEBAY4J.js +19 -0
- package/dist/chunks/chunk-XNEBAY4J.js.map +7 -0
- package/dist/chunks/chunk-YYJV54BV.js +58 -0
- package/dist/chunks/chunk-YYJV54BV.js.map +7 -0
- package/dist/chunks/compare-feed-AY3CVKUZ.js +346 -0
- package/dist/chunks/compare-feed-AY3CVKUZ.js.map +7 -0
- package/dist/chunks/{control-widgets-3V2LSSRF.js → control-widgets-UCTJJJ2D.js} +267 -78
- package/dist/chunks/control-widgets-UCTJJJ2D.js.map +7 -0
- package/dist/chunks/event-markers-feed-GEGTIHXT.js +373 -0
- package/dist/chunks/event-markers-feed-GEGTIHXT.js.map +7 -0
- package/dist/chunks/{fleet-feed-5QGDLOV5.js → fleet-feed-2SKDR6ZQ.js} +47 -8
- package/dist/chunks/fleet-feed-2SKDR6ZQ.js.map +7 -0
- package/dist/chunks/presence-widgets-2LIUKN4Y.js +350 -0
- package/dist/chunks/presence-widgets-2LIUKN4Y.js.map +7 -0
- package/dist/command-control-strings.d.ts +5 -0
- package/dist/compare-feed.d.ts +13 -0
- package/dist/compare-model.d.ts +38 -0
- package/dist/compare-strings.d.ts +13 -0
- package/dist/documented-descriptors.d.ts +4826 -0
- package/dist/event-markers-feed.d.ts +11 -0
- package/dist/event-markers-model.d.ts +38 -0
- package/dist/event-markers-strings.d.ts +20 -0
- package/dist/event-markers-types.d.ts +7 -0
- package/dist/fleet-count-model.d.ts +13 -0
- package/dist/fleet-feed.d.ts +1 -0
- package/dist/fleet-model.d.ts +1 -0
- package/dist/fleet-strings.d.ts +11 -0
- package/dist/index.d.ts +6 -3
- package/dist/index.js +946 -398
- package/dist/index.js.map +4 -4
- package/dist/presence-feed.d.ts +24 -0
- package/dist/presence-model.d.ts +13 -0
- package/dist/presence-strings.d.ts +19 -0
- package/dist/sparkline.d.ts +23 -0
- package/dist/use-bound-devices.d.ts +26 -0
- package/dist/widgets/aggregate-lazy.d.ts +81 -46
- package/dist/widgets/aggregate-widgets.d.ts +1 -0
- package/dist/widgets/alarm-grouped.d.ts +17 -0
- package/dist/widgets/alarm-lazy.d.ts +63 -16
- package/dist/widgets/alarm-severity.d.ts +8 -0
- package/dist/widgets/alarm-table.d.ts +2 -0
- package/dist/widgets/alarm-type-tabs.d.ts +10 -0
- package/dist/widgets/alarm-widgets.d.ts +2 -0
- package/dist/widgets/command-stepper.d.ts +22 -0
- package/dist/widgets/control-lazy.d.ts +16 -24
- package/dist/widgets/device-status.d.ts +4 -0
- package/dist/widgets/fleet-count.d.ts +2 -0
- package/dist/widgets/gauge.d.ts +2 -15
- package/dist/widgets/image.d.ts +2 -6
- package/dist/widgets/label.d.ts +2 -6
- package/dist/widgets/latest-card.d.ts +2 -13
- package/dist/widgets/lazy-chunk.d.ts +7 -2
- package/dist/widgets/level-lazy.d.ts +14 -96
- package/dist/widgets/map.d.ts +8 -5
- package/dist/widgets/online-doughnut.d.ts +2 -0
- package/dist/widgets/presence-lazy.d.ts +27 -0
- package/dist/widgets/presence-widgets.d.ts +3 -0
- package/dist/widgets/selection-lazy.d.ts +2 -4
- package/dist/widgets/table-lazy.d.ts +2 -7
- package/dist/widgets/time-series-chart.d.ts +62 -12
- package/package.json +13 -13
- package/dist/chunks/aggregate-feed-BD3CHNFU.js.map +0 -7
- package/dist/chunks/aggregate-widgets-HZQI5HTX.js.map +0 -7
- package/dist/chunks/alarm-widgets-7UY6MIYZ.js +0 -9
- package/dist/chunks/alarm-widgets-7UY6MIYZ.js.map +0 -7
- package/dist/chunks/chunk-2D7JNKFE.js.map +0 -7
- package/dist/chunks/chunk-6OGI4UFJ.js +0 -367
- package/dist/chunks/chunk-6OGI4UFJ.js.map +0 -7
- package/dist/chunks/chunk-WBKHYZU2.js.map +0 -7
- package/dist/chunks/control-widgets-3V2LSSRF.js.map +0 -7
- package/dist/chunks/fleet-feed-5QGDLOV5.js.map +0 -7
package/dist/index.js
CHANGED
|
@@ -1,24 +1,30 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Table
|
|
3
3
|
} from "./chunks/chunk-USRYKW2J.js";
|
|
4
|
+
import {
|
|
5
|
+
ChunkLoadingFrame,
|
|
6
|
+
lazyChunk
|
|
7
|
+
} from "./chunks/chunk-BMFQOTYG.js";
|
|
4
8
|
import {
|
|
5
9
|
alarmSubscription,
|
|
6
10
|
commandSubscription,
|
|
11
|
+
groupsAlarmsByDeviceType,
|
|
12
|
+
measurementIsMembersOnly,
|
|
7
13
|
measurementSpan,
|
|
8
14
|
measurementWindow,
|
|
9
|
-
membersMode
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
} from "./chunks/chunk-BRH66T5F.js";
|
|
15
|
+
membersMode,
|
|
16
|
+
presenceMode,
|
|
17
|
+
wantsEventMarkers
|
|
18
|
+
} from "./chunks/chunk-JFH4QMLA.js";
|
|
14
19
|
import {
|
|
15
20
|
AlarmCount,
|
|
21
|
+
AlarmSeverity,
|
|
16
22
|
AlarmTable,
|
|
17
23
|
highestSeverity,
|
|
18
24
|
severityColor,
|
|
19
25
|
severityLabel,
|
|
20
26
|
severityRank
|
|
21
|
-
} from "./chunks/chunk-
|
|
27
|
+
} from "./chunks/chunk-546TK2QG.js";
|
|
22
28
|
import {
|
|
23
29
|
CommandButton,
|
|
24
30
|
buildPayload,
|
|
@@ -30,6 +36,12 @@ import {
|
|
|
30
36
|
parseParameterSchema,
|
|
31
37
|
validateParams
|
|
32
38
|
} from "./chunks/chunk-XSLFHCNI.js";
|
|
39
|
+
import {
|
|
40
|
+
useHeld
|
|
41
|
+
} from "./chunks/chunk-XNEBAY4J.js";
|
|
42
|
+
import {
|
|
43
|
+
accessStrings
|
|
44
|
+
} from "./chunks/chunk-BRH66T5F.js";
|
|
33
45
|
import {
|
|
34
46
|
EntitySelector
|
|
35
47
|
} from "./chunks/chunk-FM7OI5TQ.js";
|
|
@@ -64,7 +76,7 @@ import {
|
|
|
64
76
|
WidgetTimeRangeProvider,
|
|
65
77
|
WidgetTokenStyles
|
|
66
78
|
} from "@devicechain/widget-sdk";
|
|
67
|
-
import { Fragment, useCallback as useCallback2, useEffect as
|
|
79
|
+
import { Fragment, useCallback as useCallback2, useEffect as useEffect3, useLayoutEffect, useMemo as useMemo5, useRef as useRef2, useState as useState4 } from "react";
|
|
68
80
|
|
|
69
81
|
// src/connected-widget.tsx
|
|
70
82
|
import {
|
|
@@ -79,22 +91,7 @@ import {
|
|
|
79
91
|
useWidgetTimeRange as useWidgetTimeRange2
|
|
80
92
|
} from "@devicechain/widget-sdk";
|
|
81
93
|
import { isForbiddenError } from "@devicechain/client";
|
|
82
|
-
import { useEffect as
|
|
83
|
-
|
|
84
|
-
// src/use-held.ts
|
|
85
|
-
import { useState } from "react";
|
|
86
|
-
function useHeld(value, hold, ready) {
|
|
87
|
-
const [held, setHeld] = useState(void 0);
|
|
88
|
-
if (!hold) {
|
|
89
|
-
if (held !== void 0) setHeld(void 0);
|
|
90
|
-
return value;
|
|
91
|
-
}
|
|
92
|
-
if (held === void 0 || ready(held.value) !== ready(value)) {
|
|
93
|
-
setHeld({ value });
|
|
94
|
-
return value;
|
|
95
|
-
}
|
|
96
|
-
return held.value;
|
|
97
|
-
}
|
|
94
|
+
import { useEffect as useEffect2, useMemo as useMemo4, useState as useState3 } from "react";
|
|
98
95
|
|
|
99
96
|
// src/builtin-registry.ts
|
|
100
97
|
import { createWidgetRegistry } from "@devicechain/widget-sdk";
|
|
@@ -108,15 +105,14 @@ import {
|
|
|
108
105
|
createWidgetCatalog,
|
|
109
106
|
defineWidgetDescriptor
|
|
110
107
|
} from "@devicechain/dashboards";
|
|
108
|
+
var defineRuntimeDescriptor = defineWidgetDescriptor;
|
|
111
109
|
var TITLE = {
|
|
112
110
|
kind: "string",
|
|
113
|
-
labelId: "widgetLabelTitle"
|
|
114
|
-
doc: "Heading shown in the widget frame. Blank hides the frame heading."
|
|
111
|
+
labelId: "widgetLabelTitle"
|
|
115
112
|
};
|
|
116
113
|
var TITLE_OR_MEASUREMENT = {
|
|
117
114
|
kind: "string",
|
|
118
|
-
labelId: "widgetLabelTitle"
|
|
119
|
-
doc: "Heading shown in the widget frame. Defaults to the displayed measurement name."
|
|
115
|
+
labelId: "widgetLabelTitle"
|
|
120
116
|
};
|
|
121
117
|
var PRECISION = {
|
|
122
118
|
kind: "number",
|
|
@@ -124,21 +120,18 @@ var PRECISION = {
|
|
|
124
120
|
min: 0,
|
|
125
121
|
max: 100,
|
|
126
122
|
labelId: "widgetLabelPrecision",
|
|
127
|
-
helpId: "widgetHintPrecision"
|
|
128
|
-
doc: "Decimal places to round displayed values to. Unset rounds to at most 3 decimals (4 significant digits under 1)."
|
|
123
|
+
helpId: "widgetHintPrecision"
|
|
129
124
|
};
|
|
130
125
|
var THRESHOLDS = {
|
|
131
126
|
kind: "list",
|
|
132
127
|
maxItems: 12,
|
|
133
128
|
labelId: "widgetLabelThresholds",
|
|
134
129
|
helpId: "widgetHintThresholds",
|
|
135
|
-
doc: "Severity bands over the value. Each entry starts a band at its value that runs to the next entry; below the first, and in a normal band, the widget keeps its own colour.",
|
|
136
130
|
item: {
|
|
137
131
|
value: {
|
|
138
132
|
kind: "number",
|
|
139
133
|
required: true,
|
|
140
|
-
labelId: "widgetLabelThresholdValue"
|
|
141
|
-
doc: "The value at which this band starts."
|
|
134
|
+
labelId: "widgetLabelThresholdValue"
|
|
142
135
|
},
|
|
143
136
|
level: {
|
|
144
137
|
kind: "enum",
|
|
@@ -152,91 +145,78 @@ var THRESHOLDS = {
|
|
|
152
145
|
major: "widgetSeverityMajor",
|
|
153
146
|
critical: "widgetSeverityCritical"
|
|
154
147
|
},
|
|
155
|
-
placeholderId: "widgetPlaceholderThresholdLevel"
|
|
156
|
-
doc: "The severity of this band. The theme decides the colour; normal has none."
|
|
148
|
+
placeholderId: "widgetPlaceholderThresholdLevel"
|
|
157
149
|
},
|
|
158
150
|
label: {
|
|
159
151
|
kind: "string",
|
|
160
|
-
labelId: "widgetLabelThresholdLabel"
|
|
161
|
-
doc: "Text shown on the chart line for this threshold. Defaults to its value."
|
|
152
|
+
labelId: "widgetLabelThresholdLabel"
|
|
162
153
|
}
|
|
163
154
|
}
|
|
164
155
|
};
|
|
165
156
|
var FLASH_ON_CHANGE = {
|
|
166
157
|
kind: "boolean",
|
|
167
158
|
labelId: "widgetFlashOnChange",
|
|
168
|
-
helpId: "widgetFlashOnChangeHint"
|
|
169
|
-
doc: "Briefly tint a value green on a rise and red on a fall when it changes."
|
|
159
|
+
helpId: "widgetFlashOnChangeHint"
|
|
170
160
|
};
|
|
171
161
|
var WINDOW = {
|
|
172
162
|
kind: "number",
|
|
173
163
|
integer: true,
|
|
174
164
|
min: 1,
|
|
175
165
|
labelId: "widgetLabelWindow",
|
|
176
|
-
helpId: "widgetHintWindow"
|
|
177
|
-
doc: "Samples retained across ALL of the widget's measurements before the oldest are dropped. Bounds memory; only the chart draws them. Default 300."
|
|
166
|
+
helpId: "widgetHintWindow"
|
|
178
167
|
};
|
|
179
168
|
var STALE_AFTER_SECONDS = {
|
|
180
169
|
kind: "number",
|
|
181
170
|
integer: true,
|
|
182
171
|
min: 1,
|
|
183
172
|
labelId: "widgetLabelStaleAfter",
|
|
184
|
-
helpId: "widgetHintStaleAfter"
|
|
185
|
-
doc: "Seconds after which the newest sample is called stale: the value is greyed out and badged. Unset shows the sample age only and never marks the widget stale."
|
|
173
|
+
helpId: "widgetHintStaleAfter"
|
|
186
174
|
};
|
|
187
175
|
var UNIT = {
|
|
188
176
|
kind: "string",
|
|
189
|
-
labelId: "widgetLabelUnit"
|
|
190
|
-
doc: "Unit suffix shown beside the value."
|
|
177
|
+
labelId: "widgetLabelUnit"
|
|
191
178
|
};
|
|
192
179
|
var SCALE_MIN = {
|
|
193
180
|
kind: "number",
|
|
194
181
|
required: true,
|
|
195
182
|
labelId: "widgetLabelMin",
|
|
196
|
-
helpId: "widgetHintScaleMin"
|
|
197
|
-
doc: "Value at the empty end of the scale. Required: the widget does not guess a range."
|
|
183
|
+
helpId: "widgetHintScaleMin"
|
|
198
184
|
};
|
|
199
185
|
var SCALE_MAX = {
|
|
200
186
|
kind: "number",
|
|
201
187
|
required: true,
|
|
202
188
|
labelId: "widgetLabelMax",
|
|
203
|
-
helpId: "widgetHintScaleMax"
|
|
204
|
-
doc: "Value at the full end of the scale. Required, and above min."
|
|
189
|
+
helpId: "widgetHintScaleMax"
|
|
205
190
|
};
|
|
206
191
|
var CONTROL_COMMAND_NAME = {
|
|
207
192
|
kind: "string",
|
|
208
193
|
required: true,
|
|
209
194
|
labelId: "widgetCommandHeading",
|
|
210
195
|
helpId: "widgetCommandFieldHint",
|
|
211
|
-
control: "command-vocabulary"
|
|
212
|
-
doc: "Command key issued to the target device. Without it the control cannot send."
|
|
196
|
+
control: "command-vocabulary"
|
|
213
197
|
};
|
|
214
198
|
var CONTROL_COMMAND_LABEL = {
|
|
215
199
|
kind: "string",
|
|
216
200
|
labelId: "widgetCommandHeading",
|
|
217
201
|
helpId: "widgetCommandFieldHint",
|
|
218
|
-
control: "command-vocabulary"
|
|
219
|
-
doc: "Name of the control for assistive technology. Defaults to the command key."
|
|
202
|
+
control: "command-vocabulary"
|
|
220
203
|
};
|
|
221
204
|
var CONTROL_PARAMETER_SCHEMA = {
|
|
222
205
|
kind: "string",
|
|
223
206
|
format: "json",
|
|
224
207
|
labelId: "widgetCommandHeading",
|
|
225
208
|
helpId: "widgetCommandFieldHint",
|
|
226
|
-
control: "command-vocabulary"
|
|
227
|
-
doc: "The command's parameter descriptors, baked in as JSON at author time. Gives the control its range and its refusals."
|
|
209
|
+
control: "command-vocabulary"
|
|
228
210
|
};
|
|
229
211
|
var CONTROL_PARAMETER = {
|
|
230
212
|
kind: "string",
|
|
231
213
|
labelId: "widgetLabelParameter",
|
|
232
|
-
helpId: "widgetHintControlParameter"
|
|
233
|
-
doc: "Which parameter of the command this control sets. May be left blank when the command has exactly one parameter of the right type."
|
|
214
|
+
helpId: "widgetHintControlParameter"
|
|
234
215
|
};
|
|
235
216
|
var MEASUREMENT = {
|
|
236
217
|
kind: "string",
|
|
237
218
|
labelId: "widgetLabelMeasurement",
|
|
238
|
-
helpId: "widgetHintMeasurement"
|
|
239
|
-
doc: "Which measurement to display. Defaults to the first the datasource selects."
|
|
219
|
+
helpId: "widgetHintMeasurement"
|
|
240
220
|
};
|
|
241
221
|
var ALARM_STATE = {
|
|
242
222
|
kind: "enum",
|
|
@@ -244,8 +224,7 @@ var ALARM_STATE = {
|
|
|
244
224
|
labelId: "widgetLabelState",
|
|
245
225
|
helpId: "widgetStateHint",
|
|
246
226
|
valueLabelIds: { ACTIVE: "widgetAlarmStateActive", CLEARED: "widgetAlarmStateCleared" },
|
|
247
|
-
placeholderId: "widgetPlaceholderAny"
|
|
248
|
-
doc: "Show only alarms in this state. Unset shows every state."
|
|
227
|
+
placeholderId: "widgetPlaceholderAny"
|
|
249
228
|
};
|
|
250
229
|
var ALARM_SEVERITY = {
|
|
251
230
|
kind: "enum",
|
|
@@ -253,8 +232,7 @@ var ALARM_SEVERITY = {
|
|
|
253
232
|
labelId: "widgetLabelSeverity",
|
|
254
233
|
helpId: "widgetSeverityHint",
|
|
255
234
|
valueLabelIds: { CRITICAL: "widgetAlarmSeverityCritical", MAJOR: "widgetAlarmSeverityMajor", MINOR: "widgetAlarmSeverityMinor", WARNING: "widgetAlarmSeverityWarning", INDETERMINATE: "widgetAlarmSeverityIndeterminate" },
|
|
256
|
-
placeholderId: "widgetPlaceholderAny"
|
|
257
|
-
doc: "Show only alarms at this severity. Unset shows every severity."
|
|
235
|
+
placeholderId: "widgetPlaceholderAny"
|
|
258
236
|
};
|
|
259
237
|
var ALARM_ACKNOWLEDGED = {
|
|
260
238
|
kind: "enum",
|
|
@@ -262,15 +240,13 @@ var ALARM_ACKNOWLEDGED = {
|
|
|
262
240
|
labelId: "widgetLabelAcknowledged",
|
|
263
241
|
helpId: "widgetAcknowledgedHint",
|
|
264
242
|
valueLabelIds: { true: "widgetAlarmAckAcknowledged", false: "widgetAlarmAckUnacknowledged" },
|
|
265
|
-
placeholderId: "widgetPlaceholderAny"
|
|
266
|
-
doc: "Show only acknowledged ('true') or unacknowledged ('false') alarms. Unset shows both."
|
|
243
|
+
placeholderId: "widgetPlaceholderAny"
|
|
267
244
|
};
|
|
268
245
|
var SELECTION_TARGET = {
|
|
269
246
|
kind: "string",
|
|
270
247
|
labelId: "widgetLabelTargetSlot",
|
|
271
248
|
helpId: "widgetTargetSlotHint",
|
|
272
|
-
control: "slot-target"
|
|
273
|
-
doc: "Name of the slot this widget re-points when the viewer picks an entity."
|
|
249
|
+
control: "slot-target"
|
|
274
250
|
};
|
|
275
251
|
var VERSION = "1.0.0";
|
|
276
252
|
var ALL_SELECTORS = ["device", "anchor", "slot"];
|
|
@@ -281,38 +257,69 @@ var ALARM_FILTERS = {
|
|
|
281
257
|
severity: { option: "severity" },
|
|
282
258
|
acknowledged: { option: "acknowledged" }
|
|
283
259
|
};
|
|
260
|
+
var MARK_ALARMS = {
|
|
261
|
+
kind: "boolean",
|
|
262
|
+
labelId: "widgetLabelMarkAlarms",
|
|
263
|
+
helpId: "widgetHintMarkAlarms"
|
|
264
|
+
};
|
|
265
|
+
var MARK_ALARMS_SCOPE = {
|
|
266
|
+
kind: "enum",
|
|
267
|
+
values: ["series", "device"],
|
|
268
|
+
labelId: "widgetLabelMarkAlarmsScope",
|
|
269
|
+
helpId: "widgetHintMarkAlarmsScope",
|
|
270
|
+
valueLabelIds: { series: "widgetMarkAlarmsScopeSeries", device: "widgetMarkAlarmsScopeDevice" },
|
|
271
|
+
placeholderId: "widgetPlaceholderWholeDevice"
|
|
272
|
+
};
|
|
273
|
+
var MARK_COMMANDS = {
|
|
274
|
+
kind: "boolean",
|
|
275
|
+
labelId: "widgetLabelMarkCommands",
|
|
276
|
+
helpId: "widgetHintMarkCommands"
|
|
277
|
+
};
|
|
278
|
+
var CHART_AXIS_MIN = {
|
|
279
|
+
kind: "number",
|
|
280
|
+
labelId: "widgetLabelMin",
|
|
281
|
+
helpId: "widgetHintChartAxisMin"
|
|
282
|
+
};
|
|
283
|
+
var CHART_AXIS_MAX = {
|
|
284
|
+
kind: "number",
|
|
285
|
+
labelId: "widgetLabelMax",
|
|
286
|
+
helpId: "widgetHintChartAxisMax"
|
|
287
|
+
};
|
|
288
|
+
var MAX_SERIES = {
|
|
289
|
+
kind: "number",
|
|
290
|
+
integer: true,
|
|
291
|
+
min: 1,
|
|
292
|
+
labelId: "widgetLabelMaxSeries",
|
|
293
|
+
helpId: "widgetHintMaxSeries"
|
|
294
|
+
};
|
|
284
295
|
var WINDOW_SECONDS = {
|
|
285
296
|
kind: "number",
|
|
286
297
|
integer: true,
|
|
287
298
|
min: 60,
|
|
288
299
|
max: 604800,
|
|
289
300
|
labelId: "widgetLabelWindowSeconds",
|
|
290
|
-
helpId: "widgetHintWindowSeconds"
|
|
291
|
-
doc: "Seconds of history the widget covers, back from now. Leave unset to follow the board\u2019s time range; set it to pin this widget to a fixed span that the viewer\u2019s range picker does not change. 60 to 604800."
|
|
301
|
+
helpId: "widgetHintWindowSeconds"
|
|
292
302
|
};
|
|
293
303
|
var CATEGORY_SORT = {
|
|
294
304
|
kind: "enum",
|
|
295
305
|
values: ["none", "ascending", "descending"],
|
|
296
306
|
labelId: "widgetLabelSort",
|
|
297
307
|
valueLabelIds: { none: "widgetSortNone", ascending: "widgetSortAscending", descending: "widgetSortDescending" },
|
|
298
|
-
placeholderId: "widgetPlaceholderDefault"
|
|
299
|
-
doc: "Order of the categories. Default: as the data source lists them."
|
|
308
|
+
placeholderId: "widgetPlaceholderDefault"
|
|
300
309
|
};
|
|
301
310
|
var FLEET_MEASUREMENT = {
|
|
302
311
|
kind: "string",
|
|
303
312
|
required: true,
|
|
304
|
-
labelId: "widgetLabelMeasurement"
|
|
305
|
-
doc: "The measurement column this entry applies to."
|
|
313
|
+
labelId: "widgetLabelMeasurement"
|
|
306
314
|
};
|
|
307
315
|
var FLEET_COLUMNS = {
|
|
308
316
|
kind: "list",
|
|
309
317
|
maxItems: 24,
|
|
310
318
|
labelId: "widgetLabelColumns",
|
|
311
319
|
helpId: "widgetHintColumns",
|
|
312
|
-
doc: "Heading, unit and precision per measurement column; a column with none shows its name.",
|
|
313
320
|
item: {
|
|
314
321
|
measurement: FLEET_MEASUREMENT,
|
|
315
|
-
label: { kind: "string", labelId: "widgetLabelColumnHeading"
|
|
322
|
+
label: { kind: "string", labelId: "widgetLabelColumnHeading" },
|
|
316
323
|
unit: { ...UNIT },
|
|
317
324
|
precision: { ...PRECISION }
|
|
318
325
|
}
|
|
@@ -325,29 +332,47 @@ var FLEET_THRESHOLDS = {
|
|
|
325
332
|
}
|
|
326
333
|
};
|
|
327
334
|
var builtinWidgetDescriptors = {
|
|
328
|
-
"timeseries-chart":
|
|
335
|
+
"timeseries-chart": defineRuntimeDescriptor({
|
|
329
336
|
id: "timeseries-chart",
|
|
330
337
|
version: VERSION,
|
|
331
338
|
sdkApiVersion: 1,
|
|
332
339
|
optionsVersion: 2,
|
|
333
340
|
display: { title: "Timeseries chart", category: "Telemetry", titleId: "widgetTypeTimeseriesChart", categoryId: "widgetCategoryTelemetry" },
|
|
334
341
|
channel: "measurement",
|
|
335
|
-
|
|
336
|
-
|
|
342
|
+
// ALL_SELECTORS because of the compare mode (groupBy device): a group bound with the default mode
|
|
343
|
+
// is refused in words at runtime, exactly as for the bar chart.
|
|
344
|
+
datasource: { mode: "required", selectors: ALL_SELECTORS },
|
|
345
|
+
binding: { windowSeconds: { option: "windowSeconds" }, members: { option: "groupBy", equals: "device" } },
|
|
337
346
|
options: {
|
|
338
347
|
title: TITLE,
|
|
339
348
|
unit: UNIT,
|
|
340
349
|
precision: PRECISION,
|
|
341
350
|
thresholds: THRESHOLDS,
|
|
342
351
|
staleAfterSeconds: STALE_AFTER_SECONDS,
|
|
343
|
-
windowSeconds: WINDOW_SECONDS
|
|
352
|
+
windowSeconds: WINDOW_SECONDS,
|
|
353
|
+
groupBy: {
|
|
354
|
+
kind: "enum",
|
|
355
|
+
values: ["measurement", "device"],
|
|
356
|
+
labelId: "widgetLabelSeriesBy",
|
|
357
|
+
helpId: "widgetHintSeriesBy",
|
|
358
|
+
valueLabelIds: { measurement: "widgetGroupByMeasurement", device: "widgetGroupByDevice" },
|
|
359
|
+
placeholderId: "widgetPlaceholderDefault"
|
|
360
|
+
},
|
|
361
|
+
measurement: MEASUREMENT,
|
|
362
|
+
maxSeries: MAX_SERIES,
|
|
363
|
+
markAlarms: MARK_ALARMS,
|
|
364
|
+
markAlarmsScope: MARK_ALARMS_SCOPE,
|
|
365
|
+
markCommands: MARK_COMMANDS,
|
|
366
|
+
min: CHART_AXIS_MIN,
|
|
367
|
+
max: CHART_AXIS_MAX
|
|
344
368
|
},
|
|
345
|
-
|
|
369
|
+
constraints: [{ kind: "greater-than", key: "max", than: "min" }],
|
|
370
|
+
defaults: { title: "Timeseries chart", markAlarmsScope: "series" },
|
|
346
371
|
interactions: {},
|
|
347
372
|
freshness: true,
|
|
348
373
|
layout: { defaultSpan: { cols: 6, rows: 4 }, minSpan: { cols: 4, rows: 3 } }
|
|
349
374
|
}),
|
|
350
|
-
"latest-card":
|
|
375
|
+
"latest-card": defineRuntimeDescriptor({
|
|
351
376
|
id: "latest-card",
|
|
352
377
|
version: VERSION,
|
|
353
378
|
sdkApiVersion: 1,
|
|
@@ -361,8 +386,7 @@ var builtinWidgetDescriptors = {
|
|
|
361
386
|
measurement: {
|
|
362
387
|
kind: "string",
|
|
363
388
|
labelId: "widgetLabelMeasurement",
|
|
364
|
-
helpId: "widgetHintMeasurement"
|
|
365
|
-
doc: "Which measurement to display. Defaults to the first the datasource selects."
|
|
389
|
+
helpId: "widgetHintMeasurement"
|
|
366
390
|
},
|
|
367
391
|
unit: UNIT,
|
|
368
392
|
precision: PRECISION,
|
|
@@ -376,7 +400,7 @@ var builtinWidgetDescriptors = {
|
|
|
376
400
|
freshness: true,
|
|
377
401
|
layout: { defaultSpan: { cols: 3, rows: 2 }, minSpan: { cols: 3, rows: 2 }, maxSpan: { cols: 6, rows: 4 } }
|
|
378
402
|
}),
|
|
379
|
-
gauge:
|
|
403
|
+
gauge: defineRuntimeDescriptor({
|
|
380
404
|
id: "gauge",
|
|
381
405
|
version: VERSION,
|
|
382
406
|
sdkApiVersion: 1,
|
|
@@ -390,18 +414,15 @@ var builtinWidgetDescriptors = {
|
|
|
390
414
|
measurement: {
|
|
391
415
|
kind: "string",
|
|
392
416
|
labelId: "widgetLabelMeasurement",
|
|
393
|
-
helpId: "widgetHintMeasurement"
|
|
394
|
-
doc: "Which measurement to display. Defaults to the first the datasource selects."
|
|
417
|
+
helpId: "widgetHintMeasurement"
|
|
395
418
|
},
|
|
396
419
|
min: {
|
|
397
420
|
kind: "number",
|
|
398
|
-
labelId: "widgetLabelMin"
|
|
399
|
-
doc: "Low end of the gauge scale. Default 0."
|
|
421
|
+
labelId: "widgetLabelMin"
|
|
400
422
|
},
|
|
401
423
|
max: {
|
|
402
424
|
kind: "number",
|
|
403
|
-
labelId: "widgetLabelMax"
|
|
404
|
-
doc: "High end of the gauge scale. Default 100."
|
|
425
|
+
labelId: "widgetLabelMax"
|
|
405
426
|
},
|
|
406
427
|
unit: UNIT,
|
|
407
428
|
precision: PRECISION,
|
|
@@ -416,7 +437,7 @@ var builtinWidgetDescriptors = {
|
|
|
416
437
|
freshness: true,
|
|
417
438
|
layout: { defaultSpan: { cols: 3, rows: 3 }, minSpan: { cols: 3, rows: 3 }, maxSpan: { cols: 6, rows: 6 } }
|
|
418
439
|
}),
|
|
419
|
-
table:
|
|
440
|
+
table: defineRuntimeDescriptor({
|
|
420
441
|
id: "table",
|
|
421
442
|
version: VERSION,
|
|
422
443
|
sdkApiVersion: 1,
|
|
@@ -439,7 +460,7 @@ var builtinWidgetDescriptors = {
|
|
|
439
460
|
}),
|
|
440
461
|
// label and image are static: the `none` channel, no datasource, no subscription and no
|
|
441
462
|
// history seed.
|
|
442
|
-
label:
|
|
463
|
+
label: defineRuntimeDescriptor({
|
|
443
464
|
id: "label",
|
|
444
465
|
version: VERSION,
|
|
445
466
|
sdkApiVersion: 1,
|
|
@@ -453,30 +474,27 @@ var builtinWidgetDescriptors = {
|
|
|
453
474
|
text: {
|
|
454
475
|
kind: "string",
|
|
455
476
|
required: true,
|
|
456
|
-
labelId: "widgetLabelText"
|
|
457
|
-
doc: "The text to show. Rendered as plain text \u2014 markup is never interpreted."
|
|
477
|
+
labelId: "widgetLabelText"
|
|
458
478
|
},
|
|
459
479
|
align: {
|
|
460
480
|
kind: "enum",
|
|
461
481
|
values: ["left", "center", "right"],
|
|
462
482
|
labelId: "widgetLabelAlign",
|
|
463
483
|
valueLabelIds: { left: "widgetAlignLeft", center: "widgetAlignCenter", right: "widgetAlignRight" },
|
|
464
|
-
placeholderId: "widgetPlaceholderDefault"
|
|
465
|
-
doc: "Horizontal alignment of the text. Default center."
|
|
484
|
+
placeholderId: "widgetPlaceholderDefault"
|
|
466
485
|
},
|
|
467
486
|
fontSize: {
|
|
468
487
|
kind: "number",
|
|
469
488
|
min: 1,
|
|
470
489
|
labelId: "widgetLabelFontSize",
|
|
471
|
-
helpId: "widgetHintFontSize"
|
|
472
|
-
doc: "Text size in pixels at the comfortable density; it scales with the board density. Default 16."
|
|
490
|
+
helpId: "widgetHintFontSize"
|
|
473
491
|
}
|
|
474
492
|
},
|
|
475
493
|
defaults: { text: "New label" },
|
|
476
494
|
interactions: {},
|
|
477
495
|
layout: { defaultSpan: { cols: 3, rows: 1 }, minSpan: { cols: 1, rows: 1 }, maxSpan: { cols: 24, rows: 3 } }
|
|
478
496
|
}),
|
|
479
|
-
image:
|
|
497
|
+
image: defineRuntimeDescriptor({
|
|
480
498
|
id: "image",
|
|
481
499
|
version: VERSION,
|
|
482
500
|
sdkApiVersion: 1,
|
|
@@ -490,28 +508,25 @@ var builtinWidgetDescriptors = {
|
|
|
490
508
|
url: {
|
|
491
509
|
kind: "string",
|
|
492
510
|
required: true,
|
|
493
|
-
labelId: "widgetLabelImageUrl"
|
|
494
|
-
doc: "Source URL of the image."
|
|
511
|
+
labelId: "widgetLabelImageUrl"
|
|
495
512
|
},
|
|
496
513
|
alt: {
|
|
497
514
|
kind: "string",
|
|
498
|
-
labelId: "widgetLabelAltText"
|
|
499
|
-
doc: "Alternative text describing the image for assistive technology."
|
|
515
|
+
labelId: "widgetLabelAltText"
|
|
500
516
|
},
|
|
501
517
|
fit: {
|
|
502
518
|
kind: "enum",
|
|
503
519
|
values: ["contain", "cover", "fill"],
|
|
504
520
|
labelId: "widgetLabelFit",
|
|
505
521
|
valueLabelIds: { contain: "widgetFitContain", cover: "widgetFitCover", fill: "widgetFitFill" },
|
|
506
|
-
placeholderId: "widgetPlaceholderDefault"
|
|
507
|
-
doc: "How the image fills its box. Default contain."
|
|
522
|
+
placeholderId: "widgetPlaceholderDefault"
|
|
508
523
|
}
|
|
509
524
|
},
|
|
510
525
|
defaults: { title: "Image" },
|
|
511
526
|
interactions: {},
|
|
512
527
|
layout: { defaultSpan: { cols: 3, rows: 2 }, minSpan: { cols: 1, rows: 1 } }
|
|
513
528
|
}),
|
|
514
|
-
"alarm-table":
|
|
529
|
+
"alarm-table": defineRuntimeDescriptor({
|
|
515
530
|
id: "alarm-table",
|
|
516
531
|
version: VERSION,
|
|
517
532
|
sdkApiVersion: 1,
|
|
@@ -519,19 +534,37 @@ var builtinWidgetDescriptors = {
|
|
|
519
534
|
display: { title: "Alarm table", category: "Alarms", titleId: "widgetTypeAlarmTable", categoryId: "widgetCategoryAlarms" },
|
|
520
535
|
channel: "alarm",
|
|
521
536
|
datasource: { mode: "optional", selectors: ALL_SELECTORS },
|
|
522
|
-
|
|
537
|
+
// groupBy 'deviceType' turns the table into one tab per device type (plus All).
|
|
538
|
+
binding: { pageSize: { option: "maxRows", default: 50, min: 1 }, ...ALARM_FILTERS, groupBy: { option: "groupBy", equals: "deviceType" } },
|
|
523
539
|
options: {
|
|
524
540
|
title: TITLE,
|
|
525
541
|
state: ALARM_STATE,
|
|
526
542
|
severity: ALARM_SEVERITY,
|
|
527
543
|
acknowledged: ALARM_ACKNOWLEDGED,
|
|
544
|
+
groupBy: {
|
|
545
|
+
kind: "enum",
|
|
546
|
+
values: ["none", "deviceType"],
|
|
547
|
+
labelId: "widgetLabelAlarmGroupBy",
|
|
548
|
+
helpId: "widgetHintAlarmGroupBy",
|
|
549
|
+
valueLabelIds: { none: "widgetAlarmGroupByNone", deviceType: "widgetAlarmGroupByDeviceType" },
|
|
550
|
+
placeholderId: "widgetPlaceholderDefault"
|
|
551
|
+
},
|
|
552
|
+
deviceTypes: {
|
|
553
|
+
kind: "list",
|
|
554
|
+
maxItems: 24,
|
|
555
|
+
ordered: true,
|
|
556
|
+
labelId: "widgetLabelAlarmDeviceTypes",
|
|
557
|
+
helpId: "widgetHintAlarmDeviceTypes",
|
|
558
|
+
item: {
|
|
559
|
+
token: { kind: "string", control: "device-type", labelId: "widgetLabelAlarmDeviceTypeToken" }
|
|
560
|
+
}
|
|
561
|
+
},
|
|
528
562
|
maxRows: {
|
|
529
563
|
kind: "number",
|
|
530
564
|
integer: true,
|
|
531
565
|
min: 1,
|
|
532
566
|
labelId: "widgetLabelMaxRows",
|
|
533
|
-
helpId: "widgetMaxRowsAlarmHint"
|
|
534
|
-
doc: "Alarms loaded into the table. Default 50."
|
|
567
|
+
helpId: "widgetMaxRowsAlarmHint"
|
|
535
568
|
},
|
|
536
569
|
precision: PRECISION,
|
|
537
570
|
flashOnChange: FLASH_ON_CHANGE,
|
|
@@ -543,7 +576,7 @@ var builtinWidgetDescriptors = {
|
|
|
543
576
|
}),
|
|
544
577
|
// The count shows the SERVER total and reads a page only to sample the worst loaded
|
|
545
578
|
// severity, so its page size is a constant rather than an authorable option.
|
|
546
|
-
"alarm-count":
|
|
579
|
+
"alarm-count": defineRuntimeDescriptor({
|
|
547
580
|
id: "alarm-count",
|
|
548
581
|
version: VERSION,
|
|
549
582
|
sdkApiVersion: 1,
|
|
@@ -565,7 +598,45 @@ var builtinWidgetDescriptors = {
|
|
|
565
598
|
interactions: {},
|
|
566
599
|
layout: { defaultSpan: { cols: 3, rows: 2 }, minSpan: { cols: 2, rows: 2 }, maxSpan: { cols: 6, rows: 4 } }
|
|
567
600
|
}),
|
|
568
|
-
|
|
601
|
+
// Alarms by severity, from ONE grouped count read (device-management's per-severity counts, every
|
|
602
|
+
// originator, exact past any page). Not a mode of alarm-count: a different shape and size, and no
|
|
603
|
+
// severity filter. `deviceType` narrows it to the alarms on one type's devices.
|
|
604
|
+
"alarm-severity": defineRuntimeDescriptor({
|
|
605
|
+
id: "alarm-severity",
|
|
606
|
+
version: VERSION,
|
|
607
|
+
sdkApiVersion: 1,
|
|
608
|
+
optionsVersion: 1,
|
|
609
|
+
display: {
|
|
610
|
+
title: "Alarm severity",
|
|
611
|
+
category: "Alarms",
|
|
612
|
+
titleId: "widgetTypeAlarmSeverity",
|
|
613
|
+
categoryId: "widgetCategoryAlarms"
|
|
614
|
+
},
|
|
615
|
+
channel: "alarm",
|
|
616
|
+
datasource: { mode: "optional", selectors: ALL_SELECTORS },
|
|
617
|
+
binding: {
|
|
618
|
+
pageSize: { const: 1 },
|
|
619
|
+
state: { option: "state" },
|
|
620
|
+
acknowledged: { option: "acknowledged" },
|
|
621
|
+
countBySeverity: { const: true },
|
|
622
|
+
deviceType: { option: "deviceType" }
|
|
623
|
+
},
|
|
624
|
+
options: {
|
|
625
|
+
title: TITLE,
|
|
626
|
+
state: ALARM_STATE,
|
|
627
|
+
acknowledged: ALARM_ACKNOWLEDGED,
|
|
628
|
+
deviceType: {
|
|
629
|
+
kind: "string",
|
|
630
|
+
control: "device-type",
|
|
631
|
+
labelId: "widgetLabelAlarmSeverityType",
|
|
632
|
+
helpId: "widgetHintAlarmSeverityType"
|
|
633
|
+
}
|
|
634
|
+
},
|
|
635
|
+
defaults: { title: "Alarm severity", state: "ACTIVE" },
|
|
636
|
+
interactions: {},
|
|
637
|
+
layout: { defaultSpan: { cols: 4, rows: 2 }, minSpan: { cols: 3, rows: 2 }, maxSpan: { cols: 12, rows: 4 } }
|
|
638
|
+
}),
|
|
639
|
+
"command-button": defineRuntimeDescriptor({
|
|
569
640
|
id: "command-button",
|
|
570
641
|
version: VERSION,
|
|
571
642
|
sdkApiVersion: 1,
|
|
@@ -581,38 +652,34 @@ var builtinWidgetDescriptors = {
|
|
|
581
652
|
required: true,
|
|
582
653
|
labelId: "widgetCommandHeading",
|
|
583
654
|
helpId: "widgetCommandFieldHint",
|
|
584
|
-
control: "command-vocabulary"
|
|
585
|
-
doc: "Command key issued to the target device. Without it the widget cannot send."
|
|
655
|
+
control: "command-vocabulary"
|
|
586
656
|
},
|
|
587
657
|
commandLabel: {
|
|
588
658
|
kind: "string",
|
|
589
659
|
labelId: "widgetCommandHeading",
|
|
590
660
|
helpId: "widgetCommandFieldHint",
|
|
591
|
-
control: "command-vocabulary"
|
|
592
|
-
doc: "Text on the send button. Defaults to the command key."
|
|
661
|
+
control: "command-vocabulary"
|
|
593
662
|
},
|
|
594
663
|
parameterSchema: {
|
|
595
664
|
kind: "string",
|
|
596
665
|
format: "json",
|
|
597
666
|
labelId: "widgetCommandHeading",
|
|
598
667
|
helpId: "widgetCommandFieldHint",
|
|
599
|
-
control: "command-vocabulary"
|
|
600
|
-
doc: "The command's parameter descriptors, baked in as JSON at author time. Drives the typed form."
|
|
668
|
+
control: "command-vocabulary"
|
|
601
669
|
},
|
|
602
670
|
maxRows: {
|
|
603
671
|
kind: "number",
|
|
604
672
|
integer: true,
|
|
605
673
|
min: 1,
|
|
606
674
|
labelId: "widgetLabelMaxRows",
|
|
607
|
-
helpId: "widgetMaxRowsCommandHint"
|
|
608
|
-
doc: "Recent commands shown in the history. Default 20."
|
|
675
|
+
helpId: "widgetMaxRowsCommandHint"
|
|
609
676
|
}
|
|
610
677
|
},
|
|
611
678
|
defaults: { title: "Command button" },
|
|
612
679
|
interactions: { commandSend: true },
|
|
613
680
|
layout: { defaultSpan: { cols: 3, rows: 3 }, minSpan: { cols: 3, rows: 2 }, maxSpan: { cols: 6, rows: 6 } }
|
|
614
681
|
}),
|
|
615
|
-
"entity-selector":
|
|
682
|
+
"entity-selector": defineRuntimeDescriptor({
|
|
616
683
|
id: "entity-selector",
|
|
617
684
|
version: VERSION,
|
|
618
685
|
sdkApiVersion: 1,
|
|
@@ -630,7 +697,7 @@ var builtinWidgetDescriptors = {
|
|
|
630
697
|
// A select control is one line high, so its rows are pinned; it widens to fit long names.
|
|
631
698
|
layout: { defaultSpan: { cols: 3, rows: 1 }, minSpan: { cols: 3, rows: 1 }, maxSpan: { cols: 12, rows: 1 }, resize: "horizontal" }
|
|
632
699
|
}),
|
|
633
|
-
map:
|
|
700
|
+
map: defineRuntimeDescriptor({
|
|
634
701
|
id: "map",
|
|
635
702
|
version: VERSION,
|
|
636
703
|
sdkApiVersion: 1,
|
|
@@ -652,25 +719,26 @@ var builtinWidgetDescriptors = {
|
|
|
652
719
|
kind: "string",
|
|
653
720
|
labelId: "widgetLabelTileUrl",
|
|
654
721
|
helpId: "widgetTileUrlHint",
|
|
655
|
-
control: "basemap"
|
|
656
|
-
doc: "Raster tile URL template, e.g. https://tiles.example.com/{z}/{x}/{y}.png. Leave empty to inherit the tenant's basemap; setting one overrides it for this board only."
|
|
722
|
+
control: "basemap"
|
|
657
723
|
},
|
|
658
724
|
attribution: {
|
|
659
725
|
kind: "string",
|
|
660
726
|
labelId: "widgetLabelAttribution",
|
|
661
727
|
helpId: "widgetAttributionHint",
|
|
662
|
-
control: "basemap"
|
|
663
|
-
|
|
664
|
-
|
|
728
|
+
control: "basemap"
|
|
729
|
+
},
|
|
730
|
+
// Optional and additive: unset, a marker is only a mark. Set, clicking a marker re-points
|
|
731
|
+
// that slot at the device, exactly as a fleet-table row does.
|
|
732
|
+
selectionTarget: SELECTION_TARGET
|
|
665
733
|
},
|
|
666
734
|
defaults: { title: "Map" },
|
|
667
|
-
interactions: {},
|
|
735
|
+
interactions: { selection: true },
|
|
668
736
|
layout: { defaultSpan: { cols: 6, rows: 4 }, minSpan: { cols: 4, rows: 3 } }
|
|
669
737
|
}),
|
|
670
738
|
// ---- Levels and indicators ------------------------------------------------
|
|
671
739
|
// DOM/SVG single-value widgets on the measurement channel. A threshold band colours the fill
|
|
672
740
|
// or lamp; `normal` keeps the widget's neutral accent.
|
|
673
|
-
"linear-gauge":
|
|
741
|
+
"linear-gauge": defineRuntimeDescriptor({
|
|
674
742
|
id: "linear-gauge",
|
|
675
743
|
version: VERSION,
|
|
676
744
|
sdkApiVersion: 1,
|
|
@@ -689,16 +757,14 @@ var builtinWidgetDescriptors = {
|
|
|
689
757
|
values: ["bar", "thermometer"],
|
|
690
758
|
labelId: "widgetLabelLinearStyle",
|
|
691
759
|
valueLabelIds: { bar: "widgetLinearStyleBar", thermometer: "widgetLinearStyleThermometer" },
|
|
692
|
-
placeholderId: "widgetPlaceholderDefault"
|
|
693
|
-
doc: "A plain bar (default) or a thermometer: a vertical tube with a bulb. A thermometer is always vertical."
|
|
760
|
+
placeholderId: "widgetPlaceholderDefault"
|
|
694
761
|
},
|
|
695
762
|
orientation: {
|
|
696
763
|
kind: "enum",
|
|
697
764
|
values: ["horizontal", "vertical"],
|
|
698
765
|
labelId: "widgetLabelOrientation",
|
|
699
766
|
valueLabelIds: { horizontal: "widgetOrientationHorizontal", vertical: "widgetOrientationVertical" },
|
|
700
|
-
placeholderId: "widgetPlaceholderDefault"
|
|
701
|
-
doc: "Direction of a bar: horizontal (default) or vertical. Ignored by a thermometer."
|
|
767
|
+
placeholderId: "widgetPlaceholderDefault"
|
|
702
768
|
},
|
|
703
769
|
unit: UNIT,
|
|
704
770
|
precision: PRECISION,
|
|
@@ -712,7 +778,7 @@ var builtinWidgetDescriptors = {
|
|
|
712
778
|
freshness: true,
|
|
713
779
|
layout: { defaultSpan: { cols: 4, rows: 3 }, minSpan: { cols: 3, rows: 3 }, maxSpan: { cols: 8, rows: 8 } }
|
|
714
780
|
}),
|
|
715
|
-
"level-gauge":
|
|
781
|
+
"level-gauge": defineRuntimeDescriptor({
|
|
716
782
|
id: "level-gauge",
|
|
717
783
|
version: VERSION,
|
|
718
784
|
sdkApiVersion: 1,
|
|
@@ -731,8 +797,7 @@ var builtinWidgetDescriptors = {
|
|
|
731
797
|
values: ["value", "percent"],
|
|
732
798
|
labelId: "widgetLabelReadout",
|
|
733
799
|
valueLabelIds: { value: "widgetReadoutValue", percent: "widgetReadoutPercent" },
|
|
734
|
-
placeholderId: "widgetPlaceholderDefault"
|
|
735
|
-
doc: "What the readout shows: the value with its unit (default) or the percent of the scale."
|
|
800
|
+
placeholderId: "widgetPlaceholderDefault"
|
|
736
801
|
},
|
|
737
802
|
unit: UNIT,
|
|
738
803
|
precision: PRECISION,
|
|
@@ -746,7 +811,7 @@ var builtinWidgetDescriptors = {
|
|
|
746
811
|
freshness: true,
|
|
747
812
|
layout: { defaultSpan: { cols: 3, rows: 4 }, minSpan: { cols: 2, rows: 3 }, maxSpan: { cols: 6, rows: 8 } }
|
|
748
813
|
}),
|
|
749
|
-
battery:
|
|
814
|
+
battery: defineRuntimeDescriptor({
|
|
750
815
|
id: "battery",
|
|
751
816
|
version: VERSION,
|
|
752
817
|
sdkApiVersion: 1,
|
|
@@ -761,14 +826,12 @@ var builtinWidgetDescriptors = {
|
|
|
761
826
|
min: {
|
|
762
827
|
kind: "number",
|
|
763
828
|
labelId: "widgetLabelMin",
|
|
764
|
-
helpId: "widgetHintBatteryRange"
|
|
765
|
-
doc: "Value of an empty battery. Default 0 (the scale is percent unless you set min and max)."
|
|
829
|
+
helpId: "widgetHintBatteryRange"
|
|
766
830
|
},
|
|
767
831
|
max: {
|
|
768
832
|
kind: "number",
|
|
769
833
|
labelId: "widgetLabelMax",
|
|
770
|
-
helpId: "widgetHintBatteryRange"
|
|
771
|
-
doc: "Value of a full battery. Default 100 (the scale is percent unless you set min and max)."
|
|
834
|
+
helpId: "widgetHintBatteryRange"
|
|
772
835
|
},
|
|
773
836
|
unit: UNIT,
|
|
774
837
|
precision: PRECISION,
|
|
@@ -782,7 +845,7 @@ var builtinWidgetDescriptors = {
|
|
|
782
845
|
freshness: true,
|
|
783
846
|
layout: { defaultSpan: { cols: 3, rows: 2 }, minSpan: { cols: 2, rows: 2 }, maxSpan: { cols: 6, rows: 4 } }
|
|
784
847
|
}),
|
|
785
|
-
"status-light":
|
|
848
|
+
"status-light": defineRuntimeDescriptor({
|
|
786
849
|
id: "status-light",
|
|
787
850
|
version: VERSION,
|
|
788
851
|
sdkApiVersion: 1,
|
|
@@ -797,8 +860,7 @@ var builtinWidgetDescriptors = {
|
|
|
797
860
|
onAt: {
|
|
798
861
|
kind: "number",
|
|
799
862
|
labelId: "widgetLabelOnAt",
|
|
800
|
-
helpId: "widgetHintOnAt"
|
|
801
|
-
doc: "For an on/off signal: the lamp is lit at or above this value and dark below it. Unset keeps the lamp lit while a value is present, coloured by its threshold band."
|
|
863
|
+
helpId: "widgetHintOnAt"
|
|
802
864
|
},
|
|
803
865
|
unit: UNIT,
|
|
804
866
|
precision: PRECISION,
|
|
@@ -811,7 +873,7 @@ var builtinWidgetDescriptors = {
|
|
|
811
873
|
freshness: true,
|
|
812
874
|
layout: { defaultSpan: { cols: 2, rows: 2 }, minSpan: { cols: 2, rows: 2 }, maxSpan: { cols: 4, rows: 4 } }
|
|
813
875
|
}),
|
|
814
|
-
"signal-bars":
|
|
876
|
+
"signal-bars": defineRuntimeDescriptor({
|
|
815
877
|
id: "signal-bars",
|
|
816
878
|
version: VERSION,
|
|
817
879
|
sdkApiVersion: 1,
|
|
@@ -830,8 +892,7 @@ var builtinWidgetDescriptors = {
|
|
|
830
892
|
...THRESHOLDS,
|
|
831
893
|
maxItems: 8,
|
|
832
894
|
required: true,
|
|
833
|
-
helpId: "widgetHintSignalThresholds"
|
|
834
|
-
doc: "The steps of the signal, lowest first: one bar per entry, lit once the value reaches it and coloured by its level. At least two, at most eight."
|
|
895
|
+
helpId: "widgetHintSignalThresholds"
|
|
835
896
|
},
|
|
836
897
|
staleAfterSeconds: STALE_AFTER_SECONDS,
|
|
837
898
|
window: WINDOW
|
|
@@ -844,7 +905,7 @@ var builtinWidgetDescriptors = {
|
|
|
844
905
|
// ---- Radial family ----------------------------------------------------------
|
|
845
906
|
// A heading on a full turn, and a ring filled between a configured min and max. The compass
|
|
846
907
|
// draws on the registered gauge series; the ring is SVG. Both put their number in DOM text.
|
|
847
|
-
compass:
|
|
908
|
+
compass: defineRuntimeDescriptor({
|
|
848
909
|
id: "compass",
|
|
849
910
|
version: VERSION,
|
|
850
911
|
sdkApiVersion: 1,
|
|
@@ -857,12 +918,10 @@ var builtinWidgetDescriptors = {
|
|
|
857
918
|
title: TITLE_OR_MEASUREMENT,
|
|
858
919
|
measurement: MEASUREMENT,
|
|
859
920
|
precision: {
|
|
860
|
-
...PRECISION
|
|
861
|
-
doc: "Decimal places of the heading. Default 0 (whole degrees). The heading is rounded first, then folded onto 0 to 360, so it never reads 360."
|
|
921
|
+
...PRECISION
|
|
862
922
|
},
|
|
863
923
|
thresholds: {
|
|
864
|
-
...THRESHOLDS
|
|
865
|
-
doc: "Severity bands over the heading in degrees (0 to 360, after folding). Each entry starts a band at its value that runs to the next entry; below the first, and in a normal band, the needle keeps its own colour."
|
|
924
|
+
...THRESHOLDS
|
|
866
925
|
},
|
|
867
926
|
staleAfterSeconds: STALE_AFTER_SECONDS,
|
|
868
927
|
window: WINDOW
|
|
@@ -872,7 +931,7 @@ var builtinWidgetDescriptors = {
|
|
|
872
931
|
freshness: true,
|
|
873
932
|
layout: { defaultSpan: { cols: 4, rows: 4 }, minSpan: { cols: 3, rows: 3 }, maxSpan: { cols: 8, rows: 8 } }
|
|
874
933
|
}),
|
|
875
|
-
"progress-ring":
|
|
934
|
+
"progress-ring": defineRuntimeDescriptor({
|
|
876
935
|
id: "progress-ring",
|
|
877
936
|
version: VERSION,
|
|
878
937
|
sdkApiVersion: 1,
|
|
@@ -891,8 +950,7 @@ var builtinWidgetDescriptors = {
|
|
|
891
950
|
values: ["percent", "value"],
|
|
892
951
|
labelId: "widgetLabelReadout",
|
|
893
952
|
valueLabelIds: { percent: "widgetReadoutPercent", value: "widgetReadoutValue" },
|
|
894
|
-
placeholderId: "widgetPlaceholderDefault"
|
|
895
|
-
doc: "What the middle of the ring shows: the percent of the scale (default) or the value with its unit."
|
|
953
|
+
placeholderId: "widgetPlaceholderDefault"
|
|
896
954
|
},
|
|
897
955
|
unit: UNIT,
|
|
898
956
|
precision: PRECISION,
|
|
@@ -906,7 +964,7 @@ var builtinWidgetDescriptors = {
|
|
|
906
964
|
freshness: true,
|
|
907
965
|
layout: { defaultSpan: { cols: 3, rows: 3 }, minSpan: { cols: 2, rows: 2 }, maxSpan: { cols: 6, rows: 6 } }
|
|
908
966
|
}),
|
|
909
|
-
"command-slider":
|
|
967
|
+
"command-slider": defineRuntimeDescriptor({
|
|
910
968
|
id: "command-slider",
|
|
911
969
|
version: VERSION,
|
|
912
970
|
sdkApiVersion: 1,
|
|
@@ -925,21 +983,25 @@ var builtinWidgetDescriptors = {
|
|
|
925
983
|
min: {
|
|
926
984
|
kind: "number",
|
|
927
985
|
labelId: "widgetLabelMin",
|
|
928
|
-
helpId: "widgetHintSliderRange"
|
|
929
|
-
doc: "Lowest value, used only when the command's parameter declares no minimum."
|
|
986
|
+
helpId: "widgetHintSliderRange"
|
|
930
987
|
},
|
|
931
988
|
max: {
|
|
932
989
|
kind: "number",
|
|
933
990
|
labelId: "widgetLabelMax",
|
|
934
|
-
helpId: "widgetHintSliderRange"
|
|
935
|
-
doc: "Highest value, used only when the command's parameter declares no maximum."
|
|
991
|
+
helpId: "widgetHintSliderRange"
|
|
936
992
|
},
|
|
937
993
|
step: {
|
|
938
994
|
kind: "number",
|
|
939
995
|
min: 0,
|
|
940
996
|
labelId: "widgetLabelStep",
|
|
941
|
-
helpId: "widgetHintSliderStep"
|
|
942
|
-
|
|
997
|
+
helpId: "widgetHintSliderStep"
|
|
998
|
+
},
|
|
999
|
+
mode: {
|
|
1000
|
+
kind: "enum",
|
|
1001
|
+
values: ["slider", "stepper"],
|
|
1002
|
+
labelId: "widgetLabelControlMode",
|
|
1003
|
+
valueLabelIds: { slider: "widgetControlModeSlider", stepper: "widgetControlModeStepper" },
|
|
1004
|
+
placeholderId: "widgetPlaceholderDefault"
|
|
943
1005
|
}
|
|
944
1006
|
},
|
|
945
1007
|
constraints: [{ kind: "greater-than", key: "max", than: "min" }],
|
|
@@ -947,7 +1009,7 @@ var builtinWidgetDescriptors = {
|
|
|
947
1009
|
interactions: { commandSend: true },
|
|
948
1010
|
layout: { defaultSpan: { cols: 4, rows: 2 }, minSpan: { cols: 3, rows: 2 }, maxSpan: { cols: 8, rows: 3 } }
|
|
949
1011
|
}),
|
|
950
|
-
"command-toggle":
|
|
1012
|
+
"command-toggle": defineRuntimeDescriptor({
|
|
951
1013
|
id: "command-toggle",
|
|
952
1014
|
version: VERSION,
|
|
953
1015
|
sdkApiVersion: 1,
|
|
@@ -967,7 +1029,7 @@ var builtinWidgetDescriptors = {
|
|
|
967
1029
|
interactions: { commandSend: true },
|
|
968
1030
|
layout: { defaultSpan: { cols: 3, rows: 2 }, minSpan: { cols: 2, rows: 2 }, maxSpan: { cols: 6, rows: 3 } }
|
|
969
1031
|
}),
|
|
970
|
-
"stat-card":
|
|
1032
|
+
"stat-card": defineRuntimeDescriptor({
|
|
971
1033
|
id: "stat-card",
|
|
972
1034
|
version: VERSION,
|
|
973
1035
|
sdkApiVersion: 1,
|
|
@@ -992,19 +1054,23 @@ var builtinWidgetDescriptors = {
|
|
|
992
1054
|
count: "widgetStatCount",
|
|
993
1055
|
last: "widgetStatLast"
|
|
994
1056
|
},
|
|
995
|
-
placeholderId: "widgetPlaceholderDefault"
|
|
996
|
-
doc: "Which figure to show. Default average."
|
|
1057
|
+
placeholderId: "widgetPlaceholderDefault"
|
|
997
1058
|
},
|
|
998
1059
|
unit: UNIT,
|
|
999
1060
|
precision: PRECISION,
|
|
1000
1061
|
thresholds: THRESHOLDS,
|
|
1062
|
+
sparkline: {
|
|
1063
|
+
kind: "boolean",
|
|
1064
|
+
labelId: "widgetLabelSparkline",
|
|
1065
|
+
helpId: "widgetHintSparkline"
|
|
1066
|
+
},
|
|
1001
1067
|
windowSeconds: WINDOW_SECONDS
|
|
1002
1068
|
},
|
|
1003
1069
|
defaults: { title: "Stat card" },
|
|
1004
1070
|
interactions: {},
|
|
1005
1071
|
layout: { defaultSpan: { cols: 3, rows: 3 }, minSpan: { cols: 3, rows: 2 }, maxSpan: { cols: 6, rows: 4 } }
|
|
1006
1072
|
}),
|
|
1007
|
-
"bar-chart":
|
|
1073
|
+
"bar-chart": defineRuntimeDescriptor({
|
|
1008
1074
|
id: "bar-chart",
|
|
1009
1075
|
version: VERSION,
|
|
1010
1076
|
sdkApiVersion: 1,
|
|
@@ -1022,8 +1088,7 @@ var builtinWidgetDescriptors = {
|
|
|
1022
1088
|
labelId: "widgetLabelGroupBy",
|
|
1023
1089
|
helpId: "widgetHintGroupBy",
|
|
1024
1090
|
valueLabelIds: { measurement: "widgetGroupByMeasurement", device: "widgetGroupByDevice" },
|
|
1025
|
-
placeholderId: "widgetPlaceholderDefault"
|
|
1026
|
-
doc: "One bar per measurement (the default), or per device of the group for the measurement set below."
|
|
1091
|
+
placeholderId: "widgetPlaceholderDefault"
|
|
1027
1092
|
},
|
|
1028
1093
|
measurement: MEASUREMENT,
|
|
1029
1094
|
unit: UNIT,
|
|
@@ -1034,7 +1099,7 @@ var builtinWidgetDescriptors = {
|
|
|
1034
1099
|
interactions: {},
|
|
1035
1100
|
layout: { defaultSpan: { cols: 6, rows: 4 }, minSpan: { cols: 4, rows: 3 } }
|
|
1036
1101
|
}),
|
|
1037
|
-
"pie-chart":
|
|
1102
|
+
"pie-chart": defineRuntimeDescriptor({
|
|
1038
1103
|
id: "pie-chart",
|
|
1039
1104
|
version: VERSION,
|
|
1040
1105
|
sdkApiVersion: 1,
|
|
@@ -1051,7 +1116,7 @@ var builtinWidgetDescriptors = {
|
|
|
1051
1116
|
// A new widget rather than a mode of `table`: that one is one device's measurements as rows, on a
|
|
1052
1117
|
// channel that keys its values by name; this one is a fleet, a row per member and a column per
|
|
1053
1118
|
// measurement, and reads its data by device.
|
|
1054
|
-
"fleet-table":
|
|
1119
|
+
"fleet-table": defineRuntimeDescriptor({
|
|
1055
1120
|
id: "fleet-table",
|
|
1056
1121
|
version: VERSION,
|
|
1057
1122
|
sdkApiVersion: 1,
|
|
@@ -1070,23 +1135,20 @@ var builtinWidgetDescriptors = {
|
|
|
1070
1135
|
integer: true,
|
|
1071
1136
|
min: 1,
|
|
1072
1137
|
labelId: "widgetLabelAgeLag",
|
|
1073
|
-
helpId: "widgetHintAgeLag"
|
|
1074
|
-
doc: "Show a reading's age under it only when the reading is at least this many seconds older than the newest reading in the table (or stale). Unset shows every reading's age."
|
|
1138
|
+
helpId: "widgetHintAgeLag"
|
|
1075
1139
|
},
|
|
1076
1140
|
sortBy: {
|
|
1077
1141
|
kind: "string",
|
|
1078
1142
|
labelId: "widgetLabelSortBy",
|
|
1079
|
-
helpId: "widgetHintSortBy"
|
|
1080
|
-
doc: "The measurement the table is ordered by. Blank orders by device name."
|
|
1143
|
+
helpId: "widgetHintSortBy"
|
|
1081
1144
|
},
|
|
1082
|
-
sortDescending: { kind: "boolean", labelId: "widgetLabelSortDescending"
|
|
1145
|
+
sortDescending: { kind: "boolean", labelId: "widgetLabelSortDescending" },
|
|
1083
1146
|
pageSize: {
|
|
1084
1147
|
kind: "number",
|
|
1085
1148
|
integer: true,
|
|
1086
1149
|
min: 5,
|
|
1087
1150
|
max: 100,
|
|
1088
|
-
labelId: "widgetLabelPageSize"
|
|
1089
|
-
doc: "Devices per page. Default 20."
|
|
1151
|
+
labelId: "widgetLabelPageSize"
|
|
1090
1152
|
},
|
|
1091
1153
|
selectionTarget: SELECTION_TARGET,
|
|
1092
1154
|
windowSeconds: WINDOW_SECONDS
|
|
@@ -1096,44 +1158,82 @@ var builtinWidgetDescriptors = {
|
|
|
1096
1158
|
freshness: true,
|
|
1097
1159
|
interactions: { selection: true },
|
|
1098
1160
|
layout: { defaultSpan: { cols: 12, rows: 6 }, minSpan: { cols: 6, rows: 3 } }
|
|
1161
|
+
}),
|
|
1162
|
+
// Counts a fleet rather than listing it: how many of its devices are in an abnormal band of one
|
|
1163
|
+
// measurement ("3 of 21"), or how many devices it has. A new widget rather than a mode of the
|
|
1164
|
+
// fleet table, which is a grid; this is the figure above one.
|
|
1165
|
+
"fleet-count": defineRuntimeDescriptor({
|
|
1166
|
+
id: "fleet-count",
|
|
1167
|
+
version: VERSION,
|
|
1168
|
+
sdkApiVersion: 1,
|
|
1169
|
+
optionsVersion: 1,
|
|
1170
|
+
display: { title: "Fleet count", category: "Telemetry", titleId: "widgetTypeFleetCount", categoryId: "widgetCategoryTelemetry" },
|
|
1171
|
+
channel: "measurement",
|
|
1172
|
+
datasource: { mode: "required", selectors: ALL_SELECTORS },
|
|
1173
|
+
binding: { windowSeconds: { option: "windowSeconds" }, members: { const: true } },
|
|
1174
|
+
options: {
|
|
1175
|
+
title: TITLE,
|
|
1176
|
+
show: {
|
|
1177
|
+
kind: "enum",
|
|
1178
|
+
values: ["attention", "devices"],
|
|
1179
|
+
labelId: "widgetLabelFleetShow",
|
|
1180
|
+
helpId: "widgetHintFleetShow",
|
|
1181
|
+
valueLabelIds: { attention: "widgetFleetShowAttention", devices: "widgetFleetShowDevices" },
|
|
1182
|
+
placeholderId: "widgetPlaceholderDefault"
|
|
1183
|
+
},
|
|
1184
|
+
measurement: {
|
|
1185
|
+
...MEASUREMENT
|
|
1186
|
+
},
|
|
1187
|
+
thresholds: THRESHOLDS,
|
|
1188
|
+
staleAfterSeconds: STALE_AFTER_SECONDS,
|
|
1189
|
+
windowSeconds: WINDOW_SECONDS
|
|
1190
|
+
},
|
|
1191
|
+
defaults: { title: "Fleet count" },
|
|
1192
|
+
freshness: true,
|
|
1193
|
+
interactions: {},
|
|
1194
|
+
layout: { defaultSpan: { cols: 3, rows: 3 }, minSpan: { cols: 3, rows: 3 }, maxSpan: { cols: 6, rows: 4 } }
|
|
1195
|
+
}),
|
|
1196
|
+
// One device's connectivity: Online or Offline, and when it was last seen. It reads device-state
|
|
1197
|
+
// (`binding.presence`), not the device's readings, and shows one device, so it takes no group.
|
|
1198
|
+
"device-status": defineRuntimeDescriptor({
|
|
1199
|
+
id: "device-status",
|
|
1200
|
+
version: VERSION,
|
|
1201
|
+
sdkApiVersion: 1,
|
|
1202
|
+
optionsVersion: 1,
|
|
1203
|
+
display: { title: "Device status", category: "Telemetry", titleId: "widgetTypeDeviceStatus", categoryId: "widgetCategoryTelemetry" },
|
|
1204
|
+
channel: "measurement",
|
|
1205
|
+
datasource: { mode: "required", selectors: ONE_DEVICE },
|
|
1206
|
+
binding: { presence: { const: true } },
|
|
1207
|
+
options: { title: TITLE, staleAfterSeconds: STALE_AFTER_SECONDS },
|
|
1208
|
+
defaults: { title: "Device status" },
|
|
1209
|
+
// The frame's age is the status's: when device-state was last read, not the device's last activity.
|
|
1210
|
+
freshness: true,
|
|
1211
|
+
interactions: {},
|
|
1212
|
+
layout: { defaultSpan: { cols: 3, rows: 3 }, minSpan: { cols: 3, rows: 3 }, maxSpan: { cols: 6, rows: 4 } }
|
|
1213
|
+
}),
|
|
1214
|
+
// How many of a group's devices are online: a ring of online, offline and no status yet. A new
|
|
1215
|
+
// widget rather than a mode of the pie chart, which is shares of readings; this reads device-state.
|
|
1216
|
+
"online-doughnut": defineRuntimeDescriptor({
|
|
1217
|
+
id: "online-doughnut",
|
|
1218
|
+
version: VERSION,
|
|
1219
|
+
sdkApiVersion: 1,
|
|
1220
|
+
optionsVersion: 1,
|
|
1221
|
+
display: { title: "Online doughnut", category: "Telemetry", titleId: "widgetTypeOnlineDoughnut", categoryId: "widgetCategoryTelemetry" },
|
|
1222
|
+
channel: "measurement",
|
|
1223
|
+
datasource: { mode: "required", selectors: ALL_SELECTORS },
|
|
1224
|
+
binding: { presence: { const: true } },
|
|
1225
|
+
options: { title: TITLE, staleAfterSeconds: STALE_AFTER_SECONDS },
|
|
1226
|
+
defaults: { title: "Online doughnut" },
|
|
1227
|
+
// The frame's age is the status's: when device-state was last read for the group.
|
|
1228
|
+
freshness: true,
|
|
1229
|
+
interactions: {},
|
|
1230
|
+
layout: { defaultSpan: { cols: 4, rows: 4 }, minSpan: { cols: 3, rows: 3 }, maxSpan: { cols: 8, rows: 8 } }
|
|
1099
1231
|
})
|
|
1100
1232
|
};
|
|
1101
1233
|
var builtinWidgetCatalog = createWidgetCatalog(Object.values(builtinWidgetDescriptors));
|
|
1102
1234
|
|
|
1103
|
-
// src/widgets/lazy-chunk.tsx
|
|
1104
|
-
import { useEffect, useState as useState2 } from "react";
|
|
1105
|
-
import { jsx } from "react/jsx-runtime";
|
|
1106
|
-
function lazyChunk(importer) {
|
|
1107
|
-
let loaded;
|
|
1108
|
-
let loading;
|
|
1109
|
-
const load = () => loading ?? (loading = importer().then(
|
|
1110
|
-
(m) => loaded = m,
|
|
1111
|
-
(err) => {
|
|
1112
|
-
loading = void 0;
|
|
1113
|
-
throw err;
|
|
1114
|
-
}
|
|
1115
|
-
));
|
|
1116
|
-
function component(name, alsoPreload) {
|
|
1117
|
-
function LazyChunkWidget(props) {
|
|
1118
|
-
const [mod, setMod] = useState2(loaded);
|
|
1119
|
-
const [error, setError] = useState2();
|
|
1120
|
-
useEffect(() => {
|
|
1121
|
-
if (!mod) load().then(setMod, setError);
|
|
1122
|
-
}, [mod]);
|
|
1123
|
-
if (error !== void 0) throw error;
|
|
1124
|
-
if (!mod) return null;
|
|
1125
|
-
const Component2 = mod[name];
|
|
1126
|
-
return /* @__PURE__ */ jsx(Component2, { ...props });
|
|
1127
|
-
}
|
|
1128
|
-
LazyChunkWidget.displayName = `Lazy(${name})`;
|
|
1129
|
-
LazyChunkWidget.preload = alsoPreload ? () => Promise.all([load(), alsoPreload()]).then(([m]) => m) : load;
|
|
1130
|
-
return LazyChunkWidget;
|
|
1131
|
-
}
|
|
1132
|
-
return { load, component };
|
|
1133
|
-
}
|
|
1134
|
-
|
|
1135
1235
|
// src/widgets/aggregate-lazy.tsx
|
|
1136
|
-
var chunk = lazyChunk(() => import("./chunks/aggregate-widgets-
|
|
1236
|
+
var chunk = lazyChunk(() => import("./chunks/aggregate-widgets-2ZQBW3YF.js"));
|
|
1137
1237
|
var loadAggregateWidgets = chunk.load;
|
|
1138
1238
|
var statCardWidget = defineWidget({
|
|
1139
1239
|
descriptor: builtinWidgetDescriptors["stat-card"],
|
|
@@ -1147,6 +1247,10 @@ var pieChartWidget = defineWidget({
|
|
|
1147
1247
|
descriptor: builtinWidgetDescriptors["pie-chart"],
|
|
1148
1248
|
implementation: { kind: "trusted-react", component: chunk.component("PieChart") }
|
|
1149
1249
|
});
|
|
1250
|
+
var fleetCountWidget = defineWidget({
|
|
1251
|
+
descriptor: builtinWidgetDescriptors["fleet-count"],
|
|
1252
|
+
implementation: { kind: "trusted-react", component: chunk.component("FleetCount") }
|
|
1253
|
+
});
|
|
1150
1254
|
var fleetTableWidget = defineWidget({
|
|
1151
1255
|
descriptor: builtinWidgetDescriptors["fleet-table"],
|
|
1152
1256
|
implementation: { kind: "trusted-react", component: chunk.component("FleetTable") }
|
|
@@ -1154,12 +1258,16 @@ var fleetTableWidget = defineWidget({
|
|
|
1154
1258
|
|
|
1155
1259
|
// src/widgets/alarm-lazy.tsx
|
|
1156
1260
|
import { defineWidget as defineWidget2 } from "@devicechain/widget-sdk";
|
|
1157
|
-
var chunk2 = lazyChunk(() => import("./chunks/alarm-widgets-
|
|
1261
|
+
var chunk2 = lazyChunk(() => import("./chunks/alarm-widgets-X4PX5MYJ.js"));
|
|
1158
1262
|
var loadAlarmWidgets = chunk2.load;
|
|
1159
1263
|
var alarmTableWidget = defineWidget2({
|
|
1160
1264
|
descriptor: builtinWidgetDescriptors["alarm-table"],
|
|
1161
1265
|
implementation: { kind: "trusted-react", component: chunk2.component("AlarmTable") }
|
|
1162
1266
|
});
|
|
1267
|
+
var alarmSeverityWidget = defineWidget2({
|
|
1268
|
+
descriptor: builtinWidgetDescriptors["alarm-severity"],
|
|
1269
|
+
implementation: { kind: "trusted-react", component: chunk2.component("AlarmSeverity") }
|
|
1270
|
+
});
|
|
1163
1271
|
var alarmCountWidget = defineWidget2({
|
|
1164
1272
|
descriptor: builtinWidgetDescriptors["alarm-count"],
|
|
1165
1273
|
implementation: { kind: "trusted-react", component: chunk2.component("AlarmCount") }
|
|
@@ -1167,7 +1275,7 @@ var alarmCountWidget = defineWidget2({
|
|
|
1167
1275
|
|
|
1168
1276
|
// src/widgets/control-lazy.tsx
|
|
1169
1277
|
import { defineWidget as defineWidget3 } from "@devicechain/widget-sdk";
|
|
1170
|
-
var chunk3 = lazyChunk(() => import("./chunks/control-widgets-
|
|
1278
|
+
var chunk3 = lazyChunk(() => import("./chunks/control-widgets-UCTJJJ2D.js"));
|
|
1171
1279
|
var loadControlWidgets = chunk3.load;
|
|
1172
1280
|
var commandSliderWidget = defineWidget3({
|
|
1173
1281
|
descriptor: builtinWidgetDescriptors["command-slider"],
|
|
@@ -1182,19 +1290,32 @@ var commandButtonWidget = defineWidget3({
|
|
|
1182
1290
|
implementation: { kind: "trusted-react", component: chunk3.component("CommandButton") }
|
|
1183
1291
|
});
|
|
1184
1292
|
|
|
1185
|
-
// src/widgets/
|
|
1293
|
+
// src/widgets/presence-lazy.tsx
|
|
1186
1294
|
import { defineWidget as defineWidget4 } from "@devicechain/widget-sdk";
|
|
1187
|
-
var chunk4 = lazyChunk(() => import("./chunks/
|
|
1188
|
-
var
|
|
1189
|
-
var
|
|
1295
|
+
var chunk4 = lazyChunk(() => import("./chunks/presence-widgets-2LIUKN4Y.js"));
|
|
1296
|
+
var loadPresenceWidgets = chunk4.load;
|
|
1297
|
+
var deviceStatusWidget = defineWidget4({
|
|
1298
|
+
descriptor: builtinWidgetDescriptors["device-status"],
|
|
1299
|
+
implementation: { kind: "trusted-react", component: chunk4.component("DeviceStatus") }
|
|
1300
|
+
});
|
|
1301
|
+
var onlineDoughnutWidget = defineWidget4({
|
|
1302
|
+
descriptor: builtinWidgetDescriptors["online-doughnut"],
|
|
1303
|
+
implementation: { kind: "trusted-react", component: chunk4.component("OnlineDoughnut") }
|
|
1304
|
+
});
|
|
1305
|
+
|
|
1306
|
+
// src/widgets/selection-lazy.tsx
|
|
1307
|
+
import { defineWidget as defineWidget5 } from "@devicechain/widget-sdk";
|
|
1308
|
+
var chunk5 = lazyChunk(() => import("./chunks/entity-selector-3JJFI4DT.js"));
|
|
1309
|
+
var loadSelectionWidgets = chunk5.load;
|
|
1310
|
+
var entitySelectorWidget = defineWidget5({
|
|
1190
1311
|
descriptor: builtinWidgetDescriptors["entity-selector"],
|
|
1191
|
-
implementation: { kind: "trusted-react", component:
|
|
1312
|
+
implementation: { kind: "trusted-react", component: chunk5.component("EntitySelector") }
|
|
1192
1313
|
});
|
|
1193
1314
|
|
|
1194
1315
|
// src/widgets/gauge.tsx
|
|
1195
1316
|
import { useMemo } from "react";
|
|
1196
1317
|
import {
|
|
1197
|
-
defineWidget as
|
|
1318
|
+
defineWidget as defineWidget6,
|
|
1198
1319
|
flashBackgroundStyle,
|
|
1199
1320
|
formatValue,
|
|
1200
1321
|
optBoolean,
|
|
@@ -1208,11 +1329,11 @@ import {
|
|
|
1208
1329
|
WidgetFrame
|
|
1209
1330
|
} from "@devicechain/widget-sdk";
|
|
1210
1331
|
import { buildGaugeOption, EChart, gaugeReadoutBox, loadChartEngine, useChartTheme } from "@devicechain/widget-sdk/echarts";
|
|
1211
|
-
import { jsx
|
|
1332
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
1212
1333
|
function Gauge({ widget, data }) {
|
|
1213
1334
|
const name = primaryMeasurementName(widget);
|
|
1214
1335
|
const sample = pickSample(data.latest, name);
|
|
1215
|
-
return /* @__PURE__ */
|
|
1336
|
+
return /* @__PURE__ */ jsx(WidgetFrame, { title: optString(widget.options, "title") ?? name, sampleTime: sample?.occurredTime ?? null, flush: true, children: /* @__PURE__ */ jsx(GaugeBody, { widget, data }) });
|
|
1216
1337
|
}
|
|
1217
1338
|
function GaugeBody({ widget, data }) {
|
|
1218
1339
|
const theme = useChartTheme();
|
|
@@ -1244,8 +1365,8 @@ function GaugeBody({ widget, data }) {
|
|
|
1244
1365
|
"aria-valuetext": `${formatValue(value, precision)}${unit ? ` ${unit}` : ""}`
|
|
1245
1366
|
} : {};
|
|
1246
1367
|
return /* @__PURE__ */ jsxs("div", { style: { position: "relative", width: "100%", height: "100%", ...flashBackgroundStyle(flashDirection) }, ...meter, children: [
|
|
1247
|
-
/* @__PURE__ */
|
|
1248
|
-
/* @__PURE__ */
|
|
1368
|
+
/* @__PURE__ */ jsx(EChart, { option }),
|
|
1369
|
+
/* @__PURE__ */ jsx(
|
|
1249
1370
|
"div",
|
|
1250
1371
|
{
|
|
1251
1372
|
style: {
|
|
@@ -1259,7 +1380,7 @@ function GaugeBody({ widget, data }) {
|
|
|
1259
1380
|
justifyContent: "center",
|
|
1260
1381
|
pointerEvents: "none"
|
|
1261
1382
|
},
|
|
1262
|
-
children: /* @__PURE__ */
|
|
1383
|
+
children: /* @__PURE__ */ jsx(
|
|
1263
1384
|
LevelReadout,
|
|
1264
1385
|
{
|
|
1265
1386
|
text: formatValue(value, precision),
|
|
@@ -1273,7 +1394,7 @@ function GaugeBody({ widget, data }) {
|
|
|
1273
1394
|
] });
|
|
1274
1395
|
}
|
|
1275
1396
|
Gauge.preload = loadChartEngine;
|
|
1276
|
-
var gaugeWidget =
|
|
1397
|
+
var gaugeWidget = defineWidget6({
|
|
1277
1398
|
descriptor: builtinWidgetDescriptors["gauge"],
|
|
1278
1399
|
implementation: { kind: "trusted-react", component: Gauge }
|
|
1279
1400
|
});
|
|
@@ -1281,19 +1402,19 @@ var gaugeWidget = defineWidget5({
|
|
|
1281
1402
|
// src/widgets/image.tsx
|
|
1282
1403
|
import {
|
|
1283
1404
|
css,
|
|
1284
|
-
defineWidget as
|
|
1405
|
+
defineWidget as defineWidget7,
|
|
1285
1406
|
fontVar,
|
|
1286
1407
|
optString as optString2,
|
|
1287
1408
|
WidgetFrame as WidgetFrame2
|
|
1288
1409
|
} from "@devicechain/widget-sdk";
|
|
1289
|
-
import { jsx as
|
|
1410
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
1290
1411
|
var FITS = /* @__PURE__ */ new Set(["contain", "cover", "fill"]);
|
|
1291
1412
|
function Image({ widget }) {
|
|
1292
1413
|
const url = optString2(widget.options, "url");
|
|
1293
1414
|
const alt = optString2(widget.options, "alt") ?? "";
|
|
1294
1415
|
const fitOption = optString2(widget.options, "fit");
|
|
1295
1416
|
const objectFit = fitOption && FITS.has(fitOption) ? fitOption : "contain";
|
|
1296
|
-
return /* @__PURE__ */
|
|
1417
|
+
return /* @__PURE__ */ jsx2(WidgetFrame2, { title: optString2(widget.options, "title"), flush: true, children: url ? /* @__PURE__ */ jsx2("img", { src: url, alt, style: { width: "100%", height: "100%", objectFit, display: "block" } }) : /* @__PURE__ */ jsx2(
|
|
1297
1418
|
"div",
|
|
1298
1419
|
{
|
|
1299
1420
|
style: {
|
|
@@ -1308,7 +1429,7 @@ function Image({ widget }) {
|
|
|
1308
1429
|
}
|
|
1309
1430
|
) });
|
|
1310
1431
|
}
|
|
1311
|
-
var imageWidget =
|
|
1432
|
+
var imageWidget = defineWidget7({
|
|
1312
1433
|
descriptor: builtinWidgetDescriptors["image"],
|
|
1313
1434
|
implementation: { kind: "trusted-react", component: Image }
|
|
1314
1435
|
});
|
|
@@ -1316,14 +1437,14 @@ var imageWidget = defineWidget6({
|
|
|
1316
1437
|
// src/widgets/label.tsx
|
|
1317
1438
|
import {
|
|
1318
1439
|
css as css2,
|
|
1319
|
-
defineWidget as
|
|
1440
|
+
defineWidget as defineWidget8,
|
|
1320
1441
|
fontVar as fontVar2,
|
|
1321
1442
|
spaceVar,
|
|
1322
1443
|
optNumber as optNumber2,
|
|
1323
1444
|
optString as optString3,
|
|
1324
1445
|
WidgetFrame as WidgetFrame3
|
|
1325
1446
|
} from "@devicechain/widget-sdk";
|
|
1326
|
-
import { jsx as
|
|
1447
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
1327
1448
|
var justify = {
|
|
1328
1449
|
left: "flex-start",
|
|
1329
1450
|
center: "center",
|
|
@@ -1334,7 +1455,7 @@ function Label({ widget }) {
|
|
|
1334
1455
|
const align = optString3(widget.options, "align") ?? "center";
|
|
1335
1456
|
const authored = optNumber2(widget.options, "fontSize");
|
|
1336
1457
|
const fontSize = authored !== void 0 ? `calc(${authored}px * var(--dc-scale, 1))` : fontVar2("lg");
|
|
1337
|
-
return /* @__PURE__ */
|
|
1458
|
+
return /* @__PURE__ */ jsx3(WidgetFrame3, { title: optString3(widget.options, "title"), flush: true, children: /* @__PURE__ */ jsx3(
|
|
1338
1459
|
"div",
|
|
1339
1460
|
{
|
|
1340
1461
|
style: {
|
|
@@ -1348,7 +1469,7 @@ function Label({ widget }) {
|
|
|
1348
1469
|
// height or less, so it keeps a slim vertical inset and the usual side inset.
|
|
1349
1470
|
padding: `${spaceVar(1)} ${spaceVar(3)}`
|
|
1350
1471
|
},
|
|
1351
|
-
children: /* @__PURE__ */
|
|
1472
|
+
children: /* @__PURE__ */ jsx3(
|
|
1352
1473
|
"span",
|
|
1353
1474
|
{
|
|
1354
1475
|
style: {
|
|
@@ -1363,7 +1484,7 @@ function Label({ widget }) {
|
|
|
1363
1484
|
}
|
|
1364
1485
|
) });
|
|
1365
1486
|
}
|
|
1366
|
-
var labelWidget =
|
|
1487
|
+
var labelWidget = defineWidget8({
|
|
1367
1488
|
descriptor: builtinWidgetDescriptors["label"],
|
|
1368
1489
|
implementation: { kind: "trusted-react", component: Label }
|
|
1369
1490
|
});
|
|
@@ -1373,7 +1494,7 @@ import { useMemo as useMemo2 } from "react";
|
|
|
1373
1494
|
import {
|
|
1374
1495
|
bandAt,
|
|
1375
1496
|
css as css3,
|
|
1376
|
-
defineWidget as
|
|
1497
|
+
defineWidget as defineWidget9,
|
|
1377
1498
|
fitValueFont,
|
|
1378
1499
|
fitValueFontCss,
|
|
1379
1500
|
FIT_MIN_FONT_PX,
|
|
@@ -1395,7 +1516,7 @@ import {
|
|
|
1395
1516
|
useWidgetTimeZone,
|
|
1396
1517
|
WidgetFrame as WidgetFrame4
|
|
1397
1518
|
} from "@devicechain/widget-sdk";
|
|
1398
|
-
import { jsx as
|
|
1519
|
+
import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1399
1520
|
var TIMESTAMP_ROOM_PX = 18;
|
|
1400
1521
|
function LatestCard({ widget, data }) {
|
|
1401
1522
|
const severity = useSeverityColors();
|
|
@@ -1415,7 +1536,7 @@ function LatestCard({ widget, data }) {
|
|
|
1415
1536
|
sample && `${sample.deviceToken}:${sample.name}`
|
|
1416
1537
|
);
|
|
1417
1538
|
const chars = useStickyChars(display.length + (sample?.value != null && unit ? Math.ceil(unit.length / 2) + 1 : 0));
|
|
1418
|
-
return /* @__PURE__ */
|
|
1539
|
+
return /* @__PURE__ */ jsx4(WidgetFrame4, { title, sampleTime: sample?.occurredTime ?? null, children: ({ size, scale }) => {
|
|
1419
1540
|
const floor = Math.round(FIT_MIN_FONT_PX * scale);
|
|
1420
1541
|
const measured = size.width > 0 && size.height > 0;
|
|
1421
1542
|
const valuePx = measured ? fitValueFont(size, chars, { floor }) : void 0;
|
|
@@ -1451,7 +1572,7 @@ function LatestCard({ widget, data }) {
|
|
|
1451
1572
|
},
|
|
1452
1573
|
children: [
|
|
1453
1574
|
display,
|
|
1454
|
-
sample?.value != null && unit ? /* @__PURE__ */
|
|
1575
|
+
sample?.value != null && unit ? /* @__PURE__ */ jsx4(
|
|
1455
1576
|
"span",
|
|
1456
1577
|
{
|
|
1457
1578
|
style: {
|
|
@@ -1465,65 +1586,65 @@ function LatestCard({ widget, data }) {
|
|
|
1465
1586
|
]
|
|
1466
1587
|
}
|
|
1467
1588
|
),
|
|
1468
|
-
sample?.occurredTime && showTimestamp ? /* @__PURE__ */
|
|
1589
|
+
sample?.occurredTime && showTimestamp ? /* @__PURE__ */ jsx4("div", { style: { fontSize: fontVar3("xs"), color: css3("muted-foreground"), marginTop: spaceVar2(1) }, children: formatTimestamp(sample.occurredTime, timeZone) }) : null
|
|
1469
1590
|
]
|
|
1470
1591
|
}
|
|
1471
1592
|
);
|
|
1472
1593
|
} });
|
|
1473
1594
|
}
|
|
1474
|
-
var latestCardWidget =
|
|
1595
|
+
var latestCardWidget = defineWidget9({
|
|
1475
1596
|
descriptor: builtinWidgetDescriptors["latest-card"],
|
|
1476
1597
|
implementation: { kind: "trusted-react", component: LatestCard }
|
|
1477
1598
|
});
|
|
1478
1599
|
|
|
1479
1600
|
// src/widgets/level-lazy.tsx
|
|
1480
|
-
import { defineWidget as
|
|
1601
|
+
import { defineWidget as defineWidget10 } from "@devicechain/widget-sdk";
|
|
1481
1602
|
import { loadChartEngine as loadChartEngine2 } from "@devicechain/widget-sdk/echarts";
|
|
1482
|
-
var
|
|
1483
|
-
var loadLevelWidgets =
|
|
1484
|
-
var lazyComponent =
|
|
1485
|
-
var linearGaugeWidget =
|
|
1603
|
+
var chunk6 = lazyChunk(() => import("./chunks/level-widgets-MJB7TOLU.js"));
|
|
1604
|
+
var loadLevelWidgets = chunk6.load;
|
|
1605
|
+
var lazyComponent = chunk6.component;
|
|
1606
|
+
var linearGaugeWidget = defineWidget10({
|
|
1486
1607
|
descriptor: builtinWidgetDescriptors["linear-gauge"],
|
|
1487
1608
|
implementation: { kind: "trusted-react", component: lazyComponent("LinearGauge") }
|
|
1488
1609
|
});
|
|
1489
|
-
var levelGaugeWidget =
|
|
1610
|
+
var levelGaugeWidget = defineWidget10({
|
|
1490
1611
|
descriptor: builtinWidgetDescriptors["level-gauge"],
|
|
1491
1612
|
implementation: { kind: "trusted-react", component: lazyComponent("LevelGauge") }
|
|
1492
1613
|
});
|
|
1493
|
-
var batteryWidget =
|
|
1614
|
+
var batteryWidget = defineWidget10({
|
|
1494
1615
|
descriptor: builtinWidgetDescriptors["battery"],
|
|
1495
1616
|
implementation: { kind: "trusted-react", component: lazyComponent("Battery") }
|
|
1496
1617
|
});
|
|
1497
|
-
var statusLightWidget =
|
|
1618
|
+
var statusLightWidget = defineWidget10({
|
|
1498
1619
|
descriptor: builtinWidgetDescriptors["status-light"],
|
|
1499
1620
|
implementation: { kind: "trusted-react", component: lazyComponent("StatusLight") }
|
|
1500
1621
|
});
|
|
1501
|
-
var signalBarsWidget =
|
|
1622
|
+
var signalBarsWidget = defineWidget10({
|
|
1502
1623
|
descriptor: builtinWidgetDescriptors["signal-bars"],
|
|
1503
1624
|
implementation: { kind: "trusted-react", component: lazyComponent("SignalBars") }
|
|
1504
1625
|
});
|
|
1505
|
-
var compassWidget =
|
|
1626
|
+
var compassWidget = defineWidget10({
|
|
1506
1627
|
descriptor: builtinWidgetDescriptors["compass"],
|
|
1507
1628
|
implementation: { kind: "trusted-react", component: lazyComponent("Compass", loadChartEngine2) }
|
|
1508
1629
|
});
|
|
1509
|
-
var progressRingWidget =
|
|
1630
|
+
var progressRingWidget = defineWidget10({
|
|
1510
1631
|
descriptor: builtinWidgetDescriptors["progress-ring"],
|
|
1511
1632
|
implementation: { kind: "trusted-react", component: lazyComponent("ProgressRing") }
|
|
1512
1633
|
});
|
|
1513
1634
|
|
|
1514
1635
|
// src/widgets/map.tsx
|
|
1515
|
-
import { useEffect
|
|
1636
|
+
import { useEffect, useRef, useState } from "react";
|
|
1516
1637
|
import { renderableBasemap, resolveBasemap } from "@devicechain/client";
|
|
1517
1638
|
|
|
1518
1639
|
// src/basemap-context.tsx
|
|
1519
1640
|
import { createContext, useContext } from "react";
|
|
1520
|
-
import { jsx as
|
|
1641
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
1521
1642
|
var TenantBasemapContext = createContext(null);
|
|
1522
1643
|
function TenantBasemapProvider({
|
|
1523
1644
|
basemap,
|
|
1524
1645
|
children
|
|
1525
1646
|
}) {
|
|
1526
|
-
return /* @__PURE__ */
|
|
1647
|
+
return /* @__PURE__ */ jsx5(TenantBasemapContext.Provider, { value: basemap, children });
|
|
1527
1648
|
}
|
|
1528
1649
|
function useTenantBasemap() {
|
|
1529
1650
|
return useContext(TenantBasemapContext);
|
|
@@ -1531,13 +1652,13 @@ function useTenantBasemap() {
|
|
|
1531
1652
|
|
|
1532
1653
|
// src/map-runtime-context.tsx
|
|
1533
1654
|
import { createContext as createContext2, useContext as useContext2 } from "react";
|
|
1534
|
-
import { jsx as
|
|
1655
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
1535
1656
|
var MapRuntimeContext = createContext2(null);
|
|
1536
1657
|
function MapRuntimeProvider({
|
|
1537
1658
|
runtime,
|
|
1538
1659
|
children
|
|
1539
1660
|
}) {
|
|
1540
|
-
return /* @__PURE__ */
|
|
1661
|
+
return /* @__PURE__ */ jsx6(MapRuntimeContext.Provider, { value: runtime, children });
|
|
1541
1662
|
}
|
|
1542
1663
|
function useMapRuntime() {
|
|
1543
1664
|
return useContext2(MapRuntimeContext);
|
|
@@ -1547,8 +1668,9 @@ function useMapRuntime() {
|
|
|
1547
1668
|
import {
|
|
1548
1669
|
css as css4,
|
|
1549
1670
|
fontVar as fontVar4,
|
|
1550
|
-
defineWidget as
|
|
1671
|
+
defineWidget as defineWidget11,
|
|
1551
1672
|
optString as optString5,
|
|
1673
|
+
useWidgetSelect,
|
|
1552
1674
|
WidgetFrame as WidgetFrame5
|
|
1553
1675
|
} from "@devicechain/widget-sdk";
|
|
1554
1676
|
|
|
@@ -1645,7 +1767,7 @@ function loadLandStyle() {
|
|
|
1645
1767
|
}
|
|
1646
1768
|
|
|
1647
1769
|
// src/widgets/map.tsx
|
|
1648
|
-
import { jsx as
|
|
1770
|
+
import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1649
1771
|
var mapLibrePromise;
|
|
1650
1772
|
function loadMapLibre(runtime) {
|
|
1651
1773
|
if (!mapLibrePromise) {
|
|
@@ -1664,6 +1786,9 @@ function MapWidget({ widget, data }) {
|
|
|
1664
1786
|
const title = optString5(widget.options, "title");
|
|
1665
1787
|
const positions = placeable(data.locations);
|
|
1666
1788
|
const runtime = useMapRuntime();
|
|
1789
|
+
const select = useWidgetSelect();
|
|
1790
|
+
const selectionTarget = optString5(widget.options, "selectionTarget");
|
|
1791
|
+
const pick = select && selectionTarget ? (deviceToken) => select({ slot: selectionTarget, binding: { kind: "device", deviceToken } }) : void 0;
|
|
1667
1792
|
const basemap = renderableBasemap(
|
|
1668
1793
|
resolveBasemap(
|
|
1669
1794
|
{
|
|
@@ -1674,7 +1799,7 @@ function MapWidget({ widget, data }) {
|
|
|
1674
1799
|
)
|
|
1675
1800
|
);
|
|
1676
1801
|
if (data.forbidden) {
|
|
1677
|
-
return /* @__PURE__ */
|
|
1802
|
+
return /* @__PURE__ */ jsx7(WidgetFrame5, { title, children: /* @__PURE__ */ jsx7(
|
|
1678
1803
|
MapNotice,
|
|
1679
1804
|
{
|
|
1680
1805
|
glyph: "\u{1F512}",
|
|
@@ -1684,7 +1809,7 @@ function MapWidget({ widget, data }) {
|
|
|
1684
1809
|
) });
|
|
1685
1810
|
}
|
|
1686
1811
|
if (!runtime) {
|
|
1687
|
-
return /* @__PURE__ */
|
|
1812
|
+
return /* @__PURE__ */ jsx7(WidgetFrame5, { title, children: /* @__PURE__ */ jsx7(
|
|
1688
1813
|
MapNotice,
|
|
1689
1814
|
{
|
|
1690
1815
|
glyph: "\u{1F9E9}",
|
|
@@ -1694,10 +1819,10 @@ function MapWidget({ widget, data }) {
|
|
|
1694
1819
|
) });
|
|
1695
1820
|
}
|
|
1696
1821
|
if (data.loading && positions.length === 0) {
|
|
1697
|
-
return /* @__PURE__ */
|
|
1822
|
+
return /* @__PURE__ */ jsx7(WidgetFrame5, { title, children: /* @__PURE__ */ jsx7(MapNotice, { heading: "Loading\u2026" }) });
|
|
1698
1823
|
}
|
|
1699
1824
|
if (positions.length === 0) {
|
|
1700
|
-
return /* @__PURE__ */
|
|
1825
|
+
return /* @__PURE__ */ jsx7(WidgetFrame5, { title, children: /* @__PURE__ */ jsx7(
|
|
1701
1826
|
MapNotice,
|
|
1702
1827
|
{
|
|
1703
1828
|
heading: data.deviceTokens.length === 0 ? "No devices selected" : "No positions reported",
|
|
@@ -1705,9 +1830,13 @@ function MapWidget({ widget, data }) {
|
|
|
1705
1830
|
}
|
|
1706
1831
|
) });
|
|
1707
1832
|
}
|
|
1708
|
-
return /* @__PURE__ */
|
|
1833
|
+
return /* @__PURE__ */ jsx7(WidgetFrame5, { title, flush: true, children: /* @__PURE__ */ jsx7(LiveMap, { basemap, positions, runtime, pick }) });
|
|
1709
1834
|
}
|
|
1710
|
-
function PlainPanel({
|
|
1835
|
+
function PlainPanel({
|
|
1836
|
+
positions,
|
|
1837
|
+
note,
|
|
1838
|
+
pick
|
|
1839
|
+
}) {
|
|
1711
1840
|
const points = projectToPanel(positions);
|
|
1712
1841
|
return /* @__PURE__ */ jsxs3(
|
|
1713
1842
|
"div",
|
|
@@ -1721,10 +1850,11 @@ function PlainPanel({ positions, note }) {
|
|
|
1721
1850
|
background: css4("muted")
|
|
1722
1851
|
},
|
|
1723
1852
|
children: [
|
|
1724
|
-
positions.map((position, i) => /* @__PURE__ */
|
|
1853
|
+
positions.map((position, i) => /* @__PURE__ */ jsx7(
|
|
1725
1854
|
Marker,
|
|
1726
1855
|
{
|
|
1727
1856
|
position,
|
|
1857
|
+
pick,
|
|
1728
1858
|
style: {
|
|
1729
1859
|
position: "absolute",
|
|
1730
1860
|
left: `${points[i].x * 100}%`,
|
|
@@ -1734,7 +1864,7 @@ function PlainPanel({ positions, note }) {
|
|
|
1734
1864
|
},
|
|
1735
1865
|
position.deviceToken
|
|
1736
1866
|
)),
|
|
1737
|
-
/* @__PURE__ */
|
|
1867
|
+
/* @__PURE__ */ jsx7(
|
|
1738
1868
|
"div",
|
|
1739
1869
|
{
|
|
1740
1870
|
"data-testid": "map-no-tiles-note",
|
|
@@ -1761,15 +1891,19 @@ function PlainPanel({ positions, note }) {
|
|
|
1761
1891
|
function LiveMap({
|
|
1762
1892
|
basemap,
|
|
1763
1893
|
positions,
|
|
1764
|
-
runtime
|
|
1894
|
+
runtime,
|
|
1895
|
+
pick
|
|
1765
1896
|
}) {
|
|
1766
1897
|
const containerRef = useRef(null);
|
|
1767
1898
|
const mapRef = useRef(null);
|
|
1768
1899
|
const markersRef = useRef([]);
|
|
1769
|
-
const [status, setStatus] =
|
|
1900
|
+
const [status, setStatus] = useState("loading");
|
|
1901
|
+
const pickRef = useRef(pick);
|
|
1902
|
+
pickRef.current = pick;
|
|
1903
|
+
const selectable = pick !== void 0;
|
|
1770
1904
|
const tileUrl = basemap?.tileUrl ?? null;
|
|
1771
1905
|
const attribution = basemap?.attribution ?? null;
|
|
1772
|
-
|
|
1906
|
+
useEffect(() => {
|
|
1773
1907
|
let cancelled = false;
|
|
1774
1908
|
setStatus("loading");
|
|
1775
1909
|
Promise.all([
|
|
@@ -1797,7 +1931,7 @@ function LiveMap({
|
|
|
1797
1931
|
mapRef.current = null;
|
|
1798
1932
|
};
|
|
1799
1933
|
}, [tileUrl, attribution, runtime.workerUrl]);
|
|
1800
|
-
|
|
1934
|
+
useEffect(() => {
|
|
1801
1935
|
const map = mapRef.current;
|
|
1802
1936
|
if (status !== "ready" || !map) return;
|
|
1803
1937
|
let live = true;
|
|
@@ -1810,7 +1944,24 @@ function LiveMap({
|
|
|
1810
1944
|
el.setAttribute("data-device", position.deviceToken);
|
|
1811
1945
|
el.setAttribute("title", describePosition(position));
|
|
1812
1946
|
el.setAttribute("aria-label", describePosition(position));
|
|
1813
|
-
|
|
1947
|
+
if (selectable) {
|
|
1948
|
+
Object.assign(el.style, MARKER_HIT_STYLE);
|
|
1949
|
+
el.setAttribute("role", "button");
|
|
1950
|
+
el.setAttribute("tabindex", "0");
|
|
1951
|
+
const dot = document.createElement("div");
|
|
1952
|
+
Object.assign(dot.style, MARKER_DOT_STYLE, { cursor: "inherit" });
|
|
1953
|
+
el.appendChild(dot);
|
|
1954
|
+
const choose = () => pickRef.current?.(position.deviceToken);
|
|
1955
|
+
el.addEventListener("click", choose);
|
|
1956
|
+
el.addEventListener("keydown", (e) => {
|
|
1957
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
1958
|
+
e.preventDefault();
|
|
1959
|
+
choose();
|
|
1960
|
+
}
|
|
1961
|
+
});
|
|
1962
|
+
} else {
|
|
1963
|
+
Object.assign(el.style, MARKER_DOT_STYLE);
|
|
1964
|
+
}
|
|
1814
1965
|
return new maplibre.Marker({ element: el }).setLngLat([position.longitude, position.latitude]).addTo(map);
|
|
1815
1966
|
});
|
|
1816
1967
|
if (positions.length === 1) {
|
|
@@ -1824,21 +1975,30 @@ function LiveMap({
|
|
|
1824
1975
|
return () => {
|
|
1825
1976
|
live = false;
|
|
1826
1977
|
};
|
|
1827
|
-
}, [status, positionsKey(positions)]);
|
|
1978
|
+
}, [status, positionsKey(positions), selectable]);
|
|
1828
1979
|
if (status === "unavailable") {
|
|
1829
|
-
return /* @__PURE__ */
|
|
1980
|
+
return /* @__PURE__ */ jsx7(
|
|
1830
1981
|
PlainPanel,
|
|
1831
1982
|
{
|
|
1832
1983
|
positions,
|
|
1833
|
-
note: "Map renderer unavailable \u2014 positions are shown without a basemap."
|
|
1984
|
+
note: "Map renderer unavailable \u2014 positions are shown without a basemap.",
|
|
1985
|
+
pick
|
|
1834
1986
|
}
|
|
1835
1987
|
);
|
|
1836
1988
|
}
|
|
1837
|
-
return /* @__PURE__ */
|
|
1989
|
+
return /* @__PURE__ */ jsx7("div", { ref: containerRef, "data-testid": "map-canvas", style: { width: "100%", height: "100%" } });
|
|
1838
1990
|
}
|
|
1839
1991
|
function positionsKey(positions) {
|
|
1840
1992
|
return positions.map((p) => `${p.deviceToken}:${p.latitude}:${p.longitude}:${p.heading ?? ""}`).join("|");
|
|
1841
1993
|
}
|
|
1994
|
+
var MARKER_HIT_STYLE = {
|
|
1995
|
+
width: "24px",
|
|
1996
|
+
height: "24px",
|
|
1997
|
+
display: "flex",
|
|
1998
|
+
alignItems: "center",
|
|
1999
|
+
justifyContent: "center",
|
|
2000
|
+
cursor: "pointer"
|
|
2001
|
+
};
|
|
1842
2002
|
var MARKER_DOT_STYLE = {
|
|
1843
2003
|
width: "12px",
|
|
1844
2004
|
height: "12px",
|
|
@@ -1850,10 +2010,26 @@ var MARKER_DOT_STYLE = {
|
|
|
1850
2010
|
};
|
|
1851
2011
|
function Marker({
|
|
1852
2012
|
position,
|
|
1853
|
-
style
|
|
2013
|
+
style,
|
|
2014
|
+
pick
|
|
1854
2015
|
}) {
|
|
1855
2016
|
const label = describePosition(position);
|
|
1856
|
-
|
|
2017
|
+
if (pick) {
|
|
2018
|
+
return /* @__PURE__ */ jsx7(
|
|
2019
|
+
"button",
|
|
2020
|
+
{
|
|
2021
|
+
type: "button",
|
|
2022
|
+
"data-testid": "map-marker",
|
|
2023
|
+
"data-device": position.deviceToken,
|
|
2024
|
+
title: label,
|
|
2025
|
+
"aria-label": label,
|
|
2026
|
+
onClick: () => pick(position.deviceToken),
|
|
2027
|
+
style: { ...MARKER_HIT_STYLE, padding: 0, border: 0, background: "transparent", ...style },
|
|
2028
|
+
children: /* @__PURE__ */ jsx7("span", { style: { ...MARKER_DOT_STYLE, cursor: "inherit", display: "block" } })
|
|
2029
|
+
}
|
|
2030
|
+
);
|
|
2031
|
+
}
|
|
2032
|
+
return /* @__PURE__ */ jsx7(
|
|
1857
2033
|
"div",
|
|
1858
2034
|
{
|
|
1859
2035
|
"data-testid": "map-marker",
|
|
@@ -1882,25 +2058,25 @@ function MapNotice({ glyph, heading, detail }) {
|
|
|
1882
2058
|
color: css4("muted-foreground")
|
|
1883
2059
|
},
|
|
1884
2060
|
children: [
|
|
1885
|
-
glyph ? /* @__PURE__ */
|
|
1886
|
-
/* @__PURE__ */
|
|
1887
|
-
detail ? /* @__PURE__ */
|
|
2061
|
+
glyph ? /* @__PURE__ */ jsx7("div", { style: { fontSize: fontVar4("xl"), lineHeight: 1 }, "aria-hidden": "true", children: glyph }) : null,
|
|
2062
|
+
/* @__PURE__ */ jsx7("div", { style: { fontSize: fontVar4("md"), fontWeight: 600 }, children: heading }),
|
|
2063
|
+
detail ? /* @__PURE__ */ jsx7("div", { style: { fontSize: fontVar4("sm"), opacity: 0.8 }, children: detail }) : null
|
|
1888
2064
|
]
|
|
1889
2065
|
}
|
|
1890
2066
|
);
|
|
1891
2067
|
}
|
|
1892
|
-
var mapWidget =
|
|
2068
|
+
var mapWidget = defineWidget11({
|
|
1893
2069
|
descriptor: builtinWidgetDescriptors["map"],
|
|
1894
2070
|
implementation: { kind: "trusted-react", component: MapWidget }
|
|
1895
2071
|
});
|
|
1896
2072
|
|
|
1897
2073
|
// src/widgets/table-lazy.tsx
|
|
1898
|
-
import { defineWidget as
|
|
1899
|
-
var
|
|
1900
|
-
var loadTableWidget =
|
|
1901
|
-
var tableWidget =
|
|
2074
|
+
import { defineWidget as defineWidget12 } from "@devicechain/widget-sdk";
|
|
2075
|
+
var chunk7 = lazyChunk(() => import("./chunks/table-6EVV7QZH.js"));
|
|
2076
|
+
var loadTableWidget = chunk7.load;
|
|
2077
|
+
var tableWidget = defineWidget12({
|
|
1902
2078
|
descriptor: builtinWidgetDescriptors["table"],
|
|
1903
|
-
implementation: { kind: "trusted-react", component:
|
|
2079
|
+
implementation: { kind: "trusted-react", component: chunk7.component("Table") }
|
|
1904
2080
|
});
|
|
1905
2081
|
|
|
1906
2082
|
// src/widgets/time-series-chart.tsx
|
|
@@ -1908,7 +2084,7 @@ import { useMemo as useMemo3 } from "react";
|
|
|
1908
2084
|
import { isValidSpanSeconds, spanLabel } from "@devicechain/dashboards";
|
|
1909
2085
|
import {
|
|
1910
2086
|
css as css5,
|
|
1911
|
-
defineWidget as
|
|
2087
|
+
defineWidget as defineWidget13,
|
|
1912
2088
|
fontVar as fontVar5,
|
|
1913
2089
|
formatDateTime,
|
|
1914
2090
|
formatTimestamp as formatTimestamp2,
|
|
@@ -1923,24 +2099,31 @@ import {
|
|
|
1923
2099
|
WidgetFrame as WidgetFrame6
|
|
1924
2100
|
} from "@devicechain/widget-sdk";
|
|
1925
2101
|
import { buildLineOption, EChart as EChart2, loadChartEngine as loadChartEngine3, useChartTheme as useChartTheme2 } from "@devicechain/widget-sdk/echarts";
|
|
1926
|
-
import { jsx as
|
|
1927
|
-
function TimeSeriesChart({ widget, data }) {
|
|
1928
|
-
return /* @__PURE__ */
|
|
2102
|
+
import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
2103
|
+
function TimeSeriesChart({ widget, data, markers }) {
|
|
2104
|
+
return /* @__PURE__ */ jsx8(WidgetFrame6, { title: optString6(widget.options, "title"), flush: true, children: /* @__PURE__ */ jsx8(TimeSeriesBody, { widget, data, markers }) });
|
|
1929
2105
|
}
|
|
1930
|
-
function TimeSeriesBody({ widget, data }) {
|
|
2106
|
+
function TimeSeriesBody({ widget, data, markers }) {
|
|
1931
2107
|
const theme = useChartTheme2();
|
|
1932
2108
|
const { size, scale } = useWidgetScale2();
|
|
1933
2109
|
const measurements = widget.datasource?.measurements;
|
|
1934
2110
|
const unit = optString6(widget.options, "unit");
|
|
1935
2111
|
const precision = optNumber4(widget.options, "precision");
|
|
1936
2112
|
const thresholds = useMemo3(() => optThresholds3(widget.options, "thresholds"), [widget.options]);
|
|
1937
|
-
const
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
2113
|
+
const min = optNumber4(widget.options, "min");
|
|
2114
|
+
const max = optNumber4(widget.options, "max");
|
|
2115
|
+
const option = useMemo3(() => {
|
|
2116
|
+
const base = buildLineOption(data.samples, theme, { measurements, unit, precision, thresholds, scale, gaps: data.gaps, min, max }, size);
|
|
2117
|
+
return markers ? markers.decorate(base, size) : base;
|
|
2118
|
+
}, [data.samples, data.gaps, theme, measurements, unit, precision, thresholds, scale, size, markers, min, max]);
|
|
2119
|
+
const chart = /* @__PURE__ */ jsxs4("div", { style: { position: "relative", width: "100%", height: "100%" }, children: [
|
|
2120
|
+
/* @__PURE__ */ jsx8(EChart2, { option }),
|
|
2121
|
+
/* @__PURE__ */ jsx8(SpanBadge, { widget, data })
|
|
2122
|
+
] });
|
|
2123
|
+
if (!markers) return chart;
|
|
2124
|
+
return /* @__PURE__ */ jsxs4("div", { style: { display: "flex", flexDirection: "column", width: "100%", height: "100%" }, children: [
|
|
2125
|
+
/* @__PURE__ */ jsx8("div", { style: { flex: 1, minHeight: 0 }, children: chart }),
|
|
2126
|
+
markers.footer
|
|
1944
2127
|
] });
|
|
1945
2128
|
}
|
|
1946
2129
|
var SPAN_STRINGS = {
|
|
@@ -1970,7 +2153,7 @@ function SpanBadge({ widget, data }) {
|
|
|
1970
2153
|
const time = cutAt ? end - Date.parse(cutAt) > DAY_MS ? formatDateTime(cutAt, timeZone) : formatTimestamp2(cutAt, timeZone) : "";
|
|
1971
2154
|
const text = [showSpan ? label : "", cutAt ? words.from(time) : ""].filter(Boolean).join(" \xB7 ");
|
|
1972
2155
|
const title = [showSpan ? words.pinned(label) : "", cutAt ? words.cut(time, label) : ""].filter(Boolean).join(" ");
|
|
1973
|
-
return /* @__PURE__ */
|
|
2156
|
+
return /* @__PURE__ */ jsx8(
|
|
1974
2157
|
"span",
|
|
1975
2158
|
{
|
|
1976
2159
|
"data-chart-span": showSpan ? label : "",
|
|
@@ -1993,7 +2176,7 @@ function SpanBadge({ widget, data }) {
|
|
|
1993
2176
|
);
|
|
1994
2177
|
}
|
|
1995
2178
|
TimeSeriesChart.preload = loadChartEngine3;
|
|
1996
|
-
var timeSeriesChartWidget =
|
|
2179
|
+
var timeSeriesChartWidget = defineWidget13({
|
|
1997
2180
|
descriptor: builtinWidgetDescriptors["timeseries-chart"],
|
|
1998
2181
|
implementation: { kind: "trusted-react", component: TimeSeriesChart }
|
|
1999
2182
|
});
|
|
@@ -2008,6 +2191,7 @@ var builtinWidgetDefinitions = [
|
|
|
2008
2191
|
imageWidget,
|
|
2009
2192
|
alarmTableWidget,
|
|
2010
2193
|
alarmCountWidget,
|
|
2194
|
+
alarmSeverityWidget,
|
|
2011
2195
|
commandButtonWidget,
|
|
2012
2196
|
entitySelectorWidget,
|
|
2013
2197
|
mapWidget,
|
|
@@ -2023,7 +2207,10 @@ var builtinWidgetDefinitions = [
|
|
|
2023
2207
|
statCardWidget,
|
|
2024
2208
|
barChartWidget,
|
|
2025
2209
|
pieChartWidget,
|
|
2026
|
-
fleetTableWidget
|
|
2210
|
+
fleetTableWidget,
|
|
2211
|
+
fleetCountWidget,
|
|
2212
|
+
deviceStatusWidget,
|
|
2213
|
+
onlineDoughnutWidget
|
|
2027
2214
|
];
|
|
2028
2215
|
function createBuiltinWidgetRegistry() {
|
|
2029
2216
|
return createWidgetRegistry(builtinWidgetDefinitions);
|
|
@@ -2045,12 +2232,12 @@ import {
|
|
|
2045
2232
|
useLocationStream,
|
|
2046
2233
|
useMeasurementStream,
|
|
2047
2234
|
useWidgetCandidates,
|
|
2048
|
-
useWidgetSelect,
|
|
2235
|
+
useWidgetSelect as useWidgetSelect2,
|
|
2049
2236
|
WidgetFrame as WidgetFrame8
|
|
2050
2237
|
} from "@devicechain/widget-sdk";
|
|
2051
2238
|
|
|
2052
2239
|
// src/widget-containment.tsx
|
|
2053
|
-
import { Component, createContext as createContext3, useCallback, useContext as useContext3, useState as
|
|
2240
|
+
import { Component, createContext as createContext3, useCallback, useContext as useContext3, useState as useState2 } from "react";
|
|
2054
2241
|
import { WidgetFrame as WidgetFrame7 } from "@devicechain/widget-sdk";
|
|
2055
2242
|
|
|
2056
2243
|
// src/widget-host.ts
|
|
@@ -2109,7 +2296,7 @@ function narrowCandidates(candidates, descriptor, report) {
|
|
|
2109
2296
|
}
|
|
2110
2297
|
|
|
2111
2298
|
// src/widget-containment.tsx
|
|
2112
|
-
import { jsx as
|
|
2299
|
+
import { jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
2113
2300
|
var MESSAGE_STYLE = {
|
|
2114
2301
|
display: "flex",
|
|
2115
2302
|
flexDirection: "column",
|
|
@@ -2153,22 +2340,22 @@ var WidgetErrorBoundary = class extends Component {
|
|
|
2153
2340
|
render() {
|
|
2154
2341
|
const { error } = this.state;
|
|
2155
2342
|
if (!error) return this.props.children;
|
|
2156
|
-
return /* @__PURE__ */
|
|
2157
|
-
/* @__PURE__ */
|
|
2158
|
-
/* @__PURE__ */
|
|
2159
|
-
/* @__PURE__ */
|
|
2160
|
-
/* @__PURE__ */
|
|
2343
|
+
return /* @__PURE__ */ jsx9(WidgetFrame7, { title: this.props.title, children: /* @__PURE__ */ jsxs5("div", { style: MESSAGE_STYLE, role: "alert", children: [
|
|
2344
|
+
/* @__PURE__ */ jsx9("div", { style: { fontSize: 20, lineHeight: 1 }, "aria-hidden": "true", children: "\u26A0" }),
|
|
2345
|
+
/* @__PURE__ */ jsx9("div", { style: { fontSize: 13, fontWeight: 600 }, children: "This widget failed to render" }),
|
|
2346
|
+
/* @__PURE__ */ jsx9("div", { style: { fontSize: 11, opacity: 0.8, wordBreak: "break-word" }, children: error.message }),
|
|
2347
|
+
/* @__PURE__ */ jsx9("button", { type: "button", style: BUTTON_STYLE, onClick: this.reset, children: "Reset widget" })
|
|
2161
2348
|
] }) });
|
|
2162
2349
|
}
|
|
2163
2350
|
};
|
|
2164
2351
|
function WidgetContainment({ title, resetKey, children }) {
|
|
2165
|
-
const [messages, setMessages] =
|
|
2352
|
+
const [messages, setMessages] = useState2([]);
|
|
2166
2353
|
const report = useCallback((message) => {
|
|
2167
2354
|
setMessages((prev) => prev.includes(message) ? prev : [...prev, message].slice(-3));
|
|
2168
2355
|
}, []);
|
|
2169
2356
|
const clear = useCallback(() => setMessages([]), []);
|
|
2170
2357
|
return /* @__PURE__ */ jsxs5("div", { style: { position: "relative", width: "100%", height: "100%" }, children: [
|
|
2171
|
-
/* @__PURE__ */
|
|
2358
|
+
/* @__PURE__ */ jsx9(ReportContext.Provider, { value: report, children: /* @__PURE__ */ jsx9(WidgetErrorBoundary, { title, resetKey, onReset: clear, children }) }),
|
|
2172
2359
|
messages.length > 0 && /* @__PURE__ */ jsxs5(
|
|
2173
2360
|
"div",
|
|
2174
2361
|
{
|
|
@@ -2188,8 +2375,8 @@ function WidgetContainment({ title, resetKey, children }) {
|
|
|
2188
2375
|
alignItems: "center"
|
|
2189
2376
|
},
|
|
2190
2377
|
children: [
|
|
2191
|
-
/* @__PURE__ */
|
|
2192
|
-
/* @__PURE__ */
|
|
2378
|
+
/* @__PURE__ */ jsx9("span", { style: { flex: 1, wordBreak: "break-word" }, children: messages.join(" \xB7 ") }),
|
|
2379
|
+
/* @__PURE__ */ jsx9("button", { type: "button", "aria-label": "Dismiss", onClick: clear, style: { cursor: "pointer" }, children: "\xD7" })
|
|
2193
2380
|
]
|
|
2194
2381
|
}
|
|
2195
2382
|
)
|
|
@@ -2197,12 +2384,12 @@ function WidgetContainment({ title, resetKey, children }) {
|
|
|
2197
2384
|
}
|
|
2198
2385
|
|
|
2199
2386
|
// src/connected-widget.tsx
|
|
2200
|
-
import { jsx as
|
|
2387
|
+
import { jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
2201
2388
|
function ConnectedWidget(props) {
|
|
2202
2389
|
const { widget } = props;
|
|
2203
2390
|
const registry = props.registry ?? defaultWidgetRegistry();
|
|
2204
2391
|
const resetKey = JSON.stringify([widget.type, widget.options ?? null, widget.datasource ?? null]);
|
|
2205
|
-
return /* @__PURE__ */
|
|
2392
|
+
return /* @__PURE__ */ jsx10(WidgetContainment, { title: optString7(widget.options, "title"), resetKey, children: /* @__PURE__ */ jsx10(ConnectedWidgetBody, { ...props, registry }) });
|
|
2206
2393
|
}
|
|
2207
2394
|
function ConnectedWidgetBody({ widget, hub, registry, actions, initialSamples, initialSamplesAsOf, onReconnect }) {
|
|
2208
2395
|
const unresolved = widget.type === UNKNOWN_WIDGET_TYPE;
|
|
@@ -2212,16 +2399,16 @@ function ConnectedWidgetBody({ widget, hub, registry, actions, initialSamples, i
|
|
|
2212
2399
|
const availability = useDatasourceAvailability(hub, readsDatasource ? widget.datasource : void 0);
|
|
2213
2400
|
const supported = useDatasourceSupported(hub, readsDatasource ? widget.datasource : void 0);
|
|
2214
2401
|
if (!supported) {
|
|
2215
|
-
return /* @__PURE__ */
|
|
2402
|
+
return /* @__PURE__ */ jsx10(WidgetNotForCustomerUsersFrame, { widget });
|
|
2216
2403
|
}
|
|
2217
2404
|
if (availability === "unavailable") {
|
|
2218
|
-
return /* @__PURE__ */
|
|
2405
|
+
return /* @__PURE__ */ jsx10(WidgetUnavailableFrame, { widget });
|
|
2219
2406
|
}
|
|
2220
2407
|
if (widget.type === UNKNOWN_WIDGET_TYPE) {
|
|
2221
|
-
return /* @__PURE__ */
|
|
2408
|
+
return /* @__PURE__ */ jsx10(UnresolvedWidgetFrame, { storedType: widget.raw.type, reason: widget.reason });
|
|
2222
2409
|
}
|
|
2223
2410
|
if (!descriptor || !implementation) {
|
|
2224
|
-
return /* @__PURE__ */
|
|
2411
|
+
return /* @__PURE__ */ jsx10(
|
|
2225
2412
|
UnresolvedWidgetFrame,
|
|
2226
2413
|
{
|
|
2227
2414
|
storedType: widget.type,
|
|
@@ -2229,7 +2416,7 @@ function ConnectedWidgetBody({ widget, hub, registry, actions, initialSamples, i
|
|
|
2229
2416
|
}
|
|
2230
2417
|
);
|
|
2231
2418
|
}
|
|
2232
|
-
return /* @__PURE__ */
|
|
2419
|
+
return /* @__PURE__ */ jsx10(HostScope, { descriptor, actions, children: (hostActions) => /* @__PURE__ */ jsx10(
|
|
2233
2420
|
ChannelBody,
|
|
2234
2421
|
{
|
|
2235
2422
|
widget,
|
|
@@ -2245,8 +2432,8 @@ function ConnectedWidgetBody({ widget, hub, registry, actions, initialSamples, i
|
|
|
2245
2432
|
}
|
|
2246
2433
|
function useDatasourceSupported(hub, datasource) {
|
|
2247
2434
|
const key = datasource ? JSON.stringify(datasource) : null;
|
|
2248
|
-
const [refused, setRefused] =
|
|
2249
|
-
|
|
2435
|
+
const [refused, setRefused] = useState3(null);
|
|
2436
|
+
useEffect2(() => {
|
|
2250
2437
|
if (!datasource || !hub.isDatasourceSupported) return;
|
|
2251
2438
|
let cancelled = false;
|
|
2252
2439
|
hub.isDatasourceSupported(datasource).then(
|
|
@@ -2269,7 +2456,7 @@ function HostScope({
|
|
|
2269
2456
|
children
|
|
2270
2457
|
}) {
|
|
2271
2458
|
const report = useReportRejection();
|
|
2272
|
-
const select =
|
|
2459
|
+
const select = useWidgetSelect2();
|
|
2273
2460
|
const candidates = useWidgetCandidates();
|
|
2274
2461
|
const narrowed = useMemo4(() => narrowActions(actions, descriptor, report), [actions, descriptor, report]);
|
|
2275
2462
|
const narrowedSelect = useMemo4(() => narrowSelect(select, descriptor), [select, descriptor]);
|
|
@@ -2277,36 +2464,40 @@ function HostScope({
|
|
|
2277
2464
|
() => narrowCandidates(candidates, descriptor, report),
|
|
2278
2465
|
[candidates, descriptor, report]
|
|
2279
2466
|
);
|
|
2280
|
-
return /* @__PURE__ */
|
|
2467
|
+
return /* @__PURE__ */ jsx10(WidgetSelectProvider, { select: narrowedSelect, children: /* @__PURE__ */ jsx10(WidgetCandidatesProvider, { candidates: narrowedCandidates, children: children(narrowed) }) });
|
|
2281
2468
|
}
|
|
2282
2469
|
function ChannelBody(props) {
|
|
2283
2470
|
switch (props.descriptor.channel) {
|
|
2284
2471
|
case "alarm":
|
|
2285
|
-
return /* @__PURE__ */
|
|
2472
|
+
return /* @__PURE__ */ jsx10(AlarmConnectedWidget, { ...props });
|
|
2286
2473
|
case "control":
|
|
2287
|
-
return /* @__PURE__ */
|
|
2474
|
+
return /* @__PURE__ */ jsx10(ControlConnectedWidget, { ...props });
|
|
2288
2475
|
case "location":
|
|
2289
|
-
return /* @__PURE__ */
|
|
2476
|
+
return /* @__PURE__ */ jsx10(LocationConnectedWidget, { ...props });
|
|
2290
2477
|
case "aggregate":
|
|
2291
|
-
return /* @__PURE__ */
|
|
2478
|
+
return /* @__PURE__ */ jsx10(AggregateConnectedWidget, { ...props });
|
|
2292
2479
|
case "selection":
|
|
2293
2480
|
case "none":
|
|
2294
|
-
return /* @__PURE__ */
|
|
2481
|
+
return /* @__PURE__ */ jsx10(StaticConnectedWidget, { ...props });
|
|
2295
2482
|
case "measurement":
|
|
2296
|
-
return /* @__PURE__ */
|
|
2483
|
+
return /* @__PURE__ */ jsx10(MeasurementConnectedWidget, { ...props });
|
|
2297
2484
|
}
|
|
2298
2485
|
}
|
|
2299
2486
|
function StaticConnectedWidget({ widget, Component: Component2, actions }) {
|
|
2300
|
-
return /* @__PURE__ */
|
|
2487
|
+
return /* @__PURE__ */ jsx10(Component2, { widget, data: null, actions });
|
|
2301
2488
|
}
|
|
2302
|
-
var FleetFeed = lazyChunk(() => import("./chunks/fleet-feed-
|
|
2489
|
+
var FleetFeed = lazyChunk(() => import("./chunks/fleet-feed-2SKDR6ZQ.js")).component("default", void 0, ChunkLoadingFrame);
|
|
2490
|
+
var PresenceFeed = lazyChunk(() => import("./chunks/presence-widgets-2LIUKN4Y.js")).component("PresenceFeed");
|
|
2303
2491
|
function MeasurementConnectedWidget(props) {
|
|
2492
|
+
if (presenceMode(props.descriptor)) {
|
|
2493
|
+
return /* @__PURE__ */ jsx10(PresenceFeed, { hub: props.hub, widget: props.widget, descriptor: props.descriptor, Component: props.Component, actions: props.actions, ErrorFrame: WidgetErrorFrame });
|
|
2494
|
+
}
|
|
2304
2495
|
const { widget, hub, descriptor, Component: Component2, actions } = props;
|
|
2305
2496
|
const members = membersMode(descriptor, widget);
|
|
2306
2497
|
if (members || widget.datasource?.kind === "anchor") {
|
|
2307
|
-
return /* @__PURE__ */
|
|
2498
|
+
return /* @__PURE__ */ jsx10(FleetFeed, { hub, widget, descriptor, Component: Component2, actions, ErrorFrame: WidgetErrorFrame, refuse: !members });
|
|
2308
2499
|
}
|
|
2309
|
-
return /* @__PURE__ */
|
|
2500
|
+
return /* @__PURE__ */ jsx10(StreamConnectedWidget, { ...props });
|
|
2310
2501
|
}
|
|
2311
2502
|
function StreamConnectedWidget({ widget, hub, descriptor, Component: Component2, actions, initialSamples, initialSamplesAsOf, onReconnect }) {
|
|
2312
2503
|
const range = useWidgetTimeRange2();
|
|
@@ -2322,42 +2513,58 @@ function StreamConnectedWidget({ widget, hub, descriptor, Component: Component2,
|
|
|
2322
2513
|
});
|
|
2323
2514
|
const freshness = useMemo4(() => {
|
|
2324
2515
|
if (descriptor.freshness !== true) return void 0;
|
|
2325
|
-
const pinned = optString7(widget.options, "measurement");
|
|
2516
|
+
const pinned = measurementIsMembersOnly(descriptor) ? void 0 : optString7(widget.options, "measurement");
|
|
2326
2517
|
const names = pinned ? [pinned] : widget.datasource?.measurements;
|
|
2327
2518
|
return {
|
|
2328
2519
|
at: newestSampleTime(data.latest, names),
|
|
2329
2520
|
staleAfterSeconds: resolveStaleAfterSeconds(widget.options)
|
|
2330
2521
|
};
|
|
2331
2522
|
}, [descriptor, widget.options, widget.datasource, data.latest]);
|
|
2332
|
-
if (data.error) return /* @__PURE__ */
|
|
2333
|
-
return /* @__PURE__ */
|
|
2523
|
+
if (data.error) return /* @__PURE__ */ jsx10(WidgetErrorFrame, { widget, error: data.error });
|
|
2524
|
+
return /* @__PURE__ */ jsx10(WidgetFreshnessProvider, { freshness, children: wantsEventMarkers(descriptor, widget) ? /* @__PURE__ */ jsx10(EventMarkersFeed, { hub, widget, descriptor, data, Component: Component2, actions }) : /* @__PURE__ */ jsx10(Component2, { widget, data, actions }) });
|
|
2334
2525
|
}
|
|
2335
|
-
var
|
|
2526
|
+
var EventMarkersFeed = lazyChunk(() => import("./chunks/event-markers-feed-GEGTIHXT.js")).component("default");
|
|
2527
|
+
var AggregateFeed = lazyChunk(() => import("./chunks/aggregate-feed-4FSBQYJL.js")).component("default");
|
|
2336
2528
|
function AggregateConnectedWidget({ widget, hub, descriptor, Component: Component2, actions }) {
|
|
2337
2529
|
const props = { hub, widget, descriptor, Component: Component2, actions, ErrorFrame: WidgetErrorFrame };
|
|
2338
|
-
return widget.datasource?.kind === "anchor" ? /* @__PURE__ */
|
|
2530
|
+
return widget.datasource?.kind === "anchor" ? /* @__PURE__ */ jsx10(FleetFeed, { ...props, refuse: true }) : /* @__PURE__ */ jsx10(AggregateFeed, { ...props });
|
|
2339
2531
|
}
|
|
2340
|
-
|
|
2532
|
+
var GroupedAlarm = lazyChunk(() => import("./chunks/alarm-widgets-X4PX5MYJ.js")).component("GroupedAlarm");
|
|
2533
|
+
function AlarmConnectedWidget(props) {
|
|
2534
|
+
return groupsAlarmsByDeviceType(props.descriptor, props.widget) ? /* @__PURE__ */ jsx10(
|
|
2535
|
+
GroupedAlarm,
|
|
2536
|
+
{
|
|
2537
|
+
hub: props.hub,
|
|
2538
|
+
widget: props.widget,
|
|
2539
|
+
base: alarmSubscription(props.descriptor, props.widget),
|
|
2540
|
+
useHeld,
|
|
2541
|
+
Component: props.Component,
|
|
2542
|
+
actions: props.actions,
|
|
2543
|
+
ErrorFrame: WidgetErrorFrame
|
|
2544
|
+
}
|
|
2545
|
+
) : /* @__PURE__ */ jsx10(PlainAlarmConnectedWidget, { ...props });
|
|
2546
|
+
}
|
|
2547
|
+
function PlainAlarmConnectedWidget({ widget, hub, descriptor, Component: Component2, actions }) {
|
|
2341
2548
|
const range = useWidgetTimeRange2();
|
|
2342
2549
|
const live = useAlarmStream(hub, alarmSubscription(descriptor, widget));
|
|
2343
2550
|
const data = useHeld(live, range?.paused === true, (s) => !s.loading);
|
|
2344
2551
|
if (data.error && data.alarms.length === 0 && data.total === 0) {
|
|
2345
|
-
return /* @__PURE__ */
|
|
2552
|
+
return /* @__PURE__ */ jsx10(WidgetErrorFrame, { widget, error: data.error });
|
|
2346
2553
|
}
|
|
2347
|
-
return /* @__PURE__ */
|
|
2554
|
+
return /* @__PURE__ */ jsx10(Component2, { widget, data, actions });
|
|
2348
2555
|
}
|
|
2349
2556
|
function ControlConnectedWidget({ widget, hub, descriptor, Component: Component2, actions }) {
|
|
2350
2557
|
const data = useCommandStream(hub, commandSubscription(descriptor, widget));
|
|
2351
|
-
return /* @__PURE__ */
|
|
2558
|
+
return /* @__PURE__ */ jsx10(Component2, { widget, data, actions });
|
|
2352
2559
|
}
|
|
2353
2560
|
function LocationConnectedWidget({ widget, hub, Component: Component2, actions }) {
|
|
2354
2561
|
const range = useWidgetTimeRange2();
|
|
2355
2562
|
const live = useLocationStream(hub, { datasource: widget.datasource });
|
|
2356
2563
|
const data = useHeld(live, range?.paused === true, (s) => !s.loading);
|
|
2357
2564
|
if (data.error && data.locations.length === 0) {
|
|
2358
|
-
return /* @__PURE__ */
|
|
2565
|
+
return /* @__PURE__ */ jsx10(WidgetErrorFrame, { widget, error: data.error });
|
|
2359
2566
|
}
|
|
2360
|
-
return /* @__PURE__ */
|
|
2567
|
+
return /* @__PURE__ */ jsx10(Component2, { widget, data, actions });
|
|
2361
2568
|
}
|
|
2362
2569
|
var STATE_STYLE = {
|
|
2363
2570
|
display: "flex",
|
|
@@ -2378,64 +2585,64 @@ function UnresolvedWidgetFrame({
|
|
|
2378
2585
|
}) {
|
|
2379
2586
|
const storedType = typeof stored === "string" ? stored : "";
|
|
2380
2587
|
const heading = (reason?.code ?? "unregistered") === "unregistered" ? "This widget needs a newer viewer" : "This widget cannot be shown here";
|
|
2381
|
-
return /* @__PURE__ */
|
|
2588
|
+
return /* @__PURE__ */ jsx10(WidgetFrame8, { children: /* @__PURE__ */ jsxs6(
|
|
2382
2589
|
"div",
|
|
2383
2590
|
{
|
|
2384
2591
|
style: STATE_STYLE,
|
|
2385
2592
|
children: [
|
|
2386
|
-
/* @__PURE__ */
|
|
2593
|
+
/* @__PURE__ */ jsx10("div", { style: { fontSize: 13, fontWeight: 600 }, children: heading }),
|
|
2387
2594
|
storedType && !reason?.message.includes(storedType) && /* @__PURE__ */ jsxs6("div", { style: { fontSize: 11, opacity: 0.8 }, children: [
|
|
2388
2595
|
"Widget type: ",
|
|
2389
2596
|
storedType
|
|
2390
2597
|
] }),
|
|
2391
|
-
reason && /* @__PURE__ */
|
|
2598
|
+
reason && /* @__PURE__ */ jsx10("div", { style: { fontSize: 11, opacity: 0.8, wordBreak: "break-word" }, children: reason.message })
|
|
2392
2599
|
]
|
|
2393
2600
|
}
|
|
2394
2601
|
) });
|
|
2395
2602
|
}
|
|
2396
2603
|
function WidgetForbiddenFrame({ widget }) {
|
|
2397
|
-
return /* @__PURE__ */
|
|
2398
|
-
/* @__PURE__ */
|
|
2399
|
-
/* @__PURE__ */
|
|
2604
|
+
return /* @__PURE__ */ jsx10(WidgetFrame8, { title: optString7(widget.options, "title"), children: /* @__PURE__ */ jsxs6("div", { role: "status", style: STATE_STYLE, children: [
|
|
2605
|
+
/* @__PURE__ */ jsx10("div", { style: { fontSize: 20, lineHeight: 1 }, "aria-hidden": "true", children: "\u2298" }),
|
|
2606
|
+
/* @__PURE__ */ jsx10("div", { style: { fontSize: 13, fontWeight: 600 }, children: accessStrings().forbidden })
|
|
2400
2607
|
] }) });
|
|
2401
2608
|
}
|
|
2402
2609
|
function WidgetUnavailableFrame({ widget }) {
|
|
2403
|
-
return /* @__PURE__ */
|
|
2610
|
+
return /* @__PURE__ */ jsx10(WidgetFrame8, { title: optString7(widget.options, "title"), children: /* @__PURE__ */ jsxs6(
|
|
2404
2611
|
"div",
|
|
2405
2612
|
{
|
|
2406
2613
|
style: STATE_STYLE,
|
|
2407
2614
|
children: [
|
|
2408
|
-
/* @__PURE__ */
|
|
2409
|
-
/* @__PURE__ */
|
|
2410
|
-
/* @__PURE__ */
|
|
2615
|
+
/* @__PURE__ */ jsx10("div", { style: { fontSize: 20, lineHeight: 1 }, "aria-hidden": "true", children: "\u2298" }),
|
|
2616
|
+
/* @__PURE__ */ jsx10("div", { style: { fontSize: 13, fontWeight: 600 }, children: "Device unavailable" }),
|
|
2617
|
+
/* @__PURE__ */ jsx10("div", { style: { fontSize: 11, opacity: 0.8 }, children: "The bound device no longer exists." })
|
|
2411
2618
|
]
|
|
2412
2619
|
}
|
|
2413
2620
|
) });
|
|
2414
2621
|
}
|
|
2415
2622
|
function WidgetNotForCustomerUsersFrame({ widget }) {
|
|
2416
|
-
return /* @__PURE__ */
|
|
2623
|
+
return /* @__PURE__ */ jsx10(WidgetFrame8, { title: optString7(widget.options, "title"), children: /* @__PURE__ */ jsxs6(
|
|
2417
2624
|
"div",
|
|
2418
2625
|
{
|
|
2419
2626
|
role: "status",
|
|
2420
2627
|
style: STATE_STYLE,
|
|
2421
2628
|
children: [
|
|
2422
|
-
/* @__PURE__ */
|
|
2423
|
-
/* @__PURE__ */
|
|
2424
|
-
/* @__PURE__ */
|
|
2629
|
+
/* @__PURE__ */ jsx10("div", { style: { fontSize: 20, lineHeight: 1 }, "aria-hidden": "true", children: "\u2298" }),
|
|
2630
|
+
/* @__PURE__ */ jsx10("div", { style: { fontSize: 13, fontWeight: 600 }, children: "Not available for customer users" }),
|
|
2631
|
+
/* @__PURE__ */ jsx10("div", { style: { fontSize: 11, opacity: 0.8 }, children: "This widget is bound to an area or an asset, which customer users cannot view." })
|
|
2425
2632
|
]
|
|
2426
2633
|
}
|
|
2427
2634
|
) });
|
|
2428
2635
|
}
|
|
2429
2636
|
function WidgetErrorFrame({ widget, error }) {
|
|
2430
|
-
if (isForbiddenError(error)) return /* @__PURE__ */
|
|
2431
|
-
return /* @__PURE__ */
|
|
2637
|
+
if (isForbiddenError(error)) return /* @__PURE__ */ jsx10(WidgetForbiddenFrame, { widget });
|
|
2638
|
+
return /* @__PURE__ */ jsx10(WidgetFrame8, { title: optString7(widget.options, "title"), children: /* @__PURE__ */ jsxs6(
|
|
2432
2639
|
"div",
|
|
2433
2640
|
{
|
|
2434
2641
|
style: STATE_STYLE,
|
|
2435
2642
|
children: [
|
|
2436
|
-
/* @__PURE__ */
|
|
2437
|
-
/* @__PURE__ */
|
|
2438
|
-
/* @__PURE__ */
|
|
2643
|
+
/* @__PURE__ */ jsx10("div", { style: { fontSize: 20, lineHeight: 1 }, children: "\u26A0" }),
|
|
2644
|
+
/* @__PURE__ */ jsx10("div", { style: { fontSize: 13, fontWeight: 600 }, children: "Data unavailable" }),
|
|
2645
|
+
/* @__PURE__ */ jsx10("div", { style: { fontSize: 11, opacity: 0.8, wordBreak: "break-word" }, children: String(error) })
|
|
2439
2646
|
]
|
|
2440
2647
|
}
|
|
2441
2648
|
) });
|
|
@@ -2449,7 +2656,7 @@ import {
|
|
|
2449
2656
|
WidgetThemeRootProvider,
|
|
2450
2657
|
WidgetTimeZoneProvider
|
|
2451
2658
|
} from "@devicechain/widget-sdk";
|
|
2452
|
-
import { Fragment as Fragment2, jsx as
|
|
2659
|
+
import { Fragment as Fragment2, jsx as jsx11, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2453
2660
|
function DashboardRenderer({
|
|
2454
2661
|
definition,
|
|
2455
2662
|
hub,
|
|
@@ -2498,8 +2705,8 @@ function DashboardRenderer({
|
|
|
2498
2705
|
"data-time-paused": range.paused ? "" : void 0,
|
|
2499
2706
|
style: { ...sizingStyle(effectiveSizing, bg), ...tokenStyle(scale) },
|
|
2500
2707
|
children: [
|
|
2501
|
-
/* @__PURE__ */
|
|
2502
|
-
/* @__PURE__ */
|
|
2708
|
+
/* @__PURE__ */ jsx11(WidgetTokenStyles, {}),
|
|
2709
|
+
/* @__PURE__ */ jsx11(WidgetDensityProvider, { scale, children: /* @__PURE__ */ jsx11(WidgetThemeRootProvider, { root: themeRoot, children: /* @__PURE__ */ jsx11(WidgetTimeZoneProvider, { timeZone, children: /* @__PURE__ */ jsx11(WidgetTimeRangeProvider, { range, children: /* @__PURE__ */ jsx11(WidgetSelectProvider2, { select, children: /* @__PURE__ */ jsx11(WidgetCandidatesProvider2, { candidates, children: /* @__PURE__ */ jsx11("div", { style: { padding: lengths.padding }, children: /* @__PURE__ */ jsx11("div", { style: { containerType: "inline-size" }, children: /* @__PURE__ */ jsx11(
|
|
2503
2710
|
"div",
|
|
2504
2711
|
{
|
|
2505
2712
|
"data-grid": "",
|
|
@@ -2512,7 +2719,7 @@ function DashboardRenderer({
|
|
|
2512
2719
|
width: "100%",
|
|
2513
2720
|
...{ "--dc-cell": lengths.cell }
|
|
2514
2721
|
},
|
|
2515
|
-
children: /* @__PURE__ */
|
|
2722
|
+
children: /* @__PURE__ */ jsx11(
|
|
2516
2723
|
PlacedWidgets,
|
|
2517
2724
|
{
|
|
2518
2725
|
widgets,
|
|
@@ -2520,7 +2727,7 @@ function DashboardRenderer({
|
|
|
2520
2727
|
columns,
|
|
2521
2728
|
grid: layout.grid,
|
|
2522
2729
|
lengths,
|
|
2523
|
-
render: (widget) => /* @__PURE__ */
|
|
2730
|
+
render: (widget) => /* @__PURE__ */ jsx11(WidgetFrameStyleProvider, { frame: resolveFrame(canvasFrame, widgetFrame(widget)), children: /* @__PURE__ */ jsx11(WidgetSubjectProvider, { label: widgetSubjectLabel(widget), children: /* @__PURE__ */ jsx11(
|
|
2524
2731
|
ConnectedWidget,
|
|
2525
2732
|
{
|
|
2526
2733
|
widget,
|
|
@@ -2608,15 +2815,15 @@ function PlacedWidgets({
|
|
|
2608
2815
|
relative(widget.id)
|
|
2609
2816
|
] }, widget.id)
|
|
2610
2817
|
));
|
|
2611
|
-
return /* @__PURE__ */
|
|
2818
|
+
return /* @__PURE__ */ jsx11(Fragment2, { children: placed.map(({ widget, placement }) => {
|
|
2612
2819
|
if (placement.mode !== "grid") return null;
|
|
2613
2820
|
const style = gridItemStyle(grid.get(widget.id) ?? placement, columns);
|
|
2614
2821
|
return /* @__PURE__ */ jsxs7(Fragment, { children: [
|
|
2615
|
-
/* @__PURE__ */
|
|
2822
|
+
/* @__PURE__ */ jsx11("div", { "data-widget": widget.id, style, children: render(widget) }),
|
|
2616
2823
|
dependents.has(widget.id) ? (
|
|
2617
2824
|
// The host's area again, as a layer for its relative widgets to be positioned in.
|
|
2618
2825
|
// It takes no pointer events itself, so the host underneath stays usable.
|
|
2619
|
-
/* @__PURE__ */
|
|
2826
|
+
/* @__PURE__ */ jsx11("div", { style: { ...style, position: "relative", pointerEvents: "none", zIndex: RELATIVE_Z }, children: relative(widget.id) })
|
|
2620
2827
|
) : null
|
|
2621
2828
|
] }, widget.id);
|
|
2622
2829
|
}) });
|
|
@@ -2647,7 +2854,7 @@ function widgetSubjectLabel(widget) {
|
|
|
2647
2854
|
}
|
|
2648
2855
|
function useContainerWidth(keyOf) {
|
|
2649
2856
|
const ref = useRef2(null);
|
|
2650
|
-
const [width, setWidth] =
|
|
2857
|
+
const [width, setWidth] = useState4(0);
|
|
2651
2858
|
const keyOfRef = useRef2(keyOf);
|
|
2652
2859
|
const measure = useCallback2(() => {
|
|
2653
2860
|
const el = ref.current;
|
|
@@ -2676,12 +2883,12 @@ function seedKey(widget, registry) {
|
|
|
2676
2883
|
return JSON.stringify(widget.datasource ?? null);
|
|
2677
2884
|
}
|
|
2678
2885
|
function useWidgetHistories(widgets, enabled, registry, range) {
|
|
2679
|
-
const [seeds, setSeeds] =
|
|
2886
|
+
const [seeds, setSeeds] = useState4({});
|
|
2680
2887
|
const requested = useRef2({});
|
|
2681
2888
|
const reseeds = useRef2({});
|
|
2682
|
-
const [reseedTick, bumpReseeds] =
|
|
2889
|
+
const [reseedTick, bumpReseeds] = useState4(0);
|
|
2683
2890
|
const mounted = useRef2(true);
|
|
2684
|
-
|
|
2891
|
+
useEffect3(() => {
|
|
2685
2892
|
mounted.current = true;
|
|
2686
2893
|
return () => {
|
|
2687
2894
|
mounted.current = false;
|
|
@@ -2699,7 +2906,7 @@ function useWidgetHistories(widgets, enabled, registry, range) {
|
|
|
2699
2906
|
return [[w.id, key, span]];
|
|
2700
2907
|
});
|
|
2701
2908
|
const wantedKey = JSON.stringify(wanted);
|
|
2702
|
-
|
|
2909
|
+
useEffect3(() => {
|
|
2703
2910
|
if (!enabled) {
|
|
2704
2911
|
requested.current = {};
|
|
2705
2912
|
setSeeds({});
|
|
@@ -2759,12 +2966,12 @@ import {
|
|
|
2759
2966
|
spanLabel as spanLabel2,
|
|
2760
2967
|
withSpan
|
|
2761
2968
|
} from "@devicechain/dashboards";
|
|
2762
|
-
import { useCallback as useCallback3, useEffect as
|
|
2763
|
-
import { jsx as
|
|
2969
|
+
import { useCallback as useCallback3, useEffect as useEffect4, useMemo as useMemo6, useRef as useRef3, useState as useState5 } from "react";
|
|
2970
|
+
import { jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2764
2971
|
function useBoardTimeRange(defaultSeconds, link = {}) {
|
|
2765
|
-
const [state, setState] =
|
|
2972
|
+
const [state, setState] = useState5(() => initialTimeRange2(defaultSeconds, link));
|
|
2766
2973
|
const lastDefault = useRef3(defaultSeconds);
|
|
2767
|
-
|
|
2974
|
+
useEffect4(() => {
|
|
2768
2975
|
if (lastDefault.current === defaultSeconds) return;
|
|
2769
2976
|
lastDefault.current = defaultSeconds;
|
|
2770
2977
|
setState((s) => withSpan(s, isValidSpanSeconds2(defaultSeconds) ? defaultSeconds : DEFAULT_TIME_RANGE_SECONDS));
|
|
@@ -2823,10 +3030,10 @@ function PausedIndicator({
|
|
|
2823
3030
|
borderRadius: 4
|
|
2824
3031
|
},
|
|
2825
3032
|
children: [
|
|
2826
|
-
/* @__PURE__ */
|
|
3033
|
+
/* @__PURE__ */ jsx12("span", { "aria-hidden": "true", children: "\u23F8" }),
|
|
2827
3034
|
labels.paused,
|
|
2828
|
-
time ? /* @__PURE__ */
|
|
2829
|
-
/* @__PURE__ */
|
|
3035
|
+
time ? /* @__PURE__ */ jsx12("span", { style: { fontWeight: 400, textTransform: "none" }, children: ` ${time}` }) : null,
|
|
3036
|
+
/* @__PURE__ */ jsx12("span", { "data-time-range-actions-live": "", style: { fontWeight: 400, textTransform: "none" }, children: `\xB7 ${labels.actionsLive}` })
|
|
2830
3037
|
]
|
|
2831
3038
|
}
|
|
2832
3039
|
);
|
|
@@ -2846,8 +3053,8 @@ function TimeRangeBar({
|
|
|
2846
3053
|
"aria-label": labels.range,
|
|
2847
3054
|
style: { display: "inline-flex", alignItems: "center", gap: 6, flexWrap: "wrap" },
|
|
2848
3055
|
children: [
|
|
2849
|
-
preset === void 0 ? /* @__PURE__ */
|
|
2850
|
-
TIME_RANGE_PRESETS.map((p) => /* @__PURE__ */
|
|
3056
|
+
preset === void 0 ? /* @__PURE__ */ jsx12("button", { type: "button", "aria-pressed": "true", "data-range": spanLabel2(state.spanSeconds), style: button(true), children: spanLabel2(state.spanSeconds) }) : null,
|
|
3057
|
+
TIME_RANGE_PRESETS.map((p) => /* @__PURE__ */ jsx12(
|
|
2851
3058
|
"button",
|
|
2852
3059
|
{
|
|
2853
3060
|
type: "button",
|
|
@@ -2859,12 +3066,348 @@ function TimeRangeBar({
|
|
|
2859
3066
|
},
|
|
2860
3067
|
p.id
|
|
2861
3068
|
)),
|
|
2862
|
-
/* @__PURE__ */
|
|
2863
|
-
state.paused ? /* @__PURE__ */
|
|
3069
|
+
/* @__PURE__ */ jsx12("button", { type: "button", "aria-pressed": state.paused, "data-time-range-pause": "", onClick: onPause, style: button(state.paused), children: state.paused ? labels.resume : labels.pause }),
|
|
3070
|
+
state.paused ? /* @__PURE__ */ jsx12(PausedIndicator, { pausedAt: state.pausedAt, labels }) : null
|
|
3071
|
+
]
|
|
3072
|
+
}
|
|
3073
|
+
);
|
|
3074
|
+
}
|
|
3075
|
+
|
|
3076
|
+
// src/use-bound-devices.ts
|
|
3077
|
+
import {
|
|
3078
|
+
bindParamsOf,
|
|
3079
|
+
bindsToSelection,
|
|
3080
|
+
parseBindParams,
|
|
3081
|
+
selectionToBinds,
|
|
3082
|
+
validateBinds,
|
|
3083
|
+
withBindParams
|
|
3084
|
+
} from "@devicechain/dashboards";
|
|
3085
|
+
import { useCallback as useCallback4, useEffect as useEffect5, useRef as useRef4, useState as useState6 } from "react";
|
|
3086
|
+
var NO_PROBLEMS = { issues: [], missing: [], failed: [] };
|
|
3087
|
+
function hasBindParams(search, definition) {
|
|
3088
|
+
const { binds, issues } = parseBindParams(search, definition);
|
|
3089
|
+
return Object.keys(binds).length > 0 || issues.length > 0;
|
|
3090
|
+
}
|
|
3091
|
+
function useBoundDevices({
|
|
3092
|
+
definition,
|
|
3093
|
+
resolver,
|
|
3094
|
+
address,
|
|
3095
|
+
enabled = true
|
|
3096
|
+
}) {
|
|
3097
|
+
const [core, setCore] = useState6(() => ({
|
|
3098
|
+
selection: {},
|
|
3099
|
+
synced: bindParamsOf(address.search)
|
|
3100
|
+
}));
|
|
3101
|
+
const { selection } = core;
|
|
3102
|
+
const [phase, setPhase] = useState6(
|
|
3103
|
+
() => hasBindParams(address.search, definition) ? "checking" : "ready"
|
|
3104
|
+
);
|
|
3105
|
+
const [problems, setProblems] = useState6(null);
|
|
3106
|
+
const [okBinds, setOkBinds] = useState6({});
|
|
3107
|
+
const definitionRef = useRef4(definition);
|
|
3108
|
+
definitionRef.current = definition;
|
|
3109
|
+
const resolverRef = useRef4(resolver);
|
|
3110
|
+
resolverRef.current = resolver;
|
|
3111
|
+
const replaceRef = useRef4(address.replaceSearch);
|
|
3112
|
+
replaceRef.current = address.replaceSearch;
|
|
3113
|
+
const seenRef = useRef4(null);
|
|
3114
|
+
const generation = useRef4(0);
|
|
3115
|
+
const [attempt, setAttempt] = useState6(0);
|
|
3116
|
+
const search = address.search;
|
|
3117
|
+
useEffect5(() => {
|
|
3118
|
+
if (!enabled) return;
|
|
3119
|
+
const slice = bindParamsOf(search);
|
|
3120
|
+
if (seenRef.current === slice) return;
|
|
3121
|
+
seenRef.current = slice;
|
|
3122
|
+
const parsed = parseBindParams(search, definitionRef.current);
|
|
3123
|
+
if (Object.keys(parsed.binds).length === 0 && parsed.issues.length === 0) {
|
|
3124
|
+
generation.current += 1;
|
|
3125
|
+
setCore({ selection: {}, synced: slice });
|
|
3126
|
+
setProblems(null);
|
|
3127
|
+
setPhase("ready");
|
|
3128
|
+
return;
|
|
3129
|
+
}
|
|
3130
|
+
const gen = ++generation.current;
|
|
3131
|
+
setPhase("checking");
|
|
3132
|
+
void validateBinds(parsed.binds, resolverRef.current).then((check) => {
|
|
3133
|
+
if (gen !== generation.current) return;
|
|
3134
|
+
setOkBinds(check.ok);
|
|
3135
|
+
if (parsed.issues.length === 0 && check.missing.length === 0 && check.failed.length === 0) {
|
|
3136
|
+
setCore({ selection: bindsToSelection(check.ok), synced: slice });
|
|
3137
|
+
setProblems(null);
|
|
3138
|
+
setPhase("ready");
|
|
3139
|
+
} else {
|
|
3140
|
+
setProblems({ issues: parsed.issues, missing: check.missing, failed: check.failed });
|
|
3141
|
+
setCore((c) => ({ ...c, synced: slice }));
|
|
3142
|
+
setPhase("refused");
|
|
3143
|
+
}
|
|
3144
|
+
});
|
|
3145
|
+
}, [search, enabled, attempt]);
|
|
3146
|
+
useEffect5(() => {
|
|
3147
|
+
if (!enabled || phase !== "ready") return;
|
|
3148
|
+
const current = bindParamsOf(search);
|
|
3149
|
+
if (current !== core.synced) return;
|
|
3150
|
+
const next = withBindParams(search, selectionToBinds(core.selection, definition));
|
|
3151
|
+
const nextSlice = bindParamsOf(next);
|
|
3152
|
+
if (nextSlice === current) return;
|
|
3153
|
+
seenRef.current = nextSlice;
|
|
3154
|
+
setCore((c) => ({ ...c, synced: nextSlice }));
|
|
3155
|
+
replaceRef.current(next);
|
|
3156
|
+
}, [core, definition, phase, enabled, search]);
|
|
3157
|
+
const select = useCallback4((t) => {
|
|
3158
|
+
setCore((c) => ({ ...c, selection: { ...c.selection, [t.slot]: t.binding } }));
|
|
3159
|
+
}, []);
|
|
3160
|
+
const reset = useCallback4(() => setCore((c) => ({ ...c, selection: {} })), []);
|
|
3161
|
+
const dismiss = useCallback4(() => {
|
|
3162
|
+
setCore((c) => ({ ...c, selection: bindsToSelection(okBinds) }));
|
|
3163
|
+
setProblems(null);
|
|
3164
|
+
setPhase("ready");
|
|
3165
|
+
}, [okBinds]);
|
|
3166
|
+
const retry = useCallback4(() => {
|
|
3167
|
+
seenRef.current = null;
|
|
3168
|
+
setAttempt((n) => n + 1);
|
|
3169
|
+
}, []);
|
|
3170
|
+
return { selection, select, reset, phase, problems: phase === "refused" ? problems ?? NO_PROBLEMS : null, dismiss, retry };
|
|
3171
|
+
}
|
|
3172
|
+
|
|
3173
|
+
// src/bound-devices-notice.tsx
|
|
3174
|
+
import { css as css6, fontVar as fontVar6 } from "@devicechain/widget-sdk";
|
|
3175
|
+
import { jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
3176
|
+
function BoundDevicesNotice({ title, lines, dismissLabel, onDismiss, retryLabel, onRetry }) {
|
|
3177
|
+
const button2 = {
|
|
3178
|
+
minHeight: 44,
|
|
3179
|
+
padding: "0 16px",
|
|
3180
|
+
borderRadius: 8,
|
|
3181
|
+
border: `1px solid ${css6("border")}`,
|
|
3182
|
+
background: css6("card"),
|
|
3183
|
+
color: css6("foreground"),
|
|
3184
|
+
fontSize: fontVar6("md"),
|
|
3185
|
+
cursor: "pointer"
|
|
3186
|
+
};
|
|
3187
|
+
return /* @__PURE__ */ jsxs9(
|
|
3188
|
+
"div",
|
|
3189
|
+
{
|
|
3190
|
+
role: "alert",
|
|
3191
|
+
"data-testid": "bound-devices-notice",
|
|
3192
|
+
style: {
|
|
3193
|
+
boxSizing: "border-box",
|
|
3194
|
+
display: "flex",
|
|
3195
|
+
flexDirection: "column",
|
|
3196
|
+
alignItems: "flex-start",
|
|
3197
|
+
gap: 12,
|
|
3198
|
+
maxWidth: 560,
|
|
3199
|
+
margin: "24px auto",
|
|
3200
|
+
padding: 16,
|
|
3201
|
+
borderRadius: 8,
|
|
3202
|
+
border: `1px solid ${css6("border")}`,
|
|
3203
|
+
background: css6("card"),
|
|
3204
|
+
color: css6("foreground")
|
|
3205
|
+
},
|
|
3206
|
+
children: [
|
|
3207
|
+
/* @__PURE__ */ jsx13("div", { style: { fontSize: fontVar6("lg"), fontWeight: 600 }, children: title }),
|
|
3208
|
+
/* @__PURE__ */ jsx13("ul", { style: { margin: 0, paddingLeft: 20, display: "flex", flexDirection: "column", gap: 4, fontSize: fontVar6("md") }, children: lines.map((line, i) => /* @__PURE__ */ jsx13("li", { style: { overflowWrap: "anywhere" }, children: line }, i)) }),
|
|
3209
|
+
/* @__PURE__ */ jsxs9("div", { style: { display: "flex", flexWrap: "wrap", gap: 8 }, children: [
|
|
3210
|
+
retryLabel && onRetry ? /* @__PURE__ */ jsx13("button", { type: "button", style: button2, onClick: onRetry, "data-testid": "bound-devices-retry", children: retryLabel }) : null,
|
|
3211
|
+
/* @__PURE__ */ jsx13("button", { type: "button", style: button2, onClick: onDismiss, "data-testid": "bound-devices-dismiss", children: dismissLabel })
|
|
3212
|
+
] })
|
|
2864
3213
|
]
|
|
2865
3214
|
}
|
|
2866
3215
|
);
|
|
2867
3216
|
}
|
|
3217
|
+
var ECHO_MAX = 48;
|
|
3218
|
+
var echo = (s) => s.length > ECHO_MAX ? `${s.slice(0, ECHO_MAX)}\u2026` : s;
|
|
3219
|
+
function describeBoundDevicesProblems(problems, w) {
|
|
3220
|
+
const out = [];
|
|
3221
|
+
for (const i of problems.issues) {
|
|
3222
|
+
const slot = echo(i.slot);
|
|
3223
|
+
if (i.kind === "unknown-slot") out.push(w.unknownSlot(slot));
|
|
3224
|
+
else if (i.kind === "not-a-device-slot") out.push(w.notADeviceSlot(slot));
|
|
3225
|
+
else if (i.kind === "duplicate-slot") out.push(w.duplicateSlot(slot));
|
|
3226
|
+
else if (i.kind === "derived-slot") out.push(w.derivedSlot(slot));
|
|
3227
|
+
else if (i.kind === "invalid-token") out.push(w.invalidToken(slot, echo(i.token)));
|
|
3228
|
+
else {
|
|
3229
|
+
const unhandled = i;
|
|
3230
|
+
throw new Error(`describeBoundDevicesProblems: unworded link issue ${JSON.stringify(unhandled)}`);
|
|
3231
|
+
}
|
|
3232
|
+
}
|
|
3233
|
+
for (const m of problems.missing) out.push(w.missing(m.slot, m.token));
|
|
3234
|
+
for (const f of problems.failed) out.push(w.failed(f.slot, f.token));
|
|
3235
|
+
return out;
|
|
3236
|
+
}
|
|
3237
|
+
|
|
3238
|
+
// src/documented-descriptors.ts
|
|
3239
|
+
import { createWidgetCatalog as createWidgetCatalog2 } from "@devicechain/dashboards";
|
|
3240
|
+
import { createWidgetRegistry as createWidgetRegistry2 } from "@devicechain/widget-sdk";
|
|
3241
|
+
|
|
3242
|
+
// src/builtin-option-docs.ts
|
|
3243
|
+
var OPTION_DOCS = {
|
|
3244
|
+
title: "Heading shown in the widget frame. Blank hides the frame heading.",
|
|
3245
|
+
unit: "Unit suffix shown beside the value.",
|
|
3246
|
+
precision: "Decimal places to round displayed values to. Unset rounds to at most 3 decimals (4 significant digits under 1).",
|
|
3247
|
+
thresholds: "Severity bands over the value. Each entry starts a band at its value that runs to the next entry; below the first, and in a normal band, the widget keeps its own colour.",
|
|
3248
|
+
"thresholds.value": "The value at which this band starts.",
|
|
3249
|
+
"thresholds.level": "The severity of this band. The theme decides the colour; normal has none.",
|
|
3250
|
+
"thresholds.label": "Text shown on the chart line for this threshold. Defaults to its value.",
|
|
3251
|
+
staleAfterSeconds: "Seconds after which the newest sample is called stale: the value is greyed out and badged. Unset shows the sample age only and never marks the widget stale.",
|
|
3252
|
+
windowSeconds: "Seconds of history the widget covers, back from now. Leave unset to follow the board\u2019s time range; set it to pin this widget to a fixed span that the viewer\u2019s range picker does not change. 60 to 604800.",
|
|
3253
|
+
measurement: "Which measurement to display. Defaults to the first the datasource selects.",
|
|
3254
|
+
flashOnChange: "Briefly tint a value green on a rise and red on a fall when it changes.",
|
|
3255
|
+
window: "Samples retained across ALL of the widget's measurements before the oldest are dropped. Bounds memory; only the chart draws them. Default 300.",
|
|
3256
|
+
min: "Value at the empty end of the scale. Required: the widget does not guess a range.",
|
|
3257
|
+
max: "Value at the full end of the scale. Required, and above min.",
|
|
3258
|
+
text: "The text to show. Rendered as plain text \u2014 markup is never interpreted.",
|
|
3259
|
+
align: "Horizontal alignment of the text. Default center.",
|
|
3260
|
+
fontSize: "Text size in pixels at the comfortable density; it scales with the board density. Default 16.",
|
|
3261
|
+
url: "Source URL of the image.",
|
|
3262
|
+
alt: "Alternative text describing the image for assistive technology.",
|
|
3263
|
+
fit: "How the image fills its box. Default contain.",
|
|
3264
|
+
state: "Show only alarms in this state. Unset shows every state.",
|
|
3265
|
+
severity: "Show only alarms at this severity. Unset shows every severity.",
|
|
3266
|
+
acknowledged: "Show only acknowledged ('true') or unacknowledged ('false') alarms. Unset shows both.",
|
|
3267
|
+
groupBy: "deviceType: a tab per device type.",
|
|
3268
|
+
deviceType: "Only alarms on devices of this type (token).",
|
|
3269
|
+
deviceTypes: "Types to tab, in order; unset tabs all.",
|
|
3270
|
+
"deviceTypes.token": "Type token.",
|
|
3271
|
+
maxRows: "Alarms loaded into the table. Default 50.",
|
|
3272
|
+
selectionTarget: "Name of the slot this widget re-points when the viewer picks an entity.",
|
|
3273
|
+
commandName: "Command key issued to the target device. Without it the control cannot send.",
|
|
3274
|
+
commandLabel: "Name of the control for assistive technology. Defaults to the command key.",
|
|
3275
|
+
parameterSchema: "The command's parameter descriptors, baked in as JSON at author time. Gives the control its range and its refusals.",
|
|
3276
|
+
tileUrl: "Raster tile URL template, e.g. https://tiles.example.com/{z}/{x}/{y}.png. Leave empty to inherit the tenant's basemap; setting one overrides it for this board only.",
|
|
3277
|
+
attribution: "Credit line the tile source requires, shown on the map. Set whatever the provider you chose asks for.",
|
|
3278
|
+
style: "A plain bar (default) or a thermometer: a vertical tube with a bulb. A thermometer is always vertical.",
|
|
3279
|
+
markAlarms: "Mark this device\u2019s alarms on the chart, from raise to clear.",
|
|
3280
|
+
markAlarmsScope: "Which alarms to mark: only those about what this chart plots (series, the default for a new chart), or every alarm on the device. An alarm with no known measurement is never marked in series mode; it is listed under the chart as another alarm on the device. A chart saved before this option marks the whole device.",
|
|
3281
|
+
markCommands: "Mark the commands sent to this device on the chart.",
|
|
3282
|
+
orientation: "Direction of a bar: horizontal (default) or vertical. Ignored by a thermometer.",
|
|
3283
|
+
readout: "What the readout shows: the value with its unit (default) or the percent of the scale.",
|
|
3284
|
+
onAt: "For an on/off signal: the lamp is lit at or above this value and dark below it. Unset keeps the lamp lit while a value is present, coloured by its threshold band.",
|
|
3285
|
+
parameter: "Which parameter of the command this control sets. May be left blank when the command has exactly one parameter of the right type.",
|
|
3286
|
+
step: "Distance between values. Defaults to 1 for a whole-number parameter, else a hundredth of the range.",
|
|
3287
|
+
mode: "Slider (default) or stepper: \u2212 / + and Send.",
|
|
3288
|
+
stat: "Which figure to show. Default average.",
|
|
3289
|
+
sparkline: "Draw the measurement\u2019s trend over the span under the figure. Default off.",
|
|
3290
|
+
sort: "Order of the categories. Default: as the data source lists them.",
|
|
3291
|
+
columns: "Heading, unit and precision per measurement column; a column with none shows its name.",
|
|
3292
|
+
"columns.measurement": "The measurement column this entry applies to.",
|
|
3293
|
+
"columns.label": "Column heading. Defaults to the measurement name.",
|
|
3294
|
+
"columns.unit": "Unit suffix shown beside the value.",
|
|
3295
|
+
"columns.precision": "Decimal places to round displayed values to. Unset rounds to at most 3 decimals (4 significant digits under 1).",
|
|
3296
|
+
"thresholds.measurement": "The measurement column this entry applies to.",
|
|
3297
|
+
ageLagSeconds: "Show a reading's age under it only when the reading is at least this many seconds older than the newest reading in the table (or stale). Unset shows every reading's age.",
|
|
3298
|
+
sortBy: "The measurement the table is ordered by. Blank orders by device name.",
|
|
3299
|
+
sortDescending: "Largest first.",
|
|
3300
|
+
pageSize: "Devices per page. Default 20.",
|
|
3301
|
+
maxSeries: "Most lines drawn when the chart shows one line per device. Default 5, at most 12. Each line costs one stored-history read, and the chart colours repeat after five; a group larger than this shows the first devices of the group and says how many it left out.",
|
|
3302
|
+
show: "What to count: devices in an abnormal band of the measurement (default), or all devices."
|
|
3303
|
+
};
|
|
3304
|
+
var OPTION_DOC_OVERRIDES = {
|
|
3305
|
+
"latest-card": {
|
|
3306
|
+
title: "Heading shown in the widget frame. Defaults to the displayed measurement name."
|
|
3307
|
+
},
|
|
3308
|
+
gauge: {
|
|
3309
|
+
title: "Heading shown in the widget frame. Defaults to the displayed measurement name.",
|
|
3310
|
+
min: "Low end of the gauge scale. Default 0.",
|
|
3311
|
+
max: "High end of the gauge scale. Default 100."
|
|
3312
|
+
},
|
|
3313
|
+
"linear-gauge": {
|
|
3314
|
+
title: "Heading shown in the widget frame. Defaults to the displayed measurement name."
|
|
3315
|
+
},
|
|
3316
|
+
"level-gauge": {
|
|
3317
|
+
title: "Heading shown in the widget frame. Defaults to the displayed measurement name."
|
|
3318
|
+
},
|
|
3319
|
+
battery: {
|
|
3320
|
+
title: "Heading shown in the widget frame. Defaults to the displayed measurement name.",
|
|
3321
|
+
min: "Value of an empty battery. Default 0 (the scale is percent unless you set min and max).",
|
|
3322
|
+
max: "Value of a full battery. Default 100 (the scale is percent unless you set min and max)."
|
|
3323
|
+
},
|
|
3324
|
+
"status-light": {
|
|
3325
|
+
title: "Heading shown in the widget frame. Defaults to the displayed measurement name."
|
|
3326
|
+
},
|
|
3327
|
+
"signal-bars": {
|
|
3328
|
+
title: "Heading shown in the widget frame. Defaults to the displayed measurement name.",
|
|
3329
|
+
thresholds: "The steps of the signal, lowest first: one bar per entry, lit once the value reaches it and coloured by its level. At least two, at most eight."
|
|
3330
|
+
},
|
|
3331
|
+
compass: {
|
|
3332
|
+
title: "Heading shown in the widget frame. Defaults to the displayed measurement name.",
|
|
3333
|
+
precision: "Decimal places of the heading. Default 0 (whole degrees). The heading is rounded first, then folded onto 0 to 360, so it never reads 360.",
|
|
3334
|
+
thresholds: "Severity bands over the heading in degrees (0 to 360, after folding). Each entry starts a band at its value that runs to the next entry; below the first, and in a normal band, the needle keeps its own colour."
|
|
3335
|
+
},
|
|
3336
|
+
"progress-ring": {
|
|
3337
|
+
title: "Heading shown in the widget frame. Defaults to the displayed measurement name.",
|
|
3338
|
+
readout: "What the middle of the ring shows: the percent of the scale (default) or the value with its unit."
|
|
3339
|
+
},
|
|
3340
|
+
"stat-card": {
|
|
3341
|
+
title: "Heading shown in the widget frame. Defaults to the displayed measurement name."
|
|
3342
|
+
},
|
|
3343
|
+
"device-status": {
|
|
3344
|
+
staleAfterSeconds: "Marks the card stale once its status has not been read for longer than this many seconds (it is re-read every 15 seconds, so only reads that keep failing make it stale). A device that is merely silent is not stale: whether it is online is the status itself. Unset, the age is shown and nothing is marked stale."
|
|
3345
|
+
},
|
|
3346
|
+
"online-doughnut": {
|
|
3347
|
+
staleAfterSeconds: "Marks the ring stale once the status of its devices has not been read for longer than this many seconds (it is re-read every 15 seconds, so only reads that keep failing make it stale). Unset, the age is shown and nothing is marked stale."
|
|
3348
|
+
},
|
|
3349
|
+
"fleet-count": {
|
|
3350
|
+
measurement: "The measurement whose bands flag a device. Defaults to the first the datasource selects."
|
|
3351
|
+
},
|
|
3352
|
+
"command-slider": {
|
|
3353
|
+
min: "Lowest value, used only when the command's parameter declares no minimum.",
|
|
3354
|
+
max: "Highest value, used only when the command's parameter declares no maximum."
|
|
3355
|
+
},
|
|
3356
|
+
"timeseries-chart": {
|
|
3357
|
+
min: "Low end of the value axis. Unset, the axis starts where the chart picks. A reading or threshold below it still shows: the axis widens to take it in.",
|
|
3358
|
+
max: "High end of the value axis, above min. Unset, the chart picks. A reading or threshold above it still shows: the axis widens to take it in.",
|
|
3359
|
+
groupBy: "One line per measurement of one device (the default), or one line per device of a group for the measurement set below. Per device, stored history is drawn as the average of each time bucket (the chart says so), and thresholds are reference lines over it.",
|
|
3360
|
+
measurement: "The measurement compared across the group. Defaults to the first the datasource selects. Used only with one line per device.",
|
|
3361
|
+
markAlarms: "Mark this device\u2019s alarms on the chart, from raise to clear. Not drawn with one line per device.",
|
|
3362
|
+
markCommands: "Mark the commands sent to this device on the chart. Not drawn with one line per device."
|
|
3363
|
+
},
|
|
3364
|
+
"bar-chart": {
|
|
3365
|
+
groupBy: "One bar per measurement (the default), or per device of the group for the measurement set below."
|
|
3366
|
+
},
|
|
3367
|
+
"command-button": {
|
|
3368
|
+
maxRows: "Recent commands shown in the history. Default 20.",
|
|
3369
|
+
commandName: "Command key issued to the target device. Without it the widget cannot send.",
|
|
3370
|
+
commandLabel: "Text on the send button. Defaults to the command key.",
|
|
3371
|
+
parameterSchema: "The command's parameter descriptors, baked in as JSON at author time. Drives the typed form."
|
|
3372
|
+
}
|
|
3373
|
+
};
|
|
3374
|
+
|
|
3375
|
+
// src/documented-descriptors.ts
|
|
3376
|
+
function documentOptions(widgetId, specs, prefix) {
|
|
3377
|
+
const out = {};
|
|
3378
|
+
for (const [key, spec] of Object.entries(specs)) {
|
|
3379
|
+
const path = `${prefix}${key}`;
|
|
3380
|
+
const copy = { ...spec };
|
|
3381
|
+
const doc = OPTION_DOC_OVERRIDES[widgetId]?.[path] ?? OPTION_DOCS[path];
|
|
3382
|
+
if (doc !== void 0) copy.doc = doc;
|
|
3383
|
+
if ("item" in spec && spec.item) copy.item = documentOptions(widgetId, spec.item, `${path}.`);
|
|
3384
|
+
out[key] = copy;
|
|
3385
|
+
}
|
|
3386
|
+
return out;
|
|
3387
|
+
}
|
|
3388
|
+
function documentDescriptor(descriptor) {
|
|
3389
|
+
return { ...descriptor, options: documentOptions(descriptor.id, descriptor.options, "") };
|
|
3390
|
+
}
|
|
3391
|
+
function documentAll(descriptors) {
|
|
3392
|
+
return Object.fromEntries(Object.entries(descriptors).map(([id, d]) => [id, documentDescriptor(d)]));
|
|
3393
|
+
}
|
|
3394
|
+
var builtinWidgetDescriptors2 = /* @__PURE__ */ documentAll(builtinWidgetDescriptors);
|
|
3395
|
+
function catalogOf(descriptors) {
|
|
3396
|
+
return createWidgetCatalog2(Object.values(descriptors));
|
|
3397
|
+
}
|
|
3398
|
+
var builtinWidgetCatalog2 = /* @__PURE__ */ catalogOf(builtinWidgetDescriptors2);
|
|
3399
|
+
function documentDefinitions(definitions) {
|
|
3400
|
+
const byId = builtinWidgetDescriptors2;
|
|
3401
|
+
return definitions.map((d) => ({ ...d, descriptor: byId[d.descriptor.id] }));
|
|
3402
|
+
}
|
|
3403
|
+
var builtinWidgetDefinitions2 = /* @__PURE__ */ documentDefinitions(builtinWidgetDefinitions);
|
|
3404
|
+
function createBuiltinWidgetRegistry2() {
|
|
3405
|
+
return createWidgetRegistry2(builtinWidgetDefinitions2);
|
|
3406
|
+
}
|
|
3407
|
+
function optionsById(descriptors) {
|
|
3408
|
+
return Object.freeze(Object.fromEntries(Object.entries(descriptors).map(([id, d]) => [id, d.options])));
|
|
3409
|
+
}
|
|
3410
|
+
var WIDGET_OPTIONS = /* @__PURE__ */ optionsById(builtinWidgetDescriptors2);
|
|
2868
3411
|
|
|
2869
3412
|
// src/preload.ts
|
|
2870
3413
|
async function preloadWidgets(registry, types) {
|
|
@@ -2895,23 +3438,23 @@ import {
|
|
|
2895
3438
|
numberSpec,
|
|
2896
3439
|
validateOptions
|
|
2897
3440
|
} from "@devicechain/dashboards";
|
|
2898
|
-
var
|
|
3441
|
+
var WIDGET_OPTIONS2 = Object.freeze(
|
|
2899
3442
|
Object.fromEntries(Object.entries(builtinWidgetDescriptors).map(([id, d]) => [id, d.options]))
|
|
2900
3443
|
);
|
|
2901
3444
|
function constraintsFor(widgetType) {
|
|
2902
3445
|
return builtinWidgetCatalog.get(widgetType)?.constraints ?? [];
|
|
2903
3446
|
}
|
|
2904
3447
|
function validateWidgetOptions(widgetType, options) {
|
|
2905
|
-
const specs =
|
|
3448
|
+
const specs = WIDGET_OPTIONS2[widgetType];
|
|
2906
3449
|
return validateOptions(specs, options, { constraints: constraintsFor(widgetType), label: widgetType }).map(
|
|
2907
3450
|
({ key, code, message }) => ({ widgetType, key, code, message })
|
|
2908
3451
|
);
|
|
2909
3452
|
}
|
|
2910
3453
|
function numberOptionSpec(type, key) {
|
|
2911
|
-
return numberSpec(
|
|
3454
|
+
return numberSpec(WIDGET_OPTIONS2[type], key);
|
|
2912
3455
|
}
|
|
2913
3456
|
function enumOptionValues(type, key) {
|
|
2914
|
-
return enumValues(
|
|
3457
|
+
return enumValues(WIDGET_OPTIONS2[type], key);
|
|
2915
3458
|
}
|
|
2916
3459
|
|
|
2917
3460
|
// src/definition-options.ts
|
|
@@ -2963,7 +3506,7 @@ import {
|
|
|
2963
3506
|
WidgetFrame as WidgetFrame9,
|
|
2964
3507
|
WidgetSubjectProvider as WidgetSubjectProvider2,
|
|
2965
3508
|
WidgetSelectProvider as WidgetSelectProvider3,
|
|
2966
|
-
useWidgetSelect as
|
|
3509
|
+
useWidgetSelect as useWidgetSelect3,
|
|
2967
3510
|
WidgetTimeZoneProvider as WidgetTimeZoneProvider2,
|
|
2968
3511
|
useWidgetTimeZone as useWidgetTimeZone3,
|
|
2969
3512
|
WidgetThemeRootProvider as WidgetThemeRootProvider2,
|
|
@@ -2986,7 +3529,7 @@ import {
|
|
|
2986
3529
|
useResolvedBindings,
|
|
2987
3530
|
useSlotCandidates,
|
|
2988
3531
|
useCandidates,
|
|
2989
|
-
css as
|
|
3532
|
+
css as css7
|
|
2990
3533
|
} from "@devicechain/widget-sdk";
|
|
2991
3534
|
import {
|
|
2992
3535
|
EChart as EChart3,
|
|
@@ -2997,8 +3540,10 @@ import {
|
|
|
2997
3540
|
} from "@devicechain/widget-sdk/echarts";
|
|
2998
3541
|
export {
|
|
2999
3542
|
AlarmCount,
|
|
3543
|
+
AlarmSeverity,
|
|
3000
3544
|
AlarmTable,
|
|
3001
3545
|
BUNDLED_BASEMAP_ATTRIBUTION,
|
|
3546
|
+
BoundDevicesNotice,
|
|
3002
3547
|
CommandButton,
|
|
3003
3548
|
ConnectedWidget,
|
|
3004
3549
|
DEFAULT_TIME_RANGE_LABELS,
|
|
@@ -3030,15 +3575,17 @@ export {
|
|
|
3030
3575
|
buildGaugeOption2 as buildGaugeOption,
|
|
3031
3576
|
buildLineOption2 as buildLineOption,
|
|
3032
3577
|
buildPayload,
|
|
3033
|
-
builtinWidgetCatalog,
|
|
3034
|
-
builtinWidgetDefinitions,
|
|
3035
|
-
|
|
3578
|
+
builtinWidgetCatalog2 as builtinWidgetCatalog,
|
|
3579
|
+
builtinWidgetDefinitions2 as builtinWidgetDefinitions,
|
|
3580
|
+
builtinWidgetDefinitions as builtinWidgetDefinitionsWithoutDocs,
|
|
3581
|
+
builtinWidgetDescriptors2 as builtinWidgetDescriptors,
|
|
3036
3582
|
clampNumberOption,
|
|
3037
3583
|
commandStatusColor,
|
|
3038
3584
|
commandStatusLabel,
|
|
3039
|
-
createBuiltinWidgetRegistry,
|
|
3040
|
-
|
|
3585
|
+
createBuiltinWidgetRegistry2 as createBuiltinWidgetRegistry,
|
|
3586
|
+
css7 as css,
|
|
3041
3587
|
defaultValues,
|
|
3588
|
+
describeBoundDevicesProblems,
|
|
3042
3589
|
describePosition,
|
|
3043
3590
|
enumOptionValues,
|
|
3044
3591
|
fitValueFont2 as fitValueFont,
|
|
@@ -3066,6 +3613,7 @@ export {
|
|
|
3066
3613
|
stripUnknownOptions,
|
|
3067
3614
|
useAlarmStream2 as useAlarmStream,
|
|
3068
3615
|
useBoardTimeRange,
|
|
3616
|
+
useBoundDevices,
|
|
3069
3617
|
useCandidates,
|
|
3070
3618
|
useChartTheme3 as useChartTheme,
|
|
3071
3619
|
useCommandStream2 as useCommandStream,
|
|
@@ -3080,7 +3628,7 @@ export {
|
|
|
3080
3628
|
useSlotCandidates,
|
|
3081
3629
|
useTenantBasemap,
|
|
3082
3630
|
useWidgetCandidates2 as useWidgetCandidates,
|
|
3083
|
-
|
|
3631
|
+
useWidgetSelect3 as useWidgetSelect,
|
|
3084
3632
|
useWidgetThemeRoot,
|
|
3085
3633
|
useWidgetTimeZone3 as useWidgetTimeZone,
|
|
3086
3634
|
validateDefinitionOptions,
|