@procaaso/alphinity-ui-components 1.11.0 → 1.13.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 +901 -644
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +327 -92
- package/dist/index.d.ts +327 -92
- package/dist/index.js +713 -464
- 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,
|
|
@@ -85,14 +88,19 @@ __export(index_exports, {
|
|
|
85
88
|
generateRoutePoints: () => generateRoutePoints,
|
|
86
89
|
getAppearanceDefaults: () => getAppearanceDefaults,
|
|
87
90
|
getAppearanceSchema: () => getAppearanceSchema,
|
|
91
|
+
getAvailableBadgeGlyphs: () => getAvailableBadgeGlyphs,
|
|
88
92
|
getAvailableSymbols: () => getAvailableSymbols,
|
|
93
|
+
getBadgeGlyph: () => getBadgeGlyph,
|
|
89
94
|
getPortWorldPosition: () => getPortWorldPosition,
|
|
90
95
|
getSymbolDefinition: () => getSymbolDefinition,
|
|
91
96
|
importDiagram: () => importDiagram,
|
|
92
97
|
mockSymbolLibrary: () => mockSymbolLibrary,
|
|
93
98
|
nodeHasPort: () => nodeHasPort,
|
|
99
|
+
normalizeDeviceStatus: () => normalizeDeviceStatus,
|
|
94
100
|
overlayStyles: () => overlayStyles,
|
|
95
101
|
readAppearanceValue: () => readAppearanceValue,
|
|
102
|
+
registerBadgeGlyph: () => registerBadgeGlyph,
|
|
103
|
+
registerBadgeGlyphs: () => registerBadgeGlyphs,
|
|
96
104
|
registerSymbol: () => registerSymbol,
|
|
97
105
|
registerSymbols: () => registerSymbols,
|
|
98
106
|
resolvePresetColor: () => resolvePresetColor,
|
|
@@ -382,6 +390,16 @@ var ValueEntry = ({
|
|
|
382
390
|
var import_react3 = require("react");
|
|
383
391
|
|
|
384
392
|
// src/theme/statusColors.ts
|
|
393
|
+
var ISA_UNKNOWN = {
|
|
394
|
+
fg: "#4f4f8a",
|
|
395
|
+
bg: "#ebebf5",
|
|
396
|
+
border: "#8f8fc2"
|
|
397
|
+
};
|
|
398
|
+
var ISA_UNKNOWN_DARK = {
|
|
399
|
+
fg: "#b9bbdb",
|
|
400
|
+
bg: "#23263a",
|
|
401
|
+
border: "#6f74a3"
|
|
402
|
+
};
|
|
385
403
|
var DEFAULT_STATUS_COLORS = {
|
|
386
404
|
normal: { fill: "#888888", stroke: "#6b6b6b", bg: "#888888", text: "#ffffff", border: "#6b6b6b" },
|
|
387
405
|
warning: { fill: "#f59e0b", stroke: "#d97706", bg: "#FFD700", text: "#000000", border: "#d97706" },
|
|
@@ -389,7 +407,8 @@ var DEFAULT_STATUS_COLORS = {
|
|
|
389
407
|
fault: { fill: "#dc2626", stroke: "#b91c1c", bg: "#FF0000", text: "#ffffff", border: "#b91c1c" },
|
|
390
408
|
off: { fill: "#edeeef", stroke: "#000000", bg: "#666666", text: "#ffffff", border: "#4b5563" },
|
|
391
409
|
starting: { fill: "#90EE90", stroke: "#22c55e", bg: "#90EE90", text: "#000000", border: "#22c55e" },
|
|
392
|
-
stopping: { fill: "#FFD700", stroke: "#d97706", bg: "#FFD700", text: "#000000", border: "#d97706" }
|
|
410
|
+
stopping: { fill: "#FFD700", stroke: "#d97706", bg: "#FFD700", text: "#000000", border: "#d97706" },
|
|
411
|
+
unknown: { fill: ISA_UNKNOWN.bg, stroke: ISA_UNKNOWN.border, bg: ISA_UNKNOWN.bg, text: ISA_UNKNOWN.fg, border: ISA_UNKNOWN.border }
|
|
393
412
|
};
|
|
394
413
|
var FORCED_MARK_COLOR = {
|
|
395
414
|
fill: "#ede9fe",
|
|
@@ -398,27 +417,16 @@ var FORCED_MARK_COLOR = {
|
|
|
398
417
|
text: "#5b21b6",
|
|
399
418
|
border: "#7c3aed"
|
|
400
419
|
};
|
|
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
420
|
var STATUS_ALIASES = {
|
|
416
421
|
running: "normal",
|
|
417
422
|
stopped: "off"
|
|
418
423
|
};
|
|
419
|
-
function
|
|
424
|
+
function normalizeDeviceStatus(status) {
|
|
420
425
|
const raw = (status || "off").toLowerCase();
|
|
421
|
-
|
|
426
|
+
return STATUS_ALIASES[raw] ?? raw;
|
|
427
|
+
}
|
|
428
|
+
function resolveStatusColor(status, customMap) {
|
|
429
|
+
const key = normalizeDeviceStatus(status);
|
|
422
430
|
const defaults = DEFAULT_STATUS_COLORS[key] ?? DEFAULT_STATUS_COLORS.off;
|
|
423
431
|
const overrides = customMap?.[key];
|
|
424
432
|
if (!overrides) return defaults;
|
|
@@ -858,7 +866,79 @@ var ControlPanel = ({
|
|
|
858
866
|
};
|
|
859
867
|
|
|
860
868
|
// src/components/StatusIndicator/StatusIndicator.tsx
|
|
869
|
+
var import_react5 = __toESM(require("react"), 1);
|
|
870
|
+
|
|
871
|
+
// src/theme/unknownStatusGlyph.tsx
|
|
861
872
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
873
|
+
var UNKNOWN_STATUS_GLYPH_COLOR_VAR = "--ui-status-indicator-unknown-glyph-color";
|
|
874
|
+
var UNKNOWN_GLYPH_STROKE_WEIGHTS = {
|
|
875
|
+
small: { ring: 4.5, ringDash: "7 6", mark: 5, dot: 2.9 },
|
|
876
|
+
medium: { ring: 4, ringDash: "6.5 5.5", mark: 4.5, dot: 2.7 },
|
|
877
|
+
large: { ring: 3.5, ringDash: "6.5 5.5", mark: 4, dot: 2.5 }
|
|
878
|
+
};
|
|
879
|
+
var UNKNOWN_GLYPH_RING_DASH = UNKNOWN_GLYPH_STROKE_WEIGHTS.medium.ringDash;
|
|
880
|
+
var UNKNOWN_GLYPH_FILL_STYLE = {
|
|
881
|
+
position: "absolute",
|
|
882
|
+
inset: 0,
|
|
883
|
+
width: "100%",
|
|
884
|
+
height: "100%"
|
|
885
|
+
};
|
|
886
|
+
function unknownGlyphHostStyle(isUnknown, style) {
|
|
887
|
+
return isUnknown ? { position: "relative", ...style } : style;
|
|
888
|
+
}
|
|
889
|
+
function UnknownStatusGlyph({
|
|
890
|
+
size = "medium",
|
|
891
|
+
counterRotate = false,
|
|
892
|
+
style,
|
|
893
|
+
...rest
|
|
894
|
+
}) {
|
|
895
|
+
const weights = UNKNOWN_GLYPH_STROKE_WEIGHTS[size];
|
|
896
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
897
|
+
"svg",
|
|
898
|
+
{
|
|
899
|
+
viewBox: "0 0 48 48",
|
|
900
|
+
"aria-hidden": "true",
|
|
901
|
+
focusable: "false",
|
|
902
|
+
style: {
|
|
903
|
+
display: "block",
|
|
904
|
+
color: `var(${UNKNOWN_STATUS_GLYPH_COLOR_VAR}, currentColor)`,
|
|
905
|
+
transform: counterRotate ? "rotate(-45deg)" : void 0,
|
|
906
|
+
...style
|
|
907
|
+
},
|
|
908
|
+
...rest,
|
|
909
|
+
children: [
|
|
910
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
911
|
+
"circle",
|
|
912
|
+
{
|
|
913
|
+
cx: 24,
|
|
914
|
+
cy: 24,
|
|
915
|
+
r: 20,
|
|
916
|
+
fill: "none",
|
|
917
|
+
stroke: "currentColor",
|
|
918
|
+
strokeDasharray: weights.ringDash,
|
|
919
|
+
strokeLinecap: "round",
|
|
920
|
+
strokeWidth: weights.ring
|
|
921
|
+
}
|
|
922
|
+
),
|
|
923
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
924
|
+
"path",
|
|
925
|
+
{
|
|
926
|
+
d: "M18.4 18.6a5.8 5.8 0 1 1 6.4 8.1v3.1",
|
|
927
|
+
fill: "none",
|
|
928
|
+
stroke: "currentColor",
|
|
929
|
+
strokeLinecap: "round",
|
|
930
|
+
strokeLinejoin: "round",
|
|
931
|
+
strokeWidth: weights.mark
|
|
932
|
+
}
|
|
933
|
+
),
|
|
934
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("circle", { cx: 24.6, cy: 35.4, r: weights.dot, fill: "currentColor" })
|
|
935
|
+
]
|
|
936
|
+
}
|
|
937
|
+
);
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
// src/components/StatusIndicator/StatusIndicator.tsx
|
|
941
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
862
942
|
var getStatusDescription = (status) => {
|
|
863
943
|
switch (status) {
|
|
864
944
|
case "alarm":
|
|
@@ -873,10 +953,23 @@ var getStatusDescription = (status) => {
|
|
|
873
953
|
return "Operating normally";
|
|
874
954
|
case "off":
|
|
875
955
|
return "Equipment is off";
|
|
956
|
+
case "unknown":
|
|
957
|
+
return "Device state cannot be confirmed. Check the link or the wiring.";
|
|
876
958
|
default:
|
|
877
959
|
return "";
|
|
878
960
|
}
|
|
879
961
|
};
|
|
962
|
+
var visuallyHiddenStyle = {
|
|
963
|
+
position: "absolute",
|
|
964
|
+
width: "1px",
|
|
965
|
+
height: "1px",
|
|
966
|
+
padding: 0,
|
|
967
|
+
margin: "-1px",
|
|
968
|
+
overflow: "hidden",
|
|
969
|
+
clip: "rect(0, 0, 0, 0)",
|
|
970
|
+
whiteSpace: "nowrap",
|
|
971
|
+
border: 0
|
|
972
|
+
};
|
|
880
973
|
var StatusIndicator = ({
|
|
881
974
|
status,
|
|
882
975
|
size = "medium",
|
|
@@ -889,17 +982,25 @@ var StatusIndicator = ({
|
|
|
889
982
|
forced = false,
|
|
890
983
|
realValue,
|
|
891
984
|
className = "",
|
|
985
|
+
style,
|
|
986
|
+
"aria-describedby": consumerDescribedBy,
|
|
987
|
+
children,
|
|
892
988
|
...props
|
|
893
989
|
}) => {
|
|
990
|
+
const generatedDescriptionId = `${import_react5.default.useId()}-status-description`;
|
|
894
991
|
if (!visible) {
|
|
895
992
|
return null;
|
|
896
993
|
}
|
|
994
|
+
const describedBy = consumerDescribedBy ? `${consumerDescribedBy} ${generatedDescriptionId}` : generatedDescriptionId;
|
|
995
|
+
const description = getStatusDescription(status);
|
|
897
996
|
const baseClass = "ui-status-indicator";
|
|
898
997
|
const statusClass = status ? `ui-status-indicator--${status}` : "";
|
|
899
998
|
const sizeClass = size ? `ui-status-indicator--${size}` : "";
|
|
900
999
|
const shapeClass = shape ? `ui-status-indicator--${shape}` : "";
|
|
901
1000
|
const animationClass = animation ? `ui-status-indicator--${animation}` : "";
|
|
902
1001
|
const ledClass = led ? "ui-status-indicator--led" : "";
|
|
1002
|
+
const isUnknown = status === "unknown";
|
|
1003
|
+
const indicatorStyle = unknownGlyphHostStyle(isUnknown, style);
|
|
903
1004
|
const getContainerLayout = () => {
|
|
904
1005
|
switch (labelPosition) {
|
|
905
1006
|
case "left":
|
|
@@ -916,19 +1017,20 @@ var StatusIndicator = ({
|
|
|
916
1017
|
};
|
|
917
1018
|
const forcedClass = forced ? "ui-status-indicator--forced" : "";
|
|
918
1019
|
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,
|
|
1020
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: getContainerLayout(), children: [
|
|
1021
|
+
label && (labelPosition === "left" || labelPosition === "top") && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "ui-status-indicator-label", children: label }),
|
|
1022
|
+
hasRealValue && (labelPosition === "left" || labelPosition === "top") && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "ui-status-indicator-real-value", children: [
|
|
922
1023
|
"REAL ",
|
|
923
1024
|
realValue
|
|
924
1025
|
] }),
|
|
925
|
-
/* @__PURE__ */ (0,
|
|
926
|
-
/* @__PURE__ */ (0,
|
|
1026
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { style: { position: "relative", display: "inline-flex" }, children: [
|
|
1027
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
927
1028
|
"span",
|
|
928
1029
|
{
|
|
929
1030
|
role: "status",
|
|
930
1031
|
"aria-label": label || `Status: ${status}`,
|
|
931
|
-
"aria-description":
|
|
1032
|
+
"aria-description": description,
|
|
1033
|
+
"aria-describedby": describedBy,
|
|
932
1034
|
"data-status": status,
|
|
933
1035
|
"data-forced": forced,
|
|
934
1036
|
className: `
|
|
@@ -941,13 +1043,26 @@ var StatusIndicator = ({
|
|
|
941
1043
|
${forcedClass}
|
|
942
1044
|
${className}
|
|
943
1045
|
`.replace(/\s+/g, " ").trim(),
|
|
944
|
-
|
|
1046
|
+
style: indicatorStyle,
|
|
1047
|
+
...props,
|
|
1048
|
+
children: [
|
|
1049
|
+
isUnknown && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1050
|
+
UnknownStatusGlyph,
|
|
1051
|
+
{
|
|
1052
|
+
size,
|
|
1053
|
+
counterRotate: shape === "diamond",
|
|
1054
|
+
style: UNKNOWN_GLYPH_FILL_STYLE
|
|
1055
|
+
}
|
|
1056
|
+
),
|
|
1057
|
+
children,
|
|
1058
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { id: generatedDescriptionId, style: visuallyHiddenStyle, children: description })
|
|
1059
|
+
]
|
|
945
1060
|
}
|
|
946
1061
|
),
|
|
947
|
-
forced && /* @__PURE__ */ (0,
|
|
1062
|
+
forced && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "ui-status-indicator-forced-badge", "aria-label": "Forced", children: "F" })
|
|
948
1063
|
] }),
|
|
949
|
-
label && (labelPosition === "right" || labelPosition === "bottom") && /* @__PURE__ */ (0,
|
|
950
|
-
hasRealValue && (labelPosition === "right" || labelPosition === "bottom") && /* @__PURE__ */ (0,
|
|
1064
|
+
label && (labelPosition === "right" || labelPosition === "bottom") && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "ui-status-indicator-label", children: label }),
|
|
1065
|
+
hasRealValue && (labelPosition === "right" || labelPosition === "bottom") && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "ui-status-indicator-real-value", children: [
|
|
951
1066
|
"REAL ",
|
|
952
1067
|
realValue
|
|
953
1068
|
] })
|
|
@@ -955,7 +1070,7 @@ var StatusIndicator = ({
|
|
|
955
1070
|
};
|
|
956
1071
|
|
|
957
1072
|
// src/components/NodeControlsPanel/NodeControlsPanel.tsx
|
|
958
|
-
var
|
|
1073
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
959
1074
|
var NodeControlsPanel = ({
|
|
960
1075
|
config,
|
|
961
1076
|
onClose,
|
|
@@ -1028,8 +1143,8 @@ var NodeControlsPanel = ({
|
|
|
1028
1143
|
overflowY: "auto",
|
|
1029
1144
|
flex: 1
|
|
1030
1145
|
};
|
|
1031
|
-
return /* @__PURE__ */ (0,
|
|
1032
|
-
/* @__PURE__ */ (0,
|
|
1146
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
1147
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1033
1148
|
"div",
|
|
1034
1149
|
{
|
|
1035
1150
|
style: {
|
|
@@ -1042,16 +1157,16 @@ var NodeControlsPanel = ({
|
|
|
1042
1157
|
onClick: onClose
|
|
1043
1158
|
}
|
|
1044
1159
|
),
|
|
1045
|
-
/* @__PURE__ */ (0,
|
|
1160
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1046
1161
|
"div",
|
|
1047
1162
|
{
|
|
1048
1163
|
className: `node-controls-panel ${touchClass} ${className}`.trim(),
|
|
1049
1164
|
style: containerStyle,
|
|
1050
1165
|
...props,
|
|
1051
1166
|
children: [
|
|
1052
|
-
/* @__PURE__ */ (0,
|
|
1053
|
-
/* @__PURE__ */ (0,
|
|
1054
|
-
/* @__PURE__ */ (0,
|
|
1167
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: headerStyle, children: [
|
|
1168
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h2", { style: titleStyle, children: config.title }),
|
|
1169
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1055
1170
|
"button",
|
|
1056
1171
|
{
|
|
1057
1172
|
style: closeButtonStyle,
|
|
@@ -1069,7 +1184,7 @@ var NodeControlsPanel = ({
|
|
|
1069
1184
|
}
|
|
1070
1185
|
)
|
|
1071
1186
|
] }),
|
|
1072
|
-
/* @__PURE__ */ (0,
|
|
1187
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: contentStyle, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1073
1188
|
ControlPanel,
|
|
1074
1189
|
{
|
|
1075
1190
|
title: config.nodeId,
|
|
@@ -1098,7 +1213,7 @@ var NodeControlsPanel = ({
|
|
|
1098
1213
|
]
|
|
1099
1214
|
}
|
|
1100
1215
|
),
|
|
1101
|
-
/* @__PURE__ */ (0,
|
|
1216
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("style", { children: `
|
|
1102
1217
|
@keyframes slideUp {
|
|
1103
1218
|
from {
|
|
1104
1219
|
transform: translateY(100%);
|
|
@@ -1144,8 +1259,8 @@ var NodeControlsPanel = ({
|
|
|
1144
1259
|
};
|
|
1145
1260
|
|
|
1146
1261
|
// src/components/DeviceControlPanel/DeviceControlPanel.tsx
|
|
1147
|
-
var
|
|
1148
|
-
var
|
|
1262
|
+
var import_react6 = __toESM(require("react"), 1);
|
|
1263
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1149
1264
|
function DeviceControlPanelImpl({
|
|
1150
1265
|
binding,
|
|
1151
1266
|
onClose,
|
|
@@ -1173,11 +1288,11 @@ function DeviceControlPanelImpl({
|
|
|
1173
1288
|
showBuiltInToast = true,
|
|
1174
1289
|
embedded = false
|
|
1175
1290
|
}) {
|
|
1176
|
-
const [localParameterValues, setLocalParameterValues] = (0,
|
|
1177
|
-
const [showModeModal, setShowModeModal] = (0,
|
|
1178
|
-
const [pendingMode, setPendingMode] = (0,
|
|
1179
|
-
const [showToast, setShowToast] = (0,
|
|
1180
|
-
(0,
|
|
1291
|
+
const [localParameterValues, setLocalParameterValues] = (0, import_react6.useState)({});
|
|
1292
|
+
const [showModeModal, setShowModeModal] = (0, import_react6.useState)(false);
|
|
1293
|
+
const [pendingMode, setPendingMode] = (0, import_react6.useState)(null);
|
|
1294
|
+
const [showToast, setShowToast] = (0, import_react6.useState)(true);
|
|
1295
|
+
(0, import_react6.useEffect)(() => {
|
|
1181
1296
|
if (binding) {
|
|
1182
1297
|
const currentParams2 = binding.parameters[binding.state.currentMode] || [];
|
|
1183
1298
|
const values = {};
|
|
@@ -1187,7 +1302,7 @@ function DeviceControlPanelImpl({
|
|
|
1187
1302
|
setLocalParameterValues(values);
|
|
1188
1303
|
}
|
|
1189
1304
|
}, [binding, binding?.state.currentMode]);
|
|
1190
|
-
(0,
|
|
1305
|
+
(0, import_react6.useEffect)(() => {
|
|
1191
1306
|
if (binding?.state.lastCommandResult) {
|
|
1192
1307
|
setShowToast(true);
|
|
1193
1308
|
const timer = setTimeout(() => {
|
|
@@ -1225,6 +1340,7 @@ function DeviceControlPanelImpl({
|
|
|
1225
1340
|
const selectedColor = "#b4d0fe";
|
|
1226
1341
|
const statusEntry = resolveStatusColor(binding.state.status, binding.theme?.statusColors);
|
|
1227
1342
|
const statusColor = statusEntry.bg;
|
|
1343
|
+
const isUnknownStatus = normalizeDeviceStatus(binding.state.status) === "unknown";
|
|
1228
1344
|
const handleModeChange = (mode) => {
|
|
1229
1345
|
onModeChange?.(mode);
|
|
1230
1346
|
};
|
|
@@ -1279,9 +1395,9 @@ function DeviceControlPanelImpl({
|
|
|
1279
1395
|
...binding.display?.style
|
|
1280
1396
|
};
|
|
1281
1397
|
const titleText = binding.display?.title || binding.deviceName || binding.tag || binding.nodeId;
|
|
1282
|
-
return /* @__PURE__ */ (0,
|
|
1283
|
-
/* @__PURE__ */ (0,
|
|
1284
|
-
/* @__PURE__ */ (0,
|
|
1398
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
1399
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: panelStyle, className: binding.display?.className, children: [
|
|
1400
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1285
1401
|
"div",
|
|
1286
1402
|
{
|
|
1287
1403
|
style: {
|
|
@@ -1293,8 +1409,8 @@ function DeviceControlPanelImpl({
|
|
|
1293
1409
|
borderBottom: `2px solid ${borderColor}`
|
|
1294
1410
|
},
|
|
1295
1411
|
children: [
|
|
1296
|
-
/* @__PURE__ */ (0,
|
|
1297
|
-
/* @__PURE__ */ (0,
|
|
1412
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { children: [
|
|
1413
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1298
1414
|
"h3",
|
|
1299
1415
|
{
|
|
1300
1416
|
style: {
|
|
@@ -1314,7 +1430,7 @@ function DeviceControlPanelImpl({
|
|
|
1314
1430
|
children: titleText.length > 25 ? titleText.slice(0, 25) + "..." : titleText
|
|
1315
1431
|
}
|
|
1316
1432
|
),
|
|
1317
|
-
binding.deviceType && /* @__PURE__ */ (0,
|
|
1433
|
+
binding.deviceType && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1318
1434
|
"div",
|
|
1319
1435
|
{
|
|
1320
1436
|
style: {
|
|
@@ -1327,8 +1443,8 @@ function DeviceControlPanelImpl({
|
|
|
1327
1443
|
}
|
|
1328
1444
|
)
|
|
1329
1445
|
] }),
|
|
1330
|
-
/* @__PURE__ */ (0,
|
|
1331
|
-
showConfigButton && onOpenConfig && /* @__PURE__ */ (0,
|
|
1446
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { display: "flex", gap: "8px" }, children: [
|
|
1447
|
+
showConfigButton && onOpenConfig && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1332
1448
|
"button",
|
|
1333
1449
|
{
|
|
1334
1450
|
onClick: onOpenConfig,
|
|
@@ -1349,7 +1465,7 @@ function DeviceControlPanelImpl({
|
|
|
1349
1465
|
children: "\u2699"
|
|
1350
1466
|
}
|
|
1351
1467
|
),
|
|
1352
|
-
onUndock && /* @__PURE__ */ (0,
|
|
1468
|
+
onUndock && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1353
1469
|
"button",
|
|
1354
1470
|
{
|
|
1355
1471
|
onClick: onUndock,
|
|
@@ -1370,7 +1486,7 @@ function DeviceControlPanelImpl({
|
|
|
1370
1486
|
children: undockIcon
|
|
1371
1487
|
}
|
|
1372
1488
|
),
|
|
1373
|
-
/* @__PURE__ */ (0,
|
|
1489
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1374
1490
|
"button",
|
|
1375
1491
|
{
|
|
1376
1492
|
onClick: onClose,
|
|
@@ -1393,7 +1509,7 @@ function DeviceControlPanelImpl({
|
|
|
1393
1509
|
]
|
|
1394
1510
|
}
|
|
1395
1511
|
),
|
|
1396
|
-
binding.state.status && /* @__PURE__ */ (0,
|
|
1512
|
+
binding.state.status && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1397
1513
|
"div",
|
|
1398
1514
|
{
|
|
1399
1515
|
style: {
|
|
@@ -1407,7 +1523,7 @@ function DeviceControlPanelImpl({
|
|
|
1407
1523
|
marginBottom: spacing.marginBottom
|
|
1408
1524
|
},
|
|
1409
1525
|
children: [
|
|
1410
|
-
/* @__PURE__ */ (0,
|
|
1526
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1411
1527
|
"div",
|
|
1412
1528
|
{
|
|
1413
1529
|
style: {
|
|
@@ -1415,12 +1531,17 @@ function DeviceControlPanelImpl({
|
|
|
1415
1531
|
height: "10px",
|
|
1416
1532
|
borderRadius: "50%",
|
|
1417
1533
|
backgroundColor: statusColor,
|
|
1418
|
-
border: "1px solid #333"
|
|
1419
|
-
|
|
1534
|
+
border: "1px solid #333",
|
|
1535
|
+
// The shared helper positions this dot only while it shows
|
|
1536
|
+
// the unknown marker. The glyph then fills the dot with an
|
|
1537
|
+
// absolute inset, the same pattern StatusIndicator uses.
|
|
1538
|
+
...unknownGlyphHostStyle(isUnknownStatus)
|
|
1539
|
+
},
|
|
1540
|
+
children: isUnknownStatus && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(UnknownStatusGlyph, { size: "small", style: UNKNOWN_GLYPH_FILL_STYLE })
|
|
1420
1541
|
}
|
|
1421
1542
|
),
|
|
1422
|
-
/* @__PURE__ */ (0,
|
|
1423
|
-
/* @__PURE__ */ (0,
|
|
1543
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { flex: 1 }, children: [
|
|
1544
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1424
1545
|
"div",
|
|
1425
1546
|
{
|
|
1426
1547
|
style: {
|
|
@@ -1434,7 +1555,7 @@ function DeviceControlPanelImpl({
|
|
|
1434
1555
|
children: binding.state.status
|
|
1435
1556
|
}
|
|
1436
1557
|
),
|
|
1437
|
-
binding.state.statusMessage && /* @__PURE__ */ (0,
|
|
1558
|
+
binding.state.statusMessage && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1438
1559
|
"div",
|
|
1439
1560
|
{
|
|
1440
1561
|
style: {
|
|
@@ -1447,28 +1568,36 @@ function DeviceControlPanelImpl({
|
|
|
1447
1568
|
}
|
|
1448
1569
|
)
|
|
1449
1570
|
] }),
|
|
1450
|
-
binding.state.isRunning !== void 0 && /* @__PURE__ */ (0,
|
|
1571
|
+
binding.state.isRunning !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1451
1572
|
"div",
|
|
1452
1573
|
{
|
|
1453
1574
|
style: {
|
|
1454
1575
|
padding: "4px 10px",
|
|
1455
|
-
|
|
1456
|
-
|
|
1576
|
+
// This badge shows the last published isRunning value. It
|
|
1577
|
+
// never re-derives that value here. When status is
|
|
1578
|
+
// unknown, the value may be stale. Muted colors carry that
|
|
1579
|
+
// warning alongside the word, so color is not the only
|
|
1580
|
+
// channel and the wording is not the only channel either.
|
|
1581
|
+
backgroundColor: isUnknownStatus ? statusEntry.bg : binding.state.isRunning ? selectedColor : surfaceColor,
|
|
1582
|
+
border: `1px solid ${isUnknownStatus ? statusEntry.border : borderColor}`,
|
|
1457
1583
|
borderRadius: "2px",
|
|
1458
1584
|
fontSize: "10px",
|
|
1459
1585
|
fontWeight: 600,
|
|
1460
1586
|
fontFamily: "Arial, sans-serif",
|
|
1461
1587
|
letterSpacing: "0.5px",
|
|
1462
|
-
color: textColor
|
|
1588
|
+
color: isUnknownStatus ? statusEntry.text : textColor
|
|
1463
1589
|
},
|
|
1464
|
-
children:
|
|
1590
|
+
children: [
|
|
1591
|
+
binding.state.isRunning ? "RUNNING" : "STOPPED",
|
|
1592
|
+
isUnknownStatus && " (unconfirmed)"
|
|
1593
|
+
]
|
|
1465
1594
|
}
|
|
1466
1595
|
)
|
|
1467
1596
|
]
|
|
1468
1597
|
}
|
|
1469
1598
|
),
|
|
1470
|
-
binding.display?.showModeSelector !== false && binding.modes.length > 0 && /* @__PURE__ */ (0,
|
|
1471
|
-
/* @__PURE__ */ (0,
|
|
1599
|
+
binding.display?.showModeSelector !== false && binding.modes.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { marginBottom: "16px" }, children: [
|
|
1600
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1472
1601
|
"label",
|
|
1473
1602
|
{
|
|
1474
1603
|
style: {
|
|
@@ -1484,7 +1613,7 @@ function DeviceControlPanelImpl({
|
|
|
1484
1613
|
children: "Mode"
|
|
1485
1614
|
}
|
|
1486
1615
|
),
|
|
1487
|
-
modeSelectionStyle === "dropdown" ? /* @__PURE__ */ (0,
|
|
1616
|
+
modeSelectionStyle === "dropdown" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1488
1617
|
"select",
|
|
1489
1618
|
{
|
|
1490
1619
|
value: currentMode,
|
|
@@ -1505,10 +1634,10 @@ function DeviceControlPanelImpl({
|
|
|
1505
1634
|
paddingRight: "12px",
|
|
1506
1635
|
cursor: "pointer"
|
|
1507
1636
|
},
|
|
1508
|
-
children: binding.modes.map((mode) => /* @__PURE__ */ (0,
|
|
1637
|
+
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
1638
|
}
|
|
1510
|
-
) : modeSelectionStyle === "modal" ? /* @__PURE__ */ (0,
|
|
1511
|
-
/* @__PURE__ */ (0,
|
|
1639
|
+
) : modeSelectionStyle === "modal" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
1640
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1512
1641
|
"div",
|
|
1513
1642
|
{
|
|
1514
1643
|
onClick: () => {
|
|
@@ -1531,12 +1660,12 @@ function DeviceControlPanelImpl({
|
|
|
1531
1660
|
alignItems: "center"
|
|
1532
1661
|
},
|
|
1533
1662
|
children: [
|
|
1534
|
-
/* @__PURE__ */ (0,
|
|
1535
|
-
/* @__PURE__ */ (0,
|
|
1663
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: binding.modes.find((m) => m.value === currentMode)?.label || currentMode }),
|
|
1664
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { fontSize: "20px", marginLeft: "8px" }, children: "\u25BC" })
|
|
1536
1665
|
]
|
|
1537
1666
|
}
|
|
1538
1667
|
),
|
|
1539
|
-
showModeModal && /* @__PURE__ */ (0,
|
|
1668
|
+
showModeModal && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1540
1669
|
"div",
|
|
1541
1670
|
{
|
|
1542
1671
|
style: {
|
|
@@ -1555,7 +1684,7 @@ function DeviceControlPanelImpl({
|
|
|
1555
1684
|
setShowModeModal(false);
|
|
1556
1685
|
setPendingMode(null);
|
|
1557
1686
|
},
|
|
1558
|
-
children: /* @__PURE__ */ (0,
|
|
1687
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1559
1688
|
"div",
|
|
1560
1689
|
{
|
|
1561
1690
|
onClick: (e) => e.stopPropagation(),
|
|
@@ -1568,7 +1697,7 @@ function DeviceControlPanelImpl({
|
|
|
1568
1697
|
border: `2px solid ${borderColor}`
|
|
1569
1698
|
},
|
|
1570
1699
|
children: [
|
|
1571
|
-
/* @__PURE__ */ (0,
|
|
1700
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1572
1701
|
"h3",
|
|
1573
1702
|
{
|
|
1574
1703
|
style: {
|
|
@@ -1581,7 +1710,7 @@ function DeviceControlPanelImpl({
|
|
|
1581
1710
|
children: "Select Mode"
|
|
1582
1711
|
}
|
|
1583
1712
|
),
|
|
1584
|
-
/* @__PURE__ */ (0,
|
|
1713
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1585
1714
|
"div",
|
|
1586
1715
|
{
|
|
1587
1716
|
style: {
|
|
@@ -1595,7 +1724,7 @@ function DeviceControlPanelImpl({
|
|
|
1595
1724
|
children: binding.display?.title || binding.deviceName || binding.tag || binding.nodeId
|
|
1596
1725
|
}
|
|
1597
1726
|
),
|
|
1598
|
-
/* @__PURE__ */ (0,
|
|
1727
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1599
1728
|
"select",
|
|
1600
1729
|
{
|
|
1601
1730
|
value: pendingMode || currentMode,
|
|
@@ -1617,7 +1746,7 @@ function DeviceControlPanelImpl({
|
|
|
1617
1746
|
paddingRight: "12px",
|
|
1618
1747
|
cursor: "pointer"
|
|
1619
1748
|
},
|
|
1620
|
-
children: binding.modes.map((mode) => /* @__PURE__ */ (0,
|
|
1749
|
+
children: binding.modes.map((mode) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1621
1750
|
"option",
|
|
1622
1751
|
{
|
|
1623
1752
|
value: mode.value,
|
|
@@ -1632,7 +1761,7 @@ function DeviceControlPanelImpl({
|
|
|
1632
1761
|
const selectedMode = binding.modes.find(
|
|
1633
1762
|
(m) => m.value === (pendingMode || currentMode)
|
|
1634
1763
|
);
|
|
1635
|
-
return selectedMode?.description ? /* @__PURE__ */ (0,
|
|
1764
|
+
return selectedMode?.description ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1636
1765
|
"div",
|
|
1637
1766
|
{
|
|
1638
1767
|
style: {
|
|
@@ -1650,8 +1779,8 @@ function DeviceControlPanelImpl({
|
|
|
1650
1779
|
}
|
|
1651
1780
|
) : null;
|
|
1652
1781
|
})(),
|
|
1653
|
-
/* @__PURE__ */ (0,
|
|
1654
|
-
/* @__PURE__ */ (0,
|
|
1782
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { display: "flex", gap: "12px" }, children: [
|
|
1783
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1655
1784
|
"button",
|
|
1656
1785
|
{
|
|
1657
1786
|
onClick: () => {
|
|
@@ -1679,7 +1808,7 @@ function DeviceControlPanelImpl({
|
|
|
1679
1808
|
children: "Confirm"
|
|
1680
1809
|
}
|
|
1681
1810
|
),
|
|
1682
|
-
/* @__PURE__ */ (0,
|
|
1811
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1683
1812
|
"button",
|
|
1684
1813
|
{
|
|
1685
1814
|
onClick: () => {
|
|
@@ -1709,7 +1838,7 @@ function DeviceControlPanelImpl({
|
|
|
1709
1838
|
)
|
|
1710
1839
|
}
|
|
1711
1840
|
)
|
|
1712
|
-
] }) : /* @__PURE__ */ (0,
|
|
1841
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1713
1842
|
"div",
|
|
1714
1843
|
{
|
|
1715
1844
|
style: {
|
|
@@ -1725,7 +1854,7 @@ function DeviceControlPanelImpl({
|
|
|
1725
1854
|
children: binding.modes.map((mode) => {
|
|
1726
1855
|
const isSelected = mode.value === currentMode;
|
|
1727
1856
|
const isEnabled = mode.enabled !== false;
|
|
1728
|
-
return /* @__PURE__ */ (0,
|
|
1857
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1729
1858
|
"button",
|
|
1730
1859
|
{
|
|
1731
1860
|
onClick: () => isEnabled && handleModeChange(mode.value),
|
|
@@ -1755,8 +1884,8 @@ function DeviceControlPanelImpl({
|
|
|
1755
1884
|
}
|
|
1756
1885
|
)
|
|
1757
1886
|
] }),
|
|
1758
|
-
currentParams.length > 0 && /* @__PURE__ */ (0,
|
|
1759
|
-
/* @__PURE__ */ (0,
|
|
1887
|
+
currentParams.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { marginBottom: spacing.marginBottom }, children: [
|
|
1888
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1760
1889
|
"label",
|
|
1761
1890
|
{
|
|
1762
1891
|
style: {
|
|
@@ -1772,7 +1901,7 @@ function DeviceControlPanelImpl({
|
|
|
1772
1901
|
children: "Parameters"
|
|
1773
1902
|
}
|
|
1774
1903
|
),
|
|
1775
|
-
currentParams.map((param) => /* @__PURE__ */ (0,
|
|
1904
|
+
currentParams.map((param) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1776
1905
|
"div",
|
|
1777
1906
|
{
|
|
1778
1907
|
style: {
|
|
@@ -1783,7 +1912,7 @@ function DeviceControlPanelImpl({
|
|
|
1783
1912
|
borderRadius: "6px"
|
|
1784
1913
|
},
|
|
1785
1914
|
children: [
|
|
1786
|
-
/* @__PURE__ */ (0,
|
|
1915
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1787
1916
|
"div",
|
|
1788
1917
|
{
|
|
1789
1918
|
style: {
|
|
@@ -1792,7 +1921,7 @@ function DeviceControlPanelImpl({
|
|
|
1792
1921
|
marginBottom: spacing.gap
|
|
1793
1922
|
},
|
|
1794
1923
|
children: [
|
|
1795
|
-
/* @__PURE__ */ (0,
|
|
1924
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1796
1925
|
"span",
|
|
1797
1926
|
{
|
|
1798
1927
|
style: {
|
|
@@ -1808,7 +1937,7 @@ function DeviceControlPanelImpl({
|
|
|
1808
1937
|
},
|
|
1809
1938
|
children: [
|
|
1810
1939
|
param.label,
|
|
1811
|
-
param.forced?.active && /* @__PURE__ */ (0,
|
|
1940
|
+
param.forced?.active && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1812
1941
|
"span",
|
|
1813
1942
|
{
|
|
1814
1943
|
"aria-label": "Forced",
|
|
@@ -1831,7 +1960,7 @@ function DeviceControlPanelImpl({
|
|
|
1831
1960
|
]
|
|
1832
1961
|
}
|
|
1833
1962
|
),
|
|
1834
|
-
/* @__PURE__ */ (0,
|
|
1963
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1835
1964
|
"span",
|
|
1836
1965
|
{
|
|
1837
1966
|
style: {
|
|
@@ -1843,14 +1972,14 @@ function DeviceControlPanelImpl({
|
|
|
1843
1972
|
children: [
|
|
1844
1973
|
localParameterValues[param.id] ?? param.value,
|
|
1845
1974
|
" ",
|
|
1846
|
-
param.unit && /* @__PURE__ */ (0,
|
|
1975
|
+
param.unit && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { color: mutedTextColor, fontSize: "10px", fontWeight: 600 }, children: param.unit })
|
|
1847
1976
|
]
|
|
1848
1977
|
}
|
|
1849
1978
|
)
|
|
1850
1979
|
]
|
|
1851
1980
|
}
|
|
1852
1981
|
),
|
|
1853
|
-
param.forced?.active && param.forced.realValue !== void 0 && /* @__PURE__ */ (0,
|
|
1982
|
+
param.forced?.active && param.forced.realValue !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1854
1983
|
"div",
|
|
1855
1984
|
{
|
|
1856
1985
|
style: {
|
|
@@ -1871,7 +2000,7 @@ function DeviceControlPanelImpl({
|
|
|
1871
2000
|
]
|
|
1872
2001
|
}
|
|
1873
2002
|
),
|
|
1874
|
-
param.type === "boolean" ? /* @__PURE__ */ (0,
|
|
2003
|
+
param.type === "boolean" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1875
2004
|
"button",
|
|
1876
2005
|
{
|
|
1877
2006
|
onClick: () => {
|
|
@@ -1896,7 +2025,7 @@ function DeviceControlPanelImpl({
|
|
|
1896
2025
|
},
|
|
1897
2026
|
children: localParameterValues[param.id] ? "ON" : "OFF"
|
|
1898
2027
|
}
|
|
1899
|
-
) : param.type === "select" ? /* @__PURE__ */ (0,
|
|
2028
|
+
) : param.type === "select" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1900
2029
|
"select",
|
|
1901
2030
|
{
|
|
1902
2031
|
value: localParameterValues[param.id] || param.value,
|
|
@@ -1917,12 +2046,12 @@ function DeviceControlPanelImpl({
|
|
|
1917
2046
|
fontFamily: "monospace",
|
|
1918
2047
|
cursor: "pointer"
|
|
1919
2048
|
},
|
|
1920
|
-
children: param.options?.map((opt) => /* @__PURE__ */ (0,
|
|
2049
|
+
children: param.options?.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: opt.value, children: opt.label }, opt.value))
|
|
1921
2050
|
}
|
|
1922
2051
|
) : onParameterActivate && !param.readOnly ? (
|
|
1923
2052
|
// Tappable value: defer editing to the consumer's editor (e.g. a
|
|
1924
2053
|
// numpad dialog). Commit happens via onParameterChange.
|
|
1925
|
-
/* @__PURE__ */ (0,
|
|
2054
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1926
2055
|
"button",
|
|
1927
2056
|
{
|
|
1928
2057
|
type: "button",
|
|
@@ -1949,7 +2078,7 @@ function DeviceControlPanelImpl({
|
|
|
1949
2078
|
]
|
|
1950
2079
|
}
|
|
1951
2080
|
)
|
|
1952
|
-
) : /* @__PURE__ */ (0,
|
|
2081
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1953
2082
|
"input",
|
|
1954
2083
|
{
|
|
1955
2084
|
type: param.type === "number" ? "number" : "text",
|
|
@@ -1982,8 +2111,8 @@ function DeviceControlPanelImpl({
|
|
|
1982
2111
|
param.id
|
|
1983
2112
|
))
|
|
1984
2113
|
] }),
|
|
1985
|
-
binding.display?.showStartStop !== false && (activeCapabilities?.canStart || activeCapabilities?.canStop) && /* @__PURE__ */ (0,
|
|
1986
|
-
activeCapabilities?.canStart && /* @__PURE__ */ (0,
|
|
2114
|
+
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: [
|
|
2115
|
+
activeCapabilities?.canStart && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1987
2116
|
"button",
|
|
1988
2117
|
{
|
|
1989
2118
|
onClick: onStart,
|
|
@@ -2004,7 +2133,7 @@ function DeviceControlPanelImpl({
|
|
|
2004
2133
|
children: startPending ? "STARTING\u2026" : "START"
|
|
2005
2134
|
}
|
|
2006
2135
|
),
|
|
2007
|
-
activeCapabilities?.canStop && /* @__PURE__ */ (0,
|
|
2136
|
+
activeCapabilities?.canStop && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2008
2137
|
"button",
|
|
2009
2138
|
{
|
|
2010
2139
|
onClick: onStop,
|
|
@@ -2026,9 +2155,9 @@ function DeviceControlPanelImpl({
|
|
|
2026
2155
|
}
|
|
2027
2156
|
)
|
|
2028
2157
|
] }),
|
|
2029
|
-
activeCapabilities?.customActions && activeCapabilities.customActions.length > 0 && /* @__PURE__ */ (0,
|
|
2158
|
+
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
2159
|
const actionDisabled = action.disabled === true;
|
|
2031
|
-
return /* @__PURE__ */ (0,
|
|
2160
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
2032
2161
|
"button",
|
|
2033
2162
|
{
|
|
2034
2163
|
onClick: () => {
|
|
@@ -2054,7 +2183,7 @@ function DeviceControlPanelImpl({
|
|
|
2054
2183
|
transition: "all 0.15s"
|
|
2055
2184
|
},
|
|
2056
2185
|
children: [
|
|
2057
|
-
action.icon && /* @__PURE__ */ (0,
|
|
2186
|
+
action.icon && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { marginRight: "6px" }, children: action.icon }),
|
|
2058
2187
|
action.label
|
|
2059
2188
|
]
|
|
2060
2189
|
},
|
|
@@ -2062,7 +2191,7 @@ function DeviceControlPanelImpl({
|
|
|
2062
2191
|
);
|
|
2063
2192
|
}) })
|
|
2064
2193
|
] }),
|
|
2065
|
-
binding.state.lastCommandResult && showToast && showBuiltInToast && /* @__PURE__ */ (0,
|
|
2194
|
+
binding.state.lastCommandResult && showToast && showBuiltInToast && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2066
2195
|
"div",
|
|
2067
2196
|
{
|
|
2068
2197
|
style: {
|
|
@@ -2086,7 +2215,7 @@ function DeviceControlPanelImpl({
|
|
|
2086
2215
|
children: binding.state.lastCommandResult.message
|
|
2087
2216
|
}
|
|
2088
2217
|
),
|
|
2089
|
-
/* @__PURE__ */ (0,
|
|
2218
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("style", { children: `
|
|
2090
2219
|
@keyframes slideInToast {
|
|
2091
2220
|
from {
|
|
2092
2221
|
opacity: 0;
|
|
@@ -2118,11 +2247,11 @@ function DeviceControlPanelImpl({
|
|
|
2118
2247
|
` })
|
|
2119
2248
|
] });
|
|
2120
2249
|
}
|
|
2121
|
-
var DeviceControlPanel =
|
|
2250
|
+
var DeviceControlPanel = import_react6.default.memo(DeviceControlPanelImpl);
|
|
2122
2251
|
|
|
2123
2252
|
// src/components/NumpadDialog/NumpadDialog.tsx
|
|
2124
|
-
var
|
|
2125
|
-
var
|
|
2253
|
+
var import_react7 = require("react");
|
|
2254
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
2126
2255
|
var NumpadDialog = ({
|
|
2127
2256
|
isOpen,
|
|
2128
2257
|
onClose,
|
|
@@ -2136,24 +2265,24 @@ var NumpadDialog = ({
|
|
|
2136
2265
|
currentValue = 0,
|
|
2137
2266
|
touchOptimized = true
|
|
2138
2267
|
}) => {
|
|
2139
|
-
const [inputValue, setInputValue] = (0,
|
|
2140
|
-
const [pristine, setPristine] = (0,
|
|
2141
|
-
const dialogRef = (0,
|
|
2142
|
-
const titleId = (0,
|
|
2268
|
+
const [inputValue, setInputValue] = (0, import_react7.useState)("");
|
|
2269
|
+
const [pristine, setPristine] = (0, import_react7.useState)(true);
|
|
2270
|
+
const dialogRef = (0, import_react7.useRef)(null);
|
|
2271
|
+
const titleId = (0, import_react7.useId)();
|
|
2143
2272
|
const decimals = precision ?? 1;
|
|
2144
|
-
(0,
|
|
2273
|
+
(0, import_react7.useEffect)(() => {
|
|
2145
2274
|
if (isOpen) {
|
|
2146
2275
|
setInputValue(Number(currentValue).toFixed(decimals));
|
|
2147
2276
|
setPristine(true);
|
|
2148
2277
|
}
|
|
2149
2278
|
}, [isOpen, currentValue, decimals]);
|
|
2150
|
-
(0,
|
|
2279
|
+
(0, import_react7.useEffect)(() => {
|
|
2151
2280
|
if (!isOpen) return;
|
|
2152
2281
|
const previouslyFocused = document.activeElement;
|
|
2153
2282
|
dialogRef.current?.focus();
|
|
2154
2283
|
return () => previouslyFocused?.focus?.();
|
|
2155
2284
|
}, [isOpen]);
|
|
2156
|
-
(0,
|
|
2285
|
+
(0, import_react7.useEffect)(() => {
|
|
2157
2286
|
if (!isOpen) return;
|
|
2158
2287
|
const prevOverflow = document.body.style.overflow;
|
|
2159
2288
|
document.body.style.overflow = "hidden";
|
|
@@ -2161,13 +2290,13 @@ var NumpadDialog = ({
|
|
|
2161
2290
|
document.body.style.overflow = prevOverflow;
|
|
2162
2291
|
};
|
|
2163
2292
|
}, [isOpen]);
|
|
2164
|
-
const handleApply = (0,
|
|
2293
|
+
const handleApply = (0, import_react7.useCallback)(() => {
|
|
2165
2294
|
const n = Number(inputValue);
|
|
2166
2295
|
if (inputValue === "" || inputValue === "-" || inputValue === "." || inputValue === "-.") return;
|
|
2167
2296
|
if (isNaN(n) || n < min || n > max) return;
|
|
2168
2297
|
onApply(Number(n.toFixed(decimals)));
|
|
2169
2298
|
}, [inputValue, min, max, onApply, decimals]);
|
|
2170
|
-
const appendDigit = (0,
|
|
2299
|
+
const appendDigit = (0, import_react7.useCallback)(
|
|
2171
2300
|
(digit) => {
|
|
2172
2301
|
setInputValue((prev) => {
|
|
2173
2302
|
const base = pristine ? "" : prev;
|
|
@@ -2187,15 +2316,15 @@ var NumpadDialog = ({
|
|
|
2187
2316
|
},
|
|
2188
2317
|
[pristine, decimals]
|
|
2189
2318
|
);
|
|
2190
|
-
const handleBackspace = (0,
|
|
2319
|
+
const handleBackspace = (0, import_react7.useCallback)(() => {
|
|
2191
2320
|
setPristine(false);
|
|
2192
2321
|
setInputValue((prev) => prev.slice(0, -1));
|
|
2193
2322
|
}, []);
|
|
2194
|
-
const handleClear = (0,
|
|
2323
|
+
const handleClear = (0, import_react7.useCallback)(() => {
|
|
2195
2324
|
setPristine(false);
|
|
2196
2325
|
setInputValue("");
|
|
2197
2326
|
}, []);
|
|
2198
|
-
const handleToggleSign = (0,
|
|
2327
|
+
const handleToggleSign = (0, import_react7.useCallback)(() => {
|
|
2199
2328
|
if (min >= 0) return;
|
|
2200
2329
|
setPristine(false);
|
|
2201
2330
|
setInputValue((prev) => {
|
|
@@ -2204,8 +2333,8 @@ var NumpadDialog = ({
|
|
|
2204
2333
|
return "-" + prev;
|
|
2205
2334
|
});
|
|
2206
2335
|
}, [min]);
|
|
2207
|
-
const bsTimer = (0,
|
|
2208
|
-
const bsLongFired = (0,
|
|
2336
|
+
const bsTimer = (0, import_react7.useRef)(null);
|
|
2337
|
+
const bsLongFired = (0, import_react7.useRef)(false);
|
|
2209
2338
|
const clearBsTimer = () => {
|
|
2210
2339
|
if (bsTimer.current !== null) {
|
|
2211
2340
|
clearTimeout(bsTimer.current);
|
|
@@ -2227,8 +2356,8 @@ var NumpadDialog = ({
|
|
|
2227
2356
|
}
|
|
2228
2357
|
handleBackspace();
|
|
2229
2358
|
};
|
|
2230
|
-
(0,
|
|
2231
|
-
(0,
|
|
2359
|
+
(0, import_react7.useEffect)(() => () => clearBsTimer(), []);
|
|
2360
|
+
(0, import_react7.useEffect)(() => {
|
|
2232
2361
|
if (!isOpen) return;
|
|
2233
2362
|
const handler = (e) => {
|
|
2234
2363
|
if (e.key === "Tab") {
|
|
@@ -2326,7 +2455,7 @@ var NumpadDialog = ({
|
|
|
2326
2455
|
};
|
|
2327
2456
|
const reason = belowMin ? `Below minimum of ${min} ${unit}` : aboveMax ? `Above maximum of ${max} ${unit}` : "Type or tap to change the value";
|
|
2328
2457
|
const backspaceInGrid = min >= 0;
|
|
2329
|
-
const BackspaceButton = ({ style, label }) => /* @__PURE__ */ (0,
|
|
2458
|
+
const BackspaceButton = ({ style, label }) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2330
2459
|
"button",
|
|
2331
2460
|
{
|
|
2332
2461
|
type: "button",
|
|
@@ -2343,7 +2472,7 @@ var NumpadDialog = ({
|
|
|
2343
2472
|
);
|
|
2344
2473
|
return (
|
|
2345
2474
|
// Backdrop
|
|
2346
|
-
/* @__PURE__ */ (0,
|
|
2475
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
2347
2476
|
"div",
|
|
2348
2477
|
{
|
|
2349
2478
|
style: {
|
|
@@ -2360,14 +2489,14 @@ var NumpadDialog = ({
|
|
|
2360
2489
|
},
|
|
2361
2490
|
onClick: onClose,
|
|
2362
2491
|
children: [
|
|
2363
|
-
/* @__PURE__ */ (0,
|
|
2492
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("style", { children: `
|
|
2364
2493
|
.np-key { transition: background .1s, transform .05s; touch-action: manipulation; }
|
|
2365
2494
|
.np-key:active:not(:disabled) { background:#e2e8f0; transform: translateY(1px); }
|
|
2366
2495
|
.np-key:focus-visible, .np-action:focus-visible { outline: 3px solid #2563eb; outline-offset: 2px; }
|
|
2367
2496
|
@keyframes np-blink { 0%,49%{opacity:1} 50%,100%{opacity:0} }
|
|
2368
2497
|
.np-caret { display:inline-block; width:2px; height:1.1em; background:#2563eb; animation: np-blink 1s step-end infinite; }
|
|
2369
2498
|
` }),
|
|
2370
|
-
/* @__PURE__ */ (0,
|
|
2499
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
2371
2500
|
"div",
|
|
2372
2501
|
{
|
|
2373
2502
|
ref: dialogRef,
|
|
@@ -2388,9 +2517,9 @@ var NumpadDialog = ({
|
|
|
2388
2517
|
},
|
|
2389
2518
|
onClick: (e) => e.stopPropagation(),
|
|
2390
2519
|
children: [
|
|
2391
|
-
/* @__PURE__ */ (0,
|
|
2392
|
-
/* @__PURE__ */ (0,
|
|
2393
|
-
/* @__PURE__ */ (0,
|
|
2520
|
+
/* @__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 }) }),
|
|
2521
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { padding: 16, display: "flex", flexDirection: "column", gap: 10 }, children: [
|
|
2522
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
2394
2523
|
"div",
|
|
2395
2524
|
{
|
|
2396
2525
|
style: {
|
|
@@ -2400,24 +2529,24 @@ var NumpadDialog = ({
|
|
|
2400
2529
|
color: "#64748b"
|
|
2401
2530
|
},
|
|
2402
2531
|
children: [
|
|
2403
|
-
/* @__PURE__ */ (0,
|
|
2532
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
|
|
2404
2533
|
"Current: ",
|
|
2405
2534
|
currentValue,
|
|
2406
2535
|
" ",
|
|
2407
2536
|
unit
|
|
2408
2537
|
] }),
|
|
2409
|
-
/* @__PURE__ */ (0,
|
|
2538
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
|
|
2410
2539
|
"Range: ",
|
|
2411
|
-
/* @__PURE__ */ (0,
|
|
2540
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: limitStyle(belowMin), children: min }),
|
|
2412
2541
|
"-",
|
|
2413
|
-
/* @__PURE__ */ (0,
|
|
2542
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: limitStyle(aboveMax), children: max }),
|
|
2414
2543
|
" ",
|
|
2415
2544
|
unit
|
|
2416
2545
|
] })
|
|
2417
2546
|
]
|
|
2418
2547
|
}
|
|
2419
2548
|
),
|
|
2420
|
-
/* @__PURE__ */ (0,
|
|
2549
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
2421
2550
|
"div",
|
|
2422
2551
|
{
|
|
2423
2552
|
"aria-live": "polite",
|
|
@@ -2439,13 +2568,13 @@ var NumpadDialog = ({
|
|
|
2439
2568
|
border: outOfRange ? "1.5px solid #fca5a5" : "1.5px solid #e2e8f0"
|
|
2440
2569
|
},
|
|
2441
2570
|
children: [
|
|
2442
|
-
/* @__PURE__ */ (0,
|
|
2443
|
-
/* @__PURE__ */ (0,
|
|
2444
|
-
/* @__PURE__ */ (0,
|
|
2571
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: inputValue || "0" }),
|
|
2572
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "np-caret", "aria-hidden": "true" }),
|
|
2573
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: { fontSize: 14, color: "#94a3b8", fontWeight: 500 }, children: unit })
|
|
2445
2574
|
]
|
|
2446
2575
|
}
|
|
2447
2576
|
),
|
|
2448
|
-
/* @__PURE__ */ (0,
|
|
2577
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2449
2578
|
"div",
|
|
2450
2579
|
{
|
|
2451
2580
|
role: "status",
|
|
@@ -2460,8 +2589,8 @@ var NumpadDialog = ({
|
|
|
2460
2589
|
children: reason
|
|
2461
2590
|
}
|
|
2462
2591
|
),
|
|
2463
|
-
/* @__PURE__ */ (0,
|
|
2464
|
-
["7", "8", "9", "4", "5", "6", "1", "2", "3"].map((digit) => /* @__PURE__ */ (0,
|
|
2592
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 5 }, children: [
|
|
2593
|
+
["7", "8", "9", "4", "5", "6", "1", "2", "3"].map((digit) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2465
2594
|
"button",
|
|
2466
2595
|
{
|
|
2467
2596
|
type: "button",
|
|
@@ -2473,7 +2602,7 @@ var NumpadDialog = ({
|
|
|
2473
2602
|
},
|
|
2474
2603
|
digit
|
|
2475
2604
|
)),
|
|
2476
|
-
min < 0 ? /* @__PURE__ */ (0,
|
|
2605
|
+
min < 0 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2477
2606
|
"button",
|
|
2478
2607
|
{
|
|
2479
2608
|
type: "button",
|
|
@@ -2484,9 +2613,9 @@ var NumpadDialog = ({
|
|
|
2484
2613
|
onClick: handleToggleSign,
|
|
2485
2614
|
children: "+/\u2212"
|
|
2486
2615
|
}
|
|
2487
|
-
) : /* @__PURE__ */ (0,
|
|
2488
|
-
/* @__PURE__ */ (0,
|
|
2489
|
-
/* @__PURE__ */ (0,
|
|
2616
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(BackspaceButton, { style: { ...keyStyle, fontSize: 20, background: "#f8fafc", color: "#64748b" }, label: "\u232B" }),
|
|
2617
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: "np-key", tabIndex: -1, style: keyStyle, onClick: () => appendDigit("0"), children: "0" }),
|
|
2618
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2490
2619
|
"button",
|
|
2491
2620
|
{
|
|
2492
2621
|
type: "button",
|
|
@@ -2504,12 +2633,12 @@ var NumpadDialog = ({
|
|
|
2504
2633
|
}
|
|
2505
2634
|
)
|
|
2506
2635
|
] }),
|
|
2507
|
-
/* @__PURE__ */ (0,
|
|
2508
|
-
/* @__PURE__ */ (0,
|
|
2509
|
-
!backspaceInGrid && /* @__PURE__ */ (0,
|
|
2636
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { display: "flex", gap: 5 }, children: [
|
|
2637
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: "np-key", tabIndex: -1, style: utilKeyStyle, onClick: handleClear, children: "Clear" }),
|
|
2638
|
+
!backspaceInGrid && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(BackspaceButton, { style: utilKeyStyle, label: "Backspace" })
|
|
2510
2639
|
] }),
|
|
2511
|
-
/* @__PURE__ */ (0,
|
|
2512
|
-
/* @__PURE__ */ (0,
|
|
2640
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { display: "flex", gap: 8, marginTop: 2 }, children: [
|
|
2641
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2513
2642
|
"button",
|
|
2514
2643
|
{
|
|
2515
2644
|
type: "button",
|
|
@@ -2529,7 +2658,7 @@ var NumpadDialog = ({
|
|
|
2529
2658
|
children: "Cancel"
|
|
2530
2659
|
}
|
|
2531
2660
|
),
|
|
2532
|
-
/* @__PURE__ */ (0,
|
|
2661
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2533
2662
|
"button",
|
|
2534
2663
|
{
|
|
2535
2664
|
type: "button",
|
|
@@ -2564,13 +2693,13 @@ var NumpadDialog = ({
|
|
|
2564
2693
|
};
|
|
2565
2694
|
|
|
2566
2695
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.tsx
|
|
2567
|
-
var
|
|
2696
|
+
var import_react9 = __toESM(require("react"), 1);
|
|
2568
2697
|
var import_material3 = require("@mui/material");
|
|
2569
2698
|
|
|
2570
2699
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.styles.tsx
|
|
2571
2700
|
var import_material = require("@mui/material");
|
|
2572
2701
|
var import_styled = __toESM(require("@emotion/styled"), 1);
|
|
2573
|
-
var
|
|
2702
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2574
2703
|
var FullscreenContainer = (0, import_styled.default)(import_material.Box)(
|
|
2575
2704
|
({ leftCollapsed, rightCollapsed }) => {
|
|
2576
2705
|
const getGridTemplateAreas = () => {
|
|
@@ -2695,7 +2824,7 @@ var DisplayModeToggle = (0, import_styled.default)(import_material.IconButton)((
|
|
|
2695
2824
|
transform: "translateX(-50%) scale(1.05)"
|
|
2696
2825
|
}
|
|
2697
2826
|
}));
|
|
2698
|
-
var ChevronLeft = () => /* @__PURE__ */ (0,
|
|
2827
|
+
var ChevronLeft = () => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2699
2828
|
"div",
|
|
2700
2829
|
{
|
|
2701
2830
|
style: {
|
|
@@ -2707,7 +2836,7 @@ var ChevronLeft = () => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
|
2707
2836
|
}
|
|
2708
2837
|
}
|
|
2709
2838
|
);
|
|
2710
|
-
var ChevronRight = () => /* @__PURE__ */ (0,
|
|
2839
|
+
var ChevronRight = () => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2711
2840
|
"div",
|
|
2712
2841
|
{
|
|
2713
2842
|
style: {
|
|
@@ -2818,10 +2947,10 @@ var ScrollableSVGWrapper = (0, import_styled.default)("div")({
|
|
|
2818
2947
|
});
|
|
2819
2948
|
|
|
2820
2949
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.overlays.tsx
|
|
2821
|
-
var
|
|
2950
|
+
var import_react8 = require("react");
|
|
2822
2951
|
var import_material2 = require("@mui/material");
|
|
2823
2952
|
var import_styled2 = __toESM(require("@emotion/styled"), 1);
|
|
2824
|
-
var
|
|
2953
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2825
2954
|
var baseOverlayStyles = {
|
|
2826
2955
|
tank: {
|
|
2827
2956
|
background: "linear-gradient(135deg, rgba(69, 90, 120, 0.95) 0%, rgba(52, 73, 94, 0.95) 100%)",
|
|
@@ -2883,8 +3012,8 @@ var SVGLockedOverlay = ({
|
|
|
2883
3012
|
onClick,
|
|
2884
3013
|
containerSelector = ".tff-svg-container"
|
|
2885
3014
|
}) => {
|
|
2886
|
-
const [svgOffset, setSvgOffset] = (0,
|
|
2887
|
-
(0,
|
|
3015
|
+
const [svgOffset, setSvgOffset] = (0, import_react8.useState)({ x: 0, y: 0 });
|
|
3016
|
+
(0, import_react8.useEffect)(() => {
|
|
2888
3017
|
const updateSvgOffset = () => {
|
|
2889
3018
|
const containerElement = document.querySelector(containerSelector);
|
|
2890
3019
|
const svgElement = containerElement?.querySelector("svg");
|
|
@@ -2904,7 +3033,7 @@ var SVGLockedOverlay = ({
|
|
|
2904
3033
|
const pixelX = svgX + svgOffset.x;
|
|
2905
3034
|
const pixelY = svgY + svgOffset.y;
|
|
2906
3035
|
const appliedStyle = theme ? { ...overlayStyles[theme], ...style } : style;
|
|
2907
|
-
return /* @__PURE__ */ (0,
|
|
3036
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2908
3037
|
import_material2.Box,
|
|
2909
3038
|
{
|
|
2910
3039
|
className: `svg-locked-overlay ${className}`.trim(),
|
|
@@ -2968,7 +3097,7 @@ var CardUnit = (0, import_styled2.default)("div")({
|
|
|
2968
3097
|
});
|
|
2969
3098
|
|
|
2970
3099
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.visuals.tsx
|
|
2971
|
-
var
|
|
3100
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2972
3101
|
var forcedTagStyle = {
|
|
2973
3102
|
position: "absolute",
|
|
2974
3103
|
top: "-6px",
|
|
@@ -2996,7 +3125,7 @@ var TrendLine = ({
|
|
|
2996
3125
|
forced = false
|
|
2997
3126
|
}) => {
|
|
2998
3127
|
if (!values || values.length < 2) {
|
|
2999
|
-
return /* @__PURE__ */ (0,
|
|
3128
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
3000
3129
|
"div",
|
|
3001
3130
|
{
|
|
3002
3131
|
style: {
|
|
@@ -3010,8 +3139,8 @@ var TrendLine = ({
|
|
|
3010
3139
|
justifyContent: "center"
|
|
3011
3140
|
},
|
|
3012
3141
|
children: [
|
|
3013
|
-
/* @__PURE__ */ (0,
|
|
3014
|
-
forced && /* @__PURE__ */ (0,
|
|
3142
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: { fontSize: "8px", color: "#ccc" }, children: "No data" }),
|
|
3143
|
+
forced && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: forcedTagStyle, "aria-label": "Forced", children: "F" })
|
|
3015
3144
|
]
|
|
3016
3145
|
}
|
|
3017
3146
|
);
|
|
@@ -3024,7 +3153,7 @@ var TrendLine = ({
|
|
|
3024
3153
|
const x = 4 + i / (values.length - 1) * (width - 8);
|
|
3025
3154
|
return i === 0 ? `M ${x} ${y}` : `L ${x} ${y}`;
|
|
3026
3155
|
}).join(" ");
|
|
3027
|
-
return /* @__PURE__ */ (0,
|
|
3156
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
3028
3157
|
"div",
|
|
3029
3158
|
{
|
|
3030
3159
|
style: {
|
|
@@ -3036,14 +3165,14 @@ var TrendLine = ({
|
|
|
3036
3165
|
overflow: "visible"
|
|
3037
3166
|
},
|
|
3038
3167
|
children: [
|
|
3039
|
-
/* @__PURE__ */ (0,
|
|
3168
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
3040
3169
|
"svg",
|
|
3041
3170
|
{
|
|
3042
3171
|
width,
|
|
3043
3172
|
height,
|
|
3044
3173
|
style: { position: "absolute", top: 0, left: 0, overflow: "hidden", borderRadius: "2px" },
|
|
3045
3174
|
children: [
|
|
3046
|
-
/* @__PURE__ */ (0,
|
|
3175
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3047
3176
|
"path",
|
|
3048
3177
|
{
|
|
3049
3178
|
d: pathData,
|
|
@@ -3054,7 +3183,7 @@ var TrendLine = ({
|
|
|
3054
3183
|
strokeLinejoin: "round"
|
|
3055
3184
|
}
|
|
3056
3185
|
),
|
|
3057
|
-
/* @__PURE__ */ (0,
|
|
3186
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3058
3187
|
"circle",
|
|
3059
3188
|
{
|
|
3060
3189
|
cx: 4 + (width - 8),
|
|
@@ -3066,7 +3195,7 @@ var TrendLine = ({
|
|
|
3066
3195
|
]
|
|
3067
3196
|
}
|
|
3068
3197
|
),
|
|
3069
|
-
forced && /* @__PURE__ */ (0,
|
|
3198
|
+
forced && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: forcedTagStyle, "aria-label": "Forced", children: "F" })
|
|
3070
3199
|
]
|
|
3071
3200
|
}
|
|
3072
3201
|
);
|
|
@@ -3098,7 +3227,7 @@ var CircularGauge = ({
|
|
|
3098
3227
|
const borderColor = isHex ? hexToRgba(color, 0.9) : color;
|
|
3099
3228
|
const backgroundColor = isHex ? hexToRgba(color, 0.15) : color;
|
|
3100
3229
|
const borderStrokeColor = isHex ? hexToRgba(color, 0.4) : color;
|
|
3101
|
-
return /* @__PURE__ */ (0,
|
|
3230
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
3102
3231
|
"div",
|
|
3103
3232
|
{
|
|
3104
3233
|
style: {
|
|
@@ -3107,7 +3236,7 @@ var CircularGauge = ({
|
|
|
3107
3236
|
alignItems: "center"
|
|
3108
3237
|
},
|
|
3109
3238
|
children: [
|
|
3110
|
-
/* @__PURE__ */ (0,
|
|
3239
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
3111
3240
|
"div",
|
|
3112
3241
|
{
|
|
3113
3242
|
style: {
|
|
@@ -3119,8 +3248,8 @@ var CircularGauge = ({
|
|
|
3119
3248
|
border: forced ? `2px solid ${FORCED_MARK_COLOR.border}` : `1px solid ${borderStrokeColor}`
|
|
3120
3249
|
},
|
|
3121
3250
|
children: [
|
|
3122
|
-
/* @__PURE__ */ (0,
|
|
3123
|
-
/* @__PURE__ */ (0,
|
|
3251
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("svg", { width: size, height: size, style: { transform: "rotate(-90deg)" }, children: [
|
|
3252
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3124
3253
|
"circle",
|
|
3125
3254
|
{
|
|
3126
3255
|
cx: size / 2,
|
|
@@ -3131,7 +3260,7 @@ var CircularGauge = ({
|
|
|
3131
3260
|
strokeWidth: 1
|
|
3132
3261
|
}
|
|
3133
3262
|
),
|
|
3134
|
-
/* @__PURE__ */ (0,
|
|
3263
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3135
3264
|
"circle",
|
|
3136
3265
|
{
|
|
3137
3266
|
cx: size / 2,
|
|
@@ -3142,7 +3271,7 @@ var CircularGauge = ({
|
|
|
3142
3271
|
fill: "transparent"
|
|
3143
3272
|
}
|
|
3144
3273
|
),
|
|
3145
|
-
/* @__PURE__ */ (0,
|
|
3274
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3146
3275
|
"circle",
|
|
3147
3276
|
{
|
|
3148
3277
|
cx: size / 2,
|
|
@@ -3158,7 +3287,7 @@ var CircularGauge = ({
|
|
|
3158
3287
|
}
|
|
3159
3288
|
)
|
|
3160
3289
|
] }),
|
|
3161
|
-
/* @__PURE__ */ (0,
|
|
3290
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
3162
3291
|
"div",
|
|
3163
3292
|
{
|
|
3164
3293
|
style: {
|
|
@@ -3174,14 +3303,14 @@ var CircularGauge = ({
|
|
|
3174
3303
|
},
|
|
3175
3304
|
children: [
|
|
3176
3305
|
value.toFixed(1),
|
|
3177
|
-
/* @__PURE__ */ (0,
|
|
3306
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { fontSize: "8px", opacity: 0.9, color: "white" }, children: unit })
|
|
3178
3307
|
]
|
|
3179
3308
|
}
|
|
3180
3309
|
)
|
|
3181
3310
|
]
|
|
3182
3311
|
}
|
|
3183
3312
|
),
|
|
3184
|
-
/* @__PURE__ */ (0,
|
|
3313
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3185
3314
|
"div",
|
|
3186
3315
|
{
|
|
3187
3316
|
style: {
|
|
@@ -3193,7 +3322,7 @@ var CircularGauge = ({
|
|
|
3193
3322
|
children: label
|
|
3194
3323
|
}
|
|
3195
3324
|
),
|
|
3196
|
-
forced && /* @__PURE__ */ (0,
|
|
3325
|
+
forced && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3197
3326
|
"span",
|
|
3198
3327
|
{
|
|
3199
3328
|
"aria-label": "Forced",
|
|
@@ -3214,7 +3343,7 @@ var CircularGauge = ({
|
|
|
3214
3343
|
children: "F"
|
|
3215
3344
|
}
|
|
3216
3345
|
),
|
|
3217
|
-
forced && realValue !== void 0 && /* @__PURE__ */ (0,
|
|
3346
|
+
forced && realValue !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: { fontSize: "8px", opacity: 0.8, color: "white", marginTop: "1px" }, children: [
|
|
3218
3347
|
"REAL ",
|
|
3219
3348
|
realValue.toFixed(1),
|
|
3220
3349
|
" ",
|
|
@@ -3239,7 +3368,7 @@ var Sparkline = ({ data, width, height, color, forced = false }) => {
|
|
|
3239
3368
|
const y = height - 8 - (value - min) / range * (height - 8);
|
|
3240
3369
|
return `${x + 4},${y + 4}`;
|
|
3241
3370
|
}).join(" ");
|
|
3242
|
-
return /* @__PURE__ */ (0,
|
|
3371
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
3243
3372
|
"div",
|
|
3244
3373
|
{
|
|
3245
3374
|
style: {
|
|
@@ -3255,13 +3384,13 @@ var Sparkline = ({ data, width, height, color, forced = false }) => {
|
|
|
3255
3384
|
boxShadow: "0 1px 3px rgba(0, 0, 0, 0.2)"
|
|
3256
3385
|
},
|
|
3257
3386
|
children: [
|
|
3258
|
-
/* @__PURE__ */ (0,
|
|
3259
|
-
forced && /* @__PURE__ */ (0,
|
|
3387
|
+
/* @__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" }) }),
|
|
3388
|
+
forced && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: forcedTagStyle, "aria-label": "Forced", children: "F" })
|
|
3260
3389
|
]
|
|
3261
3390
|
}
|
|
3262
3391
|
);
|
|
3263
3392
|
};
|
|
3264
|
-
var EquipmentForcedBadge = () => /* @__PURE__ */ (0,
|
|
3393
|
+
var EquipmentForcedBadge = () => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3265
3394
|
"span",
|
|
3266
3395
|
{
|
|
3267
3396
|
"aria-label": "Forced",
|
|
@@ -3296,9 +3425,9 @@ var EquipmentIndicatorWithSparkline = ({
|
|
|
3296
3425
|
forced = false
|
|
3297
3426
|
}) => {
|
|
3298
3427
|
const hasSparkline = sparklineData && sparklineData.length > 1 && Math.max(...sparklineData) !== Math.min(...sparklineData);
|
|
3299
|
-
return /* @__PURE__ */ (0,
|
|
3300
|
-
/* @__PURE__ */ (0,
|
|
3301
|
-
/* @__PURE__ */ (0,
|
|
3428
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
3429
|
+
/* @__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: [
|
|
3430
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3302
3431
|
"div",
|
|
3303
3432
|
{
|
|
3304
3433
|
style: {
|
|
@@ -3319,9 +3448,9 @@ var EquipmentIndicatorWithSparkline = ({
|
|
|
3319
3448
|
children: label
|
|
3320
3449
|
}
|
|
3321
3450
|
),
|
|
3322
|
-
forced && /* @__PURE__ */ (0,
|
|
3451
|
+
forced && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(EquipmentForcedBadge, {})
|
|
3323
3452
|
] }) }),
|
|
3324
|
-
hasSparkline && /* @__PURE__ */ (0,
|
|
3453
|
+
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
3454
|
] });
|
|
3326
3455
|
};
|
|
3327
3456
|
var EquipmentIndicator = ({
|
|
@@ -3335,8 +3464,8 @@ var EquipmentIndicator = ({
|
|
|
3335
3464
|
forced = false
|
|
3336
3465
|
}) => {
|
|
3337
3466
|
const overlayStyle = style !== void 0 ? { transform: "translate(-50%, -50%)", ...style } : { transform: "translate(-50%, -50%)" };
|
|
3338
|
-
return /* @__PURE__ */ (0,
|
|
3339
|
-
/* @__PURE__ */ (0,
|
|
3467
|
+
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: [
|
|
3468
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3340
3469
|
"div",
|
|
3341
3470
|
{
|
|
3342
3471
|
style: {
|
|
@@ -3357,12 +3486,12 @@ var EquipmentIndicator = ({
|
|
|
3357
3486
|
children: label
|
|
3358
3487
|
}
|
|
3359
3488
|
),
|
|
3360
|
-
forced && /* @__PURE__ */ (0,
|
|
3489
|
+
forced && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(EquipmentForcedBadge, {})
|
|
3361
3490
|
] }) });
|
|
3362
3491
|
};
|
|
3363
3492
|
|
|
3364
3493
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.tsx
|
|
3365
|
-
var
|
|
3494
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
3366
3495
|
function FullscreenWorkspace({
|
|
3367
3496
|
svgContent,
|
|
3368
3497
|
overlays,
|
|
@@ -3390,10 +3519,10 @@ function FullscreenWorkspace({
|
|
|
3390
3519
|
className = "",
|
|
3391
3520
|
...rest
|
|
3392
3521
|
}) {
|
|
3393
|
-
const [leftCollapsedState, setLeftCollapsedState] =
|
|
3394
|
-
const [rightCollapsedState, setRightCollapsedState] =
|
|
3395
|
-
const [internalDisplayMode, setInternalDisplayMode] =
|
|
3396
|
-
const [internalTab, setInternalTab] =
|
|
3522
|
+
const [leftCollapsedState, setLeftCollapsedState] = import_react9.default.useState(defaultLeftCollapsed);
|
|
3523
|
+
const [rightCollapsedState, setRightCollapsedState] = import_react9.default.useState(defaultRightCollapsed);
|
|
3524
|
+
const [internalDisplayMode, setInternalDisplayMode] = import_react9.default.useState(displayMode ?? defaultDisplayMode);
|
|
3525
|
+
const [internalTab, setInternalTab] = import_react9.default.useState(
|
|
3397
3526
|
tabs && tabs.length > 0 ? tabs[0].value : ""
|
|
3398
3527
|
);
|
|
3399
3528
|
const leftCollapsed = leftCollapsedProp ?? leftCollapsedState;
|
|
@@ -3401,10 +3530,10 @@ function FullscreenWorkspace({
|
|
|
3401
3530
|
const isDisplayModeControlled = displayMode !== void 0;
|
|
3402
3531
|
const currentDisplayMode = isDisplayModeControlled ? displayMode : internalDisplayMode;
|
|
3403
3532
|
const isTabControlled = activeTab !== void 0 && activeTab !== null;
|
|
3404
|
-
const resolvedTabs =
|
|
3533
|
+
const resolvedTabs = import_react9.default.useMemo(() => tabs ?? [], [tabs]);
|
|
3405
3534
|
const defaultTabValue = resolvedTabs.length > 0 ? resolvedTabs[0].value : "";
|
|
3406
3535
|
const currentTab = isTabControlled ? activeTab : internalTab || defaultTabValue;
|
|
3407
|
-
|
|
3536
|
+
import_react9.default.useEffect(() => {
|
|
3408
3537
|
if (resolvedTabs.length > 0) {
|
|
3409
3538
|
const values = resolvedTabs.map((tab) => tab.value);
|
|
3410
3539
|
if (!values.includes(currentTab)) {
|
|
@@ -3413,7 +3542,7 @@ function FullscreenWorkspace({
|
|
|
3413
3542
|
}
|
|
3414
3543
|
}
|
|
3415
3544
|
}, [resolvedTabs, activeTab, currentTab, defaultTabValue]);
|
|
3416
|
-
|
|
3545
|
+
import_react9.default.useEffect(() => {
|
|
3417
3546
|
if (displayMode !== void 0) {
|
|
3418
3547
|
setInternalDisplayMode(displayMode);
|
|
3419
3548
|
}
|
|
@@ -3448,7 +3577,7 @@ function FullscreenWorkspace({
|
|
|
3448
3577
|
const currentTabContent = resolvedTabs.find((tab) => tab.value === currentTab)?.content ?? null;
|
|
3449
3578
|
const showLeftToggle = Boolean(leftPanel);
|
|
3450
3579
|
const showRightToggle = Boolean(rightPanel);
|
|
3451
|
-
return /* @__PURE__ */ (0,
|
|
3580
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
3452
3581
|
FullscreenContainer,
|
|
3453
3582
|
{
|
|
3454
3583
|
leftCollapsed,
|
|
@@ -3456,25 +3585,25 @@ function FullscreenWorkspace({
|
|
|
3456
3585
|
className: `tff-svg-container ${className}`.trim(),
|
|
3457
3586
|
...rest,
|
|
3458
3587
|
children: [
|
|
3459
|
-
showLeftToggle && /* @__PURE__ */ (0,
|
|
3588
|
+
showLeftToggle && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3460
3589
|
LeftToggleButton,
|
|
3461
3590
|
{
|
|
3462
3591
|
collapsed: leftCollapsed,
|
|
3463
3592
|
onClick: handleLeftToggle,
|
|
3464
3593
|
"aria-label": leftCollapsed ? "Expand left panel" : "Collapse left panel",
|
|
3465
|
-
children: leftCollapsed ? /* @__PURE__ */ (0,
|
|
3594
|
+
children: leftCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ChevronRight, {}) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ChevronLeft, {})
|
|
3466
3595
|
}
|
|
3467
3596
|
),
|
|
3468
|
-
showRightToggle && /* @__PURE__ */ (0,
|
|
3597
|
+
showRightToggle && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3469
3598
|
RightToggleButton,
|
|
3470
3599
|
{
|
|
3471
3600
|
collapsed: rightCollapsed,
|
|
3472
3601
|
onClick: handleRightToggle,
|
|
3473
3602
|
"aria-label": rightCollapsed ? "Expand right panel" : "Collapse right panel",
|
|
3474
|
-
children: rightCollapsed ? /* @__PURE__ */ (0,
|
|
3603
|
+
children: rightCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ChevronLeft, {}) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ChevronRight, {})
|
|
3475
3604
|
}
|
|
3476
3605
|
),
|
|
3477
|
-
showDisplayModeToggle && /* @__PURE__ */ (0,
|
|
3606
|
+
showDisplayModeToggle && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3478
3607
|
DisplayModeToggle,
|
|
3479
3608
|
{
|
|
3480
3609
|
mode: currentDisplayMode,
|
|
@@ -3483,9 +3612,9 @@ function FullscreenWorkspace({
|
|
|
3483
3612
|
children: currentDisplayMode === "dashboard" ? "Dashboard Mode" : "Standard Mode"
|
|
3484
3613
|
}
|
|
3485
3614
|
),
|
|
3486
|
-
/* @__PURE__ */ (0,
|
|
3487
|
-
showZoomControls && /* @__PURE__ */ (0,
|
|
3488
|
-
/* @__PURE__ */ (0,
|
|
3615
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(SVGArea, { children: [
|
|
3616
|
+
showZoomControls && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(ZoomControls, { children: [
|
|
3617
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3489
3618
|
ZoomButton,
|
|
3490
3619
|
{
|
|
3491
3620
|
onClick: onZoomIn,
|
|
@@ -3495,7 +3624,7 @@ function FullscreenWorkspace({
|
|
|
3495
3624
|
children: "+"
|
|
3496
3625
|
}
|
|
3497
3626
|
),
|
|
3498
|
-
/* @__PURE__ */ (0,
|
|
3627
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3499
3628
|
ZoomButton,
|
|
3500
3629
|
{
|
|
3501
3630
|
onClick: onZoomOut,
|
|
@@ -3505,7 +3634,7 @@ function FullscreenWorkspace({
|
|
|
3505
3634
|
children: "-"
|
|
3506
3635
|
}
|
|
3507
3636
|
),
|
|
3508
|
-
onResetZoom && /* @__PURE__ */ (0,
|
|
3637
|
+
onResetZoom && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3509
3638
|
ZoomButton,
|
|
3510
3639
|
{
|
|
3511
3640
|
onClick: onResetZoom,
|
|
@@ -3516,44 +3645,44 @@ function FullscreenWorkspace({
|
|
|
3516
3645
|
}
|
|
3517
3646
|
)
|
|
3518
3647
|
] }),
|
|
3519
|
-
/* @__PURE__ */ (0,
|
|
3648
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ScrollableSVGWrapper, { className: "svg-scroll-wrapper", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(FixedSVGContainer, { className: "svg-container", children: [
|
|
3520
3649
|
svgContent,
|
|
3521
3650
|
overlays
|
|
3522
3651
|
] }) })
|
|
3523
3652
|
] }),
|
|
3524
|
-
/* @__PURE__ */ (0,
|
|
3525
|
-
/* @__PURE__ */ (0,
|
|
3653
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(LeftPanel, { collapsed: leftCollapsed, children: resolvedTabs.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
3654
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3526
3655
|
PanelTabs,
|
|
3527
3656
|
{
|
|
3528
3657
|
value: currentTab,
|
|
3529
3658
|
onChange: handleTabChangeInternal,
|
|
3530
3659
|
"aria-label": "Left panel tabs",
|
|
3531
|
-
children: resolvedTabs.map((tab) => /* @__PURE__ */ (0,
|
|
3660
|
+
children: resolvedTabs.map((tab) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material3.Tab, { label: tab.label, value: tab.value }, tab.value))
|
|
3532
3661
|
}
|
|
3533
3662
|
),
|
|
3534
|
-
/* @__PURE__ */ (0,
|
|
3663
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(PanelContent, { children: currentTabContent })
|
|
3535
3664
|
] }) : leftPanel }),
|
|
3536
|
-
/* @__PURE__ */ (0,
|
|
3537
|
-
/* @__PURE__ */ (0,
|
|
3665
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(RightPanel, { collapsed: rightCollapsed, children: rightPanel }),
|
|
3666
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(FooterPanel, { children: footer })
|
|
3538
3667
|
]
|
|
3539
3668
|
}
|
|
3540
3669
|
);
|
|
3541
3670
|
}
|
|
3542
3671
|
|
|
3543
3672
|
// src/theme/ThemeContext.tsx
|
|
3544
|
-
var
|
|
3545
|
-
var
|
|
3546
|
-
var ThemeContext = (0,
|
|
3673
|
+
var import_react10 = require("react");
|
|
3674
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
3675
|
+
var ThemeContext = (0, import_react10.createContext)(void 0);
|
|
3547
3676
|
var useTheme = () => {
|
|
3548
|
-
const context = (0,
|
|
3677
|
+
const context = (0, import_react10.useContext)(ThemeContext);
|
|
3549
3678
|
if (!context) {
|
|
3550
3679
|
throw new Error("useTheme must be used within a ThemeProvider");
|
|
3551
3680
|
}
|
|
3552
3681
|
return context;
|
|
3553
3682
|
};
|
|
3554
3683
|
var ThemeProvider = ({ children }) => {
|
|
3555
|
-
const [theme, setThemeState] = (0,
|
|
3556
|
-
(0,
|
|
3684
|
+
const [theme, setThemeState] = (0, import_react10.useState)("modern");
|
|
3685
|
+
(0, import_react10.useEffect)(() => {
|
|
3557
3686
|
document.body.className = "";
|
|
3558
3687
|
document.body.classList.add(`theme-${theme}`);
|
|
3559
3688
|
document.documentElement.className = "";
|
|
@@ -3565,11 +3694,11 @@ var ThemeProvider = ({ children }) => {
|
|
|
3565
3694
|
const setTheme = (newTheme) => {
|
|
3566
3695
|
setThemeState(newTheme);
|
|
3567
3696
|
};
|
|
3568
|
-
return /* @__PURE__ */ (0,
|
|
3697
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ThemeContext.Provider, { value: { theme, toggleTheme, setTheme }, children });
|
|
3569
3698
|
};
|
|
3570
3699
|
|
|
3571
3700
|
// src/theme/ThemeToggle.tsx
|
|
3572
|
-
var
|
|
3701
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
3573
3702
|
var ThemeToggle = ({
|
|
3574
3703
|
size = "medium",
|
|
3575
3704
|
position = "top-right",
|
|
@@ -3640,18 +3769,18 @@ var ThemeToggle = ({
|
|
|
3640
3769
|
transition: "all 0.2s ease",
|
|
3641
3770
|
boxShadow: "0 2px 4px rgba(0, 0, 0, 0.2)"
|
|
3642
3771
|
};
|
|
3643
|
-
return /* @__PURE__ */ (0,
|
|
3644
|
-
/* @__PURE__ */ (0,
|
|
3645
|
-
/* @__PURE__ */ (0,
|
|
3646
|
-
/* @__PURE__ */ (0,
|
|
3772
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: currentStyle, onClick: toggleTheme, className, ...props, children: [
|
|
3773
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: theme === "modern" ? "\u{1F3A8} Modern" : "\u{1F3ED} HMI" }),
|
|
3774
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: toggleStyle, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: thumbStyle }) }),
|
|
3775
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { style: { fontSize: "0.75rem", opacity: 0.8 }, children: theme === "modern" ? "Industrial Design" : "High Performance" })
|
|
3647
3776
|
] });
|
|
3648
3777
|
};
|
|
3649
3778
|
|
|
3650
3779
|
// src/components/PIDCanvas/PIDCanvas.tsx
|
|
3651
|
-
var
|
|
3780
|
+
var import_react22 = __toESM(require("react"), 1);
|
|
3652
3781
|
|
|
3653
3782
|
// src/components/PIDCanvas/NodeRenderer.tsx
|
|
3654
|
-
var
|
|
3783
|
+
var import_react11 = __toESM(require("react"), 1);
|
|
3655
3784
|
|
|
3656
3785
|
// src/diagram/symbols/mockSymbolLibrary.ts
|
|
3657
3786
|
var mockSymbolLibrary = {
|
|
@@ -5025,9 +5154,110 @@ function writeAppearanceValue(node, field, value) {
|
|
|
5025
5154
|
return { metadata: { ...node.metadata, [field.key]: value } };
|
|
5026
5155
|
}
|
|
5027
5156
|
|
|
5157
|
+
// src/diagram/badges/nodeBadgeGlyphs.ts
|
|
5158
|
+
var PROHIBIT_GLYPH = {
|
|
5159
|
+
id: "prohibit",
|
|
5160
|
+
svgContent: '<circle cx="12" cy="12" r="9" fill="none" stroke="currentColor" stroke-width="2.4"/><line x1="5.6" y1="18.4" x2="18.4" y2="5.6" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"/>'
|
|
5161
|
+
};
|
|
5162
|
+
var builtInBadgeGlyphs = {
|
|
5163
|
+
[PROHIBIT_GLYPH.id]: PROHIBIT_GLYPH
|
|
5164
|
+
};
|
|
5165
|
+
var customBadgeGlyphs = {};
|
|
5166
|
+
function registerBadgeGlyph(glyph) {
|
|
5167
|
+
customBadgeGlyphs[glyph.id] = glyph;
|
|
5168
|
+
}
|
|
5169
|
+
function registerBadgeGlyphs(glyphs) {
|
|
5170
|
+
if (Array.isArray(glyphs)) {
|
|
5171
|
+
glyphs.forEach((glyph) => registerBadgeGlyph(glyph));
|
|
5172
|
+
} else {
|
|
5173
|
+
Object.values(glyphs).forEach((glyph) => registerBadgeGlyph(glyph));
|
|
5174
|
+
}
|
|
5175
|
+
}
|
|
5176
|
+
function getBadgeGlyph(glyphId) {
|
|
5177
|
+
return customBadgeGlyphs[glyphId] ?? builtInBadgeGlyphs[glyphId];
|
|
5178
|
+
}
|
|
5179
|
+
function getAvailableBadgeGlyphs() {
|
|
5180
|
+
return [...Object.keys(customBadgeGlyphs), ...Object.keys(builtInBadgeGlyphs)];
|
|
5181
|
+
}
|
|
5182
|
+
|
|
5028
5183
|
// src/components/PIDCanvas/NodeRenderer.tsx
|
|
5029
|
-
var
|
|
5030
|
-
var
|
|
5184
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
5185
|
+
var HATCH_TILE_SIZE = 7;
|
|
5186
|
+
var HATCH_STRIPE_WIDTH = 2;
|
|
5187
|
+
var HATCH_STRIPE_ANGLE = 135;
|
|
5188
|
+
var HATCH_STRIPE_OPACITY = 85 / 255;
|
|
5189
|
+
function isUnknownNode(node) {
|
|
5190
|
+
return node.positionUnknown === true || normalizeDeviceStatus(node.status) === "unknown";
|
|
5191
|
+
}
|
|
5192
|
+
var DEFAULT_BADGE_CORNER = "top-right";
|
|
5193
|
+
var DEFAULT_BADGE_SIZE = 14;
|
|
5194
|
+
var DEFAULT_BADGE_COLOR = "#111827";
|
|
5195
|
+
var DEFAULT_BADGE_BACKGROUND = "#d1d5db";
|
|
5196
|
+
var BADGE_GLYPH_BOX = 24;
|
|
5197
|
+
var BADGE_BLINK_KEYFRAME_ID = "pid-node-badge-blink-keyframes";
|
|
5198
|
+
var BADGE_BLINK_KEYFRAME_NAME = "pid-node-badge-blink";
|
|
5199
|
+
function ensureBadgeBlinkKeyframes() {
|
|
5200
|
+
if (typeof document === "undefined") return;
|
|
5201
|
+
if (document.getElementById(BADGE_BLINK_KEYFRAME_ID)) return;
|
|
5202
|
+
const style = document.createElement("style");
|
|
5203
|
+
style.id = BADGE_BLINK_KEYFRAME_ID;
|
|
5204
|
+
style.textContent = `@keyframes ${BADGE_BLINK_KEYFRAME_NAME}{0%{opacity:1}50%{opacity:.15}100%{opacity:1}}`;
|
|
5205
|
+
document.head.appendChild(style);
|
|
5206
|
+
}
|
|
5207
|
+
function badgeCenter(corner, vb, size) {
|
|
5208
|
+
const margin = size / 4;
|
|
5209
|
+
switch (corner) {
|
|
5210
|
+
case "top-left":
|
|
5211
|
+
return { x: -margin, y: -margin };
|
|
5212
|
+
case "bottom-left":
|
|
5213
|
+
return { x: -margin, y: vb.height + margin };
|
|
5214
|
+
case "bottom-right":
|
|
5215
|
+
return { x: vb.width + margin, y: vb.height + margin };
|
|
5216
|
+
case "top-right":
|
|
5217
|
+
default:
|
|
5218
|
+
return { x: vb.width + margin, y: -margin };
|
|
5219
|
+
}
|
|
5220
|
+
}
|
|
5221
|
+
function renderNodeBadge(badge, vb, rotation) {
|
|
5222
|
+
const glyphDef = getBadgeGlyph(badge.glyph);
|
|
5223
|
+
const size = badge.size ?? DEFAULT_BADGE_SIZE;
|
|
5224
|
+
const color = badge.color ?? DEFAULT_BADGE_COLOR;
|
|
5225
|
+
const backgroundColor = badge.backgroundColor ?? DEFAULT_BADGE_BACKGROUND;
|
|
5226
|
+
const corner = badge.corner ?? DEFAULT_BADGE_CORNER;
|
|
5227
|
+
const { x: cx, y: cy } = badgeCenter(corner, vb, size);
|
|
5228
|
+
const radius = size / 2;
|
|
5229
|
+
const glyphScale = size / BADGE_GLYPH_BOX;
|
|
5230
|
+
let blinkStyle;
|
|
5231
|
+
if (badge.blink) {
|
|
5232
|
+
ensureBadgeBlinkKeyframes();
|
|
5233
|
+
blinkStyle = {
|
|
5234
|
+
animation: `${BADGE_BLINK_KEYFRAME_NAME} ${badge.blinkPeriodMs}ms ease-in-out infinite`
|
|
5235
|
+
};
|
|
5236
|
+
}
|
|
5237
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
5238
|
+
"g",
|
|
5239
|
+
{
|
|
5240
|
+
"data-node-badge": badge.glyph,
|
|
5241
|
+
"data-badge-corner": corner,
|
|
5242
|
+
"data-badge-blink": badge.blink ? "true" : "false",
|
|
5243
|
+
"aria-label": badge.label,
|
|
5244
|
+
role: badge.label ? "img" : void 0,
|
|
5245
|
+
transform: rotation ? `translate(${cx}, ${cy}) rotate(${-rotation})` : `translate(${cx}, ${cy})`,
|
|
5246
|
+
style: blinkStyle,
|
|
5247
|
+
children: [
|
|
5248
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { r: radius, fill: backgroundColor }),
|
|
5249
|
+
glyphDef && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5250
|
+
"g",
|
|
5251
|
+
{
|
|
5252
|
+
color,
|
|
5253
|
+
transform: `scale(${glyphScale}) translate(${-BADGE_GLYPH_BOX / 2}, ${-BADGE_GLYPH_BOX / 2})`,
|
|
5254
|
+
dangerouslySetInnerHTML: { __html: glyphDef.svgContent }
|
|
5255
|
+
}
|
|
5256
|
+
)
|
|
5257
|
+
]
|
|
5258
|
+
}
|
|
5259
|
+
);
|
|
5260
|
+
}
|
|
5031
5261
|
function NodeRendererImpl({
|
|
5032
5262
|
nodes: nodes2,
|
|
5033
5263
|
selectedNodeIds,
|
|
@@ -5039,41 +5269,42 @@ function NodeRendererImpl({
|
|
|
5039
5269
|
enableDrag = false,
|
|
5040
5270
|
statusColorMap
|
|
5041
5271
|
}) {
|
|
5042
|
-
const
|
|
5043
|
-
const
|
|
5044
|
-
|
|
5045
|
-
|
|
5272
|
+
const hatchPatternId = `node-unknown-hatch-${import_react11.default.useId().replace(/[^a-zA-Z0-9_-]/g, "")}`;
|
|
5273
|
+
const visibleNodes = nodes2.filter((node) => node.visible !== false);
|
|
5274
|
+
const hasUnknownNode = visibleNodes.some(isUnknownNode);
|
|
5275
|
+
const unknownEntry = resolveStatusColor("unknown", statusColorMap);
|
|
5276
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("g", { id: "layer-nodes", children: [
|
|
5277
|
+
hasUnknownNode && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
5046
5278
|
"pattern",
|
|
5047
5279
|
{
|
|
5048
|
-
id:
|
|
5049
|
-
"data-testid": "
|
|
5280
|
+
id: hatchPatternId,
|
|
5281
|
+
"data-testid": "unknown-hatch-pattern",
|
|
5050
5282
|
patternUnits: "userSpaceOnUse",
|
|
5051
|
-
width:
|
|
5052
|
-
height:
|
|
5053
|
-
patternTransform:
|
|
5283
|
+
width: HATCH_TILE_SIZE,
|
|
5284
|
+
height: HATCH_TILE_SIZE,
|
|
5285
|
+
patternTransform: `rotate(${HATCH_STRIPE_ANGLE})`,
|
|
5054
5286
|
children: [
|
|
5055
|
-
/* @__PURE__ */ (0,
|
|
5056
|
-
/* @__PURE__ */ (0,
|
|
5057
|
-
"
|
|
5287
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("rect", { width: HATCH_TILE_SIZE, height: HATCH_TILE_SIZE, fill: unknownEntry.fill }),
|
|
5288
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5289
|
+
"rect",
|
|
5058
5290
|
{
|
|
5059
|
-
|
|
5060
|
-
|
|
5061
|
-
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
strokeWidth: "2"
|
|
5291
|
+
x: HATCH_TILE_SIZE - HATCH_STRIPE_WIDTH,
|
|
5292
|
+
width: HATCH_STRIPE_WIDTH,
|
|
5293
|
+
height: HATCH_TILE_SIZE,
|
|
5294
|
+
fill: unknownEntry.stroke,
|
|
5295
|
+
fillOpacity: HATCH_STRIPE_OPACITY
|
|
5065
5296
|
}
|
|
5066
5297
|
)
|
|
5067
5298
|
]
|
|
5068
5299
|
}
|
|
5069
5300
|
) }),
|
|
5070
|
-
|
|
5301
|
+
visibleNodes.map((node) => {
|
|
5071
5302
|
const symbol = getSymbolDefinition(node.symbolId);
|
|
5072
5303
|
const isSelected = selectedNodeIds?.has(node.id) ?? false;
|
|
5073
5304
|
const isDragging = draggingNodeId === node.id;
|
|
5074
5305
|
if (!symbol) {
|
|
5075
|
-
return /* @__PURE__ */ (0,
|
|
5076
|
-
/* @__PURE__ */ (0,
|
|
5306
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("g", { children: [
|
|
5307
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5077
5308
|
"circle",
|
|
5078
5309
|
{
|
|
5079
5310
|
cx: node.transform.x,
|
|
@@ -5085,7 +5316,7 @@ function NodeRendererImpl({
|
|
|
5085
5316
|
strokeWidth: "2"
|
|
5086
5317
|
}
|
|
5087
5318
|
),
|
|
5088
|
-
/* @__PURE__ */ (0,
|
|
5319
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5089
5320
|
"text",
|
|
5090
5321
|
{
|
|
5091
5322
|
x: node.transform.x,
|
|
@@ -5125,9 +5356,9 @@ function NodeRendererImpl({
|
|
|
5125
5356
|
);
|
|
5126
5357
|
}
|
|
5127
5358
|
const statusEntry = resolveStatusColor(node.status, statusColorMap);
|
|
5128
|
-
const isUnknown = node
|
|
5129
|
-
const fillColor = isUnknown ? `url(#${
|
|
5130
|
-
const strokeColor = isUnknown ?
|
|
5359
|
+
const isUnknown = isUnknownNode(node);
|
|
5360
|
+
const fillColor = isUnknown ? `url(#${hatchPatternId})` : node.customColors?.fill ?? statusEntry.fill;
|
|
5361
|
+
const strokeColor = isUnknown ? unknownEntry.stroke : node.customColors?.stroke ?? statusEntry.stroke;
|
|
5131
5362
|
const appearance = { ...getAppearanceDefaults(node.symbolId), ...node.metadata ?? {} };
|
|
5132
5363
|
const ledStyle = {};
|
|
5133
5364
|
if (appearance.shape !== void 0) {
|
|
@@ -5138,7 +5369,8 @@ function NodeRendererImpl({
|
|
|
5138
5369
|
ledStyle["--led-bezel"] = appearance.led ? "2" : "0";
|
|
5139
5370
|
}
|
|
5140
5371
|
if (appearance.glow) {
|
|
5141
|
-
|
|
5372
|
+
const glowColor = isUnknown ? unknownEntry.stroke : fillColor;
|
|
5373
|
+
ledStyle.filter = `drop-shadow(0 0 4px ${glowColor})`;
|
|
5142
5374
|
}
|
|
5143
5375
|
const ledAnimation = typeof appearance.animation === "string" && appearance.animation !== "none" ? appearance.animation : void 0;
|
|
5144
5376
|
const vb = symbol.viewBox;
|
|
@@ -5161,7 +5393,7 @@ function NodeRendererImpl({
|
|
|
5161
5393
|
labelY = vb.height / 2 + oy;
|
|
5162
5394
|
labelAnchor = "start";
|
|
5163
5395
|
}
|
|
5164
|
-
return /* @__PURE__ */ (0,
|
|
5396
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
5165
5397
|
"g",
|
|
5166
5398
|
{
|
|
5167
5399
|
"data-node-id": node.id,
|
|
@@ -5169,7 +5401,7 @@ function NodeRendererImpl({
|
|
|
5169
5401
|
"data-selected": isSelected,
|
|
5170
5402
|
"data-dragging": isDragging,
|
|
5171
5403
|
"data-led-animation": ledAnimation,
|
|
5172
|
-
"data-position-unknown":
|
|
5404
|
+
"data-position-unknown": node.positionUnknown === true ? "true" : void 0,
|
|
5173
5405
|
transform: transforms.join(" "),
|
|
5174
5406
|
style: {
|
|
5175
5407
|
"--symbol-fill": fillColor,
|
|
@@ -5197,7 +5429,7 @@ function NodeRendererImpl({
|
|
|
5197
5429
|
}
|
|
5198
5430
|
},
|
|
5199
5431
|
children: [
|
|
5200
|
-
isSelected && /* @__PURE__ */ (0,
|
|
5432
|
+
isSelected && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5201
5433
|
"rect",
|
|
5202
5434
|
{
|
|
5203
5435
|
x: "-5",
|
|
@@ -5212,7 +5444,7 @@ function NodeRendererImpl({
|
|
|
5212
5444
|
pointerEvents: "none"
|
|
5213
5445
|
}
|
|
5214
5446
|
),
|
|
5215
|
-
/* @__PURE__ */ (0,
|
|
5447
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5216
5448
|
"g",
|
|
5217
5449
|
{
|
|
5218
5450
|
dangerouslySetInnerHTML: { __html: symbol.svgContent },
|
|
@@ -5220,7 +5452,7 @@ function NodeRendererImpl({
|
|
|
5220
5452
|
style: { pointerEvents: "auto" }
|
|
5221
5453
|
}
|
|
5222
5454
|
),
|
|
5223
|
-
/* @__PURE__ */ (0,
|
|
5455
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5224
5456
|
"text",
|
|
5225
5457
|
{
|
|
5226
5458
|
x: labelX,
|
|
@@ -5232,7 +5464,8 @@ function NodeRendererImpl({
|
|
|
5232
5464
|
transform: node.transform.rotation ? `rotate(${-node.transform.rotation}, ${labelX}, ${labelY})` : void 0,
|
|
5233
5465
|
children: node.label || node.id
|
|
5234
5466
|
}
|
|
5235
|
-
)
|
|
5467
|
+
),
|
|
5468
|
+
node.badge && renderNodeBadge(node.badge, vb, node.transform.rotation)
|
|
5236
5469
|
]
|
|
5237
5470
|
},
|
|
5238
5471
|
node.id
|
|
@@ -5240,11 +5473,11 @@ function NodeRendererImpl({
|
|
|
5240
5473
|
})
|
|
5241
5474
|
] });
|
|
5242
5475
|
}
|
|
5243
|
-
var NodeRenderer =
|
|
5476
|
+
var NodeRenderer = import_react11.default.memo(NodeRendererImpl);
|
|
5244
5477
|
|
|
5245
5478
|
// src/components/PIDCanvas/PipeRenderer.tsx
|
|
5246
|
-
var
|
|
5247
|
-
var
|
|
5479
|
+
var import_react12 = __toESM(require("react"), 1);
|
|
5480
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
5248
5481
|
function PipeRendererImpl({
|
|
5249
5482
|
pipes,
|
|
5250
5483
|
selectedPipeIds,
|
|
@@ -5259,7 +5492,7 @@ function PipeRendererImpl({
|
|
|
5259
5492
|
waypointDragOffset,
|
|
5260
5493
|
onPipeSegmentClick
|
|
5261
5494
|
}) {
|
|
5262
|
-
return /* @__PURE__ */ (0,
|
|
5495
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("g", { id: "layer-pipes", children: pipes.filter((pipe) => pipe.visible !== false).map((pipe) => {
|
|
5263
5496
|
const isSelected = selectedPipeIds?.has(pipe.id) ?? false;
|
|
5264
5497
|
const isEditing = enableWaypointEditing && editingPipeId === pipe.id;
|
|
5265
5498
|
const showEditingControls = enableWaypointEditing && isSelected;
|
|
@@ -5278,7 +5511,7 @@ function PipeRendererImpl({
|
|
|
5278
5511
|
const strokeWidth = isSelected ? (pipeStyle.strokeWidth || 3) + 2 : pipeStyle.strokeWidth || 3;
|
|
5279
5512
|
const strokeDasharray = pipeStyle.strokeDasharray;
|
|
5280
5513
|
const opacity = pipeStyle.opacity !== void 0 ? pipeStyle.opacity : 1;
|
|
5281
|
-
return /* @__PURE__ */ (0,
|
|
5514
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
5282
5515
|
"g",
|
|
5283
5516
|
{
|
|
5284
5517
|
"data-pipe-id": pipe.id,
|
|
@@ -5291,8 +5524,8 @@ function PipeRendererImpl({
|
|
|
5291
5524
|
cursor: onPipeClick ? "pointer" : "default"
|
|
5292
5525
|
},
|
|
5293
5526
|
children: [
|
|
5294
|
-
!enableWaypointEditing && /* @__PURE__ */ (0,
|
|
5295
|
-
onPipeClick && /* @__PURE__ */ (0,
|
|
5527
|
+
!enableWaypointEditing && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
5528
|
+
onPipeClick && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5296
5529
|
"polyline",
|
|
5297
5530
|
{
|
|
5298
5531
|
points: pointsString,
|
|
@@ -5304,7 +5537,7 @@ function PipeRendererImpl({
|
|
|
5304
5537
|
pointerEvents: "stroke"
|
|
5305
5538
|
}
|
|
5306
5539
|
),
|
|
5307
|
-
/* @__PURE__ */ (0,
|
|
5540
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5308
5541
|
"polyline",
|
|
5309
5542
|
{
|
|
5310
5543
|
points: pointsString,
|
|
@@ -5328,7 +5561,7 @@ function PipeRendererImpl({
|
|
|
5328
5561
|
const waypointSize = isSelectedWaypoint ? 8 : isDragging ? 8 : showEditingControls ? 6 : isSelected ? 3 : 2;
|
|
5329
5562
|
const waypointOpacity = isSelectedWaypoint ? 1 : isDragging ? 1 : showEditingControls ? 0.9 : isSelected ? 0.8 : 0.5;
|
|
5330
5563
|
const waypointColor = isSelectedWaypoint ? "#3b82f6" : isEndpoint && showEditingControls ? "#f59e0b" : isDragging ? "#10b981" : stroke;
|
|
5331
|
-
return /* @__PURE__ */ (0,
|
|
5564
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5332
5565
|
"circle",
|
|
5333
5566
|
{
|
|
5334
5567
|
cx: point.x,
|
|
@@ -5365,12 +5598,12 @@ function PipeRendererImpl({
|
|
|
5365
5598
|
`${pipe.id}-point-${idx}`
|
|
5366
5599
|
);
|
|
5367
5600
|
}),
|
|
5368
|
-
showEditingControls && onPipeSegmentClick && displayPoints.length >= 2 && /* @__PURE__ */ (0,
|
|
5601
|
+
showEditingControls && onPipeSegmentClick && displayPoints.length >= 2 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_jsx_runtime18.Fragment, { children: displayPoints.slice(0, -1).map((point, idx) => {
|
|
5369
5602
|
const nextPoint = displayPoints[idx + 1];
|
|
5370
5603
|
const midX = (point.x + nextPoint.x) / 2;
|
|
5371
5604
|
const midY = (point.y + nextPoint.y) / 2;
|
|
5372
|
-
return /* @__PURE__ */ (0,
|
|
5373
|
-
/* @__PURE__ */ (0,
|
|
5605
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("g", { children: [
|
|
5606
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5374
5607
|
"circle",
|
|
5375
5608
|
{
|
|
5376
5609
|
cx: midX,
|
|
@@ -5386,7 +5619,7 @@ function PipeRendererImpl({
|
|
|
5386
5619
|
}
|
|
5387
5620
|
}
|
|
5388
5621
|
),
|
|
5389
|
-
/* @__PURE__ */ (0,
|
|
5622
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5390
5623
|
"circle",
|
|
5391
5624
|
{
|
|
5392
5625
|
cx: midX,
|
|
@@ -5402,7 +5635,7 @@ function PipeRendererImpl({
|
|
|
5402
5635
|
)
|
|
5403
5636
|
] }, `${pipe.id}-segment-${idx}`);
|
|
5404
5637
|
}) }),
|
|
5405
|
-
pipe.showLabel !== false && pipe.label && pipe.routePoints.length >= 2 && /* @__PURE__ */ (0,
|
|
5638
|
+
pipe.showLabel !== false && pipe.label && pipe.routePoints.length >= 2 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5406
5639
|
"text",
|
|
5407
5640
|
{
|
|
5408
5641
|
x: pipe.routePoints[Math.floor(pipe.routePoints.length / 2)].x + (pipe.labelOffset?.x ?? 0),
|
|
@@ -5422,11 +5655,11 @@ function PipeRendererImpl({
|
|
|
5422
5655
|
);
|
|
5423
5656
|
}) });
|
|
5424
5657
|
}
|
|
5425
|
-
var PipeRenderer =
|
|
5658
|
+
var PipeRenderer = import_react12.default.memo(PipeRendererImpl);
|
|
5426
5659
|
|
|
5427
5660
|
// src/components/PIDCanvas/DataOverlay.tsx
|
|
5428
|
-
var
|
|
5429
|
-
var
|
|
5661
|
+
var import_react13 = __toESM(require("react"), 1);
|
|
5662
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
5430
5663
|
var PULSE_KEYFRAME_ID = "pid-data-overlay-pulse-keyframes";
|
|
5431
5664
|
var PULSE_ANIMATION = "pid-data-overlay-pulse 1.5s ease-in-out infinite";
|
|
5432
5665
|
function ensurePulseKeyframes() {
|
|
@@ -5437,9 +5670,10 @@ function ensurePulseKeyframes() {
|
|
|
5437
5670
|
style.textContent = "@keyframes pid-data-overlay-pulse{0%{opacity:.9}50%{opacity:.3}100%{opacity:.9}}";
|
|
5438
5671
|
document.head.appendChild(style);
|
|
5439
5672
|
}
|
|
5440
|
-
function renderStatusDot(cx, cy, scale, fill) {
|
|
5441
|
-
|
|
5442
|
-
|
|
5673
|
+
function renderStatusDot(cx, cy, scale, fill, status) {
|
|
5674
|
+
const isUnknown = normalizeDeviceStatus(status) === "unknown";
|
|
5675
|
+
if (!isUnknown) ensurePulseKeyframes();
|
|
5676
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5443
5677
|
"circle",
|
|
5444
5678
|
{
|
|
5445
5679
|
className: "pid-data-overlay-status-dot",
|
|
@@ -5447,7 +5681,7 @@ function renderStatusDot(cx, cy, scale, fill) {
|
|
|
5447
5681
|
cy: cy - 18 * scale,
|
|
5448
5682
|
r: 3 * scale,
|
|
5449
5683
|
fill,
|
|
5450
|
-
style: { animation: PULSE_ANIMATION }
|
|
5684
|
+
style: isUnknown ? void 0 : { animation: PULSE_ANIMATION }
|
|
5451
5685
|
}
|
|
5452
5686
|
);
|
|
5453
5687
|
}
|
|
@@ -5473,7 +5707,7 @@ function DataOverlayImpl({
|
|
|
5473
5707
|
const backgroundColor = display?.backgroundColor;
|
|
5474
5708
|
const offsetX = display?.offsetX ?? 0;
|
|
5475
5709
|
const offsetY = display?.offsetY ?? 0;
|
|
5476
|
-
const sparklinePath =
|
|
5710
|
+
const sparklinePath = import_react13.default.useMemo(() => {
|
|
5477
5711
|
if (!showSparkline || !history || history.length < 2) return "";
|
|
5478
5712
|
const width = 70 * scale;
|
|
5479
5713
|
const height = 20 * scale;
|
|
@@ -5492,7 +5726,7 @@ function DataOverlayImpl({
|
|
|
5492
5726
|
return `M ${points.join(" L ")}`;
|
|
5493
5727
|
}, [showSparkline, history, scaling, scale]);
|
|
5494
5728
|
if (!showValue) {
|
|
5495
|
-
return /* @__PURE__ */ (0,
|
|
5729
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_jsx_runtime19.Fragment, {});
|
|
5496
5730
|
}
|
|
5497
5731
|
const formatValue = (val) => {
|
|
5498
5732
|
if (typeof val === "number") {
|
|
@@ -5517,10 +5751,11 @@ function DataOverlayImpl({
|
|
|
5517
5751
|
const extraMarkRows = realDisplayText ? 1 : 0;
|
|
5518
5752
|
const overlayHeight = (label ? hasSparkline ? 55 : 30 : hasSparkline ? 47 : 22) * scale + extraMarkRows * 9 * scale;
|
|
5519
5753
|
const overlayWidth = 80 * scale;
|
|
5754
|
+
const isUnknownValue = normalizeDeviceStatus(value.status) === "unknown";
|
|
5520
5755
|
const displayX = x + offsetX;
|
|
5521
5756
|
const displayY = y + offsetY;
|
|
5522
|
-
return /* @__PURE__ */ (0,
|
|
5523
|
-
/* @__PURE__ */ (0,
|
|
5757
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("g", { "data-overlay-node": nodeId, "data-status": value.status, "data-forced": isForced, children: [
|
|
5758
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5524
5759
|
"rect",
|
|
5525
5760
|
{
|
|
5526
5761
|
x: displayX - overlayWidth / 2,
|
|
@@ -5535,7 +5770,7 @@ function DataOverlayImpl({
|
|
|
5535
5770
|
filter: "drop-shadow(0 2px 4px rgba(0,0,0,0.2))"
|
|
5536
5771
|
}
|
|
5537
5772
|
),
|
|
5538
|
-
label && /* @__PURE__ */ (0,
|
|
5773
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5539
5774
|
"text",
|
|
5540
5775
|
{
|
|
5541
5776
|
x: displayX,
|
|
@@ -5548,7 +5783,7 @@ function DataOverlayImpl({
|
|
|
5548
5783
|
children: label
|
|
5549
5784
|
}
|
|
5550
5785
|
),
|
|
5551
|
-
/* @__PURE__ */ (0,
|
|
5786
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5552
5787
|
"text",
|
|
5553
5788
|
{
|
|
5554
5789
|
x: displayX,
|
|
@@ -5561,8 +5796,17 @@ function DataOverlayImpl({
|
|
|
5561
5796
|
children: displayText
|
|
5562
5797
|
}
|
|
5563
5798
|
),
|
|
5564
|
-
showStatus && value.status !== "normal" && renderStatusDot(displayX, displayY, scale, finalTextColor),
|
|
5565
|
-
|
|
5799
|
+
showStatus && value.status !== "normal" && renderStatusDot(displayX, displayY, scale, finalTextColor, value.status),
|
|
5800
|
+
showStatus && isUnknownValue && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5801
|
+
UnknownStatusGlyph,
|
|
5802
|
+
{
|
|
5803
|
+
x: displayX - overlayWidth / 2 + 2 * scale,
|
|
5804
|
+
y: displayY - 25 * scale - 6 * scale,
|
|
5805
|
+
width: 12 * scale,
|
|
5806
|
+
height: 12 * scale
|
|
5807
|
+
}
|
|
5808
|
+
),
|
|
5809
|
+
value.quality !== void 0 && value.quality < 100 && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
5566
5810
|
"text",
|
|
5567
5811
|
{
|
|
5568
5812
|
x: displayX,
|
|
@@ -5579,13 +5823,13 @@ function DataOverlayImpl({
|
|
|
5579
5823
|
]
|
|
5580
5824
|
}
|
|
5581
5825
|
),
|
|
5582
|
-
isForced && /* @__PURE__ */ (0,
|
|
5826
|
+
isForced && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
5583
5827
|
"g",
|
|
5584
5828
|
{
|
|
5585
5829
|
transform: `translate(${displayX + overlayWidth / 2}, ${displayY - 25 * scale})`,
|
|
5586
5830
|
"aria-label": "Forced",
|
|
5587
5831
|
children: [
|
|
5588
|
-
/* @__PURE__ */ (0,
|
|
5832
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5589
5833
|
"circle",
|
|
5590
5834
|
{
|
|
5591
5835
|
r: 7 * scale,
|
|
@@ -5594,7 +5838,7 @@ function DataOverlayImpl({
|
|
|
5594
5838
|
strokeWidth: 1.5 * scale
|
|
5595
5839
|
}
|
|
5596
5840
|
),
|
|
5597
|
-
/* @__PURE__ */ (0,
|
|
5841
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5598
5842
|
"text",
|
|
5599
5843
|
{
|
|
5600
5844
|
textAnchor: "middle",
|
|
@@ -5608,7 +5852,7 @@ function DataOverlayImpl({
|
|
|
5608
5852
|
]
|
|
5609
5853
|
}
|
|
5610
5854
|
),
|
|
5611
|
-
realDisplayText && /* @__PURE__ */ (0,
|
|
5855
|
+
realDisplayText && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5612
5856
|
"text",
|
|
5613
5857
|
{
|
|
5614
5858
|
x: displayX,
|
|
@@ -5621,7 +5865,7 @@ function DataOverlayImpl({
|
|
|
5621
5865
|
children: realDisplayText
|
|
5622
5866
|
}
|
|
5623
5867
|
),
|
|
5624
|
-
hasSparkline && /* @__PURE__ */ (0,
|
|
5868
|
+
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
5869
|
"path",
|
|
5626
5870
|
{
|
|
5627
5871
|
d: sparklinePath,
|
|
@@ -5635,11 +5879,11 @@ function DataOverlayImpl({
|
|
|
5635
5879
|
) })
|
|
5636
5880
|
] });
|
|
5637
5881
|
}
|
|
5638
|
-
var DataOverlay =
|
|
5882
|
+
var DataOverlay = import_react13.default.memo(DataOverlayImpl);
|
|
5639
5883
|
|
|
5640
5884
|
// src/components/PIDCanvas/PositionPanel.tsx
|
|
5641
|
-
var
|
|
5642
|
-
var
|
|
5885
|
+
var import_react14 = require("react");
|
|
5886
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
5643
5887
|
function PositionPanel({
|
|
5644
5888
|
selectedNode,
|
|
5645
5889
|
selectedWaypoint,
|
|
@@ -5647,9 +5891,9 @@ function PositionPanel({
|
|
|
5647
5891
|
onWaypointPositionChange,
|
|
5648
5892
|
position = "top-right"
|
|
5649
5893
|
}) {
|
|
5650
|
-
const [x, setX] = (0,
|
|
5651
|
-
const [y, setY] = (0,
|
|
5652
|
-
(0,
|
|
5894
|
+
const [x, setX] = (0, import_react14.useState)("");
|
|
5895
|
+
const [y, setY] = (0, import_react14.useState)("");
|
|
5896
|
+
(0, import_react14.useEffect)(() => {
|
|
5653
5897
|
if (selectedNode) {
|
|
5654
5898
|
setX(selectedNode.transform.x.toFixed(2));
|
|
5655
5899
|
setY(selectedNode.transform.y.toFixed(2));
|
|
@@ -5708,7 +5952,7 @@ function PositionPanel({
|
|
|
5708
5952
|
"bottom-left": { bottom: 10, left: 10 },
|
|
5709
5953
|
"bottom-right": { bottom: 10, right: 10 }
|
|
5710
5954
|
};
|
|
5711
|
-
return /* @__PURE__ */ (0,
|
|
5955
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
5712
5956
|
"div",
|
|
5713
5957
|
{
|
|
5714
5958
|
style: {
|
|
@@ -5725,11 +5969,11 @@ function PositionPanel({
|
|
|
5725
5969
|
fontSize: "13px"
|
|
5726
5970
|
},
|
|
5727
5971
|
children: [
|
|
5728
|
-
/* @__PURE__ */ (0,
|
|
5729
|
-
/* @__PURE__ */ (0,
|
|
5730
|
-
/* @__PURE__ */ (0,
|
|
5731
|
-
/* @__PURE__ */ (0,
|
|
5732
|
-
/* @__PURE__ */ (0,
|
|
5972
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { marginBottom: "8px", fontWeight: 600, color: "#333" }, children: "Position" }),
|
|
5973
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "8px" }, children: [
|
|
5974
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
|
|
5975
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("label", { style: { width: "16px", color: "#666" }, children: "X:" }),
|
|
5976
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5733
5977
|
"input",
|
|
5734
5978
|
{
|
|
5735
5979
|
type: "number",
|
|
@@ -5747,9 +5991,9 @@ function PositionPanel({
|
|
|
5747
5991
|
}
|
|
5748
5992
|
)
|
|
5749
5993
|
] }),
|
|
5750
|
-
/* @__PURE__ */ (0,
|
|
5751
|
-
/* @__PURE__ */ (0,
|
|
5752
|
-
/* @__PURE__ */ (0,
|
|
5994
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
|
|
5995
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("label", { style: { width: "16px", color: "#666" }, children: "Y:" }),
|
|
5996
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5753
5997
|
"input",
|
|
5754
5998
|
{
|
|
5755
5999
|
type: "number",
|
|
@@ -5768,14 +6012,14 @@ function PositionPanel({
|
|
|
5768
6012
|
)
|
|
5769
6013
|
] })
|
|
5770
6014
|
] }),
|
|
5771
|
-
/* @__PURE__ */ (0,
|
|
6015
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { marginTop: "8px", fontSize: "11px", color: "#888" }, children: "Use arrow keys to nudge (\xB11px)" })
|
|
5772
6016
|
]
|
|
5773
6017
|
}
|
|
5774
6018
|
);
|
|
5775
6019
|
}
|
|
5776
6020
|
|
|
5777
6021
|
// src/diagram/hooks/useViewBox.ts
|
|
5778
|
-
var
|
|
6022
|
+
var import_react15 = require("react");
|
|
5779
6023
|
function useViewBox(options) {
|
|
5780
6024
|
const {
|
|
5781
6025
|
initialViewBox,
|
|
@@ -5786,16 +6030,16 @@ function useViewBox(options) {
|
|
|
5786
6030
|
zoomSensitivity = 1e-3,
|
|
5787
6031
|
allowLeftClickPan = true
|
|
5788
6032
|
} = 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,
|
|
6033
|
+
const [viewBox, setViewBox] = (0, import_react15.useState)(initialViewBox);
|
|
6034
|
+
const svgRef = (0, import_react15.useRef)(null);
|
|
6035
|
+
const isPanningRef = (0, import_react15.useRef)(false);
|
|
6036
|
+
const lastMousePosRef = (0, import_react15.useRef)({ x: 0, y: 0 });
|
|
6037
|
+
const spaceKeyDownRef = (0, import_react15.useRef)(false);
|
|
6038
|
+
const lastTouchDistanceRef = (0, import_react15.useRef)(null);
|
|
6039
|
+
const resetViewBox = (0, import_react15.useCallback)(() => {
|
|
5796
6040
|
setViewBox(initialViewBox);
|
|
5797
6041
|
}, [initialViewBox]);
|
|
5798
|
-
const zoomIn = (0,
|
|
6042
|
+
const zoomIn = (0, import_react15.useCallback)(() => {
|
|
5799
6043
|
setViewBox((prev) => {
|
|
5800
6044
|
const currentZoom = initialViewBox.width / prev.width;
|
|
5801
6045
|
const newZoom = Math.min(1 / minZoom, currentZoom * 1.25);
|
|
@@ -5812,7 +6056,7 @@ function useViewBox(options) {
|
|
|
5812
6056
|
};
|
|
5813
6057
|
});
|
|
5814
6058
|
}, [initialViewBox, minZoom]);
|
|
5815
|
-
const zoomOut = (0,
|
|
6059
|
+
const zoomOut = (0, import_react15.useCallback)(() => {
|
|
5816
6060
|
setViewBox((prev) => {
|
|
5817
6061
|
const currentZoom = initialViewBox.width / prev.width;
|
|
5818
6062
|
const newZoom = Math.max(1 / maxZoom, currentZoom * 0.8);
|
|
@@ -5829,7 +6073,7 @@ function useViewBox(options) {
|
|
|
5829
6073
|
};
|
|
5830
6074
|
});
|
|
5831
6075
|
}, [initialViewBox, maxZoom]);
|
|
5832
|
-
const fitToContent = (0,
|
|
6076
|
+
const fitToContent = (0, import_react15.useCallback)((bounds, padding = 50) => {
|
|
5833
6077
|
const contentWidth = bounds.maxX - bounds.minX;
|
|
5834
6078
|
const contentHeight = bounds.maxY - bounds.minY;
|
|
5835
6079
|
if (contentWidth === 0 || contentHeight === 0) {
|
|
@@ -5857,7 +6101,7 @@ function useViewBox(options) {
|
|
|
5857
6101
|
height: newHeight
|
|
5858
6102
|
});
|
|
5859
6103
|
}, [initialViewBox]);
|
|
5860
|
-
(0,
|
|
6104
|
+
(0, import_react15.useEffect)(() => {
|
|
5861
6105
|
if (!enableZoom || !svgRef.current) return;
|
|
5862
6106
|
const svg = svgRef.current;
|
|
5863
6107
|
const handleWheel = (e) => {
|
|
@@ -5890,7 +6134,7 @@ function useViewBox(options) {
|
|
|
5890
6134
|
svg.addEventListener("wheel", handleWheel, { passive: false });
|
|
5891
6135
|
return () => svg.removeEventListener("wheel", handleWheel);
|
|
5892
6136
|
}, [enableZoom, zoomSensitivity, minZoom, initialViewBox]);
|
|
5893
|
-
(0,
|
|
6137
|
+
(0, import_react15.useEffect)(() => {
|
|
5894
6138
|
if (!enablePan || !svgRef.current) return;
|
|
5895
6139
|
const svg = svgRef.current;
|
|
5896
6140
|
const handleMouseDown = (e) => {
|
|
@@ -5966,7 +6210,7 @@ function useViewBox(options) {
|
|
|
5966
6210
|
window.removeEventListener("keyup", handleKeyUp);
|
|
5967
6211
|
};
|
|
5968
6212
|
}, [enablePan, allowLeftClickPan]);
|
|
5969
|
-
(0,
|
|
6213
|
+
(0, import_react15.useEffect)(() => {
|
|
5970
6214
|
if (!svgRef.current) return;
|
|
5971
6215
|
if (!enablePan && !enableZoom) return;
|
|
5972
6216
|
const svg = svgRef.current;
|
|
@@ -6057,7 +6301,7 @@ function useViewBox(options) {
|
|
|
6057
6301
|
svg.removeEventListener("touchend", handleTouchEnd);
|
|
6058
6302
|
};
|
|
6059
6303
|
}, [enablePan, enableZoom, minZoom, initialViewBox]);
|
|
6060
|
-
const screenToWorld = (0,
|
|
6304
|
+
const screenToWorld = (0, import_react15.useCallback)(
|
|
6061
6305
|
(screenX, screenY) => {
|
|
6062
6306
|
const svg = svgRef.current;
|
|
6063
6307
|
if (!svg) return { x: screenX, y: screenY };
|
|
@@ -6096,15 +6340,15 @@ function useViewBox(options) {
|
|
|
6096
6340
|
}
|
|
6097
6341
|
|
|
6098
6342
|
// src/diagram/hooks/useSelection.ts
|
|
6099
|
-
var
|
|
6343
|
+
var import_react16 = require("react");
|
|
6100
6344
|
function useSelection(options = {}) {
|
|
6101
6345
|
const {
|
|
6102
6346
|
multiSelect = true,
|
|
6103
6347
|
initialSelection = { selectedNodeIds: /* @__PURE__ */ new Set(), selectedPipeIds: /* @__PURE__ */ new Set() },
|
|
6104
6348
|
onSelectionChange
|
|
6105
6349
|
} = options;
|
|
6106
|
-
const [selection, setSelection] = (0,
|
|
6107
|
-
const notifyChange = (0,
|
|
6350
|
+
const [selection, setSelection] = (0, import_react16.useState)(initialSelection);
|
|
6351
|
+
const notifyChange = (0, import_react16.useCallback)(
|
|
6108
6352
|
(newSelection) => {
|
|
6109
6353
|
if (onSelectionChange) {
|
|
6110
6354
|
onSelectionChange(newSelection);
|
|
@@ -6112,15 +6356,15 @@ function useSelection(options = {}) {
|
|
|
6112
6356
|
},
|
|
6113
6357
|
[onSelectionChange]
|
|
6114
6358
|
);
|
|
6115
|
-
const isNodeSelected = (0,
|
|
6359
|
+
const isNodeSelected = (0, import_react16.useCallback)(
|
|
6116
6360
|
(nodeId) => selection.selectedNodeIds.has(nodeId),
|
|
6117
6361
|
[selection.selectedNodeIds]
|
|
6118
6362
|
);
|
|
6119
|
-
const isPipeSelected = (0,
|
|
6363
|
+
const isPipeSelected = (0, import_react16.useCallback)(
|
|
6120
6364
|
(pipeId) => selection.selectedPipeIds.has(pipeId),
|
|
6121
6365
|
[selection.selectedPipeIds]
|
|
6122
6366
|
);
|
|
6123
|
-
const selectNode = (0,
|
|
6367
|
+
const selectNode = (0, import_react16.useCallback)(
|
|
6124
6368
|
(nodeId, isMultiSelect = false) => {
|
|
6125
6369
|
setSelection((prev) => {
|
|
6126
6370
|
const newNodeIds = new Set(isMultiSelect && multiSelect ? prev.selectedNodeIds : []);
|
|
@@ -6139,7 +6383,7 @@ function useSelection(options = {}) {
|
|
|
6139
6383
|
},
|
|
6140
6384
|
[multiSelect, notifyChange]
|
|
6141
6385
|
);
|
|
6142
|
-
const selectPipe = (0,
|
|
6386
|
+
const selectPipe = (0, import_react16.useCallback)(
|
|
6143
6387
|
(pipeId, isMultiSelect = false) => {
|
|
6144
6388
|
setSelection((prev) => {
|
|
6145
6389
|
const newPipeIds = new Set(isMultiSelect && multiSelect ? prev.selectedPipeIds : []);
|
|
@@ -6158,7 +6402,7 @@ function useSelection(options = {}) {
|
|
|
6158
6402
|
},
|
|
6159
6403
|
[multiSelect, notifyChange]
|
|
6160
6404
|
);
|
|
6161
|
-
const clearSelection = (0,
|
|
6405
|
+
const clearSelection = (0, import_react16.useCallback)(() => {
|
|
6162
6406
|
const newSelection = {
|
|
6163
6407
|
selectedNodeIds: /* @__PURE__ */ new Set(),
|
|
6164
6408
|
selectedPipeIds: /* @__PURE__ */ new Set()
|
|
@@ -6166,7 +6410,7 @@ function useSelection(options = {}) {
|
|
|
6166
6410
|
setSelection(newSelection);
|
|
6167
6411
|
notifyChange(newSelection);
|
|
6168
6412
|
}, [notifyChange]);
|
|
6169
|
-
const selectNodes = (0,
|
|
6413
|
+
const selectNodes = (0, import_react16.useCallback)(
|
|
6170
6414
|
(nodeIds) => {
|
|
6171
6415
|
const newSelection = {
|
|
6172
6416
|
selectedNodeIds: new Set(nodeIds),
|
|
@@ -6177,7 +6421,7 @@ function useSelection(options = {}) {
|
|
|
6177
6421
|
},
|
|
6178
6422
|
[notifyChange]
|
|
6179
6423
|
);
|
|
6180
|
-
const selectPipes = (0,
|
|
6424
|
+
const selectPipes = (0, import_react16.useCallback)(
|
|
6181
6425
|
(pipeIds) => {
|
|
6182
6426
|
const newSelection = {
|
|
6183
6427
|
selectedNodeIds: /* @__PURE__ */ new Set(),
|
|
@@ -6201,23 +6445,23 @@ function useSelection(options = {}) {
|
|
|
6201
6445
|
}
|
|
6202
6446
|
|
|
6203
6447
|
// src/diagram/hooks/useTelemetry.ts
|
|
6204
|
-
var
|
|
6448
|
+
var import_react17 = require("react");
|
|
6205
6449
|
function useTelemetry(options = {}) {
|
|
6206
6450
|
const {
|
|
6207
6451
|
initialBindings = [],
|
|
6208
6452
|
onTelemetryChange,
|
|
6209
6453
|
refreshInterval = 0
|
|
6210
6454
|
} = options;
|
|
6211
|
-
const [telemetry, setTelemetry] = (0,
|
|
6455
|
+
const [telemetry, setTelemetry] = (0, import_react17.useState)(() => {
|
|
6212
6456
|
const map = /* @__PURE__ */ new Map();
|
|
6213
6457
|
initialBindings.forEach((binding) => {
|
|
6214
6458
|
map.set(binding.nodeId, binding);
|
|
6215
6459
|
});
|
|
6216
6460
|
return map;
|
|
6217
6461
|
});
|
|
6218
|
-
const telemetryRef = (0,
|
|
6462
|
+
const telemetryRef = (0, import_react17.useRef)(telemetry);
|
|
6219
6463
|
telemetryRef.current = telemetry;
|
|
6220
|
-
const notifyChange = (0,
|
|
6464
|
+
const notifyChange = (0, import_react17.useCallback)(
|
|
6221
6465
|
(newTelemetry) => {
|
|
6222
6466
|
if (onTelemetryChange) {
|
|
6223
6467
|
onTelemetryChange(newTelemetry);
|
|
@@ -6225,7 +6469,7 @@ function useTelemetry(options = {}) {
|
|
|
6225
6469
|
},
|
|
6226
6470
|
[onTelemetryChange]
|
|
6227
6471
|
);
|
|
6228
|
-
const updateTelemetry = (0,
|
|
6472
|
+
const updateTelemetry = (0, import_react17.useCallback)(
|
|
6229
6473
|
(nodeId, value) => {
|
|
6230
6474
|
setTelemetry((prev) => {
|
|
6231
6475
|
const newMap = new Map(prev);
|
|
@@ -6255,7 +6499,7 @@ function useTelemetry(options = {}) {
|
|
|
6255
6499
|
},
|
|
6256
6500
|
[notifyChange]
|
|
6257
6501
|
);
|
|
6258
|
-
const updateTelemetryBatch = (0,
|
|
6502
|
+
const updateTelemetryBatch = (0, import_react17.useCallback)(
|
|
6259
6503
|
(updates) => {
|
|
6260
6504
|
setTelemetry((prev) => {
|
|
6261
6505
|
const newMap = new Map(prev);
|
|
@@ -6309,16 +6553,16 @@ function useTelemetry(options = {}) {
|
|
|
6309
6553
|
},
|
|
6310
6554
|
[notifyChange]
|
|
6311
6555
|
);
|
|
6312
|
-
const getTelemetry = (0,
|
|
6556
|
+
const getTelemetry = (0, import_react17.useCallback)(
|
|
6313
6557
|
(nodeId) => telemetryRef.current.get(nodeId),
|
|
6314
6558
|
[]
|
|
6315
6559
|
);
|
|
6316
|
-
const clearTelemetry = (0,
|
|
6560
|
+
const clearTelemetry = (0, import_react17.useCallback)(() => {
|
|
6317
6561
|
const newMap = /* @__PURE__ */ new Map();
|
|
6318
6562
|
setTelemetry(newMap);
|
|
6319
6563
|
notifyChange(newMap);
|
|
6320
6564
|
}, [notifyChange]);
|
|
6321
|
-
const setBindings = (0,
|
|
6565
|
+
const setBindings = (0, import_react17.useCallback)(
|
|
6322
6566
|
(bindings) => {
|
|
6323
6567
|
const newMap = /* @__PURE__ */ new Map();
|
|
6324
6568
|
bindings.forEach((binding) => {
|
|
@@ -6329,7 +6573,7 @@ function useTelemetry(options = {}) {
|
|
|
6329
6573
|
},
|
|
6330
6574
|
[notifyChange]
|
|
6331
6575
|
);
|
|
6332
|
-
(0,
|
|
6576
|
+
(0, import_react17.useEffect)(() => {
|
|
6333
6577
|
if (refreshInterval <= 0) return;
|
|
6334
6578
|
const intervalId = setInterval(() => {
|
|
6335
6579
|
notifyChange(telemetryRef.current);
|
|
@@ -6347,10 +6591,10 @@ function useTelemetry(options = {}) {
|
|
|
6347
6591
|
}
|
|
6348
6592
|
|
|
6349
6593
|
// src/diagram/hooks/useTelemetryStatus.ts
|
|
6350
|
-
var
|
|
6594
|
+
var import_react18 = require("react");
|
|
6351
6595
|
function useTelemetryStatus(telemetry, diagram, setDiagram, options = {}) {
|
|
6352
6596
|
const { enabled = true, mapStatus } = options;
|
|
6353
|
-
(0,
|
|
6597
|
+
(0, import_react18.useEffect)(() => {
|
|
6354
6598
|
if (!enabled) return;
|
|
6355
6599
|
const defaultMapStatus = (telemetryStatus) => {
|
|
6356
6600
|
switch (telemetryStatus) {
|
|
@@ -6363,8 +6607,13 @@ function useTelemetryStatus(telemetry, diagram, setDiagram, options = {}) {
|
|
|
6363
6607
|
return "alarm";
|
|
6364
6608
|
case "off":
|
|
6365
6609
|
return "stopped";
|
|
6366
|
-
|
|
6610
|
+
case "unknown":
|
|
6611
|
+
return "unknown";
|
|
6612
|
+
default: {
|
|
6613
|
+
const exhaustive = telemetryStatus;
|
|
6614
|
+
void exhaustive;
|
|
6367
6615
|
return "stopped";
|
|
6616
|
+
}
|
|
6368
6617
|
}
|
|
6369
6618
|
};
|
|
6370
6619
|
const statusMapper = mapStatus || defaultMapStatus;
|
|
@@ -6389,10 +6638,10 @@ function useTelemetryStatus(telemetry, diagram, setDiagram, options = {}) {
|
|
|
6389
6638
|
}
|
|
6390
6639
|
|
|
6391
6640
|
// src/diagram/hooks/useBooleanIndicators.ts
|
|
6392
|
-
var
|
|
6641
|
+
var import_react19 = require("react");
|
|
6393
6642
|
function useBooleanIndicators(telemetry, diagram, setDiagram, options = {}) {
|
|
6394
6643
|
const { enabled = true, symbolId = "status-indicator" } = options;
|
|
6395
|
-
(0,
|
|
6644
|
+
(0, import_react19.useEffect)(() => {
|
|
6396
6645
|
if (!enabled) return;
|
|
6397
6646
|
const tagIndex = /* @__PURE__ */ new Map();
|
|
6398
6647
|
telemetry.forEach((binding) => {
|
|
@@ -6430,7 +6679,7 @@ function useBooleanIndicators(telemetry, diagram, setDiagram, options = {}) {
|
|
|
6430
6679
|
}
|
|
6431
6680
|
|
|
6432
6681
|
// src/diagram/hooks/useDrag.ts
|
|
6433
|
-
var
|
|
6682
|
+
var import_react20 = require("react");
|
|
6434
6683
|
function useDrag(options = {}) {
|
|
6435
6684
|
const {
|
|
6436
6685
|
onDragStart,
|
|
@@ -6440,23 +6689,23 @@ function useDrag(options = {}) {
|
|
|
6440
6689
|
dragThreshold = 3,
|
|
6441
6690
|
screenToWorld = (x, y) => ({ x, y })
|
|
6442
6691
|
} = options;
|
|
6443
|
-
const [dragState, setDragState] = (0,
|
|
6692
|
+
const [dragState, setDragState] = (0, import_react20.useState)({
|
|
6444
6693
|
isDragging: false,
|
|
6445
6694
|
startPosition: null,
|
|
6446
6695
|
offset: { x: 0, y: 0 },
|
|
6447
6696
|
draggedId: null
|
|
6448
6697
|
});
|
|
6449
|
-
const [isListening, setIsListening] = (0,
|
|
6450
|
-
const dragStartRef = (0,
|
|
6451
|
-
const hasMovedRef = (0,
|
|
6452
|
-
const applySnap = (0,
|
|
6698
|
+
const [isListening, setIsListening] = (0, import_react20.useState)(false);
|
|
6699
|
+
const dragStartRef = (0, import_react20.useRef)(null);
|
|
6700
|
+
const hasMovedRef = (0, import_react20.useRef)(false);
|
|
6701
|
+
const applySnap = (0, import_react20.useCallback)(
|
|
6453
6702
|
(value) => {
|
|
6454
6703
|
if (snapToGrid <= 0) return value;
|
|
6455
6704
|
return Math.round(value / snapToGrid) * snapToGrid;
|
|
6456
6705
|
},
|
|
6457
6706
|
[snapToGrid]
|
|
6458
6707
|
);
|
|
6459
|
-
const handleMouseMove = (0,
|
|
6708
|
+
const handleMouseMove = (0, import_react20.useCallback)(
|
|
6460
6709
|
(event) => {
|
|
6461
6710
|
if (!dragStartRef.current) return;
|
|
6462
6711
|
const { id, screenStart: _screenStart, itemPosition, clickOffset } = dragStartRef.current;
|
|
@@ -6497,7 +6746,7 @@ function useDrag(options = {}) {
|
|
|
6497
6746
|
},
|
|
6498
6747
|
[screenToWorld, dragThreshold, applySnap, onDragStart, onDragMove]
|
|
6499
6748
|
);
|
|
6500
|
-
const handleMouseUp = (0,
|
|
6749
|
+
const handleMouseUp = (0, import_react20.useCallback)(
|
|
6501
6750
|
(event) => {
|
|
6502
6751
|
if (!dragStartRef.current || !hasMovedRef.current) {
|
|
6503
6752
|
dragStartRef.current = null;
|
|
@@ -6534,7 +6783,7 @@ function useDrag(options = {}) {
|
|
|
6534
6783
|
},
|
|
6535
6784
|
[screenToWorld, applySnap, onDragEnd]
|
|
6536
6785
|
);
|
|
6537
|
-
const handleTouchMove = (0,
|
|
6786
|
+
const handleTouchMove = (0, import_react20.useCallback)(
|
|
6538
6787
|
(event) => {
|
|
6539
6788
|
if (!dragStartRef.current || event.touches.length !== 1) return;
|
|
6540
6789
|
const touch = event.touches[0];
|
|
@@ -6577,7 +6826,7 @@ function useDrag(options = {}) {
|
|
|
6577
6826
|
},
|
|
6578
6827
|
[screenToWorld, dragThreshold, applySnap, onDragStart, onDragMove]
|
|
6579
6828
|
);
|
|
6580
|
-
const handleTouchEnd = (0,
|
|
6829
|
+
const handleTouchEnd = (0, import_react20.useCallback)(
|
|
6581
6830
|
(event) => {
|
|
6582
6831
|
if (!dragStartRef.current || !hasMovedRef.current) {
|
|
6583
6832
|
dragStartRef.current = null;
|
|
@@ -6615,7 +6864,7 @@ function useDrag(options = {}) {
|
|
|
6615
6864
|
},
|
|
6616
6865
|
[screenToWorld, applySnap, onDragEnd]
|
|
6617
6866
|
);
|
|
6618
|
-
(0,
|
|
6867
|
+
(0, import_react20.useEffect)(() => {
|
|
6619
6868
|
if (!isListening) return;
|
|
6620
6869
|
document.addEventListener("mousemove", handleMouseMove);
|
|
6621
6870
|
document.addEventListener("mouseup", handleMouseUp);
|
|
@@ -6630,7 +6879,7 @@ function useDrag(options = {}) {
|
|
|
6630
6879
|
document.removeEventListener("touchcancel", handleTouchEnd);
|
|
6631
6880
|
};
|
|
6632
6881
|
}, [isListening, handleMouseMove, handleMouseUp, handleTouchMove, handleTouchEnd]);
|
|
6633
|
-
const startDrag = (0,
|
|
6882
|
+
const startDrag = (0, import_react20.useCallback)(
|
|
6634
6883
|
(id, event, itemPosition) => {
|
|
6635
6884
|
event.stopPropagation();
|
|
6636
6885
|
let clientX;
|
|
@@ -6660,7 +6909,7 @@ function useDrag(options = {}) {
|
|
|
6660
6909
|
},
|
|
6661
6910
|
[screenToWorld]
|
|
6662
6911
|
);
|
|
6663
|
-
const cancelDrag = (0,
|
|
6912
|
+
const cancelDrag = (0, import_react20.useCallback)(() => {
|
|
6664
6913
|
dragStartRef.current = null;
|
|
6665
6914
|
hasMovedRef.current = false;
|
|
6666
6915
|
setIsListening(false);
|
|
@@ -6671,7 +6920,7 @@ function useDrag(options = {}) {
|
|
|
6671
6920
|
draggedId: null
|
|
6672
6921
|
});
|
|
6673
6922
|
}, []);
|
|
6674
|
-
const isDraggingItem = (0,
|
|
6923
|
+
const isDraggingItem = (0, import_react20.useCallback)(
|
|
6675
6924
|
(id) => dragState.isDragging && dragState.draggedId === id,
|
|
6676
6925
|
[dragState.isDragging, dragState.draggedId]
|
|
6677
6926
|
);
|
|
@@ -6684,7 +6933,7 @@ function useDrag(options = {}) {
|
|
|
6684
6933
|
}
|
|
6685
6934
|
|
|
6686
6935
|
// src/diagram/hooks/useKeyboardShortcuts.ts
|
|
6687
|
-
var
|
|
6936
|
+
var import_react21 = require("react");
|
|
6688
6937
|
function useKeyboardShortcuts(options) {
|
|
6689
6938
|
const {
|
|
6690
6939
|
onDelete,
|
|
@@ -6695,7 +6944,7 @@ function useKeyboardShortcuts(options) {
|
|
|
6695
6944
|
onSelectAll,
|
|
6696
6945
|
enabled = true
|
|
6697
6946
|
} = options;
|
|
6698
|
-
(0,
|
|
6947
|
+
(0, import_react21.useEffect)(() => {
|
|
6699
6948
|
if (!enabled) return;
|
|
6700
6949
|
const handleKeyDown = (event) => {
|
|
6701
6950
|
const target = event.target;
|
|
@@ -6804,7 +7053,7 @@ function nodeHasPort(node, portId) {
|
|
|
6804
7053
|
}
|
|
6805
7054
|
|
|
6806
7055
|
// src/components/PIDCanvas/PIDCanvas.tsx
|
|
6807
|
-
var
|
|
7056
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
6808
7057
|
var DEFAULT_FEATURES = {
|
|
6809
7058
|
pan: true,
|
|
6810
7059
|
zoom: true,
|
|
@@ -6833,21 +7082,21 @@ function PIDCanvasImpl({
|
|
|
6833
7082
|
statusColorMap,
|
|
6834
7083
|
...props
|
|
6835
7084
|
}) {
|
|
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,
|
|
7085
|
+
const [localDiagram, setLocalDiagram] = (0, import_react22.useState)(diagram);
|
|
7086
|
+
const [dragOverPosition, setDragOverPosition] = (0, import_react22.useState)(null);
|
|
7087
|
+
const [isConnecting, setIsConnecting] = (0, import_react22.useState)(false);
|
|
7088
|
+
const [connectionSource, setConnectionSource] = (0, import_react22.useState)(null);
|
|
7089
|
+
const [connectionSourcePort, setConnectionSourcePort] = (0, import_react22.useState)(null);
|
|
7090
|
+
const [connectionCursor, setConnectionCursor] = (0, import_react22.useState)(null);
|
|
7091
|
+
const [hoveredNode, setHoveredNode] = (0, import_react22.useState)(null);
|
|
7092
|
+
const [hoveredPort, setHoveredPort] = (0, import_react22.useState)(null);
|
|
7093
|
+
const [selectedWaypoint, setSelectedWaypoint] = (0, import_react22.useState)(null);
|
|
7094
|
+
const historyStack = (0, import_react22.useRef)([]);
|
|
7095
|
+
const redoStack = (0, import_react22.useRef)([]);
|
|
7096
|
+
const isUndoRedoAction = (0, import_react22.useRef)(false);
|
|
7097
|
+
const isInternalChange = (0, import_react22.useRef)(false);
|
|
7098
|
+
const lastInternalDiagram = (0, import_react22.useRef)(null);
|
|
7099
|
+
(0, import_react22.useEffect)(() => {
|
|
6851
7100
|
const isExternal = !isInternalChange.current && diagram !== lastInternalDiagram.current;
|
|
6852
7101
|
if (isExternal) {
|
|
6853
7102
|
setLocalDiagram(diagram);
|
|
@@ -6869,7 +7118,7 @@ function PIDCanvasImpl({
|
|
|
6869
7118
|
enablePan: features.pan ?? true,
|
|
6870
7119
|
enableZoom: features.zoom ?? true
|
|
6871
7120
|
});
|
|
6872
|
-
const calculateContentBounds = (0,
|
|
7121
|
+
const calculateContentBounds = (0, import_react22.useCallback)(() => {
|
|
6873
7122
|
const nodes2 = localDiagram.nodes.filter((n) => n.visible !== false);
|
|
6874
7123
|
if (nodes2.length === 0) {
|
|
6875
7124
|
return null;
|
|
@@ -6892,7 +7141,7 @@ function PIDCanvasImpl({
|
|
|
6892
7141
|
});
|
|
6893
7142
|
return { minX, minY, maxX, maxY };
|
|
6894
7143
|
}, [localDiagram.nodes]);
|
|
6895
|
-
(0,
|
|
7144
|
+
(0, import_react22.useEffect)(() => {
|
|
6896
7145
|
if (onMounted) {
|
|
6897
7146
|
const controls = {
|
|
6898
7147
|
fitToContent: (padding = 50) => {
|
|
@@ -6933,8 +7182,8 @@ function PIDCanvasImpl({
|
|
|
6933
7182
|
});
|
|
6934
7183
|
const dragEnabled = features.dragNodes ?? false;
|
|
6935
7184
|
const selectionEnabled = features.selection ?? false;
|
|
6936
|
-
const containerRef = (0,
|
|
6937
|
-
const pushToHistory = (0,
|
|
7185
|
+
const containerRef = (0, import_react22.useRef)(null);
|
|
7186
|
+
const pushToHistory = (0, import_react22.useCallback)((currentDiagram) => {
|
|
6938
7187
|
if (isUndoRedoAction.current) return;
|
|
6939
7188
|
const snapshot = JSON.parse(JSON.stringify(currentDiagram));
|
|
6940
7189
|
historyStack.current.push(snapshot);
|
|
@@ -6943,7 +7192,7 @@ function PIDCanvasImpl({
|
|
|
6943
7192
|
}
|
|
6944
7193
|
redoStack.current = [];
|
|
6945
7194
|
}, []);
|
|
6946
|
-
const undo = (0,
|
|
7195
|
+
const undo = (0, import_react22.useCallback)(() => {
|
|
6947
7196
|
if (historyStack.current.length === 0) return;
|
|
6948
7197
|
isUndoRedoAction.current = true;
|
|
6949
7198
|
const currentSnapshot = JSON.parse(JSON.stringify(localDiagram));
|
|
@@ -6957,7 +7206,7 @@ function PIDCanvasImpl({
|
|
|
6957
7206
|
isUndoRedoAction.current = false;
|
|
6958
7207
|
}, 0);
|
|
6959
7208
|
}, [localDiagram, onDiagramChange]);
|
|
6960
|
-
const redo = (0,
|
|
7209
|
+
const redo = (0, import_react22.useCallback)(() => {
|
|
6961
7210
|
if (redoStack.current.length === 0) return;
|
|
6962
7211
|
isUndoRedoAction.current = true;
|
|
6963
7212
|
const currentSnapshot = JSON.parse(JSON.stringify(localDiagram));
|
|
@@ -6971,7 +7220,7 @@ function PIDCanvasImpl({
|
|
|
6971
7220
|
isUndoRedoAction.current = false;
|
|
6972
7221
|
}, 0);
|
|
6973
7222
|
}, [localDiagram, onDiagramChange]);
|
|
6974
|
-
(0,
|
|
7223
|
+
(0, import_react22.useEffect)(() => {
|
|
6975
7224
|
const handleKeyDown = (e) => {
|
|
6976
7225
|
const isCtrlOrCmd = e.ctrlKey || e.metaKey;
|
|
6977
7226
|
if (isCtrlOrCmd && e.key === "z" && !e.shiftKey) {
|
|
@@ -6988,7 +7237,7 @@ function PIDCanvasImpl({
|
|
|
6988
7237
|
window.addEventListener("keydown", handleKeyDown);
|
|
6989
7238
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
6990
7239
|
}, [undo, redo]);
|
|
6991
|
-
(0,
|
|
7240
|
+
(0, import_react22.useEffect)(() => {
|
|
6992
7241
|
if (!features.dragNodes) return;
|
|
6993
7242
|
const handleKeyDown = (e) => {
|
|
6994
7243
|
if (selection.selectedNodeIds.size === 0 && !selectedWaypoint) return;
|
|
@@ -7073,7 +7322,7 @@ function PIDCanvasImpl({
|
|
|
7073
7322
|
onNodeMove,
|
|
7074
7323
|
pushToHistory
|
|
7075
7324
|
]);
|
|
7076
|
-
const handlePositionChange = (0,
|
|
7325
|
+
const handlePositionChange = (0, import_react22.useCallback)(
|
|
7077
7326
|
(nodeId, x, y) => {
|
|
7078
7327
|
pushToHistory(localDiagram);
|
|
7079
7328
|
const updatedNodes = localDiagram.nodes.map(
|
|
@@ -7095,7 +7344,7 @@ function PIDCanvasImpl({
|
|
|
7095
7344
|
},
|
|
7096
7345
|
[localDiagram, onDiagramChange, onNodeMove, pushToHistory]
|
|
7097
7346
|
);
|
|
7098
|
-
const handleWaypointPositionChange = (0,
|
|
7347
|
+
const handleWaypointPositionChange = (0, import_react22.useCallback)(
|
|
7099
7348
|
(pipeId, pointIndex, x, y) => {
|
|
7100
7349
|
pushToHistory(localDiagram);
|
|
7101
7350
|
const updatedPipes = localDiagram.pipes.map((pipe) => {
|
|
@@ -7113,7 +7362,7 @@ function PIDCanvasImpl({
|
|
|
7113
7362
|
},
|
|
7114
7363
|
[localDiagram, onDiagramChange, pushToHistory]
|
|
7115
7364
|
);
|
|
7116
|
-
const handleDragEnd = (0,
|
|
7365
|
+
const handleDragEnd = (0, import_react22.useCallback)(
|
|
7117
7366
|
(nodeId, offset, finalPosition) => {
|
|
7118
7367
|
const dragDistance = Math.sqrt(offset.x ** 2 + offset.y ** 2);
|
|
7119
7368
|
if (dragDistance < 2) {
|
|
@@ -7194,7 +7443,7 @@ function PIDCanvasImpl({
|
|
|
7194
7443
|
onDiagramChange?.(updatedDiagram);
|
|
7195
7444
|
}
|
|
7196
7445
|
});
|
|
7197
|
-
const handleNodeDragStart = (0,
|
|
7446
|
+
const handleNodeDragStart = (0, import_react22.useCallback)(
|
|
7198
7447
|
(nodeId, event) => {
|
|
7199
7448
|
const node = localDiagram.nodes.find((n) => n.id === nodeId);
|
|
7200
7449
|
if (!node) return;
|
|
@@ -7202,7 +7451,7 @@ function PIDCanvasImpl({
|
|
|
7202
7451
|
},
|
|
7203
7452
|
[localDiagram.nodes, startDrag]
|
|
7204
7453
|
);
|
|
7205
|
-
const handleWaypointClick = (0,
|
|
7454
|
+
const handleWaypointClick = (0, import_react22.useCallback)(
|
|
7206
7455
|
(pipeId, pointIndex) => {
|
|
7207
7456
|
setSelectedWaypoint({ pipeId, pointIndex });
|
|
7208
7457
|
if (selectionEnabled) {
|
|
@@ -7211,7 +7460,7 @@ function PIDCanvasImpl({
|
|
|
7211
7460
|
},
|
|
7212
7461
|
[selectionEnabled, clearSelection]
|
|
7213
7462
|
);
|
|
7214
|
-
const handleWaypointDragStart = (0,
|
|
7463
|
+
const handleWaypointDragStart = (0, import_react22.useCallback)(
|
|
7215
7464
|
(pipeId, pointIndex, event) => {
|
|
7216
7465
|
const pipe = localDiagram.pipes.find((p) => p.id === pipeId);
|
|
7217
7466
|
if (!pipe || pointIndex >= pipe.routePoints.length) return;
|
|
@@ -7220,7 +7469,7 @@ function PIDCanvasImpl({
|
|
|
7220
7469
|
},
|
|
7221
7470
|
[localDiagram.pipes, startWaypointDrag]
|
|
7222
7471
|
);
|
|
7223
|
-
const handlePipeSegmentClick = (0,
|
|
7472
|
+
const handlePipeSegmentClick = (0, import_react22.useCallback)(
|
|
7224
7473
|
(pipeId, position, segmentIndex) => {
|
|
7225
7474
|
pushToHistory(localDiagram);
|
|
7226
7475
|
const updatedPipes = localDiagram.pipes.map((pipe) => {
|
|
@@ -7239,7 +7488,7 @@ function PIDCanvasImpl({
|
|
|
7239
7488
|
[localDiagram, onDiagramChange, pushToHistory]
|
|
7240
7489
|
);
|
|
7241
7490
|
const telemetryEnabled = features.telemetry ?? false;
|
|
7242
|
-
const handleDelete = (0,
|
|
7491
|
+
const handleDelete = (0, import_react22.useCallback)(() => {
|
|
7243
7492
|
if (!selectionEnabled) return;
|
|
7244
7493
|
const { selectedNodeIds, selectedPipeIds } = selection;
|
|
7245
7494
|
if (selectedNodeIds.size === 0 && selectedPipeIds.size === 0) return;
|
|
@@ -7268,17 +7517,17 @@ function PIDCanvasImpl({
|
|
|
7268
7517
|
onDelete,
|
|
7269
7518
|
pushToHistory
|
|
7270
7519
|
]);
|
|
7271
|
-
const handleCopy = (0,
|
|
7520
|
+
const handleCopy = (0, import_react22.useCallback)(() => {
|
|
7272
7521
|
if (!selectionEnabled) return;
|
|
7273
7522
|
const { selectedNodeIds, selectedPipeIds } = selection;
|
|
7274
7523
|
if (selectedNodeIds.size === 0 && selectedPipeIds.size === 0) return;
|
|
7275
7524
|
onItemsCopied?.(Array.from(selectedNodeIds), Array.from(selectedPipeIds));
|
|
7276
7525
|
}, [selection, selectionEnabled, onItemsCopied]);
|
|
7277
|
-
const handlePaste = (0,
|
|
7526
|
+
const handlePaste = (0, import_react22.useCallback)(() => {
|
|
7278
7527
|
if (!selectionEnabled) return;
|
|
7279
7528
|
onPaste?.();
|
|
7280
7529
|
}, [selectionEnabled, onPaste]);
|
|
7281
|
-
const handleNodeDoubleClick = (0,
|
|
7530
|
+
const handleNodeDoubleClick = (0, import_react22.useCallback)(
|
|
7282
7531
|
(nodeId, event) => {
|
|
7283
7532
|
if (!selectionEnabled) return;
|
|
7284
7533
|
console.log("Node double-clicked:", nodeId);
|
|
@@ -7292,7 +7541,7 @@ function PIDCanvasImpl({
|
|
|
7292
7541
|
onCopy: handleCopy,
|
|
7293
7542
|
onPaste: handlePaste
|
|
7294
7543
|
});
|
|
7295
|
-
const handleNodeClick = (0,
|
|
7544
|
+
const handleNodeClick = (0, import_react22.useCallback)(
|
|
7296
7545
|
(nodeId, event) => {
|
|
7297
7546
|
const connectionModeEnabled = features.connectionMode ?? false;
|
|
7298
7547
|
if (connectionModeEnabled && isConnecting) {
|
|
@@ -7334,7 +7583,7 @@ function PIDCanvasImpl({
|
|
|
7334
7583
|
onNodeClick
|
|
7335
7584
|
]
|
|
7336
7585
|
);
|
|
7337
|
-
const handlePipeClick = (0,
|
|
7586
|
+
const handlePipeClick = (0, import_react22.useCallback)(
|
|
7338
7587
|
(pipeId, event) => {
|
|
7339
7588
|
if (selectionEnabled) {
|
|
7340
7589
|
selectPipe(pipeId, event.ctrlKey || event.metaKey);
|
|
@@ -7353,7 +7602,7 @@ function PIDCanvasImpl({
|
|
|
7353
7602
|
}
|
|
7354
7603
|
setSelectedWaypoint(null);
|
|
7355
7604
|
};
|
|
7356
|
-
const handleDragOver = (0,
|
|
7605
|
+
const handleDragOver = (0, import_react22.useCallback)(
|
|
7357
7606
|
(event) => {
|
|
7358
7607
|
if (!features.allowSymbolDrop) return;
|
|
7359
7608
|
event.preventDefault();
|
|
@@ -7364,7 +7613,7 @@ function PIDCanvasImpl({
|
|
|
7364
7613
|
},
|
|
7365
7614
|
[features.allowSymbolDrop, screenToWorld, svgRef]
|
|
7366
7615
|
);
|
|
7367
|
-
const handleDrop = (0,
|
|
7616
|
+
const handleDrop = (0, import_react22.useCallback)(
|
|
7368
7617
|
(event) => {
|
|
7369
7618
|
if (!features.allowSymbolDrop) return;
|
|
7370
7619
|
event.preventDefault();
|
|
@@ -7377,10 +7626,10 @@ function PIDCanvasImpl({
|
|
|
7377
7626
|
},
|
|
7378
7627
|
[features.allowSymbolDrop, screenToWorld, onSymbolDrop, svgRef]
|
|
7379
7628
|
);
|
|
7380
|
-
const handleDragLeave = (0,
|
|
7629
|
+
const handleDragLeave = (0, import_react22.useCallback)(() => {
|
|
7381
7630
|
setDragOverPosition(null);
|
|
7382
7631
|
}, []);
|
|
7383
|
-
const handleMouseMove = (0,
|
|
7632
|
+
const handleMouseMove = (0, import_react22.useCallback)(
|
|
7384
7633
|
(event) => {
|
|
7385
7634
|
const connectionModeEnabled = features.connectionMode ?? false;
|
|
7386
7635
|
if (connectionModeEnabled) {
|
|
@@ -7417,7 +7666,7 @@ function PIDCanvasImpl({
|
|
|
7417
7666
|
const viewBox = controlledViewBox;
|
|
7418
7667
|
const displayDiagram = localDiagram;
|
|
7419
7668
|
const selectedNode = selectionEnabled && selection.selectedNodeIds.size === 1 ? localDiagram.nodes.find((n) => selection.selectedNodeIds.has(n.id)) || null : null;
|
|
7420
|
-
return /* @__PURE__ */ (0,
|
|
7669
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
7421
7670
|
"div",
|
|
7422
7671
|
{
|
|
7423
7672
|
ref: containerRef,
|
|
@@ -7432,7 +7681,7 @@ function PIDCanvasImpl({
|
|
|
7432
7681
|
},
|
|
7433
7682
|
...props,
|
|
7434
7683
|
children: [
|
|
7435
|
-
/* @__PURE__ */ (0,
|
|
7684
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
7436
7685
|
"svg",
|
|
7437
7686
|
{
|
|
7438
7687
|
ref: svgRef,
|
|
@@ -7451,15 +7700,15 @@ function PIDCanvasImpl({
|
|
|
7451
7700
|
onDrop: handleDrop,
|
|
7452
7701
|
onDragLeave: handleDragLeave,
|
|
7453
7702
|
children: [
|
|
7454
|
-
features.showGrid !== false ? /* @__PURE__ */ (0,
|
|
7455
|
-
/* @__PURE__ */ (0,
|
|
7456
|
-
/* @__PURE__ */ (0,
|
|
7457
|
-
/* @__PURE__ */ (0,
|
|
7458
|
-
/* @__PURE__ */ (0,
|
|
7459
|
-
/* @__PURE__ */ (0,
|
|
7703
|
+
features.showGrid !== false ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
7704
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("defs", { children: [
|
|
7705
|
+
/* @__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" }) }),
|
|
7706
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("pattern", { id: "grid-major", width: "25", height: "25", patternUnits: "userSpaceOnUse", children: [
|
|
7707
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("rect", { width: "25", height: "25", fill: "url(#grid-minor)" }),
|
|
7708
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("path", { d: "M 25 0 L 0 0 0 25", fill: "none", stroke: "#d1d5db", strokeWidth: "1" })
|
|
7460
7709
|
] })
|
|
7461
7710
|
] }),
|
|
7462
|
-
/* @__PURE__ */ (0,
|
|
7711
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7463
7712
|
"rect",
|
|
7464
7713
|
{
|
|
7465
7714
|
x: Math.floor(viewBox.x / 25) * 25 - viewBox.width,
|
|
@@ -7469,7 +7718,7 @@ function PIDCanvasImpl({
|
|
|
7469
7718
|
fill: "url(#grid-major)"
|
|
7470
7719
|
}
|
|
7471
7720
|
)
|
|
7472
|
-
] }) : /* @__PURE__ */ (0,
|
|
7721
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7473
7722
|
"rect",
|
|
7474
7723
|
{
|
|
7475
7724
|
x: Math.floor(viewBox.x / 25) * 25 - viewBox.width,
|
|
@@ -7479,7 +7728,7 @@ function PIDCanvasImpl({
|
|
|
7479
7728
|
fill: features.backgroundColor ?? "#ffffff"
|
|
7480
7729
|
}
|
|
7481
7730
|
),
|
|
7482
|
-
/* @__PURE__ */ (0,
|
|
7731
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7483
7732
|
PipeRenderer,
|
|
7484
7733
|
{
|
|
7485
7734
|
pipes: displayDiagram.pipes,
|
|
@@ -7493,7 +7742,7 @@ function PIDCanvasImpl({
|
|
|
7493
7742
|
onPipeSegmentClick: void 0
|
|
7494
7743
|
}
|
|
7495
7744
|
),
|
|
7496
|
-
/* @__PURE__ */ (0,
|
|
7745
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7497
7746
|
NodeRenderer,
|
|
7498
7747
|
{
|
|
7499
7748
|
nodes: displayDiagram.nodes,
|
|
@@ -7507,7 +7756,7 @@ function PIDCanvasImpl({
|
|
|
7507
7756
|
statusColorMap
|
|
7508
7757
|
}
|
|
7509
7758
|
),
|
|
7510
|
-
(features.editPipeRoutes ?? false) && /* @__PURE__ */ (0,
|
|
7759
|
+
(features.editPipeRoutes ?? false) && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7511
7760
|
PipeRenderer,
|
|
7512
7761
|
{
|
|
7513
7762
|
pipes: displayDiagram.pipes,
|
|
@@ -7524,7 +7773,7 @@ function PIDCanvasImpl({
|
|
|
7524
7773
|
onPipeSegmentClick: handlePipeSegmentClick
|
|
7525
7774
|
}
|
|
7526
7775
|
),
|
|
7527
|
-
telemetryEnabled && telemetry && /* @__PURE__ */ (0,
|
|
7776
|
+
telemetryEnabled && telemetry && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("g", { id: "layer-telemetry", children: displayDiagram.nodes.map((node) => {
|
|
7528
7777
|
if (node.symbolId === "status-indicator") return null;
|
|
7529
7778
|
const binding = telemetry.get(node.id);
|
|
7530
7779
|
if (!binding) return null;
|
|
@@ -7532,7 +7781,7 @@ function PIDCanvasImpl({
|
|
|
7532
7781
|
if (!symbol) return null;
|
|
7533
7782
|
const overlayX = node.transform.x + symbol.viewBox.width / 2;
|
|
7534
7783
|
const overlayY = node.transform.y + symbol.viewBox.height + 50;
|
|
7535
|
-
return /* @__PURE__ */ (0,
|
|
7784
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7536
7785
|
DataOverlay,
|
|
7537
7786
|
{
|
|
7538
7787
|
nodeId: node.id,
|
|
@@ -7545,7 +7794,7 @@ function PIDCanvasImpl({
|
|
|
7545
7794
|
`telemetry-${node.id}`
|
|
7546
7795
|
);
|
|
7547
7796
|
}) }),
|
|
7548
|
-
dragOverPosition && /* @__PURE__ */ (0,
|
|
7797
|
+
dragOverPosition && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7549
7798
|
"circle",
|
|
7550
7799
|
{
|
|
7551
7800
|
cx: dragOverPosition.x,
|
|
@@ -7558,7 +7807,7 @@ function PIDCanvasImpl({
|
|
|
7558
7807
|
pointerEvents: "none"
|
|
7559
7808
|
}
|
|
7560
7809
|
),
|
|
7561
|
-
isConnecting && connectionSource && connectionCursor && /* @__PURE__ */ (0,
|
|
7810
|
+
isConnecting && connectionSource && connectionCursor && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("g", { id: "connection-preview", pointerEvents: "none", children: (() => {
|
|
7562
7811
|
const sourceNode = displayDiagram.nodes.find((n) => n.id === connectionSource);
|
|
7563
7812
|
if (!sourceNode) return null;
|
|
7564
7813
|
const symbol = getSymbolDefinition(sourceNode.symbolId);
|
|
@@ -7574,8 +7823,8 @@ function PIDCanvasImpl({
|
|
|
7574
7823
|
}
|
|
7575
7824
|
}
|
|
7576
7825
|
}
|
|
7577
|
-
return /* @__PURE__ */ (0,
|
|
7578
|
-
/* @__PURE__ */ (0,
|
|
7826
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
7827
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7579
7828
|
"circle",
|
|
7580
7829
|
{
|
|
7581
7830
|
cx: lineStartX,
|
|
@@ -7587,7 +7836,7 @@ function PIDCanvasImpl({
|
|
|
7587
7836
|
opacity: 0.6
|
|
7588
7837
|
}
|
|
7589
7838
|
),
|
|
7590
|
-
/* @__PURE__ */ (0,
|
|
7839
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7591
7840
|
"line",
|
|
7592
7841
|
{
|
|
7593
7842
|
x1: lineStartX,
|
|
@@ -7600,7 +7849,7 @@ function PIDCanvasImpl({
|
|
|
7600
7849
|
opacity: 0.8
|
|
7601
7850
|
}
|
|
7602
7851
|
),
|
|
7603
|
-
/* @__PURE__ */ (0,
|
|
7852
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7604
7853
|
"circle",
|
|
7605
7854
|
{
|
|
7606
7855
|
cx: connectionCursor.x,
|
|
@@ -7612,7 +7861,7 @@ function PIDCanvasImpl({
|
|
|
7612
7861
|
)
|
|
7613
7862
|
] });
|
|
7614
7863
|
})() }),
|
|
7615
|
-
features.connectionMode && /* @__PURE__ */ (0,
|
|
7864
|
+
features.connectionMode && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("g", { id: "port-indicators", children: displayDiagram.nodes.map((node) => {
|
|
7616
7865
|
const symbol = getSymbolDefinition(node.symbolId);
|
|
7617
7866
|
if (!symbol?.ports) return null;
|
|
7618
7867
|
return symbol.ports.map((port) => {
|
|
@@ -7620,8 +7869,8 @@ function PIDCanvasImpl({
|
|
|
7620
7869
|
if (!portPos) return null;
|
|
7621
7870
|
const isHovered = hoveredPort === port.id && hoveredNode === node.id;
|
|
7622
7871
|
const isSourcePort = node.id === connectionSource && port.id === connectionSourcePort;
|
|
7623
|
-
return /* @__PURE__ */ (0,
|
|
7624
|
-
/* @__PURE__ */ (0,
|
|
7872
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("g", { children: [
|
|
7873
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7625
7874
|
"circle",
|
|
7626
7875
|
{
|
|
7627
7876
|
cx: portPos.x,
|
|
@@ -7654,7 +7903,7 @@ function PIDCanvasImpl({
|
|
|
7654
7903
|
}
|
|
7655
7904
|
}
|
|
7656
7905
|
),
|
|
7657
|
-
/* @__PURE__ */ (0,
|
|
7906
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7658
7907
|
"circle",
|
|
7659
7908
|
{
|
|
7660
7909
|
cx: portPos.x,
|
|
@@ -7673,7 +7922,7 @@ function PIDCanvasImpl({
|
|
|
7673
7922
|
]
|
|
7674
7923
|
}
|
|
7675
7924
|
),
|
|
7676
|
-
features.dragNodes && /* @__PURE__ */ (0,
|
|
7925
|
+
features.dragNodes && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7677
7926
|
PositionPanel,
|
|
7678
7927
|
{
|
|
7679
7928
|
selectedNode,
|
|
@@ -7691,19 +7940,19 @@ function PIDCanvasImpl({
|
|
|
7691
7940
|
}
|
|
7692
7941
|
);
|
|
7693
7942
|
}
|
|
7694
|
-
var PIDCanvas =
|
|
7943
|
+
var PIDCanvas = import_react22.default.memo(PIDCanvasImpl);
|
|
7695
7944
|
|
|
7696
7945
|
// src/components/SymbolLibrary/SymbolLibrary.tsx
|
|
7697
|
-
var
|
|
7698
|
-
var
|
|
7946
|
+
var import_react23 = require("react");
|
|
7947
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
7699
7948
|
function SymbolLibrary({
|
|
7700
7949
|
className = "",
|
|
7701
7950
|
onSymbolDragStart,
|
|
7702
7951
|
showCategories = true,
|
|
7703
7952
|
categories = ["Valves", "Pumps", "Tanks", "Instruments", "Displays"]
|
|
7704
7953
|
}) {
|
|
7705
|
-
const [selectedCategory, setSelectedCategory] = (0,
|
|
7706
|
-
const [searchQuery, setSearchQuery] = (0,
|
|
7954
|
+
const [selectedCategory, setSelectedCategory] = (0, import_react23.useState)("all");
|
|
7955
|
+
const [searchQuery, setSearchQuery] = (0, import_react23.useState)("");
|
|
7707
7956
|
const symbolIds = getAvailableSymbols();
|
|
7708
7957
|
const allSymbols = symbolIds.map((id) => getSymbolDefinition(id)).filter((symbol) => symbol !== void 0);
|
|
7709
7958
|
const categoryMap = {
|
|
@@ -7724,9 +7973,9 @@ function SymbolLibrary({
|
|
|
7724
7973
|
event.dataTransfer.effectAllowed = "copy";
|
|
7725
7974
|
onSymbolDragStart?.(symbol.id, event);
|
|
7726
7975
|
};
|
|
7727
|
-
return /* @__PURE__ */ (0,
|
|
7728
|
-
/* @__PURE__ */ (0,
|
|
7729
|
-
/* @__PURE__ */ (0,
|
|
7976
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: `symbol-library ${className}`.trim(), style: styles.container, children: [
|
|
7977
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: styles.header, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h3", { style: styles.title, children: "Symbol Library" }) }),
|
|
7978
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: styles.searchContainer, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7730
7979
|
"input",
|
|
7731
7980
|
{
|
|
7732
7981
|
type: "text",
|
|
@@ -7736,8 +7985,8 @@ function SymbolLibrary({
|
|
|
7736
7985
|
style: styles.searchInput
|
|
7737
7986
|
}
|
|
7738
7987
|
) }),
|
|
7739
|
-
showCategories && /* @__PURE__ */ (0,
|
|
7740
|
-
/* @__PURE__ */ (0,
|
|
7988
|
+
showCategories && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: styles.categories, children: [
|
|
7989
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7741
7990
|
"button",
|
|
7742
7991
|
{
|
|
7743
7992
|
onClick: () => setSelectedCategory("all"),
|
|
@@ -7748,7 +7997,7 @@ function SymbolLibrary({
|
|
|
7748
7997
|
children: "All"
|
|
7749
7998
|
}
|
|
7750
7999
|
),
|
|
7751
|
-
categories.map((category) => /* @__PURE__ */ (0,
|
|
8000
|
+
categories.map((category) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7752
8001
|
"button",
|
|
7753
8002
|
{
|
|
7754
8003
|
onClick: () => setSelectedCategory(category),
|
|
@@ -7761,7 +8010,7 @@ function SymbolLibrary({
|
|
|
7761
8010
|
category
|
|
7762
8011
|
))
|
|
7763
8012
|
] }),
|
|
7764
|
-
/* @__PURE__ */ (0,
|
|
8013
|
+
/* @__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
8014
|
"div",
|
|
7766
8015
|
{
|
|
7767
8016
|
draggable: true,
|
|
@@ -7769,15 +8018,15 @@ function SymbolLibrary({
|
|
|
7769
8018
|
style: styles.symbolCard,
|
|
7770
8019
|
title: symbol.metadata?.description || symbol.name,
|
|
7771
8020
|
children: [
|
|
7772
|
-
/* @__PURE__ */ (0,
|
|
8021
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: styles.symbolPreview, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7773
8022
|
"svg",
|
|
7774
8023
|
{
|
|
7775
8024
|
viewBox: `${symbol.viewBox.x} ${symbol.viewBox.y} ${symbol.viewBox.width} ${symbol.viewBox.height}`,
|
|
7776
8025
|
style: styles.symbolSvg,
|
|
7777
|
-
children: /* @__PURE__ */ (0,
|
|
8026
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("g", { dangerouslySetInnerHTML: { __html: symbol.svgContent } })
|
|
7778
8027
|
}
|
|
7779
8028
|
) }),
|
|
7780
|
-
/* @__PURE__ */ (0,
|
|
8029
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: styles.symbolName, children: symbol.name })
|
|
7781
8030
|
]
|
|
7782
8031
|
},
|
|
7783
8032
|
symbol.id
|
|
@@ -7886,7 +8135,7 @@ var styles = {
|
|
|
7886
8135
|
};
|
|
7887
8136
|
|
|
7888
8137
|
// src/components/NodeConfigPanel/NodeConfigPanel.tsx
|
|
7889
|
-
var
|
|
8138
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
7890
8139
|
function NodeConfigPanel({
|
|
7891
8140
|
node,
|
|
7892
8141
|
binding,
|
|
@@ -7909,15 +8158,15 @@ function NodeConfigPanel({
|
|
|
7909
8158
|
};
|
|
7910
8159
|
const appearanceFields = getAppearanceSchema(node.symbolId);
|
|
7911
8160
|
const showGenericTelemetry = appearanceFields.length === 0;
|
|
7912
|
-
return /* @__PURE__ */ (0,
|
|
7913
|
-
/* @__PURE__ */ (0,
|
|
8161
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className, style: defaultStyle, children: [
|
|
8162
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("h2", { style: { margin: "0 0 16px 0", fontSize: "1rem", fontWeight: 600 }, children: [
|
|
7914
8163
|
"Configure: ",
|
|
7915
8164
|
node.id
|
|
7916
8165
|
] }),
|
|
7917
|
-
/* @__PURE__ */ (0,
|
|
7918
|
-
/* @__PURE__ */ (0,
|
|
7919
|
-
/* @__PURE__ */ (0,
|
|
7920
|
-
/* @__PURE__ */ (0,
|
|
8166
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { marginBottom: "20px" }, children: [
|
|
8167
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { style: { fontSize: "0.875rem", fontWeight: 600, marginBottom: "8px" }, children: "Node Settings" }),
|
|
8168
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Label:" }),
|
|
8169
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
7921
8170
|
"input",
|
|
7922
8171
|
{
|
|
7923
8172
|
type: "text",
|
|
@@ -7933,10 +8182,10 @@ function NodeConfigPanel({
|
|
|
7933
8182
|
}
|
|
7934
8183
|
}
|
|
7935
8184
|
),
|
|
7936
|
-
/* @__PURE__ */ (0,
|
|
7937
|
-
/* @__PURE__ */ (0,
|
|
7938
|
-
/* @__PURE__ */ (0,
|
|
7939
|
-
/* @__PURE__ */ (0,
|
|
8185
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: "8px" }, children: [
|
|
8186
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { children: [
|
|
8187
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Label Offset X:" }),
|
|
8188
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
7940
8189
|
"input",
|
|
7941
8190
|
{
|
|
7942
8191
|
type: "number",
|
|
@@ -7957,9 +8206,9 @@ function NodeConfigPanel({
|
|
|
7957
8206
|
}
|
|
7958
8207
|
)
|
|
7959
8208
|
] }),
|
|
7960
|
-
/* @__PURE__ */ (0,
|
|
7961
|
-
/* @__PURE__ */ (0,
|
|
7962
|
-
/* @__PURE__ */ (0,
|
|
8209
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { children: [
|
|
8210
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Label Offset Y:" }),
|
|
8211
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
7963
8212
|
"input",
|
|
7964
8213
|
{
|
|
7965
8214
|
type: "number",
|
|
@@ -7981,9 +8230,9 @@ function NodeConfigPanel({
|
|
|
7981
8230
|
)
|
|
7982
8231
|
] })
|
|
7983
8232
|
] }),
|
|
7984
|
-
/* @__PURE__ */ (0,
|
|
7985
|
-
/* @__PURE__ */ (0,
|
|
7986
|
-
/* @__PURE__ */ (0,
|
|
8233
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { children: [
|
|
8234
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Label Font Size:" }),
|
|
8235
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
7987
8236
|
"input",
|
|
7988
8237
|
{
|
|
7989
8238
|
type: "number",
|
|
@@ -8003,9 +8252,9 @@ function NodeConfigPanel({
|
|
|
8003
8252
|
}
|
|
8004
8253
|
)
|
|
8005
8254
|
] }),
|
|
8006
|
-
/* @__PURE__ */ (0,
|
|
8007
|
-
/* @__PURE__ */ (0,
|
|
8008
|
-
/* @__PURE__ */ (0,
|
|
8255
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { children: [
|
|
8256
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Rotation (degrees):" }),
|
|
8257
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8009
8258
|
"input",
|
|
8010
8259
|
{
|
|
8011
8260
|
type: "number",
|
|
@@ -8030,8 +8279,8 @@ function NodeConfigPanel({
|
|
|
8030
8279
|
)
|
|
8031
8280
|
] })
|
|
8032
8281
|
] }),
|
|
8033
|
-
appearanceFields.length > 0 && /* @__PURE__ */ (0,
|
|
8034
|
-
/* @__PURE__ */ (0,
|
|
8282
|
+
appearanceFields.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { marginBottom: "20px" }, children: [
|
|
8283
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { style: { fontSize: "0.875rem", fontWeight: 600, marginBottom: "8px" }, children: "Appearance" }),
|
|
8035
8284
|
appearanceFields.map((field) => {
|
|
8036
8285
|
const value = readAppearanceValue(node, field);
|
|
8037
8286
|
const fieldLabel = field.label ?? field.key;
|
|
@@ -8044,8 +8293,8 @@ function NodeConfigPanel({
|
|
|
8044
8293
|
};
|
|
8045
8294
|
let control;
|
|
8046
8295
|
if (field.kind === "boolean") {
|
|
8047
|
-
control = /* @__PURE__ */ (0,
|
|
8048
|
-
/* @__PURE__ */ (0,
|
|
8296
|
+
control = /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { style: { fontSize: "0.75rem", display: "block" }, children: [
|
|
8297
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8049
8298
|
"input",
|
|
8050
8299
|
{
|
|
8051
8300
|
type: "checkbox",
|
|
@@ -8057,28 +8306,28 @@ function NodeConfigPanel({
|
|
|
8057
8306
|
fieldLabel
|
|
8058
8307
|
] });
|
|
8059
8308
|
} else if (field.kind === "select") {
|
|
8060
|
-
control = /* @__PURE__ */ (0,
|
|
8061
|
-
/* @__PURE__ */ (0,
|
|
8309
|
+
control = /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
8310
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: [
|
|
8062
8311
|
fieldLabel,
|
|
8063
8312
|
":"
|
|
8064
8313
|
] }),
|
|
8065
|
-
/* @__PURE__ */ (0,
|
|
8314
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8066
8315
|
"select",
|
|
8067
8316
|
{
|
|
8068
8317
|
value: String(value),
|
|
8069
8318
|
onChange: (e) => onUpdateNode(writeAppearanceValue(node, field, e.target.value)),
|
|
8070
8319
|
style: inputStyle,
|
|
8071
|
-
children: field.options?.map((opt) => /* @__PURE__ */ (0,
|
|
8320
|
+
children: field.options?.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("option", { value: opt, children: opt }, opt))
|
|
8072
8321
|
}
|
|
8073
8322
|
)
|
|
8074
8323
|
] });
|
|
8075
8324
|
} else if (field.kind === "number") {
|
|
8076
|
-
control = /* @__PURE__ */ (0,
|
|
8077
|
-
/* @__PURE__ */ (0,
|
|
8325
|
+
control = /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
8326
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: [
|
|
8078
8327
|
fieldLabel,
|
|
8079
8328
|
":"
|
|
8080
8329
|
] }),
|
|
8081
|
-
/* @__PURE__ */ (0,
|
|
8330
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8082
8331
|
"input",
|
|
8083
8332
|
{
|
|
8084
8333
|
type: "number",
|
|
@@ -8093,12 +8342,12 @@ function NodeConfigPanel({
|
|
|
8093
8342
|
const listId = `tags-${node.id}-${field.key}`;
|
|
8094
8343
|
const known = tagValue.length > 0 && availableTags.includes(tagValue);
|
|
8095
8344
|
const unknown = tagValue.length > 0 && !known;
|
|
8096
|
-
control = /* @__PURE__ */ (0,
|
|
8097
|
-
/* @__PURE__ */ (0,
|
|
8345
|
+
control = /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
8346
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: [
|
|
8098
8347
|
fieldLabel,
|
|
8099
8348
|
":"
|
|
8100
8349
|
] }),
|
|
8101
|
-
/* @__PURE__ */ (0,
|
|
8350
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8102
8351
|
"input",
|
|
8103
8352
|
{
|
|
8104
8353
|
type: "text",
|
|
@@ -8112,8 +8361,8 @@ function NodeConfigPanel({
|
|
|
8112
8361
|
}
|
|
8113
8362
|
}
|
|
8114
8363
|
),
|
|
8115
|
-
/* @__PURE__ */ (0,
|
|
8116
|
-
tagValue.length > 0 && /* @__PURE__ */ (0,
|
|
8364
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("datalist", { id: listId, children: availableTags.map((t) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("option", { value: t }, t)) }),
|
|
8365
|
+
tagValue.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8117
8366
|
"div",
|
|
8118
8367
|
{
|
|
8119
8368
|
style: {
|
|
@@ -8126,12 +8375,12 @@ function NodeConfigPanel({
|
|
|
8126
8375
|
)
|
|
8127
8376
|
] });
|
|
8128
8377
|
} else {
|
|
8129
|
-
control = /* @__PURE__ */ (0,
|
|
8130
|
-
/* @__PURE__ */ (0,
|
|
8378
|
+
control = /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
8379
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: [
|
|
8131
8380
|
fieldLabel,
|
|
8132
8381
|
":"
|
|
8133
8382
|
] }),
|
|
8134
|
-
/* @__PURE__ */ (0,
|
|
8383
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8135
8384
|
"input",
|
|
8136
8385
|
{
|
|
8137
8386
|
type: "text",
|
|
@@ -8142,9 +8391,9 @@ function NodeConfigPanel({
|
|
|
8142
8391
|
)
|
|
8143
8392
|
] });
|
|
8144
8393
|
}
|
|
8145
|
-
return /* @__PURE__ */ (0,
|
|
8394
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { marginBottom: "10px" }, children: [
|
|
8146
8395
|
control,
|
|
8147
|
-
field.help && /* @__PURE__ */ (0,
|
|
8396
|
+
field.help && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8148
8397
|
"div",
|
|
8149
8398
|
{
|
|
8150
8399
|
style: {
|
|
@@ -8159,9 +8408,9 @@ function NodeConfigPanel({
|
|
|
8159
8408
|
] }, field.key);
|
|
8160
8409
|
})
|
|
8161
8410
|
] }),
|
|
8162
|
-
showGenericTelemetry && /* @__PURE__ */ (0,
|
|
8163
|
-
/* @__PURE__ */ (0,
|
|
8164
|
-
!binding ? /* @__PURE__ */ (0,
|
|
8411
|
+
showGenericTelemetry && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { marginBottom: "20px" }, children: [
|
|
8412
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { style: { fontSize: "0.875rem", fontWeight: 600, marginBottom: "8px" }, children: "Telemetry Data" }),
|
|
8413
|
+
!binding ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8165
8414
|
"button",
|
|
8166
8415
|
{
|
|
8167
8416
|
onClick: () => {
|
|
@@ -8204,9 +8453,9 @@ function NodeConfigPanel({
|
|
|
8204
8453
|
},
|
|
8205
8454
|
children: "+ Add Telemetry"
|
|
8206
8455
|
}
|
|
8207
|
-
) : /* @__PURE__ */ (0,
|
|
8208
|
-
/* @__PURE__ */ (0,
|
|
8209
|
-
/* @__PURE__ */ (0,
|
|
8456
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
8457
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Tag (attribute):" }),
|
|
8458
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8210
8459
|
"input",
|
|
8211
8460
|
{
|
|
8212
8461
|
type: "text",
|
|
@@ -8226,8 +8475,8 @@ function NodeConfigPanel({
|
|
|
8226
8475
|
}
|
|
8227
8476
|
}
|
|
8228
8477
|
),
|
|
8229
|
-
/* @__PURE__ */ (0,
|
|
8230
|
-
/* @__PURE__ */ (0,
|
|
8478
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Initial Value:" }),
|
|
8479
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8231
8480
|
"input",
|
|
8232
8481
|
{
|
|
8233
8482
|
type: "number",
|
|
@@ -8249,8 +8498,8 @@ function NodeConfigPanel({
|
|
|
8249
8498
|
}
|
|
8250
8499
|
}
|
|
8251
8500
|
),
|
|
8252
|
-
/* @__PURE__ */ (0,
|
|
8253
|
-
/* @__PURE__ */ (0,
|
|
8501
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Unit:" }),
|
|
8502
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8254
8503
|
"input",
|
|
8255
8504
|
{
|
|
8256
8505
|
type: "text",
|
|
@@ -8272,8 +8521,8 @@ function NodeConfigPanel({
|
|
|
8272
8521
|
}
|
|
8273
8522
|
}
|
|
8274
8523
|
),
|
|
8275
|
-
/* @__PURE__ */ (0,
|
|
8276
|
-
/* @__PURE__ */ (0,
|
|
8524
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: [
|
|
8525
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8277
8526
|
"input",
|
|
8278
8527
|
{
|
|
8279
8528
|
type: "checkbox",
|
|
@@ -8295,8 +8544,8 @@ function NodeConfigPanel({
|
|
|
8295
8544
|
),
|
|
8296
8545
|
"Show Sparkline"
|
|
8297
8546
|
] }),
|
|
8298
|
-
/* @__PURE__ */ (0,
|
|
8299
|
-
/* @__PURE__ */ (0,
|
|
8547
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { marginTop: "12px" }, children: [
|
|
8548
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8300
8549
|
"label",
|
|
8301
8550
|
{
|
|
8302
8551
|
style: {
|
|
@@ -8308,10 +8557,10 @@ function NodeConfigPanel({
|
|
|
8308
8557
|
children: "Telemetry Position Offset:"
|
|
8309
8558
|
}
|
|
8310
8559
|
),
|
|
8311
|
-
/* @__PURE__ */ (0,
|
|
8312
|
-
/* @__PURE__ */ (0,
|
|
8313
|
-
/* @__PURE__ */ (0,
|
|
8314
|
-
/* @__PURE__ */ (0,
|
|
8560
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: "8px" }, children: [
|
|
8561
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { children: [
|
|
8562
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "X Offset:" }),
|
|
8563
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8315
8564
|
"input",
|
|
8316
8565
|
{
|
|
8317
8566
|
type: "number",
|
|
@@ -8338,9 +8587,9 @@ function NodeConfigPanel({
|
|
|
8338
8587
|
}
|
|
8339
8588
|
)
|
|
8340
8589
|
] }),
|
|
8341
|
-
/* @__PURE__ */ (0,
|
|
8342
|
-
/* @__PURE__ */ (0,
|
|
8343
|
-
/* @__PURE__ */ (0,
|
|
8590
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { children: [
|
|
8591
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "Y Offset:" }),
|
|
8592
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8344
8593
|
"input",
|
|
8345
8594
|
{
|
|
8346
8595
|
type: "number",
|
|
@@ -8368,8 +8617,8 @@ function NodeConfigPanel({
|
|
|
8368
8617
|
)
|
|
8369
8618
|
] })
|
|
8370
8619
|
] }),
|
|
8371
|
-
/* @__PURE__ */ (0,
|
|
8372
|
-
/* @__PURE__ */ (0,
|
|
8620
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { marginTop: "16px" }, children: [
|
|
8621
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8373
8622
|
"label",
|
|
8374
8623
|
{
|
|
8375
8624
|
style: {
|
|
@@ -8381,10 +8630,10 @@ function NodeConfigPanel({
|
|
|
8381
8630
|
children: "Display Colors:"
|
|
8382
8631
|
}
|
|
8383
8632
|
),
|
|
8384
|
-
/* @__PURE__ */ (0,
|
|
8385
|
-
/* @__PURE__ */ (0,
|
|
8386
|
-
/* @__PURE__ */ (0,
|
|
8387
|
-
/* @__PURE__ */ (0,
|
|
8633
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { marginBottom: "8px" }, children: [
|
|
8634
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "Text Color:" }),
|
|
8635
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { display: "flex", gap: "8px", alignItems: "center" }, children: [
|
|
8636
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8388
8637
|
"input",
|
|
8389
8638
|
{
|
|
8390
8639
|
type: "color",
|
|
@@ -8410,7 +8659,7 @@ function NodeConfigPanel({
|
|
|
8410
8659
|
}
|
|
8411
8660
|
}
|
|
8412
8661
|
),
|
|
8413
|
-
/* @__PURE__ */ (0,
|
|
8662
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8414
8663
|
"input",
|
|
8415
8664
|
{
|
|
8416
8665
|
type: "text",
|
|
@@ -8440,10 +8689,10 @@ function NodeConfigPanel({
|
|
|
8440
8689
|
)
|
|
8441
8690
|
] })
|
|
8442
8691
|
] }),
|
|
8443
|
-
binding.display?.showSparkline && /* @__PURE__ */ (0,
|
|
8444
|
-
/* @__PURE__ */ (0,
|
|
8445
|
-
/* @__PURE__ */ (0,
|
|
8446
|
-
/* @__PURE__ */ (0,
|
|
8692
|
+
binding.display?.showSparkline && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { marginBottom: "8px" }, children: [
|
|
8693
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "Sparkline Color:" }),
|
|
8694
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { display: "flex", gap: "8px", alignItems: "center" }, children: [
|
|
8695
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8447
8696
|
"input",
|
|
8448
8697
|
{
|
|
8449
8698
|
type: "color",
|
|
@@ -8469,7 +8718,7 @@ function NodeConfigPanel({
|
|
|
8469
8718
|
}
|
|
8470
8719
|
}
|
|
8471
8720
|
),
|
|
8472
|
-
/* @__PURE__ */ (0,
|
|
8721
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8473
8722
|
"input",
|
|
8474
8723
|
{
|
|
8475
8724
|
type: "text",
|
|
@@ -8499,9 +8748,9 @@ function NodeConfigPanel({
|
|
|
8499
8748
|
)
|
|
8500
8749
|
] })
|
|
8501
8750
|
] }),
|
|
8502
|
-
/* @__PURE__ */ (0,
|
|
8503
|
-
/* @__PURE__ */ (0,
|
|
8504
|
-
/* @__PURE__ */ (0,
|
|
8751
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { marginBottom: "8px" }, children: [
|
|
8752
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "Background:" }),
|
|
8753
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8505
8754
|
"input",
|
|
8506
8755
|
{
|
|
8507
8756
|
type: "text",
|
|
@@ -8529,12 +8778,12 @@ function NodeConfigPanel({
|
|
|
8529
8778
|
}
|
|
8530
8779
|
}
|
|
8531
8780
|
),
|
|
8532
|
-
/* @__PURE__ */ (0,
|
|
8781
|
+
/* @__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
8782
|
] })
|
|
8534
8783
|
] }),
|
|
8535
8784
|
" "
|
|
8536
8785
|
] }),
|
|
8537
|
-
onRemoveTelemetry && /* @__PURE__ */ (0,
|
|
8786
|
+
onRemoveTelemetry && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8538
8787
|
"button",
|
|
8539
8788
|
{
|
|
8540
8789
|
onClick: onRemoveTelemetry,
|
|
@@ -8554,13 +8803,13 @@ function NodeConfigPanel({
|
|
|
8554
8803
|
)
|
|
8555
8804
|
] })
|
|
8556
8805
|
] }),
|
|
8557
|
-
showGenericTelemetry && binding && /* @__PURE__ */ (0,
|
|
8558
|
-
/* @__PURE__ */ (0,
|
|
8806
|
+
showGenericTelemetry && binding && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { marginBottom: "20px" }, children: [
|
|
8807
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { style: { fontSize: "0.875rem", fontWeight: 600, marginBottom: "8px" }, children: "Thresholds" }),
|
|
8559
8808
|
["highHigh", "high", "low", "lowLow"].map((key) => {
|
|
8560
8809
|
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,
|
|
8810
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { marginBottom: "8px" }, children: [
|
|
8811
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: label }),
|
|
8812
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8564
8813
|
"input",
|
|
8565
8814
|
{
|
|
8566
8815
|
type: "number",
|
|
@@ -8584,8 +8833,8 @@ function NodeConfigPanel({
|
|
|
8584
8833
|
] }, key);
|
|
8585
8834
|
})
|
|
8586
8835
|
] }),
|
|
8587
|
-
showGenericTelemetry && binding && /* @__PURE__ */ (0,
|
|
8588
|
-
/* @__PURE__ */ (0,
|
|
8836
|
+
showGenericTelemetry && binding && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { marginBottom: "20px" }, children: [
|
|
8837
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { style: { fontSize: "0.875rem", fontWeight: 600, marginBottom: "8px" }, children: "Status Colors" }),
|
|
8589
8838
|
["normal", "warning", "alarm", "fault", "off"].map((status) => {
|
|
8590
8839
|
const defaultColors = {
|
|
8591
8840
|
normal: "#10b981",
|
|
@@ -8595,13 +8844,13 @@ function NodeConfigPanel({
|
|
|
8595
8844
|
off: "#6b7280"
|
|
8596
8845
|
};
|
|
8597
8846
|
const label = status === "normal" ? "Normal" : status === "warning" ? "Warning" : status === "alarm" ? "Alarm" : status === "fault" ? "Fault" : "Off";
|
|
8598
|
-
return /* @__PURE__ */ (0,
|
|
8599
|
-
/* @__PURE__ */ (0,
|
|
8847
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { marginBottom: "8px" }, children: [
|
|
8848
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: [
|
|
8600
8849
|
label,
|
|
8601
8850
|
":"
|
|
8602
8851
|
] }),
|
|
8603
|
-
/* @__PURE__ */ (0,
|
|
8604
|
-
/* @__PURE__ */ (0,
|
|
8852
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { display: "flex", gap: "8px", alignItems: "center" }, children: [
|
|
8853
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8605
8854
|
"input",
|
|
8606
8855
|
{
|
|
8607
8856
|
type: "color",
|
|
@@ -8622,7 +8871,7 @@ function NodeConfigPanel({
|
|
|
8622
8871
|
}
|
|
8623
8872
|
}
|
|
8624
8873
|
),
|
|
8625
|
-
/* @__PURE__ */ (0,
|
|
8874
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8626
8875
|
"input",
|
|
8627
8876
|
{
|
|
8628
8877
|
type: "text",
|
|
@@ -8649,7 +8898,7 @@ function NodeConfigPanel({
|
|
|
8649
8898
|
] }, status);
|
|
8650
8899
|
})
|
|
8651
8900
|
] }),
|
|
8652
|
-
/* @__PURE__ */ (0,
|
|
8901
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { marginTop: "20px", paddingTop: "20px", borderTop: "1px solid #cbd5e1" }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8653
8902
|
"button",
|
|
8654
8903
|
{
|
|
8655
8904
|
onClick: onRemove,
|
|
@@ -8926,13 +9175,13 @@ function createControlBinding(nodeId, deviceConfig, actions) {
|
|
|
8926
9175
|
}
|
|
8927
9176
|
|
|
8928
9177
|
// src/hooks/useDeviceControls.ts
|
|
8929
|
-
var
|
|
9178
|
+
var import_react24 = require("react");
|
|
8930
9179
|
function commandKey(nodeId, kind, suffix) {
|
|
8931
9180
|
return suffix ? `${nodeId}:${kind}:${suffix}` : `${nodeId}:${kind}`;
|
|
8932
9181
|
}
|
|
8933
9182
|
function useDeviceControls(initialBindings, options) {
|
|
8934
9183
|
const { commandTimeoutMs } = options ?? {};
|
|
8935
|
-
const [controls, setControls] = (0,
|
|
9184
|
+
const [controls, setControls] = (0, import_react24.useState)(() => {
|
|
8936
9185
|
const map = /* @__PURE__ */ new Map();
|
|
8937
9186
|
if (initialBindings) {
|
|
8938
9187
|
initialBindings.forEach((binding) => {
|
|
@@ -8941,12 +9190,12 @@ function useDeviceControls(initialBindings, options) {
|
|
|
8941
9190
|
}
|
|
8942
9191
|
return map;
|
|
8943
9192
|
});
|
|
8944
|
-
const pendingRef = (0,
|
|
8945
|
-
const [pendingCommands, setPendingCommands] = (0,
|
|
8946
|
-
const syncPending = (0,
|
|
9193
|
+
const pendingRef = (0, import_react24.useRef)(/* @__PURE__ */ new Map());
|
|
9194
|
+
const [pendingCommands, setPendingCommands] = (0, import_react24.useState)(() => /* @__PURE__ */ new Set());
|
|
9195
|
+
const syncPending = (0, import_react24.useCallback)(() => {
|
|
8947
9196
|
setPendingCommands(new Set(pendingRef.current.keys()));
|
|
8948
9197
|
}, []);
|
|
8949
|
-
const updateControl = (0,
|
|
9198
|
+
const updateControl = (0, import_react24.useCallback)((nodeId, updates) => {
|
|
8950
9199
|
setControls((prev) => {
|
|
8951
9200
|
const newMap = new Map(prev);
|
|
8952
9201
|
const existing = newMap.get(nodeId);
|
|
@@ -8960,7 +9209,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
8960
9209
|
return newMap;
|
|
8961
9210
|
});
|
|
8962
9211
|
}, []);
|
|
8963
|
-
const updateControlBatch = (0,
|
|
9212
|
+
const updateControlBatch = (0, import_react24.useCallback)((updates) => {
|
|
8964
9213
|
setControls((prev) => {
|
|
8965
9214
|
const newMap = new Map(prev);
|
|
8966
9215
|
Object.entries(updates).forEach(([nodeId, update]) => {
|
|
@@ -8972,7 +9221,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
8972
9221
|
return newMap;
|
|
8973
9222
|
});
|
|
8974
9223
|
}, []);
|
|
8975
|
-
const updateDeviceState = (0,
|
|
9224
|
+
const updateDeviceState = (0, import_react24.useCallback)(
|
|
8976
9225
|
(nodeId, stateUpdates) => {
|
|
8977
9226
|
setControls((prev) => {
|
|
8978
9227
|
const newMap = new Map(prev);
|
|
@@ -8988,7 +9237,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
8988
9237
|
},
|
|
8989
9238
|
[]
|
|
8990
9239
|
);
|
|
8991
|
-
const updateParameter = (0,
|
|
9240
|
+
const updateParameter = (0, import_react24.useCallback)(
|
|
8992
9241
|
(nodeId, parameterId, value) => {
|
|
8993
9242
|
setControls((prev) => {
|
|
8994
9243
|
const newMap = new Map(prev);
|
|
@@ -9015,27 +9264,27 @@ function useDeviceControls(initialBindings, options) {
|
|
|
9015
9264
|
},
|
|
9016
9265
|
[]
|
|
9017
9266
|
);
|
|
9018
|
-
const setControlBinding = (0,
|
|
9267
|
+
const setControlBinding = (0, import_react24.useCallback)((binding) => {
|
|
9019
9268
|
setControls((prev) => {
|
|
9020
9269
|
const newMap = new Map(prev);
|
|
9021
9270
|
newMap.set(binding.nodeId, binding);
|
|
9022
9271
|
return newMap;
|
|
9023
9272
|
});
|
|
9024
9273
|
}, []);
|
|
9025
|
-
const removeControlBinding = (0,
|
|
9274
|
+
const removeControlBinding = (0, import_react24.useCallback)((nodeId) => {
|
|
9026
9275
|
setControls((prev) => {
|
|
9027
9276
|
const newMap = new Map(prev);
|
|
9028
9277
|
newMap.delete(nodeId);
|
|
9029
9278
|
return newMap;
|
|
9030
9279
|
});
|
|
9031
9280
|
}, []);
|
|
9032
|
-
const getControlBinding = (0,
|
|
9281
|
+
const getControlBinding = (0, import_react24.useCallback)(
|
|
9033
9282
|
(nodeId) => {
|
|
9034
9283
|
return controls.get(nodeId);
|
|
9035
9284
|
},
|
|
9036
9285
|
[controls]
|
|
9037
9286
|
);
|
|
9038
|
-
const isCommandPending = (0,
|
|
9287
|
+
const isCommandPending = (0, import_react24.useCallback)(
|
|
9039
9288
|
(nodeId, kind) => {
|
|
9040
9289
|
if (kind) {
|
|
9041
9290
|
const prefix2 = `${nodeId}:${kind}`;
|
|
@@ -9052,7 +9301,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
9052
9301
|
},
|
|
9053
9302
|
[pendingCommands]
|
|
9054
9303
|
);
|
|
9055
|
-
const markPending = (0,
|
|
9304
|
+
const markPending = (0, import_react24.useCallback)(
|
|
9056
9305
|
(key, delta) => {
|
|
9057
9306
|
const next = (pendingRef.current.get(key) ?? 0) + delta;
|
|
9058
9307
|
if (next > 0) pendingRef.current.set(key, next);
|
|
@@ -9061,7 +9310,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
9061
9310
|
},
|
|
9062
9311
|
[syncPending]
|
|
9063
9312
|
);
|
|
9064
|
-
const runCommand = (0,
|
|
9313
|
+
const runCommand = (0, import_react24.useCallback)(
|
|
9065
9314
|
async (nodeId, key, invoke, messages) => {
|
|
9066
9315
|
const binding = controls.get(nodeId);
|
|
9067
9316
|
if (!binding) return;
|
|
@@ -9101,7 +9350,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
9101
9350
|
},
|
|
9102
9351
|
[controls, updateDeviceState, markPending, commandTimeoutMs]
|
|
9103
9352
|
);
|
|
9104
|
-
const sendModeChange = (0,
|
|
9353
|
+
const sendModeChange = (0, import_react24.useCallback)(
|
|
9105
9354
|
(nodeId, mode) => runCommand(
|
|
9106
9355
|
nodeId,
|
|
9107
9356
|
commandKey(nodeId, "mode"),
|
|
@@ -9110,7 +9359,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
9110
9359
|
),
|
|
9111
9360
|
[runCommand]
|
|
9112
9361
|
);
|
|
9113
|
-
const sendParameterChange = (0,
|
|
9362
|
+
const sendParameterChange = (0, import_react24.useCallback)(
|
|
9114
9363
|
(nodeId, parameterId, value) => runCommand(
|
|
9115
9364
|
nodeId,
|
|
9116
9365
|
commandKey(nodeId, "parameter", parameterId),
|
|
@@ -9119,21 +9368,21 @@ function useDeviceControls(initialBindings, options) {
|
|
|
9119
9368
|
),
|
|
9120
9369
|
[runCommand]
|
|
9121
9370
|
);
|
|
9122
|
-
const sendStartCommand = (0,
|
|
9371
|
+
const sendStartCommand = (0, import_react24.useCallback)(
|
|
9123
9372
|
(nodeId) => runCommand(nodeId, commandKey(nodeId, "start"), (binding) => binding.actions.onStart?.(), {
|
|
9124
9373
|
success: "Start command sent",
|
|
9125
9374
|
failure: "Start command failed"
|
|
9126
9375
|
}),
|
|
9127
9376
|
[runCommand]
|
|
9128
9377
|
);
|
|
9129
|
-
const sendStopCommand = (0,
|
|
9378
|
+
const sendStopCommand = (0, import_react24.useCallback)(
|
|
9130
9379
|
(nodeId) => runCommand(nodeId, commandKey(nodeId, "stop"), (binding) => binding.actions.onStop?.(), {
|
|
9131
9380
|
success: "Stop command sent",
|
|
9132
9381
|
failure: "Stop command failed"
|
|
9133
9382
|
}),
|
|
9134
9383
|
[runCommand]
|
|
9135
9384
|
);
|
|
9136
|
-
const sendCustomAction = (0,
|
|
9385
|
+
const sendCustomAction = (0, import_react24.useCallback)(
|
|
9137
9386
|
(nodeId, actionId) => runCommand(
|
|
9138
9387
|
nodeId,
|
|
9139
9388
|
commandKey(nodeId, "action", actionId),
|
|
@@ -9186,9 +9435,9 @@ function createConfigBinding(nodeId, tag, parameters, actions, options) {
|
|
|
9186
9435
|
}
|
|
9187
9436
|
|
|
9188
9437
|
// src/hooks/useDeviceConfigs.ts
|
|
9189
|
-
var
|
|
9438
|
+
var import_react25 = require("react");
|
|
9190
9439
|
function useDeviceConfigs(initialConfigs) {
|
|
9191
|
-
const [configs, setConfigs] = (0,
|
|
9440
|
+
const [configs, setConfigs] = (0, import_react25.useState)(() => {
|
|
9192
9441
|
const map = /* @__PURE__ */ new Map();
|
|
9193
9442
|
if (initialConfigs) {
|
|
9194
9443
|
initialConfigs.forEach((config) => {
|
|
@@ -9197,13 +9446,13 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
9197
9446
|
}
|
|
9198
9447
|
return map;
|
|
9199
9448
|
});
|
|
9200
|
-
const getConfig = (0,
|
|
9449
|
+
const getConfig = (0, import_react25.useCallback)(
|
|
9201
9450
|
(nodeId) => {
|
|
9202
9451
|
return configs.get(nodeId);
|
|
9203
9452
|
},
|
|
9204
9453
|
[configs]
|
|
9205
9454
|
);
|
|
9206
|
-
const updateConfig = (0,
|
|
9455
|
+
const updateConfig = (0, import_react25.useCallback)((nodeId, updates) => {
|
|
9207
9456
|
setConfigs((prev) => {
|
|
9208
9457
|
const newMap = new Map(prev);
|
|
9209
9458
|
const existing = newMap.get(nodeId);
|
|
@@ -9217,7 +9466,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
9217
9466
|
return newMap;
|
|
9218
9467
|
});
|
|
9219
9468
|
}, []);
|
|
9220
|
-
const updateConfigState = (0,
|
|
9469
|
+
const updateConfigState = (0, import_react25.useCallback)((nodeId, stateUpdates) => {
|
|
9221
9470
|
setConfigs((prev) => {
|
|
9222
9471
|
const newMap = new Map(prev);
|
|
9223
9472
|
const existing = newMap.get(nodeId);
|
|
@@ -9230,7 +9479,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
9230
9479
|
return newMap;
|
|
9231
9480
|
});
|
|
9232
9481
|
}, []);
|
|
9233
|
-
const updateConfigBatch = (0,
|
|
9482
|
+
const updateConfigBatch = (0, import_react25.useCallback)((updates) => {
|
|
9234
9483
|
setConfigs((prev) => {
|
|
9235
9484
|
const newMap = new Map(prev);
|
|
9236
9485
|
Object.entries(updates).forEach(([nodeId, update]) => {
|
|
@@ -9242,7 +9491,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
9242
9491
|
return newMap;
|
|
9243
9492
|
});
|
|
9244
9493
|
}, []);
|
|
9245
|
-
const updateParameterValue = (0,
|
|
9494
|
+
const updateParameterValue = (0, import_react25.useCallback)((nodeId, parameterId, value) => {
|
|
9246
9495
|
setConfigs((prev) => {
|
|
9247
9496
|
const newMap = new Map(prev);
|
|
9248
9497
|
const existing = newMap.get(nodeId);
|
|
@@ -9259,7 +9508,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
9259
9508
|
return newMap;
|
|
9260
9509
|
});
|
|
9261
9510
|
}, []);
|
|
9262
|
-
const applyConfig = (0,
|
|
9511
|
+
const applyConfig = (0, import_react25.useCallback)(
|
|
9263
9512
|
async (nodeId) => {
|
|
9264
9513
|
const config = configs.get(nodeId);
|
|
9265
9514
|
if (!config || !config.actions.onApply) {
|
|
@@ -9292,7 +9541,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
9292
9541
|
},
|
|
9293
9542
|
[configs, updateConfigState]
|
|
9294
9543
|
);
|
|
9295
|
-
const saveConfig = (0,
|
|
9544
|
+
const saveConfig = (0, import_react25.useCallback)(
|
|
9296
9545
|
async (nodeId) => {
|
|
9297
9546
|
const config = configs.get(nodeId);
|
|
9298
9547
|
if (!config || !config.actions.onSave) {
|
|
@@ -9326,7 +9575,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
9326
9575
|
},
|
|
9327
9576
|
[configs, updateConfigState]
|
|
9328
9577
|
);
|
|
9329
|
-
const resetConfig = (0,
|
|
9578
|
+
const resetConfig = (0, import_react25.useCallback)(
|
|
9330
9579
|
async (nodeId) => {
|
|
9331
9580
|
const config = configs.get(nodeId);
|
|
9332
9581
|
if (!config) {
|
|
@@ -9356,7 +9605,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
9356
9605
|
},
|
|
9357
9606
|
[configs, updateConfig, updateConfigState]
|
|
9358
9607
|
);
|
|
9359
|
-
const cancelConfig = (0,
|
|
9608
|
+
const cancelConfig = (0, import_react25.useCallback)(
|
|
9360
9609
|
(nodeId) => {
|
|
9361
9610
|
const config = configs.get(nodeId);
|
|
9362
9611
|
if (config?.actions.onCancel) {
|
|
@@ -9365,7 +9614,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
9365
9614
|
},
|
|
9366
9615
|
[configs]
|
|
9367
9616
|
);
|
|
9368
|
-
const validateConfig = (0,
|
|
9617
|
+
const validateConfig = (0, import_react25.useCallback)(
|
|
9369
9618
|
(nodeId) => {
|
|
9370
9619
|
const config = configs.get(nodeId);
|
|
9371
9620
|
if (!config) {
|
|
@@ -9407,21 +9656,21 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
9407
9656
|
},
|
|
9408
9657
|
[configs, updateConfigState]
|
|
9409
9658
|
);
|
|
9410
|
-
const setConfig = (0,
|
|
9659
|
+
const setConfig = (0, import_react25.useCallback)((config) => {
|
|
9411
9660
|
setConfigs((prev) => {
|
|
9412
9661
|
const newMap = new Map(prev);
|
|
9413
9662
|
newMap.set(config.nodeId, config);
|
|
9414
9663
|
return newMap;
|
|
9415
9664
|
});
|
|
9416
9665
|
}, []);
|
|
9417
|
-
const removeConfig = (0,
|
|
9666
|
+
const removeConfig = (0, import_react25.useCallback)((nodeId) => {
|
|
9418
9667
|
setConfigs((prev) => {
|
|
9419
9668
|
const newMap = new Map(prev);
|
|
9420
9669
|
newMap.delete(nodeId);
|
|
9421
9670
|
return newMap;
|
|
9422
9671
|
});
|
|
9423
9672
|
}, []);
|
|
9424
|
-
const clearConfigs = (0,
|
|
9673
|
+
const clearConfigs = (0, import_react25.useCallback)(() => {
|
|
9425
9674
|
setConfigs(/* @__PURE__ */ new Map());
|
|
9426
9675
|
}, []);
|
|
9427
9676
|
return {
|
|
@@ -9443,8 +9692,8 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
9443
9692
|
}
|
|
9444
9693
|
|
|
9445
9694
|
// src/components/DeviceConfigPanel/DeviceConfigPanel.tsx
|
|
9446
|
-
var
|
|
9447
|
-
var
|
|
9695
|
+
var import_react26 = __toESM(require("react"), 1);
|
|
9696
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
9448
9697
|
function DeviceConfigPanelImpl({
|
|
9449
9698
|
binding,
|
|
9450
9699
|
onClose,
|
|
@@ -9463,7 +9712,7 @@ function DeviceConfigPanelImpl({
|
|
|
9463
9712
|
showBuiltInToast = true,
|
|
9464
9713
|
embedded = false
|
|
9465
9714
|
}) {
|
|
9466
|
-
const [localValues, setLocalValues] = (0,
|
|
9715
|
+
const [localValues, setLocalValues] = (0, import_react26.useState)(() => {
|
|
9467
9716
|
if (binding) {
|
|
9468
9717
|
const values = {};
|
|
9469
9718
|
binding.parameters.forEach((param) => {
|
|
@@ -9473,7 +9722,7 @@ function DeviceConfigPanelImpl({
|
|
|
9473
9722
|
}
|
|
9474
9723
|
return {};
|
|
9475
9724
|
});
|
|
9476
|
-
const [collapsedSections, setCollapsedSections] = (0,
|
|
9725
|
+
const [collapsedSections, setCollapsedSections] = (0, import_react26.useState)(() => {
|
|
9477
9726
|
const collapsed = /* @__PURE__ */ new Set();
|
|
9478
9727
|
if (binding?.sections) {
|
|
9479
9728
|
binding.sections.forEach((section) => {
|
|
@@ -9484,9 +9733,9 @@ function DeviceConfigPanelImpl({
|
|
|
9484
9733
|
}
|
|
9485
9734
|
return collapsed;
|
|
9486
9735
|
});
|
|
9487
|
-
const [showToast, setShowToast] = (0,
|
|
9488
|
-
const [bindingId, setBindingId] = (0,
|
|
9489
|
-
const lastResultTimestampRef = (0,
|
|
9736
|
+
const [showToast, setShowToast] = (0, import_react26.useState)(true);
|
|
9737
|
+
const [bindingId, setBindingId] = (0, import_react26.useState)(binding?.nodeId || null);
|
|
9738
|
+
const lastResultTimestampRef = (0, import_react26.useRef)(0);
|
|
9490
9739
|
if (binding && binding.nodeId !== bindingId) {
|
|
9491
9740
|
const values = {};
|
|
9492
9741
|
binding.parameters.forEach((param) => {
|
|
@@ -9502,7 +9751,7 @@ function DeviceConfigPanelImpl({
|
|
|
9502
9751
|
setCollapsedSections(collapsed);
|
|
9503
9752
|
setBindingId(binding.nodeId);
|
|
9504
9753
|
}
|
|
9505
|
-
(0,
|
|
9754
|
+
(0, import_react26.useEffect)(() => {
|
|
9506
9755
|
const currentTimestamp = binding?.state.lastSaved || 0;
|
|
9507
9756
|
if (binding?.state.lastSaveResult && currentTimestamp !== lastResultTimestampRef.current) {
|
|
9508
9757
|
lastResultTimestampRef.current = currentTimestamp;
|
|
@@ -9519,7 +9768,7 @@ function DeviceConfigPanelImpl({
|
|
|
9519
9768
|
};
|
|
9520
9769
|
}
|
|
9521
9770
|
}, [binding?.state.lastSaveResult, binding?.state.lastSaved, toastDuration]);
|
|
9522
|
-
const parametersBySection = (0,
|
|
9771
|
+
const parametersBySection = (0, import_react26.useMemo)(() => {
|
|
9523
9772
|
if (!binding) return { _unsectioned: [] };
|
|
9524
9773
|
const groups = { _unsectioned: [] };
|
|
9525
9774
|
binding.parameters.forEach((param) => {
|
|
@@ -9534,7 +9783,7 @@ function DeviceConfigPanelImpl({
|
|
|
9534
9783
|
});
|
|
9535
9784
|
return groups;
|
|
9536
9785
|
}, [binding]);
|
|
9537
|
-
const sortedSections = (0,
|
|
9786
|
+
const sortedSections = (0, import_react26.useMemo)(() => {
|
|
9538
9787
|
if (!binding?.sections) return [];
|
|
9539
9788
|
return [...binding.sections].sort((a, b) => (a.order || 0) - (b.order || 0));
|
|
9540
9789
|
}, [binding]);
|
|
@@ -9610,14 +9859,14 @@ function DeviceConfigPanelImpl({
|
|
|
9610
9859
|
const value = localValues[param.id];
|
|
9611
9860
|
const error = binding.state.errors?.[param.id];
|
|
9612
9861
|
const isDisabled = param.readOnly || param.enabled === false;
|
|
9613
|
-
return /* @__PURE__ */ (0,
|
|
9862
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
9614
9863
|
"div",
|
|
9615
9864
|
{
|
|
9616
9865
|
style: {
|
|
9617
9866
|
marginBottom: spacing.marginBottom
|
|
9618
9867
|
},
|
|
9619
9868
|
children: [
|
|
9620
|
-
/* @__PURE__ */ (0,
|
|
9869
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
9621
9870
|
"label",
|
|
9622
9871
|
{
|
|
9623
9872
|
style: {
|
|
@@ -9632,13 +9881,13 @@ function DeviceConfigPanelImpl({
|
|
|
9632
9881
|
},
|
|
9633
9882
|
children: [
|
|
9634
9883
|
param.label,
|
|
9635
|
-
param.required && /* @__PURE__ */ (0,
|
|
9636
|
-
param.unit && /* @__PURE__ */ (0,
|
|
9884
|
+
param.required && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { style: { color: errorColor }, children: " *" }),
|
|
9885
|
+
param.unit && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("span", { style: { color: mutedTextColor, fontWeight: "normal" }, children: [
|
|
9637
9886
|
" (",
|
|
9638
9887
|
param.unit,
|
|
9639
9888
|
")"
|
|
9640
9889
|
] }),
|
|
9641
|
-
param.forced?.active && /* @__PURE__ */ (0,
|
|
9890
|
+
param.forced?.active && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9642
9891
|
"span",
|
|
9643
9892
|
{
|
|
9644
9893
|
"aria-label": "Forced",
|
|
@@ -9665,7 +9914,7 @@ function DeviceConfigPanelImpl({
|
|
|
9665
9914
|
]
|
|
9666
9915
|
}
|
|
9667
9916
|
),
|
|
9668
|
-
param.forced?.active && param.forced.realValue !== void 0 && /* @__PURE__ */ (0,
|
|
9917
|
+
param.forced?.active && param.forced.realValue !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
9669
9918
|
"div",
|
|
9670
9919
|
{
|
|
9671
9920
|
style: {
|
|
@@ -9683,7 +9932,7 @@ function DeviceConfigPanelImpl({
|
|
|
9683
9932
|
]
|
|
9684
9933
|
}
|
|
9685
9934
|
),
|
|
9686
|
-
param.description && /* @__PURE__ */ (0,
|
|
9935
|
+
param.description && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9687
9936
|
"div",
|
|
9688
9937
|
{
|
|
9689
9938
|
style: {
|
|
@@ -9695,7 +9944,7 @@ function DeviceConfigPanelImpl({
|
|
|
9695
9944
|
children: param.description
|
|
9696
9945
|
}
|
|
9697
9946
|
),
|
|
9698
|
-
param.type === "number" && /* @__PURE__ */ (0,
|
|
9947
|
+
param.type === "number" && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9699
9948
|
"input",
|
|
9700
9949
|
{
|
|
9701
9950
|
type: "number",
|
|
@@ -9719,7 +9968,7 @@ function DeviceConfigPanelImpl({
|
|
|
9719
9968
|
}
|
|
9720
9969
|
}
|
|
9721
9970
|
),
|
|
9722
|
-
param.type === "string" && /* @__PURE__ */ (0,
|
|
9971
|
+
param.type === "string" && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9723
9972
|
"input",
|
|
9724
9973
|
{
|
|
9725
9974
|
type: "text",
|
|
@@ -9740,7 +9989,7 @@ function DeviceConfigPanelImpl({
|
|
|
9740
9989
|
}
|
|
9741
9990
|
}
|
|
9742
9991
|
),
|
|
9743
|
-
param.type === "boolean" && /* @__PURE__ */ (0,
|
|
9992
|
+
param.type === "boolean" && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
9744
9993
|
"label",
|
|
9745
9994
|
{
|
|
9746
9995
|
style: {
|
|
@@ -9750,7 +9999,7 @@ function DeviceConfigPanelImpl({
|
|
|
9750
9999
|
cursor: isDisabled ? "not-allowed" : "pointer"
|
|
9751
10000
|
},
|
|
9752
10001
|
children: [
|
|
9753
|
-
/* @__PURE__ */ (0,
|
|
10002
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9754
10003
|
"input",
|
|
9755
10004
|
{
|
|
9756
10005
|
type: "checkbox",
|
|
@@ -9764,11 +10013,11 @@ function DeviceConfigPanelImpl({
|
|
|
9764
10013
|
}
|
|
9765
10014
|
}
|
|
9766
10015
|
),
|
|
9767
|
-
/* @__PURE__ */ (0,
|
|
10016
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { style: { fontSize: `${fontSize.value}px`, color: textColor }, children: value ? "Enabled" : "Disabled" })
|
|
9768
10017
|
]
|
|
9769
10018
|
}
|
|
9770
10019
|
),
|
|
9771
|
-
param.type === "select" && /* @__PURE__ */ (0,
|
|
10020
|
+
param.type === "select" && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9772
10021
|
"select",
|
|
9773
10022
|
{
|
|
9774
10023
|
value: value ?? "",
|
|
@@ -9786,10 +10035,10 @@ function DeviceConfigPanelImpl({
|
|
|
9786
10035
|
borderRadius: "2px",
|
|
9787
10036
|
outline: "none"
|
|
9788
10037
|
},
|
|
9789
|
-
children: param.options?.map((option) => /* @__PURE__ */ (0,
|
|
10038
|
+
children: param.options?.map((option) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("option", { value: option.value, children: option.label }, option.value))
|
|
9790
10039
|
}
|
|
9791
10040
|
),
|
|
9792
|
-
error && /* @__PURE__ */ (0,
|
|
10041
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9793
10042
|
"div",
|
|
9794
10043
|
{
|
|
9795
10044
|
style: {
|
|
@@ -9809,7 +10058,7 @@ function DeviceConfigPanelImpl({
|
|
|
9809
10058
|
const renderSection = (section) => {
|
|
9810
10059
|
const params = parametersBySection[section.id] || [];
|
|
9811
10060
|
const isCollapsed = collapsedSections.has(section.id);
|
|
9812
|
-
return /* @__PURE__ */ (0,
|
|
10061
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
9813
10062
|
"div",
|
|
9814
10063
|
{
|
|
9815
10064
|
style: {
|
|
@@ -9819,7 +10068,7 @@ function DeviceConfigPanelImpl({
|
|
|
9819
10068
|
backgroundColor: surfaceColor
|
|
9820
10069
|
},
|
|
9821
10070
|
children: [
|
|
9822
|
-
/* @__PURE__ */ (0,
|
|
10071
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
9823
10072
|
"div",
|
|
9824
10073
|
{
|
|
9825
10074
|
onClick: () => section.collapsible && toggleSection(section.id),
|
|
@@ -9832,8 +10081,8 @@ function DeviceConfigPanelImpl({
|
|
|
9832
10081
|
alignItems: "center"
|
|
9833
10082
|
},
|
|
9834
10083
|
children: [
|
|
9835
|
-
/* @__PURE__ */ (0,
|
|
9836
|
-
/* @__PURE__ */ (0,
|
|
10084
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { children: [
|
|
10085
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
9837
10086
|
"div",
|
|
9838
10087
|
{
|
|
9839
10088
|
style: {
|
|
@@ -9845,12 +10094,12 @@ function DeviceConfigPanelImpl({
|
|
|
9845
10094
|
letterSpacing: "0.5px"
|
|
9846
10095
|
},
|
|
9847
10096
|
children: [
|
|
9848
|
-
section.icon && /* @__PURE__ */ (0,
|
|
10097
|
+
section.icon && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { style: { marginRight: "8px" }, children: section.icon }),
|
|
9849
10098
|
section.title
|
|
9850
10099
|
]
|
|
9851
10100
|
}
|
|
9852
10101
|
),
|
|
9853
|
-
section.description && /* @__PURE__ */ (0,
|
|
10102
|
+
section.description && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9854
10103
|
"div",
|
|
9855
10104
|
{
|
|
9856
10105
|
style: {
|
|
@@ -9863,11 +10112,11 @@ function DeviceConfigPanelImpl({
|
|
|
9863
10112
|
}
|
|
9864
10113
|
)
|
|
9865
10114
|
] }),
|
|
9866
|
-
section.collapsible && /* @__PURE__ */ (0,
|
|
10115
|
+
section.collapsible && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { style: { fontSize: "16px", color: mutedTextColor }, children: isCollapsed ? "\u25BC" : "\u25B2" })
|
|
9867
10116
|
]
|
|
9868
10117
|
}
|
|
9869
10118
|
),
|
|
9870
|
-
!isCollapsed && /* @__PURE__ */ (0,
|
|
10119
|
+
!isCollapsed && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: { padding: spacing.padding }, children: params.map(renderParameter) })
|
|
9871
10120
|
]
|
|
9872
10121
|
},
|
|
9873
10122
|
section.id
|
|
@@ -9926,9 +10175,9 @@ function DeviceConfigPanelImpl({
|
|
|
9926
10175
|
const showSave = binding.display?.showSave !== false && binding.actions.onSave;
|
|
9927
10176
|
const showReset = binding.display?.showReset !== false && binding.actions.onReset;
|
|
9928
10177
|
const showCancel = binding.display?.showCancel !== false;
|
|
9929
|
-
return /* @__PURE__ */ (0,
|
|
9930
|
-
/* @__PURE__ */ (0,
|
|
9931
|
-
/* @__PURE__ */ (0,
|
|
10178
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
|
|
10179
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { style: panelStyle, className: binding.display?.className, children: [
|
|
10180
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
9932
10181
|
"div",
|
|
9933
10182
|
{
|
|
9934
10183
|
style: {
|
|
@@ -9940,8 +10189,8 @@ function DeviceConfigPanelImpl({
|
|
|
9940
10189
|
borderBottom: `2px solid ${borderColor}`
|
|
9941
10190
|
},
|
|
9942
10191
|
children: [
|
|
9943
|
-
/* @__PURE__ */ (0,
|
|
9944
|
-
/* @__PURE__ */ (0,
|
|
10192
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { children: [
|
|
10193
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9945
10194
|
"h3",
|
|
9946
10195
|
{
|
|
9947
10196
|
style: {
|
|
@@ -9961,7 +10210,7 @@ function DeviceConfigPanelImpl({
|
|
|
9961
10210
|
children: titleText.length > 25 ? titleText.slice(0, 25) + "..." : titleText
|
|
9962
10211
|
}
|
|
9963
10212
|
),
|
|
9964
|
-
binding.display?.subtitle && /* @__PURE__ */ (0,
|
|
10213
|
+
binding.display?.subtitle && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9965
10214
|
"div",
|
|
9966
10215
|
{
|
|
9967
10216
|
style: {
|
|
@@ -9974,8 +10223,8 @@ function DeviceConfigPanelImpl({
|
|
|
9974
10223
|
}
|
|
9975
10224
|
)
|
|
9976
10225
|
] }),
|
|
9977
|
-
/* @__PURE__ */ (0,
|
|
9978
|
-
showControlsButton && onOpenControls && /* @__PURE__ */ (0,
|
|
10226
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { style: { display: "flex", gap: "8px" }, children: [
|
|
10227
|
+
showControlsButton && onOpenControls && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9979
10228
|
"button",
|
|
9980
10229
|
{
|
|
9981
10230
|
onClick: onOpenControls,
|
|
@@ -9998,7 +10247,7 @@ function DeviceConfigPanelImpl({
|
|
|
9998
10247
|
children: "CTRL"
|
|
9999
10248
|
}
|
|
10000
10249
|
),
|
|
10001
|
-
onUndock && /* @__PURE__ */ (0,
|
|
10250
|
+
onUndock && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
10002
10251
|
"button",
|
|
10003
10252
|
{
|
|
10004
10253
|
onClick: onUndock,
|
|
@@ -10019,7 +10268,7 @@ function DeviceConfigPanelImpl({
|
|
|
10019
10268
|
children: undockIcon
|
|
10020
10269
|
}
|
|
10021
10270
|
),
|
|
10022
|
-
/* @__PURE__ */ (0,
|
|
10271
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
10023
10272
|
"button",
|
|
10024
10273
|
{
|
|
10025
10274
|
onClick: onClose,
|
|
@@ -10042,7 +10291,7 @@ function DeviceConfigPanelImpl({
|
|
|
10042
10291
|
]
|
|
10043
10292
|
}
|
|
10044
10293
|
),
|
|
10045
|
-
binding.state.isDirty && /* @__PURE__ */ (0,
|
|
10294
|
+
binding.state.isDirty && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
10046
10295
|
"div",
|
|
10047
10296
|
{
|
|
10048
10297
|
style: {
|
|
@@ -10057,11 +10306,11 @@ function DeviceConfigPanelImpl({
|
|
|
10057
10306
|
children: "Unsaved changes"
|
|
10058
10307
|
}
|
|
10059
10308
|
),
|
|
10060
|
-
/* @__PURE__ */ (0,
|
|
10309
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: { flex: 1, overflowY: "auto", marginBottom: spacing.marginBottom }, children: sortedSections.length > 0 ? sortedSections.map(renderSection) : (
|
|
10061
10310
|
/* Render unsectioned parameters */
|
|
10062
|
-
/* @__PURE__ */ (0,
|
|
10311
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { children: parametersBySection._unsectioned?.map(renderParameter) })
|
|
10063
10312
|
) }),
|
|
10064
|
-
/* @__PURE__ */ (0,
|
|
10313
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
10065
10314
|
"div",
|
|
10066
10315
|
{
|
|
10067
10316
|
style: {
|
|
@@ -10072,7 +10321,7 @@ function DeviceConfigPanelImpl({
|
|
|
10072
10321
|
flexWrap: "wrap"
|
|
10073
10322
|
},
|
|
10074
10323
|
children: [
|
|
10075
|
-
showApply && /* @__PURE__ */ (0,
|
|
10324
|
+
showApply && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
10076
10325
|
"button",
|
|
10077
10326
|
{
|
|
10078
10327
|
onClick: handleApply,
|
|
@@ -10095,7 +10344,7 @@ function DeviceConfigPanelImpl({
|
|
|
10095
10344
|
children: binding.state.isSaving ? "Applying..." : "Apply"
|
|
10096
10345
|
}
|
|
10097
10346
|
),
|
|
10098
|
-
showSave && /* @__PURE__ */ (0,
|
|
10347
|
+
showSave && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
10099
10348
|
"button",
|
|
10100
10349
|
{
|
|
10101
10350
|
onClick: handleSave,
|
|
@@ -10118,7 +10367,7 @@ function DeviceConfigPanelImpl({
|
|
|
10118
10367
|
children: binding.state.isSaving ? "Saving..." : "Save"
|
|
10119
10368
|
}
|
|
10120
10369
|
),
|
|
10121
|
-
showReset && /* @__PURE__ */ (0,
|
|
10370
|
+
showReset && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
10122
10371
|
"button",
|
|
10123
10372
|
{
|
|
10124
10373
|
onClick: handleReset,
|
|
@@ -10141,7 +10390,7 @@ function DeviceConfigPanelImpl({
|
|
|
10141
10390
|
children: "Reset"
|
|
10142
10391
|
}
|
|
10143
10392
|
),
|
|
10144
|
-
showCancel && /* @__PURE__ */ (0,
|
|
10393
|
+
showCancel && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
10145
10394
|
"button",
|
|
10146
10395
|
{
|
|
10147
10396
|
onClick: handleCancel,
|
|
@@ -10168,7 +10417,7 @@ function DeviceConfigPanelImpl({
|
|
|
10168
10417
|
}
|
|
10169
10418
|
)
|
|
10170
10419
|
] }),
|
|
10171
|
-
binding.state.lastSaveResult && showToast && showBuiltInToast && /* @__PURE__ */ (0,
|
|
10420
|
+
binding.state.lastSaveResult && showToast && showBuiltInToast && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
10172
10421
|
"div",
|
|
10173
10422
|
{
|
|
10174
10423
|
style: {
|
|
@@ -10190,10 +10439,10 @@ function DeviceConfigPanelImpl({
|
|
|
10190
10439
|
)
|
|
10191
10440
|
] });
|
|
10192
10441
|
}
|
|
10193
|
-
var DeviceConfigPanel =
|
|
10442
|
+
var DeviceConfigPanel = import_react26.default.memo(DeviceConfigPanelImpl);
|
|
10194
10443
|
|
|
10195
10444
|
// src/diagram/hooks/useSimulation.ts
|
|
10196
|
-
var
|
|
10445
|
+
var import_react27 = require("react");
|
|
10197
10446
|
function useSimulation(telemetry, updateTelemetryBatch, options = {}) {
|
|
10198
10447
|
const {
|
|
10199
10448
|
interval = 2e3,
|
|
@@ -10204,7 +10453,7 @@ function useSimulation(telemetry, updateTelemetryBatch, options = {}) {
|
|
|
10204
10453
|
historyLength = 10,
|
|
10205
10454
|
generateValue
|
|
10206
10455
|
} = options;
|
|
10207
|
-
(0,
|
|
10456
|
+
(0, import_react27.useEffect)(() => {
|
|
10208
10457
|
if (!enabled) return;
|
|
10209
10458
|
const intervalId = setInterval(() => {
|
|
10210
10459
|
const updates = [];
|
|
@@ -10274,6 +10523,8 @@ function useSimulation(telemetry, updateTelemetryBatch, options = {}) {
|
|
|
10274
10523
|
FooterPanel,
|
|
10275
10524
|
FullscreenContainer,
|
|
10276
10525
|
FullscreenWorkspace,
|
|
10526
|
+
ISA_UNKNOWN,
|
|
10527
|
+
ISA_UNKNOWN_DARK,
|
|
10277
10528
|
LeftPanel,
|
|
10278
10529
|
LeftToggleButton,
|
|
10279
10530
|
LegacyValueEntry,
|
|
@@ -10296,8 +10547,9 @@ function useSimulation(telemetry, updateTelemetryBatch, options = {}) {
|
|
|
10296
10547
|
ThemeProvider,
|
|
10297
10548
|
ThemeToggle,
|
|
10298
10549
|
TrendLine,
|
|
10299
|
-
|
|
10300
|
-
|
|
10550
|
+
UNKNOWN_GLYPH_RING_DASH,
|
|
10551
|
+
UNKNOWN_STATUS_GLYPH_COLOR_VAR,
|
|
10552
|
+
UnknownStatusGlyph,
|
|
10301
10553
|
ValueEntry,
|
|
10302
10554
|
ZoomButton,
|
|
10303
10555
|
ZoomControls,
|
|
@@ -10309,14 +10561,19 @@ function useSimulation(telemetry, updateTelemetryBatch, options = {}) {
|
|
|
10309
10561
|
generateRoutePoints,
|
|
10310
10562
|
getAppearanceDefaults,
|
|
10311
10563
|
getAppearanceSchema,
|
|
10564
|
+
getAvailableBadgeGlyphs,
|
|
10312
10565
|
getAvailableSymbols,
|
|
10566
|
+
getBadgeGlyph,
|
|
10313
10567
|
getPortWorldPosition,
|
|
10314
10568
|
getSymbolDefinition,
|
|
10315
10569
|
importDiagram,
|
|
10316
10570
|
mockSymbolLibrary,
|
|
10317
10571
|
nodeHasPort,
|
|
10572
|
+
normalizeDeviceStatus,
|
|
10318
10573
|
overlayStyles,
|
|
10319
10574
|
readAppearanceValue,
|
|
10575
|
+
registerBadgeGlyph,
|
|
10576
|
+
registerBadgeGlyphs,
|
|
10320
10577
|
registerSymbol,
|
|
10321
10578
|
registerSymbols,
|
|
10322
10579
|
resolvePresetColor,
|