@procaaso/alphinity-ui-components 1.10.0 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/IMPLEMENTATION_GUIDE.md +1351 -1351
- package/README.md +98 -95
- package/dist/index.cjs +1317 -691
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +340 -83
- package/dist/index.d.ts +340 -83
- package/dist/index.js +1137 -525
- package/dist/index.js.map +1 -1
- package/package.json +85 -85
package/dist/index.js
CHANGED
|
@@ -267,6 +267,16 @@ var ValueEntry = ({
|
|
|
267
267
|
import { useState as useState3, useCallback as useCallback2 } from "react";
|
|
268
268
|
|
|
269
269
|
// src/theme/statusColors.ts
|
|
270
|
+
var ISA_UNKNOWN = {
|
|
271
|
+
fg: "#4f4f8a",
|
|
272
|
+
bg: "#ebebf5",
|
|
273
|
+
border: "#8f8fc2"
|
|
274
|
+
};
|
|
275
|
+
var ISA_UNKNOWN_DARK = {
|
|
276
|
+
fg: "#b9bbdb",
|
|
277
|
+
bg: "#23263a",
|
|
278
|
+
border: "#6f74a3"
|
|
279
|
+
};
|
|
270
280
|
var DEFAULT_STATUS_COLORS = {
|
|
271
281
|
normal: { fill: "#888888", stroke: "#6b6b6b", bg: "#888888", text: "#ffffff", border: "#6b6b6b" },
|
|
272
282
|
warning: { fill: "#f59e0b", stroke: "#d97706", bg: "#FFD700", text: "#000000", border: "#d97706" },
|
|
@@ -274,7 +284,8 @@ var DEFAULT_STATUS_COLORS = {
|
|
|
274
284
|
fault: { fill: "#dc2626", stroke: "#b91c1c", bg: "#FF0000", text: "#ffffff", border: "#b91c1c" },
|
|
275
285
|
off: { fill: "#edeeef", stroke: "#000000", bg: "#666666", text: "#ffffff", border: "#4b5563" },
|
|
276
286
|
starting: { fill: "#90EE90", stroke: "#22c55e", bg: "#90EE90", text: "#000000", border: "#22c55e" },
|
|
277
|
-
stopping: { fill: "#FFD700", stroke: "#d97706", bg: "#FFD700", text: "#000000", border: "#d97706" }
|
|
287
|
+
stopping: { fill: "#FFD700", stroke: "#d97706", bg: "#FFD700", text: "#000000", border: "#d97706" },
|
|
288
|
+
unknown: { fill: ISA_UNKNOWN.bg, stroke: ISA_UNKNOWN.border, bg: ISA_UNKNOWN.bg, text: ISA_UNKNOWN.fg, border: ISA_UNKNOWN.border }
|
|
278
289
|
};
|
|
279
290
|
var FORCED_MARK_COLOR = {
|
|
280
291
|
fill: "#ede9fe",
|
|
@@ -287,9 +298,12 @@ var STATUS_ALIASES = {
|
|
|
287
298
|
running: "normal",
|
|
288
299
|
stopped: "off"
|
|
289
300
|
};
|
|
290
|
-
function
|
|
301
|
+
function normalizeDeviceStatus(status) {
|
|
291
302
|
const raw = (status || "off").toLowerCase();
|
|
292
|
-
|
|
303
|
+
return STATUS_ALIASES[raw] ?? raw;
|
|
304
|
+
}
|
|
305
|
+
function resolveStatusColor(status, customMap) {
|
|
306
|
+
const key = normalizeDeviceStatus(status);
|
|
293
307
|
const defaults = DEFAULT_STATUS_COLORS[key] ?? DEFAULT_STATUS_COLORS.off;
|
|
294
308
|
const overrides = customMap?.[key];
|
|
295
309
|
if (!overrides) return defaults;
|
|
@@ -729,7 +743,79 @@ var ControlPanel = ({
|
|
|
729
743
|
};
|
|
730
744
|
|
|
731
745
|
// src/components/StatusIndicator/StatusIndicator.tsx
|
|
746
|
+
import React5 from "react";
|
|
747
|
+
|
|
748
|
+
// src/theme/unknownStatusGlyph.tsx
|
|
732
749
|
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
750
|
+
var UNKNOWN_STATUS_GLYPH_COLOR_VAR = "--ui-status-indicator-unknown-glyph-color";
|
|
751
|
+
var UNKNOWN_GLYPH_STROKE_WEIGHTS = {
|
|
752
|
+
small: { ring: 4.5, ringDash: "7 6", mark: 5, dot: 2.9 },
|
|
753
|
+
medium: { ring: 4, ringDash: "6.5 5.5", mark: 4.5, dot: 2.7 },
|
|
754
|
+
large: { ring: 3.5, ringDash: "6.5 5.5", mark: 4, dot: 2.5 }
|
|
755
|
+
};
|
|
756
|
+
var UNKNOWN_GLYPH_RING_DASH = UNKNOWN_GLYPH_STROKE_WEIGHTS.medium.ringDash;
|
|
757
|
+
var UNKNOWN_GLYPH_FILL_STYLE = {
|
|
758
|
+
position: "absolute",
|
|
759
|
+
inset: 0,
|
|
760
|
+
width: "100%",
|
|
761
|
+
height: "100%"
|
|
762
|
+
};
|
|
763
|
+
function unknownGlyphHostStyle(isUnknown, style) {
|
|
764
|
+
return isUnknown ? { position: "relative", ...style } : style;
|
|
765
|
+
}
|
|
766
|
+
function UnknownStatusGlyph({
|
|
767
|
+
size = "medium",
|
|
768
|
+
counterRotate = false,
|
|
769
|
+
style,
|
|
770
|
+
...rest
|
|
771
|
+
}) {
|
|
772
|
+
const weights = UNKNOWN_GLYPH_STROKE_WEIGHTS[size];
|
|
773
|
+
return /* @__PURE__ */ jsxs5(
|
|
774
|
+
"svg",
|
|
775
|
+
{
|
|
776
|
+
viewBox: "0 0 48 48",
|
|
777
|
+
"aria-hidden": "true",
|
|
778
|
+
focusable: "false",
|
|
779
|
+
style: {
|
|
780
|
+
display: "block",
|
|
781
|
+
color: `var(${UNKNOWN_STATUS_GLYPH_COLOR_VAR}, currentColor)`,
|
|
782
|
+
transform: counterRotate ? "rotate(-45deg)" : void 0,
|
|
783
|
+
...style
|
|
784
|
+
},
|
|
785
|
+
...rest,
|
|
786
|
+
children: [
|
|
787
|
+
/* @__PURE__ */ jsx6(
|
|
788
|
+
"circle",
|
|
789
|
+
{
|
|
790
|
+
cx: 24,
|
|
791
|
+
cy: 24,
|
|
792
|
+
r: 20,
|
|
793
|
+
fill: "none",
|
|
794
|
+
stroke: "currentColor",
|
|
795
|
+
strokeDasharray: weights.ringDash,
|
|
796
|
+
strokeLinecap: "round",
|
|
797
|
+
strokeWidth: weights.ring
|
|
798
|
+
}
|
|
799
|
+
),
|
|
800
|
+
/* @__PURE__ */ jsx6(
|
|
801
|
+
"path",
|
|
802
|
+
{
|
|
803
|
+
d: "M18.4 18.6a5.8 5.8 0 1 1 6.4 8.1v3.1",
|
|
804
|
+
fill: "none",
|
|
805
|
+
stroke: "currentColor",
|
|
806
|
+
strokeLinecap: "round",
|
|
807
|
+
strokeLinejoin: "round",
|
|
808
|
+
strokeWidth: weights.mark
|
|
809
|
+
}
|
|
810
|
+
),
|
|
811
|
+
/* @__PURE__ */ jsx6("circle", { cx: 24.6, cy: 35.4, r: weights.dot, fill: "currentColor" })
|
|
812
|
+
]
|
|
813
|
+
}
|
|
814
|
+
);
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
// src/components/StatusIndicator/StatusIndicator.tsx
|
|
818
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
733
819
|
var getStatusDescription = (status) => {
|
|
734
820
|
switch (status) {
|
|
735
821
|
case "alarm":
|
|
@@ -744,10 +830,23 @@ var getStatusDescription = (status) => {
|
|
|
744
830
|
return "Operating normally";
|
|
745
831
|
case "off":
|
|
746
832
|
return "Equipment is off";
|
|
833
|
+
case "unknown":
|
|
834
|
+
return "Device state cannot be confirmed. Check the link or the wiring.";
|
|
747
835
|
default:
|
|
748
836
|
return "";
|
|
749
837
|
}
|
|
750
838
|
};
|
|
839
|
+
var visuallyHiddenStyle = {
|
|
840
|
+
position: "absolute",
|
|
841
|
+
width: "1px",
|
|
842
|
+
height: "1px",
|
|
843
|
+
padding: 0,
|
|
844
|
+
margin: "-1px",
|
|
845
|
+
overflow: "hidden",
|
|
846
|
+
clip: "rect(0, 0, 0, 0)",
|
|
847
|
+
whiteSpace: "nowrap",
|
|
848
|
+
border: 0
|
|
849
|
+
};
|
|
751
850
|
var StatusIndicator = ({
|
|
752
851
|
status,
|
|
753
852
|
size = "medium",
|
|
@@ -756,17 +855,29 @@ var StatusIndicator = ({
|
|
|
756
855
|
labelPosition = "right",
|
|
757
856
|
shape = "circle",
|
|
758
857
|
led = true,
|
|
858
|
+
visible = true,
|
|
759
859
|
forced = false,
|
|
760
860
|
realValue,
|
|
761
861
|
className = "",
|
|
862
|
+
style,
|
|
863
|
+
"aria-describedby": consumerDescribedBy,
|
|
864
|
+
children,
|
|
762
865
|
...props
|
|
763
866
|
}) => {
|
|
867
|
+
const generatedDescriptionId = `${React5.useId()}-status-description`;
|
|
868
|
+
if (!visible) {
|
|
869
|
+
return null;
|
|
870
|
+
}
|
|
871
|
+
const describedBy = consumerDescribedBy ? `${consumerDescribedBy} ${generatedDescriptionId}` : generatedDescriptionId;
|
|
872
|
+
const description = getStatusDescription(status);
|
|
764
873
|
const baseClass = "ui-status-indicator";
|
|
765
874
|
const statusClass = status ? `ui-status-indicator--${status}` : "";
|
|
766
875
|
const sizeClass = size ? `ui-status-indicator--${size}` : "";
|
|
767
876
|
const shapeClass = shape ? `ui-status-indicator--${shape}` : "";
|
|
768
877
|
const animationClass = animation ? `ui-status-indicator--${animation}` : "";
|
|
769
878
|
const ledClass = led ? "ui-status-indicator--led" : "";
|
|
879
|
+
const isUnknown = status === "unknown";
|
|
880
|
+
const indicatorStyle = unknownGlyphHostStyle(isUnknown, style);
|
|
770
881
|
const getContainerLayout = () => {
|
|
771
882
|
switch (labelPosition) {
|
|
772
883
|
case "left":
|
|
@@ -783,19 +894,20 @@ var StatusIndicator = ({
|
|
|
783
894
|
};
|
|
784
895
|
const forcedClass = forced ? "ui-status-indicator--forced" : "";
|
|
785
896
|
const hasRealValue = forced && realValue !== void 0;
|
|
786
|
-
return /* @__PURE__ */
|
|
787
|
-
label && (labelPosition === "left" || labelPosition === "top") && /* @__PURE__ */
|
|
788
|
-
hasRealValue && (labelPosition === "left" || labelPosition === "top") && /* @__PURE__ */
|
|
897
|
+
return /* @__PURE__ */ jsxs6("span", { className: getContainerLayout(), children: [
|
|
898
|
+
label && (labelPosition === "left" || labelPosition === "top") && /* @__PURE__ */ jsx7("span", { className: "ui-status-indicator-label", children: label }),
|
|
899
|
+
hasRealValue && (labelPosition === "left" || labelPosition === "top") && /* @__PURE__ */ jsxs6("span", { className: "ui-status-indicator-real-value", children: [
|
|
789
900
|
"REAL ",
|
|
790
901
|
realValue
|
|
791
902
|
] }),
|
|
792
|
-
/* @__PURE__ */
|
|
793
|
-
/* @__PURE__ */
|
|
903
|
+
/* @__PURE__ */ jsxs6("span", { style: { position: "relative", display: "inline-flex" }, children: [
|
|
904
|
+
/* @__PURE__ */ jsxs6(
|
|
794
905
|
"span",
|
|
795
906
|
{
|
|
796
907
|
role: "status",
|
|
797
908
|
"aria-label": label || `Status: ${status}`,
|
|
798
|
-
"aria-description":
|
|
909
|
+
"aria-description": description,
|
|
910
|
+
"aria-describedby": describedBy,
|
|
799
911
|
"data-status": status,
|
|
800
912
|
"data-forced": forced,
|
|
801
913
|
className: `
|
|
@@ -808,13 +920,26 @@ var StatusIndicator = ({
|
|
|
808
920
|
${forcedClass}
|
|
809
921
|
${className}
|
|
810
922
|
`.replace(/\s+/g, " ").trim(),
|
|
811
|
-
|
|
923
|
+
style: indicatorStyle,
|
|
924
|
+
...props,
|
|
925
|
+
children: [
|
|
926
|
+
isUnknown && /* @__PURE__ */ jsx7(
|
|
927
|
+
UnknownStatusGlyph,
|
|
928
|
+
{
|
|
929
|
+
size,
|
|
930
|
+
counterRotate: shape === "diamond",
|
|
931
|
+
style: UNKNOWN_GLYPH_FILL_STYLE
|
|
932
|
+
}
|
|
933
|
+
),
|
|
934
|
+
children,
|
|
935
|
+
/* @__PURE__ */ jsx7("span", { id: generatedDescriptionId, style: visuallyHiddenStyle, children: description })
|
|
936
|
+
]
|
|
812
937
|
}
|
|
813
938
|
),
|
|
814
|
-
forced && /* @__PURE__ */
|
|
939
|
+
forced && /* @__PURE__ */ jsx7("span", { className: "ui-status-indicator-forced-badge", "aria-label": "Forced", children: "F" })
|
|
815
940
|
] }),
|
|
816
|
-
label && (labelPosition === "right" || labelPosition === "bottom") && /* @__PURE__ */
|
|
817
|
-
hasRealValue && (labelPosition === "right" || labelPosition === "bottom") && /* @__PURE__ */
|
|
941
|
+
label && (labelPosition === "right" || labelPosition === "bottom") && /* @__PURE__ */ jsx7("span", { className: "ui-status-indicator-label", children: label }),
|
|
942
|
+
hasRealValue && (labelPosition === "right" || labelPosition === "bottom") && /* @__PURE__ */ jsxs6("span", { className: "ui-status-indicator-real-value", children: [
|
|
818
943
|
"REAL ",
|
|
819
944
|
realValue
|
|
820
945
|
] })
|
|
@@ -822,7 +947,7 @@ var StatusIndicator = ({
|
|
|
822
947
|
};
|
|
823
948
|
|
|
824
949
|
// src/components/NodeControlsPanel/NodeControlsPanel.tsx
|
|
825
|
-
import { Fragment, jsx as
|
|
950
|
+
import { Fragment, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
826
951
|
var NodeControlsPanel = ({
|
|
827
952
|
config,
|
|
828
953
|
onClose,
|
|
@@ -895,8 +1020,8 @@ var NodeControlsPanel = ({
|
|
|
895
1020
|
overflowY: "auto",
|
|
896
1021
|
flex: 1
|
|
897
1022
|
};
|
|
898
|
-
return /* @__PURE__ */
|
|
899
|
-
/* @__PURE__ */
|
|
1023
|
+
return /* @__PURE__ */ jsxs7(Fragment, { children: [
|
|
1024
|
+
/* @__PURE__ */ jsx8(
|
|
900
1025
|
"div",
|
|
901
1026
|
{
|
|
902
1027
|
style: {
|
|
@@ -909,16 +1034,16 @@ var NodeControlsPanel = ({
|
|
|
909
1034
|
onClick: onClose
|
|
910
1035
|
}
|
|
911
1036
|
),
|
|
912
|
-
/* @__PURE__ */
|
|
1037
|
+
/* @__PURE__ */ jsxs7(
|
|
913
1038
|
"div",
|
|
914
1039
|
{
|
|
915
1040
|
className: `node-controls-panel ${touchClass} ${className}`.trim(),
|
|
916
1041
|
style: containerStyle,
|
|
917
1042
|
...props,
|
|
918
1043
|
children: [
|
|
919
|
-
/* @__PURE__ */
|
|
920
|
-
/* @__PURE__ */
|
|
921
|
-
/* @__PURE__ */
|
|
1044
|
+
/* @__PURE__ */ jsxs7("div", { style: headerStyle, children: [
|
|
1045
|
+
/* @__PURE__ */ jsx8("h2", { style: titleStyle, children: config.title }),
|
|
1046
|
+
/* @__PURE__ */ jsx8(
|
|
922
1047
|
"button",
|
|
923
1048
|
{
|
|
924
1049
|
style: closeButtonStyle,
|
|
@@ -936,7 +1061,7 @@ var NodeControlsPanel = ({
|
|
|
936
1061
|
}
|
|
937
1062
|
)
|
|
938
1063
|
] }),
|
|
939
|
-
/* @__PURE__ */
|
|
1064
|
+
/* @__PURE__ */ jsx8("div", { style: contentStyle, children: /* @__PURE__ */ jsx8(
|
|
940
1065
|
ControlPanel,
|
|
941
1066
|
{
|
|
942
1067
|
title: config.nodeId,
|
|
@@ -965,7 +1090,7 @@ var NodeControlsPanel = ({
|
|
|
965
1090
|
]
|
|
966
1091
|
}
|
|
967
1092
|
),
|
|
968
|
-
/* @__PURE__ */
|
|
1093
|
+
/* @__PURE__ */ jsx8("style", { children: `
|
|
969
1094
|
@keyframes slideUp {
|
|
970
1095
|
from {
|
|
971
1096
|
transform: translateY(100%);
|
|
@@ -1011,8 +1136,8 @@ var NodeControlsPanel = ({
|
|
|
1011
1136
|
};
|
|
1012
1137
|
|
|
1013
1138
|
// src/components/DeviceControlPanel/DeviceControlPanel.tsx
|
|
1014
|
-
import
|
|
1015
|
-
import { Fragment as Fragment2, jsx as
|
|
1139
|
+
import React6, { useState as useState5, useEffect as useEffect2 } from "react";
|
|
1140
|
+
import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1016
1141
|
function DeviceControlPanelImpl({
|
|
1017
1142
|
binding,
|
|
1018
1143
|
onClose,
|
|
@@ -1092,6 +1217,7 @@ function DeviceControlPanelImpl({
|
|
|
1092
1217
|
const selectedColor = "#b4d0fe";
|
|
1093
1218
|
const statusEntry = resolveStatusColor(binding.state.status, binding.theme?.statusColors);
|
|
1094
1219
|
const statusColor = statusEntry.bg;
|
|
1220
|
+
const isUnknownStatus = normalizeDeviceStatus(binding.state.status) === "unknown";
|
|
1095
1221
|
const handleModeChange = (mode) => {
|
|
1096
1222
|
onModeChange?.(mode);
|
|
1097
1223
|
};
|
|
@@ -1146,9 +1272,9 @@ function DeviceControlPanelImpl({
|
|
|
1146
1272
|
...binding.display?.style
|
|
1147
1273
|
};
|
|
1148
1274
|
const titleText = binding.display?.title || binding.deviceName || binding.tag || binding.nodeId;
|
|
1149
|
-
return /* @__PURE__ */
|
|
1150
|
-
/* @__PURE__ */
|
|
1151
|
-
/* @__PURE__ */
|
|
1275
|
+
return /* @__PURE__ */ jsxs8(Fragment2, { children: [
|
|
1276
|
+
/* @__PURE__ */ jsxs8("div", { style: panelStyle, className: binding.display?.className, children: [
|
|
1277
|
+
/* @__PURE__ */ jsxs8(
|
|
1152
1278
|
"div",
|
|
1153
1279
|
{
|
|
1154
1280
|
style: {
|
|
@@ -1160,8 +1286,8 @@ function DeviceControlPanelImpl({
|
|
|
1160
1286
|
borderBottom: `2px solid ${borderColor}`
|
|
1161
1287
|
},
|
|
1162
1288
|
children: [
|
|
1163
|
-
/* @__PURE__ */
|
|
1164
|
-
/* @__PURE__ */
|
|
1289
|
+
/* @__PURE__ */ jsxs8("div", { children: [
|
|
1290
|
+
/* @__PURE__ */ jsx9(
|
|
1165
1291
|
"h3",
|
|
1166
1292
|
{
|
|
1167
1293
|
style: {
|
|
@@ -1181,7 +1307,7 @@ function DeviceControlPanelImpl({
|
|
|
1181
1307
|
children: titleText.length > 25 ? titleText.slice(0, 25) + "..." : titleText
|
|
1182
1308
|
}
|
|
1183
1309
|
),
|
|
1184
|
-
binding.deviceType && /* @__PURE__ */
|
|
1310
|
+
binding.deviceType && /* @__PURE__ */ jsx9(
|
|
1185
1311
|
"div",
|
|
1186
1312
|
{
|
|
1187
1313
|
style: {
|
|
@@ -1194,8 +1320,8 @@ function DeviceControlPanelImpl({
|
|
|
1194
1320
|
}
|
|
1195
1321
|
)
|
|
1196
1322
|
] }),
|
|
1197
|
-
/* @__PURE__ */
|
|
1198
|
-
showConfigButton && onOpenConfig && /* @__PURE__ */
|
|
1323
|
+
/* @__PURE__ */ jsxs8("div", { style: { display: "flex", gap: "8px" }, children: [
|
|
1324
|
+
showConfigButton && onOpenConfig && /* @__PURE__ */ jsx9(
|
|
1199
1325
|
"button",
|
|
1200
1326
|
{
|
|
1201
1327
|
onClick: onOpenConfig,
|
|
@@ -1216,7 +1342,7 @@ function DeviceControlPanelImpl({
|
|
|
1216
1342
|
children: "\u2699"
|
|
1217
1343
|
}
|
|
1218
1344
|
),
|
|
1219
|
-
onUndock && /* @__PURE__ */
|
|
1345
|
+
onUndock && /* @__PURE__ */ jsx9(
|
|
1220
1346
|
"button",
|
|
1221
1347
|
{
|
|
1222
1348
|
onClick: onUndock,
|
|
@@ -1237,7 +1363,7 @@ function DeviceControlPanelImpl({
|
|
|
1237
1363
|
children: undockIcon
|
|
1238
1364
|
}
|
|
1239
1365
|
),
|
|
1240
|
-
/* @__PURE__ */
|
|
1366
|
+
/* @__PURE__ */ jsx9(
|
|
1241
1367
|
"button",
|
|
1242
1368
|
{
|
|
1243
1369
|
onClick: onClose,
|
|
@@ -1260,7 +1386,7 @@ function DeviceControlPanelImpl({
|
|
|
1260
1386
|
]
|
|
1261
1387
|
}
|
|
1262
1388
|
),
|
|
1263
|
-
binding.state.status && /* @__PURE__ */
|
|
1389
|
+
binding.state.status && /* @__PURE__ */ jsxs8(
|
|
1264
1390
|
"div",
|
|
1265
1391
|
{
|
|
1266
1392
|
style: {
|
|
@@ -1274,7 +1400,7 @@ function DeviceControlPanelImpl({
|
|
|
1274
1400
|
marginBottom: spacing.marginBottom
|
|
1275
1401
|
},
|
|
1276
1402
|
children: [
|
|
1277
|
-
/* @__PURE__ */
|
|
1403
|
+
/* @__PURE__ */ jsx9(
|
|
1278
1404
|
"div",
|
|
1279
1405
|
{
|
|
1280
1406
|
style: {
|
|
@@ -1282,12 +1408,17 @@ function DeviceControlPanelImpl({
|
|
|
1282
1408
|
height: "10px",
|
|
1283
1409
|
borderRadius: "50%",
|
|
1284
1410
|
backgroundColor: statusColor,
|
|
1285
|
-
border: "1px solid #333"
|
|
1286
|
-
|
|
1411
|
+
border: "1px solid #333",
|
|
1412
|
+
// The shared helper positions this dot only while it shows
|
|
1413
|
+
// the unknown marker. The glyph then fills the dot with an
|
|
1414
|
+
// absolute inset, the same pattern StatusIndicator uses.
|
|
1415
|
+
...unknownGlyphHostStyle(isUnknownStatus)
|
|
1416
|
+
},
|
|
1417
|
+
children: isUnknownStatus && /* @__PURE__ */ jsx9(UnknownStatusGlyph, { size: "small", style: UNKNOWN_GLYPH_FILL_STYLE })
|
|
1287
1418
|
}
|
|
1288
1419
|
),
|
|
1289
|
-
/* @__PURE__ */
|
|
1290
|
-
/* @__PURE__ */
|
|
1420
|
+
/* @__PURE__ */ jsxs8("div", { style: { flex: 1 }, children: [
|
|
1421
|
+
/* @__PURE__ */ jsx9(
|
|
1291
1422
|
"div",
|
|
1292
1423
|
{
|
|
1293
1424
|
style: {
|
|
@@ -1301,7 +1432,7 @@ function DeviceControlPanelImpl({
|
|
|
1301
1432
|
children: binding.state.status
|
|
1302
1433
|
}
|
|
1303
1434
|
),
|
|
1304
|
-
binding.state.statusMessage && /* @__PURE__ */
|
|
1435
|
+
binding.state.statusMessage && /* @__PURE__ */ jsx9(
|
|
1305
1436
|
"div",
|
|
1306
1437
|
{
|
|
1307
1438
|
style: {
|
|
@@ -1314,28 +1445,36 @@ function DeviceControlPanelImpl({
|
|
|
1314
1445
|
}
|
|
1315
1446
|
)
|
|
1316
1447
|
] }),
|
|
1317
|
-
binding.state.isRunning !== void 0 && /* @__PURE__ */
|
|
1448
|
+
binding.state.isRunning !== void 0 && /* @__PURE__ */ jsxs8(
|
|
1318
1449
|
"div",
|
|
1319
1450
|
{
|
|
1320
1451
|
style: {
|
|
1321
1452
|
padding: "4px 10px",
|
|
1322
|
-
|
|
1323
|
-
|
|
1453
|
+
// This badge shows the last published isRunning value. It
|
|
1454
|
+
// never re-derives that value here. When status is
|
|
1455
|
+
// unknown, the value may be stale. Muted colors carry that
|
|
1456
|
+
// warning alongside the word, so color is not the only
|
|
1457
|
+
// channel and the wording is not the only channel either.
|
|
1458
|
+
backgroundColor: isUnknownStatus ? statusEntry.bg : binding.state.isRunning ? selectedColor : surfaceColor,
|
|
1459
|
+
border: `1px solid ${isUnknownStatus ? statusEntry.border : borderColor}`,
|
|
1324
1460
|
borderRadius: "2px",
|
|
1325
1461
|
fontSize: "10px",
|
|
1326
1462
|
fontWeight: 600,
|
|
1327
1463
|
fontFamily: "Arial, sans-serif",
|
|
1328
1464
|
letterSpacing: "0.5px",
|
|
1329
|
-
color: textColor
|
|
1465
|
+
color: isUnknownStatus ? statusEntry.text : textColor
|
|
1330
1466
|
},
|
|
1331
|
-
children:
|
|
1467
|
+
children: [
|
|
1468
|
+
binding.state.isRunning ? "RUNNING" : "STOPPED",
|
|
1469
|
+
isUnknownStatus && " (unconfirmed)"
|
|
1470
|
+
]
|
|
1332
1471
|
}
|
|
1333
1472
|
)
|
|
1334
1473
|
]
|
|
1335
1474
|
}
|
|
1336
1475
|
),
|
|
1337
|
-
binding.display?.showModeSelector !== false && binding.modes.length > 0 && /* @__PURE__ */
|
|
1338
|
-
/* @__PURE__ */
|
|
1476
|
+
binding.display?.showModeSelector !== false && binding.modes.length > 0 && /* @__PURE__ */ jsxs8("div", { style: { marginBottom: "16px" }, children: [
|
|
1477
|
+
/* @__PURE__ */ jsx9(
|
|
1339
1478
|
"label",
|
|
1340
1479
|
{
|
|
1341
1480
|
style: {
|
|
@@ -1351,7 +1490,7 @@ function DeviceControlPanelImpl({
|
|
|
1351
1490
|
children: "Mode"
|
|
1352
1491
|
}
|
|
1353
1492
|
),
|
|
1354
|
-
modeSelectionStyle === "dropdown" ? /* @__PURE__ */
|
|
1493
|
+
modeSelectionStyle === "dropdown" ? /* @__PURE__ */ jsx9(
|
|
1355
1494
|
"select",
|
|
1356
1495
|
{
|
|
1357
1496
|
value: currentMode,
|
|
@@ -1372,10 +1511,10 @@ function DeviceControlPanelImpl({
|
|
|
1372
1511
|
paddingRight: "12px",
|
|
1373
1512
|
cursor: "pointer"
|
|
1374
1513
|
},
|
|
1375
|
-
children: binding.modes.map((mode) => /* @__PURE__ */
|
|
1514
|
+
children: binding.modes.map((mode) => /* @__PURE__ */ jsx9("option", { value: mode.value, disabled: mode.enabled === false, children: mode.label }, mode.value))
|
|
1376
1515
|
}
|
|
1377
|
-
) : modeSelectionStyle === "modal" ? /* @__PURE__ */
|
|
1378
|
-
/* @__PURE__ */
|
|
1516
|
+
) : modeSelectionStyle === "modal" ? /* @__PURE__ */ jsxs8(Fragment2, { children: [
|
|
1517
|
+
/* @__PURE__ */ jsxs8(
|
|
1379
1518
|
"div",
|
|
1380
1519
|
{
|
|
1381
1520
|
onClick: () => {
|
|
@@ -1398,12 +1537,12 @@ function DeviceControlPanelImpl({
|
|
|
1398
1537
|
alignItems: "center"
|
|
1399
1538
|
},
|
|
1400
1539
|
children: [
|
|
1401
|
-
/* @__PURE__ */
|
|
1402
|
-
/* @__PURE__ */
|
|
1540
|
+
/* @__PURE__ */ jsx9("span", { children: binding.modes.find((m) => m.value === currentMode)?.label || currentMode }),
|
|
1541
|
+
/* @__PURE__ */ jsx9("span", { style: { fontSize: "20px", marginLeft: "8px" }, children: "\u25BC" })
|
|
1403
1542
|
]
|
|
1404
1543
|
}
|
|
1405
1544
|
),
|
|
1406
|
-
showModeModal && /* @__PURE__ */
|
|
1545
|
+
showModeModal && /* @__PURE__ */ jsx9(
|
|
1407
1546
|
"div",
|
|
1408
1547
|
{
|
|
1409
1548
|
style: {
|
|
@@ -1422,7 +1561,7 @@ function DeviceControlPanelImpl({
|
|
|
1422
1561
|
setShowModeModal(false);
|
|
1423
1562
|
setPendingMode(null);
|
|
1424
1563
|
},
|
|
1425
|
-
children: /* @__PURE__ */
|
|
1564
|
+
children: /* @__PURE__ */ jsxs8(
|
|
1426
1565
|
"div",
|
|
1427
1566
|
{
|
|
1428
1567
|
onClick: (e) => e.stopPropagation(),
|
|
@@ -1435,7 +1574,7 @@ function DeviceControlPanelImpl({
|
|
|
1435
1574
|
border: `2px solid ${borderColor}`
|
|
1436
1575
|
},
|
|
1437
1576
|
children: [
|
|
1438
|
-
/* @__PURE__ */
|
|
1577
|
+
/* @__PURE__ */ jsx9(
|
|
1439
1578
|
"h3",
|
|
1440
1579
|
{
|
|
1441
1580
|
style: {
|
|
@@ -1448,7 +1587,7 @@ function DeviceControlPanelImpl({
|
|
|
1448
1587
|
children: "Select Mode"
|
|
1449
1588
|
}
|
|
1450
1589
|
),
|
|
1451
|
-
/* @__PURE__ */
|
|
1590
|
+
/* @__PURE__ */ jsx9(
|
|
1452
1591
|
"div",
|
|
1453
1592
|
{
|
|
1454
1593
|
style: {
|
|
@@ -1462,7 +1601,7 @@ function DeviceControlPanelImpl({
|
|
|
1462
1601
|
children: binding.display?.title || binding.deviceName || binding.tag || binding.nodeId
|
|
1463
1602
|
}
|
|
1464
1603
|
),
|
|
1465
|
-
/* @__PURE__ */
|
|
1604
|
+
/* @__PURE__ */ jsx9(
|
|
1466
1605
|
"select",
|
|
1467
1606
|
{
|
|
1468
1607
|
value: pendingMode || currentMode,
|
|
@@ -1484,7 +1623,7 @@ function DeviceControlPanelImpl({
|
|
|
1484
1623
|
paddingRight: "12px",
|
|
1485
1624
|
cursor: "pointer"
|
|
1486
1625
|
},
|
|
1487
|
-
children: binding.modes.map((mode) => /* @__PURE__ */
|
|
1626
|
+
children: binding.modes.map((mode) => /* @__PURE__ */ jsx9(
|
|
1488
1627
|
"option",
|
|
1489
1628
|
{
|
|
1490
1629
|
value: mode.value,
|
|
@@ -1499,7 +1638,7 @@ function DeviceControlPanelImpl({
|
|
|
1499
1638
|
const selectedMode = binding.modes.find(
|
|
1500
1639
|
(m) => m.value === (pendingMode || currentMode)
|
|
1501
1640
|
);
|
|
1502
|
-
return selectedMode?.description ? /* @__PURE__ */
|
|
1641
|
+
return selectedMode?.description ? /* @__PURE__ */ jsx9(
|
|
1503
1642
|
"div",
|
|
1504
1643
|
{
|
|
1505
1644
|
style: {
|
|
@@ -1517,8 +1656,8 @@ function DeviceControlPanelImpl({
|
|
|
1517
1656
|
}
|
|
1518
1657
|
) : null;
|
|
1519
1658
|
})(),
|
|
1520
|
-
/* @__PURE__ */
|
|
1521
|
-
/* @__PURE__ */
|
|
1659
|
+
/* @__PURE__ */ jsxs8("div", { style: { display: "flex", gap: "12px" }, children: [
|
|
1660
|
+
/* @__PURE__ */ jsx9(
|
|
1522
1661
|
"button",
|
|
1523
1662
|
{
|
|
1524
1663
|
onClick: () => {
|
|
@@ -1546,7 +1685,7 @@ function DeviceControlPanelImpl({
|
|
|
1546
1685
|
children: "Confirm"
|
|
1547
1686
|
}
|
|
1548
1687
|
),
|
|
1549
|
-
/* @__PURE__ */
|
|
1688
|
+
/* @__PURE__ */ jsx9(
|
|
1550
1689
|
"button",
|
|
1551
1690
|
{
|
|
1552
1691
|
onClick: () => {
|
|
@@ -1576,7 +1715,7 @@ function DeviceControlPanelImpl({
|
|
|
1576
1715
|
)
|
|
1577
1716
|
}
|
|
1578
1717
|
)
|
|
1579
|
-
] }) : /* @__PURE__ */
|
|
1718
|
+
] }) : /* @__PURE__ */ jsx9(
|
|
1580
1719
|
"div",
|
|
1581
1720
|
{
|
|
1582
1721
|
style: {
|
|
@@ -1592,7 +1731,7 @@ function DeviceControlPanelImpl({
|
|
|
1592
1731
|
children: binding.modes.map((mode) => {
|
|
1593
1732
|
const isSelected = mode.value === currentMode;
|
|
1594
1733
|
const isEnabled = mode.enabled !== false;
|
|
1595
|
-
return /* @__PURE__ */
|
|
1734
|
+
return /* @__PURE__ */ jsx9(
|
|
1596
1735
|
"button",
|
|
1597
1736
|
{
|
|
1598
1737
|
onClick: () => isEnabled && handleModeChange(mode.value),
|
|
@@ -1622,8 +1761,8 @@ function DeviceControlPanelImpl({
|
|
|
1622
1761
|
}
|
|
1623
1762
|
)
|
|
1624
1763
|
] }),
|
|
1625
|
-
currentParams.length > 0 && /* @__PURE__ */
|
|
1626
|
-
/* @__PURE__ */
|
|
1764
|
+
currentParams.length > 0 && /* @__PURE__ */ jsxs8("div", { style: { marginBottom: spacing.marginBottom }, children: [
|
|
1765
|
+
/* @__PURE__ */ jsx9(
|
|
1627
1766
|
"label",
|
|
1628
1767
|
{
|
|
1629
1768
|
style: {
|
|
@@ -1639,7 +1778,7 @@ function DeviceControlPanelImpl({
|
|
|
1639
1778
|
children: "Parameters"
|
|
1640
1779
|
}
|
|
1641
1780
|
),
|
|
1642
|
-
currentParams.map((param) => /* @__PURE__ */
|
|
1781
|
+
currentParams.map((param) => /* @__PURE__ */ jsxs8(
|
|
1643
1782
|
"div",
|
|
1644
1783
|
{
|
|
1645
1784
|
style: {
|
|
@@ -1650,7 +1789,7 @@ function DeviceControlPanelImpl({
|
|
|
1650
1789
|
borderRadius: "6px"
|
|
1651
1790
|
},
|
|
1652
1791
|
children: [
|
|
1653
|
-
/* @__PURE__ */
|
|
1792
|
+
/* @__PURE__ */ jsxs8(
|
|
1654
1793
|
"div",
|
|
1655
1794
|
{
|
|
1656
1795
|
style: {
|
|
@@ -1659,7 +1798,7 @@ function DeviceControlPanelImpl({
|
|
|
1659
1798
|
marginBottom: spacing.gap
|
|
1660
1799
|
},
|
|
1661
1800
|
children: [
|
|
1662
|
-
/* @__PURE__ */
|
|
1801
|
+
/* @__PURE__ */ jsxs8(
|
|
1663
1802
|
"span",
|
|
1664
1803
|
{
|
|
1665
1804
|
style: {
|
|
@@ -1675,7 +1814,7 @@ function DeviceControlPanelImpl({
|
|
|
1675
1814
|
},
|
|
1676
1815
|
children: [
|
|
1677
1816
|
param.label,
|
|
1678
|
-
param.forced?.active && /* @__PURE__ */
|
|
1817
|
+
param.forced?.active && /* @__PURE__ */ jsx9(
|
|
1679
1818
|
"span",
|
|
1680
1819
|
{
|
|
1681
1820
|
"aria-label": "Forced",
|
|
@@ -1698,7 +1837,7 @@ function DeviceControlPanelImpl({
|
|
|
1698
1837
|
]
|
|
1699
1838
|
}
|
|
1700
1839
|
),
|
|
1701
|
-
/* @__PURE__ */
|
|
1840
|
+
/* @__PURE__ */ jsxs8(
|
|
1702
1841
|
"span",
|
|
1703
1842
|
{
|
|
1704
1843
|
style: {
|
|
@@ -1710,14 +1849,14 @@ function DeviceControlPanelImpl({
|
|
|
1710
1849
|
children: [
|
|
1711
1850
|
localParameterValues[param.id] ?? param.value,
|
|
1712
1851
|
" ",
|
|
1713
|
-
param.unit && /* @__PURE__ */
|
|
1852
|
+
param.unit && /* @__PURE__ */ jsx9("span", { style: { color: mutedTextColor, fontSize: "10px", fontWeight: 600 }, children: param.unit })
|
|
1714
1853
|
]
|
|
1715
1854
|
}
|
|
1716
1855
|
)
|
|
1717
1856
|
]
|
|
1718
1857
|
}
|
|
1719
1858
|
),
|
|
1720
|
-
param.forced?.active && param.forced.realValue !== void 0 && /* @__PURE__ */
|
|
1859
|
+
param.forced?.active && param.forced.realValue !== void 0 && /* @__PURE__ */ jsxs8(
|
|
1721
1860
|
"div",
|
|
1722
1861
|
{
|
|
1723
1862
|
style: {
|
|
@@ -1738,7 +1877,7 @@ function DeviceControlPanelImpl({
|
|
|
1738
1877
|
]
|
|
1739
1878
|
}
|
|
1740
1879
|
),
|
|
1741
|
-
param.type === "boolean" ? /* @__PURE__ */
|
|
1880
|
+
param.type === "boolean" ? /* @__PURE__ */ jsx9(
|
|
1742
1881
|
"button",
|
|
1743
1882
|
{
|
|
1744
1883
|
onClick: () => {
|
|
@@ -1763,7 +1902,7 @@ function DeviceControlPanelImpl({
|
|
|
1763
1902
|
},
|
|
1764
1903
|
children: localParameterValues[param.id] ? "ON" : "OFF"
|
|
1765
1904
|
}
|
|
1766
|
-
) : param.type === "select" ? /* @__PURE__ */
|
|
1905
|
+
) : param.type === "select" ? /* @__PURE__ */ jsx9(
|
|
1767
1906
|
"select",
|
|
1768
1907
|
{
|
|
1769
1908
|
value: localParameterValues[param.id] || param.value,
|
|
@@ -1784,12 +1923,12 @@ function DeviceControlPanelImpl({
|
|
|
1784
1923
|
fontFamily: "monospace",
|
|
1785
1924
|
cursor: "pointer"
|
|
1786
1925
|
},
|
|
1787
|
-
children: param.options?.map((opt) => /* @__PURE__ */
|
|
1926
|
+
children: param.options?.map((opt) => /* @__PURE__ */ jsx9("option", { value: opt.value, children: opt.label }, opt.value))
|
|
1788
1927
|
}
|
|
1789
1928
|
) : onParameterActivate && !param.readOnly ? (
|
|
1790
1929
|
// Tappable value: defer editing to the consumer's editor (e.g. a
|
|
1791
1930
|
// numpad dialog). Commit happens via onParameterChange.
|
|
1792
|
-
/* @__PURE__ */
|
|
1931
|
+
/* @__PURE__ */ jsxs8(
|
|
1793
1932
|
"button",
|
|
1794
1933
|
{
|
|
1795
1934
|
type: "button",
|
|
@@ -1816,7 +1955,7 @@ function DeviceControlPanelImpl({
|
|
|
1816
1955
|
]
|
|
1817
1956
|
}
|
|
1818
1957
|
)
|
|
1819
|
-
) : /* @__PURE__ */
|
|
1958
|
+
) : /* @__PURE__ */ jsx9(
|
|
1820
1959
|
"input",
|
|
1821
1960
|
{
|
|
1822
1961
|
type: param.type === "number" ? "number" : "text",
|
|
@@ -1849,8 +1988,8 @@ function DeviceControlPanelImpl({
|
|
|
1849
1988
|
param.id
|
|
1850
1989
|
))
|
|
1851
1990
|
] }),
|
|
1852
|
-
binding.display?.showStartStop !== false && (activeCapabilities?.canStart || activeCapabilities?.canStop) && /* @__PURE__ */
|
|
1853
|
-
activeCapabilities?.canStart && /* @__PURE__ */
|
|
1991
|
+
binding.display?.showStartStop !== false && (activeCapabilities?.canStart || activeCapabilities?.canStop) && /* @__PURE__ */ jsxs8("div", { style: { display: "flex", gap: spacing.gap, marginBottom: spacing.marginBottom }, children: [
|
|
1992
|
+
activeCapabilities?.canStart && /* @__PURE__ */ jsx9(
|
|
1854
1993
|
"button",
|
|
1855
1994
|
{
|
|
1856
1995
|
onClick: onStart,
|
|
@@ -1871,7 +2010,7 @@ function DeviceControlPanelImpl({
|
|
|
1871
2010
|
children: startPending ? "STARTING\u2026" : "START"
|
|
1872
2011
|
}
|
|
1873
2012
|
),
|
|
1874
|
-
activeCapabilities?.canStop && /* @__PURE__ */
|
|
2013
|
+
activeCapabilities?.canStop && /* @__PURE__ */ jsx9(
|
|
1875
2014
|
"button",
|
|
1876
2015
|
{
|
|
1877
2016
|
onClick: onStop,
|
|
@@ -1893,9 +2032,9 @@ function DeviceControlPanelImpl({
|
|
|
1893
2032
|
}
|
|
1894
2033
|
)
|
|
1895
2034
|
] }),
|
|
1896
|
-
activeCapabilities?.customActions && activeCapabilities.customActions.length > 0 && /* @__PURE__ */
|
|
2035
|
+
activeCapabilities?.customActions && activeCapabilities.customActions.length > 0 && /* @__PURE__ */ jsx9("div", { style: { display: "flex", flexWrap: "wrap", gap: "8px" }, children: activeCapabilities.customActions.map((action) => {
|
|
1897
2036
|
const actionDisabled = action.disabled === true;
|
|
1898
|
-
return /* @__PURE__ */
|
|
2037
|
+
return /* @__PURE__ */ jsxs8(
|
|
1899
2038
|
"button",
|
|
1900
2039
|
{
|
|
1901
2040
|
onClick: () => {
|
|
@@ -1921,7 +2060,7 @@ function DeviceControlPanelImpl({
|
|
|
1921
2060
|
transition: "all 0.15s"
|
|
1922
2061
|
},
|
|
1923
2062
|
children: [
|
|
1924
|
-
action.icon && /* @__PURE__ */
|
|
2063
|
+
action.icon && /* @__PURE__ */ jsx9("span", { style: { marginRight: "6px" }, children: action.icon }),
|
|
1925
2064
|
action.label
|
|
1926
2065
|
]
|
|
1927
2066
|
},
|
|
@@ -1929,7 +2068,7 @@ function DeviceControlPanelImpl({
|
|
|
1929
2068
|
);
|
|
1930
2069
|
}) })
|
|
1931
2070
|
] }),
|
|
1932
|
-
binding.state.lastCommandResult && showToast && showBuiltInToast && /* @__PURE__ */
|
|
2071
|
+
binding.state.lastCommandResult && showToast && showBuiltInToast && /* @__PURE__ */ jsx9(
|
|
1933
2072
|
"div",
|
|
1934
2073
|
{
|
|
1935
2074
|
style: {
|
|
@@ -1953,7 +2092,7 @@ function DeviceControlPanelImpl({
|
|
|
1953
2092
|
children: binding.state.lastCommandResult.message
|
|
1954
2093
|
}
|
|
1955
2094
|
),
|
|
1956
|
-
/* @__PURE__ */
|
|
2095
|
+
/* @__PURE__ */ jsx9("style", { children: `
|
|
1957
2096
|
@keyframes slideInToast {
|
|
1958
2097
|
from {
|
|
1959
2098
|
opacity: 0;
|
|
@@ -1985,11 +2124,11 @@ function DeviceControlPanelImpl({
|
|
|
1985
2124
|
` })
|
|
1986
2125
|
] });
|
|
1987
2126
|
}
|
|
1988
|
-
var DeviceControlPanel =
|
|
2127
|
+
var DeviceControlPanel = React6.memo(DeviceControlPanelImpl);
|
|
1989
2128
|
|
|
1990
2129
|
// src/components/NumpadDialog/NumpadDialog.tsx
|
|
1991
2130
|
import { useState as useState6, useEffect as useEffect3, useCallback as useCallback3, useRef as useRef2, useId } from "react";
|
|
1992
|
-
import { jsx as
|
|
2131
|
+
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1993
2132
|
var NumpadDialog = ({
|
|
1994
2133
|
isOpen,
|
|
1995
2134
|
onClose,
|
|
@@ -2193,7 +2332,7 @@ var NumpadDialog = ({
|
|
|
2193
2332
|
};
|
|
2194
2333
|
const reason = belowMin ? `Below minimum of ${min} ${unit}` : aboveMax ? `Above maximum of ${max} ${unit}` : "Type or tap to change the value";
|
|
2195
2334
|
const backspaceInGrid = min >= 0;
|
|
2196
|
-
const BackspaceButton = ({ style, label }) => /* @__PURE__ */
|
|
2335
|
+
const BackspaceButton = ({ style, label }) => /* @__PURE__ */ jsx10(
|
|
2197
2336
|
"button",
|
|
2198
2337
|
{
|
|
2199
2338
|
type: "button",
|
|
@@ -2210,7 +2349,7 @@ var NumpadDialog = ({
|
|
|
2210
2349
|
);
|
|
2211
2350
|
return (
|
|
2212
2351
|
// Backdrop
|
|
2213
|
-
/* @__PURE__ */
|
|
2352
|
+
/* @__PURE__ */ jsxs9(
|
|
2214
2353
|
"div",
|
|
2215
2354
|
{
|
|
2216
2355
|
style: {
|
|
@@ -2227,14 +2366,14 @@ var NumpadDialog = ({
|
|
|
2227
2366
|
},
|
|
2228
2367
|
onClick: onClose,
|
|
2229
2368
|
children: [
|
|
2230
|
-
/* @__PURE__ */
|
|
2369
|
+
/* @__PURE__ */ jsx10("style", { children: `
|
|
2231
2370
|
.np-key { transition: background .1s, transform .05s; touch-action: manipulation; }
|
|
2232
2371
|
.np-key:active:not(:disabled) { background:#e2e8f0; transform: translateY(1px); }
|
|
2233
2372
|
.np-key:focus-visible, .np-action:focus-visible { outline: 3px solid #2563eb; outline-offset: 2px; }
|
|
2234
2373
|
@keyframes np-blink { 0%,49%{opacity:1} 50%,100%{opacity:0} }
|
|
2235
2374
|
.np-caret { display:inline-block; width:2px; height:1.1em; background:#2563eb; animation: np-blink 1s step-end infinite; }
|
|
2236
2375
|
` }),
|
|
2237
|
-
/* @__PURE__ */
|
|
2376
|
+
/* @__PURE__ */ jsxs9(
|
|
2238
2377
|
"div",
|
|
2239
2378
|
{
|
|
2240
2379
|
ref: dialogRef,
|
|
@@ -2255,9 +2394,9 @@ var NumpadDialog = ({
|
|
|
2255
2394
|
},
|
|
2256
2395
|
onClick: (e) => e.stopPropagation(),
|
|
2257
2396
|
children: [
|
|
2258
|
-
/* @__PURE__ */
|
|
2259
|
-
/* @__PURE__ */
|
|
2260
|
-
/* @__PURE__ */
|
|
2397
|
+
/* @__PURE__ */ jsx10("div", { style: { padding: "14px 16px 0 16px" }, children: /* @__PURE__ */ jsx10("h3", { id: titleId, style: { margin: 0, fontSize: 15, fontWeight: 700, color: "#0f172a" }, children: deviceName ? `${deviceName} - ${parameterLabel}` : parameterLabel }) }),
|
|
2398
|
+
/* @__PURE__ */ jsxs9("div", { style: { padding: 16, display: "flex", flexDirection: "column", gap: 10 }, children: [
|
|
2399
|
+
/* @__PURE__ */ jsxs9(
|
|
2261
2400
|
"div",
|
|
2262
2401
|
{
|
|
2263
2402
|
style: {
|
|
@@ -2267,24 +2406,24 @@ var NumpadDialog = ({
|
|
|
2267
2406
|
color: "#64748b"
|
|
2268
2407
|
},
|
|
2269
2408
|
children: [
|
|
2270
|
-
/* @__PURE__ */
|
|
2409
|
+
/* @__PURE__ */ jsxs9("span", { children: [
|
|
2271
2410
|
"Current: ",
|
|
2272
2411
|
currentValue,
|
|
2273
2412
|
" ",
|
|
2274
2413
|
unit
|
|
2275
2414
|
] }),
|
|
2276
|
-
/* @__PURE__ */
|
|
2415
|
+
/* @__PURE__ */ jsxs9("span", { children: [
|
|
2277
2416
|
"Range: ",
|
|
2278
|
-
/* @__PURE__ */
|
|
2417
|
+
/* @__PURE__ */ jsx10("span", { style: limitStyle(belowMin), children: min }),
|
|
2279
2418
|
"-",
|
|
2280
|
-
/* @__PURE__ */
|
|
2419
|
+
/* @__PURE__ */ jsx10("span", { style: limitStyle(aboveMax), children: max }),
|
|
2281
2420
|
" ",
|
|
2282
2421
|
unit
|
|
2283
2422
|
] })
|
|
2284
2423
|
]
|
|
2285
2424
|
}
|
|
2286
2425
|
),
|
|
2287
|
-
/* @__PURE__ */
|
|
2426
|
+
/* @__PURE__ */ jsxs9(
|
|
2288
2427
|
"div",
|
|
2289
2428
|
{
|
|
2290
2429
|
"aria-live": "polite",
|
|
@@ -2306,13 +2445,13 @@ var NumpadDialog = ({
|
|
|
2306
2445
|
border: outOfRange ? "1.5px solid #fca5a5" : "1.5px solid #e2e8f0"
|
|
2307
2446
|
},
|
|
2308
2447
|
children: [
|
|
2309
|
-
/* @__PURE__ */
|
|
2310
|
-
/* @__PURE__ */
|
|
2311
|
-
/* @__PURE__ */
|
|
2448
|
+
/* @__PURE__ */ jsx10("span", { children: inputValue || "0" }),
|
|
2449
|
+
/* @__PURE__ */ jsx10("span", { className: "np-caret", "aria-hidden": "true" }),
|
|
2450
|
+
/* @__PURE__ */ jsx10("span", { style: { fontSize: 14, color: "#94a3b8", fontWeight: 500 }, children: unit })
|
|
2312
2451
|
]
|
|
2313
2452
|
}
|
|
2314
2453
|
),
|
|
2315
|
-
/* @__PURE__ */
|
|
2454
|
+
/* @__PURE__ */ jsx10(
|
|
2316
2455
|
"div",
|
|
2317
2456
|
{
|
|
2318
2457
|
role: "status",
|
|
@@ -2327,8 +2466,8 @@ var NumpadDialog = ({
|
|
|
2327
2466
|
children: reason
|
|
2328
2467
|
}
|
|
2329
2468
|
),
|
|
2330
|
-
/* @__PURE__ */
|
|
2331
|
-
["7", "8", "9", "4", "5", "6", "1", "2", "3"].map((digit) => /* @__PURE__ */
|
|
2469
|
+
/* @__PURE__ */ jsxs9("div", { style: { display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 5 }, children: [
|
|
2470
|
+
["7", "8", "9", "4", "5", "6", "1", "2", "3"].map((digit) => /* @__PURE__ */ jsx10(
|
|
2332
2471
|
"button",
|
|
2333
2472
|
{
|
|
2334
2473
|
type: "button",
|
|
@@ -2340,7 +2479,7 @@ var NumpadDialog = ({
|
|
|
2340
2479
|
},
|
|
2341
2480
|
digit
|
|
2342
2481
|
)),
|
|
2343
|
-
min < 0 ? /* @__PURE__ */
|
|
2482
|
+
min < 0 ? /* @__PURE__ */ jsx10(
|
|
2344
2483
|
"button",
|
|
2345
2484
|
{
|
|
2346
2485
|
type: "button",
|
|
@@ -2351,9 +2490,9 @@ var NumpadDialog = ({
|
|
|
2351
2490
|
onClick: handleToggleSign,
|
|
2352
2491
|
children: "+/\u2212"
|
|
2353
2492
|
}
|
|
2354
|
-
) : /* @__PURE__ */
|
|
2355
|
-
/* @__PURE__ */
|
|
2356
|
-
/* @__PURE__ */
|
|
2493
|
+
) : /* @__PURE__ */ jsx10(BackspaceButton, { style: { ...keyStyle, fontSize: 20, background: "#f8fafc", color: "#64748b" }, label: "\u232B" }),
|
|
2494
|
+
/* @__PURE__ */ jsx10("button", { type: "button", className: "np-key", tabIndex: -1, style: keyStyle, onClick: () => appendDigit("0"), children: "0" }),
|
|
2495
|
+
/* @__PURE__ */ jsx10(
|
|
2357
2496
|
"button",
|
|
2358
2497
|
{
|
|
2359
2498
|
type: "button",
|
|
@@ -2371,12 +2510,12 @@ var NumpadDialog = ({
|
|
|
2371
2510
|
}
|
|
2372
2511
|
)
|
|
2373
2512
|
] }),
|
|
2374
|
-
/* @__PURE__ */
|
|
2375
|
-
/* @__PURE__ */
|
|
2376
|
-
!backspaceInGrid && /* @__PURE__ */
|
|
2513
|
+
/* @__PURE__ */ jsxs9("div", { style: { display: "flex", gap: 5 }, children: [
|
|
2514
|
+
/* @__PURE__ */ jsx10("button", { type: "button", className: "np-key", tabIndex: -1, style: utilKeyStyle, onClick: handleClear, children: "Clear" }),
|
|
2515
|
+
!backspaceInGrid && /* @__PURE__ */ jsx10(BackspaceButton, { style: utilKeyStyle, label: "Backspace" })
|
|
2377
2516
|
] }),
|
|
2378
|
-
/* @__PURE__ */
|
|
2379
|
-
/* @__PURE__ */
|
|
2517
|
+
/* @__PURE__ */ jsxs9("div", { style: { display: "flex", gap: 8, marginTop: 2 }, children: [
|
|
2518
|
+
/* @__PURE__ */ jsx10(
|
|
2380
2519
|
"button",
|
|
2381
2520
|
{
|
|
2382
2521
|
type: "button",
|
|
@@ -2396,7 +2535,7 @@ var NumpadDialog = ({
|
|
|
2396
2535
|
children: "Cancel"
|
|
2397
2536
|
}
|
|
2398
2537
|
),
|
|
2399
|
-
/* @__PURE__ */
|
|
2538
|
+
/* @__PURE__ */ jsx10(
|
|
2400
2539
|
"button",
|
|
2401
2540
|
{
|
|
2402
2541
|
type: "button",
|
|
@@ -2431,13 +2570,13 @@ var NumpadDialog = ({
|
|
|
2431
2570
|
};
|
|
2432
2571
|
|
|
2433
2572
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.tsx
|
|
2434
|
-
import
|
|
2573
|
+
import React8 from "react";
|
|
2435
2574
|
import { Tab } from "@mui/material";
|
|
2436
2575
|
|
|
2437
2576
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.styles.tsx
|
|
2438
2577
|
import { Box, IconButton, Tabs } from "@mui/material";
|
|
2439
2578
|
import styled from "@emotion/styled";
|
|
2440
|
-
import { jsx as
|
|
2579
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
2441
2580
|
var FullscreenContainer = styled(Box)(
|
|
2442
2581
|
({ leftCollapsed, rightCollapsed }) => {
|
|
2443
2582
|
const getGridTemplateAreas = () => {
|
|
@@ -2562,7 +2701,7 @@ var DisplayModeToggle = styled(IconButton)(({ mode }) => ({
|
|
|
2562
2701
|
transform: "translateX(-50%) scale(1.05)"
|
|
2563
2702
|
}
|
|
2564
2703
|
}));
|
|
2565
|
-
var ChevronLeft = () => /* @__PURE__ */
|
|
2704
|
+
var ChevronLeft = () => /* @__PURE__ */ jsx11(
|
|
2566
2705
|
"div",
|
|
2567
2706
|
{
|
|
2568
2707
|
style: {
|
|
@@ -2574,7 +2713,7 @@ var ChevronLeft = () => /* @__PURE__ */ jsx10(
|
|
|
2574
2713
|
}
|
|
2575
2714
|
}
|
|
2576
2715
|
);
|
|
2577
|
-
var ChevronRight = () => /* @__PURE__ */
|
|
2716
|
+
var ChevronRight = () => /* @__PURE__ */ jsx11(
|
|
2578
2717
|
"div",
|
|
2579
2718
|
{
|
|
2580
2719
|
style: {
|
|
@@ -2688,7 +2827,7 @@ var ScrollableSVGWrapper = styled("div")({
|
|
|
2688
2827
|
import { useEffect as useEffect4, useState as useState7 } from "react";
|
|
2689
2828
|
import { Box as Box2 } from "@mui/material";
|
|
2690
2829
|
import styled2 from "@emotion/styled";
|
|
2691
|
-
import { jsx as
|
|
2830
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
2692
2831
|
var baseOverlayStyles = {
|
|
2693
2832
|
tank: {
|
|
2694
2833
|
background: "linear-gradient(135deg, rgba(69, 90, 120, 0.95) 0%, rgba(52, 73, 94, 0.95) 100%)",
|
|
@@ -2771,7 +2910,7 @@ var SVGLockedOverlay = ({
|
|
|
2771
2910
|
const pixelX = svgX + svgOffset.x;
|
|
2772
2911
|
const pixelY = svgY + svgOffset.y;
|
|
2773
2912
|
const appliedStyle = theme ? { ...overlayStyles[theme], ...style } : style;
|
|
2774
|
-
return /* @__PURE__ */
|
|
2913
|
+
return /* @__PURE__ */ jsx12(
|
|
2775
2914
|
Box2,
|
|
2776
2915
|
{
|
|
2777
2916
|
className: `svg-locked-overlay ${className}`.trim(),
|
|
@@ -2835,7 +2974,7 @@ var CardUnit = styled2("div")({
|
|
|
2835
2974
|
});
|
|
2836
2975
|
|
|
2837
2976
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.visuals.tsx
|
|
2838
|
-
import { Fragment as Fragment3, jsx as
|
|
2977
|
+
import { Fragment as Fragment3, jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2839
2978
|
var forcedTagStyle = {
|
|
2840
2979
|
position: "absolute",
|
|
2841
2980
|
top: "-6px",
|
|
@@ -2863,7 +3002,7 @@ var TrendLine = ({
|
|
|
2863
3002
|
forced = false
|
|
2864
3003
|
}) => {
|
|
2865
3004
|
if (!values || values.length < 2) {
|
|
2866
|
-
return /* @__PURE__ */
|
|
3005
|
+
return /* @__PURE__ */ jsxs10(
|
|
2867
3006
|
"div",
|
|
2868
3007
|
{
|
|
2869
3008
|
style: {
|
|
@@ -2877,8 +3016,8 @@ var TrendLine = ({
|
|
|
2877
3016
|
justifyContent: "center"
|
|
2878
3017
|
},
|
|
2879
3018
|
children: [
|
|
2880
|
-
/* @__PURE__ */
|
|
2881
|
-
forced && /* @__PURE__ */
|
|
3019
|
+
/* @__PURE__ */ jsx13("span", { style: { fontSize: "8px", color: "#ccc" }, children: "No data" }),
|
|
3020
|
+
forced && /* @__PURE__ */ jsx13("span", { style: forcedTagStyle, "aria-label": "Forced", children: "F" })
|
|
2882
3021
|
]
|
|
2883
3022
|
}
|
|
2884
3023
|
);
|
|
@@ -2891,7 +3030,7 @@ var TrendLine = ({
|
|
|
2891
3030
|
const x = 4 + i / (values.length - 1) * (width - 8);
|
|
2892
3031
|
return i === 0 ? `M ${x} ${y}` : `L ${x} ${y}`;
|
|
2893
3032
|
}).join(" ");
|
|
2894
|
-
return /* @__PURE__ */
|
|
3033
|
+
return /* @__PURE__ */ jsxs10(
|
|
2895
3034
|
"div",
|
|
2896
3035
|
{
|
|
2897
3036
|
style: {
|
|
@@ -2903,14 +3042,14 @@ var TrendLine = ({
|
|
|
2903
3042
|
overflow: "visible"
|
|
2904
3043
|
},
|
|
2905
3044
|
children: [
|
|
2906
|
-
/* @__PURE__ */
|
|
3045
|
+
/* @__PURE__ */ jsxs10(
|
|
2907
3046
|
"svg",
|
|
2908
3047
|
{
|
|
2909
3048
|
width,
|
|
2910
3049
|
height,
|
|
2911
3050
|
style: { position: "absolute", top: 0, left: 0, overflow: "hidden", borderRadius: "2px" },
|
|
2912
3051
|
children: [
|
|
2913
|
-
/* @__PURE__ */
|
|
3052
|
+
/* @__PURE__ */ jsx13(
|
|
2914
3053
|
"path",
|
|
2915
3054
|
{
|
|
2916
3055
|
d: pathData,
|
|
@@ -2921,7 +3060,7 @@ var TrendLine = ({
|
|
|
2921
3060
|
strokeLinejoin: "round"
|
|
2922
3061
|
}
|
|
2923
3062
|
),
|
|
2924
|
-
/* @__PURE__ */
|
|
3063
|
+
/* @__PURE__ */ jsx13(
|
|
2925
3064
|
"circle",
|
|
2926
3065
|
{
|
|
2927
3066
|
cx: 4 + (width - 8),
|
|
@@ -2933,7 +3072,7 @@ var TrendLine = ({
|
|
|
2933
3072
|
]
|
|
2934
3073
|
}
|
|
2935
3074
|
),
|
|
2936
|
-
forced && /* @__PURE__ */
|
|
3075
|
+
forced && /* @__PURE__ */ jsx13("span", { style: forcedTagStyle, "aria-label": "Forced", children: "F" })
|
|
2937
3076
|
]
|
|
2938
3077
|
}
|
|
2939
3078
|
);
|
|
@@ -2965,7 +3104,7 @@ var CircularGauge = ({
|
|
|
2965
3104
|
const borderColor = isHex ? hexToRgba(color, 0.9) : color;
|
|
2966
3105
|
const backgroundColor = isHex ? hexToRgba(color, 0.15) : color;
|
|
2967
3106
|
const borderStrokeColor = isHex ? hexToRgba(color, 0.4) : color;
|
|
2968
|
-
return /* @__PURE__ */
|
|
3107
|
+
return /* @__PURE__ */ jsxs10(
|
|
2969
3108
|
"div",
|
|
2970
3109
|
{
|
|
2971
3110
|
style: {
|
|
@@ -2974,7 +3113,7 @@ var CircularGauge = ({
|
|
|
2974
3113
|
alignItems: "center"
|
|
2975
3114
|
},
|
|
2976
3115
|
children: [
|
|
2977
|
-
/* @__PURE__ */
|
|
3116
|
+
/* @__PURE__ */ jsxs10(
|
|
2978
3117
|
"div",
|
|
2979
3118
|
{
|
|
2980
3119
|
style: {
|
|
@@ -2986,8 +3125,8 @@ var CircularGauge = ({
|
|
|
2986
3125
|
border: forced ? `2px solid ${FORCED_MARK_COLOR.border}` : `1px solid ${borderStrokeColor}`
|
|
2987
3126
|
},
|
|
2988
3127
|
children: [
|
|
2989
|
-
/* @__PURE__ */
|
|
2990
|
-
/* @__PURE__ */
|
|
3128
|
+
/* @__PURE__ */ jsxs10("svg", { width: size, height: size, style: { transform: "rotate(-90deg)" }, children: [
|
|
3129
|
+
/* @__PURE__ */ jsx13(
|
|
2991
3130
|
"circle",
|
|
2992
3131
|
{
|
|
2993
3132
|
cx: size / 2,
|
|
@@ -2998,7 +3137,7 @@ var CircularGauge = ({
|
|
|
2998
3137
|
strokeWidth: 1
|
|
2999
3138
|
}
|
|
3000
3139
|
),
|
|
3001
|
-
/* @__PURE__ */
|
|
3140
|
+
/* @__PURE__ */ jsx13(
|
|
3002
3141
|
"circle",
|
|
3003
3142
|
{
|
|
3004
3143
|
cx: size / 2,
|
|
@@ -3009,7 +3148,7 @@ var CircularGauge = ({
|
|
|
3009
3148
|
fill: "transparent"
|
|
3010
3149
|
}
|
|
3011
3150
|
),
|
|
3012
|
-
/* @__PURE__ */
|
|
3151
|
+
/* @__PURE__ */ jsx13(
|
|
3013
3152
|
"circle",
|
|
3014
3153
|
{
|
|
3015
3154
|
cx: size / 2,
|
|
@@ -3025,7 +3164,7 @@ var CircularGauge = ({
|
|
|
3025
3164
|
}
|
|
3026
3165
|
)
|
|
3027
3166
|
] }),
|
|
3028
|
-
/* @__PURE__ */
|
|
3167
|
+
/* @__PURE__ */ jsxs10(
|
|
3029
3168
|
"div",
|
|
3030
3169
|
{
|
|
3031
3170
|
style: {
|
|
@@ -3041,14 +3180,14 @@ var CircularGauge = ({
|
|
|
3041
3180
|
},
|
|
3042
3181
|
children: [
|
|
3043
3182
|
value.toFixed(1),
|
|
3044
|
-
/* @__PURE__ */
|
|
3183
|
+
/* @__PURE__ */ jsx13("div", { style: { fontSize: "8px", opacity: 0.9, color: "white" }, children: unit })
|
|
3045
3184
|
]
|
|
3046
3185
|
}
|
|
3047
3186
|
)
|
|
3048
3187
|
]
|
|
3049
3188
|
}
|
|
3050
3189
|
),
|
|
3051
|
-
/* @__PURE__ */
|
|
3190
|
+
/* @__PURE__ */ jsx13(
|
|
3052
3191
|
"div",
|
|
3053
3192
|
{
|
|
3054
3193
|
style: {
|
|
@@ -3060,7 +3199,7 @@ var CircularGauge = ({
|
|
|
3060
3199
|
children: label
|
|
3061
3200
|
}
|
|
3062
3201
|
),
|
|
3063
|
-
forced && /* @__PURE__ */
|
|
3202
|
+
forced && /* @__PURE__ */ jsx13(
|
|
3064
3203
|
"span",
|
|
3065
3204
|
{
|
|
3066
3205
|
"aria-label": "Forced",
|
|
@@ -3081,7 +3220,7 @@ var CircularGauge = ({
|
|
|
3081
3220
|
children: "F"
|
|
3082
3221
|
}
|
|
3083
3222
|
),
|
|
3084
|
-
forced && realValue !== void 0 && /* @__PURE__ */
|
|
3223
|
+
forced && realValue !== void 0 && /* @__PURE__ */ jsxs10("div", { style: { fontSize: "8px", opacity: 0.8, color: "white", marginTop: "1px" }, children: [
|
|
3085
3224
|
"REAL ",
|
|
3086
3225
|
realValue.toFixed(1),
|
|
3087
3226
|
" ",
|
|
@@ -3106,7 +3245,7 @@ var Sparkline = ({ data, width, height, color, forced = false }) => {
|
|
|
3106
3245
|
const y = height - 8 - (value - min) / range * (height - 8);
|
|
3107
3246
|
return `${x + 4},${y + 4}`;
|
|
3108
3247
|
}).join(" ");
|
|
3109
|
-
return /* @__PURE__ */
|
|
3248
|
+
return /* @__PURE__ */ jsxs10(
|
|
3110
3249
|
"div",
|
|
3111
3250
|
{
|
|
3112
3251
|
style: {
|
|
@@ -3122,13 +3261,13 @@ var Sparkline = ({ data, width, height, color, forced = false }) => {
|
|
|
3122
3261
|
boxShadow: "0 1px 3px rgba(0, 0, 0, 0.2)"
|
|
3123
3262
|
},
|
|
3124
3263
|
children: [
|
|
3125
|
-
/* @__PURE__ */
|
|
3126
|
-
forced && /* @__PURE__ */
|
|
3264
|
+
/* @__PURE__ */ jsx13("svg", { width, height, children: /* @__PURE__ */ jsx13("polyline", { points, fill: "none", stroke: color, strokeWidth: "1.5", opacity: "0.9" }) }),
|
|
3265
|
+
forced && /* @__PURE__ */ jsx13("span", { style: forcedTagStyle, "aria-label": "Forced", children: "F" })
|
|
3127
3266
|
]
|
|
3128
3267
|
}
|
|
3129
3268
|
);
|
|
3130
3269
|
};
|
|
3131
|
-
var EquipmentForcedBadge = () => /* @__PURE__ */
|
|
3270
|
+
var EquipmentForcedBadge = () => /* @__PURE__ */ jsx13(
|
|
3132
3271
|
"span",
|
|
3133
3272
|
{
|
|
3134
3273
|
"aria-label": "Forced",
|
|
@@ -3163,9 +3302,9 @@ var EquipmentIndicatorWithSparkline = ({
|
|
|
3163
3302
|
forced = false
|
|
3164
3303
|
}) => {
|
|
3165
3304
|
const hasSparkline = sparklineData && sparklineData.length > 1 && Math.max(...sparklineData) !== Math.min(...sparklineData);
|
|
3166
|
-
return /* @__PURE__ */
|
|
3167
|
-
/* @__PURE__ */
|
|
3168
|
-
/* @__PURE__ */
|
|
3305
|
+
return /* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
3306
|
+
/* @__PURE__ */ jsx13(SVGLockedOverlay, { svgX, svgY, style: { transform: "translate(-50%, -50%)" }, children: /* @__PURE__ */ jsxs10("div", { style: { position: "relative", width: size, height: size }, children: [
|
|
3307
|
+
/* @__PURE__ */ jsx13(
|
|
3169
3308
|
"div",
|
|
3170
3309
|
{
|
|
3171
3310
|
style: {
|
|
@@ -3186,9 +3325,9 @@ var EquipmentIndicatorWithSparkline = ({
|
|
|
3186
3325
|
children: label
|
|
3187
3326
|
}
|
|
3188
3327
|
),
|
|
3189
|
-
forced && /* @__PURE__ */
|
|
3328
|
+
forced && /* @__PURE__ */ jsx13(EquipmentForcedBadge, {})
|
|
3190
3329
|
] }) }),
|
|
3191
|
-
hasSparkline && /* @__PURE__ */
|
|
3330
|
+
hasSparkline && /* @__PURE__ */ jsx13(SVGLockedOverlay, { svgX: svgX + sparklineOffset.x, svgY: svgY + sparklineOffset.y, children: /* @__PURE__ */ jsx13(Sparkline, { data: sparklineData, width: 60, height: 20, color, forced }) })
|
|
3192
3331
|
] });
|
|
3193
3332
|
};
|
|
3194
3333
|
var EquipmentIndicator = ({
|
|
@@ -3202,8 +3341,8 @@ var EquipmentIndicator = ({
|
|
|
3202
3341
|
forced = false
|
|
3203
3342
|
}) => {
|
|
3204
3343
|
const overlayStyle = style !== void 0 ? { transform: "translate(-50%, -50%)", ...style } : { transform: "translate(-50%, -50%)" };
|
|
3205
|
-
return /* @__PURE__ */
|
|
3206
|
-
/* @__PURE__ */
|
|
3344
|
+
return /* @__PURE__ */ jsx13(SVGLockedOverlay, { svgX, svgY, style: overlayStyle, className, children: /* @__PURE__ */ jsxs10("div", { style: { position: "relative", width: size, height: size }, children: [
|
|
3345
|
+
/* @__PURE__ */ jsx13(
|
|
3207
3346
|
"div",
|
|
3208
3347
|
{
|
|
3209
3348
|
style: {
|
|
@@ -3224,12 +3363,12 @@ var EquipmentIndicator = ({
|
|
|
3224
3363
|
children: label
|
|
3225
3364
|
}
|
|
3226
3365
|
),
|
|
3227
|
-
forced && /* @__PURE__ */
|
|
3366
|
+
forced && /* @__PURE__ */ jsx13(EquipmentForcedBadge, {})
|
|
3228
3367
|
] }) });
|
|
3229
3368
|
};
|
|
3230
3369
|
|
|
3231
3370
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.tsx
|
|
3232
|
-
import { Fragment as Fragment4, jsx as
|
|
3371
|
+
import { Fragment as Fragment4, jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
3233
3372
|
function FullscreenWorkspace({
|
|
3234
3373
|
svgContent,
|
|
3235
3374
|
overlays,
|
|
@@ -3257,10 +3396,10 @@ function FullscreenWorkspace({
|
|
|
3257
3396
|
className = "",
|
|
3258
3397
|
...rest
|
|
3259
3398
|
}) {
|
|
3260
|
-
const [leftCollapsedState, setLeftCollapsedState] =
|
|
3261
|
-
const [rightCollapsedState, setRightCollapsedState] =
|
|
3262
|
-
const [internalDisplayMode, setInternalDisplayMode] =
|
|
3263
|
-
const [internalTab, setInternalTab] =
|
|
3399
|
+
const [leftCollapsedState, setLeftCollapsedState] = React8.useState(defaultLeftCollapsed);
|
|
3400
|
+
const [rightCollapsedState, setRightCollapsedState] = React8.useState(defaultRightCollapsed);
|
|
3401
|
+
const [internalDisplayMode, setInternalDisplayMode] = React8.useState(displayMode ?? defaultDisplayMode);
|
|
3402
|
+
const [internalTab, setInternalTab] = React8.useState(
|
|
3264
3403
|
tabs && tabs.length > 0 ? tabs[0].value : ""
|
|
3265
3404
|
);
|
|
3266
3405
|
const leftCollapsed = leftCollapsedProp ?? leftCollapsedState;
|
|
@@ -3268,10 +3407,10 @@ function FullscreenWorkspace({
|
|
|
3268
3407
|
const isDisplayModeControlled = displayMode !== void 0;
|
|
3269
3408
|
const currentDisplayMode = isDisplayModeControlled ? displayMode : internalDisplayMode;
|
|
3270
3409
|
const isTabControlled = activeTab !== void 0 && activeTab !== null;
|
|
3271
|
-
const resolvedTabs =
|
|
3410
|
+
const resolvedTabs = React8.useMemo(() => tabs ?? [], [tabs]);
|
|
3272
3411
|
const defaultTabValue = resolvedTabs.length > 0 ? resolvedTabs[0].value : "";
|
|
3273
3412
|
const currentTab = isTabControlled ? activeTab : internalTab || defaultTabValue;
|
|
3274
|
-
|
|
3413
|
+
React8.useEffect(() => {
|
|
3275
3414
|
if (resolvedTabs.length > 0) {
|
|
3276
3415
|
const values = resolvedTabs.map((tab) => tab.value);
|
|
3277
3416
|
if (!values.includes(currentTab)) {
|
|
@@ -3280,7 +3419,7 @@ function FullscreenWorkspace({
|
|
|
3280
3419
|
}
|
|
3281
3420
|
}
|
|
3282
3421
|
}, [resolvedTabs, activeTab, currentTab, defaultTabValue]);
|
|
3283
|
-
|
|
3422
|
+
React8.useEffect(() => {
|
|
3284
3423
|
if (displayMode !== void 0) {
|
|
3285
3424
|
setInternalDisplayMode(displayMode);
|
|
3286
3425
|
}
|
|
@@ -3315,7 +3454,7 @@ function FullscreenWorkspace({
|
|
|
3315
3454
|
const currentTabContent = resolvedTabs.find((tab) => tab.value === currentTab)?.content ?? null;
|
|
3316
3455
|
const showLeftToggle = Boolean(leftPanel);
|
|
3317
3456
|
const showRightToggle = Boolean(rightPanel);
|
|
3318
|
-
return /* @__PURE__ */
|
|
3457
|
+
return /* @__PURE__ */ jsxs11(
|
|
3319
3458
|
FullscreenContainer,
|
|
3320
3459
|
{
|
|
3321
3460
|
leftCollapsed,
|
|
@@ -3323,25 +3462,25 @@ function FullscreenWorkspace({
|
|
|
3323
3462
|
className: `tff-svg-container ${className}`.trim(),
|
|
3324
3463
|
...rest,
|
|
3325
3464
|
children: [
|
|
3326
|
-
showLeftToggle && /* @__PURE__ */
|
|
3465
|
+
showLeftToggle && /* @__PURE__ */ jsx14(
|
|
3327
3466
|
LeftToggleButton,
|
|
3328
3467
|
{
|
|
3329
3468
|
collapsed: leftCollapsed,
|
|
3330
3469
|
onClick: handleLeftToggle,
|
|
3331
3470
|
"aria-label": leftCollapsed ? "Expand left panel" : "Collapse left panel",
|
|
3332
|
-
children: leftCollapsed ? /* @__PURE__ */
|
|
3471
|
+
children: leftCollapsed ? /* @__PURE__ */ jsx14(ChevronRight, {}) : /* @__PURE__ */ jsx14(ChevronLeft, {})
|
|
3333
3472
|
}
|
|
3334
3473
|
),
|
|
3335
|
-
showRightToggle && /* @__PURE__ */
|
|
3474
|
+
showRightToggle && /* @__PURE__ */ jsx14(
|
|
3336
3475
|
RightToggleButton,
|
|
3337
3476
|
{
|
|
3338
3477
|
collapsed: rightCollapsed,
|
|
3339
3478
|
onClick: handleRightToggle,
|
|
3340
3479
|
"aria-label": rightCollapsed ? "Expand right panel" : "Collapse right panel",
|
|
3341
|
-
children: rightCollapsed ? /* @__PURE__ */
|
|
3480
|
+
children: rightCollapsed ? /* @__PURE__ */ jsx14(ChevronLeft, {}) : /* @__PURE__ */ jsx14(ChevronRight, {})
|
|
3342
3481
|
}
|
|
3343
3482
|
),
|
|
3344
|
-
showDisplayModeToggle && /* @__PURE__ */
|
|
3483
|
+
showDisplayModeToggle && /* @__PURE__ */ jsx14(
|
|
3345
3484
|
DisplayModeToggle,
|
|
3346
3485
|
{
|
|
3347
3486
|
mode: currentDisplayMode,
|
|
@@ -3350,9 +3489,9 @@ function FullscreenWorkspace({
|
|
|
3350
3489
|
children: currentDisplayMode === "dashboard" ? "Dashboard Mode" : "Standard Mode"
|
|
3351
3490
|
}
|
|
3352
3491
|
),
|
|
3353
|
-
/* @__PURE__ */
|
|
3354
|
-
showZoomControls && /* @__PURE__ */
|
|
3355
|
-
/* @__PURE__ */
|
|
3492
|
+
/* @__PURE__ */ jsxs11(SVGArea, { children: [
|
|
3493
|
+
showZoomControls && /* @__PURE__ */ jsxs11(ZoomControls, { children: [
|
|
3494
|
+
/* @__PURE__ */ jsx14(
|
|
3356
3495
|
ZoomButton,
|
|
3357
3496
|
{
|
|
3358
3497
|
onClick: onZoomIn,
|
|
@@ -3362,7 +3501,7 @@ function FullscreenWorkspace({
|
|
|
3362
3501
|
children: "+"
|
|
3363
3502
|
}
|
|
3364
3503
|
),
|
|
3365
|
-
/* @__PURE__ */
|
|
3504
|
+
/* @__PURE__ */ jsx14(
|
|
3366
3505
|
ZoomButton,
|
|
3367
3506
|
{
|
|
3368
3507
|
onClick: onZoomOut,
|
|
@@ -3372,7 +3511,7 @@ function FullscreenWorkspace({
|
|
|
3372
3511
|
children: "-"
|
|
3373
3512
|
}
|
|
3374
3513
|
),
|
|
3375
|
-
onResetZoom && /* @__PURE__ */
|
|
3514
|
+
onResetZoom && /* @__PURE__ */ jsx14(
|
|
3376
3515
|
ZoomButton,
|
|
3377
3516
|
{
|
|
3378
3517
|
onClick: onResetZoom,
|
|
@@ -3383,25 +3522,25 @@ function FullscreenWorkspace({
|
|
|
3383
3522
|
}
|
|
3384
3523
|
)
|
|
3385
3524
|
] }),
|
|
3386
|
-
/* @__PURE__ */
|
|
3525
|
+
/* @__PURE__ */ jsx14(ScrollableSVGWrapper, { className: "svg-scroll-wrapper", children: /* @__PURE__ */ jsxs11(FixedSVGContainer, { className: "svg-container", children: [
|
|
3387
3526
|
svgContent,
|
|
3388
3527
|
overlays
|
|
3389
3528
|
] }) })
|
|
3390
3529
|
] }),
|
|
3391
|
-
/* @__PURE__ */
|
|
3392
|
-
/* @__PURE__ */
|
|
3530
|
+
/* @__PURE__ */ jsx14(LeftPanel, { collapsed: leftCollapsed, children: resolvedTabs.length > 0 ? /* @__PURE__ */ jsxs11(Fragment4, { children: [
|
|
3531
|
+
/* @__PURE__ */ jsx14(
|
|
3393
3532
|
PanelTabs,
|
|
3394
3533
|
{
|
|
3395
3534
|
value: currentTab,
|
|
3396
3535
|
onChange: handleTabChangeInternal,
|
|
3397
3536
|
"aria-label": "Left panel tabs",
|
|
3398
|
-
children: resolvedTabs.map((tab) => /* @__PURE__ */
|
|
3537
|
+
children: resolvedTabs.map((tab) => /* @__PURE__ */ jsx14(Tab, { label: tab.label, value: tab.value }, tab.value))
|
|
3399
3538
|
}
|
|
3400
3539
|
),
|
|
3401
|
-
/* @__PURE__ */
|
|
3540
|
+
/* @__PURE__ */ jsx14(PanelContent, { children: currentTabContent })
|
|
3402
3541
|
] }) : leftPanel }),
|
|
3403
|
-
/* @__PURE__ */
|
|
3404
|
-
/* @__PURE__ */
|
|
3542
|
+
/* @__PURE__ */ jsx14(RightPanel, { collapsed: rightCollapsed, children: rightPanel }),
|
|
3543
|
+
/* @__PURE__ */ jsx14(FooterPanel, { children: footer })
|
|
3405
3544
|
]
|
|
3406
3545
|
}
|
|
3407
3546
|
);
|
|
@@ -3409,7 +3548,7 @@ function FullscreenWorkspace({
|
|
|
3409
3548
|
|
|
3410
3549
|
// src/theme/ThemeContext.tsx
|
|
3411
3550
|
import { createContext, useContext, useState as useState8, useEffect as useEffect5 } from "react";
|
|
3412
|
-
import { jsx as
|
|
3551
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
3413
3552
|
var ThemeContext = createContext(void 0);
|
|
3414
3553
|
var useTheme = () => {
|
|
3415
3554
|
const context = useContext(ThemeContext);
|
|
@@ -3432,11 +3571,11 @@ var ThemeProvider = ({ children }) => {
|
|
|
3432
3571
|
const setTheme = (newTheme) => {
|
|
3433
3572
|
setThemeState(newTheme);
|
|
3434
3573
|
};
|
|
3435
|
-
return /* @__PURE__ */
|
|
3574
|
+
return /* @__PURE__ */ jsx15(ThemeContext.Provider, { value: { theme, toggleTheme, setTheme }, children });
|
|
3436
3575
|
};
|
|
3437
3576
|
|
|
3438
3577
|
// src/theme/ThemeToggle.tsx
|
|
3439
|
-
import { jsx as
|
|
3578
|
+
import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
3440
3579
|
var ThemeToggle = ({
|
|
3441
3580
|
size = "medium",
|
|
3442
3581
|
position = "top-right",
|
|
@@ -3507,18 +3646,18 @@ var ThemeToggle = ({
|
|
|
3507
3646
|
transition: "all 0.2s ease",
|
|
3508
3647
|
boxShadow: "0 2px 4px rgba(0, 0, 0, 0.2)"
|
|
3509
3648
|
};
|
|
3510
|
-
return /* @__PURE__ */
|
|
3511
|
-
/* @__PURE__ */
|
|
3512
|
-
/* @__PURE__ */
|
|
3513
|
-
/* @__PURE__ */
|
|
3649
|
+
return /* @__PURE__ */ jsxs12("div", { style: currentStyle, onClick: toggleTheme, className, ...props, children: [
|
|
3650
|
+
/* @__PURE__ */ jsx16("span", { children: theme === "modern" ? "\u{1F3A8} Modern" : "\u{1F3ED} HMI" }),
|
|
3651
|
+
/* @__PURE__ */ jsx16("div", { style: toggleStyle, children: /* @__PURE__ */ jsx16("div", { style: thumbStyle }) }),
|
|
3652
|
+
/* @__PURE__ */ jsx16("span", { style: { fontSize: "0.75rem", opacity: 0.8 }, children: theme === "modern" ? "Industrial Design" : "High Performance" })
|
|
3514
3653
|
] });
|
|
3515
3654
|
};
|
|
3516
3655
|
|
|
3517
3656
|
// src/components/PIDCanvas/PIDCanvas.tsx
|
|
3518
|
-
import
|
|
3657
|
+
import React14, { useCallback as useCallback8, useState as useState14, useEffect as useEffect13, useRef as useRef6 } from "react";
|
|
3519
3658
|
|
|
3520
3659
|
// src/components/PIDCanvas/NodeRenderer.tsx
|
|
3521
|
-
import
|
|
3660
|
+
import React10 from "react";
|
|
3522
3661
|
|
|
3523
3662
|
// src/diagram/symbols/mockSymbolLibrary.ts
|
|
3524
3663
|
var mockSymbolLibrary = {
|
|
@@ -3546,6 +3685,25 @@ var mockSymbolLibrary = {
|
|
|
3546
3685
|
tags: ["valve", "gate", "powered", "actuator"]
|
|
3547
3686
|
}
|
|
3548
3687
|
},
|
|
3688
|
+
"status-indicator": {
|
|
3689
|
+
id: "status-indicator",
|
|
3690
|
+
name: "Status LED",
|
|
3691
|
+
category: "instrument",
|
|
3692
|
+
viewBox: { x: 0, y: 0, width: 24, height: 24 },
|
|
3693
|
+
ports: [],
|
|
3694
|
+
svgContent: `
|
|
3695
|
+
<rect x="2" y="2" width="20" height="20"
|
|
3696
|
+
rx="var(--led-rx, 50%)"
|
|
3697
|
+
fill="var(--symbol-fill, #64748b)"
|
|
3698
|
+
stroke="rgba(255,255,255,0.4)"
|
|
3699
|
+
stroke-width="var(--led-bezel, 0)"
|
|
3700
|
+
style="transform-box: fill-box; transform: rotate(var(--led-rotate, 0deg)); transform-origin: center; pointer-events: all;"/>
|
|
3701
|
+
`,
|
|
3702
|
+
metadata: {
|
|
3703
|
+
description: "Status LED indicator driven by telemetry status color",
|
|
3704
|
+
tags: ["status", "led", "indicator", "instrument"]
|
|
3705
|
+
}
|
|
3706
|
+
},
|
|
3549
3707
|
"pump-positive-displacement": {
|
|
3550
3708
|
id: "pump-positive-displacement",
|
|
3551
3709
|
name: "Positive Displacement Pump",
|
|
@@ -4738,8 +4896,150 @@ function getAvailableSymbols() {
|
|
|
4738
4896
|
return [...Object.keys(customSymbols), ...Object.keys(mockSymbolLibrary)];
|
|
4739
4897
|
}
|
|
4740
4898
|
|
|
4899
|
+
// src/diagram/symbols/appearanceSchema.ts
|
|
4900
|
+
var COLOR_PRESETS = {
|
|
4901
|
+
green: "#22c55e",
|
|
4902
|
+
red: "#ef4444",
|
|
4903
|
+
amber: "#f59e0b",
|
|
4904
|
+
blue: "#3b82f6",
|
|
4905
|
+
grey: "#64748b"
|
|
4906
|
+
};
|
|
4907
|
+
function resolvePresetColor(name) {
|
|
4908
|
+
return name && COLOR_PRESETS[name] || COLOR_PRESETS.grey;
|
|
4909
|
+
}
|
|
4910
|
+
var COLOR_OPTIONS = Object.keys(COLOR_PRESETS);
|
|
4911
|
+
var STATUS_LED_APPEARANCE = [
|
|
4912
|
+
{
|
|
4913
|
+
key: "shape",
|
|
4914
|
+
kind: "select",
|
|
4915
|
+
label: "Shape",
|
|
4916
|
+
options: ["circle", "square", "diamond"],
|
|
4917
|
+
default: "circle"
|
|
4918
|
+
},
|
|
4919
|
+
{
|
|
4920
|
+
key: "size",
|
|
4921
|
+
kind: "select",
|
|
4922
|
+
label: "Size",
|
|
4923
|
+
target: "scale",
|
|
4924
|
+
options: ["small", "medium", "large"],
|
|
4925
|
+
default: "medium",
|
|
4926
|
+
valueMap: { small: 0.75, medium: 1, large: 1.5 }
|
|
4927
|
+
},
|
|
4928
|
+
{ key: "led", kind: "boolean", label: "Bezel ring", default: true },
|
|
4929
|
+
{ key: "glow", kind: "boolean", label: "Diffusion (glow)", default: false },
|
|
4930
|
+
{
|
|
4931
|
+
key: "animation",
|
|
4932
|
+
kind: "select",
|
|
4933
|
+
label: "Animation",
|
|
4934
|
+
options: ["none", "pulse", "blink"],
|
|
4935
|
+
default: "none"
|
|
4936
|
+
},
|
|
4937
|
+
{
|
|
4938
|
+
key: "labelPosition",
|
|
4939
|
+
kind: "select",
|
|
4940
|
+
label: "Label position",
|
|
4941
|
+
options: ["bottom", "top", "left", "right"],
|
|
4942
|
+
default: "bottom"
|
|
4943
|
+
},
|
|
4944
|
+
// Color binding: a named signal drives the on/off color.
|
|
4945
|
+
{
|
|
4946
|
+
key: "colorSource",
|
|
4947
|
+
kind: "tag",
|
|
4948
|
+
label: "Color source (tag)",
|
|
4949
|
+
default: "",
|
|
4950
|
+
help: "Signal/tag that drives color. True (non-zero) shows On color; false shows Off color. Blank = unbound (grey)."
|
|
4951
|
+
},
|
|
4952
|
+
{
|
|
4953
|
+
key: "onColor",
|
|
4954
|
+
kind: "select",
|
|
4955
|
+
label: "On color (true)",
|
|
4956
|
+
options: COLOR_OPTIONS,
|
|
4957
|
+
default: "green",
|
|
4958
|
+
help: "Color when the Color source is true."
|
|
4959
|
+
},
|
|
4960
|
+
{
|
|
4961
|
+
key: "offColor",
|
|
4962
|
+
kind: "select",
|
|
4963
|
+
label: "Off color (false)",
|
|
4964
|
+
options: COLOR_OPTIONS,
|
|
4965
|
+
default: "red",
|
|
4966
|
+
help: "Color when the Color source is false."
|
|
4967
|
+
},
|
|
4968
|
+
// Visibility binding: an independent named signal drives show/hide.
|
|
4969
|
+
{
|
|
4970
|
+
key: "visibleSource",
|
|
4971
|
+
kind: "tag",
|
|
4972
|
+
label: "Visibility source (tag)",
|
|
4973
|
+
default: "",
|
|
4974
|
+
help: "Signal/tag that drives visibility. True shows the LED, false hides it. Blank = always visible (use the Visible checkbox)."
|
|
4975
|
+
},
|
|
4976
|
+
{
|
|
4977
|
+
key: "visible",
|
|
4978
|
+
kind: "boolean",
|
|
4979
|
+
label: "Visible",
|
|
4980
|
+
target: "visible",
|
|
4981
|
+
default: true,
|
|
4982
|
+
help: "Static show/hide, used only when no Visibility source is set."
|
|
4983
|
+
}
|
|
4984
|
+
];
|
|
4985
|
+
var APPEARANCE_REGISTRY = {
|
|
4986
|
+
"status-indicator": STATUS_LED_APPEARANCE
|
|
4987
|
+
};
|
|
4988
|
+
function getAppearanceSchema(symbolId) {
|
|
4989
|
+
return APPEARANCE_REGISTRY[symbolId] ?? [];
|
|
4990
|
+
}
|
|
4991
|
+
function getAppearanceDefaults(symbolId) {
|
|
4992
|
+
const out = {};
|
|
4993
|
+
for (const field of getAppearanceSchema(symbolId)) {
|
|
4994
|
+
if ((field.target ?? "metadata") === "metadata" && field.default !== void 0) {
|
|
4995
|
+
out[field.key] = field.default;
|
|
4996
|
+
}
|
|
4997
|
+
}
|
|
4998
|
+
return out;
|
|
4999
|
+
}
|
|
5000
|
+
function readAppearanceValue(node, field) {
|
|
5001
|
+
if (field.target === "visible") {
|
|
5002
|
+
return node.visible ?? field.default ?? true;
|
|
5003
|
+
}
|
|
5004
|
+
if (field.target === "scale") {
|
|
5005
|
+
const scale = node.transform.scale ?? 1;
|
|
5006
|
+
if (field.valueMap) {
|
|
5007
|
+
let bestOption = field.options?.[0] ?? String(scale);
|
|
5008
|
+
let bestDiff = Infinity;
|
|
5009
|
+
for (const [option, value2] of Object.entries(field.valueMap)) {
|
|
5010
|
+
const diff = Math.abs(value2 - scale);
|
|
5011
|
+
if (diff < bestDiff) {
|
|
5012
|
+
bestDiff = diff;
|
|
5013
|
+
bestOption = option;
|
|
5014
|
+
}
|
|
5015
|
+
}
|
|
5016
|
+
return bestOption;
|
|
5017
|
+
}
|
|
5018
|
+
return scale;
|
|
5019
|
+
}
|
|
5020
|
+
const value = node.metadata?.[field.key];
|
|
5021
|
+
return value ?? field.default;
|
|
5022
|
+
}
|
|
5023
|
+
function writeAppearanceValue(node, field, value) {
|
|
5024
|
+
if (field.target === "visible") {
|
|
5025
|
+
return { visible: Boolean(value) };
|
|
5026
|
+
}
|
|
5027
|
+
if (field.target === "scale") {
|
|
5028
|
+
const scale = field.valueMap ? field.valueMap[String(value)] ?? 1 : Number(value);
|
|
5029
|
+
return { transform: { ...node.transform, scale } };
|
|
5030
|
+
}
|
|
5031
|
+
return { metadata: { ...node.metadata, [field.key]: value } };
|
|
5032
|
+
}
|
|
5033
|
+
|
|
4741
5034
|
// src/components/PIDCanvas/NodeRenderer.tsx
|
|
4742
|
-
import { jsx as
|
|
5035
|
+
import { jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
5036
|
+
var HATCH_TILE_SIZE = 7;
|
|
5037
|
+
var HATCH_STRIPE_WIDTH = 2;
|
|
5038
|
+
var HATCH_STRIPE_ANGLE = 135;
|
|
5039
|
+
var HATCH_STRIPE_OPACITY = 85 / 255;
|
|
5040
|
+
function isUnknownNode(node) {
|
|
5041
|
+
return node.positionUnknown === true || normalizeDeviceStatus(node.status) === "unknown";
|
|
5042
|
+
}
|
|
4743
5043
|
function NodeRendererImpl({
|
|
4744
5044
|
nodes: nodes2,
|
|
4745
5045
|
selectedNodeIds,
|
|
@@ -4751,146 +5051,214 @@ function NodeRendererImpl({
|
|
|
4751
5051
|
enableDrag = false,
|
|
4752
5052
|
statusColorMap
|
|
4753
5053
|
}) {
|
|
4754
|
-
|
|
4755
|
-
|
|
4756
|
-
|
|
4757
|
-
|
|
4758
|
-
|
|
4759
|
-
|
|
4760
|
-
|
|
4761
|
-
"circle",
|
|
4762
|
-
{
|
|
4763
|
-
cx: node.transform.x,
|
|
4764
|
-
cy: node.transform.y,
|
|
4765
|
-
r: "15",
|
|
4766
|
-
fill: "#ff0000",
|
|
4767
|
-
opacity: "0.3",
|
|
4768
|
-
stroke: "#ff0000",
|
|
4769
|
-
strokeWidth: "2"
|
|
4770
|
-
}
|
|
4771
|
-
),
|
|
4772
|
-
/* @__PURE__ */ jsx16(
|
|
4773
|
-
"text",
|
|
4774
|
-
{
|
|
4775
|
-
x: node.transform.x,
|
|
4776
|
-
y: node.transform.y,
|
|
4777
|
-
textAnchor: "middle",
|
|
4778
|
-
dominantBaseline: "middle",
|
|
4779
|
-
fontSize: "10",
|
|
4780
|
-
fill: "#ff0000",
|
|
4781
|
-
children: "?"
|
|
4782
|
-
}
|
|
4783
|
-
)
|
|
4784
|
-
] }, node.id);
|
|
4785
|
-
}
|
|
4786
|
-
const transforms = [];
|
|
4787
|
-
const effectiveX = isDragging ? node.transform.x + dragOffset.x : node.transform.x;
|
|
4788
|
-
const effectiveY = isDragging ? node.transform.y + dragOffset.y : node.transform.y;
|
|
4789
|
-
transforms.push(`translate(${effectiveX}, ${effectiveY})`);
|
|
4790
|
-
if (node.transform.rotation) {
|
|
4791
|
-
const centerX = symbol.viewBox.width / 2;
|
|
4792
|
-
const centerY = symbol.viewBox.height / 2;
|
|
4793
|
-
transforms.push(`rotate(${node.transform.rotation}, ${centerX}, ${centerY})`);
|
|
4794
|
-
}
|
|
4795
|
-
if (node.transform.scale && node.transform.scale !== 1) {
|
|
4796
|
-
const centerX = symbol.viewBox.width / 2;
|
|
4797
|
-
const centerY = symbol.viewBox.height / 2;
|
|
4798
|
-
transforms.push(
|
|
4799
|
-
`translate(${centerX}, ${centerY}) scale(${node.transform.scale}) translate(${-centerX}, ${-centerY})`
|
|
4800
|
-
);
|
|
4801
|
-
}
|
|
4802
|
-
if (node.transform.flipX || node.transform.flipY) {
|
|
4803
|
-
const scaleX = node.transform.flipX ? -1 : 1;
|
|
4804
|
-
const scaleY = node.transform.flipY ? -1 : 1;
|
|
4805
|
-
const centerX = symbol.viewBox.width / 2;
|
|
4806
|
-
const centerY = symbol.viewBox.height / 2;
|
|
4807
|
-
transforms.push(
|
|
4808
|
-
`translate(${centerX}, ${centerY}) scale(${scaleX}, ${scaleY}) translate(${-centerX}, ${-centerY})`
|
|
4809
|
-
);
|
|
4810
|
-
}
|
|
4811
|
-
const statusEntry = resolveStatusColor(node.status, statusColorMap);
|
|
4812
|
-
const fillColor = node.customColors?.fill ?? statusEntry.fill;
|
|
4813
|
-
const strokeColor = node.customColors?.stroke ?? statusEntry.stroke;
|
|
4814
|
-
return /* @__PURE__ */ jsxs12(
|
|
4815
|
-
"g",
|
|
5054
|
+
const hatchPatternId = `node-unknown-hatch-${React10.useId().replace(/[^a-zA-Z0-9_-]/g, "")}`;
|
|
5055
|
+
const visibleNodes = nodes2.filter((node) => node.visible !== false);
|
|
5056
|
+
const hasUnknownNode = visibleNodes.some(isUnknownNode);
|
|
5057
|
+
const unknownEntry = resolveStatusColor("unknown", statusColorMap);
|
|
5058
|
+
return /* @__PURE__ */ jsxs13("g", { id: "layer-nodes", children: [
|
|
5059
|
+
hasUnknownNode && /* @__PURE__ */ jsx17("defs", { children: /* @__PURE__ */ jsxs13(
|
|
5060
|
+
"pattern",
|
|
4816
5061
|
{
|
|
4817
|
-
|
|
4818
|
-
"data-
|
|
4819
|
-
"
|
|
4820
|
-
|
|
4821
|
-
|
|
4822
|
-
|
|
4823
|
-
"--symbol-fill": fillColor,
|
|
4824
|
-
"--symbol-stroke": strokeColor,
|
|
4825
|
-
cursor: enableDrag ? isDragging ? "grabbing" : "grab" : onNodeClick ? "pointer" : "default"
|
|
4826
|
-
},
|
|
4827
|
-
onClick: (e) => {
|
|
4828
|
-
e.stopPropagation();
|
|
4829
|
-
onNodeClick?.(node.id, e);
|
|
4830
|
-
},
|
|
4831
|
-
onDoubleClick: (e) => {
|
|
4832
|
-
e.stopPropagation();
|
|
4833
|
-
onNodeDoubleClick?.(node.id, e);
|
|
4834
|
-
},
|
|
4835
|
-
onMouseDown: (e) => {
|
|
4836
|
-
if (enableDrag) {
|
|
4837
|
-
onNodeDragStart?.(node.id, e);
|
|
4838
|
-
}
|
|
4839
|
-
},
|
|
4840
|
-
onTouchStart: (e) => {
|
|
4841
|
-
if (enableDrag) {
|
|
4842
|
-
e.stopPropagation();
|
|
4843
|
-
onNodeDragStart?.(node.id, e);
|
|
4844
|
-
}
|
|
4845
|
-
},
|
|
5062
|
+
id: hatchPatternId,
|
|
5063
|
+
"data-testid": "unknown-hatch-pattern",
|
|
5064
|
+
patternUnits: "userSpaceOnUse",
|
|
5065
|
+
width: HATCH_TILE_SIZE,
|
|
5066
|
+
height: HATCH_TILE_SIZE,
|
|
5067
|
+
patternTransform: `rotate(${HATCH_STRIPE_ANGLE})`,
|
|
4846
5068
|
children: [
|
|
4847
|
-
|
|
5069
|
+
/* @__PURE__ */ jsx17("rect", { width: HATCH_TILE_SIZE, height: HATCH_TILE_SIZE, fill: unknownEntry.fill }),
|
|
5070
|
+
/* @__PURE__ */ jsx17(
|
|
4848
5071
|
"rect",
|
|
4849
5072
|
{
|
|
4850
|
-
x:
|
|
4851
|
-
|
|
4852
|
-
|
|
4853
|
-
|
|
4854
|
-
|
|
4855
|
-
stroke: isDragging ? "#10b981" : "#3b82f6",
|
|
4856
|
-
strokeWidth: isDragging ? "3" : "2",
|
|
4857
|
-
strokeDasharray: "4 2",
|
|
4858
|
-
rx: "2",
|
|
4859
|
-
pointerEvents: "none"
|
|
5073
|
+
x: HATCH_TILE_SIZE - HATCH_STRIPE_WIDTH,
|
|
5074
|
+
width: HATCH_STRIPE_WIDTH,
|
|
5075
|
+
height: HATCH_TILE_SIZE,
|
|
5076
|
+
fill: unknownEntry.stroke,
|
|
5077
|
+
fillOpacity: HATCH_STRIPE_OPACITY
|
|
4860
5078
|
}
|
|
4861
|
-
)
|
|
4862
|
-
|
|
4863
|
-
|
|
5079
|
+
)
|
|
5080
|
+
]
|
|
5081
|
+
}
|
|
5082
|
+
) }),
|
|
5083
|
+
visibleNodes.map((node) => {
|
|
5084
|
+
const symbol = getSymbolDefinition(node.symbolId);
|
|
5085
|
+
const isSelected = selectedNodeIds?.has(node.id) ?? false;
|
|
5086
|
+
const isDragging = draggingNodeId === node.id;
|
|
5087
|
+
if (!symbol) {
|
|
5088
|
+
return /* @__PURE__ */ jsxs13("g", { children: [
|
|
5089
|
+
/* @__PURE__ */ jsx17(
|
|
5090
|
+
"circle",
|
|
4864
5091
|
{
|
|
4865
|
-
|
|
4866
|
-
|
|
4867
|
-
|
|
5092
|
+
cx: node.transform.x,
|
|
5093
|
+
cy: node.transform.y,
|
|
5094
|
+
r: "15",
|
|
5095
|
+
fill: "#ff0000",
|
|
5096
|
+
opacity: "0.3",
|
|
5097
|
+
stroke: "#ff0000",
|
|
5098
|
+
strokeWidth: "2"
|
|
4868
5099
|
}
|
|
4869
5100
|
),
|
|
4870
|
-
/* @__PURE__ */
|
|
5101
|
+
/* @__PURE__ */ jsx17(
|
|
4871
5102
|
"text",
|
|
4872
5103
|
{
|
|
4873
|
-
x:
|
|
4874
|
-
y:
|
|
5104
|
+
x: node.transform.x,
|
|
5105
|
+
y: node.transform.y,
|
|
4875
5106
|
textAnchor: "middle",
|
|
4876
|
-
|
|
4877
|
-
|
|
4878
|
-
fill:
|
|
4879
|
-
|
|
4880
|
-
children: node.label || node.id
|
|
5107
|
+
dominantBaseline: "middle",
|
|
5108
|
+
fontSize: "10",
|
|
5109
|
+
fill: "#ff0000",
|
|
5110
|
+
children: "?"
|
|
4881
5111
|
}
|
|
4882
5112
|
)
|
|
4883
|
-
]
|
|
4884
|
-
}
|
|
4885
|
-
|
|
4886
|
-
|
|
4887
|
-
|
|
5113
|
+
] }, node.id);
|
|
5114
|
+
}
|
|
5115
|
+
const transforms = [];
|
|
5116
|
+
const effectiveX = isDragging ? node.transform.x + dragOffset.x : node.transform.x;
|
|
5117
|
+
const effectiveY = isDragging ? node.transform.y + dragOffset.y : node.transform.y;
|
|
5118
|
+
transforms.push(`translate(${effectiveX}, ${effectiveY})`);
|
|
5119
|
+
if (node.transform.rotation) {
|
|
5120
|
+
const centerX = symbol.viewBox.width / 2;
|
|
5121
|
+
const centerY = symbol.viewBox.height / 2;
|
|
5122
|
+
transforms.push(`rotate(${node.transform.rotation}, ${centerX}, ${centerY})`);
|
|
5123
|
+
}
|
|
5124
|
+
if (node.transform.scale && node.transform.scale !== 1) {
|
|
5125
|
+
const centerX = symbol.viewBox.width / 2;
|
|
5126
|
+
const centerY = symbol.viewBox.height / 2;
|
|
5127
|
+
transforms.push(
|
|
5128
|
+
`translate(${centerX}, ${centerY}) scale(${node.transform.scale}) translate(${-centerX}, ${-centerY})`
|
|
5129
|
+
);
|
|
5130
|
+
}
|
|
5131
|
+
if (node.transform.flipX || node.transform.flipY) {
|
|
5132
|
+
const scaleX = node.transform.flipX ? -1 : 1;
|
|
5133
|
+
const scaleY = node.transform.flipY ? -1 : 1;
|
|
5134
|
+
const centerX = symbol.viewBox.width / 2;
|
|
5135
|
+
const centerY = symbol.viewBox.height / 2;
|
|
5136
|
+
transforms.push(
|
|
5137
|
+
`translate(${centerX}, ${centerY}) scale(${scaleX}, ${scaleY}) translate(${-centerX}, ${-centerY})`
|
|
5138
|
+
);
|
|
5139
|
+
}
|
|
5140
|
+
const statusEntry = resolveStatusColor(node.status, statusColorMap);
|
|
5141
|
+
const isUnknown = isUnknownNode(node);
|
|
5142
|
+
const fillColor = isUnknown ? `url(#${hatchPatternId})` : node.customColors?.fill ?? statusEntry.fill;
|
|
5143
|
+
const strokeColor = isUnknown ? unknownEntry.stroke : node.customColors?.stroke ?? statusEntry.stroke;
|
|
5144
|
+
const appearance = { ...getAppearanceDefaults(node.symbolId), ...node.metadata ?? {} };
|
|
5145
|
+
const ledStyle = {};
|
|
5146
|
+
if (appearance.shape !== void 0) {
|
|
5147
|
+
ledStyle["--led-rx"] = appearance.shape === "circle" ? "50%" : "2";
|
|
5148
|
+
ledStyle["--led-rotate"] = appearance.shape === "diamond" ? "45deg" : "0deg";
|
|
5149
|
+
}
|
|
5150
|
+
if (appearance.led !== void 0) {
|
|
5151
|
+
ledStyle["--led-bezel"] = appearance.led ? "2" : "0";
|
|
5152
|
+
}
|
|
5153
|
+
if (appearance.glow) {
|
|
5154
|
+
const glowColor = isUnknown ? unknownEntry.stroke : fillColor;
|
|
5155
|
+
ledStyle.filter = `drop-shadow(0 0 4px ${glowColor})`;
|
|
5156
|
+
}
|
|
5157
|
+
const ledAnimation = typeof appearance.animation === "string" && appearance.animation !== "none" ? appearance.animation : void 0;
|
|
5158
|
+
const vb = symbol.viewBox;
|
|
5159
|
+
const ox = node.labelOffset?.x ?? 0;
|
|
5160
|
+
const oy = node.labelOffset?.y ?? 0;
|
|
5161
|
+
const labelPos = typeof appearance.labelPosition === "string" ? appearance.labelPosition : "bottom";
|
|
5162
|
+
let labelX = vb.width / 2 + ox;
|
|
5163
|
+
let labelY = vb.height + 12 + oy;
|
|
5164
|
+
let labelAnchor = "middle";
|
|
5165
|
+
if (labelPos === "top") {
|
|
5166
|
+
labelX = vb.width / 2 + ox;
|
|
5167
|
+
labelY = -6 + oy;
|
|
5168
|
+
labelAnchor = "middle";
|
|
5169
|
+
} else if (labelPos === "left") {
|
|
5170
|
+
labelX = -6 + ox;
|
|
5171
|
+
labelY = vb.height / 2 + oy;
|
|
5172
|
+
labelAnchor = "end";
|
|
5173
|
+
} else if (labelPos === "right") {
|
|
5174
|
+
labelX = vb.width + 6 + ox;
|
|
5175
|
+
labelY = vb.height / 2 + oy;
|
|
5176
|
+
labelAnchor = "start";
|
|
5177
|
+
}
|
|
5178
|
+
return /* @__PURE__ */ jsxs13(
|
|
5179
|
+
"g",
|
|
5180
|
+
{
|
|
5181
|
+
"data-node-id": node.id,
|
|
5182
|
+
"data-symbol-id": node.symbolId,
|
|
5183
|
+
"data-selected": isSelected,
|
|
5184
|
+
"data-dragging": isDragging,
|
|
5185
|
+
"data-led-animation": ledAnimation,
|
|
5186
|
+
"data-position-unknown": node.positionUnknown === true ? "true" : void 0,
|
|
5187
|
+
transform: transforms.join(" "),
|
|
5188
|
+
style: {
|
|
5189
|
+
"--symbol-fill": fillColor,
|
|
5190
|
+
"--symbol-stroke": strokeColor,
|
|
5191
|
+
cursor: enableDrag ? isDragging ? "grabbing" : "grab" : onNodeClick ? "pointer" : "default",
|
|
5192
|
+
...ledStyle
|
|
5193
|
+
},
|
|
5194
|
+
onClick: (e) => {
|
|
5195
|
+
e.stopPropagation();
|
|
5196
|
+
onNodeClick?.(node.id, e);
|
|
5197
|
+
},
|
|
5198
|
+
onDoubleClick: (e) => {
|
|
5199
|
+
e.stopPropagation();
|
|
5200
|
+
onNodeDoubleClick?.(node.id, e);
|
|
5201
|
+
},
|
|
5202
|
+
onMouseDown: (e) => {
|
|
5203
|
+
if (enableDrag) {
|
|
5204
|
+
onNodeDragStart?.(node.id, e);
|
|
5205
|
+
}
|
|
5206
|
+
},
|
|
5207
|
+
onTouchStart: (e) => {
|
|
5208
|
+
if (enableDrag) {
|
|
5209
|
+
e.stopPropagation();
|
|
5210
|
+
onNodeDragStart?.(node.id, e);
|
|
5211
|
+
}
|
|
5212
|
+
},
|
|
5213
|
+
children: [
|
|
5214
|
+
isSelected && /* @__PURE__ */ jsx17(
|
|
5215
|
+
"rect",
|
|
5216
|
+
{
|
|
5217
|
+
x: "-5",
|
|
5218
|
+
y: "-5",
|
|
5219
|
+
width: symbol.viewBox.width + 10,
|
|
5220
|
+
height: symbol.viewBox.height + 10,
|
|
5221
|
+
fill: "none",
|
|
5222
|
+
stroke: isDragging ? "#10b981" : "#3b82f6",
|
|
5223
|
+
strokeWidth: isDragging ? "3" : "2",
|
|
5224
|
+
strokeDasharray: "4 2",
|
|
5225
|
+
rx: "2",
|
|
5226
|
+
pointerEvents: "none"
|
|
5227
|
+
}
|
|
5228
|
+
),
|
|
5229
|
+
/* @__PURE__ */ jsx17(
|
|
5230
|
+
"g",
|
|
5231
|
+
{
|
|
5232
|
+
dangerouslySetInnerHTML: { __html: symbol.svgContent },
|
|
5233
|
+
"data-symbol-content": symbol.id,
|
|
5234
|
+
style: { pointerEvents: "auto" }
|
|
5235
|
+
}
|
|
5236
|
+
),
|
|
5237
|
+
/* @__PURE__ */ jsx17(
|
|
5238
|
+
"text",
|
|
5239
|
+
{
|
|
5240
|
+
x: labelX,
|
|
5241
|
+
y: labelY,
|
|
5242
|
+
textAnchor: labelAnchor,
|
|
5243
|
+
fontSize: node.labelFontSize ?? 10,
|
|
5244
|
+
fontWeight: "600",
|
|
5245
|
+
fill: isSelected ? "#3b82f6" : "#1f2937",
|
|
5246
|
+
transform: node.transform.rotation ? `rotate(${-node.transform.rotation}, ${labelX}, ${labelY})` : void 0,
|
|
5247
|
+
children: node.label || node.id
|
|
5248
|
+
}
|
|
5249
|
+
)
|
|
5250
|
+
]
|
|
5251
|
+
},
|
|
5252
|
+
node.id
|
|
5253
|
+
);
|
|
5254
|
+
})
|
|
5255
|
+
] });
|
|
4888
5256
|
}
|
|
4889
|
-
var NodeRenderer =
|
|
5257
|
+
var NodeRenderer = React10.memo(NodeRendererImpl);
|
|
4890
5258
|
|
|
4891
5259
|
// src/components/PIDCanvas/PipeRenderer.tsx
|
|
4892
|
-
import
|
|
4893
|
-
import { Fragment as Fragment5, jsx as
|
|
5260
|
+
import React11 from "react";
|
|
5261
|
+
import { Fragment as Fragment5, jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
4894
5262
|
function PipeRendererImpl({
|
|
4895
5263
|
pipes,
|
|
4896
5264
|
selectedPipeIds,
|
|
@@ -4905,7 +5273,7 @@ function PipeRendererImpl({
|
|
|
4905
5273
|
waypointDragOffset,
|
|
4906
5274
|
onPipeSegmentClick
|
|
4907
5275
|
}) {
|
|
4908
|
-
return /* @__PURE__ */
|
|
5276
|
+
return /* @__PURE__ */ jsx18("g", { id: "layer-pipes", children: pipes.filter((pipe) => pipe.visible !== false).map((pipe) => {
|
|
4909
5277
|
const isSelected = selectedPipeIds?.has(pipe.id) ?? false;
|
|
4910
5278
|
const isEditing = enableWaypointEditing && editingPipeId === pipe.id;
|
|
4911
5279
|
const showEditingControls = enableWaypointEditing && isSelected;
|
|
@@ -4924,7 +5292,7 @@ function PipeRendererImpl({
|
|
|
4924
5292
|
const strokeWidth = isSelected ? (pipeStyle.strokeWidth || 3) + 2 : pipeStyle.strokeWidth || 3;
|
|
4925
5293
|
const strokeDasharray = pipeStyle.strokeDasharray;
|
|
4926
5294
|
const opacity = pipeStyle.opacity !== void 0 ? pipeStyle.opacity : 1;
|
|
4927
|
-
return /* @__PURE__ */
|
|
5295
|
+
return /* @__PURE__ */ jsxs14(
|
|
4928
5296
|
"g",
|
|
4929
5297
|
{
|
|
4930
5298
|
"data-pipe-id": pipe.id,
|
|
@@ -4937,8 +5305,8 @@ function PipeRendererImpl({
|
|
|
4937
5305
|
cursor: onPipeClick ? "pointer" : "default"
|
|
4938
5306
|
},
|
|
4939
5307
|
children: [
|
|
4940
|
-
!enableWaypointEditing && /* @__PURE__ */
|
|
4941
|
-
onPipeClick && /* @__PURE__ */
|
|
5308
|
+
!enableWaypointEditing && /* @__PURE__ */ jsxs14(Fragment5, { children: [
|
|
5309
|
+
onPipeClick && /* @__PURE__ */ jsx18(
|
|
4942
5310
|
"polyline",
|
|
4943
5311
|
{
|
|
4944
5312
|
points: pointsString,
|
|
@@ -4950,7 +5318,7 @@ function PipeRendererImpl({
|
|
|
4950
5318
|
pointerEvents: "stroke"
|
|
4951
5319
|
}
|
|
4952
5320
|
),
|
|
4953
|
-
/* @__PURE__ */
|
|
5321
|
+
/* @__PURE__ */ jsx18(
|
|
4954
5322
|
"polyline",
|
|
4955
5323
|
{
|
|
4956
5324
|
points: pointsString,
|
|
@@ -4974,7 +5342,7 @@ function PipeRendererImpl({
|
|
|
4974
5342
|
const waypointSize = isSelectedWaypoint ? 8 : isDragging ? 8 : showEditingControls ? 6 : isSelected ? 3 : 2;
|
|
4975
5343
|
const waypointOpacity = isSelectedWaypoint ? 1 : isDragging ? 1 : showEditingControls ? 0.9 : isSelected ? 0.8 : 0.5;
|
|
4976
5344
|
const waypointColor = isSelectedWaypoint ? "#3b82f6" : isEndpoint && showEditingControls ? "#f59e0b" : isDragging ? "#10b981" : stroke;
|
|
4977
|
-
return /* @__PURE__ */
|
|
5345
|
+
return /* @__PURE__ */ jsx18(
|
|
4978
5346
|
"circle",
|
|
4979
5347
|
{
|
|
4980
5348
|
cx: point.x,
|
|
@@ -5011,12 +5379,12 @@ function PipeRendererImpl({
|
|
|
5011
5379
|
`${pipe.id}-point-${idx}`
|
|
5012
5380
|
);
|
|
5013
5381
|
}),
|
|
5014
|
-
showEditingControls && onPipeSegmentClick && displayPoints.length >= 2 && /* @__PURE__ */
|
|
5382
|
+
showEditingControls && onPipeSegmentClick && displayPoints.length >= 2 && /* @__PURE__ */ jsx18(Fragment5, { children: displayPoints.slice(0, -1).map((point, idx) => {
|
|
5015
5383
|
const nextPoint = displayPoints[idx + 1];
|
|
5016
5384
|
const midX = (point.x + nextPoint.x) / 2;
|
|
5017
5385
|
const midY = (point.y + nextPoint.y) / 2;
|
|
5018
|
-
return /* @__PURE__ */
|
|
5019
|
-
/* @__PURE__ */
|
|
5386
|
+
return /* @__PURE__ */ jsxs14("g", { children: [
|
|
5387
|
+
/* @__PURE__ */ jsx18(
|
|
5020
5388
|
"circle",
|
|
5021
5389
|
{
|
|
5022
5390
|
cx: midX,
|
|
@@ -5032,7 +5400,7 @@ function PipeRendererImpl({
|
|
|
5032
5400
|
}
|
|
5033
5401
|
}
|
|
5034
5402
|
),
|
|
5035
|
-
/* @__PURE__ */
|
|
5403
|
+
/* @__PURE__ */ jsx18(
|
|
5036
5404
|
"circle",
|
|
5037
5405
|
{
|
|
5038
5406
|
cx: midX,
|
|
@@ -5048,7 +5416,7 @@ function PipeRendererImpl({
|
|
|
5048
5416
|
)
|
|
5049
5417
|
] }, `${pipe.id}-segment-${idx}`);
|
|
5050
5418
|
}) }),
|
|
5051
|
-
pipe.showLabel !== false && pipe.label && pipe.routePoints.length >= 2 && /* @__PURE__ */
|
|
5419
|
+
pipe.showLabel !== false && pipe.label && pipe.routePoints.length >= 2 && /* @__PURE__ */ jsx18(
|
|
5052
5420
|
"text",
|
|
5053
5421
|
{
|
|
5054
5422
|
x: pipe.routePoints[Math.floor(pipe.routePoints.length / 2)].x + (pipe.labelOffset?.x ?? 0),
|
|
@@ -5068,11 +5436,11 @@ function PipeRendererImpl({
|
|
|
5068
5436
|
);
|
|
5069
5437
|
}) });
|
|
5070
5438
|
}
|
|
5071
|
-
var PipeRenderer =
|
|
5439
|
+
var PipeRenderer = React11.memo(PipeRendererImpl);
|
|
5072
5440
|
|
|
5073
5441
|
// src/components/PIDCanvas/DataOverlay.tsx
|
|
5074
|
-
import
|
|
5075
|
-
import { Fragment as Fragment6, jsx as
|
|
5442
|
+
import React12 from "react";
|
|
5443
|
+
import { Fragment as Fragment6, jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
5076
5444
|
var PULSE_KEYFRAME_ID = "pid-data-overlay-pulse-keyframes";
|
|
5077
5445
|
var PULSE_ANIMATION = "pid-data-overlay-pulse 1.5s ease-in-out infinite";
|
|
5078
5446
|
function ensurePulseKeyframes() {
|
|
@@ -5083,9 +5451,10 @@ function ensurePulseKeyframes() {
|
|
|
5083
5451
|
style.textContent = "@keyframes pid-data-overlay-pulse{0%{opacity:.9}50%{opacity:.3}100%{opacity:.9}}";
|
|
5084
5452
|
document.head.appendChild(style);
|
|
5085
5453
|
}
|
|
5086
|
-
function renderStatusDot(cx, cy, scale, fill) {
|
|
5087
|
-
|
|
5088
|
-
|
|
5454
|
+
function renderStatusDot(cx, cy, scale, fill, status) {
|
|
5455
|
+
const isUnknown = normalizeDeviceStatus(status) === "unknown";
|
|
5456
|
+
if (!isUnknown) ensurePulseKeyframes();
|
|
5457
|
+
return /* @__PURE__ */ jsx19(
|
|
5089
5458
|
"circle",
|
|
5090
5459
|
{
|
|
5091
5460
|
className: "pid-data-overlay-status-dot",
|
|
@@ -5093,7 +5462,7 @@ function renderStatusDot(cx, cy, scale, fill) {
|
|
|
5093
5462
|
cy: cy - 18 * scale,
|
|
5094
5463
|
r: 3 * scale,
|
|
5095
5464
|
fill,
|
|
5096
|
-
style: { animation: PULSE_ANIMATION }
|
|
5465
|
+
style: isUnknown ? void 0 : { animation: PULSE_ANIMATION }
|
|
5097
5466
|
}
|
|
5098
5467
|
);
|
|
5099
5468
|
}
|
|
@@ -5119,7 +5488,7 @@ function DataOverlayImpl({
|
|
|
5119
5488
|
const backgroundColor = display?.backgroundColor;
|
|
5120
5489
|
const offsetX = display?.offsetX ?? 0;
|
|
5121
5490
|
const offsetY = display?.offsetY ?? 0;
|
|
5122
|
-
const sparklinePath =
|
|
5491
|
+
const sparklinePath = React12.useMemo(() => {
|
|
5123
5492
|
if (!showSparkline || !history || history.length < 2) return "";
|
|
5124
5493
|
const width = 70 * scale;
|
|
5125
5494
|
const height = 20 * scale;
|
|
@@ -5138,7 +5507,7 @@ function DataOverlayImpl({
|
|
|
5138
5507
|
return `M ${points.join(" L ")}`;
|
|
5139
5508
|
}, [showSparkline, history, scaling, scale]);
|
|
5140
5509
|
if (!showValue) {
|
|
5141
|
-
return /* @__PURE__ */
|
|
5510
|
+
return /* @__PURE__ */ jsx19(Fragment6, {});
|
|
5142
5511
|
}
|
|
5143
5512
|
const formatValue = (val) => {
|
|
5144
5513
|
if (typeof val === "number") {
|
|
@@ -5163,10 +5532,11 @@ function DataOverlayImpl({
|
|
|
5163
5532
|
const extraMarkRows = realDisplayText ? 1 : 0;
|
|
5164
5533
|
const overlayHeight = (label ? hasSparkline ? 55 : 30 : hasSparkline ? 47 : 22) * scale + extraMarkRows * 9 * scale;
|
|
5165
5534
|
const overlayWidth = 80 * scale;
|
|
5535
|
+
const isUnknownValue = normalizeDeviceStatus(value.status) === "unknown";
|
|
5166
5536
|
const displayX = x + offsetX;
|
|
5167
5537
|
const displayY = y + offsetY;
|
|
5168
|
-
return /* @__PURE__ */
|
|
5169
|
-
/* @__PURE__ */
|
|
5538
|
+
return /* @__PURE__ */ jsxs15("g", { "data-overlay-node": nodeId, "data-status": value.status, "data-forced": isForced, children: [
|
|
5539
|
+
/* @__PURE__ */ jsx19(
|
|
5170
5540
|
"rect",
|
|
5171
5541
|
{
|
|
5172
5542
|
x: displayX - overlayWidth / 2,
|
|
@@ -5181,7 +5551,7 @@ function DataOverlayImpl({
|
|
|
5181
5551
|
filter: "drop-shadow(0 2px 4px rgba(0,0,0,0.2))"
|
|
5182
5552
|
}
|
|
5183
5553
|
),
|
|
5184
|
-
label && /* @__PURE__ */
|
|
5554
|
+
label && /* @__PURE__ */ jsx19(
|
|
5185
5555
|
"text",
|
|
5186
5556
|
{
|
|
5187
5557
|
x: displayX,
|
|
@@ -5194,7 +5564,7 @@ function DataOverlayImpl({
|
|
|
5194
5564
|
children: label
|
|
5195
5565
|
}
|
|
5196
5566
|
),
|
|
5197
|
-
/* @__PURE__ */
|
|
5567
|
+
/* @__PURE__ */ jsx19(
|
|
5198
5568
|
"text",
|
|
5199
5569
|
{
|
|
5200
5570
|
x: displayX,
|
|
@@ -5207,8 +5577,17 @@ function DataOverlayImpl({
|
|
|
5207
5577
|
children: displayText
|
|
5208
5578
|
}
|
|
5209
5579
|
),
|
|
5210
|
-
showStatus && value.status !== "normal" && renderStatusDot(displayX, displayY, scale, finalTextColor),
|
|
5211
|
-
|
|
5580
|
+
showStatus && value.status !== "normal" && renderStatusDot(displayX, displayY, scale, finalTextColor, value.status),
|
|
5581
|
+
showStatus && isUnknownValue && /* @__PURE__ */ jsx19(
|
|
5582
|
+
UnknownStatusGlyph,
|
|
5583
|
+
{
|
|
5584
|
+
x: displayX - overlayWidth / 2 + 2 * scale,
|
|
5585
|
+
y: displayY - 25 * scale - 6 * scale,
|
|
5586
|
+
width: 12 * scale,
|
|
5587
|
+
height: 12 * scale
|
|
5588
|
+
}
|
|
5589
|
+
),
|
|
5590
|
+
value.quality !== void 0 && value.quality < 100 && /* @__PURE__ */ jsxs15(
|
|
5212
5591
|
"text",
|
|
5213
5592
|
{
|
|
5214
5593
|
x: displayX,
|
|
@@ -5225,13 +5604,13 @@ function DataOverlayImpl({
|
|
|
5225
5604
|
]
|
|
5226
5605
|
}
|
|
5227
5606
|
),
|
|
5228
|
-
isForced && /* @__PURE__ */
|
|
5607
|
+
isForced && /* @__PURE__ */ jsxs15(
|
|
5229
5608
|
"g",
|
|
5230
5609
|
{
|
|
5231
5610
|
transform: `translate(${displayX + overlayWidth / 2}, ${displayY - 25 * scale})`,
|
|
5232
5611
|
"aria-label": "Forced",
|
|
5233
5612
|
children: [
|
|
5234
|
-
/* @__PURE__ */
|
|
5613
|
+
/* @__PURE__ */ jsx19(
|
|
5235
5614
|
"circle",
|
|
5236
5615
|
{
|
|
5237
5616
|
r: 7 * scale,
|
|
@@ -5240,7 +5619,7 @@ function DataOverlayImpl({
|
|
|
5240
5619
|
strokeWidth: 1.5 * scale
|
|
5241
5620
|
}
|
|
5242
5621
|
),
|
|
5243
|
-
/* @__PURE__ */
|
|
5622
|
+
/* @__PURE__ */ jsx19(
|
|
5244
5623
|
"text",
|
|
5245
5624
|
{
|
|
5246
5625
|
textAnchor: "middle",
|
|
@@ -5254,7 +5633,7 @@ function DataOverlayImpl({
|
|
|
5254
5633
|
]
|
|
5255
5634
|
}
|
|
5256
5635
|
),
|
|
5257
|
-
realDisplayText && /* @__PURE__ */
|
|
5636
|
+
realDisplayText && /* @__PURE__ */ jsx19(
|
|
5258
5637
|
"text",
|
|
5259
5638
|
{
|
|
5260
5639
|
x: displayX,
|
|
@@ -5267,7 +5646,7 @@ function DataOverlayImpl({
|
|
|
5267
5646
|
children: realDisplayText
|
|
5268
5647
|
}
|
|
5269
5648
|
),
|
|
5270
|
-
hasSparkline && /* @__PURE__ */
|
|
5649
|
+
hasSparkline && /* @__PURE__ */ jsx19("g", { transform: `translate(${displayX - 35 * scale}, ${displayY + (label ? 5 : 0) * scale})`, children: /* @__PURE__ */ jsx19(
|
|
5271
5650
|
"path",
|
|
5272
5651
|
{
|
|
5273
5652
|
d: sparklinePath,
|
|
@@ -5281,11 +5660,11 @@ function DataOverlayImpl({
|
|
|
5281
5660
|
) })
|
|
5282
5661
|
] });
|
|
5283
5662
|
}
|
|
5284
|
-
var DataOverlay =
|
|
5663
|
+
var DataOverlay = React12.memo(DataOverlayImpl);
|
|
5285
5664
|
|
|
5286
5665
|
// src/components/PIDCanvas/PositionPanel.tsx
|
|
5287
5666
|
import { useState as useState9, useEffect as useEffect6 } from "react";
|
|
5288
|
-
import { jsx as
|
|
5667
|
+
import { jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
5289
5668
|
function PositionPanel({
|
|
5290
5669
|
selectedNode,
|
|
5291
5670
|
selectedWaypoint,
|
|
@@ -5354,7 +5733,7 @@ function PositionPanel({
|
|
|
5354
5733
|
"bottom-left": { bottom: 10, left: 10 },
|
|
5355
5734
|
"bottom-right": { bottom: 10, right: 10 }
|
|
5356
5735
|
};
|
|
5357
|
-
return /* @__PURE__ */
|
|
5736
|
+
return /* @__PURE__ */ jsxs16(
|
|
5358
5737
|
"div",
|
|
5359
5738
|
{
|
|
5360
5739
|
style: {
|
|
@@ -5371,11 +5750,11 @@ function PositionPanel({
|
|
|
5371
5750
|
fontSize: "13px"
|
|
5372
5751
|
},
|
|
5373
5752
|
children: [
|
|
5374
|
-
/* @__PURE__ */
|
|
5375
|
-
/* @__PURE__ */
|
|
5376
|
-
/* @__PURE__ */
|
|
5377
|
-
/* @__PURE__ */
|
|
5378
|
-
/* @__PURE__ */
|
|
5753
|
+
/* @__PURE__ */ jsx20("div", { style: { marginBottom: "8px", fontWeight: 600, color: "#333" }, children: "Position" }),
|
|
5754
|
+
/* @__PURE__ */ jsxs16("div", { style: { display: "flex", flexDirection: "column", gap: "8px" }, children: [
|
|
5755
|
+
/* @__PURE__ */ jsxs16("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
|
|
5756
|
+
/* @__PURE__ */ jsx20("label", { style: { width: "16px", color: "#666" }, children: "X:" }),
|
|
5757
|
+
/* @__PURE__ */ jsx20(
|
|
5379
5758
|
"input",
|
|
5380
5759
|
{
|
|
5381
5760
|
type: "number",
|
|
@@ -5393,9 +5772,9 @@ function PositionPanel({
|
|
|
5393
5772
|
}
|
|
5394
5773
|
)
|
|
5395
5774
|
] }),
|
|
5396
|
-
/* @__PURE__ */
|
|
5397
|
-
/* @__PURE__ */
|
|
5398
|
-
/* @__PURE__ */
|
|
5775
|
+
/* @__PURE__ */ jsxs16("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
|
|
5776
|
+
/* @__PURE__ */ jsx20("label", { style: { width: "16px", color: "#666" }, children: "Y:" }),
|
|
5777
|
+
/* @__PURE__ */ jsx20(
|
|
5399
5778
|
"input",
|
|
5400
5779
|
{
|
|
5401
5780
|
type: "number",
|
|
@@ -5414,7 +5793,7 @@ function PositionPanel({
|
|
|
5414
5793
|
)
|
|
5415
5794
|
] })
|
|
5416
5795
|
] }),
|
|
5417
|
-
/* @__PURE__ */
|
|
5796
|
+
/* @__PURE__ */ jsx20("div", { style: { marginTop: "8px", fontSize: "11px", color: "#888" }, children: "Use arrow keys to nudge (\xB11px)" })
|
|
5418
5797
|
]
|
|
5419
5798
|
}
|
|
5420
5799
|
);
|
|
@@ -6009,8 +6388,13 @@ function useTelemetryStatus(telemetry, diagram, setDiagram, options = {}) {
|
|
|
6009
6388
|
return "alarm";
|
|
6010
6389
|
case "off":
|
|
6011
6390
|
return "stopped";
|
|
6012
|
-
|
|
6391
|
+
case "unknown":
|
|
6392
|
+
return "unknown";
|
|
6393
|
+
default: {
|
|
6394
|
+
const exhaustive = telemetryStatus;
|
|
6395
|
+
void exhaustive;
|
|
6013
6396
|
return "stopped";
|
|
6397
|
+
}
|
|
6014
6398
|
}
|
|
6015
6399
|
};
|
|
6016
6400
|
const statusMapper = mapStatus || defaultMapStatus;
|
|
@@ -6034,8 +6418,49 @@ function useTelemetryStatus(telemetry, diagram, setDiagram, options = {}) {
|
|
|
6034
6418
|
}, [telemetry, diagram, setDiagram, enabled, mapStatus]);
|
|
6035
6419
|
}
|
|
6036
6420
|
|
|
6421
|
+
// src/diagram/hooks/useBooleanIndicators.ts
|
|
6422
|
+
import { useEffect as useEffect10 } from "react";
|
|
6423
|
+
function useBooleanIndicators(telemetry, diagram, setDiagram, options = {}) {
|
|
6424
|
+
const { enabled = true, symbolId = "status-indicator" } = options;
|
|
6425
|
+
useEffect10(() => {
|
|
6426
|
+
if (!enabled) return;
|
|
6427
|
+
const tagIndex = /* @__PURE__ */ new Map();
|
|
6428
|
+
telemetry.forEach((binding) => {
|
|
6429
|
+
if (binding.tag) tagIndex.set(binding.tag, binding.value.value);
|
|
6430
|
+
});
|
|
6431
|
+
let needsUpdate = false;
|
|
6432
|
+
const updatedNodes = diagram.nodes.map((node) => {
|
|
6433
|
+
if (node.symbolId !== symbolId) return node;
|
|
6434
|
+
const meta = node.metadata ?? {};
|
|
6435
|
+
const colorSource = typeof meta.colorSource === "string" ? meta.colorSource : "";
|
|
6436
|
+
const visibleSource = typeof meta.visibleSource === "string" ? meta.visibleSource : "";
|
|
6437
|
+
let next = node;
|
|
6438
|
+
if (colorSource) {
|
|
6439
|
+
const isTrue = Boolean(tagIndex.get(colorSource));
|
|
6440
|
+
const fill = resolvePresetColor(
|
|
6441
|
+
String(isTrue ? meta.onColor ?? "green" : meta.offColor ?? "red")
|
|
6442
|
+
);
|
|
6443
|
+
if (node.customColors?.fill !== fill) {
|
|
6444
|
+
next = { ...next, customColors: { ...next.customColors, fill } };
|
|
6445
|
+
}
|
|
6446
|
+
}
|
|
6447
|
+
if (visibleSource) {
|
|
6448
|
+
const vis = Boolean(tagIndex.get(visibleSource));
|
|
6449
|
+
if ((next.visible ?? true) !== vis) {
|
|
6450
|
+
next = { ...next, visible: vis };
|
|
6451
|
+
}
|
|
6452
|
+
}
|
|
6453
|
+
if (next !== node) needsUpdate = true;
|
|
6454
|
+
return next;
|
|
6455
|
+
});
|
|
6456
|
+
if (needsUpdate) {
|
|
6457
|
+
setDiagram({ ...diagram, nodes: updatedNodes });
|
|
6458
|
+
}
|
|
6459
|
+
}, [telemetry, diagram, setDiagram, enabled, symbolId]);
|
|
6460
|
+
}
|
|
6461
|
+
|
|
6037
6462
|
// src/diagram/hooks/useDrag.ts
|
|
6038
|
-
import { useState as useState13, useCallback as useCallback7, useRef as useRef5, useEffect as
|
|
6463
|
+
import { useState as useState13, useCallback as useCallback7, useRef as useRef5, useEffect as useEffect11 } from "react";
|
|
6039
6464
|
function useDrag(options = {}) {
|
|
6040
6465
|
const {
|
|
6041
6466
|
onDragStart,
|
|
@@ -6220,7 +6645,7 @@ function useDrag(options = {}) {
|
|
|
6220
6645
|
},
|
|
6221
6646
|
[screenToWorld, applySnap, onDragEnd]
|
|
6222
6647
|
);
|
|
6223
|
-
|
|
6648
|
+
useEffect11(() => {
|
|
6224
6649
|
if (!isListening) return;
|
|
6225
6650
|
document.addEventListener("mousemove", handleMouseMove);
|
|
6226
6651
|
document.addEventListener("mouseup", handleMouseUp);
|
|
@@ -6289,7 +6714,7 @@ function useDrag(options = {}) {
|
|
|
6289
6714
|
}
|
|
6290
6715
|
|
|
6291
6716
|
// src/diagram/hooks/useKeyboardShortcuts.ts
|
|
6292
|
-
import { useEffect as
|
|
6717
|
+
import { useEffect as useEffect12 } from "react";
|
|
6293
6718
|
function useKeyboardShortcuts(options) {
|
|
6294
6719
|
const {
|
|
6295
6720
|
onDelete,
|
|
@@ -6300,7 +6725,7 @@ function useKeyboardShortcuts(options) {
|
|
|
6300
6725
|
onSelectAll,
|
|
6301
6726
|
enabled = true
|
|
6302
6727
|
} = options;
|
|
6303
|
-
|
|
6728
|
+
useEffect12(() => {
|
|
6304
6729
|
if (!enabled) return;
|
|
6305
6730
|
const handleKeyDown = (event) => {
|
|
6306
6731
|
const target = event.target;
|
|
@@ -6409,7 +6834,7 @@ function nodeHasPort(node, portId) {
|
|
|
6409
6834
|
}
|
|
6410
6835
|
|
|
6411
6836
|
// src/components/PIDCanvas/PIDCanvas.tsx
|
|
6412
|
-
import { Fragment as Fragment7, jsx as
|
|
6837
|
+
import { Fragment as Fragment7, jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
6413
6838
|
var DEFAULT_FEATURES = {
|
|
6414
6839
|
pan: true,
|
|
6415
6840
|
zoom: true,
|
|
@@ -6452,7 +6877,7 @@ function PIDCanvasImpl({
|
|
|
6452
6877
|
const isUndoRedoAction = useRef6(false);
|
|
6453
6878
|
const isInternalChange = useRef6(false);
|
|
6454
6879
|
const lastInternalDiagram = useRef6(null);
|
|
6455
|
-
|
|
6880
|
+
useEffect13(() => {
|
|
6456
6881
|
const isExternal = !isInternalChange.current && diagram !== lastInternalDiagram.current;
|
|
6457
6882
|
if (isExternal) {
|
|
6458
6883
|
setLocalDiagram(diagram);
|
|
@@ -6497,7 +6922,7 @@ function PIDCanvasImpl({
|
|
|
6497
6922
|
});
|
|
6498
6923
|
return { minX, minY, maxX, maxY };
|
|
6499
6924
|
}, [localDiagram.nodes]);
|
|
6500
|
-
|
|
6925
|
+
useEffect13(() => {
|
|
6501
6926
|
if (onMounted) {
|
|
6502
6927
|
const controls = {
|
|
6503
6928
|
fitToContent: (padding = 50) => {
|
|
@@ -6576,7 +7001,7 @@ function PIDCanvasImpl({
|
|
|
6576
7001
|
isUndoRedoAction.current = false;
|
|
6577
7002
|
}, 0);
|
|
6578
7003
|
}, [localDiagram, onDiagramChange]);
|
|
6579
|
-
|
|
7004
|
+
useEffect13(() => {
|
|
6580
7005
|
const handleKeyDown = (e) => {
|
|
6581
7006
|
const isCtrlOrCmd = e.ctrlKey || e.metaKey;
|
|
6582
7007
|
if (isCtrlOrCmd && e.key === "z" && !e.shiftKey) {
|
|
@@ -6593,7 +7018,7 @@ function PIDCanvasImpl({
|
|
|
6593
7018
|
window.addEventListener("keydown", handleKeyDown);
|
|
6594
7019
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
6595
7020
|
}, [undo, redo]);
|
|
6596
|
-
|
|
7021
|
+
useEffect13(() => {
|
|
6597
7022
|
if (!features.dragNodes) return;
|
|
6598
7023
|
const handleKeyDown = (e) => {
|
|
6599
7024
|
if (selection.selectedNodeIds.size === 0 && !selectedWaypoint) return;
|
|
@@ -7022,7 +7447,7 @@ function PIDCanvasImpl({
|
|
|
7022
7447
|
const viewBox = controlledViewBox;
|
|
7023
7448
|
const displayDiagram = localDiagram;
|
|
7024
7449
|
const selectedNode = selectionEnabled && selection.selectedNodeIds.size === 1 ? localDiagram.nodes.find((n) => selection.selectedNodeIds.has(n.id)) || null : null;
|
|
7025
|
-
return /* @__PURE__ */
|
|
7450
|
+
return /* @__PURE__ */ jsxs17(
|
|
7026
7451
|
"div",
|
|
7027
7452
|
{
|
|
7028
7453
|
ref: containerRef,
|
|
@@ -7037,7 +7462,7 @@ function PIDCanvasImpl({
|
|
|
7037
7462
|
},
|
|
7038
7463
|
...props,
|
|
7039
7464
|
children: [
|
|
7040
|
-
/* @__PURE__ */
|
|
7465
|
+
/* @__PURE__ */ jsxs17(
|
|
7041
7466
|
"svg",
|
|
7042
7467
|
{
|
|
7043
7468
|
ref: svgRef,
|
|
@@ -7056,15 +7481,15 @@ function PIDCanvasImpl({
|
|
|
7056
7481
|
onDrop: handleDrop,
|
|
7057
7482
|
onDragLeave: handleDragLeave,
|
|
7058
7483
|
children: [
|
|
7059
|
-
features.showGrid !== false ? /* @__PURE__ */
|
|
7060
|
-
/* @__PURE__ */
|
|
7061
|
-
/* @__PURE__ */
|
|
7062
|
-
/* @__PURE__ */
|
|
7063
|
-
/* @__PURE__ */
|
|
7064
|
-
/* @__PURE__ */
|
|
7484
|
+
features.showGrid !== false ? /* @__PURE__ */ jsxs17(Fragment7, { children: [
|
|
7485
|
+
/* @__PURE__ */ jsxs17("defs", { children: [
|
|
7486
|
+
/* @__PURE__ */ jsx21("pattern", { id: "grid-minor", width: "5", height: "5", patternUnits: "userSpaceOnUse", children: /* @__PURE__ */ jsx21("path", { d: "M 5 0 L 0 0 0 5", fill: "none", stroke: "#e5e7eb", strokeWidth: "0.5" }) }),
|
|
7487
|
+
/* @__PURE__ */ jsxs17("pattern", { id: "grid-major", width: "25", height: "25", patternUnits: "userSpaceOnUse", children: [
|
|
7488
|
+
/* @__PURE__ */ jsx21("rect", { width: "25", height: "25", fill: "url(#grid-minor)" }),
|
|
7489
|
+
/* @__PURE__ */ jsx21("path", { d: "M 25 0 L 0 0 0 25", fill: "none", stroke: "#d1d5db", strokeWidth: "1" })
|
|
7065
7490
|
] })
|
|
7066
7491
|
] }),
|
|
7067
|
-
/* @__PURE__ */
|
|
7492
|
+
/* @__PURE__ */ jsx21(
|
|
7068
7493
|
"rect",
|
|
7069
7494
|
{
|
|
7070
7495
|
x: Math.floor(viewBox.x / 25) * 25 - viewBox.width,
|
|
@@ -7074,7 +7499,7 @@ function PIDCanvasImpl({
|
|
|
7074
7499
|
fill: "url(#grid-major)"
|
|
7075
7500
|
}
|
|
7076
7501
|
)
|
|
7077
|
-
] }) : /* @__PURE__ */
|
|
7502
|
+
] }) : /* @__PURE__ */ jsx21(
|
|
7078
7503
|
"rect",
|
|
7079
7504
|
{
|
|
7080
7505
|
x: Math.floor(viewBox.x / 25) * 25 - viewBox.width,
|
|
@@ -7084,7 +7509,7 @@ function PIDCanvasImpl({
|
|
|
7084
7509
|
fill: features.backgroundColor ?? "#ffffff"
|
|
7085
7510
|
}
|
|
7086
7511
|
),
|
|
7087
|
-
/* @__PURE__ */
|
|
7512
|
+
/* @__PURE__ */ jsx21(
|
|
7088
7513
|
PipeRenderer,
|
|
7089
7514
|
{
|
|
7090
7515
|
pipes: displayDiagram.pipes,
|
|
@@ -7098,7 +7523,7 @@ function PIDCanvasImpl({
|
|
|
7098
7523
|
onPipeSegmentClick: void 0
|
|
7099
7524
|
}
|
|
7100
7525
|
),
|
|
7101
|
-
/* @__PURE__ */
|
|
7526
|
+
/* @__PURE__ */ jsx21(
|
|
7102
7527
|
NodeRenderer,
|
|
7103
7528
|
{
|
|
7104
7529
|
nodes: displayDiagram.nodes,
|
|
@@ -7112,7 +7537,7 @@ function PIDCanvasImpl({
|
|
|
7112
7537
|
statusColorMap
|
|
7113
7538
|
}
|
|
7114
7539
|
),
|
|
7115
|
-
(features.editPipeRoutes ?? false) && /* @__PURE__ */
|
|
7540
|
+
(features.editPipeRoutes ?? false) && /* @__PURE__ */ jsx21(
|
|
7116
7541
|
PipeRenderer,
|
|
7117
7542
|
{
|
|
7118
7543
|
pipes: displayDiagram.pipes,
|
|
@@ -7129,14 +7554,15 @@ function PIDCanvasImpl({
|
|
|
7129
7554
|
onPipeSegmentClick: handlePipeSegmentClick
|
|
7130
7555
|
}
|
|
7131
7556
|
),
|
|
7132
|
-
telemetryEnabled && telemetry && /* @__PURE__ */
|
|
7557
|
+
telemetryEnabled && telemetry && /* @__PURE__ */ jsx21("g", { id: "layer-telemetry", children: displayDiagram.nodes.map((node) => {
|
|
7558
|
+
if (node.symbolId === "status-indicator") return null;
|
|
7133
7559
|
const binding = telemetry.get(node.id);
|
|
7134
7560
|
if (!binding) return null;
|
|
7135
7561
|
const symbol = getSymbolDefinition(node.symbolId);
|
|
7136
7562
|
if (!symbol) return null;
|
|
7137
7563
|
const overlayX = node.transform.x + symbol.viewBox.width / 2;
|
|
7138
7564
|
const overlayY = node.transform.y + symbol.viewBox.height + 50;
|
|
7139
|
-
return /* @__PURE__ */
|
|
7565
|
+
return /* @__PURE__ */ jsx21(
|
|
7140
7566
|
DataOverlay,
|
|
7141
7567
|
{
|
|
7142
7568
|
nodeId: node.id,
|
|
@@ -7149,7 +7575,7 @@ function PIDCanvasImpl({
|
|
|
7149
7575
|
`telemetry-${node.id}`
|
|
7150
7576
|
);
|
|
7151
7577
|
}) }),
|
|
7152
|
-
dragOverPosition && /* @__PURE__ */
|
|
7578
|
+
dragOverPosition && /* @__PURE__ */ jsx21(
|
|
7153
7579
|
"circle",
|
|
7154
7580
|
{
|
|
7155
7581
|
cx: dragOverPosition.x,
|
|
@@ -7162,7 +7588,7 @@ function PIDCanvasImpl({
|
|
|
7162
7588
|
pointerEvents: "none"
|
|
7163
7589
|
}
|
|
7164
7590
|
),
|
|
7165
|
-
isConnecting && connectionSource && connectionCursor && /* @__PURE__ */
|
|
7591
|
+
isConnecting && connectionSource && connectionCursor && /* @__PURE__ */ jsx21("g", { id: "connection-preview", pointerEvents: "none", children: (() => {
|
|
7166
7592
|
const sourceNode = displayDiagram.nodes.find((n) => n.id === connectionSource);
|
|
7167
7593
|
if (!sourceNode) return null;
|
|
7168
7594
|
const symbol = getSymbolDefinition(sourceNode.symbolId);
|
|
@@ -7178,8 +7604,8 @@ function PIDCanvasImpl({
|
|
|
7178
7604
|
}
|
|
7179
7605
|
}
|
|
7180
7606
|
}
|
|
7181
|
-
return /* @__PURE__ */
|
|
7182
|
-
/* @__PURE__ */
|
|
7607
|
+
return /* @__PURE__ */ jsxs17(Fragment7, { children: [
|
|
7608
|
+
/* @__PURE__ */ jsx21(
|
|
7183
7609
|
"circle",
|
|
7184
7610
|
{
|
|
7185
7611
|
cx: lineStartX,
|
|
@@ -7191,7 +7617,7 @@ function PIDCanvasImpl({
|
|
|
7191
7617
|
opacity: 0.6
|
|
7192
7618
|
}
|
|
7193
7619
|
),
|
|
7194
|
-
/* @__PURE__ */
|
|
7620
|
+
/* @__PURE__ */ jsx21(
|
|
7195
7621
|
"line",
|
|
7196
7622
|
{
|
|
7197
7623
|
x1: lineStartX,
|
|
@@ -7204,7 +7630,7 @@ function PIDCanvasImpl({
|
|
|
7204
7630
|
opacity: 0.8
|
|
7205
7631
|
}
|
|
7206
7632
|
),
|
|
7207
|
-
/* @__PURE__ */
|
|
7633
|
+
/* @__PURE__ */ jsx21(
|
|
7208
7634
|
"circle",
|
|
7209
7635
|
{
|
|
7210
7636
|
cx: connectionCursor.x,
|
|
@@ -7216,7 +7642,7 @@ function PIDCanvasImpl({
|
|
|
7216
7642
|
)
|
|
7217
7643
|
] });
|
|
7218
7644
|
})() }),
|
|
7219
|
-
features.connectionMode && /* @__PURE__ */
|
|
7645
|
+
features.connectionMode && /* @__PURE__ */ jsx21("g", { id: "port-indicators", children: displayDiagram.nodes.map((node) => {
|
|
7220
7646
|
const symbol = getSymbolDefinition(node.symbolId);
|
|
7221
7647
|
if (!symbol?.ports) return null;
|
|
7222
7648
|
return symbol.ports.map((port) => {
|
|
@@ -7224,8 +7650,8 @@ function PIDCanvasImpl({
|
|
|
7224
7650
|
if (!portPos) return null;
|
|
7225
7651
|
const isHovered = hoveredPort === port.id && hoveredNode === node.id;
|
|
7226
7652
|
const isSourcePort = node.id === connectionSource && port.id === connectionSourcePort;
|
|
7227
|
-
return /* @__PURE__ */
|
|
7228
|
-
/* @__PURE__ */
|
|
7653
|
+
return /* @__PURE__ */ jsxs17("g", { children: [
|
|
7654
|
+
/* @__PURE__ */ jsx21(
|
|
7229
7655
|
"circle",
|
|
7230
7656
|
{
|
|
7231
7657
|
cx: portPos.x,
|
|
@@ -7258,7 +7684,7 @@ function PIDCanvasImpl({
|
|
|
7258
7684
|
}
|
|
7259
7685
|
}
|
|
7260
7686
|
),
|
|
7261
|
-
/* @__PURE__ */
|
|
7687
|
+
/* @__PURE__ */ jsx21(
|
|
7262
7688
|
"circle",
|
|
7263
7689
|
{
|
|
7264
7690
|
cx: portPos.x,
|
|
@@ -7277,7 +7703,7 @@ function PIDCanvasImpl({
|
|
|
7277
7703
|
]
|
|
7278
7704
|
}
|
|
7279
7705
|
),
|
|
7280
|
-
features.dragNodes && /* @__PURE__ */
|
|
7706
|
+
features.dragNodes && /* @__PURE__ */ jsx21(
|
|
7281
7707
|
PositionPanel,
|
|
7282
7708
|
{
|
|
7283
7709
|
selectedNode,
|
|
@@ -7295,11 +7721,11 @@ function PIDCanvasImpl({
|
|
|
7295
7721
|
}
|
|
7296
7722
|
);
|
|
7297
7723
|
}
|
|
7298
|
-
var PIDCanvas =
|
|
7724
|
+
var PIDCanvas = React14.memo(PIDCanvasImpl);
|
|
7299
7725
|
|
|
7300
7726
|
// src/components/SymbolLibrary/SymbolLibrary.tsx
|
|
7301
7727
|
import { useState as useState15 } from "react";
|
|
7302
|
-
import { jsx as
|
|
7728
|
+
import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
7303
7729
|
function SymbolLibrary({
|
|
7304
7730
|
className = "",
|
|
7305
7731
|
onSymbolDragStart,
|
|
@@ -7328,9 +7754,9 @@ function SymbolLibrary({
|
|
|
7328
7754
|
event.dataTransfer.effectAllowed = "copy";
|
|
7329
7755
|
onSymbolDragStart?.(symbol.id, event);
|
|
7330
7756
|
};
|
|
7331
|
-
return /* @__PURE__ */
|
|
7332
|
-
/* @__PURE__ */
|
|
7333
|
-
/* @__PURE__ */
|
|
7757
|
+
return /* @__PURE__ */ jsxs18("div", { className: `symbol-library ${className}`.trim(), style: styles.container, children: [
|
|
7758
|
+
/* @__PURE__ */ jsx22("div", { style: styles.header, children: /* @__PURE__ */ jsx22("h3", { style: styles.title, children: "Symbol Library" }) }),
|
|
7759
|
+
/* @__PURE__ */ jsx22("div", { style: styles.searchContainer, children: /* @__PURE__ */ jsx22(
|
|
7334
7760
|
"input",
|
|
7335
7761
|
{
|
|
7336
7762
|
type: "text",
|
|
@@ -7340,8 +7766,8 @@ function SymbolLibrary({
|
|
|
7340
7766
|
style: styles.searchInput
|
|
7341
7767
|
}
|
|
7342
7768
|
) }),
|
|
7343
|
-
showCategories && /* @__PURE__ */
|
|
7344
|
-
/* @__PURE__ */
|
|
7769
|
+
showCategories && /* @__PURE__ */ jsxs18("div", { style: styles.categories, children: [
|
|
7770
|
+
/* @__PURE__ */ jsx22(
|
|
7345
7771
|
"button",
|
|
7346
7772
|
{
|
|
7347
7773
|
onClick: () => setSelectedCategory("all"),
|
|
@@ -7352,7 +7778,7 @@ function SymbolLibrary({
|
|
|
7352
7778
|
children: "All"
|
|
7353
7779
|
}
|
|
7354
7780
|
),
|
|
7355
|
-
categories.map((category) => /* @__PURE__ */
|
|
7781
|
+
categories.map((category) => /* @__PURE__ */ jsx22(
|
|
7356
7782
|
"button",
|
|
7357
7783
|
{
|
|
7358
7784
|
onClick: () => setSelectedCategory(category),
|
|
@@ -7365,7 +7791,7 @@ function SymbolLibrary({
|
|
|
7365
7791
|
category
|
|
7366
7792
|
))
|
|
7367
7793
|
] }),
|
|
7368
|
-
/* @__PURE__ */
|
|
7794
|
+
/* @__PURE__ */ jsx22("div", { style: styles.symbolGrid, children: filteredSymbols.length === 0 ? /* @__PURE__ */ jsx22("div", { style: styles.emptyState, children: "No symbols found" }) : filteredSymbols.map((symbol) => /* @__PURE__ */ jsxs18(
|
|
7369
7795
|
"div",
|
|
7370
7796
|
{
|
|
7371
7797
|
draggable: true,
|
|
@@ -7373,15 +7799,15 @@ function SymbolLibrary({
|
|
|
7373
7799
|
style: styles.symbolCard,
|
|
7374
7800
|
title: symbol.metadata?.description || symbol.name,
|
|
7375
7801
|
children: [
|
|
7376
|
-
/* @__PURE__ */
|
|
7802
|
+
/* @__PURE__ */ jsx22("div", { style: styles.symbolPreview, children: /* @__PURE__ */ jsx22(
|
|
7377
7803
|
"svg",
|
|
7378
7804
|
{
|
|
7379
7805
|
viewBox: `${symbol.viewBox.x} ${symbol.viewBox.y} ${symbol.viewBox.width} ${symbol.viewBox.height}`,
|
|
7380
7806
|
style: styles.symbolSvg,
|
|
7381
|
-
children: /* @__PURE__ */
|
|
7807
|
+
children: /* @__PURE__ */ jsx22("g", { dangerouslySetInnerHTML: { __html: symbol.svgContent } })
|
|
7382
7808
|
}
|
|
7383
7809
|
) }),
|
|
7384
|
-
/* @__PURE__ */
|
|
7810
|
+
/* @__PURE__ */ jsx22("div", { style: styles.symbolName, children: symbol.name })
|
|
7385
7811
|
]
|
|
7386
7812
|
},
|
|
7387
7813
|
symbol.id
|
|
@@ -7490,13 +7916,15 @@ var styles = {
|
|
|
7490
7916
|
};
|
|
7491
7917
|
|
|
7492
7918
|
// src/components/NodeConfigPanel/NodeConfigPanel.tsx
|
|
7493
|
-
import { Fragment as Fragment8, jsx as
|
|
7919
|
+
import { Fragment as Fragment8, jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
7494
7920
|
function NodeConfigPanel({
|
|
7495
7921
|
node,
|
|
7496
7922
|
binding,
|
|
7497
7923
|
onUpdateNode,
|
|
7498
7924
|
onUpdateTelemetry,
|
|
7499
7925
|
onAddTelemetry,
|
|
7926
|
+
onRemoveTelemetry,
|
|
7927
|
+
availableTags = [],
|
|
7500
7928
|
onRemove,
|
|
7501
7929
|
className = "",
|
|
7502
7930
|
style = {}
|
|
@@ -7509,15 +7937,17 @@ function NodeConfigPanel({
|
|
|
7509
7937
|
padding: "20px",
|
|
7510
7938
|
...style
|
|
7511
7939
|
};
|
|
7512
|
-
|
|
7513
|
-
|
|
7940
|
+
const appearanceFields = getAppearanceSchema(node.symbolId);
|
|
7941
|
+
const showGenericTelemetry = appearanceFields.length === 0;
|
|
7942
|
+
return /* @__PURE__ */ jsxs19("div", { className, style: defaultStyle, children: [
|
|
7943
|
+
/* @__PURE__ */ jsxs19("h2", { style: { margin: "0 0 16px 0", fontSize: "1rem", fontWeight: 600 }, children: [
|
|
7514
7944
|
"Configure: ",
|
|
7515
7945
|
node.id
|
|
7516
7946
|
] }),
|
|
7517
|
-
/* @__PURE__ */
|
|
7518
|
-
/* @__PURE__ */
|
|
7519
|
-
/* @__PURE__ */
|
|
7520
|
-
/* @__PURE__ */
|
|
7947
|
+
/* @__PURE__ */ jsxs19("div", { style: { marginBottom: "20px" }, children: [
|
|
7948
|
+
/* @__PURE__ */ jsx23("h3", { style: { fontSize: "0.875rem", fontWeight: 600, marginBottom: "8px" }, children: "Node Settings" }),
|
|
7949
|
+
/* @__PURE__ */ jsx23("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Label:" }),
|
|
7950
|
+
/* @__PURE__ */ jsx23(
|
|
7521
7951
|
"input",
|
|
7522
7952
|
{
|
|
7523
7953
|
type: "text",
|
|
@@ -7533,10 +7963,10 @@ function NodeConfigPanel({
|
|
|
7533
7963
|
}
|
|
7534
7964
|
}
|
|
7535
7965
|
),
|
|
7536
|
-
/* @__PURE__ */
|
|
7537
|
-
/* @__PURE__ */
|
|
7538
|
-
/* @__PURE__ */
|
|
7539
|
-
/* @__PURE__ */
|
|
7966
|
+
/* @__PURE__ */ jsxs19("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: "8px" }, children: [
|
|
7967
|
+
/* @__PURE__ */ jsxs19("div", { children: [
|
|
7968
|
+
/* @__PURE__ */ jsx23("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Label Offset X:" }),
|
|
7969
|
+
/* @__PURE__ */ jsx23(
|
|
7540
7970
|
"input",
|
|
7541
7971
|
{
|
|
7542
7972
|
type: "number",
|
|
@@ -7557,9 +7987,9 @@ function NodeConfigPanel({
|
|
|
7557
7987
|
}
|
|
7558
7988
|
)
|
|
7559
7989
|
] }),
|
|
7560
|
-
/* @__PURE__ */
|
|
7561
|
-
/* @__PURE__ */
|
|
7562
|
-
/* @__PURE__ */
|
|
7990
|
+
/* @__PURE__ */ jsxs19("div", { children: [
|
|
7991
|
+
/* @__PURE__ */ jsx23("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Label Offset Y:" }),
|
|
7992
|
+
/* @__PURE__ */ jsx23(
|
|
7563
7993
|
"input",
|
|
7564
7994
|
{
|
|
7565
7995
|
type: "number",
|
|
@@ -7581,9 +8011,9 @@ function NodeConfigPanel({
|
|
|
7581
8011
|
)
|
|
7582
8012
|
] })
|
|
7583
8013
|
] }),
|
|
7584
|
-
/* @__PURE__ */
|
|
7585
|
-
/* @__PURE__ */
|
|
7586
|
-
/* @__PURE__ */
|
|
8014
|
+
/* @__PURE__ */ jsxs19("div", { children: [
|
|
8015
|
+
/* @__PURE__ */ jsx23("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Label Font Size:" }),
|
|
8016
|
+
/* @__PURE__ */ jsx23(
|
|
7587
8017
|
"input",
|
|
7588
8018
|
{
|
|
7589
8019
|
type: "number",
|
|
@@ -7603,9 +8033,9 @@ function NodeConfigPanel({
|
|
|
7603
8033
|
}
|
|
7604
8034
|
)
|
|
7605
8035
|
] }),
|
|
7606
|
-
/* @__PURE__ */
|
|
7607
|
-
/* @__PURE__ */
|
|
7608
|
-
/* @__PURE__ */
|
|
8036
|
+
/* @__PURE__ */ jsxs19("div", { children: [
|
|
8037
|
+
/* @__PURE__ */ jsx23("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Rotation (degrees):" }),
|
|
8038
|
+
/* @__PURE__ */ jsx23(
|
|
7609
8039
|
"input",
|
|
7610
8040
|
{
|
|
7611
8041
|
type: "number",
|
|
@@ -7630,9 +8060,138 @@ function NodeConfigPanel({
|
|
|
7630
8060
|
)
|
|
7631
8061
|
] })
|
|
7632
8062
|
] }),
|
|
7633
|
-
/* @__PURE__ */
|
|
7634
|
-
/* @__PURE__ */
|
|
7635
|
-
|
|
8063
|
+
appearanceFields.length > 0 && /* @__PURE__ */ jsxs19("div", { style: { marginBottom: "20px" }, children: [
|
|
8064
|
+
/* @__PURE__ */ jsx23("h3", { style: { fontSize: "0.875rem", fontWeight: 600, marginBottom: "8px" }, children: "Appearance" }),
|
|
8065
|
+
appearanceFields.map((field) => {
|
|
8066
|
+
const value = readAppearanceValue(node, field);
|
|
8067
|
+
const fieldLabel = field.label ?? field.key;
|
|
8068
|
+
const inputStyle = {
|
|
8069
|
+
width: "100%",
|
|
8070
|
+
padding: "6px 8px",
|
|
8071
|
+
borderRadius: "4px",
|
|
8072
|
+
border: "1px solid #cbd5e1",
|
|
8073
|
+
fontSize: "0.875rem"
|
|
8074
|
+
};
|
|
8075
|
+
let control;
|
|
8076
|
+
if (field.kind === "boolean") {
|
|
8077
|
+
control = /* @__PURE__ */ jsxs19("label", { style: { fontSize: "0.75rem", display: "block" }, children: [
|
|
8078
|
+
/* @__PURE__ */ jsx23(
|
|
8079
|
+
"input",
|
|
8080
|
+
{
|
|
8081
|
+
type: "checkbox",
|
|
8082
|
+
checked: Boolean(value),
|
|
8083
|
+
onChange: (e) => onUpdateNode(writeAppearanceValue(node, field, e.target.checked)),
|
|
8084
|
+
style: { marginRight: "6px" }
|
|
8085
|
+
}
|
|
8086
|
+
),
|
|
8087
|
+
fieldLabel
|
|
8088
|
+
] });
|
|
8089
|
+
} else if (field.kind === "select") {
|
|
8090
|
+
control = /* @__PURE__ */ jsxs19(Fragment8, { children: [
|
|
8091
|
+
/* @__PURE__ */ jsxs19("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: [
|
|
8092
|
+
fieldLabel,
|
|
8093
|
+
":"
|
|
8094
|
+
] }),
|
|
8095
|
+
/* @__PURE__ */ jsx23(
|
|
8096
|
+
"select",
|
|
8097
|
+
{
|
|
8098
|
+
value: String(value),
|
|
8099
|
+
onChange: (e) => onUpdateNode(writeAppearanceValue(node, field, e.target.value)),
|
|
8100
|
+
style: inputStyle,
|
|
8101
|
+
children: field.options?.map((opt) => /* @__PURE__ */ jsx23("option", { value: opt, children: opt }, opt))
|
|
8102
|
+
}
|
|
8103
|
+
)
|
|
8104
|
+
] });
|
|
8105
|
+
} else if (field.kind === "number") {
|
|
8106
|
+
control = /* @__PURE__ */ jsxs19(Fragment8, { children: [
|
|
8107
|
+
/* @__PURE__ */ jsxs19("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: [
|
|
8108
|
+
fieldLabel,
|
|
8109
|
+
":"
|
|
8110
|
+
] }),
|
|
8111
|
+
/* @__PURE__ */ jsx23(
|
|
8112
|
+
"input",
|
|
8113
|
+
{
|
|
8114
|
+
type: "number",
|
|
8115
|
+
value: Number(value),
|
|
8116
|
+
onChange: (e) => onUpdateNode(writeAppearanceValue(node, field, parseFloat(e.target.value) || 0)),
|
|
8117
|
+
style: inputStyle
|
|
8118
|
+
}
|
|
8119
|
+
)
|
|
8120
|
+
] });
|
|
8121
|
+
} else if (field.kind === "tag") {
|
|
8122
|
+
const tagValue = String(value);
|
|
8123
|
+
const listId = `tags-${node.id}-${field.key}`;
|
|
8124
|
+
const known = tagValue.length > 0 && availableTags.includes(tagValue);
|
|
8125
|
+
const unknown = tagValue.length > 0 && !known;
|
|
8126
|
+
control = /* @__PURE__ */ jsxs19(Fragment8, { children: [
|
|
8127
|
+
/* @__PURE__ */ jsxs19("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: [
|
|
8128
|
+
fieldLabel,
|
|
8129
|
+
":"
|
|
8130
|
+
] }),
|
|
8131
|
+
/* @__PURE__ */ jsx23(
|
|
8132
|
+
"input",
|
|
8133
|
+
{
|
|
8134
|
+
type: "text",
|
|
8135
|
+
value: tagValue,
|
|
8136
|
+
list: listId,
|
|
8137
|
+
onChange: (e) => onUpdateNode(writeAppearanceValue(node, field, e.target.value)),
|
|
8138
|
+
placeholder: "type or pick a signal\u2026",
|
|
8139
|
+
style: {
|
|
8140
|
+
...inputStyle,
|
|
8141
|
+
border: `1px solid ${unknown ? "#f59e0b" : known ? "#22c55e" : "#cbd5e1"}`
|
|
8142
|
+
}
|
|
8143
|
+
}
|
|
8144
|
+
),
|
|
8145
|
+
/* @__PURE__ */ jsx23("datalist", { id: listId, children: availableTags.map((t) => /* @__PURE__ */ jsx23("option", { value: t }, t)) }),
|
|
8146
|
+
tagValue.length > 0 && /* @__PURE__ */ jsx23(
|
|
8147
|
+
"div",
|
|
8148
|
+
{
|
|
8149
|
+
style: {
|
|
8150
|
+
fontSize: "0.7rem",
|
|
8151
|
+
marginTop: "3px",
|
|
8152
|
+
color: known ? "#16a34a" : "#b45309"
|
|
8153
|
+
},
|
|
8154
|
+
children: known ? "\u2713 matched signal" : "\u26A0 no matching signal (reads as false until published)"
|
|
8155
|
+
}
|
|
8156
|
+
)
|
|
8157
|
+
] });
|
|
8158
|
+
} else {
|
|
8159
|
+
control = /* @__PURE__ */ jsxs19(Fragment8, { children: [
|
|
8160
|
+
/* @__PURE__ */ jsxs19("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: [
|
|
8161
|
+
fieldLabel,
|
|
8162
|
+
":"
|
|
8163
|
+
] }),
|
|
8164
|
+
/* @__PURE__ */ jsx23(
|
|
8165
|
+
"input",
|
|
8166
|
+
{
|
|
8167
|
+
type: "text",
|
|
8168
|
+
value: String(value),
|
|
8169
|
+
onChange: (e) => onUpdateNode(writeAppearanceValue(node, field, e.target.value)),
|
|
8170
|
+
style: inputStyle
|
|
8171
|
+
}
|
|
8172
|
+
)
|
|
8173
|
+
] });
|
|
8174
|
+
}
|
|
8175
|
+
return /* @__PURE__ */ jsxs19("div", { style: { marginBottom: "10px" }, children: [
|
|
8176
|
+
control,
|
|
8177
|
+
field.help && /* @__PURE__ */ jsx23(
|
|
8178
|
+
"div",
|
|
8179
|
+
{
|
|
8180
|
+
style: {
|
|
8181
|
+
fontSize: "0.7rem",
|
|
8182
|
+
color: "#64748b",
|
|
8183
|
+
marginTop: "3px",
|
|
8184
|
+
lineHeight: 1.35
|
|
8185
|
+
},
|
|
8186
|
+
children: field.help
|
|
8187
|
+
}
|
|
8188
|
+
)
|
|
8189
|
+
] }, field.key);
|
|
8190
|
+
})
|
|
8191
|
+
] }),
|
|
8192
|
+
showGenericTelemetry && /* @__PURE__ */ jsxs19("div", { style: { marginBottom: "20px" }, children: [
|
|
8193
|
+
/* @__PURE__ */ jsx23("h3", { style: { fontSize: "0.875rem", fontWeight: 600, marginBottom: "8px" }, children: "Telemetry Data" }),
|
|
8194
|
+
!binding ? /* @__PURE__ */ jsx23(
|
|
7636
8195
|
"button",
|
|
7637
8196
|
{
|
|
7638
8197
|
onClick: () => {
|
|
@@ -7675,9 +8234,30 @@ function NodeConfigPanel({
|
|
|
7675
8234
|
},
|
|
7676
8235
|
children: "+ Add Telemetry"
|
|
7677
8236
|
}
|
|
7678
|
-
) : /* @__PURE__ */
|
|
7679
|
-
/* @__PURE__ */
|
|
7680
|
-
/* @__PURE__ */
|
|
8237
|
+
) : /* @__PURE__ */ jsxs19(Fragment8, { children: [
|
|
8238
|
+
/* @__PURE__ */ jsx23("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Tag (attribute):" }),
|
|
8239
|
+
/* @__PURE__ */ jsx23(
|
|
8240
|
+
"input",
|
|
8241
|
+
{
|
|
8242
|
+
type: "text",
|
|
8243
|
+
value: binding.tag || "",
|
|
8244
|
+
onChange: (e) => onUpdateTelemetry({
|
|
8245
|
+
nodeId: node.id,
|
|
8246
|
+
tag: e.target.value
|
|
8247
|
+
}),
|
|
8248
|
+
placeholder: "e.g. pump.running",
|
|
8249
|
+
style: {
|
|
8250
|
+
width: "100%",
|
|
8251
|
+
padding: "6px 8px",
|
|
8252
|
+
borderRadius: "4px",
|
|
8253
|
+
border: "1px solid #cbd5e1",
|
|
8254
|
+
fontSize: "0.875rem",
|
|
8255
|
+
marginBottom: "8px"
|
|
8256
|
+
}
|
|
8257
|
+
}
|
|
8258
|
+
),
|
|
8259
|
+
/* @__PURE__ */ jsx23("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Initial Value:" }),
|
|
8260
|
+
/* @__PURE__ */ jsx23(
|
|
7681
8261
|
"input",
|
|
7682
8262
|
{
|
|
7683
8263
|
type: "number",
|
|
@@ -7699,8 +8279,8 @@ function NodeConfigPanel({
|
|
|
7699
8279
|
}
|
|
7700
8280
|
}
|
|
7701
8281
|
),
|
|
7702
|
-
/* @__PURE__ */
|
|
7703
|
-
/* @__PURE__ */
|
|
8282
|
+
/* @__PURE__ */ jsx23("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Unit:" }),
|
|
8283
|
+
/* @__PURE__ */ jsx23(
|
|
7704
8284
|
"input",
|
|
7705
8285
|
{
|
|
7706
8286
|
type: "text",
|
|
@@ -7722,8 +8302,8 @@ function NodeConfigPanel({
|
|
|
7722
8302
|
}
|
|
7723
8303
|
}
|
|
7724
8304
|
),
|
|
7725
|
-
/* @__PURE__ */
|
|
7726
|
-
/* @__PURE__ */
|
|
8305
|
+
/* @__PURE__ */ jsxs19("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: [
|
|
8306
|
+
/* @__PURE__ */ jsx23(
|
|
7727
8307
|
"input",
|
|
7728
8308
|
{
|
|
7729
8309
|
type: "checkbox",
|
|
@@ -7745,8 +8325,8 @@ function NodeConfigPanel({
|
|
|
7745
8325
|
),
|
|
7746
8326
|
"Show Sparkline"
|
|
7747
8327
|
] }),
|
|
7748
|
-
/* @__PURE__ */
|
|
7749
|
-
/* @__PURE__ */
|
|
8328
|
+
/* @__PURE__ */ jsxs19("div", { style: { marginTop: "12px" }, children: [
|
|
8329
|
+
/* @__PURE__ */ jsx23(
|
|
7750
8330
|
"label",
|
|
7751
8331
|
{
|
|
7752
8332
|
style: {
|
|
@@ -7758,10 +8338,10 @@ function NodeConfigPanel({
|
|
|
7758
8338
|
children: "Telemetry Position Offset:"
|
|
7759
8339
|
}
|
|
7760
8340
|
),
|
|
7761
|
-
/* @__PURE__ */
|
|
7762
|
-
/* @__PURE__ */
|
|
7763
|
-
/* @__PURE__ */
|
|
7764
|
-
/* @__PURE__ */
|
|
8341
|
+
/* @__PURE__ */ jsxs19("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: "8px" }, children: [
|
|
8342
|
+
/* @__PURE__ */ jsxs19("div", { children: [
|
|
8343
|
+
/* @__PURE__ */ jsx23("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "X Offset:" }),
|
|
8344
|
+
/* @__PURE__ */ jsx23(
|
|
7765
8345
|
"input",
|
|
7766
8346
|
{
|
|
7767
8347
|
type: "number",
|
|
@@ -7788,9 +8368,9 @@ function NodeConfigPanel({
|
|
|
7788
8368
|
}
|
|
7789
8369
|
)
|
|
7790
8370
|
] }),
|
|
7791
|
-
/* @__PURE__ */
|
|
7792
|
-
/* @__PURE__ */
|
|
7793
|
-
/* @__PURE__ */
|
|
8371
|
+
/* @__PURE__ */ jsxs19("div", { children: [
|
|
8372
|
+
/* @__PURE__ */ jsx23("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "Y Offset:" }),
|
|
8373
|
+
/* @__PURE__ */ jsx23(
|
|
7794
8374
|
"input",
|
|
7795
8375
|
{
|
|
7796
8376
|
type: "number",
|
|
@@ -7818,8 +8398,8 @@ function NodeConfigPanel({
|
|
|
7818
8398
|
)
|
|
7819
8399
|
] })
|
|
7820
8400
|
] }),
|
|
7821
|
-
/* @__PURE__ */
|
|
7822
|
-
/* @__PURE__ */
|
|
8401
|
+
/* @__PURE__ */ jsxs19("div", { style: { marginTop: "16px" }, children: [
|
|
8402
|
+
/* @__PURE__ */ jsx23(
|
|
7823
8403
|
"label",
|
|
7824
8404
|
{
|
|
7825
8405
|
style: {
|
|
@@ -7831,10 +8411,10 @@ function NodeConfigPanel({
|
|
|
7831
8411
|
children: "Display Colors:"
|
|
7832
8412
|
}
|
|
7833
8413
|
),
|
|
7834
|
-
/* @__PURE__ */
|
|
7835
|
-
/* @__PURE__ */
|
|
7836
|
-
/* @__PURE__ */
|
|
7837
|
-
/* @__PURE__ */
|
|
8414
|
+
/* @__PURE__ */ jsxs19("div", { style: { marginBottom: "8px" }, children: [
|
|
8415
|
+
/* @__PURE__ */ jsx23("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "Text Color:" }),
|
|
8416
|
+
/* @__PURE__ */ jsxs19("div", { style: { display: "flex", gap: "8px", alignItems: "center" }, children: [
|
|
8417
|
+
/* @__PURE__ */ jsx23(
|
|
7838
8418
|
"input",
|
|
7839
8419
|
{
|
|
7840
8420
|
type: "color",
|
|
@@ -7860,7 +8440,7 @@ function NodeConfigPanel({
|
|
|
7860
8440
|
}
|
|
7861
8441
|
}
|
|
7862
8442
|
),
|
|
7863
|
-
/* @__PURE__ */
|
|
8443
|
+
/* @__PURE__ */ jsx23(
|
|
7864
8444
|
"input",
|
|
7865
8445
|
{
|
|
7866
8446
|
type: "text",
|
|
@@ -7890,10 +8470,10 @@ function NodeConfigPanel({
|
|
|
7890
8470
|
)
|
|
7891
8471
|
] })
|
|
7892
8472
|
] }),
|
|
7893
|
-
binding.display?.showSparkline && /* @__PURE__ */
|
|
7894
|
-
/* @__PURE__ */
|
|
7895
|
-
/* @__PURE__ */
|
|
7896
|
-
/* @__PURE__ */
|
|
8473
|
+
binding.display?.showSparkline && /* @__PURE__ */ jsxs19("div", { style: { marginBottom: "8px" }, children: [
|
|
8474
|
+
/* @__PURE__ */ jsx23("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "Sparkline Color:" }),
|
|
8475
|
+
/* @__PURE__ */ jsxs19("div", { style: { display: "flex", gap: "8px", alignItems: "center" }, children: [
|
|
8476
|
+
/* @__PURE__ */ jsx23(
|
|
7897
8477
|
"input",
|
|
7898
8478
|
{
|
|
7899
8479
|
type: "color",
|
|
@@ -7919,7 +8499,7 @@ function NodeConfigPanel({
|
|
|
7919
8499
|
}
|
|
7920
8500
|
}
|
|
7921
8501
|
),
|
|
7922
|
-
/* @__PURE__ */
|
|
8502
|
+
/* @__PURE__ */ jsx23(
|
|
7923
8503
|
"input",
|
|
7924
8504
|
{
|
|
7925
8505
|
type: "text",
|
|
@@ -7949,9 +8529,9 @@ function NodeConfigPanel({
|
|
|
7949
8529
|
)
|
|
7950
8530
|
] })
|
|
7951
8531
|
] }),
|
|
7952
|
-
/* @__PURE__ */
|
|
7953
|
-
/* @__PURE__ */
|
|
7954
|
-
/* @__PURE__ */
|
|
8532
|
+
/* @__PURE__ */ jsxs19("div", { style: { marginBottom: "8px" }, children: [
|
|
8533
|
+
/* @__PURE__ */ jsx23("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "Background:" }),
|
|
8534
|
+
/* @__PURE__ */ jsx23(
|
|
7955
8535
|
"input",
|
|
7956
8536
|
{
|
|
7957
8537
|
type: "text",
|
|
@@ -7979,20 +8559,38 @@ function NodeConfigPanel({
|
|
|
7979
8559
|
}
|
|
7980
8560
|
}
|
|
7981
8561
|
),
|
|
7982
|
-
/* @__PURE__ */
|
|
8562
|
+
/* @__PURE__ */ jsx23("div", { style: { fontSize: "0.65rem", color: "#6b7280", marginTop: "2px" }, children: "Use 'status' for status-based color or hex code" })
|
|
7983
8563
|
] })
|
|
7984
8564
|
] }),
|
|
7985
8565
|
" "
|
|
7986
|
-
] })
|
|
8566
|
+
] }),
|
|
8567
|
+
onRemoveTelemetry && /* @__PURE__ */ jsx23(
|
|
8568
|
+
"button",
|
|
8569
|
+
{
|
|
8570
|
+
onClick: onRemoveTelemetry,
|
|
8571
|
+
style: {
|
|
8572
|
+
width: "100%",
|
|
8573
|
+
padding: "6px 8px",
|
|
8574
|
+
marginTop: "8px",
|
|
8575
|
+
borderRadius: "4px",
|
|
8576
|
+
border: "1px solid #ef4444",
|
|
8577
|
+
background: "transparent",
|
|
8578
|
+
color: "#ef4444",
|
|
8579
|
+
fontSize: "0.8125rem",
|
|
8580
|
+
cursor: "pointer"
|
|
8581
|
+
},
|
|
8582
|
+
children: "Remove Telemetry"
|
|
8583
|
+
}
|
|
8584
|
+
)
|
|
7987
8585
|
] })
|
|
7988
8586
|
] }),
|
|
7989
|
-
binding && /* @__PURE__ */
|
|
7990
|
-
/* @__PURE__ */
|
|
8587
|
+
showGenericTelemetry && binding && /* @__PURE__ */ jsxs19("div", { style: { marginBottom: "20px" }, children: [
|
|
8588
|
+
/* @__PURE__ */ jsx23("h3", { style: { fontSize: "0.875rem", fontWeight: 600, marginBottom: "8px" }, children: "Thresholds" }),
|
|
7991
8589
|
["highHigh", "high", "low", "lowLow"].map((key) => {
|
|
7992
8590
|
const label = key === "highHigh" ? "High-High (\u2265)" : key === "high" ? "High (\u2265)" : key === "low" ? "Low (\u2264)" : "Low-Low (\u2264)";
|
|
7993
|
-
return /* @__PURE__ */
|
|
7994
|
-
/* @__PURE__ */
|
|
7995
|
-
/* @__PURE__ */
|
|
8591
|
+
return /* @__PURE__ */ jsxs19("div", { style: { marginBottom: "8px" }, children: [
|
|
8592
|
+
/* @__PURE__ */ jsx23("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: label }),
|
|
8593
|
+
/* @__PURE__ */ jsx23(
|
|
7996
8594
|
"input",
|
|
7997
8595
|
{
|
|
7998
8596
|
type: "number",
|
|
@@ -8016,8 +8614,8 @@ function NodeConfigPanel({
|
|
|
8016
8614
|
] }, key);
|
|
8017
8615
|
})
|
|
8018
8616
|
] }),
|
|
8019
|
-
binding && /* @__PURE__ */
|
|
8020
|
-
/* @__PURE__ */
|
|
8617
|
+
showGenericTelemetry && binding && /* @__PURE__ */ jsxs19("div", { style: { marginBottom: "20px" }, children: [
|
|
8618
|
+
/* @__PURE__ */ jsx23("h3", { style: { fontSize: "0.875rem", fontWeight: 600, marginBottom: "8px" }, children: "Status Colors" }),
|
|
8021
8619
|
["normal", "warning", "alarm", "fault", "off"].map((status) => {
|
|
8022
8620
|
const defaultColors = {
|
|
8023
8621
|
normal: "#10b981",
|
|
@@ -8027,13 +8625,13 @@ function NodeConfigPanel({
|
|
|
8027
8625
|
off: "#6b7280"
|
|
8028
8626
|
};
|
|
8029
8627
|
const label = status === "normal" ? "Normal" : status === "warning" ? "Warning" : status === "alarm" ? "Alarm" : status === "fault" ? "Fault" : "Off";
|
|
8030
|
-
return /* @__PURE__ */
|
|
8031
|
-
/* @__PURE__ */
|
|
8628
|
+
return /* @__PURE__ */ jsxs19("div", { style: { marginBottom: "8px" }, children: [
|
|
8629
|
+
/* @__PURE__ */ jsxs19("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: [
|
|
8032
8630
|
label,
|
|
8033
8631
|
":"
|
|
8034
8632
|
] }),
|
|
8035
|
-
/* @__PURE__ */
|
|
8036
|
-
/* @__PURE__ */
|
|
8633
|
+
/* @__PURE__ */ jsxs19("div", { style: { display: "flex", gap: "8px", alignItems: "center" }, children: [
|
|
8634
|
+
/* @__PURE__ */ jsx23(
|
|
8037
8635
|
"input",
|
|
8038
8636
|
{
|
|
8039
8637
|
type: "color",
|
|
@@ -8054,7 +8652,7 @@ function NodeConfigPanel({
|
|
|
8054
8652
|
}
|
|
8055
8653
|
}
|
|
8056
8654
|
),
|
|
8057
|
-
/* @__PURE__ */
|
|
8655
|
+
/* @__PURE__ */ jsx23(
|
|
8058
8656
|
"input",
|
|
8059
8657
|
{
|
|
8060
8658
|
type: "text",
|
|
@@ -8081,7 +8679,7 @@ function NodeConfigPanel({
|
|
|
8081
8679
|
] }, status);
|
|
8082
8680
|
})
|
|
8083
8681
|
] }),
|
|
8084
|
-
/* @__PURE__ */
|
|
8682
|
+
/* @__PURE__ */ jsx23("div", { style: { marginTop: "20px", paddingTop: "20px", borderTop: "1px solid #cbd5e1" }, children: /* @__PURE__ */ jsx23(
|
|
8085
8683
|
"button",
|
|
8086
8684
|
{
|
|
8087
8685
|
onClick: onRemove,
|
|
@@ -8875,8 +9473,8 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
8875
9473
|
}
|
|
8876
9474
|
|
|
8877
9475
|
// src/components/DeviceConfigPanel/DeviceConfigPanel.tsx
|
|
8878
|
-
import
|
|
8879
|
-
import { Fragment as Fragment9, jsx as
|
|
9476
|
+
import React16, { useState as useState18, useEffect as useEffect14, useMemo, useRef as useRef8 } from "react";
|
|
9477
|
+
import { Fragment as Fragment9, jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
8880
9478
|
function DeviceConfigPanelImpl({
|
|
8881
9479
|
binding,
|
|
8882
9480
|
onClose,
|
|
@@ -8934,7 +9532,7 @@ function DeviceConfigPanelImpl({
|
|
|
8934
9532
|
setCollapsedSections(collapsed);
|
|
8935
9533
|
setBindingId(binding.nodeId);
|
|
8936
9534
|
}
|
|
8937
|
-
|
|
9535
|
+
useEffect14(() => {
|
|
8938
9536
|
const currentTimestamp = binding?.state.lastSaved || 0;
|
|
8939
9537
|
if (binding?.state.lastSaveResult && currentTimestamp !== lastResultTimestampRef.current) {
|
|
8940
9538
|
lastResultTimestampRef.current = currentTimestamp;
|
|
@@ -9042,14 +9640,14 @@ function DeviceConfigPanelImpl({
|
|
|
9042
9640
|
const value = localValues[param.id];
|
|
9043
9641
|
const error = binding.state.errors?.[param.id];
|
|
9044
9642
|
const isDisabled = param.readOnly || param.enabled === false;
|
|
9045
|
-
return /* @__PURE__ */
|
|
9643
|
+
return /* @__PURE__ */ jsxs20(
|
|
9046
9644
|
"div",
|
|
9047
9645
|
{
|
|
9048
9646
|
style: {
|
|
9049
9647
|
marginBottom: spacing.marginBottom
|
|
9050
9648
|
},
|
|
9051
9649
|
children: [
|
|
9052
|
-
/* @__PURE__ */
|
|
9650
|
+
/* @__PURE__ */ jsxs20(
|
|
9053
9651
|
"label",
|
|
9054
9652
|
{
|
|
9055
9653
|
style: {
|
|
@@ -9064,13 +9662,13 @@ function DeviceConfigPanelImpl({
|
|
|
9064
9662
|
},
|
|
9065
9663
|
children: [
|
|
9066
9664
|
param.label,
|
|
9067
|
-
param.required && /* @__PURE__ */
|
|
9068
|
-
param.unit && /* @__PURE__ */
|
|
9665
|
+
param.required && /* @__PURE__ */ jsx24("span", { style: { color: errorColor }, children: " *" }),
|
|
9666
|
+
param.unit && /* @__PURE__ */ jsxs20("span", { style: { color: mutedTextColor, fontWeight: "normal" }, children: [
|
|
9069
9667
|
" (",
|
|
9070
9668
|
param.unit,
|
|
9071
9669
|
")"
|
|
9072
9670
|
] }),
|
|
9073
|
-
param.forced?.active && /* @__PURE__ */
|
|
9671
|
+
param.forced?.active && /* @__PURE__ */ jsx24(
|
|
9074
9672
|
"span",
|
|
9075
9673
|
{
|
|
9076
9674
|
"aria-label": "Forced",
|
|
@@ -9097,7 +9695,7 @@ function DeviceConfigPanelImpl({
|
|
|
9097
9695
|
]
|
|
9098
9696
|
}
|
|
9099
9697
|
),
|
|
9100
|
-
param.forced?.active && param.forced.realValue !== void 0 && /* @__PURE__ */
|
|
9698
|
+
param.forced?.active && param.forced.realValue !== void 0 && /* @__PURE__ */ jsxs20(
|
|
9101
9699
|
"div",
|
|
9102
9700
|
{
|
|
9103
9701
|
style: {
|
|
@@ -9115,7 +9713,7 @@ function DeviceConfigPanelImpl({
|
|
|
9115
9713
|
]
|
|
9116
9714
|
}
|
|
9117
9715
|
),
|
|
9118
|
-
param.description && /* @__PURE__ */
|
|
9716
|
+
param.description && /* @__PURE__ */ jsx24(
|
|
9119
9717
|
"div",
|
|
9120
9718
|
{
|
|
9121
9719
|
style: {
|
|
@@ -9127,7 +9725,7 @@ function DeviceConfigPanelImpl({
|
|
|
9127
9725
|
children: param.description
|
|
9128
9726
|
}
|
|
9129
9727
|
),
|
|
9130
|
-
param.type === "number" && /* @__PURE__ */
|
|
9728
|
+
param.type === "number" && /* @__PURE__ */ jsx24(
|
|
9131
9729
|
"input",
|
|
9132
9730
|
{
|
|
9133
9731
|
type: "number",
|
|
@@ -9151,7 +9749,7 @@ function DeviceConfigPanelImpl({
|
|
|
9151
9749
|
}
|
|
9152
9750
|
}
|
|
9153
9751
|
),
|
|
9154
|
-
param.type === "string" && /* @__PURE__ */
|
|
9752
|
+
param.type === "string" && /* @__PURE__ */ jsx24(
|
|
9155
9753
|
"input",
|
|
9156
9754
|
{
|
|
9157
9755
|
type: "text",
|
|
@@ -9172,7 +9770,7 @@ function DeviceConfigPanelImpl({
|
|
|
9172
9770
|
}
|
|
9173
9771
|
}
|
|
9174
9772
|
),
|
|
9175
|
-
param.type === "boolean" && /* @__PURE__ */
|
|
9773
|
+
param.type === "boolean" && /* @__PURE__ */ jsxs20(
|
|
9176
9774
|
"label",
|
|
9177
9775
|
{
|
|
9178
9776
|
style: {
|
|
@@ -9182,7 +9780,7 @@ function DeviceConfigPanelImpl({
|
|
|
9182
9780
|
cursor: isDisabled ? "not-allowed" : "pointer"
|
|
9183
9781
|
},
|
|
9184
9782
|
children: [
|
|
9185
|
-
/* @__PURE__ */
|
|
9783
|
+
/* @__PURE__ */ jsx24(
|
|
9186
9784
|
"input",
|
|
9187
9785
|
{
|
|
9188
9786
|
type: "checkbox",
|
|
@@ -9196,11 +9794,11 @@ function DeviceConfigPanelImpl({
|
|
|
9196
9794
|
}
|
|
9197
9795
|
}
|
|
9198
9796
|
),
|
|
9199
|
-
/* @__PURE__ */
|
|
9797
|
+
/* @__PURE__ */ jsx24("span", { style: { fontSize: `${fontSize.value}px`, color: textColor }, children: value ? "Enabled" : "Disabled" })
|
|
9200
9798
|
]
|
|
9201
9799
|
}
|
|
9202
9800
|
),
|
|
9203
|
-
param.type === "select" && /* @__PURE__ */
|
|
9801
|
+
param.type === "select" && /* @__PURE__ */ jsx24(
|
|
9204
9802
|
"select",
|
|
9205
9803
|
{
|
|
9206
9804
|
value: value ?? "",
|
|
@@ -9218,10 +9816,10 @@ function DeviceConfigPanelImpl({
|
|
|
9218
9816
|
borderRadius: "2px",
|
|
9219
9817
|
outline: "none"
|
|
9220
9818
|
},
|
|
9221
|
-
children: param.options?.map((option) => /* @__PURE__ */
|
|
9819
|
+
children: param.options?.map((option) => /* @__PURE__ */ jsx24("option", { value: option.value, children: option.label }, option.value))
|
|
9222
9820
|
}
|
|
9223
9821
|
),
|
|
9224
|
-
error && /* @__PURE__ */
|
|
9822
|
+
error && /* @__PURE__ */ jsx24(
|
|
9225
9823
|
"div",
|
|
9226
9824
|
{
|
|
9227
9825
|
style: {
|
|
@@ -9241,7 +9839,7 @@ function DeviceConfigPanelImpl({
|
|
|
9241
9839
|
const renderSection = (section) => {
|
|
9242
9840
|
const params = parametersBySection[section.id] || [];
|
|
9243
9841
|
const isCollapsed = collapsedSections.has(section.id);
|
|
9244
|
-
return /* @__PURE__ */
|
|
9842
|
+
return /* @__PURE__ */ jsxs20(
|
|
9245
9843
|
"div",
|
|
9246
9844
|
{
|
|
9247
9845
|
style: {
|
|
@@ -9251,7 +9849,7 @@ function DeviceConfigPanelImpl({
|
|
|
9251
9849
|
backgroundColor: surfaceColor
|
|
9252
9850
|
},
|
|
9253
9851
|
children: [
|
|
9254
|
-
/* @__PURE__ */
|
|
9852
|
+
/* @__PURE__ */ jsxs20(
|
|
9255
9853
|
"div",
|
|
9256
9854
|
{
|
|
9257
9855
|
onClick: () => section.collapsible && toggleSection(section.id),
|
|
@@ -9264,8 +9862,8 @@ function DeviceConfigPanelImpl({
|
|
|
9264
9862
|
alignItems: "center"
|
|
9265
9863
|
},
|
|
9266
9864
|
children: [
|
|
9267
|
-
/* @__PURE__ */
|
|
9268
|
-
/* @__PURE__ */
|
|
9865
|
+
/* @__PURE__ */ jsxs20("div", { children: [
|
|
9866
|
+
/* @__PURE__ */ jsxs20(
|
|
9269
9867
|
"div",
|
|
9270
9868
|
{
|
|
9271
9869
|
style: {
|
|
@@ -9277,12 +9875,12 @@ function DeviceConfigPanelImpl({
|
|
|
9277
9875
|
letterSpacing: "0.5px"
|
|
9278
9876
|
},
|
|
9279
9877
|
children: [
|
|
9280
|
-
section.icon && /* @__PURE__ */
|
|
9878
|
+
section.icon && /* @__PURE__ */ jsx24("span", { style: { marginRight: "8px" }, children: section.icon }),
|
|
9281
9879
|
section.title
|
|
9282
9880
|
]
|
|
9283
9881
|
}
|
|
9284
9882
|
),
|
|
9285
|
-
section.description && /* @__PURE__ */
|
|
9883
|
+
section.description && /* @__PURE__ */ jsx24(
|
|
9286
9884
|
"div",
|
|
9287
9885
|
{
|
|
9288
9886
|
style: {
|
|
@@ -9295,11 +9893,11 @@ function DeviceConfigPanelImpl({
|
|
|
9295
9893
|
}
|
|
9296
9894
|
)
|
|
9297
9895
|
] }),
|
|
9298
|
-
section.collapsible && /* @__PURE__ */
|
|
9896
|
+
section.collapsible && /* @__PURE__ */ jsx24("span", { style: { fontSize: "16px", color: mutedTextColor }, children: isCollapsed ? "\u25BC" : "\u25B2" })
|
|
9299
9897
|
]
|
|
9300
9898
|
}
|
|
9301
9899
|
),
|
|
9302
|
-
!isCollapsed && /* @__PURE__ */
|
|
9900
|
+
!isCollapsed && /* @__PURE__ */ jsx24("div", { style: { padding: spacing.padding }, children: params.map(renderParameter) })
|
|
9303
9901
|
]
|
|
9304
9902
|
},
|
|
9305
9903
|
section.id
|
|
@@ -9358,9 +9956,9 @@ function DeviceConfigPanelImpl({
|
|
|
9358
9956
|
const showSave = binding.display?.showSave !== false && binding.actions.onSave;
|
|
9359
9957
|
const showReset = binding.display?.showReset !== false && binding.actions.onReset;
|
|
9360
9958
|
const showCancel = binding.display?.showCancel !== false;
|
|
9361
|
-
return /* @__PURE__ */
|
|
9362
|
-
/* @__PURE__ */
|
|
9363
|
-
/* @__PURE__ */
|
|
9959
|
+
return /* @__PURE__ */ jsxs20(Fragment9, { children: [
|
|
9960
|
+
/* @__PURE__ */ jsxs20("div", { style: panelStyle, className: binding.display?.className, children: [
|
|
9961
|
+
/* @__PURE__ */ jsxs20(
|
|
9364
9962
|
"div",
|
|
9365
9963
|
{
|
|
9366
9964
|
style: {
|
|
@@ -9372,8 +9970,8 @@ function DeviceConfigPanelImpl({
|
|
|
9372
9970
|
borderBottom: `2px solid ${borderColor}`
|
|
9373
9971
|
},
|
|
9374
9972
|
children: [
|
|
9375
|
-
/* @__PURE__ */
|
|
9376
|
-
/* @__PURE__ */
|
|
9973
|
+
/* @__PURE__ */ jsxs20("div", { children: [
|
|
9974
|
+
/* @__PURE__ */ jsx24(
|
|
9377
9975
|
"h3",
|
|
9378
9976
|
{
|
|
9379
9977
|
style: {
|
|
@@ -9393,7 +9991,7 @@ function DeviceConfigPanelImpl({
|
|
|
9393
9991
|
children: titleText.length > 25 ? titleText.slice(0, 25) + "..." : titleText
|
|
9394
9992
|
}
|
|
9395
9993
|
),
|
|
9396
|
-
binding.display?.subtitle && /* @__PURE__ */
|
|
9994
|
+
binding.display?.subtitle && /* @__PURE__ */ jsx24(
|
|
9397
9995
|
"div",
|
|
9398
9996
|
{
|
|
9399
9997
|
style: {
|
|
@@ -9406,8 +10004,8 @@ function DeviceConfigPanelImpl({
|
|
|
9406
10004
|
}
|
|
9407
10005
|
)
|
|
9408
10006
|
] }),
|
|
9409
|
-
/* @__PURE__ */
|
|
9410
|
-
showControlsButton && onOpenControls && /* @__PURE__ */
|
|
10007
|
+
/* @__PURE__ */ jsxs20("div", { style: { display: "flex", gap: "8px" }, children: [
|
|
10008
|
+
showControlsButton && onOpenControls && /* @__PURE__ */ jsx24(
|
|
9411
10009
|
"button",
|
|
9412
10010
|
{
|
|
9413
10011
|
onClick: onOpenControls,
|
|
@@ -9430,7 +10028,7 @@ function DeviceConfigPanelImpl({
|
|
|
9430
10028
|
children: "CTRL"
|
|
9431
10029
|
}
|
|
9432
10030
|
),
|
|
9433
|
-
onUndock && /* @__PURE__ */
|
|
10031
|
+
onUndock && /* @__PURE__ */ jsx24(
|
|
9434
10032
|
"button",
|
|
9435
10033
|
{
|
|
9436
10034
|
onClick: onUndock,
|
|
@@ -9451,7 +10049,7 @@ function DeviceConfigPanelImpl({
|
|
|
9451
10049
|
children: undockIcon
|
|
9452
10050
|
}
|
|
9453
10051
|
),
|
|
9454
|
-
/* @__PURE__ */
|
|
10052
|
+
/* @__PURE__ */ jsx24(
|
|
9455
10053
|
"button",
|
|
9456
10054
|
{
|
|
9457
10055
|
onClick: onClose,
|
|
@@ -9474,7 +10072,7 @@ function DeviceConfigPanelImpl({
|
|
|
9474
10072
|
]
|
|
9475
10073
|
}
|
|
9476
10074
|
),
|
|
9477
|
-
binding.state.isDirty && /* @__PURE__ */
|
|
10075
|
+
binding.state.isDirty && /* @__PURE__ */ jsx24(
|
|
9478
10076
|
"div",
|
|
9479
10077
|
{
|
|
9480
10078
|
style: {
|
|
@@ -9489,11 +10087,11 @@ function DeviceConfigPanelImpl({
|
|
|
9489
10087
|
children: "Unsaved changes"
|
|
9490
10088
|
}
|
|
9491
10089
|
),
|
|
9492
|
-
/* @__PURE__ */
|
|
10090
|
+
/* @__PURE__ */ jsx24("div", { style: { flex: 1, overflowY: "auto", marginBottom: spacing.marginBottom }, children: sortedSections.length > 0 ? sortedSections.map(renderSection) : (
|
|
9493
10091
|
/* Render unsectioned parameters */
|
|
9494
|
-
/* @__PURE__ */
|
|
10092
|
+
/* @__PURE__ */ jsx24("div", { children: parametersBySection._unsectioned?.map(renderParameter) })
|
|
9495
10093
|
) }),
|
|
9496
|
-
/* @__PURE__ */
|
|
10094
|
+
/* @__PURE__ */ jsxs20(
|
|
9497
10095
|
"div",
|
|
9498
10096
|
{
|
|
9499
10097
|
style: {
|
|
@@ -9504,7 +10102,7 @@ function DeviceConfigPanelImpl({
|
|
|
9504
10102
|
flexWrap: "wrap"
|
|
9505
10103
|
},
|
|
9506
10104
|
children: [
|
|
9507
|
-
showApply && /* @__PURE__ */
|
|
10105
|
+
showApply && /* @__PURE__ */ jsx24(
|
|
9508
10106
|
"button",
|
|
9509
10107
|
{
|
|
9510
10108
|
onClick: handleApply,
|
|
@@ -9527,7 +10125,7 @@ function DeviceConfigPanelImpl({
|
|
|
9527
10125
|
children: binding.state.isSaving ? "Applying..." : "Apply"
|
|
9528
10126
|
}
|
|
9529
10127
|
),
|
|
9530
|
-
showSave && /* @__PURE__ */
|
|
10128
|
+
showSave && /* @__PURE__ */ jsx24(
|
|
9531
10129
|
"button",
|
|
9532
10130
|
{
|
|
9533
10131
|
onClick: handleSave,
|
|
@@ -9550,7 +10148,7 @@ function DeviceConfigPanelImpl({
|
|
|
9550
10148
|
children: binding.state.isSaving ? "Saving..." : "Save"
|
|
9551
10149
|
}
|
|
9552
10150
|
),
|
|
9553
|
-
showReset && /* @__PURE__ */
|
|
10151
|
+
showReset && /* @__PURE__ */ jsx24(
|
|
9554
10152
|
"button",
|
|
9555
10153
|
{
|
|
9556
10154
|
onClick: handleReset,
|
|
@@ -9573,7 +10171,7 @@ function DeviceConfigPanelImpl({
|
|
|
9573
10171
|
children: "Reset"
|
|
9574
10172
|
}
|
|
9575
10173
|
),
|
|
9576
|
-
showCancel && /* @__PURE__ */
|
|
10174
|
+
showCancel && /* @__PURE__ */ jsx24(
|
|
9577
10175
|
"button",
|
|
9578
10176
|
{
|
|
9579
10177
|
onClick: handleCancel,
|
|
@@ -9600,7 +10198,7 @@ function DeviceConfigPanelImpl({
|
|
|
9600
10198
|
}
|
|
9601
10199
|
)
|
|
9602
10200
|
] }),
|
|
9603
|
-
binding.state.lastSaveResult && showToast && showBuiltInToast && /* @__PURE__ */
|
|
10201
|
+
binding.state.lastSaveResult && showToast && showBuiltInToast && /* @__PURE__ */ jsx24(
|
|
9604
10202
|
"div",
|
|
9605
10203
|
{
|
|
9606
10204
|
style: {
|
|
@@ -9622,10 +10220,10 @@ function DeviceConfigPanelImpl({
|
|
|
9622
10220
|
)
|
|
9623
10221
|
] });
|
|
9624
10222
|
}
|
|
9625
|
-
var DeviceConfigPanel =
|
|
10223
|
+
var DeviceConfigPanel = React16.memo(DeviceConfigPanelImpl);
|
|
9626
10224
|
|
|
9627
10225
|
// src/diagram/hooks/useSimulation.ts
|
|
9628
|
-
import { useEffect as
|
|
10226
|
+
import { useEffect as useEffect15 } from "react";
|
|
9629
10227
|
function useSimulation(telemetry, updateTelemetryBatch, options = {}) {
|
|
9630
10228
|
const {
|
|
9631
10229
|
interval = 2e3,
|
|
@@ -9636,7 +10234,7 @@ function useSimulation(telemetry, updateTelemetryBatch, options = {}) {
|
|
|
9636
10234
|
historyLength = 10,
|
|
9637
10235
|
generateValue
|
|
9638
10236
|
} = options;
|
|
9639
|
-
|
|
10237
|
+
useEffect15(() => {
|
|
9640
10238
|
if (!enabled) return;
|
|
9641
10239
|
const intervalId = setInterval(() => {
|
|
9642
10240
|
const updates = [];
|
|
@@ -9686,6 +10284,7 @@ function useSimulation(telemetry, updateTelemetryBatch, options = {}) {
|
|
|
9686
10284
|
}
|
|
9687
10285
|
export {
|
|
9688
10286
|
Button,
|
|
10287
|
+
COLOR_PRESETS,
|
|
9689
10288
|
CardHeader,
|
|
9690
10289
|
CardUnit,
|
|
9691
10290
|
CardValue,
|
|
@@ -9704,6 +10303,8 @@ export {
|
|
|
9704
10303
|
FooterPanel,
|
|
9705
10304
|
FullscreenContainer,
|
|
9706
10305
|
FullscreenWorkspace,
|
|
10306
|
+
ISA_UNKNOWN,
|
|
10307
|
+
ISA_UNKNOWN_DARK,
|
|
9707
10308
|
LeftPanel,
|
|
9708
10309
|
LeftToggleButton,
|
|
9709
10310
|
LegacyValueEntry,
|
|
@@ -9715,6 +10316,7 @@ export {
|
|
|
9715
10316
|
PanelTabs,
|
|
9716
10317
|
RightPanel,
|
|
9717
10318
|
RightToggleButton,
|
|
10319
|
+
STATUS_LED_APPEARANCE,
|
|
9718
10320
|
SVGArea,
|
|
9719
10321
|
SVGLockedOverlay,
|
|
9720
10322
|
ScrollableSVGWrapper,
|
|
@@ -9725,6 +10327,9 @@ export {
|
|
|
9725
10327
|
ThemeProvider,
|
|
9726
10328
|
ThemeToggle,
|
|
9727
10329
|
TrendLine,
|
|
10330
|
+
UNKNOWN_GLYPH_RING_DASH,
|
|
10331
|
+
UNKNOWN_STATUS_GLYPH_COLOR_VAR,
|
|
10332
|
+
UnknownStatusGlyph,
|
|
9728
10333
|
ValueEntry,
|
|
9729
10334
|
ZoomButton,
|
|
9730
10335
|
ZoomControls,
|
|
@@ -9734,16 +10339,22 @@ export {
|
|
|
9734
10339
|
exampleDiagram,
|
|
9735
10340
|
exportDiagram,
|
|
9736
10341
|
generateRoutePoints,
|
|
10342
|
+
getAppearanceDefaults,
|
|
10343
|
+
getAppearanceSchema,
|
|
9737
10344
|
getAvailableSymbols,
|
|
9738
10345
|
getPortWorldPosition,
|
|
9739
10346
|
getSymbolDefinition,
|
|
9740
10347
|
importDiagram,
|
|
9741
10348
|
mockSymbolLibrary,
|
|
9742
10349
|
nodeHasPort,
|
|
10350
|
+
normalizeDeviceStatus,
|
|
9743
10351
|
overlayStyles,
|
|
10352
|
+
readAppearanceValue,
|
|
9744
10353
|
registerSymbol,
|
|
9745
10354
|
registerSymbols,
|
|
10355
|
+
resolvePresetColor,
|
|
9746
10356
|
resolveStatusColor,
|
|
10357
|
+
useBooleanIndicators,
|
|
9747
10358
|
useDeviceConfigs,
|
|
9748
10359
|
useDeviceControls,
|
|
9749
10360
|
useDrag,
|
|
@@ -9754,6 +10365,7 @@ export {
|
|
|
9754
10365
|
useTelemetryStatus,
|
|
9755
10366
|
useTheme,
|
|
9756
10367
|
useViewBox,
|
|
9757
|
-
validateDiagram
|
|
10368
|
+
validateDiagram,
|
|
10369
|
+
writeAppearanceValue
|
|
9758
10370
|
};
|
|
9759
10371
|
//# sourceMappingURL=index.js.map
|