@procaaso/alphinity-ui-components 1.11.0 → 1.12.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 +3 -0
- package/dist/index.cjs +796 -643
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +242 -92
- package/dist/index.d.ts +242 -92
- package/dist/index.js +612 -463
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -50,6 +50,8 @@ __export(index_exports, {
|
|
|
50
50
|
FooterPanel: () => FooterPanel,
|
|
51
51
|
FullscreenContainer: () => FullscreenContainer,
|
|
52
52
|
FullscreenWorkspace: () => FullscreenWorkspace,
|
|
53
|
+
ISA_UNKNOWN: () => ISA_UNKNOWN,
|
|
54
|
+
ISA_UNKNOWN_DARK: () => ISA_UNKNOWN_DARK,
|
|
53
55
|
LeftPanel: () => LeftPanel,
|
|
54
56
|
LeftToggleButton: () => LeftToggleButton,
|
|
55
57
|
LegacyValueEntry: () => LegacyValueEntry,
|
|
@@ -72,8 +74,9 @@ __export(index_exports, {
|
|
|
72
74
|
ThemeProvider: () => ThemeProvider,
|
|
73
75
|
ThemeToggle: () => ThemeToggle,
|
|
74
76
|
TrendLine: () => TrendLine,
|
|
75
|
-
|
|
76
|
-
|
|
77
|
+
UNKNOWN_GLYPH_RING_DASH: () => UNKNOWN_GLYPH_RING_DASH,
|
|
78
|
+
UNKNOWN_STATUS_GLYPH_COLOR_VAR: () => UNKNOWN_STATUS_GLYPH_COLOR_VAR,
|
|
79
|
+
UnknownStatusGlyph: () => UnknownStatusGlyph,
|
|
77
80
|
ValueEntry: () => ValueEntry,
|
|
78
81
|
ZoomButton: () => ZoomButton,
|
|
79
82
|
ZoomControls: () => ZoomControls,
|
|
@@ -91,6 +94,7 @@ __export(index_exports, {
|
|
|
91
94
|
importDiagram: () => importDiagram,
|
|
92
95
|
mockSymbolLibrary: () => mockSymbolLibrary,
|
|
93
96
|
nodeHasPort: () => nodeHasPort,
|
|
97
|
+
normalizeDeviceStatus: () => normalizeDeviceStatus,
|
|
94
98
|
overlayStyles: () => overlayStyles,
|
|
95
99
|
readAppearanceValue: () => readAppearanceValue,
|
|
96
100
|
registerSymbol: () => registerSymbol,
|
|
@@ -382,6 +386,16 @@ var ValueEntry = ({
|
|
|
382
386
|
var import_react3 = require("react");
|
|
383
387
|
|
|
384
388
|
// src/theme/statusColors.ts
|
|
389
|
+
var ISA_UNKNOWN = {
|
|
390
|
+
fg: "#4f4f8a",
|
|
391
|
+
bg: "#ebebf5",
|
|
392
|
+
border: "#8f8fc2"
|
|
393
|
+
};
|
|
394
|
+
var ISA_UNKNOWN_DARK = {
|
|
395
|
+
fg: "#b9bbdb",
|
|
396
|
+
bg: "#23263a",
|
|
397
|
+
border: "#6f74a3"
|
|
398
|
+
};
|
|
385
399
|
var DEFAULT_STATUS_COLORS = {
|
|
386
400
|
normal: { fill: "#888888", stroke: "#6b6b6b", bg: "#888888", text: "#ffffff", border: "#6b6b6b" },
|
|
387
401
|
warning: { fill: "#f59e0b", stroke: "#d97706", bg: "#FFD700", text: "#000000", border: "#d97706" },
|
|
@@ -389,7 +403,8 @@ var DEFAULT_STATUS_COLORS = {
|
|
|
389
403
|
fault: { fill: "#dc2626", stroke: "#b91c1c", bg: "#FF0000", text: "#ffffff", border: "#b91c1c" },
|
|
390
404
|
off: { fill: "#edeeef", stroke: "#000000", bg: "#666666", text: "#ffffff", border: "#4b5563" },
|
|
391
405
|
starting: { fill: "#90EE90", stroke: "#22c55e", bg: "#90EE90", text: "#000000", border: "#22c55e" },
|
|
392
|
-
stopping: { fill: "#FFD700", stroke: "#d97706", bg: "#FFD700", text: "#000000", border: "#d97706" }
|
|
406
|
+
stopping: { fill: "#FFD700", stroke: "#d97706", bg: "#FFD700", text: "#000000", border: "#d97706" },
|
|
407
|
+
unknown: { fill: ISA_UNKNOWN.bg, stroke: ISA_UNKNOWN.border, bg: ISA_UNKNOWN.bg, text: ISA_UNKNOWN.fg, border: ISA_UNKNOWN.border }
|
|
393
408
|
};
|
|
394
409
|
var FORCED_MARK_COLOR = {
|
|
395
410
|
fill: "#ede9fe",
|
|
@@ -398,27 +413,16 @@ var FORCED_MARK_COLOR = {
|
|
|
398
413
|
text: "#5b21b6",
|
|
399
414
|
border: "#7c3aed"
|
|
400
415
|
};
|
|
401
|
-
var UNKNOWN_MARK_COLOR = {
|
|
402
|
-
fill: "#ebebf5",
|
|
403
|
-
stroke: "#8f8fc2",
|
|
404
|
-
bg: "#ebebf5",
|
|
405
|
-
text: "#4f4f8a",
|
|
406
|
-
border: "#8f8fc2"
|
|
407
|
-
};
|
|
408
|
-
var UNKNOWN_MARK_COLOR_DARK = {
|
|
409
|
-
fill: "#23263a",
|
|
410
|
-
stroke: "#6f74a3",
|
|
411
|
-
bg: "#23263a",
|
|
412
|
-
text: "#b9bbdb",
|
|
413
|
-
border: "#6f74a3"
|
|
414
|
-
};
|
|
415
416
|
var STATUS_ALIASES = {
|
|
416
417
|
running: "normal",
|
|
417
418
|
stopped: "off"
|
|
418
419
|
};
|
|
419
|
-
function
|
|
420
|
+
function normalizeDeviceStatus(status) {
|
|
420
421
|
const raw = (status || "off").toLowerCase();
|
|
421
|
-
|
|
422
|
+
return STATUS_ALIASES[raw] ?? raw;
|
|
423
|
+
}
|
|
424
|
+
function resolveStatusColor(status, customMap) {
|
|
425
|
+
const key = normalizeDeviceStatus(status);
|
|
422
426
|
const defaults = DEFAULT_STATUS_COLORS[key] ?? DEFAULT_STATUS_COLORS.off;
|
|
423
427
|
const overrides = customMap?.[key];
|
|
424
428
|
if (!overrides) return defaults;
|
|
@@ -858,7 +862,79 @@ var ControlPanel = ({
|
|
|
858
862
|
};
|
|
859
863
|
|
|
860
864
|
// src/components/StatusIndicator/StatusIndicator.tsx
|
|
865
|
+
var import_react5 = __toESM(require("react"), 1);
|
|
866
|
+
|
|
867
|
+
// src/theme/unknownStatusGlyph.tsx
|
|
861
868
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
869
|
+
var UNKNOWN_STATUS_GLYPH_COLOR_VAR = "--ui-status-indicator-unknown-glyph-color";
|
|
870
|
+
var UNKNOWN_GLYPH_STROKE_WEIGHTS = {
|
|
871
|
+
small: { ring: 4.5, ringDash: "7 6", mark: 5, dot: 2.9 },
|
|
872
|
+
medium: { ring: 4, ringDash: "6.5 5.5", mark: 4.5, dot: 2.7 },
|
|
873
|
+
large: { ring: 3.5, ringDash: "6.5 5.5", mark: 4, dot: 2.5 }
|
|
874
|
+
};
|
|
875
|
+
var UNKNOWN_GLYPH_RING_DASH = UNKNOWN_GLYPH_STROKE_WEIGHTS.medium.ringDash;
|
|
876
|
+
var UNKNOWN_GLYPH_FILL_STYLE = {
|
|
877
|
+
position: "absolute",
|
|
878
|
+
inset: 0,
|
|
879
|
+
width: "100%",
|
|
880
|
+
height: "100%"
|
|
881
|
+
};
|
|
882
|
+
function unknownGlyphHostStyle(isUnknown, style) {
|
|
883
|
+
return isUnknown ? { position: "relative", ...style } : style;
|
|
884
|
+
}
|
|
885
|
+
function UnknownStatusGlyph({
|
|
886
|
+
size = "medium",
|
|
887
|
+
counterRotate = false,
|
|
888
|
+
style,
|
|
889
|
+
...rest
|
|
890
|
+
}) {
|
|
891
|
+
const weights = UNKNOWN_GLYPH_STROKE_WEIGHTS[size];
|
|
892
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
893
|
+
"svg",
|
|
894
|
+
{
|
|
895
|
+
viewBox: "0 0 48 48",
|
|
896
|
+
"aria-hidden": "true",
|
|
897
|
+
focusable: "false",
|
|
898
|
+
style: {
|
|
899
|
+
display: "block",
|
|
900
|
+
color: `var(${UNKNOWN_STATUS_GLYPH_COLOR_VAR}, currentColor)`,
|
|
901
|
+
transform: counterRotate ? "rotate(-45deg)" : void 0,
|
|
902
|
+
...style
|
|
903
|
+
},
|
|
904
|
+
...rest,
|
|
905
|
+
children: [
|
|
906
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
907
|
+
"circle",
|
|
908
|
+
{
|
|
909
|
+
cx: 24,
|
|
910
|
+
cy: 24,
|
|
911
|
+
r: 20,
|
|
912
|
+
fill: "none",
|
|
913
|
+
stroke: "currentColor",
|
|
914
|
+
strokeDasharray: weights.ringDash,
|
|
915
|
+
strokeLinecap: "round",
|
|
916
|
+
strokeWidth: weights.ring
|
|
917
|
+
}
|
|
918
|
+
),
|
|
919
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
920
|
+
"path",
|
|
921
|
+
{
|
|
922
|
+
d: "M18.4 18.6a5.8 5.8 0 1 1 6.4 8.1v3.1",
|
|
923
|
+
fill: "none",
|
|
924
|
+
stroke: "currentColor",
|
|
925
|
+
strokeLinecap: "round",
|
|
926
|
+
strokeLinejoin: "round",
|
|
927
|
+
strokeWidth: weights.mark
|
|
928
|
+
}
|
|
929
|
+
),
|
|
930
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("circle", { cx: 24.6, cy: 35.4, r: weights.dot, fill: "currentColor" })
|
|
931
|
+
]
|
|
932
|
+
}
|
|
933
|
+
);
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
// src/components/StatusIndicator/StatusIndicator.tsx
|
|
937
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
862
938
|
var getStatusDescription = (status) => {
|
|
863
939
|
switch (status) {
|
|
864
940
|
case "alarm":
|
|
@@ -873,10 +949,23 @@ var getStatusDescription = (status) => {
|
|
|
873
949
|
return "Operating normally";
|
|
874
950
|
case "off":
|
|
875
951
|
return "Equipment is off";
|
|
952
|
+
case "unknown":
|
|
953
|
+
return "Device state cannot be confirmed. Check the link or the wiring.";
|
|
876
954
|
default:
|
|
877
955
|
return "";
|
|
878
956
|
}
|
|
879
957
|
};
|
|
958
|
+
var visuallyHiddenStyle = {
|
|
959
|
+
position: "absolute",
|
|
960
|
+
width: "1px",
|
|
961
|
+
height: "1px",
|
|
962
|
+
padding: 0,
|
|
963
|
+
margin: "-1px",
|
|
964
|
+
overflow: "hidden",
|
|
965
|
+
clip: "rect(0, 0, 0, 0)",
|
|
966
|
+
whiteSpace: "nowrap",
|
|
967
|
+
border: 0
|
|
968
|
+
};
|
|
880
969
|
var StatusIndicator = ({
|
|
881
970
|
status,
|
|
882
971
|
size = "medium",
|
|
@@ -889,17 +978,25 @@ var StatusIndicator = ({
|
|
|
889
978
|
forced = false,
|
|
890
979
|
realValue,
|
|
891
980
|
className = "",
|
|
981
|
+
style,
|
|
982
|
+
"aria-describedby": consumerDescribedBy,
|
|
983
|
+
children,
|
|
892
984
|
...props
|
|
893
985
|
}) => {
|
|
986
|
+
const generatedDescriptionId = `${import_react5.default.useId()}-status-description`;
|
|
894
987
|
if (!visible) {
|
|
895
988
|
return null;
|
|
896
989
|
}
|
|
990
|
+
const describedBy = consumerDescribedBy ? `${consumerDescribedBy} ${generatedDescriptionId}` : generatedDescriptionId;
|
|
991
|
+
const description = getStatusDescription(status);
|
|
897
992
|
const baseClass = "ui-status-indicator";
|
|
898
993
|
const statusClass = status ? `ui-status-indicator--${status}` : "";
|
|
899
994
|
const sizeClass = size ? `ui-status-indicator--${size}` : "";
|
|
900
995
|
const shapeClass = shape ? `ui-status-indicator--${shape}` : "";
|
|
901
996
|
const animationClass = animation ? `ui-status-indicator--${animation}` : "";
|
|
902
997
|
const ledClass = led ? "ui-status-indicator--led" : "";
|
|
998
|
+
const isUnknown = status === "unknown";
|
|
999
|
+
const indicatorStyle = unknownGlyphHostStyle(isUnknown, style);
|
|
903
1000
|
const getContainerLayout = () => {
|
|
904
1001
|
switch (labelPosition) {
|
|
905
1002
|
case "left":
|
|
@@ -916,19 +1013,20 @@ var StatusIndicator = ({
|
|
|
916
1013
|
};
|
|
917
1014
|
const forcedClass = forced ? "ui-status-indicator--forced" : "";
|
|
918
1015
|
const hasRealValue = forced && realValue !== void 0;
|
|
919
|
-
return /* @__PURE__ */ (0,
|
|
920
|
-
label && (labelPosition === "left" || labelPosition === "top") && /* @__PURE__ */ (0,
|
|
921
|
-
hasRealValue && (labelPosition === "left" || labelPosition === "top") && /* @__PURE__ */ (0,
|
|
1016
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: getContainerLayout(), children: [
|
|
1017
|
+
label && (labelPosition === "left" || labelPosition === "top") && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "ui-status-indicator-label", children: label }),
|
|
1018
|
+
hasRealValue && (labelPosition === "left" || labelPosition === "top") && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "ui-status-indicator-real-value", children: [
|
|
922
1019
|
"REAL ",
|
|
923
1020
|
realValue
|
|
924
1021
|
] }),
|
|
925
|
-
/* @__PURE__ */ (0,
|
|
926
|
-
/* @__PURE__ */ (0,
|
|
1022
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { style: { position: "relative", display: "inline-flex" }, children: [
|
|
1023
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
927
1024
|
"span",
|
|
928
1025
|
{
|
|
929
1026
|
role: "status",
|
|
930
1027
|
"aria-label": label || `Status: ${status}`,
|
|
931
|
-
"aria-description":
|
|
1028
|
+
"aria-description": description,
|
|
1029
|
+
"aria-describedby": describedBy,
|
|
932
1030
|
"data-status": status,
|
|
933
1031
|
"data-forced": forced,
|
|
934
1032
|
className: `
|
|
@@ -941,13 +1039,26 @@ var StatusIndicator = ({
|
|
|
941
1039
|
${forcedClass}
|
|
942
1040
|
${className}
|
|
943
1041
|
`.replace(/\s+/g, " ").trim(),
|
|
944
|
-
|
|
1042
|
+
style: indicatorStyle,
|
|
1043
|
+
...props,
|
|
1044
|
+
children: [
|
|
1045
|
+
isUnknown && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1046
|
+
UnknownStatusGlyph,
|
|
1047
|
+
{
|
|
1048
|
+
size,
|
|
1049
|
+
counterRotate: shape === "diamond",
|
|
1050
|
+
style: UNKNOWN_GLYPH_FILL_STYLE
|
|
1051
|
+
}
|
|
1052
|
+
),
|
|
1053
|
+
children,
|
|
1054
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { id: generatedDescriptionId, style: visuallyHiddenStyle, children: description })
|
|
1055
|
+
]
|
|
945
1056
|
}
|
|
946
1057
|
),
|
|
947
|
-
forced && /* @__PURE__ */ (0,
|
|
1058
|
+
forced && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "ui-status-indicator-forced-badge", "aria-label": "Forced", children: "F" })
|
|
948
1059
|
] }),
|
|
949
|
-
label && (labelPosition === "right" || labelPosition === "bottom") && /* @__PURE__ */ (0,
|
|
950
|
-
hasRealValue && (labelPosition === "right" || labelPosition === "bottom") && /* @__PURE__ */ (0,
|
|
1060
|
+
label && (labelPosition === "right" || labelPosition === "bottom") && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "ui-status-indicator-label", children: label }),
|
|
1061
|
+
hasRealValue && (labelPosition === "right" || labelPosition === "bottom") && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "ui-status-indicator-real-value", children: [
|
|
951
1062
|
"REAL ",
|
|
952
1063
|
realValue
|
|
953
1064
|
] })
|
|
@@ -955,7 +1066,7 @@ var StatusIndicator = ({
|
|
|
955
1066
|
};
|
|
956
1067
|
|
|
957
1068
|
// src/components/NodeControlsPanel/NodeControlsPanel.tsx
|
|
958
|
-
var
|
|
1069
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
959
1070
|
var NodeControlsPanel = ({
|
|
960
1071
|
config,
|
|
961
1072
|
onClose,
|
|
@@ -1028,8 +1139,8 @@ var NodeControlsPanel = ({
|
|
|
1028
1139
|
overflowY: "auto",
|
|
1029
1140
|
flex: 1
|
|
1030
1141
|
};
|
|
1031
|
-
return /* @__PURE__ */ (0,
|
|
1032
|
-
/* @__PURE__ */ (0,
|
|
1142
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
1143
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1033
1144
|
"div",
|
|
1034
1145
|
{
|
|
1035
1146
|
style: {
|
|
@@ -1042,16 +1153,16 @@ var NodeControlsPanel = ({
|
|
|
1042
1153
|
onClick: onClose
|
|
1043
1154
|
}
|
|
1044
1155
|
),
|
|
1045
|
-
/* @__PURE__ */ (0,
|
|
1156
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1046
1157
|
"div",
|
|
1047
1158
|
{
|
|
1048
1159
|
className: `node-controls-panel ${touchClass} ${className}`.trim(),
|
|
1049
1160
|
style: containerStyle,
|
|
1050
1161
|
...props,
|
|
1051
1162
|
children: [
|
|
1052
|
-
/* @__PURE__ */ (0,
|
|
1053
|
-
/* @__PURE__ */ (0,
|
|
1054
|
-
/* @__PURE__ */ (0,
|
|
1163
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: headerStyle, children: [
|
|
1164
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h2", { style: titleStyle, children: config.title }),
|
|
1165
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1055
1166
|
"button",
|
|
1056
1167
|
{
|
|
1057
1168
|
style: closeButtonStyle,
|
|
@@ -1069,7 +1180,7 @@ var NodeControlsPanel = ({
|
|
|
1069
1180
|
}
|
|
1070
1181
|
)
|
|
1071
1182
|
] }),
|
|
1072
|
-
/* @__PURE__ */ (0,
|
|
1183
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: contentStyle, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1073
1184
|
ControlPanel,
|
|
1074
1185
|
{
|
|
1075
1186
|
title: config.nodeId,
|
|
@@ -1098,7 +1209,7 @@ var NodeControlsPanel = ({
|
|
|
1098
1209
|
]
|
|
1099
1210
|
}
|
|
1100
1211
|
),
|
|
1101
|
-
/* @__PURE__ */ (0,
|
|
1212
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("style", { children: `
|
|
1102
1213
|
@keyframes slideUp {
|
|
1103
1214
|
from {
|
|
1104
1215
|
transform: translateY(100%);
|
|
@@ -1144,8 +1255,8 @@ var NodeControlsPanel = ({
|
|
|
1144
1255
|
};
|
|
1145
1256
|
|
|
1146
1257
|
// src/components/DeviceControlPanel/DeviceControlPanel.tsx
|
|
1147
|
-
var
|
|
1148
|
-
var
|
|
1258
|
+
var import_react6 = __toESM(require("react"), 1);
|
|
1259
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1149
1260
|
function DeviceControlPanelImpl({
|
|
1150
1261
|
binding,
|
|
1151
1262
|
onClose,
|
|
@@ -1173,11 +1284,11 @@ function DeviceControlPanelImpl({
|
|
|
1173
1284
|
showBuiltInToast = true,
|
|
1174
1285
|
embedded = false
|
|
1175
1286
|
}) {
|
|
1176
|
-
const [localParameterValues, setLocalParameterValues] = (0,
|
|
1177
|
-
const [showModeModal, setShowModeModal] = (0,
|
|
1178
|
-
const [pendingMode, setPendingMode] = (0,
|
|
1179
|
-
const [showToast, setShowToast] = (0,
|
|
1180
|
-
(0,
|
|
1287
|
+
const [localParameterValues, setLocalParameterValues] = (0, import_react6.useState)({});
|
|
1288
|
+
const [showModeModal, setShowModeModal] = (0, import_react6.useState)(false);
|
|
1289
|
+
const [pendingMode, setPendingMode] = (0, import_react6.useState)(null);
|
|
1290
|
+
const [showToast, setShowToast] = (0, import_react6.useState)(true);
|
|
1291
|
+
(0, import_react6.useEffect)(() => {
|
|
1181
1292
|
if (binding) {
|
|
1182
1293
|
const currentParams2 = binding.parameters[binding.state.currentMode] || [];
|
|
1183
1294
|
const values = {};
|
|
@@ -1187,7 +1298,7 @@ function DeviceControlPanelImpl({
|
|
|
1187
1298
|
setLocalParameterValues(values);
|
|
1188
1299
|
}
|
|
1189
1300
|
}, [binding, binding?.state.currentMode]);
|
|
1190
|
-
(0,
|
|
1301
|
+
(0, import_react6.useEffect)(() => {
|
|
1191
1302
|
if (binding?.state.lastCommandResult) {
|
|
1192
1303
|
setShowToast(true);
|
|
1193
1304
|
const timer = setTimeout(() => {
|
|
@@ -1225,6 +1336,7 @@ function DeviceControlPanelImpl({
|
|
|
1225
1336
|
const selectedColor = "#b4d0fe";
|
|
1226
1337
|
const statusEntry = resolveStatusColor(binding.state.status, binding.theme?.statusColors);
|
|
1227
1338
|
const statusColor = statusEntry.bg;
|
|
1339
|
+
const isUnknownStatus = normalizeDeviceStatus(binding.state.status) === "unknown";
|
|
1228
1340
|
const handleModeChange = (mode) => {
|
|
1229
1341
|
onModeChange?.(mode);
|
|
1230
1342
|
};
|
|
@@ -1279,9 +1391,9 @@ function DeviceControlPanelImpl({
|
|
|
1279
1391
|
...binding.display?.style
|
|
1280
1392
|
};
|
|
1281
1393
|
const titleText = binding.display?.title || binding.deviceName || binding.tag || binding.nodeId;
|
|
1282
|
-
return /* @__PURE__ */ (0,
|
|
1283
|
-
/* @__PURE__ */ (0,
|
|
1284
|
-
/* @__PURE__ */ (0,
|
|
1394
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
1395
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: panelStyle, className: binding.display?.className, children: [
|
|
1396
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1285
1397
|
"div",
|
|
1286
1398
|
{
|
|
1287
1399
|
style: {
|
|
@@ -1293,8 +1405,8 @@ function DeviceControlPanelImpl({
|
|
|
1293
1405
|
borderBottom: `2px solid ${borderColor}`
|
|
1294
1406
|
},
|
|
1295
1407
|
children: [
|
|
1296
|
-
/* @__PURE__ */ (0,
|
|
1297
|
-
/* @__PURE__ */ (0,
|
|
1408
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { children: [
|
|
1409
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1298
1410
|
"h3",
|
|
1299
1411
|
{
|
|
1300
1412
|
style: {
|
|
@@ -1314,7 +1426,7 @@ function DeviceControlPanelImpl({
|
|
|
1314
1426
|
children: titleText.length > 25 ? titleText.slice(0, 25) + "..." : titleText
|
|
1315
1427
|
}
|
|
1316
1428
|
),
|
|
1317
|
-
binding.deviceType && /* @__PURE__ */ (0,
|
|
1429
|
+
binding.deviceType && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1318
1430
|
"div",
|
|
1319
1431
|
{
|
|
1320
1432
|
style: {
|
|
@@ -1327,8 +1439,8 @@ function DeviceControlPanelImpl({
|
|
|
1327
1439
|
}
|
|
1328
1440
|
)
|
|
1329
1441
|
] }),
|
|
1330
|
-
/* @__PURE__ */ (0,
|
|
1331
|
-
showConfigButton && onOpenConfig && /* @__PURE__ */ (0,
|
|
1442
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { display: "flex", gap: "8px" }, children: [
|
|
1443
|
+
showConfigButton && onOpenConfig && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1332
1444
|
"button",
|
|
1333
1445
|
{
|
|
1334
1446
|
onClick: onOpenConfig,
|
|
@@ -1349,7 +1461,7 @@ function DeviceControlPanelImpl({
|
|
|
1349
1461
|
children: "\u2699"
|
|
1350
1462
|
}
|
|
1351
1463
|
),
|
|
1352
|
-
onUndock && /* @__PURE__ */ (0,
|
|
1464
|
+
onUndock && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1353
1465
|
"button",
|
|
1354
1466
|
{
|
|
1355
1467
|
onClick: onUndock,
|
|
@@ -1370,7 +1482,7 @@ function DeviceControlPanelImpl({
|
|
|
1370
1482
|
children: undockIcon
|
|
1371
1483
|
}
|
|
1372
1484
|
),
|
|
1373
|
-
/* @__PURE__ */ (0,
|
|
1485
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1374
1486
|
"button",
|
|
1375
1487
|
{
|
|
1376
1488
|
onClick: onClose,
|
|
@@ -1393,7 +1505,7 @@ function DeviceControlPanelImpl({
|
|
|
1393
1505
|
]
|
|
1394
1506
|
}
|
|
1395
1507
|
),
|
|
1396
|
-
binding.state.status && /* @__PURE__ */ (0,
|
|
1508
|
+
binding.state.status && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1397
1509
|
"div",
|
|
1398
1510
|
{
|
|
1399
1511
|
style: {
|
|
@@ -1407,7 +1519,7 @@ function DeviceControlPanelImpl({
|
|
|
1407
1519
|
marginBottom: spacing.marginBottom
|
|
1408
1520
|
},
|
|
1409
1521
|
children: [
|
|
1410
|
-
/* @__PURE__ */ (0,
|
|
1522
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1411
1523
|
"div",
|
|
1412
1524
|
{
|
|
1413
1525
|
style: {
|
|
@@ -1415,12 +1527,17 @@ function DeviceControlPanelImpl({
|
|
|
1415
1527
|
height: "10px",
|
|
1416
1528
|
borderRadius: "50%",
|
|
1417
1529
|
backgroundColor: statusColor,
|
|
1418
|
-
border: "1px solid #333"
|
|
1419
|
-
|
|
1530
|
+
border: "1px solid #333",
|
|
1531
|
+
// The shared helper positions this dot only while it shows
|
|
1532
|
+
// the unknown marker. The glyph then fills the dot with an
|
|
1533
|
+
// absolute inset, the same pattern StatusIndicator uses.
|
|
1534
|
+
...unknownGlyphHostStyle(isUnknownStatus)
|
|
1535
|
+
},
|
|
1536
|
+
children: isUnknownStatus && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(UnknownStatusGlyph, { size: "small", style: UNKNOWN_GLYPH_FILL_STYLE })
|
|
1420
1537
|
}
|
|
1421
1538
|
),
|
|
1422
|
-
/* @__PURE__ */ (0,
|
|
1423
|
-
/* @__PURE__ */ (0,
|
|
1539
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { flex: 1 }, children: [
|
|
1540
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1424
1541
|
"div",
|
|
1425
1542
|
{
|
|
1426
1543
|
style: {
|
|
@@ -1434,7 +1551,7 @@ function DeviceControlPanelImpl({
|
|
|
1434
1551
|
children: binding.state.status
|
|
1435
1552
|
}
|
|
1436
1553
|
),
|
|
1437
|
-
binding.state.statusMessage && /* @__PURE__ */ (0,
|
|
1554
|
+
binding.state.statusMessage && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1438
1555
|
"div",
|
|
1439
1556
|
{
|
|
1440
1557
|
style: {
|
|
@@ -1447,28 +1564,36 @@ function DeviceControlPanelImpl({
|
|
|
1447
1564
|
}
|
|
1448
1565
|
)
|
|
1449
1566
|
] }),
|
|
1450
|
-
binding.state.isRunning !== void 0 && /* @__PURE__ */ (0,
|
|
1567
|
+
binding.state.isRunning !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1451
1568
|
"div",
|
|
1452
1569
|
{
|
|
1453
1570
|
style: {
|
|
1454
1571
|
padding: "4px 10px",
|
|
1455
|
-
|
|
1456
|
-
|
|
1572
|
+
// This badge shows the last published isRunning value. It
|
|
1573
|
+
// never re-derives that value here. When status is
|
|
1574
|
+
// unknown, the value may be stale. Muted colors carry that
|
|
1575
|
+
// warning alongside the word, so color is not the only
|
|
1576
|
+
// channel and the wording is not the only channel either.
|
|
1577
|
+
backgroundColor: isUnknownStatus ? statusEntry.bg : binding.state.isRunning ? selectedColor : surfaceColor,
|
|
1578
|
+
border: `1px solid ${isUnknownStatus ? statusEntry.border : borderColor}`,
|
|
1457
1579
|
borderRadius: "2px",
|
|
1458
1580
|
fontSize: "10px",
|
|
1459
1581
|
fontWeight: 600,
|
|
1460
1582
|
fontFamily: "Arial, sans-serif",
|
|
1461
1583
|
letterSpacing: "0.5px",
|
|
1462
|
-
color: textColor
|
|
1584
|
+
color: isUnknownStatus ? statusEntry.text : textColor
|
|
1463
1585
|
},
|
|
1464
|
-
children:
|
|
1586
|
+
children: [
|
|
1587
|
+
binding.state.isRunning ? "RUNNING" : "STOPPED",
|
|
1588
|
+
isUnknownStatus && " (unconfirmed)"
|
|
1589
|
+
]
|
|
1465
1590
|
}
|
|
1466
1591
|
)
|
|
1467
1592
|
]
|
|
1468
1593
|
}
|
|
1469
1594
|
),
|
|
1470
|
-
binding.display?.showModeSelector !== false && binding.modes.length > 0 && /* @__PURE__ */ (0,
|
|
1471
|
-
/* @__PURE__ */ (0,
|
|
1595
|
+
binding.display?.showModeSelector !== false && binding.modes.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { marginBottom: "16px" }, children: [
|
|
1596
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1472
1597
|
"label",
|
|
1473
1598
|
{
|
|
1474
1599
|
style: {
|
|
@@ -1484,7 +1609,7 @@ function DeviceControlPanelImpl({
|
|
|
1484
1609
|
children: "Mode"
|
|
1485
1610
|
}
|
|
1486
1611
|
),
|
|
1487
|
-
modeSelectionStyle === "dropdown" ? /* @__PURE__ */ (0,
|
|
1612
|
+
modeSelectionStyle === "dropdown" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1488
1613
|
"select",
|
|
1489
1614
|
{
|
|
1490
1615
|
value: currentMode,
|
|
@@ -1505,10 +1630,10 @@ function DeviceControlPanelImpl({
|
|
|
1505
1630
|
paddingRight: "12px",
|
|
1506
1631
|
cursor: "pointer"
|
|
1507
1632
|
},
|
|
1508
|
-
children: binding.modes.map((mode) => /* @__PURE__ */ (0,
|
|
1633
|
+
children: binding.modes.map((mode) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: mode.value, disabled: mode.enabled === false, children: mode.label }, mode.value))
|
|
1509
1634
|
}
|
|
1510
|
-
) : modeSelectionStyle === "modal" ? /* @__PURE__ */ (0,
|
|
1511
|
-
/* @__PURE__ */ (0,
|
|
1635
|
+
) : modeSelectionStyle === "modal" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
1636
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1512
1637
|
"div",
|
|
1513
1638
|
{
|
|
1514
1639
|
onClick: () => {
|
|
@@ -1531,12 +1656,12 @@ function DeviceControlPanelImpl({
|
|
|
1531
1656
|
alignItems: "center"
|
|
1532
1657
|
},
|
|
1533
1658
|
children: [
|
|
1534
|
-
/* @__PURE__ */ (0,
|
|
1535
|
-
/* @__PURE__ */ (0,
|
|
1659
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: binding.modes.find((m) => m.value === currentMode)?.label || currentMode }),
|
|
1660
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { fontSize: "20px", marginLeft: "8px" }, children: "\u25BC" })
|
|
1536
1661
|
]
|
|
1537
1662
|
}
|
|
1538
1663
|
),
|
|
1539
|
-
showModeModal && /* @__PURE__ */ (0,
|
|
1664
|
+
showModeModal && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1540
1665
|
"div",
|
|
1541
1666
|
{
|
|
1542
1667
|
style: {
|
|
@@ -1555,7 +1680,7 @@ function DeviceControlPanelImpl({
|
|
|
1555
1680
|
setShowModeModal(false);
|
|
1556
1681
|
setPendingMode(null);
|
|
1557
1682
|
},
|
|
1558
|
-
children: /* @__PURE__ */ (0,
|
|
1683
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1559
1684
|
"div",
|
|
1560
1685
|
{
|
|
1561
1686
|
onClick: (e) => e.stopPropagation(),
|
|
@@ -1568,7 +1693,7 @@ function DeviceControlPanelImpl({
|
|
|
1568
1693
|
border: `2px solid ${borderColor}`
|
|
1569
1694
|
},
|
|
1570
1695
|
children: [
|
|
1571
|
-
/* @__PURE__ */ (0,
|
|
1696
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1572
1697
|
"h3",
|
|
1573
1698
|
{
|
|
1574
1699
|
style: {
|
|
@@ -1581,7 +1706,7 @@ function DeviceControlPanelImpl({
|
|
|
1581
1706
|
children: "Select Mode"
|
|
1582
1707
|
}
|
|
1583
1708
|
),
|
|
1584
|
-
/* @__PURE__ */ (0,
|
|
1709
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1585
1710
|
"div",
|
|
1586
1711
|
{
|
|
1587
1712
|
style: {
|
|
@@ -1595,7 +1720,7 @@ function DeviceControlPanelImpl({
|
|
|
1595
1720
|
children: binding.display?.title || binding.deviceName || binding.tag || binding.nodeId
|
|
1596
1721
|
}
|
|
1597
1722
|
),
|
|
1598
|
-
/* @__PURE__ */ (0,
|
|
1723
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1599
1724
|
"select",
|
|
1600
1725
|
{
|
|
1601
1726
|
value: pendingMode || currentMode,
|
|
@@ -1617,7 +1742,7 @@ function DeviceControlPanelImpl({
|
|
|
1617
1742
|
paddingRight: "12px",
|
|
1618
1743
|
cursor: "pointer"
|
|
1619
1744
|
},
|
|
1620
|
-
children: binding.modes.map((mode) => /* @__PURE__ */ (0,
|
|
1745
|
+
children: binding.modes.map((mode) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1621
1746
|
"option",
|
|
1622
1747
|
{
|
|
1623
1748
|
value: mode.value,
|
|
@@ -1632,7 +1757,7 @@ function DeviceControlPanelImpl({
|
|
|
1632
1757
|
const selectedMode = binding.modes.find(
|
|
1633
1758
|
(m) => m.value === (pendingMode || currentMode)
|
|
1634
1759
|
);
|
|
1635
|
-
return selectedMode?.description ? /* @__PURE__ */ (0,
|
|
1760
|
+
return selectedMode?.description ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1636
1761
|
"div",
|
|
1637
1762
|
{
|
|
1638
1763
|
style: {
|
|
@@ -1650,8 +1775,8 @@ function DeviceControlPanelImpl({
|
|
|
1650
1775
|
}
|
|
1651
1776
|
) : null;
|
|
1652
1777
|
})(),
|
|
1653
|
-
/* @__PURE__ */ (0,
|
|
1654
|
-
/* @__PURE__ */ (0,
|
|
1778
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { display: "flex", gap: "12px" }, children: [
|
|
1779
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1655
1780
|
"button",
|
|
1656
1781
|
{
|
|
1657
1782
|
onClick: () => {
|
|
@@ -1679,7 +1804,7 @@ function DeviceControlPanelImpl({
|
|
|
1679
1804
|
children: "Confirm"
|
|
1680
1805
|
}
|
|
1681
1806
|
),
|
|
1682
|
-
/* @__PURE__ */ (0,
|
|
1807
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1683
1808
|
"button",
|
|
1684
1809
|
{
|
|
1685
1810
|
onClick: () => {
|
|
@@ -1709,7 +1834,7 @@ function DeviceControlPanelImpl({
|
|
|
1709
1834
|
)
|
|
1710
1835
|
}
|
|
1711
1836
|
)
|
|
1712
|
-
] }) : /* @__PURE__ */ (0,
|
|
1837
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1713
1838
|
"div",
|
|
1714
1839
|
{
|
|
1715
1840
|
style: {
|
|
@@ -1725,7 +1850,7 @@ function DeviceControlPanelImpl({
|
|
|
1725
1850
|
children: binding.modes.map((mode) => {
|
|
1726
1851
|
const isSelected = mode.value === currentMode;
|
|
1727
1852
|
const isEnabled = mode.enabled !== false;
|
|
1728
|
-
return /* @__PURE__ */ (0,
|
|
1853
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1729
1854
|
"button",
|
|
1730
1855
|
{
|
|
1731
1856
|
onClick: () => isEnabled && handleModeChange(mode.value),
|
|
@@ -1755,8 +1880,8 @@ function DeviceControlPanelImpl({
|
|
|
1755
1880
|
}
|
|
1756
1881
|
)
|
|
1757
1882
|
] }),
|
|
1758
|
-
currentParams.length > 0 && /* @__PURE__ */ (0,
|
|
1759
|
-
/* @__PURE__ */ (0,
|
|
1883
|
+
currentParams.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { marginBottom: spacing.marginBottom }, children: [
|
|
1884
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1760
1885
|
"label",
|
|
1761
1886
|
{
|
|
1762
1887
|
style: {
|
|
@@ -1772,7 +1897,7 @@ function DeviceControlPanelImpl({
|
|
|
1772
1897
|
children: "Parameters"
|
|
1773
1898
|
}
|
|
1774
1899
|
),
|
|
1775
|
-
currentParams.map((param) => /* @__PURE__ */ (0,
|
|
1900
|
+
currentParams.map((param) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1776
1901
|
"div",
|
|
1777
1902
|
{
|
|
1778
1903
|
style: {
|
|
@@ -1783,7 +1908,7 @@ function DeviceControlPanelImpl({
|
|
|
1783
1908
|
borderRadius: "6px"
|
|
1784
1909
|
},
|
|
1785
1910
|
children: [
|
|
1786
|
-
/* @__PURE__ */ (0,
|
|
1911
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1787
1912
|
"div",
|
|
1788
1913
|
{
|
|
1789
1914
|
style: {
|
|
@@ -1792,7 +1917,7 @@ function DeviceControlPanelImpl({
|
|
|
1792
1917
|
marginBottom: spacing.gap
|
|
1793
1918
|
},
|
|
1794
1919
|
children: [
|
|
1795
|
-
/* @__PURE__ */ (0,
|
|
1920
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1796
1921
|
"span",
|
|
1797
1922
|
{
|
|
1798
1923
|
style: {
|
|
@@ -1808,7 +1933,7 @@ function DeviceControlPanelImpl({
|
|
|
1808
1933
|
},
|
|
1809
1934
|
children: [
|
|
1810
1935
|
param.label,
|
|
1811
|
-
param.forced?.active && /* @__PURE__ */ (0,
|
|
1936
|
+
param.forced?.active && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1812
1937
|
"span",
|
|
1813
1938
|
{
|
|
1814
1939
|
"aria-label": "Forced",
|
|
@@ -1831,7 +1956,7 @@ function DeviceControlPanelImpl({
|
|
|
1831
1956
|
]
|
|
1832
1957
|
}
|
|
1833
1958
|
),
|
|
1834
|
-
/* @__PURE__ */ (0,
|
|
1959
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1835
1960
|
"span",
|
|
1836
1961
|
{
|
|
1837
1962
|
style: {
|
|
@@ -1843,14 +1968,14 @@ function DeviceControlPanelImpl({
|
|
|
1843
1968
|
children: [
|
|
1844
1969
|
localParameterValues[param.id] ?? param.value,
|
|
1845
1970
|
" ",
|
|
1846
|
-
param.unit && /* @__PURE__ */ (0,
|
|
1971
|
+
param.unit && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { color: mutedTextColor, fontSize: "10px", fontWeight: 600 }, children: param.unit })
|
|
1847
1972
|
]
|
|
1848
1973
|
}
|
|
1849
1974
|
)
|
|
1850
1975
|
]
|
|
1851
1976
|
}
|
|
1852
1977
|
),
|
|
1853
|
-
param.forced?.active && param.forced.realValue !== void 0 && /* @__PURE__ */ (0,
|
|
1978
|
+
param.forced?.active && param.forced.realValue !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1854
1979
|
"div",
|
|
1855
1980
|
{
|
|
1856
1981
|
style: {
|
|
@@ -1871,7 +1996,7 @@ function DeviceControlPanelImpl({
|
|
|
1871
1996
|
]
|
|
1872
1997
|
}
|
|
1873
1998
|
),
|
|
1874
|
-
param.type === "boolean" ? /* @__PURE__ */ (0,
|
|
1999
|
+
param.type === "boolean" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1875
2000
|
"button",
|
|
1876
2001
|
{
|
|
1877
2002
|
onClick: () => {
|
|
@@ -1896,7 +2021,7 @@ function DeviceControlPanelImpl({
|
|
|
1896
2021
|
},
|
|
1897
2022
|
children: localParameterValues[param.id] ? "ON" : "OFF"
|
|
1898
2023
|
}
|
|
1899
|
-
) : param.type === "select" ? /* @__PURE__ */ (0,
|
|
2024
|
+
) : param.type === "select" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1900
2025
|
"select",
|
|
1901
2026
|
{
|
|
1902
2027
|
value: localParameterValues[param.id] || param.value,
|
|
@@ -1917,12 +2042,12 @@ function DeviceControlPanelImpl({
|
|
|
1917
2042
|
fontFamily: "monospace",
|
|
1918
2043
|
cursor: "pointer"
|
|
1919
2044
|
},
|
|
1920
|
-
children: param.options?.map((opt) => /* @__PURE__ */ (0,
|
|
2045
|
+
children: param.options?.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: opt.value, children: opt.label }, opt.value))
|
|
1921
2046
|
}
|
|
1922
2047
|
) : onParameterActivate && !param.readOnly ? (
|
|
1923
2048
|
// Tappable value: defer editing to the consumer's editor (e.g. a
|
|
1924
2049
|
// numpad dialog). Commit happens via onParameterChange.
|
|
1925
|
-
/* @__PURE__ */ (0,
|
|
2050
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1926
2051
|
"button",
|
|
1927
2052
|
{
|
|
1928
2053
|
type: "button",
|
|
@@ -1949,7 +2074,7 @@ function DeviceControlPanelImpl({
|
|
|
1949
2074
|
]
|
|
1950
2075
|
}
|
|
1951
2076
|
)
|
|
1952
|
-
) : /* @__PURE__ */ (0,
|
|
2077
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1953
2078
|
"input",
|
|
1954
2079
|
{
|
|
1955
2080
|
type: param.type === "number" ? "number" : "text",
|
|
@@ -1982,8 +2107,8 @@ function DeviceControlPanelImpl({
|
|
|
1982
2107
|
param.id
|
|
1983
2108
|
))
|
|
1984
2109
|
] }),
|
|
1985
|
-
binding.display?.showStartStop !== false && (activeCapabilities?.canStart || activeCapabilities?.canStop) && /* @__PURE__ */ (0,
|
|
1986
|
-
activeCapabilities?.canStart && /* @__PURE__ */ (0,
|
|
2110
|
+
binding.display?.showStartStop !== false && (activeCapabilities?.canStart || activeCapabilities?.canStop) && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { display: "flex", gap: spacing.gap, marginBottom: spacing.marginBottom }, children: [
|
|
2111
|
+
activeCapabilities?.canStart && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1987
2112
|
"button",
|
|
1988
2113
|
{
|
|
1989
2114
|
onClick: onStart,
|
|
@@ -2004,7 +2129,7 @@ function DeviceControlPanelImpl({
|
|
|
2004
2129
|
children: startPending ? "STARTING\u2026" : "START"
|
|
2005
2130
|
}
|
|
2006
2131
|
),
|
|
2007
|
-
activeCapabilities?.canStop && /* @__PURE__ */ (0,
|
|
2132
|
+
activeCapabilities?.canStop && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2008
2133
|
"button",
|
|
2009
2134
|
{
|
|
2010
2135
|
onClick: onStop,
|
|
@@ -2026,9 +2151,9 @@ function DeviceControlPanelImpl({
|
|
|
2026
2151
|
}
|
|
2027
2152
|
)
|
|
2028
2153
|
] }),
|
|
2029
|
-
activeCapabilities?.customActions && activeCapabilities.customActions.length > 0 && /* @__PURE__ */ (0,
|
|
2154
|
+
activeCapabilities?.customActions && activeCapabilities.customActions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { display: "flex", flexWrap: "wrap", gap: "8px" }, children: activeCapabilities.customActions.map((action) => {
|
|
2030
2155
|
const actionDisabled = action.disabled === true;
|
|
2031
|
-
return /* @__PURE__ */ (0,
|
|
2156
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
2032
2157
|
"button",
|
|
2033
2158
|
{
|
|
2034
2159
|
onClick: () => {
|
|
@@ -2054,7 +2179,7 @@ function DeviceControlPanelImpl({
|
|
|
2054
2179
|
transition: "all 0.15s"
|
|
2055
2180
|
},
|
|
2056
2181
|
children: [
|
|
2057
|
-
action.icon && /* @__PURE__ */ (0,
|
|
2182
|
+
action.icon && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { marginRight: "6px" }, children: action.icon }),
|
|
2058
2183
|
action.label
|
|
2059
2184
|
]
|
|
2060
2185
|
},
|
|
@@ -2062,7 +2187,7 @@ function DeviceControlPanelImpl({
|
|
|
2062
2187
|
);
|
|
2063
2188
|
}) })
|
|
2064
2189
|
] }),
|
|
2065
|
-
binding.state.lastCommandResult && showToast && showBuiltInToast && /* @__PURE__ */ (0,
|
|
2190
|
+
binding.state.lastCommandResult && showToast && showBuiltInToast && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2066
2191
|
"div",
|
|
2067
2192
|
{
|
|
2068
2193
|
style: {
|
|
@@ -2086,7 +2211,7 @@ function DeviceControlPanelImpl({
|
|
|
2086
2211
|
children: binding.state.lastCommandResult.message
|
|
2087
2212
|
}
|
|
2088
2213
|
),
|
|
2089
|
-
/* @__PURE__ */ (0,
|
|
2214
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("style", { children: `
|
|
2090
2215
|
@keyframes slideInToast {
|
|
2091
2216
|
from {
|
|
2092
2217
|
opacity: 0;
|
|
@@ -2118,11 +2243,11 @@ function DeviceControlPanelImpl({
|
|
|
2118
2243
|
` })
|
|
2119
2244
|
] });
|
|
2120
2245
|
}
|
|
2121
|
-
var DeviceControlPanel =
|
|
2246
|
+
var DeviceControlPanel = import_react6.default.memo(DeviceControlPanelImpl);
|
|
2122
2247
|
|
|
2123
2248
|
// src/components/NumpadDialog/NumpadDialog.tsx
|
|
2124
|
-
var
|
|
2125
|
-
var
|
|
2249
|
+
var import_react7 = require("react");
|
|
2250
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
2126
2251
|
var NumpadDialog = ({
|
|
2127
2252
|
isOpen,
|
|
2128
2253
|
onClose,
|
|
@@ -2136,24 +2261,24 @@ var NumpadDialog = ({
|
|
|
2136
2261
|
currentValue = 0,
|
|
2137
2262
|
touchOptimized = true
|
|
2138
2263
|
}) => {
|
|
2139
|
-
const [inputValue, setInputValue] = (0,
|
|
2140
|
-
const [pristine, setPristine] = (0,
|
|
2141
|
-
const dialogRef = (0,
|
|
2142
|
-
const titleId = (0,
|
|
2264
|
+
const [inputValue, setInputValue] = (0, import_react7.useState)("");
|
|
2265
|
+
const [pristine, setPristine] = (0, import_react7.useState)(true);
|
|
2266
|
+
const dialogRef = (0, import_react7.useRef)(null);
|
|
2267
|
+
const titleId = (0, import_react7.useId)();
|
|
2143
2268
|
const decimals = precision ?? 1;
|
|
2144
|
-
(0,
|
|
2269
|
+
(0, import_react7.useEffect)(() => {
|
|
2145
2270
|
if (isOpen) {
|
|
2146
2271
|
setInputValue(Number(currentValue).toFixed(decimals));
|
|
2147
2272
|
setPristine(true);
|
|
2148
2273
|
}
|
|
2149
2274
|
}, [isOpen, currentValue, decimals]);
|
|
2150
|
-
(0,
|
|
2275
|
+
(0, import_react7.useEffect)(() => {
|
|
2151
2276
|
if (!isOpen) return;
|
|
2152
2277
|
const previouslyFocused = document.activeElement;
|
|
2153
2278
|
dialogRef.current?.focus();
|
|
2154
2279
|
return () => previouslyFocused?.focus?.();
|
|
2155
2280
|
}, [isOpen]);
|
|
2156
|
-
(0,
|
|
2281
|
+
(0, import_react7.useEffect)(() => {
|
|
2157
2282
|
if (!isOpen) return;
|
|
2158
2283
|
const prevOverflow = document.body.style.overflow;
|
|
2159
2284
|
document.body.style.overflow = "hidden";
|
|
@@ -2161,13 +2286,13 @@ var NumpadDialog = ({
|
|
|
2161
2286
|
document.body.style.overflow = prevOverflow;
|
|
2162
2287
|
};
|
|
2163
2288
|
}, [isOpen]);
|
|
2164
|
-
const handleApply = (0,
|
|
2289
|
+
const handleApply = (0, import_react7.useCallback)(() => {
|
|
2165
2290
|
const n = Number(inputValue);
|
|
2166
2291
|
if (inputValue === "" || inputValue === "-" || inputValue === "." || inputValue === "-.") return;
|
|
2167
2292
|
if (isNaN(n) || n < min || n > max) return;
|
|
2168
2293
|
onApply(Number(n.toFixed(decimals)));
|
|
2169
2294
|
}, [inputValue, min, max, onApply, decimals]);
|
|
2170
|
-
const appendDigit = (0,
|
|
2295
|
+
const appendDigit = (0, import_react7.useCallback)(
|
|
2171
2296
|
(digit) => {
|
|
2172
2297
|
setInputValue((prev) => {
|
|
2173
2298
|
const base = pristine ? "" : prev;
|
|
@@ -2187,15 +2312,15 @@ var NumpadDialog = ({
|
|
|
2187
2312
|
},
|
|
2188
2313
|
[pristine, decimals]
|
|
2189
2314
|
);
|
|
2190
|
-
const handleBackspace = (0,
|
|
2315
|
+
const handleBackspace = (0, import_react7.useCallback)(() => {
|
|
2191
2316
|
setPristine(false);
|
|
2192
2317
|
setInputValue((prev) => prev.slice(0, -1));
|
|
2193
2318
|
}, []);
|
|
2194
|
-
const handleClear = (0,
|
|
2319
|
+
const handleClear = (0, import_react7.useCallback)(() => {
|
|
2195
2320
|
setPristine(false);
|
|
2196
2321
|
setInputValue("");
|
|
2197
2322
|
}, []);
|
|
2198
|
-
const handleToggleSign = (0,
|
|
2323
|
+
const handleToggleSign = (0, import_react7.useCallback)(() => {
|
|
2199
2324
|
if (min >= 0) return;
|
|
2200
2325
|
setPristine(false);
|
|
2201
2326
|
setInputValue((prev) => {
|
|
@@ -2204,8 +2329,8 @@ var NumpadDialog = ({
|
|
|
2204
2329
|
return "-" + prev;
|
|
2205
2330
|
});
|
|
2206
2331
|
}, [min]);
|
|
2207
|
-
const bsTimer = (0,
|
|
2208
|
-
const bsLongFired = (0,
|
|
2332
|
+
const bsTimer = (0, import_react7.useRef)(null);
|
|
2333
|
+
const bsLongFired = (0, import_react7.useRef)(false);
|
|
2209
2334
|
const clearBsTimer = () => {
|
|
2210
2335
|
if (bsTimer.current !== null) {
|
|
2211
2336
|
clearTimeout(bsTimer.current);
|
|
@@ -2227,8 +2352,8 @@ var NumpadDialog = ({
|
|
|
2227
2352
|
}
|
|
2228
2353
|
handleBackspace();
|
|
2229
2354
|
};
|
|
2230
|
-
(0,
|
|
2231
|
-
(0,
|
|
2355
|
+
(0, import_react7.useEffect)(() => () => clearBsTimer(), []);
|
|
2356
|
+
(0, import_react7.useEffect)(() => {
|
|
2232
2357
|
if (!isOpen) return;
|
|
2233
2358
|
const handler = (e) => {
|
|
2234
2359
|
if (e.key === "Tab") {
|
|
@@ -2326,7 +2451,7 @@ var NumpadDialog = ({
|
|
|
2326
2451
|
};
|
|
2327
2452
|
const reason = belowMin ? `Below minimum of ${min} ${unit}` : aboveMax ? `Above maximum of ${max} ${unit}` : "Type or tap to change the value";
|
|
2328
2453
|
const backspaceInGrid = min >= 0;
|
|
2329
|
-
const BackspaceButton = ({ style, label }) => /* @__PURE__ */ (0,
|
|
2454
|
+
const BackspaceButton = ({ style, label }) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2330
2455
|
"button",
|
|
2331
2456
|
{
|
|
2332
2457
|
type: "button",
|
|
@@ -2343,7 +2468,7 @@ var NumpadDialog = ({
|
|
|
2343
2468
|
);
|
|
2344
2469
|
return (
|
|
2345
2470
|
// Backdrop
|
|
2346
|
-
/* @__PURE__ */ (0,
|
|
2471
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
2347
2472
|
"div",
|
|
2348
2473
|
{
|
|
2349
2474
|
style: {
|
|
@@ -2360,14 +2485,14 @@ var NumpadDialog = ({
|
|
|
2360
2485
|
},
|
|
2361
2486
|
onClick: onClose,
|
|
2362
2487
|
children: [
|
|
2363
|
-
/* @__PURE__ */ (0,
|
|
2488
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("style", { children: `
|
|
2364
2489
|
.np-key { transition: background .1s, transform .05s; touch-action: manipulation; }
|
|
2365
2490
|
.np-key:active:not(:disabled) { background:#e2e8f0; transform: translateY(1px); }
|
|
2366
2491
|
.np-key:focus-visible, .np-action:focus-visible { outline: 3px solid #2563eb; outline-offset: 2px; }
|
|
2367
2492
|
@keyframes np-blink { 0%,49%{opacity:1} 50%,100%{opacity:0} }
|
|
2368
2493
|
.np-caret { display:inline-block; width:2px; height:1.1em; background:#2563eb; animation: np-blink 1s step-end infinite; }
|
|
2369
2494
|
` }),
|
|
2370
|
-
/* @__PURE__ */ (0,
|
|
2495
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
2371
2496
|
"div",
|
|
2372
2497
|
{
|
|
2373
2498
|
ref: dialogRef,
|
|
@@ -2388,9 +2513,9 @@ var NumpadDialog = ({
|
|
|
2388
2513
|
},
|
|
2389
2514
|
onClick: (e) => e.stopPropagation(),
|
|
2390
2515
|
children: [
|
|
2391
|
-
/* @__PURE__ */ (0,
|
|
2392
|
-
/* @__PURE__ */ (0,
|
|
2393
|
-
/* @__PURE__ */ (0,
|
|
2516
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { padding: "14px 16px 0 16px" }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { id: titleId, style: { margin: 0, fontSize: 15, fontWeight: 700, color: "#0f172a" }, children: deviceName ? `${deviceName} - ${parameterLabel}` : parameterLabel }) }),
|
|
2517
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { padding: 16, display: "flex", flexDirection: "column", gap: 10 }, children: [
|
|
2518
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
2394
2519
|
"div",
|
|
2395
2520
|
{
|
|
2396
2521
|
style: {
|
|
@@ -2400,24 +2525,24 @@ var NumpadDialog = ({
|
|
|
2400
2525
|
color: "#64748b"
|
|
2401
2526
|
},
|
|
2402
2527
|
children: [
|
|
2403
|
-
/* @__PURE__ */ (0,
|
|
2528
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
|
|
2404
2529
|
"Current: ",
|
|
2405
2530
|
currentValue,
|
|
2406
2531
|
" ",
|
|
2407
2532
|
unit
|
|
2408
2533
|
] }),
|
|
2409
|
-
/* @__PURE__ */ (0,
|
|
2534
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
|
|
2410
2535
|
"Range: ",
|
|
2411
|
-
/* @__PURE__ */ (0,
|
|
2536
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: limitStyle(belowMin), children: min }),
|
|
2412
2537
|
"-",
|
|
2413
|
-
/* @__PURE__ */ (0,
|
|
2538
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: limitStyle(aboveMax), children: max }),
|
|
2414
2539
|
" ",
|
|
2415
2540
|
unit
|
|
2416
2541
|
] })
|
|
2417
2542
|
]
|
|
2418
2543
|
}
|
|
2419
2544
|
),
|
|
2420
|
-
/* @__PURE__ */ (0,
|
|
2545
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
2421
2546
|
"div",
|
|
2422
2547
|
{
|
|
2423
2548
|
"aria-live": "polite",
|
|
@@ -2439,13 +2564,13 @@ var NumpadDialog = ({
|
|
|
2439
2564
|
border: outOfRange ? "1.5px solid #fca5a5" : "1.5px solid #e2e8f0"
|
|
2440
2565
|
},
|
|
2441
2566
|
children: [
|
|
2442
|
-
/* @__PURE__ */ (0,
|
|
2443
|
-
/* @__PURE__ */ (0,
|
|
2444
|
-
/* @__PURE__ */ (0,
|
|
2567
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: inputValue || "0" }),
|
|
2568
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "np-caret", "aria-hidden": "true" }),
|
|
2569
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: { fontSize: 14, color: "#94a3b8", fontWeight: 500 }, children: unit })
|
|
2445
2570
|
]
|
|
2446
2571
|
}
|
|
2447
2572
|
),
|
|
2448
|
-
/* @__PURE__ */ (0,
|
|
2573
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2449
2574
|
"div",
|
|
2450
2575
|
{
|
|
2451
2576
|
role: "status",
|
|
@@ -2460,8 +2585,8 @@ var NumpadDialog = ({
|
|
|
2460
2585
|
children: reason
|
|
2461
2586
|
}
|
|
2462
2587
|
),
|
|
2463
|
-
/* @__PURE__ */ (0,
|
|
2464
|
-
["7", "8", "9", "4", "5", "6", "1", "2", "3"].map((digit) => /* @__PURE__ */ (0,
|
|
2588
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 5 }, children: [
|
|
2589
|
+
["7", "8", "9", "4", "5", "6", "1", "2", "3"].map((digit) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2465
2590
|
"button",
|
|
2466
2591
|
{
|
|
2467
2592
|
type: "button",
|
|
@@ -2473,7 +2598,7 @@ var NumpadDialog = ({
|
|
|
2473
2598
|
},
|
|
2474
2599
|
digit
|
|
2475
2600
|
)),
|
|
2476
|
-
min < 0 ? /* @__PURE__ */ (0,
|
|
2601
|
+
min < 0 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2477
2602
|
"button",
|
|
2478
2603
|
{
|
|
2479
2604
|
type: "button",
|
|
@@ -2484,9 +2609,9 @@ var NumpadDialog = ({
|
|
|
2484
2609
|
onClick: handleToggleSign,
|
|
2485
2610
|
children: "+/\u2212"
|
|
2486
2611
|
}
|
|
2487
|
-
) : /* @__PURE__ */ (0,
|
|
2488
|
-
/* @__PURE__ */ (0,
|
|
2489
|
-
/* @__PURE__ */ (0,
|
|
2612
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(BackspaceButton, { style: { ...keyStyle, fontSize: 20, background: "#f8fafc", color: "#64748b" }, label: "\u232B" }),
|
|
2613
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: "np-key", tabIndex: -1, style: keyStyle, onClick: () => appendDigit("0"), children: "0" }),
|
|
2614
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2490
2615
|
"button",
|
|
2491
2616
|
{
|
|
2492
2617
|
type: "button",
|
|
@@ -2504,12 +2629,12 @@ var NumpadDialog = ({
|
|
|
2504
2629
|
}
|
|
2505
2630
|
)
|
|
2506
2631
|
] }),
|
|
2507
|
-
/* @__PURE__ */ (0,
|
|
2508
|
-
/* @__PURE__ */ (0,
|
|
2509
|
-
!backspaceInGrid && /* @__PURE__ */ (0,
|
|
2632
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { display: "flex", gap: 5 }, children: [
|
|
2633
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: "np-key", tabIndex: -1, style: utilKeyStyle, onClick: handleClear, children: "Clear" }),
|
|
2634
|
+
!backspaceInGrid && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(BackspaceButton, { style: utilKeyStyle, label: "Backspace" })
|
|
2510
2635
|
] }),
|
|
2511
|
-
/* @__PURE__ */ (0,
|
|
2512
|
-
/* @__PURE__ */ (0,
|
|
2636
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { display: "flex", gap: 8, marginTop: 2 }, children: [
|
|
2637
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2513
2638
|
"button",
|
|
2514
2639
|
{
|
|
2515
2640
|
type: "button",
|
|
@@ -2529,7 +2654,7 @@ var NumpadDialog = ({
|
|
|
2529
2654
|
children: "Cancel"
|
|
2530
2655
|
}
|
|
2531
2656
|
),
|
|
2532
|
-
/* @__PURE__ */ (0,
|
|
2657
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2533
2658
|
"button",
|
|
2534
2659
|
{
|
|
2535
2660
|
type: "button",
|
|
@@ -2564,13 +2689,13 @@ var NumpadDialog = ({
|
|
|
2564
2689
|
};
|
|
2565
2690
|
|
|
2566
2691
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.tsx
|
|
2567
|
-
var
|
|
2692
|
+
var import_react9 = __toESM(require("react"), 1);
|
|
2568
2693
|
var import_material3 = require("@mui/material");
|
|
2569
2694
|
|
|
2570
2695
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.styles.tsx
|
|
2571
2696
|
var import_material = require("@mui/material");
|
|
2572
2697
|
var import_styled = __toESM(require("@emotion/styled"), 1);
|
|
2573
|
-
var
|
|
2698
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2574
2699
|
var FullscreenContainer = (0, import_styled.default)(import_material.Box)(
|
|
2575
2700
|
({ leftCollapsed, rightCollapsed }) => {
|
|
2576
2701
|
const getGridTemplateAreas = () => {
|
|
@@ -2695,7 +2820,7 @@ var DisplayModeToggle = (0, import_styled.default)(import_material.IconButton)((
|
|
|
2695
2820
|
transform: "translateX(-50%) scale(1.05)"
|
|
2696
2821
|
}
|
|
2697
2822
|
}));
|
|
2698
|
-
var ChevronLeft = () => /* @__PURE__ */ (0,
|
|
2823
|
+
var ChevronLeft = () => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2699
2824
|
"div",
|
|
2700
2825
|
{
|
|
2701
2826
|
style: {
|
|
@@ -2707,7 +2832,7 @@ var ChevronLeft = () => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
|
2707
2832
|
}
|
|
2708
2833
|
}
|
|
2709
2834
|
);
|
|
2710
|
-
var ChevronRight = () => /* @__PURE__ */ (0,
|
|
2835
|
+
var ChevronRight = () => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2711
2836
|
"div",
|
|
2712
2837
|
{
|
|
2713
2838
|
style: {
|
|
@@ -2818,10 +2943,10 @@ var ScrollableSVGWrapper = (0, import_styled.default)("div")({
|
|
|
2818
2943
|
});
|
|
2819
2944
|
|
|
2820
2945
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.overlays.tsx
|
|
2821
|
-
var
|
|
2946
|
+
var import_react8 = require("react");
|
|
2822
2947
|
var import_material2 = require("@mui/material");
|
|
2823
2948
|
var import_styled2 = __toESM(require("@emotion/styled"), 1);
|
|
2824
|
-
var
|
|
2949
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2825
2950
|
var baseOverlayStyles = {
|
|
2826
2951
|
tank: {
|
|
2827
2952
|
background: "linear-gradient(135deg, rgba(69, 90, 120, 0.95) 0%, rgba(52, 73, 94, 0.95) 100%)",
|
|
@@ -2883,8 +3008,8 @@ var SVGLockedOverlay = ({
|
|
|
2883
3008
|
onClick,
|
|
2884
3009
|
containerSelector = ".tff-svg-container"
|
|
2885
3010
|
}) => {
|
|
2886
|
-
const [svgOffset, setSvgOffset] = (0,
|
|
2887
|
-
(0,
|
|
3011
|
+
const [svgOffset, setSvgOffset] = (0, import_react8.useState)({ x: 0, y: 0 });
|
|
3012
|
+
(0, import_react8.useEffect)(() => {
|
|
2888
3013
|
const updateSvgOffset = () => {
|
|
2889
3014
|
const containerElement = document.querySelector(containerSelector);
|
|
2890
3015
|
const svgElement = containerElement?.querySelector("svg");
|
|
@@ -2904,7 +3029,7 @@ var SVGLockedOverlay = ({
|
|
|
2904
3029
|
const pixelX = svgX + svgOffset.x;
|
|
2905
3030
|
const pixelY = svgY + svgOffset.y;
|
|
2906
3031
|
const appliedStyle = theme ? { ...overlayStyles[theme], ...style } : style;
|
|
2907
|
-
return /* @__PURE__ */ (0,
|
|
3032
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2908
3033
|
import_material2.Box,
|
|
2909
3034
|
{
|
|
2910
3035
|
className: `svg-locked-overlay ${className}`.trim(),
|
|
@@ -2968,7 +3093,7 @@ var CardUnit = (0, import_styled2.default)("div")({
|
|
|
2968
3093
|
});
|
|
2969
3094
|
|
|
2970
3095
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.visuals.tsx
|
|
2971
|
-
var
|
|
3096
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2972
3097
|
var forcedTagStyle = {
|
|
2973
3098
|
position: "absolute",
|
|
2974
3099
|
top: "-6px",
|
|
@@ -2996,7 +3121,7 @@ var TrendLine = ({
|
|
|
2996
3121
|
forced = false
|
|
2997
3122
|
}) => {
|
|
2998
3123
|
if (!values || values.length < 2) {
|
|
2999
|
-
return /* @__PURE__ */ (0,
|
|
3124
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
3000
3125
|
"div",
|
|
3001
3126
|
{
|
|
3002
3127
|
style: {
|
|
@@ -3010,8 +3135,8 @@ var TrendLine = ({
|
|
|
3010
3135
|
justifyContent: "center"
|
|
3011
3136
|
},
|
|
3012
3137
|
children: [
|
|
3013
|
-
/* @__PURE__ */ (0,
|
|
3014
|
-
forced && /* @__PURE__ */ (0,
|
|
3138
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: { fontSize: "8px", color: "#ccc" }, children: "No data" }),
|
|
3139
|
+
forced && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: forcedTagStyle, "aria-label": "Forced", children: "F" })
|
|
3015
3140
|
]
|
|
3016
3141
|
}
|
|
3017
3142
|
);
|
|
@@ -3024,7 +3149,7 @@ var TrendLine = ({
|
|
|
3024
3149
|
const x = 4 + i / (values.length - 1) * (width - 8);
|
|
3025
3150
|
return i === 0 ? `M ${x} ${y}` : `L ${x} ${y}`;
|
|
3026
3151
|
}).join(" ");
|
|
3027
|
-
return /* @__PURE__ */ (0,
|
|
3152
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
3028
3153
|
"div",
|
|
3029
3154
|
{
|
|
3030
3155
|
style: {
|
|
@@ -3036,14 +3161,14 @@ var TrendLine = ({
|
|
|
3036
3161
|
overflow: "visible"
|
|
3037
3162
|
},
|
|
3038
3163
|
children: [
|
|
3039
|
-
/* @__PURE__ */ (0,
|
|
3164
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
3040
3165
|
"svg",
|
|
3041
3166
|
{
|
|
3042
3167
|
width,
|
|
3043
3168
|
height,
|
|
3044
3169
|
style: { position: "absolute", top: 0, left: 0, overflow: "hidden", borderRadius: "2px" },
|
|
3045
3170
|
children: [
|
|
3046
|
-
/* @__PURE__ */ (0,
|
|
3171
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3047
3172
|
"path",
|
|
3048
3173
|
{
|
|
3049
3174
|
d: pathData,
|
|
@@ -3054,7 +3179,7 @@ var TrendLine = ({
|
|
|
3054
3179
|
strokeLinejoin: "round"
|
|
3055
3180
|
}
|
|
3056
3181
|
),
|
|
3057
|
-
/* @__PURE__ */ (0,
|
|
3182
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3058
3183
|
"circle",
|
|
3059
3184
|
{
|
|
3060
3185
|
cx: 4 + (width - 8),
|
|
@@ -3066,7 +3191,7 @@ var TrendLine = ({
|
|
|
3066
3191
|
]
|
|
3067
3192
|
}
|
|
3068
3193
|
),
|
|
3069
|
-
forced && /* @__PURE__ */ (0,
|
|
3194
|
+
forced && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: forcedTagStyle, "aria-label": "Forced", children: "F" })
|
|
3070
3195
|
]
|
|
3071
3196
|
}
|
|
3072
3197
|
);
|
|
@@ -3098,7 +3223,7 @@ var CircularGauge = ({
|
|
|
3098
3223
|
const borderColor = isHex ? hexToRgba(color, 0.9) : color;
|
|
3099
3224
|
const backgroundColor = isHex ? hexToRgba(color, 0.15) : color;
|
|
3100
3225
|
const borderStrokeColor = isHex ? hexToRgba(color, 0.4) : color;
|
|
3101
|
-
return /* @__PURE__ */ (0,
|
|
3226
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
3102
3227
|
"div",
|
|
3103
3228
|
{
|
|
3104
3229
|
style: {
|
|
@@ -3107,7 +3232,7 @@ var CircularGauge = ({
|
|
|
3107
3232
|
alignItems: "center"
|
|
3108
3233
|
},
|
|
3109
3234
|
children: [
|
|
3110
|
-
/* @__PURE__ */ (0,
|
|
3235
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
3111
3236
|
"div",
|
|
3112
3237
|
{
|
|
3113
3238
|
style: {
|
|
@@ -3119,8 +3244,8 @@ var CircularGauge = ({
|
|
|
3119
3244
|
border: forced ? `2px solid ${FORCED_MARK_COLOR.border}` : `1px solid ${borderStrokeColor}`
|
|
3120
3245
|
},
|
|
3121
3246
|
children: [
|
|
3122
|
-
/* @__PURE__ */ (0,
|
|
3123
|
-
/* @__PURE__ */ (0,
|
|
3247
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("svg", { width: size, height: size, style: { transform: "rotate(-90deg)" }, children: [
|
|
3248
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3124
3249
|
"circle",
|
|
3125
3250
|
{
|
|
3126
3251
|
cx: size / 2,
|
|
@@ -3131,7 +3256,7 @@ var CircularGauge = ({
|
|
|
3131
3256
|
strokeWidth: 1
|
|
3132
3257
|
}
|
|
3133
3258
|
),
|
|
3134
|
-
/* @__PURE__ */ (0,
|
|
3259
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3135
3260
|
"circle",
|
|
3136
3261
|
{
|
|
3137
3262
|
cx: size / 2,
|
|
@@ -3142,7 +3267,7 @@ var CircularGauge = ({
|
|
|
3142
3267
|
fill: "transparent"
|
|
3143
3268
|
}
|
|
3144
3269
|
),
|
|
3145
|
-
/* @__PURE__ */ (0,
|
|
3270
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3146
3271
|
"circle",
|
|
3147
3272
|
{
|
|
3148
3273
|
cx: size / 2,
|
|
@@ -3158,7 +3283,7 @@ var CircularGauge = ({
|
|
|
3158
3283
|
}
|
|
3159
3284
|
)
|
|
3160
3285
|
] }),
|
|
3161
|
-
/* @__PURE__ */ (0,
|
|
3286
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
3162
3287
|
"div",
|
|
3163
3288
|
{
|
|
3164
3289
|
style: {
|
|
@@ -3174,14 +3299,14 @@ var CircularGauge = ({
|
|
|
3174
3299
|
},
|
|
3175
3300
|
children: [
|
|
3176
3301
|
value.toFixed(1),
|
|
3177
|
-
/* @__PURE__ */ (0,
|
|
3302
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { fontSize: "8px", opacity: 0.9, color: "white" }, children: unit })
|
|
3178
3303
|
]
|
|
3179
3304
|
}
|
|
3180
3305
|
)
|
|
3181
3306
|
]
|
|
3182
3307
|
}
|
|
3183
3308
|
),
|
|
3184
|
-
/* @__PURE__ */ (0,
|
|
3309
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3185
3310
|
"div",
|
|
3186
3311
|
{
|
|
3187
3312
|
style: {
|
|
@@ -3193,7 +3318,7 @@ var CircularGauge = ({
|
|
|
3193
3318
|
children: label
|
|
3194
3319
|
}
|
|
3195
3320
|
),
|
|
3196
|
-
forced && /* @__PURE__ */ (0,
|
|
3321
|
+
forced && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3197
3322
|
"span",
|
|
3198
3323
|
{
|
|
3199
3324
|
"aria-label": "Forced",
|
|
@@ -3214,7 +3339,7 @@ var CircularGauge = ({
|
|
|
3214
3339
|
children: "F"
|
|
3215
3340
|
}
|
|
3216
3341
|
),
|
|
3217
|
-
forced && realValue !== void 0 && /* @__PURE__ */ (0,
|
|
3342
|
+
forced && realValue !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: { fontSize: "8px", opacity: 0.8, color: "white", marginTop: "1px" }, children: [
|
|
3218
3343
|
"REAL ",
|
|
3219
3344
|
realValue.toFixed(1),
|
|
3220
3345
|
" ",
|
|
@@ -3239,7 +3364,7 @@ var Sparkline = ({ data, width, height, color, forced = false }) => {
|
|
|
3239
3364
|
const y = height - 8 - (value - min) / range * (height - 8);
|
|
3240
3365
|
return `${x + 4},${y + 4}`;
|
|
3241
3366
|
}).join(" ");
|
|
3242
|
-
return /* @__PURE__ */ (0,
|
|
3367
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
3243
3368
|
"div",
|
|
3244
3369
|
{
|
|
3245
3370
|
style: {
|
|
@@ -3255,13 +3380,13 @@ var Sparkline = ({ data, width, height, color, forced = false }) => {
|
|
|
3255
3380
|
boxShadow: "0 1px 3px rgba(0, 0, 0, 0.2)"
|
|
3256
3381
|
},
|
|
3257
3382
|
children: [
|
|
3258
|
-
/* @__PURE__ */ (0,
|
|
3259
|
-
forced && /* @__PURE__ */ (0,
|
|
3383
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("svg", { width, height, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("polyline", { points, fill: "none", stroke: color, strokeWidth: "1.5", opacity: "0.9" }) }),
|
|
3384
|
+
forced && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: forcedTagStyle, "aria-label": "Forced", children: "F" })
|
|
3260
3385
|
]
|
|
3261
3386
|
}
|
|
3262
3387
|
);
|
|
3263
3388
|
};
|
|
3264
|
-
var EquipmentForcedBadge = () => /* @__PURE__ */ (0,
|
|
3389
|
+
var EquipmentForcedBadge = () => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3265
3390
|
"span",
|
|
3266
3391
|
{
|
|
3267
3392
|
"aria-label": "Forced",
|
|
@@ -3296,9 +3421,9 @@ var EquipmentIndicatorWithSparkline = ({
|
|
|
3296
3421
|
forced = false
|
|
3297
3422
|
}) => {
|
|
3298
3423
|
const hasSparkline = sparklineData && sparklineData.length > 1 && Math.max(...sparklineData) !== Math.min(...sparklineData);
|
|
3299
|
-
return /* @__PURE__ */ (0,
|
|
3300
|
-
/* @__PURE__ */ (0,
|
|
3301
|
-
/* @__PURE__ */ (0,
|
|
3424
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
3425
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SVGLockedOverlay, { svgX, svgY, style: { transform: "translate(-50%, -50%)" }, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: { position: "relative", width: size, height: size }, children: [
|
|
3426
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3302
3427
|
"div",
|
|
3303
3428
|
{
|
|
3304
3429
|
style: {
|
|
@@ -3319,9 +3444,9 @@ var EquipmentIndicatorWithSparkline = ({
|
|
|
3319
3444
|
children: label
|
|
3320
3445
|
}
|
|
3321
3446
|
),
|
|
3322
|
-
forced && /* @__PURE__ */ (0,
|
|
3447
|
+
forced && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(EquipmentForcedBadge, {})
|
|
3323
3448
|
] }) }),
|
|
3324
|
-
hasSparkline && /* @__PURE__ */ (0,
|
|
3449
|
+
hasSparkline && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SVGLockedOverlay, { svgX: svgX + sparklineOffset.x, svgY: svgY + sparklineOffset.y, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Sparkline, { data: sparklineData, width: 60, height: 20, color, forced }) })
|
|
3325
3450
|
] });
|
|
3326
3451
|
};
|
|
3327
3452
|
var EquipmentIndicator = ({
|
|
@@ -3335,8 +3460,8 @@ var EquipmentIndicator = ({
|
|
|
3335
3460
|
forced = false
|
|
3336
3461
|
}) => {
|
|
3337
3462
|
const overlayStyle = style !== void 0 ? { transform: "translate(-50%, -50%)", ...style } : { transform: "translate(-50%, -50%)" };
|
|
3338
|
-
return /* @__PURE__ */ (0,
|
|
3339
|
-
/* @__PURE__ */ (0,
|
|
3463
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SVGLockedOverlay, { svgX, svgY, style: overlayStyle, className, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: { position: "relative", width: size, height: size }, children: [
|
|
3464
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3340
3465
|
"div",
|
|
3341
3466
|
{
|
|
3342
3467
|
style: {
|
|
@@ -3357,12 +3482,12 @@ var EquipmentIndicator = ({
|
|
|
3357
3482
|
children: label
|
|
3358
3483
|
}
|
|
3359
3484
|
),
|
|
3360
|
-
forced && /* @__PURE__ */ (0,
|
|
3485
|
+
forced && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(EquipmentForcedBadge, {})
|
|
3361
3486
|
] }) });
|
|
3362
3487
|
};
|
|
3363
3488
|
|
|
3364
3489
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.tsx
|
|
3365
|
-
var
|
|
3490
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
3366
3491
|
function FullscreenWorkspace({
|
|
3367
3492
|
svgContent,
|
|
3368
3493
|
overlays,
|
|
@@ -3390,10 +3515,10 @@ function FullscreenWorkspace({
|
|
|
3390
3515
|
className = "",
|
|
3391
3516
|
...rest
|
|
3392
3517
|
}) {
|
|
3393
|
-
const [leftCollapsedState, setLeftCollapsedState] =
|
|
3394
|
-
const [rightCollapsedState, setRightCollapsedState] =
|
|
3395
|
-
const [internalDisplayMode, setInternalDisplayMode] =
|
|
3396
|
-
const [internalTab, setInternalTab] =
|
|
3518
|
+
const [leftCollapsedState, setLeftCollapsedState] = import_react9.default.useState(defaultLeftCollapsed);
|
|
3519
|
+
const [rightCollapsedState, setRightCollapsedState] = import_react9.default.useState(defaultRightCollapsed);
|
|
3520
|
+
const [internalDisplayMode, setInternalDisplayMode] = import_react9.default.useState(displayMode ?? defaultDisplayMode);
|
|
3521
|
+
const [internalTab, setInternalTab] = import_react9.default.useState(
|
|
3397
3522
|
tabs && tabs.length > 0 ? tabs[0].value : ""
|
|
3398
3523
|
);
|
|
3399
3524
|
const leftCollapsed = leftCollapsedProp ?? leftCollapsedState;
|
|
@@ -3401,10 +3526,10 @@ function FullscreenWorkspace({
|
|
|
3401
3526
|
const isDisplayModeControlled = displayMode !== void 0;
|
|
3402
3527
|
const currentDisplayMode = isDisplayModeControlled ? displayMode : internalDisplayMode;
|
|
3403
3528
|
const isTabControlled = activeTab !== void 0 && activeTab !== null;
|
|
3404
|
-
const resolvedTabs =
|
|
3529
|
+
const resolvedTabs = import_react9.default.useMemo(() => tabs ?? [], [tabs]);
|
|
3405
3530
|
const defaultTabValue = resolvedTabs.length > 0 ? resolvedTabs[0].value : "";
|
|
3406
3531
|
const currentTab = isTabControlled ? activeTab : internalTab || defaultTabValue;
|
|
3407
|
-
|
|
3532
|
+
import_react9.default.useEffect(() => {
|
|
3408
3533
|
if (resolvedTabs.length > 0) {
|
|
3409
3534
|
const values = resolvedTabs.map((tab) => tab.value);
|
|
3410
3535
|
if (!values.includes(currentTab)) {
|
|
@@ -3413,7 +3538,7 @@ function FullscreenWorkspace({
|
|
|
3413
3538
|
}
|
|
3414
3539
|
}
|
|
3415
3540
|
}, [resolvedTabs, activeTab, currentTab, defaultTabValue]);
|
|
3416
|
-
|
|
3541
|
+
import_react9.default.useEffect(() => {
|
|
3417
3542
|
if (displayMode !== void 0) {
|
|
3418
3543
|
setInternalDisplayMode(displayMode);
|
|
3419
3544
|
}
|
|
@@ -3448,7 +3573,7 @@ function FullscreenWorkspace({
|
|
|
3448
3573
|
const currentTabContent = resolvedTabs.find((tab) => tab.value === currentTab)?.content ?? null;
|
|
3449
3574
|
const showLeftToggle = Boolean(leftPanel);
|
|
3450
3575
|
const showRightToggle = Boolean(rightPanel);
|
|
3451
|
-
return /* @__PURE__ */ (0,
|
|
3576
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
3452
3577
|
FullscreenContainer,
|
|
3453
3578
|
{
|
|
3454
3579
|
leftCollapsed,
|
|
@@ -3456,25 +3581,25 @@ function FullscreenWorkspace({
|
|
|
3456
3581
|
className: `tff-svg-container ${className}`.trim(),
|
|
3457
3582
|
...rest,
|
|
3458
3583
|
children: [
|
|
3459
|
-
showLeftToggle && /* @__PURE__ */ (0,
|
|
3584
|
+
showLeftToggle && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3460
3585
|
LeftToggleButton,
|
|
3461
3586
|
{
|
|
3462
3587
|
collapsed: leftCollapsed,
|
|
3463
3588
|
onClick: handleLeftToggle,
|
|
3464
3589
|
"aria-label": leftCollapsed ? "Expand left panel" : "Collapse left panel",
|
|
3465
|
-
children: leftCollapsed ? /* @__PURE__ */ (0,
|
|
3590
|
+
children: leftCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ChevronRight, {}) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ChevronLeft, {})
|
|
3466
3591
|
}
|
|
3467
3592
|
),
|
|
3468
|
-
showRightToggle && /* @__PURE__ */ (0,
|
|
3593
|
+
showRightToggle && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3469
3594
|
RightToggleButton,
|
|
3470
3595
|
{
|
|
3471
3596
|
collapsed: rightCollapsed,
|
|
3472
3597
|
onClick: handleRightToggle,
|
|
3473
3598
|
"aria-label": rightCollapsed ? "Expand right panel" : "Collapse right panel",
|
|
3474
|
-
children: rightCollapsed ? /* @__PURE__ */ (0,
|
|
3599
|
+
children: rightCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ChevronLeft, {}) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ChevronRight, {})
|
|
3475
3600
|
}
|
|
3476
3601
|
),
|
|
3477
|
-
showDisplayModeToggle && /* @__PURE__ */ (0,
|
|
3602
|
+
showDisplayModeToggle && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3478
3603
|
DisplayModeToggle,
|
|
3479
3604
|
{
|
|
3480
3605
|
mode: currentDisplayMode,
|
|
@@ -3483,9 +3608,9 @@ function FullscreenWorkspace({
|
|
|
3483
3608
|
children: currentDisplayMode === "dashboard" ? "Dashboard Mode" : "Standard Mode"
|
|
3484
3609
|
}
|
|
3485
3610
|
),
|
|
3486
|
-
/* @__PURE__ */ (0,
|
|
3487
|
-
showZoomControls && /* @__PURE__ */ (0,
|
|
3488
|
-
/* @__PURE__ */ (0,
|
|
3611
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(SVGArea, { children: [
|
|
3612
|
+
showZoomControls && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(ZoomControls, { children: [
|
|
3613
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3489
3614
|
ZoomButton,
|
|
3490
3615
|
{
|
|
3491
3616
|
onClick: onZoomIn,
|
|
@@ -3495,7 +3620,7 @@ function FullscreenWorkspace({
|
|
|
3495
3620
|
children: "+"
|
|
3496
3621
|
}
|
|
3497
3622
|
),
|
|
3498
|
-
/* @__PURE__ */ (0,
|
|
3623
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3499
3624
|
ZoomButton,
|
|
3500
3625
|
{
|
|
3501
3626
|
onClick: onZoomOut,
|
|
@@ -3505,7 +3630,7 @@ function FullscreenWorkspace({
|
|
|
3505
3630
|
children: "-"
|
|
3506
3631
|
}
|
|
3507
3632
|
),
|
|
3508
|
-
onResetZoom && /* @__PURE__ */ (0,
|
|
3633
|
+
onResetZoom && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3509
3634
|
ZoomButton,
|
|
3510
3635
|
{
|
|
3511
3636
|
onClick: onResetZoom,
|
|
@@ -3516,44 +3641,44 @@ function FullscreenWorkspace({
|
|
|
3516
3641
|
}
|
|
3517
3642
|
)
|
|
3518
3643
|
] }),
|
|
3519
|
-
/* @__PURE__ */ (0,
|
|
3644
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ScrollableSVGWrapper, { className: "svg-scroll-wrapper", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(FixedSVGContainer, { className: "svg-container", children: [
|
|
3520
3645
|
svgContent,
|
|
3521
3646
|
overlays
|
|
3522
3647
|
] }) })
|
|
3523
3648
|
] }),
|
|
3524
|
-
/* @__PURE__ */ (0,
|
|
3525
|
-
/* @__PURE__ */ (0,
|
|
3649
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(LeftPanel, { collapsed: leftCollapsed, children: resolvedTabs.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
3650
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3526
3651
|
PanelTabs,
|
|
3527
3652
|
{
|
|
3528
3653
|
value: currentTab,
|
|
3529
3654
|
onChange: handleTabChangeInternal,
|
|
3530
3655
|
"aria-label": "Left panel tabs",
|
|
3531
|
-
children: resolvedTabs.map((tab) => /* @__PURE__ */ (0,
|
|
3656
|
+
children: resolvedTabs.map((tab) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material3.Tab, { label: tab.label, value: tab.value }, tab.value))
|
|
3532
3657
|
}
|
|
3533
3658
|
),
|
|
3534
|
-
/* @__PURE__ */ (0,
|
|
3659
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(PanelContent, { children: currentTabContent })
|
|
3535
3660
|
] }) : leftPanel }),
|
|
3536
|
-
/* @__PURE__ */ (0,
|
|
3537
|
-
/* @__PURE__ */ (0,
|
|
3661
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(RightPanel, { collapsed: rightCollapsed, children: rightPanel }),
|
|
3662
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(FooterPanel, { children: footer })
|
|
3538
3663
|
]
|
|
3539
3664
|
}
|
|
3540
3665
|
);
|
|
3541
3666
|
}
|
|
3542
3667
|
|
|
3543
3668
|
// src/theme/ThemeContext.tsx
|
|
3544
|
-
var
|
|
3545
|
-
var
|
|
3546
|
-
var ThemeContext = (0,
|
|
3669
|
+
var import_react10 = require("react");
|
|
3670
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
3671
|
+
var ThemeContext = (0, import_react10.createContext)(void 0);
|
|
3547
3672
|
var useTheme = () => {
|
|
3548
|
-
const context = (0,
|
|
3673
|
+
const context = (0, import_react10.useContext)(ThemeContext);
|
|
3549
3674
|
if (!context) {
|
|
3550
3675
|
throw new Error("useTheme must be used within a ThemeProvider");
|
|
3551
3676
|
}
|
|
3552
3677
|
return context;
|
|
3553
3678
|
};
|
|
3554
3679
|
var ThemeProvider = ({ children }) => {
|
|
3555
|
-
const [theme, setThemeState] = (0,
|
|
3556
|
-
(0,
|
|
3680
|
+
const [theme, setThemeState] = (0, import_react10.useState)("modern");
|
|
3681
|
+
(0, import_react10.useEffect)(() => {
|
|
3557
3682
|
document.body.className = "";
|
|
3558
3683
|
document.body.classList.add(`theme-${theme}`);
|
|
3559
3684
|
document.documentElement.className = "";
|
|
@@ -3565,11 +3690,11 @@ var ThemeProvider = ({ children }) => {
|
|
|
3565
3690
|
const setTheme = (newTheme) => {
|
|
3566
3691
|
setThemeState(newTheme);
|
|
3567
3692
|
};
|
|
3568
|
-
return /* @__PURE__ */ (0,
|
|
3693
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ThemeContext.Provider, { value: { theme, toggleTheme, setTheme }, children });
|
|
3569
3694
|
};
|
|
3570
3695
|
|
|
3571
3696
|
// src/theme/ThemeToggle.tsx
|
|
3572
|
-
var
|
|
3697
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
3573
3698
|
var ThemeToggle = ({
|
|
3574
3699
|
size = "medium",
|
|
3575
3700
|
position = "top-right",
|
|
@@ -3640,18 +3765,18 @@ var ThemeToggle = ({
|
|
|
3640
3765
|
transition: "all 0.2s ease",
|
|
3641
3766
|
boxShadow: "0 2px 4px rgba(0, 0, 0, 0.2)"
|
|
3642
3767
|
};
|
|
3643
|
-
return /* @__PURE__ */ (0,
|
|
3644
|
-
/* @__PURE__ */ (0,
|
|
3645
|
-
/* @__PURE__ */ (0,
|
|
3646
|
-
/* @__PURE__ */ (0,
|
|
3768
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: currentStyle, onClick: toggleTheme, className, ...props, children: [
|
|
3769
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: theme === "modern" ? "\u{1F3A8} Modern" : "\u{1F3ED} HMI" }),
|
|
3770
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: toggleStyle, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: thumbStyle }) }),
|
|
3771
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { style: { fontSize: "0.75rem", opacity: 0.8 }, children: theme === "modern" ? "Industrial Design" : "High Performance" })
|
|
3647
3772
|
] });
|
|
3648
3773
|
};
|
|
3649
3774
|
|
|
3650
3775
|
// src/components/PIDCanvas/PIDCanvas.tsx
|
|
3651
|
-
var
|
|
3776
|
+
var import_react22 = __toESM(require("react"), 1);
|
|
3652
3777
|
|
|
3653
3778
|
// src/components/PIDCanvas/NodeRenderer.tsx
|
|
3654
|
-
var
|
|
3779
|
+
var import_react11 = __toESM(require("react"), 1);
|
|
3655
3780
|
|
|
3656
3781
|
// src/diagram/symbols/mockSymbolLibrary.ts
|
|
3657
3782
|
var mockSymbolLibrary = {
|
|
@@ -5026,8 +5151,14 @@ function writeAppearanceValue(node, field, value) {
|
|
|
5026
5151
|
}
|
|
5027
5152
|
|
|
5028
5153
|
// src/components/PIDCanvas/NodeRenderer.tsx
|
|
5029
|
-
var
|
|
5030
|
-
var
|
|
5154
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
5155
|
+
var HATCH_TILE_SIZE = 7;
|
|
5156
|
+
var HATCH_STRIPE_WIDTH = 2;
|
|
5157
|
+
var HATCH_STRIPE_ANGLE = 135;
|
|
5158
|
+
var HATCH_STRIPE_OPACITY = 85 / 255;
|
|
5159
|
+
function isUnknownNode(node) {
|
|
5160
|
+
return node.positionUnknown === true || normalizeDeviceStatus(node.status) === "unknown";
|
|
5161
|
+
}
|
|
5031
5162
|
function NodeRendererImpl({
|
|
5032
5163
|
nodes: nodes2,
|
|
5033
5164
|
selectedNodeIds,
|
|
@@ -5039,41 +5170,42 @@ function NodeRendererImpl({
|
|
|
5039
5170
|
enableDrag = false,
|
|
5040
5171
|
statusColorMap
|
|
5041
5172
|
}) {
|
|
5042
|
-
const
|
|
5043
|
-
const
|
|
5044
|
-
|
|
5045
|
-
|
|
5173
|
+
const hatchPatternId = `node-unknown-hatch-${import_react11.default.useId().replace(/[^a-zA-Z0-9_-]/g, "")}`;
|
|
5174
|
+
const visibleNodes = nodes2.filter((node) => node.visible !== false);
|
|
5175
|
+
const hasUnknownNode = visibleNodes.some(isUnknownNode);
|
|
5176
|
+
const unknownEntry = resolveStatusColor("unknown", statusColorMap);
|
|
5177
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("g", { id: "layer-nodes", children: [
|
|
5178
|
+
hasUnknownNode && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
5046
5179
|
"pattern",
|
|
5047
5180
|
{
|
|
5048
|
-
id:
|
|
5049
|
-
"data-testid": "
|
|
5181
|
+
id: hatchPatternId,
|
|
5182
|
+
"data-testid": "unknown-hatch-pattern",
|
|
5050
5183
|
patternUnits: "userSpaceOnUse",
|
|
5051
|
-
width:
|
|
5052
|
-
height:
|
|
5053
|
-
patternTransform:
|
|
5184
|
+
width: HATCH_TILE_SIZE,
|
|
5185
|
+
height: HATCH_TILE_SIZE,
|
|
5186
|
+
patternTransform: `rotate(${HATCH_STRIPE_ANGLE})`,
|
|
5054
5187
|
children: [
|
|
5055
|
-
/* @__PURE__ */ (0,
|
|
5056
|
-
/* @__PURE__ */ (0,
|
|
5057
|
-
"
|
|
5188
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("rect", { width: HATCH_TILE_SIZE, height: HATCH_TILE_SIZE, fill: unknownEntry.fill }),
|
|
5189
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5190
|
+
"rect",
|
|
5058
5191
|
{
|
|
5059
|
-
|
|
5060
|
-
|
|
5061
|
-
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
strokeWidth: "2"
|
|
5192
|
+
x: HATCH_TILE_SIZE - HATCH_STRIPE_WIDTH,
|
|
5193
|
+
width: HATCH_STRIPE_WIDTH,
|
|
5194
|
+
height: HATCH_TILE_SIZE,
|
|
5195
|
+
fill: unknownEntry.stroke,
|
|
5196
|
+
fillOpacity: HATCH_STRIPE_OPACITY
|
|
5065
5197
|
}
|
|
5066
5198
|
)
|
|
5067
5199
|
]
|
|
5068
5200
|
}
|
|
5069
5201
|
) }),
|
|
5070
|
-
|
|
5202
|
+
visibleNodes.map((node) => {
|
|
5071
5203
|
const symbol = getSymbolDefinition(node.symbolId);
|
|
5072
5204
|
const isSelected = selectedNodeIds?.has(node.id) ?? false;
|
|
5073
5205
|
const isDragging = draggingNodeId === node.id;
|
|
5074
5206
|
if (!symbol) {
|
|
5075
|
-
return /* @__PURE__ */ (0,
|
|
5076
|
-
/* @__PURE__ */ (0,
|
|
5207
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("g", { children: [
|
|
5208
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5077
5209
|
"circle",
|
|
5078
5210
|
{
|
|
5079
5211
|
cx: node.transform.x,
|
|
@@ -5085,7 +5217,7 @@ function NodeRendererImpl({
|
|
|
5085
5217
|
strokeWidth: "2"
|
|
5086
5218
|
}
|
|
5087
5219
|
),
|
|
5088
|
-
/* @__PURE__ */ (0,
|
|
5220
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5089
5221
|
"text",
|
|
5090
5222
|
{
|
|
5091
5223
|
x: node.transform.x,
|
|
@@ -5125,9 +5257,9 @@ function NodeRendererImpl({
|
|
|
5125
5257
|
);
|
|
5126
5258
|
}
|
|
5127
5259
|
const statusEntry = resolveStatusColor(node.status, statusColorMap);
|
|
5128
|
-
const isUnknown = node
|
|
5129
|
-
const fillColor = isUnknown ? `url(#${
|
|
5130
|
-
const strokeColor = isUnknown ?
|
|
5260
|
+
const isUnknown = isUnknownNode(node);
|
|
5261
|
+
const fillColor = isUnknown ? `url(#${hatchPatternId})` : node.customColors?.fill ?? statusEntry.fill;
|
|
5262
|
+
const strokeColor = isUnknown ? unknownEntry.stroke : node.customColors?.stroke ?? statusEntry.stroke;
|
|
5131
5263
|
const appearance = { ...getAppearanceDefaults(node.symbolId), ...node.metadata ?? {} };
|
|
5132
5264
|
const ledStyle = {};
|
|
5133
5265
|
if (appearance.shape !== void 0) {
|
|
@@ -5138,7 +5270,8 @@ function NodeRendererImpl({
|
|
|
5138
5270
|
ledStyle["--led-bezel"] = appearance.led ? "2" : "0";
|
|
5139
5271
|
}
|
|
5140
5272
|
if (appearance.glow) {
|
|
5141
|
-
|
|
5273
|
+
const glowColor = isUnknown ? unknownEntry.stroke : fillColor;
|
|
5274
|
+
ledStyle.filter = `drop-shadow(0 0 4px ${glowColor})`;
|
|
5142
5275
|
}
|
|
5143
5276
|
const ledAnimation = typeof appearance.animation === "string" && appearance.animation !== "none" ? appearance.animation : void 0;
|
|
5144
5277
|
const vb = symbol.viewBox;
|
|
@@ -5161,7 +5294,7 @@ function NodeRendererImpl({
|
|
|
5161
5294
|
labelY = vb.height / 2 + oy;
|
|
5162
5295
|
labelAnchor = "start";
|
|
5163
5296
|
}
|
|
5164
|
-
return /* @__PURE__ */ (0,
|
|
5297
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
5165
5298
|
"g",
|
|
5166
5299
|
{
|
|
5167
5300
|
"data-node-id": node.id,
|
|
@@ -5169,7 +5302,7 @@ function NodeRendererImpl({
|
|
|
5169
5302
|
"data-selected": isSelected,
|
|
5170
5303
|
"data-dragging": isDragging,
|
|
5171
5304
|
"data-led-animation": ledAnimation,
|
|
5172
|
-
"data-position-unknown":
|
|
5305
|
+
"data-position-unknown": node.positionUnknown === true ? "true" : void 0,
|
|
5173
5306
|
transform: transforms.join(" "),
|
|
5174
5307
|
style: {
|
|
5175
5308
|
"--symbol-fill": fillColor,
|
|
@@ -5197,7 +5330,7 @@ function NodeRendererImpl({
|
|
|
5197
5330
|
}
|
|
5198
5331
|
},
|
|
5199
5332
|
children: [
|
|
5200
|
-
isSelected && /* @__PURE__ */ (0,
|
|
5333
|
+
isSelected && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5201
5334
|
"rect",
|
|
5202
5335
|
{
|
|
5203
5336
|
x: "-5",
|
|
@@ -5212,7 +5345,7 @@ function NodeRendererImpl({
|
|
|
5212
5345
|
pointerEvents: "none"
|
|
5213
5346
|
}
|
|
5214
5347
|
),
|
|
5215
|
-
/* @__PURE__ */ (0,
|
|
5348
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5216
5349
|
"g",
|
|
5217
5350
|
{
|
|
5218
5351
|
dangerouslySetInnerHTML: { __html: symbol.svgContent },
|
|
@@ -5220,7 +5353,7 @@ function NodeRendererImpl({
|
|
|
5220
5353
|
style: { pointerEvents: "auto" }
|
|
5221
5354
|
}
|
|
5222
5355
|
),
|
|
5223
|
-
/* @__PURE__ */ (0,
|
|
5356
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5224
5357
|
"text",
|
|
5225
5358
|
{
|
|
5226
5359
|
x: labelX,
|
|
@@ -5240,11 +5373,11 @@ function NodeRendererImpl({
|
|
|
5240
5373
|
})
|
|
5241
5374
|
] });
|
|
5242
5375
|
}
|
|
5243
|
-
var NodeRenderer =
|
|
5376
|
+
var NodeRenderer = import_react11.default.memo(NodeRendererImpl);
|
|
5244
5377
|
|
|
5245
5378
|
// src/components/PIDCanvas/PipeRenderer.tsx
|
|
5246
|
-
var
|
|
5247
|
-
var
|
|
5379
|
+
var import_react12 = __toESM(require("react"), 1);
|
|
5380
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
5248
5381
|
function PipeRendererImpl({
|
|
5249
5382
|
pipes,
|
|
5250
5383
|
selectedPipeIds,
|
|
@@ -5259,7 +5392,7 @@ function PipeRendererImpl({
|
|
|
5259
5392
|
waypointDragOffset,
|
|
5260
5393
|
onPipeSegmentClick
|
|
5261
5394
|
}) {
|
|
5262
|
-
return /* @__PURE__ */ (0,
|
|
5395
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("g", { id: "layer-pipes", children: pipes.filter((pipe) => pipe.visible !== false).map((pipe) => {
|
|
5263
5396
|
const isSelected = selectedPipeIds?.has(pipe.id) ?? false;
|
|
5264
5397
|
const isEditing = enableWaypointEditing && editingPipeId === pipe.id;
|
|
5265
5398
|
const showEditingControls = enableWaypointEditing && isSelected;
|
|
@@ -5278,7 +5411,7 @@ function PipeRendererImpl({
|
|
|
5278
5411
|
const strokeWidth = isSelected ? (pipeStyle.strokeWidth || 3) + 2 : pipeStyle.strokeWidth || 3;
|
|
5279
5412
|
const strokeDasharray = pipeStyle.strokeDasharray;
|
|
5280
5413
|
const opacity = pipeStyle.opacity !== void 0 ? pipeStyle.opacity : 1;
|
|
5281
|
-
return /* @__PURE__ */ (0,
|
|
5414
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
5282
5415
|
"g",
|
|
5283
5416
|
{
|
|
5284
5417
|
"data-pipe-id": pipe.id,
|
|
@@ -5291,8 +5424,8 @@ function PipeRendererImpl({
|
|
|
5291
5424
|
cursor: onPipeClick ? "pointer" : "default"
|
|
5292
5425
|
},
|
|
5293
5426
|
children: [
|
|
5294
|
-
!enableWaypointEditing && /* @__PURE__ */ (0,
|
|
5295
|
-
onPipeClick && /* @__PURE__ */ (0,
|
|
5427
|
+
!enableWaypointEditing && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
5428
|
+
onPipeClick && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5296
5429
|
"polyline",
|
|
5297
5430
|
{
|
|
5298
5431
|
points: pointsString,
|
|
@@ -5304,7 +5437,7 @@ function PipeRendererImpl({
|
|
|
5304
5437
|
pointerEvents: "stroke"
|
|
5305
5438
|
}
|
|
5306
5439
|
),
|
|
5307
|
-
/* @__PURE__ */ (0,
|
|
5440
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5308
5441
|
"polyline",
|
|
5309
5442
|
{
|
|
5310
5443
|
points: pointsString,
|
|
@@ -5328,7 +5461,7 @@ function PipeRendererImpl({
|
|
|
5328
5461
|
const waypointSize = isSelectedWaypoint ? 8 : isDragging ? 8 : showEditingControls ? 6 : isSelected ? 3 : 2;
|
|
5329
5462
|
const waypointOpacity = isSelectedWaypoint ? 1 : isDragging ? 1 : showEditingControls ? 0.9 : isSelected ? 0.8 : 0.5;
|
|
5330
5463
|
const waypointColor = isSelectedWaypoint ? "#3b82f6" : isEndpoint && showEditingControls ? "#f59e0b" : isDragging ? "#10b981" : stroke;
|
|
5331
|
-
return /* @__PURE__ */ (0,
|
|
5464
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5332
5465
|
"circle",
|
|
5333
5466
|
{
|
|
5334
5467
|
cx: point.x,
|
|
@@ -5365,12 +5498,12 @@ function PipeRendererImpl({
|
|
|
5365
5498
|
`${pipe.id}-point-${idx}`
|
|
5366
5499
|
);
|
|
5367
5500
|
}),
|
|
5368
|
-
showEditingControls && onPipeSegmentClick && displayPoints.length >= 2 && /* @__PURE__ */ (0,
|
|
5501
|
+
showEditingControls && onPipeSegmentClick && displayPoints.length >= 2 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_jsx_runtime18.Fragment, { children: displayPoints.slice(0, -1).map((point, idx) => {
|
|
5369
5502
|
const nextPoint = displayPoints[idx + 1];
|
|
5370
5503
|
const midX = (point.x + nextPoint.x) / 2;
|
|
5371
5504
|
const midY = (point.y + nextPoint.y) / 2;
|
|
5372
|
-
return /* @__PURE__ */ (0,
|
|
5373
|
-
/* @__PURE__ */ (0,
|
|
5505
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("g", { children: [
|
|
5506
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5374
5507
|
"circle",
|
|
5375
5508
|
{
|
|
5376
5509
|
cx: midX,
|
|
@@ -5386,7 +5519,7 @@ function PipeRendererImpl({
|
|
|
5386
5519
|
}
|
|
5387
5520
|
}
|
|
5388
5521
|
),
|
|
5389
|
-
/* @__PURE__ */ (0,
|
|
5522
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5390
5523
|
"circle",
|
|
5391
5524
|
{
|
|
5392
5525
|
cx: midX,
|
|
@@ -5402,7 +5535,7 @@ function PipeRendererImpl({
|
|
|
5402
5535
|
)
|
|
5403
5536
|
] }, `${pipe.id}-segment-${idx}`);
|
|
5404
5537
|
}) }),
|
|
5405
|
-
pipe.showLabel !== false && pipe.label && pipe.routePoints.length >= 2 && /* @__PURE__ */ (0,
|
|
5538
|
+
pipe.showLabel !== false && pipe.label && pipe.routePoints.length >= 2 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5406
5539
|
"text",
|
|
5407
5540
|
{
|
|
5408
5541
|
x: pipe.routePoints[Math.floor(pipe.routePoints.length / 2)].x + (pipe.labelOffset?.x ?? 0),
|
|
@@ -5422,11 +5555,11 @@ function PipeRendererImpl({
|
|
|
5422
5555
|
);
|
|
5423
5556
|
}) });
|
|
5424
5557
|
}
|
|
5425
|
-
var PipeRenderer =
|
|
5558
|
+
var PipeRenderer = import_react12.default.memo(PipeRendererImpl);
|
|
5426
5559
|
|
|
5427
5560
|
// src/components/PIDCanvas/DataOverlay.tsx
|
|
5428
|
-
var
|
|
5429
|
-
var
|
|
5561
|
+
var import_react13 = __toESM(require("react"), 1);
|
|
5562
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
5430
5563
|
var PULSE_KEYFRAME_ID = "pid-data-overlay-pulse-keyframes";
|
|
5431
5564
|
var PULSE_ANIMATION = "pid-data-overlay-pulse 1.5s ease-in-out infinite";
|
|
5432
5565
|
function ensurePulseKeyframes() {
|
|
@@ -5437,9 +5570,10 @@ function ensurePulseKeyframes() {
|
|
|
5437
5570
|
style.textContent = "@keyframes pid-data-overlay-pulse{0%{opacity:.9}50%{opacity:.3}100%{opacity:.9}}";
|
|
5438
5571
|
document.head.appendChild(style);
|
|
5439
5572
|
}
|
|
5440
|
-
function renderStatusDot(cx, cy, scale, fill) {
|
|
5441
|
-
|
|
5442
|
-
|
|
5573
|
+
function renderStatusDot(cx, cy, scale, fill, status) {
|
|
5574
|
+
const isUnknown = normalizeDeviceStatus(status) === "unknown";
|
|
5575
|
+
if (!isUnknown) ensurePulseKeyframes();
|
|
5576
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5443
5577
|
"circle",
|
|
5444
5578
|
{
|
|
5445
5579
|
className: "pid-data-overlay-status-dot",
|
|
@@ -5447,7 +5581,7 @@ function renderStatusDot(cx, cy, scale, fill) {
|
|
|
5447
5581
|
cy: cy - 18 * scale,
|
|
5448
5582
|
r: 3 * scale,
|
|
5449
5583
|
fill,
|
|
5450
|
-
style: { animation: PULSE_ANIMATION }
|
|
5584
|
+
style: isUnknown ? void 0 : { animation: PULSE_ANIMATION }
|
|
5451
5585
|
}
|
|
5452
5586
|
);
|
|
5453
5587
|
}
|
|
@@ -5473,7 +5607,7 @@ function DataOverlayImpl({
|
|
|
5473
5607
|
const backgroundColor = display?.backgroundColor;
|
|
5474
5608
|
const offsetX = display?.offsetX ?? 0;
|
|
5475
5609
|
const offsetY = display?.offsetY ?? 0;
|
|
5476
|
-
const sparklinePath =
|
|
5610
|
+
const sparklinePath = import_react13.default.useMemo(() => {
|
|
5477
5611
|
if (!showSparkline || !history || history.length < 2) return "";
|
|
5478
5612
|
const width = 70 * scale;
|
|
5479
5613
|
const height = 20 * scale;
|
|
@@ -5492,7 +5626,7 @@ function DataOverlayImpl({
|
|
|
5492
5626
|
return `M ${points.join(" L ")}`;
|
|
5493
5627
|
}, [showSparkline, history, scaling, scale]);
|
|
5494
5628
|
if (!showValue) {
|
|
5495
|
-
return /* @__PURE__ */ (0,
|
|
5629
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_jsx_runtime19.Fragment, {});
|
|
5496
5630
|
}
|
|
5497
5631
|
const formatValue = (val) => {
|
|
5498
5632
|
if (typeof val === "number") {
|
|
@@ -5517,10 +5651,11 @@ function DataOverlayImpl({
|
|
|
5517
5651
|
const extraMarkRows = realDisplayText ? 1 : 0;
|
|
5518
5652
|
const overlayHeight = (label ? hasSparkline ? 55 : 30 : hasSparkline ? 47 : 22) * scale + extraMarkRows * 9 * scale;
|
|
5519
5653
|
const overlayWidth = 80 * scale;
|
|
5654
|
+
const isUnknownValue = normalizeDeviceStatus(value.status) === "unknown";
|
|
5520
5655
|
const displayX = x + offsetX;
|
|
5521
5656
|
const displayY = y + offsetY;
|
|
5522
|
-
return /* @__PURE__ */ (0,
|
|
5523
|
-
/* @__PURE__ */ (0,
|
|
5657
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("g", { "data-overlay-node": nodeId, "data-status": value.status, "data-forced": isForced, children: [
|
|
5658
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5524
5659
|
"rect",
|
|
5525
5660
|
{
|
|
5526
5661
|
x: displayX - overlayWidth / 2,
|
|
@@ -5535,7 +5670,7 @@ function DataOverlayImpl({
|
|
|
5535
5670
|
filter: "drop-shadow(0 2px 4px rgba(0,0,0,0.2))"
|
|
5536
5671
|
}
|
|
5537
5672
|
),
|
|
5538
|
-
label && /* @__PURE__ */ (0,
|
|
5673
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5539
5674
|
"text",
|
|
5540
5675
|
{
|
|
5541
5676
|
x: displayX,
|
|
@@ -5548,7 +5683,7 @@ function DataOverlayImpl({
|
|
|
5548
5683
|
children: label
|
|
5549
5684
|
}
|
|
5550
5685
|
),
|
|
5551
|
-
/* @__PURE__ */ (0,
|
|
5686
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5552
5687
|
"text",
|
|
5553
5688
|
{
|
|
5554
5689
|
x: displayX,
|
|
@@ -5561,8 +5696,17 @@ function DataOverlayImpl({
|
|
|
5561
5696
|
children: displayText
|
|
5562
5697
|
}
|
|
5563
5698
|
),
|
|
5564
|
-
showStatus && value.status !== "normal" && renderStatusDot(displayX, displayY, scale, finalTextColor),
|
|
5565
|
-
|
|
5699
|
+
showStatus && value.status !== "normal" && renderStatusDot(displayX, displayY, scale, finalTextColor, value.status),
|
|
5700
|
+
showStatus && isUnknownValue && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5701
|
+
UnknownStatusGlyph,
|
|
5702
|
+
{
|
|
5703
|
+
x: displayX - overlayWidth / 2 + 2 * scale,
|
|
5704
|
+
y: displayY - 25 * scale - 6 * scale,
|
|
5705
|
+
width: 12 * scale,
|
|
5706
|
+
height: 12 * scale
|
|
5707
|
+
}
|
|
5708
|
+
),
|
|
5709
|
+
value.quality !== void 0 && value.quality < 100 && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
5566
5710
|
"text",
|
|
5567
5711
|
{
|
|
5568
5712
|
x: displayX,
|
|
@@ -5579,13 +5723,13 @@ function DataOverlayImpl({
|
|
|
5579
5723
|
]
|
|
5580
5724
|
}
|
|
5581
5725
|
),
|
|
5582
|
-
isForced && /* @__PURE__ */ (0,
|
|
5726
|
+
isForced && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
5583
5727
|
"g",
|
|
5584
5728
|
{
|
|
5585
5729
|
transform: `translate(${displayX + overlayWidth / 2}, ${displayY - 25 * scale})`,
|
|
5586
5730
|
"aria-label": "Forced",
|
|
5587
5731
|
children: [
|
|
5588
|
-
/* @__PURE__ */ (0,
|
|
5732
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5589
5733
|
"circle",
|
|
5590
5734
|
{
|
|
5591
5735
|
r: 7 * scale,
|
|
@@ -5594,7 +5738,7 @@ function DataOverlayImpl({
|
|
|
5594
5738
|
strokeWidth: 1.5 * scale
|
|
5595
5739
|
}
|
|
5596
5740
|
),
|
|
5597
|
-
/* @__PURE__ */ (0,
|
|
5741
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5598
5742
|
"text",
|
|
5599
5743
|
{
|
|
5600
5744
|
textAnchor: "middle",
|
|
@@ -5608,7 +5752,7 @@ function DataOverlayImpl({
|
|
|
5608
5752
|
]
|
|
5609
5753
|
}
|
|
5610
5754
|
),
|
|
5611
|
-
realDisplayText && /* @__PURE__ */ (0,
|
|
5755
|
+
realDisplayText && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5612
5756
|
"text",
|
|
5613
5757
|
{
|
|
5614
5758
|
x: displayX,
|
|
@@ -5621,7 +5765,7 @@ function DataOverlayImpl({
|
|
|
5621
5765
|
children: realDisplayText
|
|
5622
5766
|
}
|
|
5623
5767
|
),
|
|
5624
|
-
hasSparkline && /* @__PURE__ */ (0,
|
|
5768
|
+
hasSparkline && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("g", { transform: `translate(${displayX - 35 * scale}, ${displayY + (label ? 5 : 0) * scale})`, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5625
5769
|
"path",
|
|
5626
5770
|
{
|
|
5627
5771
|
d: sparklinePath,
|
|
@@ -5635,11 +5779,11 @@ function DataOverlayImpl({
|
|
|
5635
5779
|
) })
|
|
5636
5780
|
] });
|
|
5637
5781
|
}
|
|
5638
|
-
var DataOverlay =
|
|
5782
|
+
var DataOverlay = import_react13.default.memo(DataOverlayImpl);
|
|
5639
5783
|
|
|
5640
5784
|
// src/components/PIDCanvas/PositionPanel.tsx
|
|
5641
|
-
var
|
|
5642
|
-
var
|
|
5785
|
+
var import_react14 = require("react");
|
|
5786
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
5643
5787
|
function PositionPanel({
|
|
5644
5788
|
selectedNode,
|
|
5645
5789
|
selectedWaypoint,
|
|
@@ -5647,9 +5791,9 @@ function PositionPanel({
|
|
|
5647
5791
|
onWaypointPositionChange,
|
|
5648
5792
|
position = "top-right"
|
|
5649
5793
|
}) {
|
|
5650
|
-
const [x, setX] = (0,
|
|
5651
|
-
const [y, setY] = (0,
|
|
5652
|
-
(0,
|
|
5794
|
+
const [x, setX] = (0, import_react14.useState)("");
|
|
5795
|
+
const [y, setY] = (0, import_react14.useState)("");
|
|
5796
|
+
(0, import_react14.useEffect)(() => {
|
|
5653
5797
|
if (selectedNode) {
|
|
5654
5798
|
setX(selectedNode.transform.x.toFixed(2));
|
|
5655
5799
|
setY(selectedNode.transform.y.toFixed(2));
|
|
@@ -5708,7 +5852,7 @@ function PositionPanel({
|
|
|
5708
5852
|
"bottom-left": { bottom: 10, left: 10 },
|
|
5709
5853
|
"bottom-right": { bottom: 10, right: 10 }
|
|
5710
5854
|
};
|
|
5711
|
-
return /* @__PURE__ */ (0,
|
|
5855
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
5712
5856
|
"div",
|
|
5713
5857
|
{
|
|
5714
5858
|
style: {
|
|
@@ -5725,11 +5869,11 @@ function PositionPanel({
|
|
|
5725
5869
|
fontSize: "13px"
|
|
5726
5870
|
},
|
|
5727
5871
|
children: [
|
|
5728
|
-
/* @__PURE__ */ (0,
|
|
5729
|
-
/* @__PURE__ */ (0,
|
|
5730
|
-
/* @__PURE__ */ (0,
|
|
5731
|
-
/* @__PURE__ */ (0,
|
|
5732
|
-
/* @__PURE__ */ (0,
|
|
5872
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { marginBottom: "8px", fontWeight: 600, color: "#333" }, children: "Position" }),
|
|
5873
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "8px" }, children: [
|
|
5874
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
|
|
5875
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("label", { style: { width: "16px", color: "#666" }, children: "X:" }),
|
|
5876
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5733
5877
|
"input",
|
|
5734
5878
|
{
|
|
5735
5879
|
type: "number",
|
|
@@ -5747,9 +5891,9 @@ function PositionPanel({
|
|
|
5747
5891
|
}
|
|
5748
5892
|
)
|
|
5749
5893
|
] }),
|
|
5750
|
-
/* @__PURE__ */ (0,
|
|
5751
|
-
/* @__PURE__ */ (0,
|
|
5752
|
-
/* @__PURE__ */ (0,
|
|
5894
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
|
|
5895
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("label", { style: { width: "16px", color: "#666" }, children: "Y:" }),
|
|
5896
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5753
5897
|
"input",
|
|
5754
5898
|
{
|
|
5755
5899
|
type: "number",
|
|
@@ -5768,14 +5912,14 @@ function PositionPanel({
|
|
|
5768
5912
|
)
|
|
5769
5913
|
] })
|
|
5770
5914
|
] }),
|
|
5771
|
-
/* @__PURE__ */ (0,
|
|
5915
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { marginTop: "8px", fontSize: "11px", color: "#888" }, children: "Use arrow keys to nudge (\xB11px)" })
|
|
5772
5916
|
]
|
|
5773
5917
|
}
|
|
5774
5918
|
);
|
|
5775
5919
|
}
|
|
5776
5920
|
|
|
5777
5921
|
// src/diagram/hooks/useViewBox.ts
|
|
5778
|
-
var
|
|
5922
|
+
var import_react15 = require("react");
|
|
5779
5923
|
function useViewBox(options) {
|
|
5780
5924
|
const {
|
|
5781
5925
|
initialViewBox,
|
|
@@ -5786,16 +5930,16 @@ function useViewBox(options) {
|
|
|
5786
5930
|
zoomSensitivity = 1e-3,
|
|
5787
5931
|
allowLeftClickPan = true
|
|
5788
5932
|
} = options;
|
|
5789
|
-
const [viewBox, setViewBox] = (0,
|
|
5790
|
-
const svgRef = (0,
|
|
5791
|
-
const isPanningRef = (0,
|
|
5792
|
-
const lastMousePosRef = (0,
|
|
5793
|
-
const spaceKeyDownRef = (0,
|
|
5794
|
-
const lastTouchDistanceRef = (0,
|
|
5795
|
-
const resetViewBox = (0,
|
|
5933
|
+
const [viewBox, setViewBox] = (0, import_react15.useState)(initialViewBox);
|
|
5934
|
+
const svgRef = (0, import_react15.useRef)(null);
|
|
5935
|
+
const isPanningRef = (0, import_react15.useRef)(false);
|
|
5936
|
+
const lastMousePosRef = (0, import_react15.useRef)({ x: 0, y: 0 });
|
|
5937
|
+
const spaceKeyDownRef = (0, import_react15.useRef)(false);
|
|
5938
|
+
const lastTouchDistanceRef = (0, import_react15.useRef)(null);
|
|
5939
|
+
const resetViewBox = (0, import_react15.useCallback)(() => {
|
|
5796
5940
|
setViewBox(initialViewBox);
|
|
5797
5941
|
}, [initialViewBox]);
|
|
5798
|
-
const zoomIn = (0,
|
|
5942
|
+
const zoomIn = (0, import_react15.useCallback)(() => {
|
|
5799
5943
|
setViewBox((prev) => {
|
|
5800
5944
|
const currentZoom = initialViewBox.width / prev.width;
|
|
5801
5945
|
const newZoom = Math.min(1 / minZoom, currentZoom * 1.25);
|
|
@@ -5812,7 +5956,7 @@ function useViewBox(options) {
|
|
|
5812
5956
|
};
|
|
5813
5957
|
});
|
|
5814
5958
|
}, [initialViewBox, minZoom]);
|
|
5815
|
-
const zoomOut = (0,
|
|
5959
|
+
const zoomOut = (0, import_react15.useCallback)(() => {
|
|
5816
5960
|
setViewBox((prev) => {
|
|
5817
5961
|
const currentZoom = initialViewBox.width / prev.width;
|
|
5818
5962
|
const newZoom = Math.max(1 / maxZoom, currentZoom * 0.8);
|
|
@@ -5829,7 +5973,7 @@ function useViewBox(options) {
|
|
|
5829
5973
|
};
|
|
5830
5974
|
});
|
|
5831
5975
|
}, [initialViewBox, maxZoom]);
|
|
5832
|
-
const fitToContent = (0,
|
|
5976
|
+
const fitToContent = (0, import_react15.useCallback)((bounds, padding = 50) => {
|
|
5833
5977
|
const contentWidth = bounds.maxX - bounds.minX;
|
|
5834
5978
|
const contentHeight = bounds.maxY - bounds.minY;
|
|
5835
5979
|
if (contentWidth === 0 || contentHeight === 0) {
|
|
@@ -5857,7 +6001,7 @@ function useViewBox(options) {
|
|
|
5857
6001
|
height: newHeight
|
|
5858
6002
|
});
|
|
5859
6003
|
}, [initialViewBox]);
|
|
5860
|
-
(0,
|
|
6004
|
+
(0, import_react15.useEffect)(() => {
|
|
5861
6005
|
if (!enableZoom || !svgRef.current) return;
|
|
5862
6006
|
const svg = svgRef.current;
|
|
5863
6007
|
const handleWheel = (e) => {
|
|
@@ -5890,7 +6034,7 @@ function useViewBox(options) {
|
|
|
5890
6034
|
svg.addEventListener("wheel", handleWheel, { passive: false });
|
|
5891
6035
|
return () => svg.removeEventListener("wheel", handleWheel);
|
|
5892
6036
|
}, [enableZoom, zoomSensitivity, minZoom, initialViewBox]);
|
|
5893
|
-
(0,
|
|
6037
|
+
(0, import_react15.useEffect)(() => {
|
|
5894
6038
|
if (!enablePan || !svgRef.current) return;
|
|
5895
6039
|
const svg = svgRef.current;
|
|
5896
6040
|
const handleMouseDown = (e) => {
|
|
@@ -5966,7 +6110,7 @@ function useViewBox(options) {
|
|
|
5966
6110
|
window.removeEventListener("keyup", handleKeyUp);
|
|
5967
6111
|
};
|
|
5968
6112
|
}, [enablePan, allowLeftClickPan]);
|
|
5969
|
-
(0,
|
|
6113
|
+
(0, import_react15.useEffect)(() => {
|
|
5970
6114
|
if (!svgRef.current) return;
|
|
5971
6115
|
if (!enablePan && !enableZoom) return;
|
|
5972
6116
|
const svg = svgRef.current;
|
|
@@ -6057,7 +6201,7 @@ function useViewBox(options) {
|
|
|
6057
6201
|
svg.removeEventListener("touchend", handleTouchEnd);
|
|
6058
6202
|
};
|
|
6059
6203
|
}, [enablePan, enableZoom, minZoom, initialViewBox]);
|
|
6060
|
-
const screenToWorld = (0,
|
|
6204
|
+
const screenToWorld = (0, import_react15.useCallback)(
|
|
6061
6205
|
(screenX, screenY) => {
|
|
6062
6206
|
const svg = svgRef.current;
|
|
6063
6207
|
if (!svg) return { x: screenX, y: screenY };
|
|
@@ -6096,15 +6240,15 @@ function useViewBox(options) {
|
|
|
6096
6240
|
}
|
|
6097
6241
|
|
|
6098
6242
|
// src/diagram/hooks/useSelection.ts
|
|
6099
|
-
var
|
|
6243
|
+
var import_react16 = require("react");
|
|
6100
6244
|
function useSelection(options = {}) {
|
|
6101
6245
|
const {
|
|
6102
6246
|
multiSelect = true,
|
|
6103
6247
|
initialSelection = { selectedNodeIds: /* @__PURE__ */ new Set(), selectedPipeIds: /* @__PURE__ */ new Set() },
|
|
6104
6248
|
onSelectionChange
|
|
6105
6249
|
} = options;
|
|
6106
|
-
const [selection, setSelection] = (0,
|
|
6107
|
-
const notifyChange = (0,
|
|
6250
|
+
const [selection, setSelection] = (0, import_react16.useState)(initialSelection);
|
|
6251
|
+
const notifyChange = (0, import_react16.useCallback)(
|
|
6108
6252
|
(newSelection) => {
|
|
6109
6253
|
if (onSelectionChange) {
|
|
6110
6254
|
onSelectionChange(newSelection);
|
|
@@ -6112,15 +6256,15 @@ function useSelection(options = {}) {
|
|
|
6112
6256
|
},
|
|
6113
6257
|
[onSelectionChange]
|
|
6114
6258
|
);
|
|
6115
|
-
const isNodeSelected = (0,
|
|
6259
|
+
const isNodeSelected = (0, import_react16.useCallback)(
|
|
6116
6260
|
(nodeId) => selection.selectedNodeIds.has(nodeId),
|
|
6117
6261
|
[selection.selectedNodeIds]
|
|
6118
6262
|
);
|
|
6119
|
-
const isPipeSelected = (0,
|
|
6263
|
+
const isPipeSelected = (0, import_react16.useCallback)(
|
|
6120
6264
|
(pipeId) => selection.selectedPipeIds.has(pipeId),
|
|
6121
6265
|
[selection.selectedPipeIds]
|
|
6122
6266
|
);
|
|
6123
|
-
const selectNode = (0,
|
|
6267
|
+
const selectNode = (0, import_react16.useCallback)(
|
|
6124
6268
|
(nodeId, isMultiSelect = false) => {
|
|
6125
6269
|
setSelection((prev) => {
|
|
6126
6270
|
const newNodeIds = new Set(isMultiSelect && multiSelect ? prev.selectedNodeIds : []);
|
|
@@ -6139,7 +6283,7 @@ function useSelection(options = {}) {
|
|
|
6139
6283
|
},
|
|
6140
6284
|
[multiSelect, notifyChange]
|
|
6141
6285
|
);
|
|
6142
|
-
const selectPipe = (0,
|
|
6286
|
+
const selectPipe = (0, import_react16.useCallback)(
|
|
6143
6287
|
(pipeId, isMultiSelect = false) => {
|
|
6144
6288
|
setSelection((prev) => {
|
|
6145
6289
|
const newPipeIds = new Set(isMultiSelect && multiSelect ? prev.selectedPipeIds : []);
|
|
@@ -6158,7 +6302,7 @@ function useSelection(options = {}) {
|
|
|
6158
6302
|
},
|
|
6159
6303
|
[multiSelect, notifyChange]
|
|
6160
6304
|
);
|
|
6161
|
-
const clearSelection = (0,
|
|
6305
|
+
const clearSelection = (0, import_react16.useCallback)(() => {
|
|
6162
6306
|
const newSelection = {
|
|
6163
6307
|
selectedNodeIds: /* @__PURE__ */ new Set(),
|
|
6164
6308
|
selectedPipeIds: /* @__PURE__ */ new Set()
|
|
@@ -6166,7 +6310,7 @@ function useSelection(options = {}) {
|
|
|
6166
6310
|
setSelection(newSelection);
|
|
6167
6311
|
notifyChange(newSelection);
|
|
6168
6312
|
}, [notifyChange]);
|
|
6169
|
-
const selectNodes = (0,
|
|
6313
|
+
const selectNodes = (0, import_react16.useCallback)(
|
|
6170
6314
|
(nodeIds) => {
|
|
6171
6315
|
const newSelection = {
|
|
6172
6316
|
selectedNodeIds: new Set(nodeIds),
|
|
@@ -6177,7 +6321,7 @@ function useSelection(options = {}) {
|
|
|
6177
6321
|
},
|
|
6178
6322
|
[notifyChange]
|
|
6179
6323
|
);
|
|
6180
|
-
const selectPipes = (0,
|
|
6324
|
+
const selectPipes = (0, import_react16.useCallback)(
|
|
6181
6325
|
(pipeIds) => {
|
|
6182
6326
|
const newSelection = {
|
|
6183
6327
|
selectedNodeIds: /* @__PURE__ */ new Set(),
|
|
@@ -6201,23 +6345,23 @@ function useSelection(options = {}) {
|
|
|
6201
6345
|
}
|
|
6202
6346
|
|
|
6203
6347
|
// src/diagram/hooks/useTelemetry.ts
|
|
6204
|
-
var
|
|
6348
|
+
var import_react17 = require("react");
|
|
6205
6349
|
function useTelemetry(options = {}) {
|
|
6206
6350
|
const {
|
|
6207
6351
|
initialBindings = [],
|
|
6208
6352
|
onTelemetryChange,
|
|
6209
6353
|
refreshInterval = 0
|
|
6210
6354
|
} = options;
|
|
6211
|
-
const [telemetry, setTelemetry] = (0,
|
|
6355
|
+
const [telemetry, setTelemetry] = (0, import_react17.useState)(() => {
|
|
6212
6356
|
const map = /* @__PURE__ */ new Map();
|
|
6213
6357
|
initialBindings.forEach((binding) => {
|
|
6214
6358
|
map.set(binding.nodeId, binding);
|
|
6215
6359
|
});
|
|
6216
6360
|
return map;
|
|
6217
6361
|
});
|
|
6218
|
-
const telemetryRef = (0,
|
|
6362
|
+
const telemetryRef = (0, import_react17.useRef)(telemetry);
|
|
6219
6363
|
telemetryRef.current = telemetry;
|
|
6220
|
-
const notifyChange = (0,
|
|
6364
|
+
const notifyChange = (0, import_react17.useCallback)(
|
|
6221
6365
|
(newTelemetry) => {
|
|
6222
6366
|
if (onTelemetryChange) {
|
|
6223
6367
|
onTelemetryChange(newTelemetry);
|
|
@@ -6225,7 +6369,7 @@ function useTelemetry(options = {}) {
|
|
|
6225
6369
|
},
|
|
6226
6370
|
[onTelemetryChange]
|
|
6227
6371
|
);
|
|
6228
|
-
const updateTelemetry = (0,
|
|
6372
|
+
const updateTelemetry = (0, import_react17.useCallback)(
|
|
6229
6373
|
(nodeId, value) => {
|
|
6230
6374
|
setTelemetry((prev) => {
|
|
6231
6375
|
const newMap = new Map(prev);
|
|
@@ -6255,7 +6399,7 @@ function useTelemetry(options = {}) {
|
|
|
6255
6399
|
},
|
|
6256
6400
|
[notifyChange]
|
|
6257
6401
|
);
|
|
6258
|
-
const updateTelemetryBatch = (0,
|
|
6402
|
+
const updateTelemetryBatch = (0, import_react17.useCallback)(
|
|
6259
6403
|
(updates) => {
|
|
6260
6404
|
setTelemetry((prev) => {
|
|
6261
6405
|
const newMap = new Map(prev);
|
|
@@ -6309,16 +6453,16 @@ function useTelemetry(options = {}) {
|
|
|
6309
6453
|
},
|
|
6310
6454
|
[notifyChange]
|
|
6311
6455
|
);
|
|
6312
|
-
const getTelemetry = (0,
|
|
6456
|
+
const getTelemetry = (0, import_react17.useCallback)(
|
|
6313
6457
|
(nodeId) => telemetryRef.current.get(nodeId),
|
|
6314
6458
|
[]
|
|
6315
6459
|
);
|
|
6316
|
-
const clearTelemetry = (0,
|
|
6460
|
+
const clearTelemetry = (0, import_react17.useCallback)(() => {
|
|
6317
6461
|
const newMap = /* @__PURE__ */ new Map();
|
|
6318
6462
|
setTelemetry(newMap);
|
|
6319
6463
|
notifyChange(newMap);
|
|
6320
6464
|
}, [notifyChange]);
|
|
6321
|
-
const setBindings = (0,
|
|
6465
|
+
const setBindings = (0, import_react17.useCallback)(
|
|
6322
6466
|
(bindings) => {
|
|
6323
6467
|
const newMap = /* @__PURE__ */ new Map();
|
|
6324
6468
|
bindings.forEach((binding) => {
|
|
@@ -6329,7 +6473,7 @@ function useTelemetry(options = {}) {
|
|
|
6329
6473
|
},
|
|
6330
6474
|
[notifyChange]
|
|
6331
6475
|
);
|
|
6332
|
-
(0,
|
|
6476
|
+
(0, import_react17.useEffect)(() => {
|
|
6333
6477
|
if (refreshInterval <= 0) return;
|
|
6334
6478
|
const intervalId = setInterval(() => {
|
|
6335
6479
|
notifyChange(telemetryRef.current);
|
|
@@ -6347,10 +6491,10 @@ function useTelemetry(options = {}) {
|
|
|
6347
6491
|
}
|
|
6348
6492
|
|
|
6349
6493
|
// src/diagram/hooks/useTelemetryStatus.ts
|
|
6350
|
-
var
|
|
6494
|
+
var import_react18 = require("react");
|
|
6351
6495
|
function useTelemetryStatus(telemetry, diagram, setDiagram, options = {}) {
|
|
6352
6496
|
const { enabled = true, mapStatus } = options;
|
|
6353
|
-
(0,
|
|
6497
|
+
(0, import_react18.useEffect)(() => {
|
|
6354
6498
|
if (!enabled) return;
|
|
6355
6499
|
const defaultMapStatus = (telemetryStatus) => {
|
|
6356
6500
|
switch (telemetryStatus) {
|
|
@@ -6363,8 +6507,13 @@ function useTelemetryStatus(telemetry, diagram, setDiagram, options = {}) {
|
|
|
6363
6507
|
return "alarm";
|
|
6364
6508
|
case "off":
|
|
6365
6509
|
return "stopped";
|
|
6366
|
-
|
|
6510
|
+
case "unknown":
|
|
6511
|
+
return "unknown";
|
|
6512
|
+
default: {
|
|
6513
|
+
const exhaustive = telemetryStatus;
|
|
6514
|
+
void exhaustive;
|
|
6367
6515
|
return "stopped";
|
|
6516
|
+
}
|
|
6368
6517
|
}
|
|
6369
6518
|
};
|
|
6370
6519
|
const statusMapper = mapStatus || defaultMapStatus;
|
|
@@ -6389,10 +6538,10 @@ function useTelemetryStatus(telemetry, diagram, setDiagram, options = {}) {
|
|
|
6389
6538
|
}
|
|
6390
6539
|
|
|
6391
6540
|
// src/diagram/hooks/useBooleanIndicators.ts
|
|
6392
|
-
var
|
|
6541
|
+
var import_react19 = require("react");
|
|
6393
6542
|
function useBooleanIndicators(telemetry, diagram, setDiagram, options = {}) {
|
|
6394
6543
|
const { enabled = true, symbolId = "status-indicator" } = options;
|
|
6395
|
-
(0,
|
|
6544
|
+
(0, import_react19.useEffect)(() => {
|
|
6396
6545
|
if (!enabled) return;
|
|
6397
6546
|
const tagIndex = /* @__PURE__ */ new Map();
|
|
6398
6547
|
telemetry.forEach((binding) => {
|
|
@@ -6430,7 +6579,7 @@ function useBooleanIndicators(telemetry, diagram, setDiagram, options = {}) {
|
|
|
6430
6579
|
}
|
|
6431
6580
|
|
|
6432
6581
|
// src/diagram/hooks/useDrag.ts
|
|
6433
|
-
var
|
|
6582
|
+
var import_react20 = require("react");
|
|
6434
6583
|
function useDrag(options = {}) {
|
|
6435
6584
|
const {
|
|
6436
6585
|
onDragStart,
|
|
@@ -6440,23 +6589,23 @@ function useDrag(options = {}) {
|
|
|
6440
6589
|
dragThreshold = 3,
|
|
6441
6590
|
screenToWorld = (x, y) => ({ x, y })
|
|
6442
6591
|
} = options;
|
|
6443
|
-
const [dragState, setDragState] = (0,
|
|
6592
|
+
const [dragState, setDragState] = (0, import_react20.useState)({
|
|
6444
6593
|
isDragging: false,
|
|
6445
6594
|
startPosition: null,
|
|
6446
6595
|
offset: { x: 0, y: 0 },
|
|
6447
6596
|
draggedId: null
|
|
6448
6597
|
});
|
|
6449
|
-
const [isListening, setIsListening] = (0,
|
|
6450
|
-
const dragStartRef = (0,
|
|
6451
|
-
const hasMovedRef = (0,
|
|
6452
|
-
const applySnap = (0,
|
|
6598
|
+
const [isListening, setIsListening] = (0, import_react20.useState)(false);
|
|
6599
|
+
const dragStartRef = (0, import_react20.useRef)(null);
|
|
6600
|
+
const hasMovedRef = (0, import_react20.useRef)(false);
|
|
6601
|
+
const applySnap = (0, import_react20.useCallback)(
|
|
6453
6602
|
(value) => {
|
|
6454
6603
|
if (snapToGrid <= 0) return value;
|
|
6455
6604
|
return Math.round(value / snapToGrid) * snapToGrid;
|
|
6456
6605
|
},
|
|
6457
6606
|
[snapToGrid]
|
|
6458
6607
|
);
|
|
6459
|
-
const handleMouseMove = (0,
|
|
6608
|
+
const handleMouseMove = (0, import_react20.useCallback)(
|
|
6460
6609
|
(event) => {
|
|
6461
6610
|
if (!dragStartRef.current) return;
|
|
6462
6611
|
const { id, screenStart: _screenStart, itemPosition, clickOffset } = dragStartRef.current;
|
|
@@ -6497,7 +6646,7 @@ function useDrag(options = {}) {
|
|
|
6497
6646
|
},
|
|
6498
6647
|
[screenToWorld, dragThreshold, applySnap, onDragStart, onDragMove]
|
|
6499
6648
|
);
|
|
6500
|
-
const handleMouseUp = (0,
|
|
6649
|
+
const handleMouseUp = (0, import_react20.useCallback)(
|
|
6501
6650
|
(event) => {
|
|
6502
6651
|
if (!dragStartRef.current || !hasMovedRef.current) {
|
|
6503
6652
|
dragStartRef.current = null;
|
|
@@ -6534,7 +6683,7 @@ function useDrag(options = {}) {
|
|
|
6534
6683
|
},
|
|
6535
6684
|
[screenToWorld, applySnap, onDragEnd]
|
|
6536
6685
|
);
|
|
6537
|
-
const handleTouchMove = (0,
|
|
6686
|
+
const handleTouchMove = (0, import_react20.useCallback)(
|
|
6538
6687
|
(event) => {
|
|
6539
6688
|
if (!dragStartRef.current || event.touches.length !== 1) return;
|
|
6540
6689
|
const touch = event.touches[0];
|
|
@@ -6577,7 +6726,7 @@ function useDrag(options = {}) {
|
|
|
6577
6726
|
},
|
|
6578
6727
|
[screenToWorld, dragThreshold, applySnap, onDragStart, onDragMove]
|
|
6579
6728
|
);
|
|
6580
|
-
const handleTouchEnd = (0,
|
|
6729
|
+
const handleTouchEnd = (0, import_react20.useCallback)(
|
|
6581
6730
|
(event) => {
|
|
6582
6731
|
if (!dragStartRef.current || !hasMovedRef.current) {
|
|
6583
6732
|
dragStartRef.current = null;
|
|
@@ -6615,7 +6764,7 @@ function useDrag(options = {}) {
|
|
|
6615
6764
|
},
|
|
6616
6765
|
[screenToWorld, applySnap, onDragEnd]
|
|
6617
6766
|
);
|
|
6618
|
-
(0,
|
|
6767
|
+
(0, import_react20.useEffect)(() => {
|
|
6619
6768
|
if (!isListening) return;
|
|
6620
6769
|
document.addEventListener("mousemove", handleMouseMove);
|
|
6621
6770
|
document.addEventListener("mouseup", handleMouseUp);
|
|
@@ -6630,7 +6779,7 @@ function useDrag(options = {}) {
|
|
|
6630
6779
|
document.removeEventListener("touchcancel", handleTouchEnd);
|
|
6631
6780
|
};
|
|
6632
6781
|
}, [isListening, handleMouseMove, handleMouseUp, handleTouchMove, handleTouchEnd]);
|
|
6633
|
-
const startDrag = (0,
|
|
6782
|
+
const startDrag = (0, import_react20.useCallback)(
|
|
6634
6783
|
(id, event, itemPosition) => {
|
|
6635
6784
|
event.stopPropagation();
|
|
6636
6785
|
let clientX;
|
|
@@ -6660,7 +6809,7 @@ function useDrag(options = {}) {
|
|
|
6660
6809
|
},
|
|
6661
6810
|
[screenToWorld]
|
|
6662
6811
|
);
|
|
6663
|
-
const cancelDrag = (0,
|
|
6812
|
+
const cancelDrag = (0, import_react20.useCallback)(() => {
|
|
6664
6813
|
dragStartRef.current = null;
|
|
6665
6814
|
hasMovedRef.current = false;
|
|
6666
6815
|
setIsListening(false);
|
|
@@ -6671,7 +6820,7 @@ function useDrag(options = {}) {
|
|
|
6671
6820
|
draggedId: null
|
|
6672
6821
|
});
|
|
6673
6822
|
}, []);
|
|
6674
|
-
const isDraggingItem = (0,
|
|
6823
|
+
const isDraggingItem = (0, import_react20.useCallback)(
|
|
6675
6824
|
(id) => dragState.isDragging && dragState.draggedId === id,
|
|
6676
6825
|
[dragState.isDragging, dragState.draggedId]
|
|
6677
6826
|
);
|
|
@@ -6684,7 +6833,7 @@ function useDrag(options = {}) {
|
|
|
6684
6833
|
}
|
|
6685
6834
|
|
|
6686
6835
|
// src/diagram/hooks/useKeyboardShortcuts.ts
|
|
6687
|
-
var
|
|
6836
|
+
var import_react21 = require("react");
|
|
6688
6837
|
function useKeyboardShortcuts(options) {
|
|
6689
6838
|
const {
|
|
6690
6839
|
onDelete,
|
|
@@ -6695,7 +6844,7 @@ function useKeyboardShortcuts(options) {
|
|
|
6695
6844
|
onSelectAll,
|
|
6696
6845
|
enabled = true
|
|
6697
6846
|
} = options;
|
|
6698
|
-
(0,
|
|
6847
|
+
(0, import_react21.useEffect)(() => {
|
|
6699
6848
|
if (!enabled) return;
|
|
6700
6849
|
const handleKeyDown = (event) => {
|
|
6701
6850
|
const target = event.target;
|
|
@@ -6804,7 +6953,7 @@ function nodeHasPort(node, portId) {
|
|
|
6804
6953
|
}
|
|
6805
6954
|
|
|
6806
6955
|
// src/components/PIDCanvas/PIDCanvas.tsx
|
|
6807
|
-
var
|
|
6956
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
6808
6957
|
var DEFAULT_FEATURES = {
|
|
6809
6958
|
pan: true,
|
|
6810
6959
|
zoom: true,
|
|
@@ -6833,21 +6982,21 @@ function PIDCanvasImpl({
|
|
|
6833
6982
|
statusColorMap,
|
|
6834
6983
|
...props
|
|
6835
6984
|
}) {
|
|
6836
|
-
const [localDiagram, setLocalDiagram] = (0,
|
|
6837
|
-
const [dragOverPosition, setDragOverPosition] = (0,
|
|
6838
|
-
const [isConnecting, setIsConnecting] = (0,
|
|
6839
|
-
const [connectionSource, setConnectionSource] = (0,
|
|
6840
|
-
const [connectionSourcePort, setConnectionSourcePort] = (0,
|
|
6841
|
-
const [connectionCursor, setConnectionCursor] = (0,
|
|
6842
|
-
const [hoveredNode, setHoveredNode] = (0,
|
|
6843
|
-
const [hoveredPort, setHoveredPort] = (0,
|
|
6844
|
-
const [selectedWaypoint, setSelectedWaypoint] = (0,
|
|
6845
|
-
const historyStack = (0,
|
|
6846
|
-
const redoStack = (0,
|
|
6847
|
-
const isUndoRedoAction = (0,
|
|
6848
|
-
const isInternalChange = (0,
|
|
6849
|
-
const lastInternalDiagram = (0,
|
|
6850
|
-
(0,
|
|
6985
|
+
const [localDiagram, setLocalDiagram] = (0, import_react22.useState)(diagram);
|
|
6986
|
+
const [dragOverPosition, setDragOverPosition] = (0, import_react22.useState)(null);
|
|
6987
|
+
const [isConnecting, setIsConnecting] = (0, import_react22.useState)(false);
|
|
6988
|
+
const [connectionSource, setConnectionSource] = (0, import_react22.useState)(null);
|
|
6989
|
+
const [connectionSourcePort, setConnectionSourcePort] = (0, import_react22.useState)(null);
|
|
6990
|
+
const [connectionCursor, setConnectionCursor] = (0, import_react22.useState)(null);
|
|
6991
|
+
const [hoveredNode, setHoveredNode] = (0, import_react22.useState)(null);
|
|
6992
|
+
const [hoveredPort, setHoveredPort] = (0, import_react22.useState)(null);
|
|
6993
|
+
const [selectedWaypoint, setSelectedWaypoint] = (0, import_react22.useState)(null);
|
|
6994
|
+
const historyStack = (0, import_react22.useRef)([]);
|
|
6995
|
+
const redoStack = (0, import_react22.useRef)([]);
|
|
6996
|
+
const isUndoRedoAction = (0, import_react22.useRef)(false);
|
|
6997
|
+
const isInternalChange = (0, import_react22.useRef)(false);
|
|
6998
|
+
const lastInternalDiagram = (0, import_react22.useRef)(null);
|
|
6999
|
+
(0, import_react22.useEffect)(() => {
|
|
6851
7000
|
const isExternal = !isInternalChange.current && diagram !== lastInternalDiagram.current;
|
|
6852
7001
|
if (isExternal) {
|
|
6853
7002
|
setLocalDiagram(diagram);
|
|
@@ -6869,7 +7018,7 @@ function PIDCanvasImpl({
|
|
|
6869
7018
|
enablePan: features.pan ?? true,
|
|
6870
7019
|
enableZoom: features.zoom ?? true
|
|
6871
7020
|
});
|
|
6872
|
-
const calculateContentBounds = (0,
|
|
7021
|
+
const calculateContentBounds = (0, import_react22.useCallback)(() => {
|
|
6873
7022
|
const nodes2 = localDiagram.nodes.filter((n) => n.visible !== false);
|
|
6874
7023
|
if (nodes2.length === 0) {
|
|
6875
7024
|
return null;
|
|
@@ -6892,7 +7041,7 @@ function PIDCanvasImpl({
|
|
|
6892
7041
|
});
|
|
6893
7042
|
return { minX, minY, maxX, maxY };
|
|
6894
7043
|
}, [localDiagram.nodes]);
|
|
6895
|
-
(0,
|
|
7044
|
+
(0, import_react22.useEffect)(() => {
|
|
6896
7045
|
if (onMounted) {
|
|
6897
7046
|
const controls = {
|
|
6898
7047
|
fitToContent: (padding = 50) => {
|
|
@@ -6933,8 +7082,8 @@ function PIDCanvasImpl({
|
|
|
6933
7082
|
});
|
|
6934
7083
|
const dragEnabled = features.dragNodes ?? false;
|
|
6935
7084
|
const selectionEnabled = features.selection ?? false;
|
|
6936
|
-
const containerRef = (0,
|
|
6937
|
-
const pushToHistory = (0,
|
|
7085
|
+
const containerRef = (0, import_react22.useRef)(null);
|
|
7086
|
+
const pushToHistory = (0, import_react22.useCallback)((currentDiagram) => {
|
|
6938
7087
|
if (isUndoRedoAction.current) return;
|
|
6939
7088
|
const snapshot = JSON.parse(JSON.stringify(currentDiagram));
|
|
6940
7089
|
historyStack.current.push(snapshot);
|
|
@@ -6943,7 +7092,7 @@ function PIDCanvasImpl({
|
|
|
6943
7092
|
}
|
|
6944
7093
|
redoStack.current = [];
|
|
6945
7094
|
}, []);
|
|
6946
|
-
const undo = (0,
|
|
7095
|
+
const undo = (0, import_react22.useCallback)(() => {
|
|
6947
7096
|
if (historyStack.current.length === 0) return;
|
|
6948
7097
|
isUndoRedoAction.current = true;
|
|
6949
7098
|
const currentSnapshot = JSON.parse(JSON.stringify(localDiagram));
|
|
@@ -6957,7 +7106,7 @@ function PIDCanvasImpl({
|
|
|
6957
7106
|
isUndoRedoAction.current = false;
|
|
6958
7107
|
}, 0);
|
|
6959
7108
|
}, [localDiagram, onDiagramChange]);
|
|
6960
|
-
const redo = (0,
|
|
7109
|
+
const redo = (0, import_react22.useCallback)(() => {
|
|
6961
7110
|
if (redoStack.current.length === 0) return;
|
|
6962
7111
|
isUndoRedoAction.current = true;
|
|
6963
7112
|
const currentSnapshot = JSON.parse(JSON.stringify(localDiagram));
|
|
@@ -6971,7 +7120,7 @@ function PIDCanvasImpl({
|
|
|
6971
7120
|
isUndoRedoAction.current = false;
|
|
6972
7121
|
}, 0);
|
|
6973
7122
|
}, [localDiagram, onDiagramChange]);
|
|
6974
|
-
(0,
|
|
7123
|
+
(0, import_react22.useEffect)(() => {
|
|
6975
7124
|
const handleKeyDown = (e) => {
|
|
6976
7125
|
const isCtrlOrCmd = e.ctrlKey || e.metaKey;
|
|
6977
7126
|
if (isCtrlOrCmd && e.key === "z" && !e.shiftKey) {
|
|
@@ -6988,7 +7137,7 @@ function PIDCanvasImpl({
|
|
|
6988
7137
|
window.addEventListener("keydown", handleKeyDown);
|
|
6989
7138
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
6990
7139
|
}, [undo, redo]);
|
|
6991
|
-
(0,
|
|
7140
|
+
(0, import_react22.useEffect)(() => {
|
|
6992
7141
|
if (!features.dragNodes) return;
|
|
6993
7142
|
const handleKeyDown = (e) => {
|
|
6994
7143
|
if (selection.selectedNodeIds.size === 0 && !selectedWaypoint) return;
|
|
@@ -7073,7 +7222,7 @@ function PIDCanvasImpl({
|
|
|
7073
7222
|
onNodeMove,
|
|
7074
7223
|
pushToHistory
|
|
7075
7224
|
]);
|
|
7076
|
-
const handlePositionChange = (0,
|
|
7225
|
+
const handlePositionChange = (0, import_react22.useCallback)(
|
|
7077
7226
|
(nodeId, x, y) => {
|
|
7078
7227
|
pushToHistory(localDiagram);
|
|
7079
7228
|
const updatedNodes = localDiagram.nodes.map(
|
|
@@ -7095,7 +7244,7 @@ function PIDCanvasImpl({
|
|
|
7095
7244
|
},
|
|
7096
7245
|
[localDiagram, onDiagramChange, onNodeMove, pushToHistory]
|
|
7097
7246
|
);
|
|
7098
|
-
const handleWaypointPositionChange = (0,
|
|
7247
|
+
const handleWaypointPositionChange = (0, import_react22.useCallback)(
|
|
7099
7248
|
(pipeId, pointIndex, x, y) => {
|
|
7100
7249
|
pushToHistory(localDiagram);
|
|
7101
7250
|
const updatedPipes = localDiagram.pipes.map((pipe) => {
|
|
@@ -7113,7 +7262,7 @@ function PIDCanvasImpl({
|
|
|
7113
7262
|
},
|
|
7114
7263
|
[localDiagram, onDiagramChange, pushToHistory]
|
|
7115
7264
|
);
|
|
7116
|
-
const handleDragEnd = (0,
|
|
7265
|
+
const handleDragEnd = (0, import_react22.useCallback)(
|
|
7117
7266
|
(nodeId, offset, finalPosition) => {
|
|
7118
7267
|
const dragDistance = Math.sqrt(offset.x ** 2 + offset.y ** 2);
|
|
7119
7268
|
if (dragDistance < 2) {
|
|
@@ -7194,7 +7343,7 @@ function PIDCanvasImpl({
|
|
|
7194
7343
|
onDiagramChange?.(updatedDiagram);
|
|
7195
7344
|
}
|
|
7196
7345
|
});
|
|
7197
|
-
const handleNodeDragStart = (0,
|
|
7346
|
+
const handleNodeDragStart = (0, import_react22.useCallback)(
|
|
7198
7347
|
(nodeId, event) => {
|
|
7199
7348
|
const node = localDiagram.nodes.find((n) => n.id === nodeId);
|
|
7200
7349
|
if (!node) return;
|
|
@@ -7202,7 +7351,7 @@ function PIDCanvasImpl({
|
|
|
7202
7351
|
},
|
|
7203
7352
|
[localDiagram.nodes, startDrag]
|
|
7204
7353
|
);
|
|
7205
|
-
const handleWaypointClick = (0,
|
|
7354
|
+
const handleWaypointClick = (0, import_react22.useCallback)(
|
|
7206
7355
|
(pipeId, pointIndex) => {
|
|
7207
7356
|
setSelectedWaypoint({ pipeId, pointIndex });
|
|
7208
7357
|
if (selectionEnabled) {
|
|
@@ -7211,7 +7360,7 @@ function PIDCanvasImpl({
|
|
|
7211
7360
|
},
|
|
7212
7361
|
[selectionEnabled, clearSelection]
|
|
7213
7362
|
);
|
|
7214
|
-
const handleWaypointDragStart = (0,
|
|
7363
|
+
const handleWaypointDragStart = (0, import_react22.useCallback)(
|
|
7215
7364
|
(pipeId, pointIndex, event) => {
|
|
7216
7365
|
const pipe = localDiagram.pipes.find((p) => p.id === pipeId);
|
|
7217
7366
|
if (!pipe || pointIndex >= pipe.routePoints.length) return;
|
|
@@ -7220,7 +7369,7 @@ function PIDCanvasImpl({
|
|
|
7220
7369
|
},
|
|
7221
7370
|
[localDiagram.pipes, startWaypointDrag]
|
|
7222
7371
|
);
|
|
7223
|
-
const handlePipeSegmentClick = (0,
|
|
7372
|
+
const handlePipeSegmentClick = (0, import_react22.useCallback)(
|
|
7224
7373
|
(pipeId, position, segmentIndex) => {
|
|
7225
7374
|
pushToHistory(localDiagram);
|
|
7226
7375
|
const updatedPipes = localDiagram.pipes.map((pipe) => {
|
|
@@ -7239,7 +7388,7 @@ function PIDCanvasImpl({
|
|
|
7239
7388
|
[localDiagram, onDiagramChange, pushToHistory]
|
|
7240
7389
|
);
|
|
7241
7390
|
const telemetryEnabled = features.telemetry ?? false;
|
|
7242
|
-
const handleDelete = (0,
|
|
7391
|
+
const handleDelete = (0, import_react22.useCallback)(() => {
|
|
7243
7392
|
if (!selectionEnabled) return;
|
|
7244
7393
|
const { selectedNodeIds, selectedPipeIds } = selection;
|
|
7245
7394
|
if (selectedNodeIds.size === 0 && selectedPipeIds.size === 0) return;
|
|
@@ -7268,17 +7417,17 @@ function PIDCanvasImpl({
|
|
|
7268
7417
|
onDelete,
|
|
7269
7418
|
pushToHistory
|
|
7270
7419
|
]);
|
|
7271
|
-
const handleCopy = (0,
|
|
7420
|
+
const handleCopy = (0, import_react22.useCallback)(() => {
|
|
7272
7421
|
if (!selectionEnabled) return;
|
|
7273
7422
|
const { selectedNodeIds, selectedPipeIds } = selection;
|
|
7274
7423
|
if (selectedNodeIds.size === 0 && selectedPipeIds.size === 0) return;
|
|
7275
7424
|
onItemsCopied?.(Array.from(selectedNodeIds), Array.from(selectedPipeIds));
|
|
7276
7425
|
}, [selection, selectionEnabled, onItemsCopied]);
|
|
7277
|
-
const handlePaste = (0,
|
|
7426
|
+
const handlePaste = (0, import_react22.useCallback)(() => {
|
|
7278
7427
|
if (!selectionEnabled) return;
|
|
7279
7428
|
onPaste?.();
|
|
7280
7429
|
}, [selectionEnabled, onPaste]);
|
|
7281
|
-
const handleNodeDoubleClick = (0,
|
|
7430
|
+
const handleNodeDoubleClick = (0, import_react22.useCallback)(
|
|
7282
7431
|
(nodeId, event) => {
|
|
7283
7432
|
if (!selectionEnabled) return;
|
|
7284
7433
|
console.log("Node double-clicked:", nodeId);
|
|
@@ -7292,7 +7441,7 @@ function PIDCanvasImpl({
|
|
|
7292
7441
|
onCopy: handleCopy,
|
|
7293
7442
|
onPaste: handlePaste
|
|
7294
7443
|
});
|
|
7295
|
-
const handleNodeClick = (0,
|
|
7444
|
+
const handleNodeClick = (0, import_react22.useCallback)(
|
|
7296
7445
|
(nodeId, event) => {
|
|
7297
7446
|
const connectionModeEnabled = features.connectionMode ?? false;
|
|
7298
7447
|
if (connectionModeEnabled && isConnecting) {
|
|
@@ -7334,7 +7483,7 @@ function PIDCanvasImpl({
|
|
|
7334
7483
|
onNodeClick
|
|
7335
7484
|
]
|
|
7336
7485
|
);
|
|
7337
|
-
const handlePipeClick = (0,
|
|
7486
|
+
const handlePipeClick = (0, import_react22.useCallback)(
|
|
7338
7487
|
(pipeId, event) => {
|
|
7339
7488
|
if (selectionEnabled) {
|
|
7340
7489
|
selectPipe(pipeId, event.ctrlKey || event.metaKey);
|
|
@@ -7353,7 +7502,7 @@ function PIDCanvasImpl({
|
|
|
7353
7502
|
}
|
|
7354
7503
|
setSelectedWaypoint(null);
|
|
7355
7504
|
};
|
|
7356
|
-
const handleDragOver = (0,
|
|
7505
|
+
const handleDragOver = (0, import_react22.useCallback)(
|
|
7357
7506
|
(event) => {
|
|
7358
7507
|
if (!features.allowSymbolDrop) return;
|
|
7359
7508
|
event.preventDefault();
|
|
@@ -7364,7 +7513,7 @@ function PIDCanvasImpl({
|
|
|
7364
7513
|
},
|
|
7365
7514
|
[features.allowSymbolDrop, screenToWorld, svgRef]
|
|
7366
7515
|
);
|
|
7367
|
-
const handleDrop = (0,
|
|
7516
|
+
const handleDrop = (0, import_react22.useCallback)(
|
|
7368
7517
|
(event) => {
|
|
7369
7518
|
if (!features.allowSymbolDrop) return;
|
|
7370
7519
|
event.preventDefault();
|
|
@@ -7377,10 +7526,10 @@ function PIDCanvasImpl({
|
|
|
7377
7526
|
},
|
|
7378
7527
|
[features.allowSymbolDrop, screenToWorld, onSymbolDrop, svgRef]
|
|
7379
7528
|
);
|
|
7380
|
-
const handleDragLeave = (0,
|
|
7529
|
+
const handleDragLeave = (0, import_react22.useCallback)(() => {
|
|
7381
7530
|
setDragOverPosition(null);
|
|
7382
7531
|
}, []);
|
|
7383
|
-
const handleMouseMove = (0,
|
|
7532
|
+
const handleMouseMove = (0, import_react22.useCallback)(
|
|
7384
7533
|
(event) => {
|
|
7385
7534
|
const connectionModeEnabled = features.connectionMode ?? false;
|
|
7386
7535
|
if (connectionModeEnabled) {
|
|
@@ -7417,7 +7566,7 @@ function PIDCanvasImpl({
|
|
|
7417
7566
|
const viewBox = controlledViewBox;
|
|
7418
7567
|
const displayDiagram = localDiagram;
|
|
7419
7568
|
const selectedNode = selectionEnabled && selection.selectedNodeIds.size === 1 ? localDiagram.nodes.find((n) => selection.selectedNodeIds.has(n.id)) || null : null;
|
|
7420
|
-
return /* @__PURE__ */ (0,
|
|
7569
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
7421
7570
|
"div",
|
|
7422
7571
|
{
|
|
7423
7572
|
ref: containerRef,
|
|
@@ -7432,7 +7581,7 @@ function PIDCanvasImpl({
|
|
|
7432
7581
|
},
|
|
7433
7582
|
...props,
|
|
7434
7583
|
children: [
|
|
7435
|
-
/* @__PURE__ */ (0,
|
|
7584
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
7436
7585
|
"svg",
|
|
7437
7586
|
{
|
|
7438
7587
|
ref: svgRef,
|
|
@@ -7451,15 +7600,15 @@ function PIDCanvasImpl({
|
|
|
7451
7600
|
onDrop: handleDrop,
|
|
7452
7601
|
onDragLeave: handleDragLeave,
|
|
7453
7602
|
children: [
|
|
7454
|
-
features.showGrid !== false ? /* @__PURE__ */ (0,
|
|
7455
|
-
/* @__PURE__ */ (0,
|
|
7456
|
-
/* @__PURE__ */ (0,
|
|
7457
|
-
/* @__PURE__ */ (0,
|
|
7458
|
-
/* @__PURE__ */ (0,
|
|
7459
|
-
/* @__PURE__ */ (0,
|
|
7603
|
+
features.showGrid !== false ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
7604
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("defs", { children: [
|
|
7605
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("pattern", { id: "grid-minor", width: "5", height: "5", patternUnits: "userSpaceOnUse", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("path", { d: "M 5 0 L 0 0 0 5", fill: "none", stroke: "#e5e7eb", strokeWidth: "0.5" }) }),
|
|
7606
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("pattern", { id: "grid-major", width: "25", height: "25", patternUnits: "userSpaceOnUse", children: [
|
|
7607
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("rect", { width: "25", height: "25", fill: "url(#grid-minor)" }),
|
|
7608
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("path", { d: "M 25 0 L 0 0 0 25", fill: "none", stroke: "#d1d5db", strokeWidth: "1" })
|
|
7460
7609
|
] })
|
|
7461
7610
|
] }),
|
|
7462
|
-
/* @__PURE__ */ (0,
|
|
7611
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7463
7612
|
"rect",
|
|
7464
7613
|
{
|
|
7465
7614
|
x: Math.floor(viewBox.x / 25) * 25 - viewBox.width,
|
|
@@ -7469,7 +7618,7 @@ function PIDCanvasImpl({
|
|
|
7469
7618
|
fill: "url(#grid-major)"
|
|
7470
7619
|
}
|
|
7471
7620
|
)
|
|
7472
|
-
] }) : /* @__PURE__ */ (0,
|
|
7621
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7473
7622
|
"rect",
|
|
7474
7623
|
{
|
|
7475
7624
|
x: Math.floor(viewBox.x / 25) * 25 - viewBox.width,
|
|
@@ -7479,7 +7628,7 @@ function PIDCanvasImpl({
|
|
|
7479
7628
|
fill: features.backgroundColor ?? "#ffffff"
|
|
7480
7629
|
}
|
|
7481
7630
|
),
|
|
7482
|
-
/* @__PURE__ */ (0,
|
|
7631
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7483
7632
|
PipeRenderer,
|
|
7484
7633
|
{
|
|
7485
7634
|
pipes: displayDiagram.pipes,
|
|
@@ -7493,7 +7642,7 @@ function PIDCanvasImpl({
|
|
|
7493
7642
|
onPipeSegmentClick: void 0
|
|
7494
7643
|
}
|
|
7495
7644
|
),
|
|
7496
|
-
/* @__PURE__ */ (0,
|
|
7645
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7497
7646
|
NodeRenderer,
|
|
7498
7647
|
{
|
|
7499
7648
|
nodes: displayDiagram.nodes,
|
|
@@ -7507,7 +7656,7 @@ function PIDCanvasImpl({
|
|
|
7507
7656
|
statusColorMap
|
|
7508
7657
|
}
|
|
7509
7658
|
),
|
|
7510
|
-
(features.editPipeRoutes ?? false) && /* @__PURE__ */ (0,
|
|
7659
|
+
(features.editPipeRoutes ?? false) && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7511
7660
|
PipeRenderer,
|
|
7512
7661
|
{
|
|
7513
7662
|
pipes: displayDiagram.pipes,
|
|
@@ -7524,7 +7673,7 @@ function PIDCanvasImpl({
|
|
|
7524
7673
|
onPipeSegmentClick: handlePipeSegmentClick
|
|
7525
7674
|
}
|
|
7526
7675
|
),
|
|
7527
|
-
telemetryEnabled && telemetry && /* @__PURE__ */ (0,
|
|
7676
|
+
telemetryEnabled && telemetry && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("g", { id: "layer-telemetry", children: displayDiagram.nodes.map((node) => {
|
|
7528
7677
|
if (node.symbolId === "status-indicator") return null;
|
|
7529
7678
|
const binding = telemetry.get(node.id);
|
|
7530
7679
|
if (!binding) return null;
|
|
@@ -7532,7 +7681,7 @@ function PIDCanvasImpl({
|
|
|
7532
7681
|
if (!symbol) return null;
|
|
7533
7682
|
const overlayX = node.transform.x + symbol.viewBox.width / 2;
|
|
7534
7683
|
const overlayY = node.transform.y + symbol.viewBox.height + 50;
|
|
7535
|
-
return /* @__PURE__ */ (0,
|
|
7684
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7536
7685
|
DataOverlay,
|
|
7537
7686
|
{
|
|
7538
7687
|
nodeId: node.id,
|
|
@@ -7545,7 +7694,7 @@ function PIDCanvasImpl({
|
|
|
7545
7694
|
`telemetry-${node.id}`
|
|
7546
7695
|
);
|
|
7547
7696
|
}) }),
|
|
7548
|
-
dragOverPosition && /* @__PURE__ */ (0,
|
|
7697
|
+
dragOverPosition && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7549
7698
|
"circle",
|
|
7550
7699
|
{
|
|
7551
7700
|
cx: dragOverPosition.x,
|
|
@@ -7558,7 +7707,7 @@ function PIDCanvasImpl({
|
|
|
7558
7707
|
pointerEvents: "none"
|
|
7559
7708
|
}
|
|
7560
7709
|
),
|
|
7561
|
-
isConnecting && connectionSource && connectionCursor && /* @__PURE__ */ (0,
|
|
7710
|
+
isConnecting && connectionSource && connectionCursor && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("g", { id: "connection-preview", pointerEvents: "none", children: (() => {
|
|
7562
7711
|
const sourceNode = displayDiagram.nodes.find((n) => n.id === connectionSource);
|
|
7563
7712
|
if (!sourceNode) return null;
|
|
7564
7713
|
const symbol = getSymbolDefinition(sourceNode.symbolId);
|
|
@@ -7574,8 +7723,8 @@ function PIDCanvasImpl({
|
|
|
7574
7723
|
}
|
|
7575
7724
|
}
|
|
7576
7725
|
}
|
|
7577
|
-
return /* @__PURE__ */ (0,
|
|
7578
|
-
/* @__PURE__ */ (0,
|
|
7726
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
7727
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7579
7728
|
"circle",
|
|
7580
7729
|
{
|
|
7581
7730
|
cx: lineStartX,
|
|
@@ -7587,7 +7736,7 @@ function PIDCanvasImpl({
|
|
|
7587
7736
|
opacity: 0.6
|
|
7588
7737
|
}
|
|
7589
7738
|
),
|
|
7590
|
-
/* @__PURE__ */ (0,
|
|
7739
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7591
7740
|
"line",
|
|
7592
7741
|
{
|
|
7593
7742
|
x1: lineStartX,
|
|
@@ -7600,7 +7749,7 @@ function PIDCanvasImpl({
|
|
|
7600
7749
|
opacity: 0.8
|
|
7601
7750
|
}
|
|
7602
7751
|
),
|
|
7603
|
-
/* @__PURE__ */ (0,
|
|
7752
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7604
7753
|
"circle",
|
|
7605
7754
|
{
|
|
7606
7755
|
cx: connectionCursor.x,
|
|
@@ -7612,7 +7761,7 @@ function PIDCanvasImpl({
|
|
|
7612
7761
|
)
|
|
7613
7762
|
] });
|
|
7614
7763
|
})() }),
|
|
7615
|
-
features.connectionMode && /* @__PURE__ */ (0,
|
|
7764
|
+
features.connectionMode && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("g", { id: "port-indicators", children: displayDiagram.nodes.map((node) => {
|
|
7616
7765
|
const symbol = getSymbolDefinition(node.symbolId);
|
|
7617
7766
|
if (!symbol?.ports) return null;
|
|
7618
7767
|
return symbol.ports.map((port) => {
|
|
@@ -7620,8 +7769,8 @@ function PIDCanvasImpl({
|
|
|
7620
7769
|
if (!portPos) return null;
|
|
7621
7770
|
const isHovered = hoveredPort === port.id && hoveredNode === node.id;
|
|
7622
7771
|
const isSourcePort = node.id === connectionSource && port.id === connectionSourcePort;
|
|
7623
|
-
return /* @__PURE__ */ (0,
|
|
7624
|
-
/* @__PURE__ */ (0,
|
|
7772
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("g", { children: [
|
|
7773
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7625
7774
|
"circle",
|
|
7626
7775
|
{
|
|
7627
7776
|
cx: portPos.x,
|
|
@@ -7654,7 +7803,7 @@ function PIDCanvasImpl({
|
|
|
7654
7803
|
}
|
|
7655
7804
|
}
|
|
7656
7805
|
),
|
|
7657
|
-
/* @__PURE__ */ (0,
|
|
7806
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7658
7807
|
"circle",
|
|
7659
7808
|
{
|
|
7660
7809
|
cx: portPos.x,
|
|
@@ -7673,7 +7822,7 @@ function PIDCanvasImpl({
|
|
|
7673
7822
|
]
|
|
7674
7823
|
}
|
|
7675
7824
|
),
|
|
7676
|
-
features.dragNodes && /* @__PURE__ */ (0,
|
|
7825
|
+
features.dragNodes && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7677
7826
|
PositionPanel,
|
|
7678
7827
|
{
|
|
7679
7828
|
selectedNode,
|
|
@@ -7691,19 +7840,19 @@ function PIDCanvasImpl({
|
|
|
7691
7840
|
}
|
|
7692
7841
|
);
|
|
7693
7842
|
}
|
|
7694
|
-
var PIDCanvas =
|
|
7843
|
+
var PIDCanvas = import_react22.default.memo(PIDCanvasImpl);
|
|
7695
7844
|
|
|
7696
7845
|
// src/components/SymbolLibrary/SymbolLibrary.tsx
|
|
7697
|
-
var
|
|
7698
|
-
var
|
|
7846
|
+
var import_react23 = require("react");
|
|
7847
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
7699
7848
|
function SymbolLibrary({
|
|
7700
7849
|
className = "",
|
|
7701
7850
|
onSymbolDragStart,
|
|
7702
7851
|
showCategories = true,
|
|
7703
7852
|
categories = ["Valves", "Pumps", "Tanks", "Instruments", "Displays"]
|
|
7704
7853
|
}) {
|
|
7705
|
-
const [selectedCategory, setSelectedCategory] = (0,
|
|
7706
|
-
const [searchQuery, setSearchQuery] = (0,
|
|
7854
|
+
const [selectedCategory, setSelectedCategory] = (0, import_react23.useState)("all");
|
|
7855
|
+
const [searchQuery, setSearchQuery] = (0, import_react23.useState)("");
|
|
7707
7856
|
const symbolIds = getAvailableSymbols();
|
|
7708
7857
|
const allSymbols = symbolIds.map((id) => getSymbolDefinition(id)).filter((symbol) => symbol !== void 0);
|
|
7709
7858
|
const categoryMap = {
|
|
@@ -7724,9 +7873,9 @@ function SymbolLibrary({
|
|
|
7724
7873
|
event.dataTransfer.effectAllowed = "copy";
|
|
7725
7874
|
onSymbolDragStart?.(symbol.id, event);
|
|
7726
7875
|
};
|
|
7727
|
-
return /* @__PURE__ */ (0,
|
|
7728
|
-
/* @__PURE__ */ (0,
|
|
7729
|
-
/* @__PURE__ */ (0,
|
|
7876
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: `symbol-library ${className}`.trim(), style: styles.container, children: [
|
|
7877
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: styles.header, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h3", { style: styles.title, children: "Symbol Library" }) }),
|
|
7878
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: styles.searchContainer, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7730
7879
|
"input",
|
|
7731
7880
|
{
|
|
7732
7881
|
type: "text",
|
|
@@ -7736,8 +7885,8 @@ function SymbolLibrary({
|
|
|
7736
7885
|
style: styles.searchInput
|
|
7737
7886
|
}
|
|
7738
7887
|
) }),
|
|
7739
|
-
showCategories && /* @__PURE__ */ (0,
|
|
7740
|
-
/* @__PURE__ */ (0,
|
|
7888
|
+
showCategories && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: styles.categories, children: [
|
|
7889
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7741
7890
|
"button",
|
|
7742
7891
|
{
|
|
7743
7892
|
onClick: () => setSelectedCategory("all"),
|
|
@@ -7748,7 +7897,7 @@ function SymbolLibrary({
|
|
|
7748
7897
|
children: "All"
|
|
7749
7898
|
}
|
|
7750
7899
|
),
|
|
7751
|
-
categories.map((category) => /* @__PURE__ */ (0,
|
|
7900
|
+
categories.map((category) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7752
7901
|
"button",
|
|
7753
7902
|
{
|
|
7754
7903
|
onClick: () => setSelectedCategory(category),
|
|
@@ -7761,7 +7910,7 @@ function SymbolLibrary({
|
|
|
7761
7910
|
category
|
|
7762
7911
|
))
|
|
7763
7912
|
] }),
|
|
7764
|
-
/* @__PURE__ */ (0,
|
|
7913
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: styles.symbolGrid, children: filteredSymbols.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: styles.emptyState, children: "No symbols found" }) : filteredSymbols.map((symbol) => /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
7765
7914
|
"div",
|
|
7766
7915
|
{
|
|
7767
7916
|
draggable: true,
|
|
@@ -7769,15 +7918,15 @@ function SymbolLibrary({
|
|
|
7769
7918
|
style: styles.symbolCard,
|
|
7770
7919
|
title: symbol.metadata?.description || symbol.name,
|
|
7771
7920
|
children: [
|
|
7772
|
-
/* @__PURE__ */ (0,
|
|
7921
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: styles.symbolPreview, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7773
7922
|
"svg",
|
|
7774
7923
|
{
|
|
7775
7924
|
viewBox: `${symbol.viewBox.x} ${symbol.viewBox.y} ${symbol.viewBox.width} ${symbol.viewBox.height}`,
|
|
7776
7925
|
style: styles.symbolSvg,
|
|
7777
|
-
children: /* @__PURE__ */ (0,
|
|
7926
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("g", { dangerouslySetInnerHTML: { __html: symbol.svgContent } })
|
|
7778
7927
|
}
|
|
7779
7928
|
) }),
|
|
7780
|
-
/* @__PURE__ */ (0,
|
|
7929
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: styles.symbolName, children: symbol.name })
|
|
7781
7930
|
]
|
|
7782
7931
|
},
|
|
7783
7932
|
symbol.id
|
|
@@ -7886,7 +8035,7 @@ var styles = {
|
|
|
7886
8035
|
};
|
|
7887
8036
|
|
|
7888
8037
|
// src/components/NodeConfigPanel/NodeConfigPanel.tsx
|
|
7889
|
-
var
|
|
8038
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
7890
8039
|
function NodeConfigPanel({
|
|
7891
8040
|
node,
|
|
7892
8041
|
binding,
|
|
@@ -7909,15 +8058,15 @@ function NodeConfigPanel({
|
|
|
7909
8058
|
};
|
|
7910
8059
|
const appearanceFields = getAppearanceSchema(node.symbolId);
|
|
7911
8060
|
const showGenericTelemetry = appearanceFields.length === 0;
|
|
7912
|
-
return /* @__PURE__ */ (0,
|
|
7913
|
-
/* @__PURE__ */ (0,
|
|
8061
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className, style: defaultStyle, children: [
|
|
8062
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("h2", { style: { margin: "0 0 16px 0", fontSize: "1rem", fontWeight: 600 }, children: [
|
|
7914
8063
|
"Configure: ",
|
|
7915
8064
|
node.id
|
|
7916
8065
|
] }),
|
|
7917
|
-
/* @__PURE__ */ (0,
|
|
7918
|
-
/* @__PURE__ */ (0,
|
|
7919
|
-
/* @__PURE__ */ (0,
|
|
7920
|
-
/* @__PURE__ */ (0,
|
|
8066
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { marginBottom: "20px" }, children: [
|
|
8067
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { style: { fontSize: "0.875rem", fontWeight: 600, marginBottom: "8px" }, children: "Node Settings" }),
|
|
8068
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Label:" }),
|
|
8069
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
7921
8070
|
"input",
|
|
7922
8071
|
{
|
|
7923
8072
|
type: "text",
|
|
@@ -7933,10 +8082,10 @@ function NodeConfigPanel({
|
|
|
7933
8082
|
}
|
|
7934
8083
|
}
|
|
7935
8084
|
),
|
|
7936
|
-
/* @__PURE__ */ (0,
|
|
7937
|
-
/* @__PURE__ */ (0,
|
|
7938
|
-
/* @__PURE__ */ (0,
|
|
7939
|
-
/* @__PURE__ */ (0,
|
|
8085
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: "8px" }, children: [
|
|
8086
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { children: [
|
|
8087
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Label Offset X:" }),
|
|
8088
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
7940
8089
|
"input",
|
|
7941
8090
|
{
|
|
7942
8091
|
type: "number",
|
|
@@ -7957,9 +8106,9 @@ function NodeConfigPanel({
|
|
|
7957
8106
|
}
|
|
7958
8107
|
)
|
|
7959
8108
|
] }),
|
|
7960
|
-
/* @__PURE__ */ (0,
|
|
7961
|
-
/* @__PURE__ */ (0,
|
|
7962
|
-
/* @__PURE__ */ (0,
|
|
8109
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { children: [
|
|
8110
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Label Offset Y:" }),
|
|
8111
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
7963
8112
|
"input",
|
|
7964
8113
|
{
|
|
7965
8114
|
type: "number",
|
|
@@ -7981,9 +8130,9 @@ function NodeConfigPanel({
|
|
|
7981
8130
|
)
|
|
7982
8131
|
] })
|
|
7983
8132
|
] }),
|
|
7984
|
-
/* @__PURE__ */ (0,
|
|
7985
|
-
/* @__PURE__ */ (0,
|
|
7986
|
-
/* @__PURE__ */ (0,
|
|
8133
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { children: [
|
|
8134
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Label Font Size:" }),
|
|
8135
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
7987
8136
|
"input",
|
|
7988
8137
|
{
|
|
7989
8138
|
type: "number",
|
|
@@ -8003,9 +8152,9 @@ function NodeConfigPanel({
|
|
|
8003
8152
|
}
|
|
8004
8153
|
)
|
|
8005
8154
|
] }),
|
|
8006
|
-
/* @__PURE__ */ (0,
|
|
8007
|
-
/* @__PURE__ */ (0,
|
|
8008
|
-
/* @__PURE__ */ (0,
|
|
8155
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { children: [
|
|
8156
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Rotation (degrees):" }),
|
|
8157
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8009
8158
|
"input",
|
|
8010
8159
|
{
|
|
8011
8160
|
type: "number",
|
|
@@ -8030,8 +8179,8 @@ function NodeConfigPanel({
|
|
|
8030
8179
|
)
|
|
8031
8180
|
] })
|
|
8032
8181
|
] }),
|
|
8033
|
-
appearanceFields.length > 0 && /* @__PURE__ */ (0,
|
|
8034
|
-
/* @__PURE__ */ (0,
|
|
8182
|
+
appearanceFields.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { marginBottom: "20px" }, children: [
|
|
8183
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { style: { fontSize: "0.875rem", fontWeight: 600, marginBottom: "8px" }, children: "Appearance" }),
|
|
8035
8184
|
appearanceFields.map((field) => {
|
|
8036
8185
|
const value = readAppearanceValue(node, field);
|
|
8037
8186
|
const fieldLabel = field.label ?? field.key;
|
|
@@ -8044,8 +8193,8 @@ function NodeConfigPanel({
|
|
|
8044
8193
|
};
|
|
8045
8194
|
let control;
|
|
8046
8195
|
if (field.kind === "boolean") {
|
|
8047
|
-
control = /* @__PURE__ */ (0,
|
|
8048
|
-
/* @__PURE__ */ (0,
|
|
8196
|
+
control = /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { style: { fontSize: "0.75rem", display: "block" }, children: [
|
|
8197
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8049
8198
|
"input",
|
|
8050
8199
|
{
|
|
8051
8200
|
type: "checkbox",
|
|
@@ -8057,28 +8206,28 @@ function NodeConfigPanel({
|
|
|
8057
8206
|
fieldLabel
|
|
8058
8207
|
] });
|
|
8059
8208
|
} else if (field.kind === "select") {
|
|
8060
|
-
control = /* @__PURE__ */ (0,
|
|
8061
|
-
/* @__PURE__ */ (0,
|
|
8209
|
+
control = /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
8210
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: [
|
|
8062
8211
|
fieldLabel,
|
|
8063
8212
|
":"
|
|
8064
8213
|
] }),
|
|
8065
|
-
/* @__PURE__ */ (0,
|
|
8214
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8066
8215
|
"select",
|
|
8067
8216
|
{
|
|
8068
8217
|
value: String(value),
|
|
8069
8218
|
onChange: (e) => onUpdateNode(writeAppearanceValue(node, field, e.target.value)),
|
|
8070
8219
|
style: inputStyle,
|
|
8071
|
-
children: field.options?.map((opt) => /* @__PURE__ */ (0,
|
|
8220
|
+
children: field.options?.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("option", { value: opt, children: opt }, opt))
|
|
8072
8221
|
}
|
|
8073
8222
|
)
|
|
8074
8223
|
] });
|
|
8075
8224
|
} else if (field.kind === "number") {
|
|
8076
|
-
control = /* @__PURE__ */ (0,
|
|
8077
|
-
/* @__PURE__ */ (0,
|
|
8225
|
+
control = /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
8226
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: [
|
|
8078
8227
|
fieldLabel,
|
|
8079
8228
|
":"
|
|
8080
8229
|
] }),
|
|
8081
|
-
/* @__PURE__ */ (0,
|
|
8230
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8082
8231
|
"input",
|
|
8083
8232
|
{
|
|
8084
8233
|
type: "number",
|
|
@@ -8093,12 +8242,12 @@ function NodeConfigPanel({
|
|
|
8093
8242
|
const listId = `tags-${node.id}-${field.key}`;
|
|
8094
8243
|
const known = tagValue.length > 0 && availableTags.includes(tagValue);
|
|
8095
8244
|
const unknown = tagValue.length > 0 && !known;
|
|
8096
|
-
control = /* @__PURE__ */ (0,
|
|
8097
|
-
/* @__PURE__ */ (0,
|
|
8245
|
+
control = /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
8246
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: [
|
|
8098
8247
|
fieldLabel,
|
|
8099
8248
|
":"
|
|
8100
8249
|
] }),
|
|
8101
|
-
/* @__PURE__ */ (0,
|
|
8250
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8102
8251
|
"input",
|
|
8103
8252
|
{
|
|
8104
8253
|
type: "text",
|
|
@@ -8112,8 +8261,8 @@ function NodeConfigPanel({
|
|
|
8112
8261
|
}
|
|
8113
8262
|
}
|
|
8114
8263
|
),
|
|
8115
|
-
/* @__PURE__ */ (0,
|
|
8116
|
-
tagValue.length > 0 && /* @__PURE__ */ (0,
|
|
8264
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("datalist", { id: listId, children: availableTags.map((t) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("option", { value: t }, t)) }),
|
|
8265
|
+
tagValue.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8117
8266
|
"div",
|
|
8118
8267
|
{
|
|
8119
8268
|
style: {
|
|
@@ -8126,12 +8275,12 @@ function NodeConfigPanel({
|
|
|
8126
8275
|
)
|
|
8127
8276
|
] });
|
|
8128
8277
|
} else {
|
|
8129
|
-
control = /* @__PURE__ */ (0,
|
|
8130
|
-
/* @__PURE__ */ (0,
|
|
8278
|
+
control = /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
8279
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: [
|
|
8131
8280
|
fieldLabel,
|
|
8132
8281
|
":"
|
|
8133
8282
|
] }),
|
|
8134
|
-
/* @__PURE__ */ (0,
|
|
8283
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8135
8284
|
"input",
|
|
8136
8285
|
{
|
|
8137
8286
|
type: "text",
|
|
@@ -8142,9 +8291,9 @@ function NodeConfigPanel({
|
|
|
8142
8291
|
)
|
|
8143
8292
|
] });
|
|
8144
8293
|
}
|
|
8145
|
-
return /* @__PURE__ */ (0,
|
|
8294
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { marginBottom: "10px" }, children: [
|
|
8146
8295
|
control,
|
|
8147
|
-
field.help && /* @__PURE__ */ (0,
|
|
8296
|
+
field.help && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8148
8297
|
"div",
|
|
8149
8298
|
{
|
|
8150
8299
|
style: {
|
|
@@ -8159,9 +8308,9 @@ function NodeConfigPanel({
|
|
|
8159
8308
|
] }, field.key);
|
|
8160
8309
|
})
|
|
8161
8310
|
] }),
|
|
8162
|
-
showGenericTelemetry && /* @__PURE__ */ (0,
|
|
8163
|
-
/* @__PURE__ */ (0,
|
|
8164
|
-
!binding ? /* @__PURE__ */ (0,
|
|
8311
|
+
showGenericTelemetry && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { marginBottom: "20px" }, children: [
|
|
8312
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { style: { fontSize: "0.875rem", fontWeight: 600, marginBottom: "8px" }, children: "Telemetry Data" }),
|
|
8313
|
+
!binding ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8165
8314
|
"button",
|
|
8166
8315
|
{
|
|
8167
8316
|
onClick: () => {
|
|
@@ -8204,9 +8353,9 @@ function NodeConfigPanel({
|
|
|
8204
8353
|
},
|
|
8205
8354
|
children: "+ Add Telemetry"
|
|
8206
8355
|
}
|
|
8207
|
-
) : /* @__PURE__ */ (0,
|
|
8208
|
-
/* @__PURE__ */ (0,
|
|
8209
|
-
/* @__PURE__ */ (0,
|
|
8356
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
8357
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Tag (attribute):" }),
|
|
8358
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8210
8359
|
"input",
|
|
8211
8360
|
{
|
|
8212
8361
|
type: "text",
|
|
@@ -8226,8 +8375,8 @@ function NodeConfigPanel({
|
|
|
8226
8375
|
}
|
|
8227
8376
|
}
|
|
8228
8377
|
),
|
|
8229
|
-
/* @__PURE__ */ (0,
|
|
8230
|
-
/* @__PURE__ */ (0,
|
|
8378
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Initial Value:" }),
|
|
8379
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8231
8380
|
"input",
|
|
8232
8381
|
{
|
|
8233
8382
|
type: "number",
|
|
@@ -8249,8 +8398,8 @@ function NodeConfigPanel({
|
|
|
8249
8398
|
}
|
|
8250
8399
|
}
|
|
8251
8400
|
),
|
|
8252
|
-
/* @__PURE__ */ (0,
|
|
8253
|
-
/* @__PURE__ */ (0,
|
|
8401
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Unit:" }),
|
|
8402
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8254
8403
|
"input",
|
|
8255
8404
|
{
|
|
8256
8405
|
type: "text",
|
|
@@ -8272,8 +8421,8 @@ function NodeConfigPanel({
|
|
|
8272
8421
|
}
|
|
8273
8422
|
}
|
|
8274
8423
|
),
|
|
8275
|
-
/* @__PURE__ */ (0,
|
|
8276
|
-
/* @__PURE__ */ (0,
|
|
8424
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: [
|
|
8425
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8277
8426
|
"input",
|
|
8278
8427
|
{
|
|
8279
8428
|
type: "checkbox",
|
|
@@ -8295,8 +8444,8 @@ function NodeConfigPanel({
|
|
|
8295
8444
|
),
|
|
8296
8445
|
"Show Sparkline"
|
|
8297
8446
|
] }),
|
|
8298
|
-
/* @__PURE__ */ (0,
|
|
8299
|
-
/* @__PURE__ */ (0,
|
|
8447
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { marginTop: "12px" }, children: [
|
|
8448
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8300
8449
|
"label",
|
|
8301
8450
|
{
|
|
8302
8451
|
style: {
|
|
@@ -8308,10 +8457,10 @@ function NodeConfigPanel({
|
|
|
8308
8457
|
children: "Telemetry Position Offset:"
|
|
8309
8458
|
}
|
|
8310
8459
|
),
|
|
8311
|
-
/* @__PURE__ */ (0,
|
|
8312
|
-
/* @__PURE__ */ (0,
|
|
8313
|
-
/* @__PURE__ */ (0,
|
|
8314
|
-
/* @__PURE__ */ (0,
|
|
8460
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: "8px" }, children: [
|
|
8461
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { children: [
|
|
8462
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "X Offset:" }),
|
|
8463
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8315
8464
|
"input",
|
|
8316
8465
|
{
|
|
8317
8466
|
type: "number",
|
|
@@ -8338,9 +8487,9 @@ function NodeConfigPanel({
|
|
|
8338
8487
|
}
|
|
8339
8488
|
)
|
|
8340
8489
|
] }),
|
|
8341
|
-
/* @__PURE__ */ (0,
|
|
8342
|
-
/* @__PURE__ */ (0,
|
|
8343
|
-
/* @__PURE__ */ (0,
|
|
8490
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { children: [
|
|
8491
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "Y Offset:" }),
|
|
8492
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8344
8493
|
"input",
|
|
8345
8494
|
{
|
|
8346
8495
|
type: "number",
|
|
@@ -8368,8 +8517,8 @@ function NodeConfigPanel({
|
|
|
8368
8517
|
)
|
|
8369
8518
|
] })
|
|
8370
8519
|
] }),
|
|
8371
|
-
/* @__PURE__ */ (0,
|
|
8372
|
-
/* @__PURE__ */ (0,
|
|
8520
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { marginTop: "16px" }, children: [
|
|
8521
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8373
8522
|
"label",
|
|
8374
8523
|
{
|
|
8375
8524
|
style: {
|
|
@@ -8381,10 +8530,10 @@ function NodeConfigPanel({
|
|
|
8381
8530
|
children: "Display Colors:"
|
|
8382
8531
|
}
|
|
8383
8532
|
),
|
|
8384
|
-
/* @__PURE__ */ (0,
|
|
8385
|
-
/* @__PURE__ */ (0,
|
|
8386
|
-
/* @__PURE__ */ (0,
|
|
8387
|
-
/* @__PURE__ */ (0,
|
|
8533
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { marginBottom: "8px" }, children: [
|
|
8534
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "Text Color:" }),
|
|
8535
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { display: "flex", gap: "8px", alignItems: "center" }, children: [
|
|
8536
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8388
8537
|
"input",
|
|
8389
8538
|
{
|
|
8390
8539
|
type: "color",
|
|
@@ -8410,7 +8559,7 @@ function NodeConfigPanel({
|
|
|
8410
8559
|
}
|
|
8411
8560
|
}
|
|
8412
8561
|
),
|
|
8413
|
-
/* @__PURE__ */ (0,
|
|
8562
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8414
8563
|
"input",
|
|
8415
8564
|
{
|
|
8416
8565
|
type: "text",
|
|
@@ -8440,10 +8589,10 @@ function NodeConfigPanel({
|
|
|
8440
8589
|
)
|
|
8441
8590
|
] })
|
|
8442
8591
|
] }),
|
|
8443
|
-
binding.display?.showSparkline && /* @__PURE__ */ (0,
|
|
8444
|
-
/* @__PURE__ */ (0,
|
|
8445
|
-
/* @__PURE__ */ (0,
|
|
8446
|
-
/* @__PURE__ */ (0,
|
|
8592
|
+
binding.display?.showSparkline && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { marginBottom: "8px" }, children: [
|
|
8593
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "Sparkline Color:" }),
|
|
8594
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { display: "flex", gap: "8px", alignItems: "center" }, children: [
|
|
8595
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8447
8596
|
"input",
|
|
8448
8597
|
{
|
|
8449
8598
|
type: "color",
|
|
@@ -8469,7 +8618,7 @@ function NodeConfigPanel({
|
|
|
8469
8618
|
}
|
|
8470
8619
|
}
|
|
8471
8620
|
),
|
|
8472
|
-
/* @__PURE__ */ (0,
|
|
8621
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8473
8622
|
"input",
|
|
8474
8623
|
{
|
|
8475
8624
|
type: "text",
|
|
@@ -8499,9 +8648,9 @@ function NodeConfigPanel({
|
|
|
8499
8648
|
)
|
|
8500
8649
|
] })
|
|
8501
8650
|
] }),
|
|
8502
|
-
/* @__PURE__ */ (0,
|
|
8503
|
-
/* @__PURE__ */ (0,
|
|
8504
|
-
/* @__PURE__ */ (0,
|
|
8651
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { marginBottom: "8px" }, children: [
|
|
8652
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "Background:" }),
|
|
8653
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8505
8654
|
"input",
|
|
8506
8655
|
{
|
|
8507
8656
|
type: "text",
|
|
@@ -8529,12 +8678,12 @@ function NodeConfigPanel({
|
|
|
8529
8678
|
}
|
|
8530
8679
|
}
|
|
8531
8680
|
),
|
|
8532
|
-
/* @__PURE__ */ (0,
|
|
8681
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { fontSize: "0.65rem", color: "#6b7280", marginTop: "2px" }, children: "Use 'status' for status-based color or hex code" })
|
|
8533
8682
|
] })
|
|
8534
8683
|
] }),
|
|
8535
8684
|
" "
|
|
8536
8685
|
] }),
|
|
8537
|
-
onRemoveTelemetry && /* @__PURE__ */ (0,
|
|
8686
|
+
onRemoveTelemetry && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8538
8687
|
"button",
|
|
8539
8688
|
{
|
|
8540
8689
|
onClick: onRemoveTelemetry,
|
|
@@ -8554,13 +8703,13 @@ function NodeConfigPanel({
|
|
|
8554
8703
|
)
|
|
8555
8704
|
] })
|
|
8556
8705
|
] }),
|
|
8557
|
-
showGenericTelemetry && binding && /* @__PURE__ */ (0,
|
|
8558
|
-
/* @__PURE__ */ (0,
|
|
8706
|
+
showGenericTelemetry && binding && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { marginBottom: "20px" }, children: [
|
|
8707
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { style: { fontSize: "0.875rem", fontWeight: 600, marginBottom: "8px" }, children: "Thresholds" }),
|
|
8559
8708
|
["highHigh", "high", "low", "lowLow"].map((key) => {
|
|
8560
8709
|
const label = key === "highHigh" ? "High-High (\u2265)" : key === "high" ? "High (\u2265)" : key === "low" ? "Low (\u2264)" : "Low-Low (\u2264)";
|
|
8561
|
-
return /* @__PURE__ */ (0,
|
|
8562
|
-
/* @__PURE__ */ (0,
|
|
8563
|
-
/* @__PURE__ */ (0,
|
|
8710
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { marginBottom: "8px" }, children: [
|
|
8711
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: label }),
|
|
8712
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8564
8713
|
"input",
|
|
8565
8714
|
{
|
|
8566
8715
|
type: "number",
|
|
@@ -8584,8 +8733,8 @@ function NodeConfigPanel({
|
|
|
8584
8733
|
] }, key);
|
|
8585
8734
|
})
|
|
8586
8735
|
] }),
|
|
8587
|
-
showGenericTelemetry && binding && /* @__PURE__ */ (0,
|
|
8588
|
-
/* @__PURE__ */ (0,
|
|
8736
|
+
showGenericTelemetry && binding && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { marginBottom: "20px" }, children: [
|
|
8737
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { style: { fontSize: "0.875rem", fontWeight: 600, marginBottom: "8px" }, children: "Status Colors" }),
|
|
8589
8738
|
["normal", "warning", "alarm", "fault", "off"].map((status) => {
|
|
8590
8739
|
const defaultColors = {
|
|
8591
8740
|
normal: "#10b981",
|
|
@@ -8595,13 +8744,13 @@ function NodeConfigPanel({
|
|
|
8595
8744
|
off: "#6b7280"
|
|
8596
8745
|
};
|
|
8597
8746
|
const label = status === "normal" ? "Normal" : status === "warning" ? "Warning" : status === "alarm" ? "Alarm" : status === "fault" ? "Fault" : "Off";
|
|
8598
|
-
return /* @__PURE__ */ (0,
|
|
8599
|
-
/* @__PURE__ */ (0,
|
|
8747
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { marginBottom: "8px" }, children: [
|
|
8748
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: [
|
|
8600
8749
|
label,
|
|
8601
8750
|
":"
|
|
8602
8751
|
] }),
|
|
8603
|
-
/* @__PURE__ */ (0,
|
|
8604
|
-
/* @__PURE__ */ (0,
|
|
8752
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { display: "flex", gap: "8px", alignItems: "center" }, children: [
|
|
8753
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8605
8754
|
"input",
|
|
8606
8755
|
{
|
|
8607
8756
|
type: "color",
|
|
@@ -8622,7 +8771,7 @@ function NodeConfigPanel({
|
|
|
8622
8771
|
}
|
|
8623
8772
|
}
|
|
8624
8773
|
),
|
|
8625
|
-
/* @__PURE__ */ (0,
|
|
8774
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8626
8775
|
"input",
|
|
8627
8776
|
{
|
|
8628
8777
|
type: "text",
|
|
@@ -8649,7 +8798,7 @@ function NodeConfigPanel({
|
|
|
8649
8798
|
] }, status);
|
|
8650
8799
|
})
|
|
8651
8800
|
] }),
|
|
8652
|
-
/* @__PURE__ */ (0,
|
|
8801
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { marginTop: "20px", paddingTop: "20px", borderTop: "1px solid #cbd5e1" }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8653
8802
|
"button",
|
|
8654
8803
|
{
|
|
8655
8804
|
onClick: onRemove,
|
|
@@ -8926,13 +9075,13 @@ function createControlBinding(nodeId, deviceConfig, actions) {
|
|
|
8926
9075
|
}
|
|
8927
9076
|
|
|
8928
9077
|
// src/hooks/useDeviceControls.ts
|
|
8929
|
-
var
|
|
9078
|
+
var import_react24 = require("react");
|
|
8930
9079
|
function commandKey(nodeId, kind, suffix) {
|
|
8931
9080
|
return suffix ? `${nodeId}:${kind}:${suffix}` : `${nodeId}:${kind}`;
|
|
8932
9081
|
}
|
|
8933
9082
|
function useDeviceControls(initialBindings, options) {
|
|
8934
9083
|
const { commandTimeoutMs } = options ?? {};
|
|
8935
|
-
const [controls, setControls] = (0,
|
|
9084
|
+
const [controls, setControls] = (0, import_react24.useState)(() => {
|
|
8936
9085
|
const map = /* @__PURE__ */ new Map();
|
|
8937
9086
|
if (initialBindings) {
|
|
8938
9087
|
initialBindings.forEach((binding) => {
|
|
@@ -8941,12 +9090,12 @@ function useDeviceControls(initialBindings, options) {
|
|
|
8941
9090
|
}
|
|
8942
9091
|
return map;
|
|
8943
9092
|
});
|
|
8944
|
-
const pendingRef = (0,
|
|
8945
|
-
const [pendingCommands, setPendingCommands] = (0,
|
|
8946
|
-
const syncPending = (0,
|
|
9093
|
+
const pendingRef = (0, import_react24.useRef)(/* @__PURE__ */ new Map());
|
|
9094
|
+
const [pendingCommands, setPendingCommands] = (0, import_react24.useState)(() => /* @__PURE__ */ new Set());
|
|
9095
|
+
const syncPending = (0, import_react24.useCallback)(() => {
|
|
8947
9096
|
setPendingCommands(new Set(pendingRef.current.keys()));
|
|
8948
9097
|
}, []);
|
|
8949
|
-
const updateControl = (0,
|
|
9098
|
+
const updateControl = (0, import_react24.useCallback)((nodeId, updates) => {
|
|
8950
9099
|
setControls((prev) => {
|
|
8951
9100
|
const newMap = new Map(prev);
|
|
8952
9101
|
const existing = newMap.get(nodeId);
|
|
@@ -8960,7 +9109,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
8960
9109
|
return newMap;
|
|
8961
9110
|
});
|
|
8962
9111
|
}, []);
|
|
8963
|
-
const updateControlBatch = (0,
|
|
9112
|
+
const updateControlBatch = (0, import_react24.useCallback)((updates) => {
|
|
8964
9113
|
setControls((prev) => {
|
|
8965
9114
|
const newMap = new Map(prev);
|
|
8966
9115
|
Object.entries(updates).forEach(([nodeId, update]) => {
|
|
@@ -8972,7 +9121,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
8972
9121
|
return newMap;
|
|
8973
9122
|
});
|
|
8974
9123
|
}, []);
|
|
8975
|
-
const updateDeviceState = (0,
|
|
9124
|
+
const updateDeviceState = (0, import_react24.useCallback)(
|
|
8976
9125
|
(nodeId, stateUpdates) => {
|
|
8977
9126
|
setControls((prev) => {
|
|
8978
9127
|
const newMap = new Map(prev);
|
|
@@ -8988,7 +9137,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
8988
9137
|
},
|
|
8989
9138
|
[]
|
|
8990
9139
|
);
|
|
8991
|
-
const updateParameter = (0,
|
|
9140
|
+
const updateParameter = (0, import_react24.useCallback)(
|
|
8992
9141
|
(nodeId, parameterId, value) => {
|
|
8993
9142
|
setControls((prev) => {
|
|
8994
9143
|
const newMap = new Map(prev);
|
|
@@ -9015,27 +9164,27 @@ function useDeviceControls(initialBindings, options) {
|
|
|
9015
9164
|
},
|
|
9016
9165
|
[]
|
|
9017
9166
|
);
|
|
9018
|
-
const setControlBinding = (0,
|
|
9167
|
+
const setControlBinding = (0, import_react24.useCallback)((binding) => {
|
|
9019
9168
|
setControls((prev) => {
|
|
9020
9169
|
const newMap = new Map(prev);
|
|
9021
9170
|
newMap.set(binding.nodeId, binding);
|
|
9022
9171
|
return newMap;
|
|
9023
9172
|
});
|
|
9024
9173
|
}, []);
|
|
9025
|
-
const removeControlBinding = (0,
|
|
9174
|
+
const removeControlBinding = (0, import_react24.useCallback)((nodeId) => {
|
|
9026
9175
|
setControls((prev) => {
|
|
9027
9176
|
const newMap = new Map(prev);
|
|
9028
9177
|
newMap.delete(nodeId);
|
|
9029
9178
|
return newMap;
|
|
9030
9179
|
});
|
|
9031
9180
|
}, []);
|
|
9032
|
-
const getControlBinding = (0,
|
|
9181
|
+
const getControlBinding = (0, import_react24.useCallback)(
|
|
9033
9182
|
(nodeId) => {
|
|
9034
9183
|
return controls.get(nodeId);
|
|
9035
9184
|
},
|
|
9036
9185
|
[controls]
|
|
9037
9186
|
);
|
|
9038
|
-
const isCommandPending = (0,
|
|
9187
|
+
const isCommandPending = (0, import_react24.useCallback)(
|
|
9039
9188
|
(nodeId, kind) => {
|
|
9040
9189
|
if (kind) {
|
|
9041
9190
|
const prefix2 = `${nodeId}:${kind}`;
|
|
@@ -9052,7 +9201,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
9052
9201
|
},
|
|
9053
9202
|
[pendingCommands]
|
|
9054
9203
|
);
|
|
9055
|
-
const markPending = (0,
|
|
9204
|
+
const markPending = (0, import_react24.useCallback)(
|
|
9056
9205
|
(key, delta) => {
|
|
9057
9206
|
const next = (pendingRef.current.get(key) ?? 0) + delta;
|
|
9058
9207
|
if (next > 0) pendingRef.current.set(key, next);
|
|
@@ -9061,7 +9210,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
9061
9210
|
},
|
|
9062
9211
|
[syncPending]
|
|
9063
9212
|
);
|
|
9064
|
-
const runCommand = (0,
|
|
9213
|
+
const runCommand = (0, import_react24.useCallback)(
|
|
9065
9214
|
async (nodeId, key, invoke, messages) => {
|
|
9066
9215
|
const binding = controls.get(nodeId);
|
|
9067
9216
|
if (!binding) return;
|
|
@@ -9101,7 +9250,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
9101
9250
|
},
|
|
9102
9251
|
[controls, updateDeviceState, markPending, commandTimeoutMs]
|
|
9103
9252
|
);
|
|
9104
|
-
const sendModeChange = (0,
|
|
9253
|
+
const sendModeChange = (0, import_react24.useCallback)(
|
|
9105
9254
|
(nodeId, mode) => runCommand(
|
|
9106
9255
|
nodeId,
|
|
9107
9256
|
commandKey(nodeId, "mode"),
|
|
@@ -9110,7 +9259,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
9110
9259
|
),
|
|
9111
9260
|
[runCommand]
|
|
9112
9261
|
);
|
|
9113
|
-
const sendParameterChange = (0,
|
|
9262
|
+
const sendParameterChange = (0, import_react24.useCallback)(
|
|
9114
9263
|
(nodeId, parameterId, value) => runCommand(
|
|
9115
9264
|
nodeId,
|
|
9116
9265
|
commandKey(nodeId, "parameter", parameterId),
|
|
@@ -9119,21 +9268,21 @@ function useDeviceControls(initialBindings, options) {
|
|
|
9119
9268
|
),
|
|
9120
9269
|
[runCommand]
|
|
9121
9270
|
);
|
|
9122
|
-
const sendStartCommand = (0,
|
|
9271
|
+
const sendStartCommand = (0, import_react24.useCallback)(
|
|
9123
9272
|
(nodeId) => runCommand(nodeId, commandKey(nodeId, "start"), (binding) => binding.actions.onStart?.(), {
|
|
9124
9273
|
success: "Start command sent",
|
|
9125
9274
|
failure: "Start command failed"
|
|
9126
9275
|
}),
|
|
9127
9276
|
[runCommand]
|
|
9128
9277
|
);
|
|
9129
|
-
const sendStopCommand = (0,
|
|
9278
|
+
const sendStopCommand = (0, import_react24.useCallback)(
|
|
9130
9279
|
(nodeId) => runCommand(nodeId, commandKey(nodeId, "stop"), (binding) => binding.actions.onStop?.(), {
|
|
9131
9280
|
success: "Stop command sent",
|
|
9132
9281
|
failure: "Stop command failed"
|
|
9133
9282
|
}),
|
|
9134
9283
|
[runCommand]
|
|
9135
9284
|
);
|
|
9136
|
-
const sendCustomAction = (0,
|
|
9285
|
+
const sendCustomAction = (0, import_react24.useCallback)(
|
|
9137
9286
|
(nodeId, actionId) => runCommand(
|
|
9138
9287
|
nodeId,
|
|
9139
9288
|
commandKey(nodeId, "action", actionId),
|
|
@@ -9186,9 +9335,9 @@ function createConfigBinding(nodeId, tag, parameters, actions, options) {
|
|
|
9186
9335
|
}
|
|
9187
9336
|
|
|
9188
9337
|
// src/hooks/useDeviceConfigs.ts
|
|
9189
|
-
var
|
|
9338
|
+
var import_react25 = require("react");
|
|
9190
9339
|
function useDeviceConfigs(initialConfigs) {
|
|
9191
|
-
const [configs, setConfigs] = (0,
|
|
9340
|
+
const [configs, setConfigs] = (0, import_react25.useState)(() => {
|
|
9192
9341
|
const map = /* @__PURE__ */ new Map();
|
|
9193
9342
|
if (initialConfigs) {
|
|
9194
9343
|
initialConfigs.forEach((config) => {
|
|
@@ -9197,13 +9346,13 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
9197
9346
|
}
|
|
9198
9347
|
return map;
|
|
9199
9348
|
});
|
|
9200
|
-
const getConfig = (0,
|
|
9349
|
+
const getConfig = (0, import_react25.useCallback)(
|
|
9201
9350
|
(nodeId) => {
|
|
9202
9351
|
return configs.get(nodeId);
|
|
9203
9352
|
},
|
|
9204
9353
|
[configs]
|
|
9205
9354
|
);
|
|
9206
|
-
const updateConfig = (0,
|
|
9355
|
+
const updateConfig = (0, import_react25.useCallback)((nodeId, updates) => {
|
|
9207
9356
|
setConfigs((prev) => {
|
|
9208
9357
|
const newMap = new Map(prev);
|
|
9209
9358
|
const existing = newMap.get(nodeId);
|
|
@@ -9217,7 +9366,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
9217
9366
|
return newMap;
|
|
9218
9367
|
});
|
|
9219
9368
|
}, []);
|
|
9220
|
-
const updateConfigState = (0,
|
|
9369
|
+
const updateConfigState = (0, import_react25.useCallback)((nodeId, stateUpdates) => {
|
|
9221
9370
|
setConfigs((prev) => {
|
|
9222
9371
|
const newMap = new Map(prev);
|
|
9223
9372
|
const existing = newMap.get(nodeId);
|
|
@@ -9230,7 +9379,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
9230
9379
|
return newMap;
|
|
9231
9380
|
});
|
|
9232
9381
|
}, []);
|
|
9233
|
-
const updateConfigBatch = (0,
|
|
9382
|
+
const updateConfigBatch = (0, import_react25.useCallback)((updates) => {
|
|
9234
9383
|
setConfigs((prev) => {
|
|
9235
9384
|
const newMap = new Map(prev);
|
|
9236
9385
|
Object.entries(updates).forEach(([nodeId, update]) => {
|
|
@@ -9242,7 +9391,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
9242
9391
|
return newMap;
|
|
9243
9392
|
});
|
|
9244
9393
|
}, []);
|
|
9245
|
-
const updateParameterValue = (0,
|
|
9394
|
+
const updateParameterValue = (0, import_react25.useCallback)((nodeId, parameterId, value) => {
|
|
9246
9395
|
setConfigs((prev) => {
|
|
9247
9396
|
const newMap = new Map(prev);
|
|
9248
9397
|
const existing = newMap.get(nodeId);
|
|
@@ -9259,7 +9408,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
9259
9408
|
return newMap;
|
|
9260
9409
|
});
|
|
9261
9410
|
}, []);
|
|
9262
|
-
const applyConfig = (0,
|
|
9411
|
+
const applyConfig = (0, import_react25.useCallback)(
|
|
9263
9412
|
async (nodeId) => {
|
|
9264
9413
|
const config = configs.get(nodeId);
|
|
9265
9414
|
if (!config || !config.actions.onApply) {
|
|
@@ -9292,7 +9441,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
9292
9441
|
},
|
|
9293
9442
|
[configs, updateConfigState]
|
|
9294
9443
|
);
|
|
9295
|
-
const saveConfig = (0,
|
|
9444
|
+
const saveConfig = (0, import_react25.useCallback)(
|
|
9296
9445
|
async (nodeId) => {
|
|
9297
9446
|
const config = configs.get(nodeId);
|
|
9298
9447
|
if (!config || !config.actions.onSave) {
|
|
@@ -9326,7 +9475,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
9326
9475
|
},
|
|
9327
9476
|
[configs, updateConfigState]
|
|
9328
9477
|
);
|
|
9329
|
-
const resetConfig = (0,
|
|
9478
|
+
const resetConfig = (0, import_react25.useCallback)(
|
|
9330
9479
|
async (nodeId) => {
|
|
9331
9480
|
const config = configs.get(nodeId);
|
|
9332
9481
|
if (!config) {
|
|
@@ -9356,7 +9505,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
9356
9505
|
},
|
|
9357
9506
|
[configs, updateConfig, updateConfigState]
|
|
9358
9507
|
);
|
|
9359
|
-
const cancelConfig = (0,
|
|
9508
|
+
const cancelConfig = (0, import_react25.useCallback)(
|
|
9360
9509
|
(nodeId) => {
|
|
9361
9510
|
const config = configs.get(nodeId);
|
|
9362
9511
|
if (config?.actions.onCancel) {
|
|
@@ -9365,7 +9514,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
9365
9514
|
},
|
|
9366
9515
|
[configs]
|
|
9367
9516
|
);
|
|
9368
|
-
const validateConfig = (0,
|
|
9517
|
+
const validateConfig = (0, import_react25.useCallback)(
|
|
9369
9518
|
(nodeId) => {
|
|
9370
9519
|
const config = configs.get(nodeId);
|
|
9371
9520
|
if (!config) {
|
|
@@ -9407,21 +9556,21 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
9407
9556
|
},
|
|
9408
9557
|
[configs, updateConfigState]
|
|
9409
9558
|
);
|
|
9410
|
-
const setConfig = (0,
|
|
9559
|
+
const setConfig = (0, import_react25.useCallback)((config) => {
|
|
9411
9560
|
setConfigs((prev) => {
|
|
9412
9561
|
const newMap = new Map(prev);
|
|
9413
9562
|
newMap.set(config.nodeId, config);
|
|
9414
9563
|
return newMap;
|
|
9415
9564
|
});
|
|
9416
9565
|
}, []);
|
|
9417
|
-
const removeConfig = (0,
|
|
9566
|
+
const removeConfig = (0, import_react25.useCallback)((nodeId) => {
|
|
9418
9567
|
setConfigs((prev) => {
|
|
9419
9568
|
const newMap = new Map(prev);
|
|
9420
9569
|
newMap.delete(nodeId);
|
|
9421
9570
|
return newMap;
|
|
9422
9571
|
});
|
|
9423
9572
|
}, []);
|
|
9424
|
-
const clearConfigs = (0,
|
|
9573
|
+
const clearConfigs = (0, import_react25.useCallback)(() => {
|
|
9425
9574
|
setConfigs(/* @__PURE__ */ new Map());
|
|
9426
9575
|
}, []);
|
|
9427
9576
|
return {
|
|
@@ -9443,8 +9592,8 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
9443
9592
|
}
|
|
9444
9593
|
|
|
9445
9594
|
// src/components/DeviceConfigPanel/DeviceConfigPanel.tsx
|
|
9446
|
-
var
|
|
9447
|
-
var
|
|
9595
|
+
var import_react26 = __toESM(require("react"), 1);
|
|
9596
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
9448
9597
|
function DeviceConfigPanelImpl({
|
|
9449
9598
|
binding,
|
|
9450
9599
|
onClose,
|
|
@@ -9463,7 +9612,7 @@ function DeviceConfigPanelImpl({
|
|
|
9463
9612
|
showBuiltInToast = true,
|
|
9464
9613
|
embedded = false
|
|
9465
9614
|
}) {
|
|
9466
|
-
const [localValues, setLocalValues] = (0,
|
|
9615
|
+
const [localValues, setLocalValues] = (0, import_react26.useState)(() => {
|
|
9467
9616
|
if (binding) {
|
|
9468
9617
|
const values = {};
|
|
9469
9618
|
binding.parameters.forEach((param) => {
|
|
@@ -9473,7 +9622,7 @@ function DeviceConfigPanelImpl({
|
|
|
9473
9622
|
}
|
|
9474
9623
|
return {};
|
|
9475
9624
|
});
|
|
9476
|
-
const [collapsedSections, setCollapsedSections] = (0,
|
|
9625
|
+
const [collapsedSections, setCollapsedSections] = (0, import_react26.useState)(() => {
|
|
9477
9626
|
const collapsed = /* @__PURE__ */ new Set();
|
|
9478
9627
|
if (binding?.sections) {
|
|
9479
9628
|
binding.sections.forEach((section) => {
|
|
@@ -9484,9 +9633,9 @@ function DeviceConfigPanelImpl({
|
|
|
9484
9633
|
}
|
|
9485
9634
|
return collapsed;
|
|
9486
9635
|
});
|
|
9487
|
-
const [showToast, setShowToast] = (0,
|
|
9488
|
-
const [bindingId, setBindingId] = (0,
|
|
9489
|
-
const lastResultTimestampRef = (0,
|
|
9636
|
+
const [showToast, setShowToast] = (0, import_react26.useState)(true);
|
|
9637
|
+
const [bindingId, setBindingId] = (0, import_react26.useState)(binding?.nodeId || null);
|
|
9638
|
+
const lastResultTimestampRef = (0, import_react26.useRef)(0);
|
|
9490
9639
|
if (binding && binding.nodeId !== bindingId) {
|
|
9491
9640
|
const values = {};
|
|
9492
9641
|
binding.parameters.forEach((param) => {
|
|
@@ -9502,7 +9651,7 @@ function DeviceConfigPanelImpl({
|
|
|
9502
9651
|
setCollapsedSections(collapsed);
|
|
9503
9652
|
setBindingId(binding.nodeId);
|
|
9504
9653
|
}
|
|
9505
|
-
(0,
|
|
9654
|
+
(0, import_react26.useEffect)(() => {
|
|
9506
9655
|
const currentTimestamp = binding?.state.lastSaved || 0;
|
|
9507
9656
|
if (binding?.state.lastSaveResult && currentTimestamp !== lastResultTimestampRef.current) {
|
|
9508
9657
|
lastResultTimestampRef.current = currentTimestamp;
|
|
@@ -9519,7 +9668,7 @@ function DeviceConfigPanelImpl({
|
|
|
9519
9668
|
};
|
|
9520
9669
|
}
|
|
9521
9670
|
}, [binding?.state.lastSaveResult, binding?.state.lastSaved, toastDuration]);
|
|
9522
|
-
const parametersBySection = (0,
|
|
9671
|
+
const parametersBySection = (0, import_react26.useMemo)(() => {
|
|
9523
9672
|
if (!binding) return { _unsectioned: [] };
|
|
9524
9673
|
const groups = { _unsectioned: [] };
|
|
9525
9674
|
binding.parameters.forEach((param) => {
|
|
@@ -9534,7 +9683,7 @@ function DeviceConfigPanelImpl({
|
|
|
9534
9683
|
});
|
|
9535
9684
|
return groups;
|
|
9536
9685
|
}, [binding]);
|
|
9537
|
-
const sortedSections = (0,
|
|
9686
|
+
const sortedSections = (0, import_react26.useMemo)(() => {
|
|
9538
9687
|
if (!binding?.sections) return [];
|
|
9539
9688
|
return [...binding.sections].sort((a, b) => (a.order || 0) - (b.order || 0));
|
|
9540
9689
|
}, [binding]);
|
|
@@ -9610,14 +9759,14 @@ function DeviceConfigPanelImpl({
|
|
|
9610
9759
|
const value = localValues[param.id];
|
|
9611
9760
|
const error = binding.state.errors?.[param.id];
|
|
9612
9761
|
const isDisabled = param.readOnly || param.enabled === false;
|
|
9613
|
-
return /* @__PURE__ */ (0,
|
|
9762
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
9614
9763
|
"div",
|
|
9615
9764
|
{
|
|
9616
9765
|
style: {
|
|
9617
9766
|
marginBottom: spacing.marginBottom
|
|
9618
9767
|
},
|
|
9619
9768
|
children: [
|
|
9620
|
-
/* @__PURE__ */ (0,
|
|
9769
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
9621
9770
|
"label",
|
|
9622
9771
|
{
|
|
9623
9772
|
style: {
|
|
@@ -9632,13 +9781,13 @@ function DeviceConfigPanelImpl({
|
|
|
9632
9781
|
},
|
|
9633
9782
|
children: [
|
|
9634
9783
|
param.label,
|
|
9635
|
-
param.required && /* @__PURE__ */ (0,
|
|
9636
|
-
param.unit && /* @__PURE__ */ (0,
|
|
9784
|
+
param.required && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { style: { color: errorColor }, children: " *" }),
|
|
9785
|
+
param.unit && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("span", { style: { color: mutedTextColor, fontWeight: "normal" }, children: [
|
|
9637
9786
|
" (",
|
|
9638
9787
|
param.unit,
|
|
9639
9788
|
")"
|
|
9640
9789
|
] }),
|
|
9641
|
-
param.forced?.active && /* @__PURE__ */ (0,
|
|
9790
|
+
param.forced?.active && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9642
9791
|
"span",
|
|
9643
9792
|
{
|
|
9644
9793
|
"aria-label": "Forced",
|
|
@@ -9665,7 +9814,7 @@ function DeviceConfigPanelImpl({
|
|
|
9665
9814
|
]
|
|
9666
9815
|
}
|
|
9667
9816
|
),
|
|
9668
|
-
param.forced?.active && param.forced.realValue !== void 0 && /* @__PURE__ */ (0,
|
|
9817
|
+
param.forced?.active && param.forced.realValue !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
9669
9818
|
"div",
|
|
9670
9819
|
{
|
|
9671
9820
|
style: {
|
|
@@ -9683,7 +9832,7 @@ function DeviceConfigPanelImpl({
|
|
|
9683
9832
|
]
|
|
9684
9833
|
}
|
|
9685
9834
|
),
|
|
9686
|
-
param.description && /* @__PURE__ */ (0,
|
|
9835
|
+
param.description && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9687
9836
|
"div",
|
|
9688
9837
|
{
|
|
9689
9838
|
style: {
|
|
@@ -9695,7 +9844,7 @@ function DeviceConfigPanelImpl({
|
|
|
9695
9844
|
children: param.description
|
|
9696
9845
|
}
|
|
9697
9846
|
),
|
|
9698
|
-
param.type === "number" && /* @__PURE__ */ (0,
|
|
9847
|
+
param.type === "number" && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9699
9848
|
"input",
|
|
9700
9849
|
{
|
|
9701
9850
|
type: "number",
|
|
@@ -9719,7 +9868,7 @@ function DeviceConfigPanelImpl({
|
|
|
9719
9868
|
}
|
|
9720
9869
|
}
|
|
9721
9870
|
),
|
|
9722
|
-
param.type === "string" && /* @__PURE__ */ (0,
|
|
9871
|
+
param.type === "string" && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9723
9872
|
"input",
|
|
9724
9873
|
{
|
|
9725
9874
|
type: "text",
|
|
@@ -9740,7 +9889,7 @@ function DeviceConfigPanelImpl({
|
|
|
9740
9889
|
}
|
|
9741
9890
|
}
|
|
9742
9891
|
),
|
|
9743
|
-
param.type === "boolean" && /* @__PURE__ */ (0,
|
|
9892
|
+
param.type === "boolean" && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
9744
9893
|
"label",
|
|
9745
9894
|
{
|
|
9746
9895
|
style: {
|
|
@@ -9750,7 +9899,7 @@ function DeviceConfigPanelImpl({
|
|
|
9750
9899
|
cursor: isDisabled ? "not-allowed" : "pointer"
|
|
9751
9900
|
},
|
|
9752
9901
|
children: [
|
|
9753
|
-
/* @__PURE__ */ (0,
|
|
9902
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9754
9903
|
"input",
|
|
9755
9904
|
{
|
|
9756
9905
|
type: "checkbox",
|
|
@@ -9764,11 +9913,11 @@ function DeviceConfigPanelImpl({
|
|
|
9764
9913
|
}
|
|
9765
9914
|
}
|
|
9766
9915
|
),
|
|
9767
|
-
/* @__PURE__ */ (0,
|
|
9916
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { style: { fontSize: `${fontSize.value}px`, color: textColor }, children: value ? "Enabled" : "Disabled" })
|
|
9768
9917
|
]
|
|
9769
9918
|
}
|
|
9770
9919
|
),
|
|
9771
|
-
param.type === "select" && /* @__PURE__ */ (0,
|
|
9920
|
+
param.type === "select" && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9772
9921
|
"select",
|
|
9773
9922
|
{
|
|
9774
9923
|
value: value ?? "",
|
|
@@ -9786,10 +9935,10 @@ function DeviceConfigPanelImpl({
|
|
|
9786
9935
|
borderRadius: "2px",
|
|
9787
9936
|
outline: "none"
|
|
9788
9937
|
},
|
|
9789
|
-
children: param.options?.map((option) => /* @__PURE__ */ (0,
|
|
9938
|
+
children: param.options?.map((option) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("option", { value: option.value, children: option.label }, option.value))
|
|
9790
9939
|
}
|
|
9791
9940
|
),
|
|
9792
|
-
error && /* @__PURE__ */ (0,
|
|
9941
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9793
9942
|
"div",
|
|
9794
9943
|
{
|
|
9795
9944
|
style: {
|
|
@@ -9809,7 +9958,7 @@ function DeviceConfigPanelImpl({
|
|
|
9809
9958
|
const renderSection = (section) => {
|
|
9810
9959
|
const params = parametersBySection[section.id] || [];
|
|
9811
9960
|
const isCollapsed = collapsedSections.has(section.id);
|
|
9812
|
-
return /* @__PURE__ */ (0,
|
|
9961
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
9813
9962
|
"div",
|
|
9814
9963
|
{
|
|
9815
9964
|
style: {
|
|
@@ -9819,7 +9968,7 @@ function DeviceConfigPanelImpl({
|
|
|
9819
9968
|
backgroundColor: surfaceColor
|
|
9820
9969
|
},
|
|
9821
9970
|
children: [
|
|
9822
|
-
/* @__PURE__ */ (0,
|
|
9971
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
9823
9972
|
"div",
|
|
9824
9973
|
{
|
|
9825
9974
|
onClick: () => section.collapsible && toggleSection(section.id),
|
|
@@ -9832,8 +9981,8 @@ function DeviceConfigPanelImpl({
|
|
|
9832
9981
|
alignItems: "center"
|
|
9833
9982
|
},
|
|
9834
9983
|
children: [
|
|
9835
|
-
/* @__PURE__ */ (0,
|
|
9836
|
-
/* @__PURE__ */ (0,
|
|
9984
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { children: [
|
|
9985
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
9837
9986
|
"div",
|
|
9838
9987
|
{
|
|
9839
9988
|
style: {
|
|
@@ -9845,12 +9994,12 @@ function DeviceConfigPanelImpl({
|
|
|
9845
9994
|
letterSpacing: "0.5px"
|
|
9846
9995
|
},
|
|
9847
9996
|
children: [
|
|
9848
|
-
section.icon && /* @__PURE__ */ (0,
|
|
9997
|
+
section.icon && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { style: { marginRight: "8px" }, children: section.icon }),
|
|
9849
9998
|
section.title
|
|
9850
9999
|
]
|
|
9851
10000
|
}
|
|
9852
10001
|
),
|
|
9853
|
-
section.description && /* @__PURE__ */ (0,
|
|
10002
|
+
section.description && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9854
10003
|
"div",
|
|
9855
10004
|
{
|
|
9856
10005
|
style: {
|
|
@@ -9863,11 +10012,11 @@ function DeviceConfigPanelImpl({
|
|
|
9863
10012
|
}
|
|
9864
10013
|
)
|
|
9865
10014
|
] }),
|
|
9866
|
-
section.collapsible && /* @__PURE__ */ (0,
|
|
10015
|
+
section.collapsible && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { style: { fontSize: "16px", color: mutedTextColor }, children: isCollapsed ? "\u25BC" : "\u25B2" })
|
|
9867
10016
|
]
|
|
9868
10017
|
}
|
|
9869
10018
|
),
|
|
9870
|
-
!isCollapsed && /* @__PURE__ */ (0,
|
|
10019
|
+
!isCollapsed && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: { padding: spacing.padding }, children: params.map(renderParameter) })
|
|
9871
10020
|
]
|
|
9872
10021
|
},
|
|
9873
10022
|
section.id
|
|
@@ -9926,9 +10075,9 @@ function DeviceConfigPanelImpl({
|
|
|
9926
10075
|
const showSave = binding.display?.showSave !== false && binding.actions.onSave;
|
|
9927
10076
|
const showReset = binding.display?.showReset !== false && binding.actions.onReset;
|
|
9928
10077
|
const showCancel = binding.display?.showCancel !== false;
|
|
9929
|
-
return /* @__PURE__ */ (0,
|
|
9930
|
-
/* @__PURE__ */ (0,
|
|
9931
|
-
/* @__PURE__ */ (0,
|
|
10078
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
|
|
10079
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { style: panelStyle, className: binding.display?.className, children: [
|
|
10080
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
9932
10081
|
"div",
|
|
9933
10082
|
{
|
|
9934
10083
|
style: {
|
|
@@ -9940,8 +10089,8 @@ function DeviceConfigPanelImpl({
|
|
|
9940
10089
|
borderBottom: `2px solid ${borderColor}`
|
|
9941
10090
|
},
|
|
9942
10091
|
children: [
|
|
9943
|
-
/* @__PURE__ */ (0,
|
|
9944
|
-
/* @__PURE__ */ (0,
|
|
10092
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { children: [
|
|
10093
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9945
10094
|
"h3",
|
|
9946
10095
|
{
|
|
9947
10096
|
style: {
|
|
@@ -9961,7 +10110,7 @@ function DeviceConfigPanelImpl({
|
|
|
9961
10110
|
children: titleText.length > 25 ? titleText.slice(0, 25) + "..." : titleText
|
|
9962
10111
|
}
|
|
9963
10112
|
),
|
|
9964
|
-
binding.display?.subtitle && /* @__PURE__ */ (0,
|
|
10113
|
+
binding.display?.subtitle && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9965
10114
|
"div",
|
|
9966
10115
|
{
|
|
9967
10116
|
style: {
|
|
@@ -9974,8 +10123,8 @@ function DeviceConfigPanelImpl({
|
|
|
9974
10123
|
}
|
|
9975
10124
|
)
|
|
9976
10125
|
] }),
|
|
9977
|
-
/* @__PURE__ */ (0,
|
|
9978
|
-
showControlsButton && onOpenControls && /* @__PURE__ */ (0,
|
|
10126
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { style: { display: "flex", gap: "8px" }, children: [
|
|
10127
|
+
showControlsButton && onOpenControls && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9979
10128
|
"button",
|
|
9980
10129
|
{
|
|
9981
10130
|
onClick: onOpenControls,
|
|
@@ -9998,7 +10147,7 @@ function DeviceConfigPanelImpl({
|
|
|
9998
10147
|
children: "CTRL"
|
|
9999
10148
|
}
|
|
10000
10149
|
),
|
|
10001
|
-
onUndock && /* @__PURE__ */ (0,
|
|
10150
|
+
onUndock && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
10002
10151
|
"button",
|
|
10003
10152
|
{
|
|
10004
10153
|
onClick: onUndock,
|
|
@@ -10019,7 +10168,7 @@ function DeviceConfigPanelImpl({
|
|
|
10019
10168
|
children: undockIcon
|
|
10020
10169
|
}
|
|
10021
10170
|
),
|
|
10022
|
-
/* @__PURE__ */ (0,
|
|
10171
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
10023
10172
|
"button",
|
|
10024
10173
|
{
|
|
10025
10174
|
onClick: onClose,
|
|
@@ -10042,7 +10191,7 @@ function DeviceConfigPanelImpl({
|
|
|
10042
10191
|
]
|
|
10043
10192
|
}
|
|
10044
10193
|
),
|
|
10045
|
-
binding.state.isDirty && /* @__PURE__ */ (0,
|
|
10194
|
+
binding.state.isDirty && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
10046
10195
|
"div",
|
|
10047
10196
|
{
|
|
10048
10197
|
style: {
|
|
@@ -10057,11 +10206,11 @@ function DeviceConfigPanelImpl({
|
|
|
10057
10206
|
children: "Unsaved changes"
|
|
10058
10207
|
}
|
|
10059
10208
|
),
|
|
10060
|
-
/* @__PURE__ */ (0,
|
|
10209
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: { flex: 1, overflowY: "auto", marginBottom: spacing.marginBottom }, children: sortedSections.length > 0 ? sortedSections.map(renderSection) : (
|
|
10061
10210
|
/* Render unsectioned parameters */
|
|
10062
|
-
/* @__PURE__ */ (0,
|
|
10211
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { children: parametersBySection._unsectioned?.map(renderParameter) })
|
|
10063
10212
|
) }),
|
|
10064
|
-
/* @__PURE__ */ (0,
|
|
10213
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
10065
10214
|
"div",
|
|
10066
10215
|
{
|
|
10067
10216
|
style: {
|
|
@@ -10072,7 +10221,7 @@ function DeviceConfigPanelImpl({
|
|
|
10072
10221
|
flexWrap: "wrap"
|
|
10073
10222
|
},
|
|
10074
10223
|
children: [
|
|
10075
|
-
showApply && /* @__PURE__ */ (0,
|
|
10224
|
+
showApply && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
10076
10225
|
"button",
|
|
10077
10226
|
{
|
|
10078
10227
|
onClick: handleApply,
|
|
@@ -10095,7 +10244,7 @@ function DeviceConfigPanelImpl({
|
|
|
10095
10244
|
children: binding.state.isSaving ? "Applying..." : "Apply"
|
|
10096
10245
|
}
|
|
10097
10246
|
),
|
|
10098
|
-
showSave && /* @__PURE__ */ (0,
|
|
10247
|
+
showSave && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
10099
10248
|
"button",
|
|
10100
10249
|
{
|
|
10101
10250
|
onClick: handleSave,
|
|
@@ -10118,7 +10267,7 @@ function DeviceConfigPanelImpl({
|
|
|
10118
10267
|
children: binding.state.isSaving ? "Saving..." : "Save"
|
|
10119
10268
|
}
|
|
10120
10269
|
),
|
|
10121
|
-
showReset && /* @__PURE__ */ (0,
|
|
10270
|
+
showReset && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
10122
10271
|
"button",
|
|
10123
10272
|
{
|
|
10124
10273
|
onClick: handleReset,
|
|
@@ -10141,7 +10290,7 @@ function DeviceConfigPanelImpl({
|
|
|
10141
10290
|
children: "Reset"
|
|
10142
10291
|
}
|
|
10143
10292
|
),
|
|
10144
|
-
showCancel && /* @__PURE__ */ (0,
|
|
10293
|
+
showCancel && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
10145
10294
|
"button",
|
|
10146
10295
|
{
|
|
10147
10296
|
onClick: handleCancel,
|
|
@@ -10168,7 +10317,7 @@ function DeviceConfigPanelImpl({
|
|
|
10168
10317
|
}
|
|
10169
10318
|
)
|
|
10170
10319
|
] }),
|
|
10171
|
-
binding.state.lastSaveResult && showToast && showBuiltInToast && /* @__PURE__ */ (0,
|
|
10320
|
+
binding.state.lastSaveResult && showToast && showBuiltInToast && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
10172
10321
|
"div",
|
|
10173
10322
|
{
|
|
10174
10323
|
style: {
|
|
@@ -10190,10 +10339,10 @@ function DeviceConfigPanelImpl({
|
|
|
10190
10339
|
)
|
|
10191
10340
|
] });
|
|
10192
10341
|
}
|
|
10193
|
-
var DeviceConfigPanel =
|
|
10342
|
+
var DeviceConfigPanel = import_react26.default.memo(DeviceConfigPanelImpl);
|
|
10194
10343
|
|
|
10195
10344
|
// src/diagram/hooks/useSimulation.ts
|
|
10196
|
-
var
|
|
10345
|
+
var import_react27 = require("react");
|
|
10197
10346
|
function useSimulation(telemetry, updateTelemetryBatch, options = {}) {
|
|
10198
10347
|
const {
|
|
10199
10348
|
interval = 2e3,
|
|
@@ -10204,7 +10353,7 @@ function useSimulation(telemetry, updateTelemetryBatch, options = {}) {
|
|
|
10204
10353
|
historyLength = 10,
|
|
10205
10354
|
generateValue
|
|
10206
10355
|
} = options;
|
|
10207
|
-
(0,
|
|
10356
|
+
(0, import_react27.useEffect)(() => {
|
|
10208
10357
|
if (!enabled) return;
|
|
10209
10358
|
const intervalId = setInterval(() => {
|
|
10210
10359
|
const updates = [];
|
|
@@ -10274,6 +10423,8 @@ function useSimulation(telemetry, updateTelemetryBatch, options = {}) {
|
|
|
10274
10423
|
FooterPanel,
|
|
10275
10424
|
FullscreenContainer,
|
|
10276
10425
|
FullscreenWorkspace,
|
|
10426
|
+
ISA_UNKNOWN,
|
|
10427
|
+
ISA_UNKNOWN_DARK,
|
|
10277
10428
|
LeftPanel,
|
|
10278
10429
|
LeftToggleButton,
|
|
10279
10430
|
LegacyValueEntry,
|
|
@@ -10296,8 +10447,9 @@ function useSimulation(telemetry, updateTelemetryBatch, options = {}) {
|
|
|
10296
10447
|
ThemeProvider,
|
|
10297
10448
|
ThemeToggle,
|
|
10298
10449
|
TrendLine,
|
|
10299
|
-
|
|
10300
|
-
|
|
10450
|
+
UNKNOWN_GLYPH_RING_DASH,
|
|
10451
|
+
UNKNOWN_STATUS_GLYPH_COLOR_VAR,
|
|
10452
|
+
UnknownStatusGlyph,
|
|
10301
10453
|
ValueEntry,
|
|
10302
10454
|
ZoomButton,
|
|
10303
10455
|
ZoomControls,
|
|
@@ -10315,6 +10467,7 @@ function useSimulation(telemetry, updateTelemetryBatch, options = {}) {
|
|
|
10315
10467
|
importDiagram,
|
|
10316
10468
|
mockSymbolLibrary,
|
|
10317
10469
|
nodeHasPort,
|
|
10470
|
+
normalizeDeviceStatus,
|
|
10318
10471
|
overlayStyles,
|
|
10319
10472
|
readAppearanceValue,
|
|
10320
10473
|
registerSymbol,
|