@procaaso/alphinity-ui-components 1.0.6 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1313 -321
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +305 -1
- package/dist/index.d.ts +305 -1
- package/dist/index.js +1248 -260
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -38,6 +38,7 @@ __export(index_exports, {
|
|
|
38
38
|
ControlPanel: () => ControlPanel,
|
|
39
39
|
DEFAULT_THRESHOLDS: () => DEFAULT_THRESHOLDS,
|
|
40
40
|
DashboardCard: () => DashboardCard,
|
|
41
|
+
DeviceControlPanel: () => DeviceControlPanel,
|
|
41
42
|
DisplayModeToggle: () => DisplayModeToggle,
|
|
42
43
|
EquipmentIndicator: () => EquipmentIndicator,
|
|
43
44
|
EquipmentIndicatorWithSparkline: () => EquipmentIndicatorWithSparkline,
|
|
@@ -49,6 +50,7 @@ __export(index_exports, {
|
|
|
49
50
|
LeftToggleButton: () => LeftToggleButton,
|
|
50
51
|
LegacyValueEntry: () => LegacyValueEntry,
|
|
51
52
|
NodeConfigPanel: () => NodeConfigPanel,
|
|
53
|
+
NodeControlsPanel: () => NodeControlsPanel,
|
|
52
54
|
PIDCanvas: () => PIDCanvas,
|
|
53
55
|
PanelContent: () => PanelContent,
|
|
54
56
|
PanelTabs: () => PanelTabs,
|
|
@@ -68,6 +70,7 @@ __export(index_exports, {
|
|
|
68
70
|
ZoomButton: () => ZoomButton,
|
|
69
71
|
ZoomControls: () => ZoomControls,
|
|
70
72
|
calculateThresholdStatus: () => calculateThresholdStatus,
|
|
73
|
+
createControlBinding: () => createControlBinding,
|
|
71
74
|
exampleDiagram: () => exampleDiagram,
|
|
72
75
|
exportDiagram: () => exportDiagram,
|
|
73
76
|
generateRoutePoints: () => generateRoutePoints,
|
|
@@ -80,6 +83,7 @@ __export(index_exports, {
|
|
|
80
83
|
overlayStyles: () => overlayStyles,
|
|
81
84
|
registerSymbol: () => registerSymbol,
|
|
82
85
|
registerSymbols: () => registerSymbols,
|
|
86
|
+
useDeviceControls: () => useDeviceControls,
|
|
83
87
|
useDrag: () => useDrag,
|
|
84
88
|
useKeyboardShortcuts: () => useKeyboardShortcuts,
|
|
85
89
|
useSelection: () => useSelection,
|
|
@@ -801,14 +805,721 @@ var StatusIndicator = ({
|
|
|
801
805
|
] });
|
|
802
806
|
};
|
|
803
807
|
|
|
808
|
+
// src/components/NodeControlsPanel/NodeControlsPanel.tsx
|
|
809
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
810
|
+
var NodeControlsPanel = ({
|
|
811
|
+
config,
|
|
812
|
+
onClose,
|
|
813
|
+
position = "bottom",
|
|
814
|
+
touchOptimized = true,
|
|
815
|
+
className = "",
|
|
816
|
+
style,
|
|
817
|
+
...props
|
|
818
|
+
}) => {
|
|
819
|
+
if (!config) return null;
|
|
820
|
+
const isBottom = position === "bottom";
|
|
821
|
+
const touchClass = touchOptimized ? "touch-optimized" : "";
|
|
822
|
+
const containerStyle = {
|
|
823
|
+
position: "fixed",
|
|
824
|
+
zIndex: 9999,
|
|
825
|
+
background: "white",
|
|
826
|
+
boxShadow: "0 -4px 16px rgba(0, 0, 0, 0.15)",
|
|
827
|
+
borderRadius: isBottom ? "16px 16px 0 0" : "0",
|
|
828
|
+
animation: isBottom ? "slideUp 0.3s ease-out" : "slideInRight 0.3s ease-out",
|
|
829
|
+
display: "flex",
|
|
830
|
+
flexDirection: "column",
|
|
831
|
+
...isBottom ? {
|
|
832
|
+
left: 0,
|
|
833
|
+
right: 0,
|
|
834
|
+
bottom: 0,
|
|
835
|
+
maxHeight: "70vh",
|
|
836
|
+
borderTop: "1px solid #e5e7eb"
|
|
837
|
+
} : {
|
|
838
|
+
right: 0,
|
|
839
|
+
top: 0,
|
|
840
|
+
bottom: 0,
|
|
841
|
+
width: touchOptimized ? "400px" : "320px",
|
|
842
|
+
borderLeft: "1px solid #e5e7eb"
|
|
843
|
+
},
|
|
844
|
+
...style
|
|
845
|
+
};
|
|
846
|
+
const headerStyle = {
|
|
847
|
+
display: "flex",
|
|
848
|
+
alignItems: "center",
|
|
849
|
+
justifyContent: "space-between",
|
|
850
|
+
padding: touchOptimized ? "1.25rem 1.5rem" : "1rem",
|
|
851
|
+
borderBottom: "2px solid #e5e7eb",
|
|
852
|
+
background: "#f9fafb",
|
|
853
|
+
flexShrink: 0
|
|
854
|
+
};
|
|
855
|
+
const titleStyle = {
|
|
856
|
+
margin: 0,
|
|
857
|
+
fontSize: touchOptimized ? "1.5rem" : "1.25rem",
|
|
858
|
+
fontWeight: 600,
|
|
859
|
+
color: "#111827"
|
|
860
|
+
};
|
|
861
|
+
const closeButtonStyle = {
|
|
862
|
+
background: "#ef4444",
|
|
863
|
+
color: "white",
|
|
864
|
+
border: "none",
|
|
865
|
+
borderRadius: "8px",
|
|
866
|
+
width: touchOptimized ? "56px" : "44px",
|
|
867
|
+
height: touchOptimized ? "56px" : "44px",
|
|
868
|
+
fontSize: touchOptimized ? "1.75rem" : "1.5rem",
|
|
869
|
+
fontWeight: "bold",
|
|
870
|
+
cursor: "pointer",
|
|
871
|
+
display: "flex",
|
|
872
|
+
alignItems: "center",
|
|
873
|
+
justifyContent: "center",
|
|
874
|
+
transition: "all 0.2s ease",
|
|
875
|
+
flexShrink: 0
|
|
876
|
+
};
|
|
877
|
+
const contentStyle = {
|
|
878
|
+
padding: touchOptimized ? "1.5rem" : "1rem",
|
|
879
|
+
overflowY: "auto",
|
|
880
|
+
flex: 1
|
|
881
|
+
};
|
|
882
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
883
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
884
|
+
"div",
|
|
885
|
+
{
|
|
886
|
+
style: {
|
|
887
|
+
position: "fixed",
|
|
888
|
+
inset: 0,
|
|
889
|
+
background: "rgba(0, 0, 0, 0.3)",
|
|
890
|
+
zIndex: 9998,
|
|
891
|
+
animation: "fadeIn 0.3s ease-out"
|
|
892
|
+
},
|
|
893
|
+
onClick: onClose
|
|
894
|
+
}
|
|
895
|
+
),
|
|
896
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
897
|
+
"div",
|
|
898
|
+
{
|
|
899
|
+
className: `node-controls-panel ${touchClass} ${className}`.trim(),
|
|
900
|
+
style: containerStyle,
|
|
901
|
+
...props,
|
|
902
|
+
children: [
|
|
903
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: headerStyle, children: [
|
|
904
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h2", { style: titleStyle, children: config.title }),
|
|
905
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
906
|
+
"button",
|
|
907
|
+
{
|
|
908
|
+
style: closeButtonStyle,
|
|
909
|
+
onClick: onClose,
|
|
910
|
+
onMouseEnter: (e) => {
|
|
911
|
+
e.currentTarget.style.background = "#dc2626";
|
|
912
|
+
e.currentTarget.style.transform = "scale(1.05)";
|
|
913
|
+
},
|
|
914
|
+
onMouseLeave: (e) => {
|
|
915
|
+
e.currentTarget.style.background = "#ef4444";
|
|
916
|
+
e.currentTarget.style.transform = "scale(1)";
|
|
917
|
+
},
|
|
918
|
+
"aria-label": "Close",
|
|
919
|
+
children: "\u2715"
|
|
920
|
+
}
|
|
921
|
+
)
|
|
922
|
+
] }),
|
|
923
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: contentStyle, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
924
|
+
ControlPanel,
|
|
925
|
+
{
|
|
926
|
+
title: config.nodeId,
|
|
927
|
+
selectedMode: config.currentMode,
|
|
928
|
+
modeOptions: config.modes,
|
|
929
|
+
onModeChange: config.onModeChange,
|
|
930
|
+
setpointValue: config.setpoint,
|
|
931
|
+
onSetpointChange: config.onSetpointChange,
|
|
932
|
+
secondSetpointValue: config.secondSetpoint,
|
|
933
|
+
onSecondSetpointChange: config.onSecondSetpointChange,
|
|
934
|
+
modeConfigs: config.modeConfigs,
|
|
935
|
+
status: config.status,
|
|
936
|
+
setpointReadOnly: config.readOnly,
|
|
937
|
+
showStartStopButtons: !!(config.onStart || config.onStop),
|
|
938
|
+
isRunning: config.isRunning,
|
|
939
|
+
onStart: config.onStart,
|
|
940
|
+
onStop: config.onStop,
|
|
941
|
+
startButtonText: config.startButtonText,
|
|
942
|
+
stopButtonText: config.stopButtonText,
|
|
943
|
+
size: touchOptimized ? "large" : "medium"
|
|
944
|
+
}
|
|
945
|
+
) })
|
|
946
|
+
]
|
|
947
|
+
}
|
|
948
|
+
),
|
|
949
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("style", { children: `
|
|
950
|
+
@keyframes slideUp {
|
|
951
|
+
from {
|
|
952
|
+
transform: translateY(100%);
|
|
953
|
+
opacity: 0;
|
|
954
|
+
}
|
|
955
|
+
to {
|
|
956
|
+
transform: translateY(0);
|
|
957
|
+
opacity: 1;
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
@keyframes slideInRight {
|
|
962
|
+
from {
|
|
963
|
+
transform: translateX(100%);
|
|
964
|
+
opacity: 0;
|
|
965
|
+
}
|
|
966
|
+
to {
|
|
967
|
+
transform: translateX(0);
|
|
968
|
+
opacity: 1;
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
@keyframes fadeIn {
|
|
973
|
+
from {
|
|
974
|
+
opacity: 0;
|
|
975
|
+
}
|
|
976
|
+
to {
|
|
977
|
+
opacity: 1;
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
.node-controls-panel.touch-optimized button {
|
|
982
|
+
min-height: 56px;
|
|
983
|
+
font-size: 1.125rem;
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
.node-controls-panel.touch-optimized input {
|
|
987
|
+
min-height: 56px;
|
|
988
|
+
font-size: 1.125rem;
|
|
989
|
+
}
|
|
990
|
+
` })
|
|
991
|
+
] });
|
|
992
|
+
};
|
|
993
|
+
|
|
994
|
+
// src/components/DeviceControlPanel/DeviceControlPanel.tsx
|
|
995
|
+
var import_react5 = require("react");
|
|
996
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
997
|
+
function DeviceControlPanel({
|
|
998
|
+
binding,
|
|
999
|
+
onClose,
|
|
1000
|
+
position = "bottom",
|
|
1001
|
+
touchOptimized = true,
|
|
1002
|
+
onModeChange,
|
|
1003
|
+
onParameterChange,
|
|
1004
|
+
onStart,
|
|
1005
|
+
onStop,
|
|
1006
|
+
onCustomAction
|
|
1007
|
+
}) {
|
|
1008
|
+
const [localParameterValues, setLocalParameterValues] = (0, import_react5.useState)({});
|
|
1009
|
+
(0, import_react5.useEffect)(() => {
|
|
1010
|
+
if (binding) {
|
|
1011
|
+
const currentParams2 = binding.parameters[binding.state.currentMode] || [];
|
|
1012
|
+
const values = {};
|
|
1013
|
+
currentParams2.forEach((param) => {
|
|
1014
|
+
values[param.id] = param.value;
|
|
1015
|
+
});
|
|
1016
|
+
setLocalParameterValues(values);
|
|
1017
|
+
}
|
|
1018
|
+
}, [binding, binding?.state.currentMode]);
|
|
1019
|
+
if (!binding) return null;
|
|
1020
|
+
const currentMode = binding.state.currentMode;
|
|
1021
|
+
const currentParams = binding.parameters[currentMode] || [];
|
|
1022
|
+
const touchSize = touchOptimized ? 56 : 40;
|
|
1023
|
+
const backgroundColor = binding.theme?.backgroundColor || "#edeeef";
|
|
1024
|
+
const surfaceColor = "#f5f6f7";
|
|
1025
|
+
const borderColor = "#d2d2d2";
|
|
1026
|
+
const textColor = binding.theme?.textColor || "#000000";
|
|
1027
|
+
const mutedTextColor = "#666666";
|
|
1028
|
+
const selectedColor = "#b4d0fe";
|
|
1029
|
+
const statusColors = {
|
|
1030
|
+
normal: binding.theme?.statusColors?.normal || "#888888",
|
|
1031
|
+
// Gray (no alarm)
|
|
1032
|
+
warning: binding.theme?.statusColors?.warning || "#FFD700",
|
|
1033
|
+
// Yellow
|
|
1034
|
+
alarm: binding.theme?.statusColors?.alarm || "#FF0000",
|
|
1035
|
+
// Red
|
|
1036
|
+
fault: binding.theme?.statusColors?.fault || "#FF0000",
|
|
1037
|
+
// Red
|
|
1038
|
+
off: binding.theme?.statusColors?.off || "#666666",
|
|
1039
|
+
// Dark gray
|
|
1040
|
+
starting: binding.theme?.statusColors?.starting || "#90EE90",
|
|
1041
|
+
// Light green
|
|
1042
|
+
stopping: binding.theme?.statusColors?.stopping || "#FFD700"
|
|
1043
|
+
// Yellow
|
|
1044
|
+
};
|
|
1045
|
+
const statusColor = statusColors[binding.state.status || "normal"];
|
|
1046
|
+
const handleModeChange = (mode) => {
|
|
1047
|
+
onModeChange?.(mode);
|
|
1048
|
+
};
|
|
1049
|
+
const handleParameterCommit = (parameterId, value) => {
|
|
1050
|
+
onParameterChange?.(parameterId, value);
|
|
1051
|
+
};
|
|
1052
|
+
const handleParameterInput = (parameterId, value) => {
|
|
1053
|
+
setLocalParameterValues((prev) => ({ ...prev, [parameterId]: value }));
|
|
1054
|
+
};
|
|
1055
|
+
const panelStyle = {
|
|
1056
|
+
position: "fixed",
|
|
1057
|
+
...position === "bottom" ? {
|
|
1058
|
+
bottom: 0,
|
|
1059
|
+
left: 0,
|
|
1060
|
+
right: 0,
|
|
1061
|
+
animation: "slideUp 0.3s ease-out"
|
|
1062
|
+
} : {
|
|
1063
|
+
right: 0,
|
|
1064
|
+
top: 0,
|
|
1065
|
+
bottom: 0,
|
|
1066
|
+
width: "400px",
|
|
1067
|
+
animation: "slideIn 0.3s ease-out"
|
|
1068
|
+
},
|
|
1069
|
+
backgroundColor,
|
|
1070
|
+
color: textColor,
|
|
1071
|
+
borderRadius: position === "bottom" ? "8px 8px 0 0" : "8px 0 0 8px",
|
|
1072
|
+
boxShadow: "none",
|
|
1073
|
+
border: `2px solid ${borderColor}`,
|
|
1074
|
+
padding: "20px",
|
|
1075
|
+
zIndex: 9999,
|
|
1076
|
+
maxHeight: position === "bottom" ? "70vh" : "100vh",
|
|
1077
|
+
overflowY: "auto",
|
|
1078
|
+
...binding.display?.style
|
|
1079
|
+
};
|
|
1080
|
+
const titleText = binding.display?.title || binding.deviceName || binding.tag || binding.nodeId;
|
|
1081
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_jsx_runtime8.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: panelStyle, className: binding.display?.className, children: [
|
|
1082
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1083
|
+
"div",
|
|
1084
|
+
{
|
|
1085
|
+
style: {
|
|
1086
|
+
display: "flex",
|
|
1087
|
+
justifyContent: "space-between",
|
|
1088
|
+
alignItems: "center",
|
|
1089
|
+
marginBottom: "16px",
|
|
1090
|
+
paddingBottom: "12px",
|
|
1091
|
+
borderBottom: `2px solid ${borderColor}`
|
|
1092
|
+
},
|
|
1093
|
+
children: [
|
|
1094
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
|
|
1095
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1096
|
+
"h3",
|
|
1097
|
+
{
|
|
1098
|
+
style: {
|
|
1099
|
+
margin: 0,
|
|
1100
|
+
fontSize: "14px",
|
|
1101
|
+
fontWeight: 600,
|
|
1102
|
+
fontFamily: "Arial, sans-serif",
|
|
1103
|
+
letterSpacing: "0.5px",
|
|
1104
|
+
textTransform: "uppercase",
|
|
1105
|
+
color: textColor
|
|
1106
|
+
},
|
|
1107
|
+
children: titleText
|
|
1108
|
+
}
|
|
1109
|
+
),
|
|
1110
|
+
binding.deviceType && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1111
|
+
"div",
|
|
1112
|
+
{
|
|
1113
|
+
style: {
|
|
1114
|
+
fontSize: "11px",
|
|
1115
|
+
color: mutedTextColor,
|
|
1116
|
+
marginTop: "4px",
|
|
1117
|
+
fontFamily: "Arial, sans-serif"
|
|
1118
|
+
},
|
|
1119
|
+
children: binding.deviceType
|
|
1120
|
+
}
|
|
1121
|
+
)
|
|
1122
|
+
] }),
|
|
1123
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1124
|
+
"button",
|
|
1125
|
+
{
|
|
1126
|
+
onClick: onClose,
|
|
1127
|
+
style: {
|
|
1128
|
+
width: touchSize * 0.7,
|
|
1129
|
+
height: touchSize * 0.7,
|
|
1130
|
+
backgroundColor: surfaceColor,
|
|
1131
|
+
color: textColor,
|
|
1132
|
+
border: `2px solid ${borderColor}`,
|
|
1133
|
+
borderRadius: "2px",
|
|
1134
|
+
fontSize: "18px",
|
|
1135
|
+
cursor: "pointer",
|
|
1136
|
+
fontWeight: "bold",
|
|
1137
|
+
fontFamily: "Arial, sans-serif"
|
|
1138
|
+
},
|
|
1139
|
+
children: "\xD7"
|
|
1140
|
+
}
|
|
1141
|
+
)
|
|
1142
|
+
]
|
|
1143
|
+
}
|
|
1144
|
+
),
|
|
1145
|
+
binding.state.status && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1146
|
+
"div",
|
|
1147
|
+
{
|
|
1148
|
+
style: {
|
|
1149
|
+
display: "flex",
|
|
1150
|
+
alignItems: "center",
|
|
1151
|
+
gap: "12px",
|
|
1152
|
+
padding: "10px 12px",
|
|
1153
|
+
backgroundColor: surfaceColor,
|
|
1154
|
+
border: `1px solid ${borderColor}`,
|
|
1155
|
+
borderRadius: "6px",
|
|
1156
|
+
marginBottom: "16px"
|
|
1157
|
+
},
|
|
1158
|
+
children: [
|
|
1159
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1160
|
+
"div",
|
|
1161
|
+
{
|
|
1162
|
+
style: {
|
|
1163
|
+
width: "10px",
|
|
1164
|
+
height: "10px",
|
|
1165
|
+
borderRadius: "50%",
|
|
1166
|
+
backgroundColor: statusColor,
|
|
1167
|
+
border: "1px solid #333"
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
),
|
|
1171
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { flex: 1 }, children: [
|
|
1172
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1173
|
+
"div",
|
|
1174
|
+
{
|
|
1175
|
+
style: {
|
|
1176
|
+
fontWeight: 600,
|
|
1177
|
+
textTransform: "uppercase",
|
|
1178
|
+
fontSize: "11px",
|
|
1179
|
+
fontFamily: "Arial, sans-serif",
|
|
1180
|
+
letterSpacing: "0.5px",
|
|
1181
|
+
color: textColor
|
|
1182
|
+
},
|
|
1183
|
+
children: binding.state.status
|
|
1184
|
+
}
|
|
1185
|
+
),
|
|
1186
|
+
binding.state.statusMessage && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1187
|
+
"div",
|
|
1188
|
+
{
|
|
1189
|
+
style: {
|
|
1190
|
+
fontSize: "10px",
|
|
1191
|
+
color: mutedTextColor,
|
|
1192
|
+
marginTop: "2px",
|
|
1193
|
+
fontFamily: "Arial, sans-serif"
|
|
1194
|
+
},
|
|
1195
|
+
children: binding.state.statusMessage
|
|
1196
|
+
}
|
|
1197
|
+
)
|
|
1198
|
+
] }),
|
|
1199
|
+
binding.state.isRunning !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1200
|
+
"div",
|
|
1201
|
+
{
|
|
1202
|
+
style: {
|
|
1203
|
+
padding: "4px 10px",
|
|
1204
|
+
backgroundColor: binding.state.isRunning ? selectedColor : surfaceColor,
|
|
1205
|
+
border: `1px solid ${borderColor}`,
|
|
1206
|
+
borderRadius: "2px",
|
|
1207
|
+
fontSize: "10px",
|
|
1208
|
+
fontWeight: 600,
|
|
1209
|
+
fontFamily: "Arial, sans-serif",
|
|
1210
|
+
letterSpacing: "0.5px",
|
|
1211
|
+
color: textColor
|
|
1212
|
+
},
|
|
1213
|
+
children: binding.state.isRunning ? "RUNNING" : "STOPPED"
|
|
1214
|
+
}
|
|
1215
|
+
)
|
|
1216
|
+
]
|
|
1217
|
+
}
|
|
1218
|
+
),
|
|
1219
|
+
binding.display?.showModeSelector !== false && binding.modes.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { marginBottom: "16px" }, children: [
|
|
1220
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1221
|
+
"label",
|
|
1222
|
+
{
|
|
1223
|
+
style: {
|
|
1224
|
+
display: "block",
|
|
1225
|
+
marginBottom: "8px",
|
|
1226
|
+
fontSize: "11px",
|
|
1227
|
+
fontWeight: 600,
|
|
1228
|
+
textTransform: "uppercase",
|
|
1229
|
+
letterSpacing: "0.5px",
|
|
1230
|
+
fontFamily: "Arial, sans-serif",
|
|
1231
|
+
color: mutedTextColor
|
|
1232
|
+
},
|
|
1233
|
+
children: "Mode"
|
|
1234
|
+
}
|
|
1235
|
+
),
|
|
1236
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { display: "flex", gap: "6px", flexWrap: "wrap" }, children: binding.modes.map((mode) => {
|
|
1237
|
+
const isSelected = mode.value === currentMode;
|
|
1238
|
+
const isEnabled = mode.enabled !== false;
|
|
1239
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1240
|
+
"button",
|
|
1241
|
+
{
|
|
1242
|
+
onClick: () => isEnabled && handleModeChange(mode.value),
|
|
1243
|
+
disabled: !isEnabled,
|
|
1244
|
+
style: {
|
|
1245
|
+
flex: 1,
|
|
1246
|
+
minWidth: "80px",
|
|
1247
|
+
height: touchSize,
|
|
1248
|
+
backgroundColor: isSelected ? selectedColor : surfaceColor,
|
|
1249
|
+
color: isSelected ? "#000000" : textColor,
|
|
1250
|
+
border: `1px solid ${isSelected ? "#b4d0fe" : borderColor}`,
|
|
1251
|
+
borderRadius: "6px",
|
|
1252
|
+
fontSize: "11px",
|
|
1253
|
+
fontWeight: 600,
|
|
1254
|
+
fontFamily: "Arial, sans-serif",
|
|
1255
|
+
letterSpacing: "0.5px",
|
|
1256
|
+
textTransform: "uppercase",
|
|
1257
|
+
cursor: isEnabled ? "pointer" : "not-allowed",
|
|
1258
|
+
opacity: isEnabled ? 1 : 0.4
|
|
1259
|
+
},
|
|
1260
|
+
children: mode.label
|
|
1261
|
+
},
|
|
1262
|
+
mode.value
|
|
1263
|
+
);
|
|
1264
|
+
}) })
|
|
1265
|
+
] }),
|
|
1266
|
+
currentParams.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { marginBottom: "16px" }, children: [
|
|
1267
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1268
|
+
"label",
|
|
1269
|
+
{
|
|
1270
|
+
style: {
|
|
1271
|
+
display: "block",
|
|
1272
|
+
marginBottom: "8px",
|
|
1273
|
+
fontSize: "11px",
|
|
1274
|
+
fontWeight: 600,
|
|
1275
|
+
textTransform: "uppercase",
|
|
1276
|
+
letterSpacing: "0.5px",
|
|
1277
|
+
fontFamily: "Arial, sans-serif",
|
|
1278
|
+
color: mutedTextColor
|
|
1279
|
+
},
|
|
1280
|
+
children: "Parameters"
|
|
1281
|
+
}
|
|
1282
|
+
),
|
|
1283
|
+
currentParams.map((param) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1284
|
+
"div",
|
|
1285
|
+
{
|
|
1286
|
+
style: {
|
|
1287
|
+
marginBottom: "10px",
|
|
1288
|
+
padding: "10px",
|
|
1289
|
+
backgroundColor: surfaceColor,
|
|
1290
|
+
border: `1px solid ${borderColor}`,
|
|
1291
|
+
borderRadius: "6px"
|
|
1292
|
+
},
|
|
1293
|
+
children: [
|
|
1294
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1295
|
+
"div",
|
|
1296
|
+
{
|
|
1297
|
+
style: { display: "flex", justifyContent: "space-between", marginBottom: "8px" },
|
|
1298
|
+
children: [
|
|
1299
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1300
|
+
"span",
|
|
1301
|
+
{
|
|
1302
|
+
style: {
|
|
1303
|
+
fontSize: "11px",
|
|
1304
|
+
fontWeight: 600,
|
|
1305
|
+
textTransform: "uppercase",
|
|
1306
|
+
letterSpacing: "0.5px",
|
|
1307
|
+
fontFamily: "Arial, sans-serif",
|
|
1308
|
+
color: mutedTextColor
|
|
1309
|
+
},
|
|
1310
|
+
children: param.label
|
|
1311
|
+
}
|
|
1312
|
+
),
|
|
1313
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1314
|
+
"span",
|
|
1315
|
+
{
|
|
1316
|
+
style: {
|
|
1317
|
+
fontSize: "13px",
|
|
1318
|
+
fontWeight: 700,
|
|
1319
|
+
fontFamily: "Arial, sans-serif",
|
|
1320
|
+
color: textColor
|
|
1321
|
+
},
|
|
1322
|
+
children: [
|
|
1323
|
+
localParameterValues[param.id] ?? param.value,
|
|
1324
|
+
" ",
|
|
1325
|
+
param.unit && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { color: mutedTextColor, fontSize: "10px", fontWeight: 600 }, children: param.unit })
|
|
1326
|
+
]
|
|
1327
|
+
}
|
|
1328
|
+
)
|
|
1329
|
+
]
|
|
1330
|
+
}
|
|
1331
|
+
),
|
|
1332
|
+
param.type === "boolean" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1333
|
+
"button",
|
|
1334
|
+
{
|
|
1335
|
+
onClick: () => {
|
|
1336
|
+
const newValue = !localParameterValues[param.id];
|
|
1337
|
+
handleParameterInput(param.id, newValue);
|
|
1338
|
+
handleParameterCommit(param.id, newValue);
|
|
1339
|
+
},
|
|
1340
|
+
disabled: param.readOnly,
|
|
1341
|
+
style: {
|
|
1342
|
+
width: "100%",
|
|
1343
|
+
height: touchSize,
|
|
1344
|
+
backgroundColor: localParameterValues[param.id] ? "#3f3f46" : surfaceColor,
|
|
1345
|
+
color: localParameterValues[param.id] ? textColor : mutedTextColor,
|
|
1346
|
+
border: `1px solid ${localParameterValues[param.id] ? "#52525b" : borderColor}`,
|
|
1347
|
+
borderRadius: "4px",
|
|
1348
|
+
fontSize: "12px",
|
|
1349
|
+
fontWeight: 600,
|
|
1350
|
+
fontFamily: "monospace",
|
|
1351
|
+
letterSpacing: "0.5px",
|
|
1352
|
+
cursor: param.readOnly ? "not-allowed" : "pointer",
|
|
1353
|
+
transition: "all 0.15s"
|
|
1354
|
+
},
|
|
1355
|
+
children: localParameterValues[param.id] ? "ON" : "OFF"
|
|
1356
|
+
}
|
|
1357
|
+
) : param.type === "select" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1358
|
+
"select",
|
|
1359
|
+
{
|
|
1360
|
+
value: localParameterValues[param.id] || param.value,
|
|
1361
|
+
onChange: (e) => {
|
|
1362
|
+
handleParameterInput(param.id, e.target.value);
|
|
1363
|
+
handleParameterCommit(param.id, e.target.value);
|
|
1364
|
+
},
|
|
1365
|
+
disabled: param.readOnly,
|
|
1366
|
+
style: {
|
|
1367
|
+
width: "100%",
|
|
1368
|
+
height: touchSize,
|
|
1369
|
+
backgroundColor: surfaceColor,
|
|
1370
|
+
color: textColor,
|
|
1371
|
+
border: `1px solid ${borderColor}`,
|
|
1372
|
+
borderRadius: "4px",
|
|
1373
|
+
padding: "0 12px",
|
|
1374
|
+
fontSize: "12px",
|
|
1375
|
+
fontFamily: "monospace",
|
|
1376
|
+
cursor: "pointer"
|
|
1377
|
+
},
|
|
1378
|
+
children: param.options?.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: opt.value, children: opt.label }, opt.value))
|
|
1379
|
+
}
|
|
1380
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1381
|
+
"input",
|
|
1382
|
+
{
|
|
1383
|
+
type: param.type === "number" ? "number" : "text",
|
|
1384
|
+
value: localParameterValues[param.id] ?? param.value,
|
|
1385
|
+
onChange: (e) => handleParameterInput(
|
|
1386
|
+
param.id,
|
|
1387
|
+
param.type === "number" ? +e.target.value : e.target.value
|
|
1388
|
+
),
|
|
1389
|
+
onBlur: () => handleParameterCommit(param.id, localParameterValues[param.id]),
|
|
1390
|
+
disabled: param.readOnly,
|
|
1391
|
+
min: param.min,
|
|
1392
|
+
max: param.max,
|
|
1393
|
+
step: param.step,
|
|
1394
|
+
style: {
|
|
1395
|
+
width: "100%",
|
|
1396
|
+
height: touchSize,
|
|
1397
|
+
backgroundColor: "#ffffff",
|
|
1398
|
+
color: textColor,
|
|
1399
|
+
border: `1px solid ${borderColor}`,
|
|
1400
|
+
borderRadius: "6px",
|
|
1401
|
+
padding: "0 12px",
|
|
1402
|
+
fontSize: "14px",
|
|
1403
|
+
fontFamily: "Arial, sans-serif",
|
|
1404
|
+
fontWeight: 600
|
|
1405
|
+
}
|
|
1406
|
+
}
|
|
1407
|
+
)
|
|
1408
|
+
]
|
|
1409
|
+
},
|
|
1410
|
+
param.id
|
|
1411
|
+
))
|
|
1412
|
+
] }),
|
|
1413
|
+
binding.display?.showStartStop !== false && (binding.capabilities?.canStart || binding.capabilities?.canStop) && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { display: "flex", gap: "8px", marginBottom: "16px" }, children: [
|
|
1414
|
+
binding.capabilities?.canStart && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1415
|
+
"button",
|
|
1416
|
+
{
|
|
1417
|
+
onClick: onStart,
|
|
1418
|
+
disabled: binding.state.isRunning,
|
|
1419
|
+
style: {
|
|
1420
|
+
flex: 1,
|
|
1421
|
+
height: touchSize,
|
|
1422
|
+
backgroundColor: binding.state.isRunning ? "#a3a3a3" : "#10b981",
|
|
1423
|
+
color: "#ffffff",
|
|
1424
|
+
border: "none",
|
|
1425
|
+
borderRadius: "6px",
|
|
1426
|
+
fontSize: "12px",
|
|
1427
|
+
fontWeight: 700,
|
|
1428
|
+
fontFamily: "Arial, sans-serif",
|
|
1429
|
+
letterSpacing: "0.5px",
|
|
1430
|
+
cursor: binding.state.isRunning ? "not-allowed" : "pointer",
|
|
1431
|
+
opacity: binding.state.isRunning ? 0.5 : 1
|
|
1432
|
+
},
|
|
1433
|
+
children: "START"
|
|
1434
|
+
}
|
|
1435
|
+
),
|
|
1436
|
+
binding.capabilities?.canStop && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1437
|
+
"button",
|
|
1438
|
+
{
|
|
1439
|
+
onClick: onStop,
|
|
1440
|
+
disabled: !binding.state.isRunning,
|
|
1441
|
+
style: {
|
|
1442
|
+
flex: 1,
|
|
1443
|
+
height: touchSize,
|
|
1444
|
+
backgroundColor: !binding.state.isRunning ? "#a3a3a3" : "#ef4444",
|
|
1445
|
+
color: "#ffffff",
|
|
1446
|
+
border: "none",
|
|
1447
|
+
borderRadius: "6px",
|
|
1448
|
+
fontSize: "12px",
|
|
1449
|
+
fontWeight: 700,
|
|
1450
|
+
fontFamily: "Arial, sans-serif",
|
|
1451
|
+
letterSpacing: "0.5px",
|
|
1452
|
+
cursor: !binding.state.isRunning ? "not-allowed" : "pointer",
|
|
1453
|
+
opacity: !binding.state.isRunning ? 0.5 : 1
|
|
1454
|
+
},
|
|
1455
|
+
children: "STOP"
|
|
1456
|
+
}
|
|
1457
|
+
)
|
|
1458
|
+
] }),
|
|
1459
|
+
binding.capabilities?.customActions && binding.capabilities.customActions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { display: "flex", flexWrap: "wrap", gap: "8px" }, children: binding.capabilities.customActions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1460
|
+
"button",
|
|
1461
|
+
{
|
|
1462
|
+
onClick: () => onCustomAction?.(action.id),
|
|
1463
|
+
style: {
|
|
1464
|
+
flex: 1,
|
|
1465
|
+
minWidth: "120px",
|
|
1466
|
+
height: touchSize,
|
|
1467
|
+
backgroundColor: surfaceColor,
|
|
1468
|
+
color: textColor,
|
|
1469
|
+
border: `1px solid ${borderColor}`,
|
|
1470
|
+
borderRadius: "6px",
|
|
1471
|
+
fontSize: "11px",
|
|
1472
|
+
fontWeight: 600,
|
|
1473
|
+
fontFamily: "monospace",
|
|
1474
|
+
letterSpacing: "0.5px",
|
|
1475
|
+
textTransform: "uppercase",
|
|
1476
|
+
cursor: "pointer",
|
|
1477
|
+
transition: "all 0.15s"
|
|
1478
|
+
},
|
|
1479
|
+
children: [
|
|
1480
|
+
action.icon && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { marginRight: "6px" }, children: action.icon }),
|
|
1481
|
+
action.label
|
|
1482
|
+
]
|
|
1483
|
+
},
|
|
1484
|
+
action.id
|
|
1485
|
+
)) }),
|
|
1486
|
+
binding.state.lastCommandResult && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1487
|
+
"div",
|
|
1488
|
+
{
|
|
1489
|
+
style: {
|
|
1490
|
+
marginTop: "16px",
|
|
1491
|
+
padding: "10px 12px",
|
|
1492
|
+
backgroundColor: surfaceColor,
|
|
1493
|
+
border: `1px solid ${binding.state.lastCommandResult.success ? "#52525b" : borderColor}`,
|
|
1494
|
+
borderRadius: "4px",
|
|
1495
|
+
fontSize: "11px",
|
|
1496
|
+
fontFamily: "monospace",
|
|
1497
|
+
color: binding.state.lastCommandResult.success ? textColor : mutedTextColor
|
|
1498
|
+
},
|
|
1499
|
+
children: binding.state.lastCommandResult.message
|
|
1500
|
+
}
|
|
1501
|
+
),
|
|
1502
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("style", { children: `
|
|
1503
|
+
@keyframes slideUp {
|
|
1504
|
+
from { transform: translateY(100%); }
|
|
1505
|
+
to { transform: translateY(0); }
|
|
1506
|
+
}
|
|
1507
|
+
@keyframes slideIn {
|
|
1508
|
+
from { transform: translateX(100%); }
|
|
1509
|
+
to { transform: translateX(0); }
|
|
1510
|
+
}
|
|
1511
|
+
` })
|
|
1512
|
+
] }) });
|
|
1513
|
+
}
|
|
1514
|
+
|
|
804
1515
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.tsx
|
|
805
|
-
var
|
|
1516
|
+
var import_react7 = __toESM(require("react"), 1);
|
|
806
1517
|
var import_material3 = require("@mui/material");
|
|
807
1518
|
|
|
808
1519
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.styles.tsx
|
|
809
1520
|
var import_material = require("@mui/material");
|
|
810
1521
|
var import_styled = __toESM(require("@emotion/styled"), 1);
|
|
811
|
-
var
|
|
1522
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
812
1523
|
var FullscreenContainer = (0, import_styled.default)(import_material.Box)(
|
|
813
1524
|
({ leftCollapsed, rightCollapsed }) => {
|
|
814
1525
|
const getGridTemplateAreas = () => {
|
|
@@ -933,7 +1644,7 @@ var DisplayModeToggle = (0, import_styled.default)(import_material.IconButton)((
|
|
|
933
1644
|
transform: "translateX(-50%) scale(1.05)"
|
|
934
1645
|
}
|
|
935
1646
|
}));
|
|
936
|
-
var ChevronLeft = () => /* @__PURE__ */ (0,
|
|
1647
|
+
var ChevronLeft = () => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
937
1648
|
"div",
|
|
938
1649
|
{
|
|
939
1650
|
style: {
|
|
@@ -945,7 +1656,7 @@ var ChevronLeft = () => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
|
945
1656
|
}
|
|
946
1657
|
}
|
|
947
1658
|
);
|
|
948
|
-
var ChevronRight = () => /* @__PURE__ */ (0,
|
|
1659
|
+
var ChevronRight = () => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
949
1660
|
"div",
|
|
950
1661
|
{
|
|
951
1662
|
style: {
|
|
@@ -1056,10 +1767,10 @@ var ScrollableSVGWrapper = (0, import_styled.default)("div")({
|
|
|
1056
1767
|
});
|
|
1057
1768
|
|
|
1058
1769
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.overlays.tsx
|
|
1059
|
-
var
|
|
1770
|
+
var import_react6 = require("react");
|
|
1060
1771
|
var import_material2 = require("@mui/material");
|
|
1061
1772
|
var import_styled2 = __toESM(require("@emotion/styled"), 1);
|
|
1062
|
-
var
|
|
1773
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1063
1774
|
var baseOverlayStyles = {
|
|
1064
1775
|
tank: {
|
|
1065
1776
|
background: "linear-gradient(135deg, rgba(69, 90, 120, 0.95) 0%, rgba(52, 73, 94, 0.95) 100%)",
|
|
@@ -1121,8 +1832,8 @@ var SVGLockedOverlay = ({
|
|
|
1121
1832
|
onClick,
|
|
1122
1833
|
containerSelector = ".tff-svg-container"
|
|
1123
1834
|
}) => {
|
|
1124
|
-
const [svgOffset, setSvgOffset] = (0,
|
|
1125
|
-
(0,
|
|
1835
|
+
const [svgOffset, setSvgOffset] = (0, import_react6.useState)({ x: 0, y: 0 });
|
|
1836
|
+
(0, import_react6.useEffect)(() => {
|
|
1126
1837
|
const updateSvgOffset = () => {
|
|
1127
1838
|
const containerElement = document.querySelector(containerSelector);
|
|
1128
1839
|
const svgElement = containerElement?.querySelector("svg");
|
|
@@ -1142,7 +1853,7 @@ var SVGLockedOverlay = ({
|
|
|
1142
1853
|
const pixelX = svgX + svgOffset.x;
|
|
1143
1854
|
const pixelY = svgY + svgOffset.y;
|
|
1144
1855
|
const appliedStyle = theme ? { ...overlayStyles[theme], ...style } : style;
|
|
1145
|
-
return /* @__PURE__ */ (0,
|
|
1856
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1146
1857
|
import_material2.Box,
|
|
1147
1858
|
{
|
|
1148
1859
|
className: `svg-locked-overlay ${className}`.trim(),
|
|
@@ -1206,7 +1917,7 @@ var CardUnit = (0, import_styled2.default)("div")({
|
|
|
1206
1917
|
});
|
|
1207
1918
|
|
|
1208
1919
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.visuals.tsx
|
|
1209
|
-
var
|
|
1920
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1210
1921
|
var TrendLine = ({
|
|
1211
1922
|
values,
|
|
1212
1923
|
width = 60,
|
|
@@ -1216,7 +1927,7 @@ var TrendLine = ({
|
|
|
1216
1927
|
backgroundColor = "rgba(255, 255, 255, 0.1)"
|
|
1217
1928
|
}) => {
|
|
1218
1929
|
if (!values || values.length < 2) {
|
|
1219
|
-
return /* @__PURE__ */ (0,
|
|
1930
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1220
1931
|
"div",
|
|
1221
1932
|
{
|
|
1222
1933
|
style: {
|
|
@@ -1228,7 +1939,7 @@ var TrendLine = ({
|
|
|
1228
1939
|
alignItems: "center",
|
|
1229
1940
|
justifyContent: "center"
|
|
1230
1941
|
},
|
|
1231
|
-
children: /* @__PURE__ */ (0,
|
|
1942
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { style: { fontSize: "8px", color: "#ccc" }, children: "No data" })
|
|
1232
1943
|
}
|
|
1233
1944
|
);
|
|
1234
1945
|
}
|
|
@@ -1240,7 +1951,7 @@ var TrendLine = ({
|
|
|
1240
1951
|
const x = 4 + i / (values.length - 1) * (width - 8);
|
|
1241
1952
|
return i === 0 ? `M ${x} ${y}` : `L ${x} ${y}`;
|
|
1242
1953
|
}).join(" ");
|
|
1243
|
-
return /* @__PURE__ */ (0,
|
|
1954
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1244
1955
|
"div",
|
|
1245
1956
|
{
|
|
1246
1957
|
style: {
|
|
@@ -1251,8 +1962,8 @@ var TrendLine = ({
|
|
|
1251
1962
|
position: "relative",
|
|
1252
1963
|
overflow: "hidden"
|
|
1253
1964
|
},
|
|
1254
|
-
children: /* @__PURE__ */ (0,
|
|
1255
|
-
/* @__PURE__ */ (0,
|
|
1965
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("svg", { width, height, style: { position: "absolute", top: 0, left: 0 }, children: [
|
|
1966
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1256
1967
|
"path",
|
|
1257
1968
|
{
|
|
1258
1969
|
d: pathData,
|
|
@@ -1263,7 +1974,7 @@ var TrendLine = ({
|
|
|
1263
1974
|
strokeLinejoin: "round"
|
|
1264
1975
|
}
|
|
1265
1976
|
),
|
|
1266
|
-
/* @__PURE__ */ (0,
|
|
1977
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1267
1978
|
"circle",
|
|
1268
1979
|
{
|
|
1269
1980
|
cx: 4 + (width - 8),
|
|
@@ -1301,7 +2012,7 @@ var CircularGauge = ({
|
|
|
1301
2012
|
const borderColor = isHex ? hexToRgba(color, 0.9) : color;
|
|
1302
2013
|
const backgroundColor = isHex ? hexToRgba(color, 0.15) : color;
|
|
1303
2014
|
const borderStrokeColor = isHex ? hexToRgba(color, 0.4) : color;
|
|
1304
|
-
return /* @__PURE__ */ (0,
|
|
2015
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
1305
2016
|
"div",
|
|
1306
2017
|
{
|
|
1307
2018
|
style: {
|
|
@@ -1310,7 +2021,7 @@ var CircularGauge = ({
|
|
|
1310
2021
|
alignItems: "center"
|
|
1311
2022
|
},
|
|
1312
2023
|
children: [
|
|
1313
|
-
/* @__PURE__ */ (0,
|
|
2024
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
1314
2025
|
"div",
|
|
1315
2026
|
{
|
|
1316
2027
|
style: {
|
|
@@ -1322,8 +2033,8 @@ var CircularGauge = ({
|
|
|
1322
2033
|
border: `1px solid ${borderStrokeColor}`
|
|
1323
2034
|
},
|
|
1324
2035
|
children: [
|
|
1325
|
-
/* @__PURE__ */ (0,
|
|
1326
|
-
/* @__PURE__ */ (0,
|
|
2036
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("svg", { width: size, height: size, style: { transform: "rotate(-90deg)" }, children: [
|
|
2037
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1327
2038
|
"circle",
|
|
1328
2039
|
{
|
|
1329
2040
|
cx: size / 2,
|
|
@@ -1334,7 +2045,7 @@ var CircularGauge = ({
|
|
|
1334
2045
|
strokeWidth: 1
|
|
1335
2046
|
}
|
|
1336
2047
|
),
|
|
1337
|
-
/* @__PURE__ */ (0,
|
|
2048
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1338
2049
|
"circle",
|
|
1339
2050
|
{
|
|
1340
2051
|
cx: size / 2,
|
|
@@ -1345,7 +2056,7 @@ var CircularGauge = ({
|
|
|
1345
2056
|
fill: "transparent"
|
|
1346
2057
|
}
|
|
1347
2058
|
),
|
|
1348
|
-
/* @__PURE__ */ (0,
|
|
2059
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1349
2060
|
"circle",
|
|
1350
2061
|
{
|
|
1351
2062
|
cx: size / 2,
|
|
@@ -1361,7 +2072,7 @@ var CircularGauge = ({
|
|
|
1361
2072
|
}
|
|
1362
2073
|
)
|
|
1363
2074
|
] }),
|
|
1364
|
-
/* @__PURE__ */ (0,
|
|
2075
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
1365
2076
|
"div",
|
|
1366
2077
|
{
|
|
1367
2078
|
style: {
|
|
@@ -1377,14 +2088,14 @@ var CircularGauge = ({
|
|
|
1377
2088
|
},
|
|
1378
2089
|
children: [
|
|
1379
2090
|
value.toFixed(1),
|
|
1380
|
-
/* @__PURE__ */ (0,
|
|
2091
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: { fontSize: "8px", opacity: 0.9, color: "white" }, children: unit })
|
|
1381
2092
|
]
|
|
1382
2093
|
}
|
|
1383
2094
|
)
|
|
1384
2095
|
]
|
|
1385
2096
|
}
|
|
1386
2097
|
),
|
|
1387
|
-
/* @__PURE__ */ (0,
|
|
2098
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1388
2099
|
"div",
|
|
1389
2100
|
{
|
|
1390
2101
|
style: {
|
|
@@ -1415,7 +2126,7 @@ var Sparkline = ({ data, width, height, color }) => {
|
|
|
1415
2126
|
const y = height - 8 - (value - min) / range * (height - 8);
|
|
1416
2127
|
return `${x + 4},${y + 4}`;
|
|
1417
2128
|
}).join(" ");
|
|
1418
|
-
return /* @__PURE__ */ (0,
|
|
2129
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1419
2130
|
"div",
|
|
1420
2131
|
{
|
|
1421
2132
|
style: {
|
|
@@ -1429,7 +2140,7 @@ var Sparkline = ({ data, width, height, color }) => {
|
|
|
1429
2140
|
justifyContent: "center",
|
|
1430
2141
|
boxShadow: "0 1px 3px rgba(0, 0, 0, 0.2)"
|
|
1431
2142
|
},
|
|
1432
|
-
children: /* @__PURE__ */ (0,
|
|
2143
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { width, height, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("polyline", { points, fill: "none", stroke: color, strokeWidth: "1.5", opacity: "0.9" }) })
|
|
1433
2144
|
}
|
|
1434
2145
|
);
|
|
1435
2146
|
};
|
|
@@ -1443,8 +2154,8 @@ var EquipmentIndicatorWithSparkline = ({
|
|
|
1443
2154
|
sparklineOffset = { x: 40, y: 0 }
|
|
1444
2155
|
}) => {
|
|
1445
2156
|
const hasSparkline = sparklineData && sparklineData.length > 1 && Math.max(...sparklineData) !== Math.min(...sparklineData);
|
|
1446
|
-
return /* @__PURE__ */ (0,
|
|
1447
|
-
/* @__PURE__ */ (0,
|
|
2157
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
2158
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SVGLockedOverlay, { svgX, svgY, style: { transform: "translate(-50%, -50%)" }, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1448
2159
|
"div",
|
|
1449
2160
|
{
|
|
1450
2161
|
style: {
|
|
@@ -1465,7 +2176,7 @@ var EquipmentIndicatorWithSparkline = ({
|
|
|
1465
2176
|
children: label
|
|
1466
2177
|
}
|
|
1467
2178
|
) }),
|
|
1468
|
-
hasSparkline && /* @__PURE__ */ (0,
|
|
2179
|
+
hasSparkline && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SVGLockedOverlay, { svgX: svgX + sparklineOffset.x, svgY: svgY + sparklineOffset.y, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Sparkline, { data: sparklineData, width: 60, height: 20, color }) })
|
|
1469
2180
|
] });
|
|
1470
2181
|
};
|
|
1471
2182
|
var EquipmentIndicator = ({
|
|
@@ -1478,7 +2189,7 @@ var EquipmentIndicator = ({
|
|
|
1478
2189
|
className
|
|
1479
2190
|
}) => {
|
|
1480
2191
|
const overlayStyle = style !== void 0 ? { transform: "translate(-50%, -50%)", ...style } : { transform: "translate(-50%, -50%)" };
|
|
1481
|
-
return /* @__PURE__ */ (0,
|
|
2192
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SVGLockedOverlay, { svgX, svgY, style: overlayStyle, className, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1482
2193
|
"div",
|
|
1483
2194
|
{
|
|
1484
2195
|
style: {
|
|
@@ -1502,7 +2213,7 @@ var EquipmentIndicator = ({
|
|
|
1502
2213
|
};
|
|
1503
2214
|
|
|
1504
2215
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.tsx
|
|
1505
|
-
var
|
|
2216
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1506
2217
|
function FullscreenWorkspace({
|
|
1507
2218
|
svgContent,
|
|
1508
2219
|
overlays,
|
|
@@ -1530,10 +2241,10 @@ function FullscreenWorkspace({
|
|
|
1530
2241
|
className = "",
|
|
1531
2242
|
...rest
|
|
1532
2243
|
}) {
|
|
1533
|
-
const [leftCollapsedState, setLeftCollapsedState] =
|
|
1534
|
-
const [rightCollapsedState, setRightCollapsedState] =
|
|
1535
|
-
const [internalDisplayMode, setInternalDisplayMode] =
|
|
1536
|
-
const [internalTab, setInternalTab] =
|
|
2244
|
+
const [leftCollapsedState, setLeftCollapsedState] = import_react7.default.useState(defaultLeftCollapsed);
|
|
2245
|
+
const [rightCollapsedState, setRightCollapsedState] = import_react7.default.useState(defaultRightCollapsed);
|
|
2246
|
+
const [internalDisplayMode, setInternalDisplayMode] = import_react7.default.useState(displayMode ?? defaultDisplayMode);
|
|
2247
|
+
const [internalTab, setInternalTab] = import_react7.default.useState(
|
|
1537
2248
|
tabs && tabs.length > 0 ? tabs[0].value : ""
|
|
1538
2249
|
);
|
|
1539
2250
|
const leftCollapsed = leftCollapsedProp ?? leftCollapsedState;
|
|
@@ -1541,10 +2252,10 @@ function FullscreenWorkspace({
|
|
|
1541
2252
|
const isDisplayModeControlled = displayMode !== void 0;
|
|
1542
2253
|
const currentDisplayMode = isDisplayModeControlled ? displayMode : internalDisplayMode;
|
|
1543
2254
|
const isTabControlled = activeTab !== void 0 && activeTab !== null;
|
|
1544
|
-
const resolvedTabs =
|
|
2255
|
+
const resolvedTabs = import_react7.default.useMemo(() => tabs ?? [], [tabs]);
|
|
1545
2256
|
const defaultTabValue = resolvedTabs.length > 0 ? resolvedTabs[0].value : "";
|
|
1546
2257
|
const currentTab = isTabControlled ? activeTab : internalTab || defaultTabValue;
|
|
1547
|
-
|
|
2258
|
+
import_react7.default.useEffect(() => {
|
|
1548
2259
|
if (resolvedTabs.length > 0) {
|
|
1549
2260
|
const values = resolvedTabs.map((tab) => tab.value);
|
|
1550
2261
|
if (!values.includes(currentTab)) {
|
|
@@ -1553,7 +2264,7 @@ function FullscreenWorkspace({
|
|
|
1553
2264
|
}
|
|
1554
2265
|
}
|
|
1555
2266
|
}, [resolvedTabs, activeTab, currentTab, defaultTabValue]);
|
|
1556
|
-
|
|
2267
|
+
import_react7.default.useEffect(() => {
|
|
1557
2268
|
if (displayMode !== void 0) {
|
|
1558
2269
|
setInternalDisplayMode(displayMode);
|
|
1559
2270
|
}
|
|
@@ -1588,7 +2299,7 @@ function FullscreenWorkspace({
|
|
|
1588
2299
|
const currentTabContent = resolvedTabs.find((tab) => tab.value === currentTab)?.content ?? null;
|
|
1589
2300
|
const showLeftToggle = Boolean(leftPanel);
|
|
1590
2301
|
const showRightToggle = Boolean(rightPanel);
|
|
1591
|
-
return /* @__PURE__ */ (0,
|
|
2302
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
1592
2303
|
FullscreenContainer,
|
|
1593
2304
|
{
|
|
1594
2305
|
leftCollapsed,
|
|
@@ -1596,25 +2307,25 @@ function FullscreenWorkspace({
|
|
|
1596
2307
|
className: `tff-svg-container ${className}`.trim(),
|
|
1597
2308
|
...rest,
|
|
1598
2309
|
children: [
|
|
1599
|
-
showLeftToggle && /* @__PURE__ */ (0,
|
|
2310
|
+
showLeftToggle && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1600
2311
|
LeftToggleButton,
|
|
1601
2312
|
{
|
|
1602
2313
|
collapsed: leftCollapsed,
|
|
1603
2314
|
onClick: handleLeftToggle,
|
|
1604
2315
|
"aria-label": leftCollapsed ? "Expand left panel" : "Collapse left panel",
|
|
1605
|
-
children: leftCollapsed ? /* @__PURE__ */ (0,
|
|
2316
|
+
children: leftCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ChevronRight, {}) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ChevronLeft, {})
|
|
1606
2317
|
}
|
|
1607
2318
|
),
|
|
1608
|
-
showRightToggle && /* @__PURE__ */ (0,
|
|
2319
|
+
showRightToggle && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1609
2320
|
RightToggleButton,
|
|
1610
2321
|
{
|
|
1611
2322
|
collapsed: rightCollapsed,
|
|
1612
2323
|
onClick: handleRightToggle,
|
|
1613
2324
|
"aria-label": rightCollapsed ? "Expand right panel" : "Collapse right panel",
|
|
1614
|
-
children: rightCollapsed ? /* @__PURE__ */ (0,
|
|
2325
|
+
children: rightCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ChevronLeft, {}) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ChevronRight, {})
|
|
1615
2326
|
}
|
|
1616
2327
|
),
|
|
1617
|
-
showDisplayModeToggle && /* @__PURE__ */ (0,
|
|
2328
|
+
showDisplayModeToggle && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1618
2329
|
DisplayModeToggle,
|
|
1619
2330
|
{
|
|
1620
2331
|
mode: currentDisplayMode,
|
|
@@ -1623,9 +2334,9 @@ function FullscreenWorkspace({
|
|
|
1623
2334
|
children: currentDisplayMode === "dashboard" ? "Dashboard Mode" : "Standard Mode"
|
|
1624
2335
|
}
|
|
1625
2336
|
),
|
|
1626
|
-
/* @__PURE__ */ (0,
|
|
1627
|
-
showZoomControls && /* @__PURE__ */ (0,
|
|
1628
|
-
/* @__PURE__ */ (0,
|
|
2337
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(SVGArea, { children: [
|
|
2338
|
+
showZoomControls && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(ZoomControls, { children: [
|
|
2339
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1629
2340
|
ZoomButton,
|
|
1630
2341
|
{
|
|
1631
2342
|
onClick: onZoomIn,
|
|
@@ -1635,7 +2346,7 @@ function FullscreenWorkspace({
|
|
|
1635
2346
|
children: "+"
|
|
1636
2347
|
}
|
|
1637
2348
|
),
|
|
1638
|
-
/* @__PURE__ */ (0,
|
|
2349
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1639
2350
|
ZoomButton,
|
|
1640
2351
|
{
|
|
1641
2352
|
onClick: onZoomOut,
|
|
@@ -1645,7 +2356,7 @@ function FullscreenWorkspace({
|
|
|
1645
2356
|
children: "-"
|
|
1646
2357
|
}
|
|
1647
2358
|
),
|
|
1648
|
-
onResetZoom && /* @__PURE__ */ (0,
|
|
2359
|
+
onResetZoom && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1649
2360
|
ZoomButton,
|
|
1650
2361
|
{
|
|
1651
2362
|
onClick: onResetZoom,
|
|
@@ -1656,44 +2367,44 @@ function FullscreenWorkspace({
|
|
|
1656
2367
|
}
|
|
1657
2368
|
)
|
|
1658
2369
|
] }),
|
|
1659
|
-
/* @__PURE__ */ (0,
|
|
2370
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ScrollableSVGWrapper, { className: "svg-scroll-wrapper", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(FixedSVGContainer, { className: "svg-container", children: [
|
|
1660
2371
|
svgContent,
|
|
1661
2372
|
overlays
|
|
1662
2373
|
] }) })
|
|
1663
2374
|
] }),
|
|
1664
|
-
/* @__PURE__ */ (0,
|
|
1665
|
-
/* @__PURE__ */ (0,
|
|
2375
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(LeftPanel, { collapsed: leftCollapsed, children: resolvedTabs.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
|
|
2376
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1666
2377
|
PanelTabs,
|
|
1667
2378
|
{
|
|
1668
2379
|
value: currentTab,
|
|
1669
2380
|
onChange: handleTabChangeInternal,
|
|
1670
2381
|
"aria-label": "Left panel tabs",
|
|
1671
|
-
children: resolvedTabs.map((tab) => /* @__PURE__ */ (0,
|
|
2382
|
+
children: resolvedTabs.map((tab) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_material3.Tab, { label: tab.label, value: tab.value }, tab.value))
|
|
1672
2383
|
}
|
|
1673
2384
|
),
|
|
1674
|
-
/* @__PURE__ */ (0,
|
|
2385
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PanelContent, { children: currentTabContent })
|
|
1675
2386
|
] }) : leftPanel }),
|
|
1676
|
-
/* @__PURE__ */ (0,
|
|
1677
|
-
/* @__PURE__ */ (0,
|
|
2387
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(RightPanel, { collapsed: rightCollapsed, children: rightPanel }),
|
|
2388
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(FooterPanel, { children: footer })
|
|
1678
2389
|
]
|
|
1679
2390
|
}
|
|
1680
2391
|
);
|
|
1681
2392
|
}
|
|
1682
2393
|
|
|
1683
2394
|
// src/theme/ThemeContext.tsx
|
|
1684
|
-
var
|
|
1685
|
-
var
|
|
1686
|
-
var ThemeContext = (0,
|
|
2395
|
+
var import_react8 = require("react");
|
|
2396
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2397
|
+
var ThemeContext = (0, import_react8.createContext)(void 0);
|
|
1687
2398
|
var useTheme = () => {
|
|
1688
|
-
const context = (0,
|
|
2399
|
+
const context = (0, import_react8.useContext)(ThemeContext);
|
|
1689
2400
|
if (!context) {
|
|
1690
2401
|
throw new Error("useTheme must be used within a ThemeProvider");
|
|
1691
2402
|
}
|
|
1692
2403
|
return context;
|
|
1693
2404
|
};
|
|
1694
2405
|
var ThemeProvider = ({ children }) => {
|
|
1695
|
-
const [theme, setThemeState] = (0,
|
|
1696
|
-
(0,
|
|
2406
|
+
const [theme, setThemeState] = (0, import_react8.useState)("modern");
|
|
2407
|
+
(0, import_react8.useEffect)(() => {
|
|
1697
2408
|
document.body.className = "";
|
|
1698
2409
|
document.body.classList.add(`theme-${theme}`);
|
|
1699
2410
|
document.documentElement.className = "";
|
|
@@ -1705,11 +2416,11 @@ var ThemeProvider = ({ children }) => {
|
|
|
1705
2416
|
const setTheme = (newTheme) => {
|
|
1706
2417
|
setThemeState(newTheme);
|
|
1707
2418
|
};
|
|
1708
|
-
return /* @__PURE__ */ (0,
|
|
2419
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ThemeContext.Provider, { value: { theme, toggleTheme, setTheme }, children });
|
|
1709
2420
|
};
|
|
1710
2421
|
|
|
1711
2422
|
// src/theme/ThemeToggle.tsx
|
|
1712
|
-
var
|
|
2423
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
1713
2424
|
var ThemeToggle = ({
|
|
1714
2425
|
size = "medium",
|
|
1715
2426
|
position = "top-right",
|
|
@@ -1780,15 +2491,15 @@ var ThemeToggle = ({
|
|
|
1780
2491
|
transition: "all 0.2s ease",
|
|
1781
2492
|
boxShadow: "0 2px 4px rgba(0, 0, 0, 0.2)"
|
|
1782
2493
|
};
|
|
1783
|
-
return /* @__PURE__ */ (0,
|
|
1784
|
-
/* @__PURE__ */ (0,
|
|
1785
|
-
/* @__PURE__ */ (0,
|
|
1786
|
-
/* @__PURE__ */ (0,
|
|
2494
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: currentStyle, onClick: toggleTheme, className, ...props, children: [
|
|
2495
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: theme === "modern" ? "\u{1F3A8} Modern" : "\u{1F3ED} HMI" }),
|
|
2496
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: toggleStyle, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: thumbStyle }) }),
|
|
2497
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { style: { fontSize: "0.75rem", opacity: 0.8 }, children: theme === "modern" ? "Industrial Design" : "High Performance" })
|
|
1787
2498
|
] });
|
|
1788
2499
|
};
|
|
1789
2500
|
|
|
1790
2501
|
// src/components/PIDCanvas/PIDCanvas.tsx
|
|
1791
|
-
var
|
|
2502
|
+
var import_react16 = require("react");
|
|
1792
2503
|
|
|
1793
2504
|
// src/diagram/symbols/mockSymbolLibrary.ts
|
|
1794
2505
|
var mockSymbolLibrary = {
|
|
@@ -3009,7 +3720,7 @@ function getAvailableSymbols() {
|
|
|
3009
3720
|
}
|
|
3010
3721
|
|
|
3011
3722
|
// src/components/PIDCanvas/NodeRenderer.tsx
|
|
3012
|
-
var
|
|
3723
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
3013
3724
|
function NodeRenderer({
|
|
3014
3725
|
nodes: nodes2,
|
|
3015
3726
|
selectedNodeIds,
|
|
@@ -3020,13 +3731,13 @@ function NodeRenderer({
|
|
|
3020
3731
|
dragOffset = { x: 0, y: 0 },
|
|
3021
3732
|
enableDrag = false
|
|
3022
3733
|
}) {
|
|
3023
|
-
return /* @__PURE__ */ (0,
|
|
3734
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("g", { id: "layer-nodes", children: nodes2.filter((node) => node.visible !== false).map((node) => {
|
|
3024
3735
|
const symbol = getSymbolDefinition(node.symbolId);
|
|
3025
3736
|
const isSelected = selectedNodeIds?.has(node.id) ?? false;
|
|
3026
3737
|
const isDragging = draggingNodeId === node.id;
|
|
3027
3738
|
if (!symbol) {
|
|
3028
|
-
return /* @__PURE__ */ (0,
|
|
3029
|
-
/* @__PURE__ */ (0,
|
|
3739
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("g", { children: [
|
|
3740
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3030
3741
|
"circle",
|
|
3031
3742
|
{
|
|
3032
3743
|
cx: node.transform.x,
|
|
@@ -3038,7 +3749,7 @@ function NodeRenderer({
|
|
|
3038
3749
|
strokeWidth: "2"
|
|
3039
3750
|
}
|
|
3040
3751
|
),
|
|
3041
|
-
/* @__PURE__ */ (0,
|
|
3752
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3042
3753
|
"text",
|
|
3043
3754
|
{
|
|
3044
3755
|
x: node.transform.x,
|
|
@@ -3095,7 +3806,7 @@ function NodeRenderer({
|
|
|
3095
3806
|
};
|
|
3096
3807
|
const fillColor = node.customColors?.fill ?? getStatusColor(node.status);
|
|
3097
3808
|
const strokeColor = node.customColors?.stroke ?? "rgb(0, 0, 0)";
|
|
3098
|
-
return /* @__PURE__ */ (0,
|
|
3809
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
3099
3810
|
"g",
|
|
3100
3811
|
{
|
|
3101
3812
|
"data-node-id": node.id,
|
|
@@ -3128,7 +3839,7 @@ function NodeRenderer({
|
|
|
3128
3839
|
}
|
|
3129
3840
|
},
|
|
3130
3841
|
children: [
|
|
3131
|
-
isSelected && /* @__PURE__ */ (0,
|
|
3842
|
+
isSelected && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3132
3843
|
"rect",
|
|
3133
3844
|
{
|
|
3134
3845
|
x: "-5",
|
|
@@ -3143,7 +3854,7 @@ function NodeRenderer({
|
|
|
3143
3854
|
pointerEvents: "none"
|
|
3144
3855
|
}
|
|
3145
3856
|
),
|
|
3146
|
-
/* @__PURE__ */ (0,
|
|
3857
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3147
3858
|
"g",
|
|
3148
3859
|
{
|
|
3149
3860
|
dangerouslySetInnerHTML: { __html: symbol.svgContent },
|
|
@@ -3151,7 +3862,7 @@ function NodeRenderer({
|
|
|
3151
3862
|
style: { pointerEvents: "auto" }
|
|
3152
3863
|
}
|
|
3153
3864
|
),
|
|
3154
|
-
/* @__PURE__ */ (0,
|
|
3865
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3155
3866
|
"text",
|
|
3156
3867
|
{
|
|
3157
3868
|
x: symbol.viewBox.width / 2 + (node.labelOffset?.x ?? 0),
|
|
@@ -3172,7 +3883,7 @@ function NodeRenderer({
|
|
|
3172
3883
|
}
|
|
3173
3884
|
|
|
3174
3885
|
// src/components/PIDCanvas/PipeRenderer.tsx
|
|
3175
|
-
var
|
|
3886
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
3176
3887
|
function PipeRenderer({
|
|
3177
3888
|
pipes,
|
|
3178
3889
|
selectedPipeIds,
|
|
@@ -3187,7 +3898,7 @@ function PipeRenderer({
|
|
|
3187
3898
|
waypointDragOffset,
|
|
3188
3899
|
onPipeSegmentClick
|
|
3189
3900
|
}) {
|
|
3190
|
-
return /* @__PURE__ */ (0,
|
|
3901
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("g", { id: "layer-pipes", children: pipes.filter((pipe) => pipe.visible !== false).map((pipe) => {
|
|
3191
3902
|
const isSelected = selectedPipeIds?.has(pipe.id) ?? false;
|
|
3192
3903
|
const isEditing = enableWaypointEditing && editingPipeId === pipe.id;
|
|
3193
3904
|
const showEditingControls = enableWaypointEditing && isSelected;
|
|
@@ -3206,7 +3917,7 @@ function PipeRenderer({
|
|
|
3206
3917
|
const strokeWidth = isSelected ? (pipeStyle.strokeWidth || 3) + 2 : pipeStyle.strokeWidth || 3;
|
|
3207
3918
|
const strokeDasharray = pipeStyle.strokeDasharray;
|
|
3208
3919
|
const opacity = pipeStyle.opacity !== void 0 ? pipeStyle.opacity : 1;
|
|
3209
|
-
return /* @__PURE__ */ (0,
|
|
3920
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
3210
3921
|
"g",
|
|
3211
3922
|
{
|
|
3212
3923
|
"data-pipe-id": pipe.id,
|
|
@@ -3219,8 +3930,8 @@ function PipeRenderer({
|
|
|
3219
3930
|
cursor: onPipeClick ? "pointer" : "default"
|
|
3220
3931
|
},
|
|
3221
3932
|
children: [
|
|
3222
|
-
!enableWaypointEditing && /* @__PURE__ */ (0,
|
|
3223
|
-
onPipeClick && /* @__PURE__ */ (0,
|
|
3933
|
+
!enableWaypointEditing && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
3934
|
+
onPipeClick && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3224
3935
|
"polyline",
|
|
3225
3936
|
{
|
|
3226
3937
|
points: pointsString,
|
|
@@ -3232,7 +3943,7 @@ function PipeRenderer({
|
|
|
3232
3943
|
pointerEvents: "stroke"
|
|
3233
3944
|
}
|
|
3234
3945
|
),
|
|
3235
|
-
/* @__PURE__ */ (0,
|
|
3946
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3236
3947
|
"polyline",
|
|
3237
3948
|
{
|
|
3238
3949
|
points: pointsString,
|
|
@@ -3256,7 +3967,7 @@ function PipeRenderer({
|
|
|
3256
3967
|
const waypointSize = isSelectedWaypoint ? 8 : isDragging ? 8 : showEditingControls ? 6 : isSelected ? 3 : 2;
|
|
3257
3968
|
const waypointOpacity = isSelectedWaypoint ? 1 : isDragging ? 1 : showEditingControls ? 0.9 : isSelected ? 0.8 : 0.5;
|
|
3258
3969
|
const waypointColor = isSelectedWaypoint ? "#3b82f6" : isEndpoint && showEditingControls ? "#f59e0b" : isDragging ? "#10b981" : stroke;
|
|
3259
|
-
return /* @__PURE__ */ (0,
|
|
3970
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3260
3971
|
"circle",
|
|
3261
3972
|
{
|
|
3262
3973
|
cx: point.x,
|
|
@@ -3293,12 +4004,12 @@ function PipeRenderer({
|
|
|
3293
4004
|
`${pipe.id}-point-${idx}`
|
|
3294
4005
|
);
|
|
3295
4006
|
}),
|
|
3296
|
-
showEditingControls && onPipeSegmentClick && displayPoints.length >= 2 && /* @__PURE__ */ (0,
|
|
4007
|
+
showEditingControls && onPipeSegmentClick && displayPoints.length >= 2 && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_jsx_runtime16.Fragment, { children: displayPoints.slice(0, -1).map((point, idx) => {
|
|
3297
4008
|
const nextPoint = displayPoints[idx + 1];
|
|
3298
4009
|
const midX = (point.x + nextPoint.x) / 2;
|
|
3299
4010
|
const midY = (point.y + nextPoint.y) / 2;
|
|
3300
|
-
return /* @__PURE__ */ (0,
|
|
3301
|
-
/* @__PURE__ */ (0,
|
|
4011
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("g", { children: [
|
|
4012
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3302
4013
|
"circle",
|
|
3303
4014
|
{
|
|
3304
4015
|
cx: midX,
|
|
@@ -3314,7 +4025,7 @@ function PipeRenderer({
|
|
|
3314
4025
|
}
|
|
3315
4026
|
}
|
|
3316
4027
|
),
|
|
3317
|
-
/* @__PURE__ */ (0,
|
|
4028
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3318
4029
|
"circle",
|
|
3319
4030
|
{
|
|
3320
4031
|
cx: midX,
|
|
@@ -3330,7 +4041,7 @@ function PipeRenderer({
|
|
|
3330
4041
|
)
|
|
3331
4042
|
] }, `${pipe.id}-segment-${idx}`);
|
|
3332
4043
|
}) }),
|
|
3333
|
-
pipe.showLabel !== false && pipe.label && pipe.routePoints.length >= 2 && /* @__PURE__ */ (0,
|
|
4044
|
+
pipe.showLabel !== false && pipe.label && pipe.routePoints.length >= 2 && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3334
4045
|
"text",
|
|
3335
4046
|
{
|
|
3336
4047
|
x: pipe.routePoints[Math.floor(pipe.routePoints.length / 2)].x + (pipe.labelOffset?.x ?? 0),
|
|
@@ -3352,7 +4063,7 @@ function PipeRenderer({
|
|
|
3352
4063
|
}
|
|
3353
4064
|
|
|
3354
4065
|
// src/components/PIDCanvas/DataOverlay.tsx
|
|
3355
|
-
var
|
|
4066
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
3356
4067
|
function DataOverlay({
|
|
3357
4068
|
nodeId,
|
|
3358
4069
|
x,
|
|
@@ -3372,7 +4083,7 @@ function DataOverlay({
|
|
|
3372
4083
|
const offsetX = display?.offsetX ?? 0;
|
|
3373
4084
|
const offsetY = display?.offsetY ?? 0;
|
|
3374
4085
|
if (!showValue) {
|
|
3375
|
-
return /* @__PURE__ */ (0,
|
|
4086
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_jsx_runtime17.Fragment, {});
|
|
3376
4087
|
}
|
|
3377
4088
|
const formatValue = (val) => {
|
|
3378
4089
|
if (typeof val === "number") {
|
|
@@ -3390,9 +4101,14 @@ function DataOverlay({
|
|
|
3390
4101
|
fault: { bg: "#dc2626", text: "#ffffff", border: "#b91c1c" },
|
|
3391
4102
|
off: { bg: "#6b7280", text: "#ffffff", border: "#4b5563" }
|
|
3392
4103
|
};
|
|
3393
|
-
const
|
|
3394
|
-
|
|
3395
|
-
|
|
4104
|
+
const getStatusColors = () => {
|
|
4105
|
+
const customColor = telemetry.statusColors?.[value.status];
|
|
4106
|
+
if (customColor) {
|
|
4107
|
+
return { bg: customColor, text: "#ffffff", border: customColor };
|
|
4108
|
+
}
|
|
4109
|
+
return defaultStatusColors[value.status] || defaultStatusColors.normal;
|
|
4110
|
+
};
|
|
4111
|
+
const statusColors = getStatusColors();
|
|
3396
4112
|
const colors = backgroundColor && backgroundColor !== "status" ? { bg: backgroundColor, text: textColor || "#ffffff", border: backgroundColor } : statusColors;
|
|
3397
4113
|
const finalTextColor = textColor || colors.text;
|
|
3398
4114
|
const formattedValue = formatValue(value.value);
|
|
@@ -3419,8 +4135,8 @@ function DataOverlay({
|
|
|
3419
4135
|
const overlayWidth = 80 * scale;
|
|
3420
4136
|
const displayX = x + offsetX;
|
|
3421
4137
|
const displayY = y + offsetY;
|
|
3422
|
-
return /* @__PURE__ */ (0,
|
|
3423
|
-
/* @__PURE__ */ (0,
|
|
4138
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("g", { "data-overlay-node": nodeId, "data-status": value.status, children: [
|
|
4139
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3424
4140
|
"rect",
|
|
3425
4141
|
{
|
|
3426
4142
|
x: displayX - overlayWidth / 2,
|
|
@@ -3435,7 +4151,7 @@ function DataOverlay({
|
|
|
3435
4151
|
filter: "drop-shadow(0 2px 4px rgba(0,0,0,0.2))"
|
|
3436
4152
|
}
|
|
3437
4153
|
),
|
|
3438
|
-
label && /* @__PURE__ */ (0,
|
|
4154
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3439
4155
|
"text",
|
|
3440
4156
|
{
|
|
3441
4157
|
x: displayX,
|
|
@@ -3448,7 +4164,7 @@ function DataOverlay({
|
|
|
3448
4164
|
children: label
|
|
3449
4165
|
}
|
|
3450
4166
|
),
|
|
3451
|
-
/* @__PURE__ */ (0,
|
|
4167
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3452
4168
|
"text",
|
|
3453
4169
|
{
|
|
3454
4170
|
x: displayX,
|
|
@@ -3461,7 +4177,7 @@ function DataOverlay({
|
|
|
3461
4177
|
children: displayText
|
|
3462
4178
|
}
|
|
3463
4179
|
),
|
|
3464
|
-
showStatus && value.status !== "normal" && /* @__PURE__ */ (0,
|
|
4180
|
+
showStatus && value.status !== "normal" && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3465
4181
|
"circle",
|
|
3466
4182
|
{
|
|
3467
4183
|
cx: displayX + 35 * scale,
|
|
@@ -3469,7 +4185,7 @@ function DataOverlay({
|
|
|
3469
4185
|
r: 3 * scale,
|
|
3470
4186
|
fill: finalTextColor,
|
|
3471
4187
|
opacity: "0.9",
|
|
3472
|
-
children: /* @__PURE__ */ (0,
|
|
4188
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3473
4189
|
"animate",
|
|
3474
4190
|
{
|
|
3475
4191
|
attributeName: "opacity",
|
|
@@ -3480,7 +4196,7 @@ function DataOverlay({
|
|
|
3480
4196
|
)
|
|
3481
4197
|
}
|
|
3482
4198
|
),
|
|
3483
|
-
value.quality !== void 0 && value.quality < 100 && /* @__PURE__ */ (0,
|
|
4199
|
+
value.quality !== void 0 && value.quality < 100 && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
3484
4200
|
"text",
|
|
3485
4201
|
{
|
|
3486
4202
|
x: displayX,
|
|
@@ -3497,7 +4213,7 @@ function DataOverlay({
|
|
|
3497
4213
|
]
|
|
3498
4214
|
}
|
|
3499
4215
|
),
|
|
3500
|
-
hasSparkline && /* @__PURE__ */ (0,
|
|
4216
|
+
hasSparkline && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("g", { transform: `translate(${displayX - 35 * scale}, ${displayY + (label ? 5 : 0) * scale})`, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3501
4217
|
"path",
|
|
3502
4218
|
{
|
|
3503
4219
|
d: sparklinePath,
|
|
@@ -3513,8 +4229,8 @@ function DataOverlay({
|
|
|
3513
4229
|
}
|
|
3514
4230
|
|
|
3515
4231
|
// src/components/PIDCanvas/PositionPanel.tsx
|
|
3516
|
-
var
|
|
3517
|
-
var
|
|
4232
|
+
var import_react9 = require("react");
|
|
4233
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
3518
4234
|
function PositionPanel({
|
|
3519
4235
|
selectedNode,
|
|
3520
4236
|
selectedWaypoint,
|
|
@@ -3522,9 +4238,9 @@ function PositionPanel({
|
|
|
3522
4238
|
onWaypointPositionChange,
|
|
3523
4239
|
position = "top-right"
|
|
3524
4240
|
}) {
|
|
3525
|
-
const [x, setX] = (0,
|
|
3526
|
-
const [y, setY] = (0,
|
|
3527
|
-
(0,
|
|
4241
|
+
const [x, setX] = (0, import_react9.useState)("");
|
|
4242
|
+
const [y, setY] = (0, import_react9.useState)("");
|
|
4243
|
+
(0, import_react9.useEffect)(() => {
|
|
3528
4244
|
if (selectedNode) {
|
|
3529
4245
|
setX(selectedNode.transform.x.toFixed(2));
|
|
3530
4246
|
setY(selectedNode.transform.y.toFixed(2));
|
|
@@ -3583,7 +4299,7 @@ function PositionPanel({
|
|
|
3583
4299
|
"bottom-left": { bottom: 10, left: 10 },
|
|
3584
4300
|
"bottom-right": { bottom: 10, right: 10 }
|
|
3585
4301
|
};
|
|
3586
|
-
return /* @__PURE__ */ (0,
|
|
4302
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
3587
4303
|
"div",
|
|
3588
4304
|
{
|
|
3589
4305
|
style: {
|
|
@@ -3600,11 +4316,11 @@ function PositionPanel({
|
|
|
3600
4316
|
fontSize: "13px"
|
|
3601
4317
|
},
|
|
3602
4318
|
children: [
|
|
3603
|
-
/* @__PURE__ */ (0,
|
|
3604
|
-
/* @__PURE__ */ (0,
|
|
3605
|
-
/* @__PURE__ */ (0,
|
|
3606
|
-
/* @__PURE__ */ (0,
|
|
3607
|
-
/* @__PURE__ */ (0,
|
|
4319
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { marginBottom: "8px", fontWeight: 600, color: "#333" }, children: "Position" }),
|
|
4320
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "8px" }, children: [
|
|
4321
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
|
|
4322
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("label", { style: { width: "16px", color: "#666" }, children: "X:" }),
|
|
4323
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3608
4324
|
"input",
|
|
3609
4325
|
{
|
|
3610
4326
|
type: "number",
|
|
@@ -3622,9 +4338,9 @@ function PositionPanel({
|
|
|
3622
4338
|
}
|
|
3623
4339
|
)
|
|
3624
4340
|
] }),
|
|
3625
|
-
/* @__PURE__ */ (0,
|
|
3626
|
-
/* @__PURE__ */ (0,
|
|
3627
|
-
/* @__PURE__ */ (0,
|
|
4341
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
|
|
4342
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("label", { style: { width: "16px", color: "#666" }, children: "Y:" }),
|
|
4343
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3628
4344
|
"input",
|
|
3629
4345
|
{
|
|
3630
4346
|
type: "number",
|
|
@@ -3643,14 +4359,14 @@ function PositionPanel({
|
|
|
3643
4359
|
)
|
|
3644
4360
|
] })
|
|
3645
4361
|
] }),
|
|
3646
|
-
/* @__PURE__ */ (0,
|
|
4362
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { marginTop: "8px", fontSize: "11px", color: "#888" }, children: "Use arrow keys to nudge (\xB11px)" })
|
|
3647
4363
|
]
|
|
3648
4364
|
}
|
|
3649
4365
|
);
|
|
3650
4366
|
}
|
|
3651
4367
|
|
|
3652
4368
|
// src/diagram/hooks/useViewBox.ts
|
|
3653
|
-
var
|
|
4369
|
+
var import_react10 = require("react");
|
|
3654
4370
|
function useViewBox(options) {
|
|
3655
4371
|
const {
|
|
3656
4372
|
initialViewBox,
|
|
@@ -3661,16 +4377,16 @@ function useViewBox(options) {
|
|
|
3661
4377
|
zoomSensitivity = 1e-3,
|
|
3662
4378
|
allowLeftClickPan = true
|
|
3663
4379
|
} = options;
|
|
3664
|
-
const [viewBox, setViewBox] = (0,
|
|
3665
|
-
const svgRef = (0,
|
|
3666
|
-
const isPanningRef = (0,
|
|
3667
|
-
const lastMousePosRef = (0,
|
|
3668
|
-
const spaceKeyDownRef = (0,
|
|
3669
|
-
const lastTouchDistanceRef = (0,
|
|
3670
|
-
const resetViewBox = (0,
|
|
4380
|
+
const [viewBox, setViewBox] = (0, import_react10.useState)(initialViewBox);
|
|
4381
|
+
const svgRef = (0, import_react10.useRef)(null);
|
|
4382
|
+
const isPanningRef = (0, import_react10.useRef)(false);
|
|
4383
|
+
const lastMousePosRef = (0, import_react10.useRef)({ x: 0, y: 0 });
|
|
4384
|
+
const spaceKeyDownRef = (0, import_react10.useRef)(false);
|
|
4385
|
+
const lastTouchDistanceRef = (0, import_react10.useRef)(null);
|
|
4386
|
+
const resetViewBox = (0, import_react10.useCallback)(() => {
|
|
3671
4387
|
setViewBox(initialViewBox);
|
|
3672
4388
|
}, [initialViewBox]);
|
|
3673
|
-
const zoomIn = (0,
|
|
4389
|
+
const zoomIn = (0, import_react10.useCallback)(() => {
|
|
3674
4390
|
setViewBox((prev) => {
|
|
3675
4391
|
const currentZoom = initialViewBox.width / prev.width;
|
|
3676
4392
|
const newZoom = Math.min(1 / minZoom, currentZoom * 1.25);
|
|
@@ -3687,7 +4403,7 @@ function useViewBox(options) {
|
|
|
3687
4403
|
};
|
|
3688
4404
|
});
|
|
3689
4405
|
}, [initialViewBox, minZoom]);
|
|
3690
|
-
const zoomOut = (0,
|
|
4406
|
+
const zoomOut = (0, import_react10.useCallback)(() => {
|
|
3691
4407
|
setViewBox((prev) => {
|
|
3692
4408
|
const currentZoom = initialViewBox.width / prev.width;
|
|
3693
4409
|
const newZoom = Math.max(1 / maxZoom, currentZoom * 0.8);
|
|
@@ -3704,7 +4420,7 @@ function useViewBox(options) {
|
|
|
3704
4420
|
};
|
|
3705
4421
|
});
|
|
3706
4422
|
}, [initialViewBox, maxZoom]);
|
|
3707
|
-
const fitToContent = (0,
|
|
4423
|
+
const fitToContent = (0, import_react10.useCallback)((bounds, padding = 50) => {
|
|
3708
4424
|
const contentWidth = bounds.maxX - bounds.minX;
|
|
3709
4425
|
const contentHeight = bounds.maxY - bounds.minY;
|
|
3710
4426
|
if (contentWidth === 0 || contentHeight === 0) {
|
|
@@ -3732,7 +4448,7 @@ function useViewBox(options) {
|
|
|
3732
4448
|
height: newHeight
|
|
3733
4449
|
});
|
|
3734
4450
|
}, [initialViewBox]);
|
|
3735
|
-
(0,
|
|
4451
|
+
(0, import_react10.useEffect)(() => {
|
|
3736
4452
|
if (!enableZoom || !svgRef.current) return;
|
|
3737
4453
|
const svg = svgRef.current;
|
|
3738
4454
|
const handleWheel = (e) => {
|
|
@@ -3765,7 +4481,7 @@ function useViewBox(options) {
|
|
|
3765
4481
|
svg.addEventListener("wheel", handleWheel, { passive: false });
|
|
3766
4482
|
return () => svg.removeEventListener("wheel", handleWheel);
|
|
3767
4483
|
}, [enableZoom, zoomSensitivity, minZoom, initialViewBox]);
|
|
3768
|
-
(0,
|
|
4484
|
+
(0, import_react10.useEffect)(() => {
|
|
3769
4485
|
if (!enablePan || !svgRef.current) return;
|
|
3770
4486
|
const svg = svgRef.current;
|
|
3771
4487
|
const handleMouseDown = (e) => {
|
|
@@ -3841,7 +4557,7 @@ function useViewBox(options) {
|
|
|
3841
4557
|
window.removeEventListener("keyup", handleKeyUp);
|
|
3842
4558
|
};
|
|
3843
4559
|
}, [enablePan, allowLeftClickPan]);
|
|
3844
|
-
(0,
|
|
4560
|
+
(0, import_react10.useEffect)(() => {
|
|
3845
4561
|
if (!svgRef.current) return;
|
|
3846
4562
|
if (!enablePan && !enableZoom) return;
|
|
3847
4563
|
const svg = svgRef.current;
|
|
@@ -3932,7 +4648,7 @@ function useViewBox(options) {
|
|
|
3932
4648
|
svg.removeEventListener("touchend", handleTouchEnd);
|
|
3933
4649
|
};
|
|
3934
4650
|
}, [enablePan, enableZoom, minZoom, initialViewBox]);
|
|
3935
|
-
const screenToWorld = (0,
|
|
4651
|
+
const screenToWorld = (0, import_react10.useCallback)(
|
|
3936
4652
|
(screenX, screenY) => {
|
|
3937
4653
|
const svg = svgRef.current;
|
|
3938
4654
|
if (!svg) return { x: screenX, y: screenY };
|
|
@@ -3971,15 +4687,15 @@ function useViewBox(options) {
|
|
|
3971
4687
|
}
|
|
3972
4688
|
|
|
3973
4689
|
// src/diagram/hooks/useSelection.ts
|
|
3974
|
-
var
|
|
4690
|
+
var import_react11 = require("react");
|
|
3975
4691
|
function useSelection(options = {}) {
|
|
3976
4692
|
const {
|
|
3977
4693
|
multiSelect = true,
|
|
3978
4694
|
initialSelection = { selectedNodeIds: /* @__PURE__ */ new Set(), selectedPipeIds: /* @__PURE__ */ new Set() },
|
|
3979
4695
|
onSelectionChange
|
|
3980
4696
|
} = options;
|
|
3981
|
-
const [selection, setSelection] = (0,
|
|
3982
|
-
const notifyChange = (0,
|
|
4697
|
+
const [selection, setSelection] = (0, import_react11.useState)(initialSelection);
|
|
4698
|
+
const notifyChange = (0, import_react11.useCallback)(
|
|
3983
4699
|
(newSelection) => {
|
|
3984
4700
|
if (onSelectionChange) {
|
|
3985
4701
|
onSelectionChange(newSelection);
|
|
@@ -3987,15 +4703,15 @@ function useSelection(options = {}) {
|
|
|
3987
4703
|
},
|
|
3988
4704
|
[onSelectionChange]
|
|
3989
4705
|
);
|
|
3990
|
-
const isNodeSelected = (0,
|
|
4706
|
+
const isNodeSelected = (0, import_react11.useCallback)(
|
|
3991
4707
|
(nodeId) => selection.selectedNodeIds.has(nodeId),
|
|
3992
4708
|
[selection.selectedNodeIds]
|
|
3993
4709
|
);
|
|
3994
|
-
const isPipeSelected = (0,
|
|
4710
|
+
const isPipeSelected = (0, import_react11.useCallback)(
|
|
3995
4711
|
(pipeId) => selection.selectedPipeIds.has(pipeId),
|
|
3996
4712
|
[selection.selectedPipeIds]
|
|
3997
4713
|
);
|
|
3998
|
-
const selectNode = (0,
|
|
4714
|
+
const selectNode = (0, import_react11.useCallback)(
|
|
3999
4715
|
(nodeId, isMultiSelect = false) => {
|
|
4000
4716
|
setSelection((prev) => {
|
|
4001
4717
|
const newNodeIds = new Set(isMultiSelect && multiSelect ? prev.selectedNodeIds : []);
|
|
@@ -4014,7 +4730,7 @@ function useSelection(options = {}) {
|
|
|
4014
4730
|
},
|
|
4015
4731
|
[multiSelect, notifyChange]
|
|
4016
4732
|
);
|
|
4017
|
-
const selectPipe = (0,
|
|
4733
|
+
const selectPipe = (0, import_react11.useCallback)(
|
|
4018
4734
|
(pipeId, isMultiSelect = false) => {
|
|
4019
4735
|
setSelection((prev) => {
|
|
4020
4736
|
const newPipeIds = new Set(isMultiSelect && multiSelect ? prev.selectedPipeIds : []);
|
|
@@ -4033,7 +4749,7 @@ function useSelection(options = {}) {
|
|
|
4033
4749
|
},
|
|
4034
4750
|
[multiSelect, notifyChange]
|
|
4035
4751
|
);
|
|
4036
|
-
const clearSelection = (0,
|
|
4752
|
+
const clearSelection = (0, import_react11.useCallback)(() => {
|
|
4037
4753
|
const newSelection = {
|
|
4038
4754
|
selectedNodeIds: /* @__PURE__ */ new Set(),
|
|
4039
4755
|
selectedPipeIds: /* @__PURE__ */ new Set()
|
|
@@ -4041,7 +4757,7 @@ function useSelection(options = {}) {
|
|
|
4041
4757
|
setSelection(newSelection);
|
|
4042
4758
|
notifyChange(newSelection);
|
|
4043
4759
|
}, [notifyChange]);
|
|
4044
|
-
const selectNodes = (0,
|
|
4760
|
+
const selectNodes = (0, import_react11.useCallback)(
|
|
4045
4761
|
(nodeIds) => {
|
|
4046
4762
|
const newSelection = {
|
|
4047
4763
|
selectedNodeIds: new Set(nodeIds),
|
|
@@ -4052,7 +4768,7 @@ function useSelection(options = {}) {
|
|
|
4052
4768
|
},
|
|
4053
4769
|
[notifyChange]
|
|
4054
4770
|
);
|
|
4055
|
-
const selectPipes = (0,
|
|
4771
|
+
const selectPipes = (0, import_react11.useCallback)(
|
|
4056
4772
|
(pipeIds) => {
|
|
4057
4773
|
const newSelection = {
|
|
4058
4774
|
selectedNodeIds: /* @__PURE__ */ new Set(),
|
|
@@ -4076,23 +4792,23 @@ function useSelection(options = {}) {
|
|
|
4076
4792
|
}
|
|
4077
4793
|
|
|
4078
4794
|
// src/diagram/hooks/useTelemetry.ts
|
|
4079
|
-
var
|
|
4795
|
+
var import_react12 = require("react");
|
|
4080
4796
|
function useTelemetry(options = {}) {
|
|
4081
4797
|
const {
|
|
4082
4798
|
initialBindings = [],
|
|
4083
4799
|
onTelemetryChange,
|
|
4084
4800
|
refreshInterval = 0
|
|
4085
4801
|
} = options;
|
|
4086
|
-
const [telemetry, setTelemetry] = (0,
|
|
4802
|
+
const [telemetry, setTelemetry] = (0, import_react12.useState)(() => {
|
|
4087
4803
|
const map = /* @__PURE__ */ new Map();
|
|
4088
4804
|
initialBindings.forEach((binding) => {
|
|
4089
4805
|
map.set(binding.nodeId, binding);
|
|
4090
4806
|
});
|
|
4091
4807
|
return map;
|
|
4092
4808
|
});
|
|
4093
|
-
const telemetryRef = (0,
|
|
4809
|
+
const telemetryRef = (0, import_react12.useRef)(telemetry);
|
|
4094
4810
|
telemetryRef.current = telemetry;
|
|
4095
|
-
const notifyChange = (0,
|
|
4811
|
+
const notifyChange = (0, import_react12.useCallback)(
|
|
4096
4812
|
(newTelemetry) => {
|
|
4097
4813
|
if (onTelemetryChange) {
|
|
4098
4814
|
onTelemetryChange(newTelemetry);
|
|
@@ -4100,7 +4816,7 @@ function useTelemetry(options = {}) {
|
|
|
4100
4816
|
},
|
|
4101
4817
|
[onTelemetryChange]
|
|
4102
4818
|
);
|
|
4103
|
-
const updateTelemetry = (0,
|
|
4819
|
+
const updateTelemetry = (0, import_react12.useCallback)(
|
|
4104
4820
|
(nodeId, value) => {
|
|
4105
4821
|
setTelemetry((prev) => {
|
|
4106
4822
|
const newMap = new Map(prev);
|
|
@@ -4130,7 +4846,7 @@ function useTelemetry(options = {}) {
|
|
|
4130
4846
|
},
|
|
4131
4847
|
[notifyChange]
|
|
4132
4848
|
);
|
|
4133
|
-
const updateTelemetryBatch = (0,
|
|
4849
|
+
const updateTelemetryBatch = (0, import_react12.useCallback)(
|
|
4134
4850
|
(updates) => {
|
|
4135
4851
|
setTelemetry((prev) => {
|
|
4136
4852
|
const newMap = new Map(prev);
|
|
@@ -4184,16 +4900,16 @@ function useTelemetry(options = {}) {
|
|
|
4184
4900
|
},
|
|
4185
4901
|
[notifyChange]
|
|
4186
4902
|
);
|
|
4187
|
-
const getTelemetry = (0,
|
|
4903
|
+
const getTelemetry = (0, import_react12.useCallback)(
|
|
4188
4904
|
(nodeId) => telemetryRef.current.get(nodeId),
|
|
4189
4905
|
[]
|
|
4190
4906
|
);
|
|
4191
|
-
const clearTelemetry = (0,
|
|
4907
|
+
const clearTelemetry = (0, import_react12.useCallback)(() => {
|
|
4192
4908
|
const newMap = /* @__PURE__ */ new Map();
|
|
4193
4909
|
setTelemetry(newMap);
|
|
4194
4910
|
notifyChange(newMap);
|
|
4195
4911
|
}, [notifyChange]);
|
|
4196
|
-
const setBindings = (0,
|
|
4912
|
+
const setBindings = (0, import_react12.useCallback)(
|
|
4197
4913
|
(bindings) => {
|
|
4198
4914
|
const newMap = /* @__PURE__ */ new Map();
|
|
4199
4915
|
bindings.forEach((binding) => {
|
|
@@ -4204,7 +4920,7 @@ function useTelemetry(options = {}) {
|
|
|
4204
4920
|
},
|
|
4205
4921
|
[notifyChange]
|
|
4206
4922
|
);
|
|
4207
|
-
(0,
|
|
4923
|
+
(0, import_react12.useEffect)(() => {
|
|
4208
4924
|
if (refreshInterval <= 0) return;
|
|
4209
4925
|
const intervalId = setInterval(() => {
|
|
4210
4926
|
notifyChange(telemetryRef.current);
|
|
@@ -4222,10 +4938,10 @@ function useTelemetry(options = {}) {
|
|
|
4222
4938
|
}
|
|
4223
4939
|
|
|
4224
4940
|
// src/diagram/hooks/useTelemetryStatus.ts
|
|
4225
|
-
var
|
|
4941
|
+
var import_react13 = require("react");
|
|
4226
4942
|
function useTelemetryStatus(telemetry, diagram, setDiagram, options = {}) {
|
|
4227
4943
|
const { enabled = true, mapStatus } = options;
|
|
4228
|
-
(0,
|
|
4944
|
+
(0, import_react13.useEffect)(() => {
|
|
4229
4945
|
if (!enabled) return;
|
|
4230
4946
|
const defaultMapStatus = (telemetryStatus) => {
|
|
4231
4947
|
switch (telemetryStatus) {
|
|
@@ -4264,7 +4980,7 @@ function useTelemetryStatus(telemetry, diagram, setDiagram, options = {}) {
|
|
|
4264
4980
|
}
|
|
4265
4981
|
|
|
4266
4982
|
// src/diagram/hooks/useDrag.ts
|
|
4267
|
-
var
|
|
4983
|
+
var import_react14 = require("react");
|
|
4268
4984
|
function useDrag(options = {}) {
|
|
4269
4985
|
const {
|
|
4270
4986
|
onDragStart,
|
|
@@ -4274,23 +4990,23 @@ function useDrag(options = {}) {
|
|
|
4274
4990
|
dragThreshold = 3,
|
|
4275
4991
|
screenToWorld = (x, y) => ({ x, y })
|
|
4276
4992
|
} = options;
|
|
4277
|
-
const [dragState, setDragState] = (0,
|
|
4993
|
+
const [dragState, setDragState] = (0, import_react14.useState)({
|
|
4278
4994
|
isDragging: false,
|
|
4279
4995
|
startPosition: null,
|
|
4280
4996
|
offset: { x: 0, y: 0 },
|
|
4281
4997
|
draggedId: null
|
|
4282
4998
|
});
|
|
4283
|
-
const [isListening, setIsListening] = (0,
|
|
4284
|
-
const dragStartRef = (0,
|
|
4285
|
-
const hasMovedRef = (0,
|
|
4286
|
-
const applySnap = (0,
|
|
4999
|
+
const [isListening, setIsListening] = (0, import_react14.useState)(false);
|
|
5000
|
+
const dragStartRef = (0, import_react14.useRef)(null);
|
|
5001
|
+
const hasMovedRef = (0, import_react14.useRef)(false);
|
|
5002
|
+
const applySnap = (0, import_react14.useCallback)(
|
|
4287
5003
|
(value) => {
|
|
4288
5004
|
if (snapToGrid <= 0) return value;
|
|
4289
5005
|
return Math.round(value / snapToGrid) * snapToGrid;
|
|
4290
5006
|
},
|
|
4291
5007
|
[snapToGrid]
|
|
4292
5008
|
);
|
|
4293
|
-
const handleMouseMove = (0,
|
|
5009
|
+
const handleMouseMove = (0, import_react14.useCallback)(
|
|
4294
5010
|
(event) => {
|
|
4295
5011
|
if (!dragStartRef.current) return;
|
|
4296
5012
|
const { id, screenStart: _screenStart, itemPosition, clickOffset } = dragStartRef.current;
|
|
@@ -4331,7 +5047,7 @@ function useDrag(options = {}) {
|
|
|
4331
5047
|
},
|
|
4332
5048
|
[screenToWorld, dragThreshold, applySnap, onDragStart, onDragMove]
|
|
4333
5049
|
);
|
|
4334
|
-
const handleMouseUp = (0,
|
|
5050
|
+
const handleMouseUp = (0, import_react14.useCallback)(
|
|
4335
5051
|
(event) => {
|
|
4336
5052
|
if (!dragStartRef.current || !hasMovedRef.current) {
|
|
4337
5053
|
dragStartRef.current = null;
|
|
@@ -4368,7 +5084,7 @@ function useDrag(options = {}) {
|
|
|
4368
5084
|
},
|
|
4369
5085
|
[screenToWorld, applySnap, onDragEnd]
|
|
4370
5086
|
);
|
|
4371
|
-
const handleTouchMove = (0,
|
|
5087
|
+
const handleTouchMove = (0, import_react14.useCallback)(
|
|
4372
5088
|
(event) => {
|
|
4373
5089
|
if (!dragStartRef.current || event.touches.length !== 1) return;
|
|
4374
5090
|
const touch = event.touches[0];
|
|
@@ -4411,7 +5127,7 @@ function useDrag(options = {}) {
|
|
|
4411
5127
|
},
|
|
4412
5128
|
[screenToWorld, dragThreshold, applySnap, onDragStart, onDragMove]
|
|
4413
5129
|
);
|
|
4414
|
-
const handleTouchEnd = (0,
|
|
5130
|
+
const handleTouchEnd = (0, import_react14.useCallback)(
|
|
4415
5131
|
(event) => {
|
|
4416
5132
|
if (!dragStartRef.current || !hasMovedRef.current) {
|
|
4417
5133
|
dragStartRef.current = null;
|
|
@@ -4449,7 +5165,7 @@ function useDrag(options = {}) {
|
|
|
4449
5165
|
},
|
|
4450
5166
|
[screenToWorld, applySnap, onDragEnd]
|
|
4451
5167
|
);
|
|
4452
|
-
(0,
|
|
5168
|
+
(0, import_react14.useEffect)(() => {
|
|
4453
5169
|
if (!isListening) return;
|
|
4454
5170
|
document.addEventListener("mousemove", handleMouseMove);
|
|
4455
5171
|
document.addEventListener("mouseup", handleMouseUp);
|
|
@@ -4464,7 +5180,7 @@ function useDrag(options = {}) {
|
|
|
4464
5180
|
document.removeEventListener("touchcancel", handleTouchEnd);
|
|
4465
5181
|
};
|
|
4466
5182
|
}, [isListening, handleMouseMove, handleMouseUp, handleTouchMove, handleTouchEnd]);
|
|
4467
|
-
const startDrag = (0,
|
|
5183
|
+
const startDrag = (0, import_react14.useCallback)(
|
|
4468
5184
|
(id, event, itemPosition) => {
|
|
4469
5185
|
event.stopPropagation();
|
|
4470
5186
|
let clientX;
|
|
@@ -4494,7 +5210,7 @@ function useDrag(options = {}) {
|
|
|
4494
5210
|
},
|
|
4495
5211
|
[screenToWorld]
|
|
4496
5212
|
);
|
|
4497
|
-
const cancelDrag = (0,
|
|
5213
|
+
const cancelDrag = (0, import_react14.useCallback)(() => {
|
|
4498
5214
|
dragStartRef.current = null;
|
|
4499
5215
|
hasMovedRef.current = false;
|
|
4500
5216
|
setIsListening(false);
|
|
@@ -4505,7 +5221,7 @@ function useDrag(options = {}) {
|
|
|
4505
5221
|
draggedId: null
|
|
4506
5222
|
});
|
|
4507
5223
|
}, []);
|
|
4508
|
-
const isDraggingItem = (0,
|
|
5224
|
+
const isDraggingItem = (0, import_react14.useCallback)(
|
|
4509
5225
|
(id) => dragState.isDragging && dragState.draggedId === id,
|
|
4510
5226
|
[dragState.isDragging, dragState.draggedId]
|
|
4511
5227
|
);
|
|
@@ -4518,7 +5234,7 @@ function useDrag(options = {}) {
|
|
|
4518
5234
|
}
|
|
4519
5235
|
|
|
4520
5236
|
// src/diagram/hooks/useKeyboardShortcuts.ts
|
|
4521
|
-
var
|
|
5237
|
+
var import_react15 = require("react");
|
|
4522
5238
|
function useKeyboardShortcuts(options) {
|
|
4523
5239
|
const {
|
|
4524
5240
|
onDelete,
|
|
@@ -4529,7 +5245,7 @@ function useKeyboardShortcuts(options) {
|
|
|
4529
5245
|
onSelectAll,
|
|
4530
5246
|
enabled = true
|
|
4531
5247
|
} = options;
|
|
4532
|
-
(0,
|
|
5248
|
+
(0, import_react15.useEffect)(() => {
|
|
4533
5249
|
if (!enabled) return;
|
|
4534
5250
|
const handleKeyDown = (event) => {
|
|
4535
5251
|
const target = event.target;
|
|
@@ -4638,7 +5354,7 @@ function nodeHasPort(node, portId) {
|
|
|
4638
5354
|
}
|
|
4639
5355
|
|
|
4640
5356
|
// src/components/PIDCanvas/PIDCanvas.tsx
|
|
4641
|
-
var
|
|
5357
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
4642
5358
|
function PIDCanvas({
|
|
4643
5359
|
diagram,
|
|
4644
5360
|
className = "",
|
|
@@ -4665,21 +5381,21 @@ function PIDCanvas({
|
|
|
4665
5381
|
telemetry,
|
|
4666
5382
|
...props
|
|
4667
5383
|
}) {
|
|
4668
|
-
const [localDiagram, setLocalDiagram] = (0,
|
|
4669
|
-
const [dragOverPosition, setDragOverPosition] = (0,
|
|
4670
|
-
const [isConnecting, setIsConnecting] = (0,
|
|
4671
|
-
const [connectionSource, setConnectionSource] = (0,
|
|
4672
|
-
const [connectionSourcePort, setConnectionSourcePort] = (0,
|
|
4673
|
-
const [connectionCursor, setConnectionCursor] = (0,
|
|
4674
|
-
const [hoveredNode, setHoveredNode] = (0,
|
|
4675
|
-
const [hoveredPort, setHoveredPort] = (0,
|
|
4676
|
-
const [selectedWaypoint, setSelectedWaypoint] = (0,
|
|
4677
|
-
const historyStack = (0,
|
|
4678
|
-
const redoStack = (0,
|
|
4679
|
-
const isUndoRedoAction = (0,
|
|
4680
|
-
const isInternalChange = (0,
|
|
4681
|
-
const lastInternalDiagram = (0,
|
|
4682
|
-
(0,
|
|
5384
|
+
const [localDiagram, setLocalDiagram] = (0, import_react16.useState)(diagram);
|
|
5385
|
+
const [dragOverPosition, setDragOverPosition] = (0, import_react16.useState)(null);
|
|
5386
|
+
const [isConnecting, setIsConnecting] = (0, import_react16.useState)(false);
|
|
5387
|
+
const [connectionSource, setConnectionSource] = (0, import_react16.useState)(null);
|
|
5388
|
+
const [connectionSourcePort, setConnectionSourcePort] = (0, import_react16.useState)(null);
|
|
5389
|
+
const [connectionCursor, setConnectionCursor] = (0, import_react16.useState)(null);
|
|
5390
|
+
const [hoveredNode, setHoveredNode] = (0, import_react16.useState)(null);
|
|
5391
|
+
const [hoveredPort, setHoveredPort] = (0, import_react16.useState)(null);
|
|
5392
|
+
const [selectedWaypoint, setSelectedWaypoint] = (0, import_react16.useState)(null);
|
|
5393
|
+
const historyStack = (0, import_react16.useRef)([]);
|
|
5394
|
+
const redoStack = (0, import_react16.useRef)([]);
|
|
5395
|
+
const isUndoRedoAction = (0, import_react16.useRef)(false);
|
|
5396
|
+
const isInternalChange = (0, import_react16.useRef)(false);
|
|
5397
|
+
const lastInternalDiagram = (0, import_react16.useRef)(null);
|
|
5398
|
+
(0, import_react16.useEffect)(() => {
|
|
4683
5399
|
const isExternal = !isInternalChange.current && diagram !== lastInternalDiagram.current;
|
|
4684
5400
|
if (isExternal) {
|
|
4685
5401
|
setLocalDiagram(diagram);
|
|
@@ -4701,7 +5417,7 @@ function PIDCanvas({
|
|
|
4701
5417
|
enablePan: features.pan ?? true,
|
|
4702
5418
|
enableZoom: features.zoom ?? true
|
|
4703
5419
|
});
|
|
4704
|
-
const calculateContentBounds = (0,
|
|
5420
|
+
const calculateContentBounds = (0, import_react16.useCallback)(() => {
|
|
4705
5421
|
const nodes2 = localDiagram.nodes.filter((n) => n.visible !== false);
|
|
4706
5422
|
if (nodes2.length === 0) {
|
|
4707
5423
|
return null;
|
|
@@ -4724,7 +5440,7 @@ function PIDCanvas({
|
|
|
4724
5440
|
});
|
|
4725
5441
|
return { minX, minY, maxX, maxY };
|
|
4726
5442
|
}, [localDiagram.nodes]);
|
|
4727
|
-
(0,
|
|
5443
|
+
(0, import_react16.useEffect)(() => {
|
|
4728
5444
|
if (onMounted) {
|
|
4729
5445
|
const controls = {
|
|
4730
5446
|
fitToContent: (padding = 50) => {
|
|
@@ -4765,8 +5481,8 @@ function PIDCanvas({
|
|
|
4765
5481
|
});
|
|
4766
5482
|
const dragEnabled = features.dragNodes ?? false;
|
|
4767
5483
|
const selectionEnabled = features.selection ?? false;
|
|
4768
|
-
const containerRef = (0,
|
|
4769
|
-
const pushToHistory = (0,
|
|
5484
|
+
const containerRef = (0, import_react16.useRef)(null);
|
|
5485
|
+
const pushToHistory = (0, import_react16.useCallback)((currentDiagram) => {
|
|
4770
5486
|
if (isUndoRedoAction.current) return;
|
|
4771
5487
|
const snapshot = JSON.parse(JSON.stringify(currentDiagram));
|
|
4772
5488
|
historyStack.current.push(snapshot);
|
|
@@ -4775,7 +5491,7 @@ function PIDCanvas({
|
|
|
4775
5491
|
}
|
|
4776
5492
|
redoStack.current = [];
|
|
4777
5493
|
}, []);
|
|
4778
|
-
const undo = (0,
|
|
5494
|
+
const undo = (0, import_react16.useCallback)(() => {
|
|
4779
5495
|
if (historyStack.current.length === 0) return;
|
|
4780
5496
|
isUndoRedoAction.current = true;
|
|
4781
5497
|
const currentSnapshot = JSON.parse(JSON.stringify(localDiagram));
|
|
@@ -4789,7 +5505,7 @@ function PIDCanvas({
|
|
|
4789
5505
|
isUndoRedoAction.current = false;
|
|
4790
5506
|
}, 0);
|
|
4791
5507
|
}, [localDiagram, onDiagramChange]);
|
|
4792
|
-
const redo = (0,
|
|
5508
|
+
const redo = (0, import_react16.useCallback)(() => {
|
|
4793
5509
|
if (redoStack.current.length === 0) return;
|
|
4794
5510
|
isUndoRedoAction.current = true;
|
|
4795
5511
|
const currentSnapshot = JSON.parse(JSON.stringify(localDiagram));
|
|
@@ -4803,7 +5519,7 @@ function PIDCanvas({
|
|
|
4803
5519
|
isUndoRedoAction.current = false;
|
|
4804
5520
|
}, 0);
|
|
4805
5521
|
}, [localDiagram, onDiagramChange]);
|
|
4806
|
-
(0,
|
|
5522
|
+
(0, import_react16.useEffect)(() => {
|
|
4807
5523
|
const handleKeyDown = (e) => {
|
|
4808
5524
|
const isCtrlOrCmd = e.ctrlKey || e.metaKey;
|
|
4809
5525
|
if (isCtrlOrCmd && e.key === "z" && !e.shiftKey) {
|
|
@@ -4820,7 +5536,7 @@ function PIDCanvas({
|
|
|
4820
5536
|
window.addEventListener("keydown", handleKeyDown);
|
|
4821
5537
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
4822
5538
|
}, [undo, redo]);
|
|
4823
|
-
(0,
|
|
5539
|
+
(0, import_react16.useEffect)(() => {
|
|
4824
5540
|
if (!features.dragNodes) return;
|
|
4825
5541
|
const handleKeyDown = (e) => {
|
|
4826
5542
|
if (selection.selectedNodeIds.size === 0 && !selectedWaypoint) return;
|
|
@@ -4905,7 +5621,7 @@ function PIDCanvas({
|
|
|
4905
5621
|
onNodeMove,
|
|
4906
5622
|
pushToHistory
|
|
4907
5623
|
]);
|
|
4908
|
-
const handlePositionChange = (0,
|
|
5624
|
+
const handlePositionChange = (0, import_react16.useCallback)(
|
|
4909
5625
|
(nodeId, x, y) => {
|
|
4910
5626
|
pushToHistory(localDiagram);
|
|
4911
5627
|
const updatedNodes = localDiagram.nodes.map(
|
|
@@ -4927,7 +5643,7 @@ function PIDCanvas({
|
|
|
4927
5643
|
},
|
|
4928
5644
|
[localDiagram, onDiagramChange, onNodeMove, pushToHistory]
|
|
4929
5645
|
);
|
|
4930
|
-
const handleWaypointPositionChange = (0,
|
|
5646
|
+
const handleWaypointPositionChange = (0, import_react16.useCallback)(
|
|
4931
5647
|
(pipeId, pointIndex, x, y) => {
|
|
4932
5648
|
pushToHistory(localDiagram);
|
|
4933
5649
|
const updatedPipes = localDiagram.pipes.map((pipe) => {
|
|
@@ -4945,7 +5661,7 @@ function PIDCanvas({
|
|
|
4945
5661
|
},
|
|
4946
5662
|
[localDiagram, onDiagramChange, pushToHistory]
|
|
4947
5663
|
);
|
|
4948
|
-
const handleDragEnd = (0,
|
|
5664
|
+
const handleDragEnd = (0, import_react16.useCallback)(
|
|
4949
5665
|
(nodeId, offset, finalPosition) => {
|
|
4950
5666
|
const dragDistance = Math.sqrt(offset.x ** 2 + offset.y ** 2);
|
|
4951
5667
|
if (dragDistance < 2) {
|
|
@@ -5026,7 +5742,7 @@ function PIDCanvas({
|
|
|
5026
5742
|
onDiagramChange?.(updatedDiagram);
|
|
5027
5743
|
}
|
|
5028
5744
|
});
|
|
5029
|
-
const handleNodeDragStart = (0,
|
|
5745
|
+
const handleNodeDragStart = (0, import_react16.useCallback)(
|
|
5030
5746
|
(nodeId, event) => {
|
|
5031
5747
|
const node = localDiagram.nodes.find((n) => n.id === nodeId);
|
|
5032
5748
|
if (!node) return;
|
|
@@ -5034,7 +5750,7 @@ function PIDCanvas({
|
|
|
5034
5750
|
},
|
|
5035
5751
|
[localDiagram.nodes, startDrag]
|
|
5036
5752
|
);
|
|
5037
|
-
const handleWaypointClick = (0,
|
|
5753
|
+
const handleWaypointClick = (0, import_react16.useCallback)(
|
|
5038
5754
|
(pipeId, pointIndex) => {
|
|
5039
5755
|
setSelectedWaypoint({ pipeId, pointIndex });
|
|
5040
5756
|
if (selectionEnabled) {
|
|
@@ -5043,7 +5759,7 @@ function PIDCanvas({
|
|
|
5043
5759
|
},
|
|
5044
5760
|
[selectionEnabled, clearSelection]
|
|
5045
5761
|
);
|
|
5046
|
-
const handleWaypointDragStart = (0,
|
|
5762
|
+
const handleWaypointDragStart = (0, import_react16.useCallback)(
|
|
5047
5763
|
(pipeId, pointIndex, event) => {
|
|
5048
5764
|
const pipe = localDiagram.pipes.find((p) => p.id === pipeId);
|
|
5049
5765
|
if (!pipe || pointIndex >= pipe.routePoints.length) return;
|
|
@@ -5052,7 +5768,7 @@ function PIDCanvas({
|
|
|
5052
5768
|
},
|
|
5053
5769
|
[localDiagram.pipes, startWaypointDrag]
|
|
5054
5770
|
);
|
|
5055
|
-
const handlePipeSegmentClick = (0,
|
|
5771
|
+
const handlePipeSegmentClick = (0, import_react16.useCallback)(
|
|
5056
5772
|
(pipeId, position, segmentIndex) => {
|
|
5057
5773
|
pushToHistory(localDiagram);
|
|
5058
5774
|
const updatedPipes = localDiagram.pipes.map((pipe) => {
|
|
@@ -5071,7 +5787,7 @@ function PIDCanvas({
|
|
|
5071
5787
|
[localDiagram, onDiagramChange, pushToHistory]
|
|
5072
5788
|
);
|
|
5073
5789
|
const telemetryEnabled = features.telemetry ?? false;
|
|
5074
|
-
const handleDelete = (0,
|
|
5790
|
+
const handleDelete = (0, import_react16.useCallback)(() => {
|
|
5075
5791
|
if (!selectionEnabled) return;
|
|
5076
5792
|
const { selectedNodeIds, selectedPipeIds } = selection;
|
|
5077
5793
|
if (selectedNodeIds.size === 0 && selectedPipeIds.size === 0) return;
|
|
@@ -5100,13 +5816,13 @@ function PIDCanvas({
|
|
|
5100
5816
|
onDelete,
|
|
5101
5817
|
pushToHistory
|
|
5102
5818
|
]);
|
|
5103
|
-
const handleCopy = (0,
|
|
5819
|
+
const handleCopy = (0, import_react16.useCallback)(() => {
|
|
5104
5820
|
if (!selectionEnabled) return;
|
|
5105
5821
|
const { selectedNodeIds, selectedPipeIds } = selection;
|
|
5106
5822
|
if (selectedNodeIds.size === 0 && selectedPipeIds.size === 0) return;
|
|
5107
5823
|
onItemsCopied?.(Array.from(selectedNodeIds), Array.from(selectedPipeIds));
|
|
5108
5824
|
}, [selection, selectionEnabled, onItemsCopied]);
|
|
5109
|
-
const handlePaste = (0,
|
|
5825
|
+
const handlePaste = (0, import_react16.useCallback)(() => {
|
|
5110
5826
|
if (!selectionEnabled) return;
|
|
5111
5827
|
onPaste?.();
|
|
5112
5828
|
}, [selectionEnabled, onPaste]);
|
|
@@ -5166,7 +5882,7 @@ function PIDCanvas({
|
|
|
5166
5882
|
}
|
|
5167
5883
|
setSelectedWaypoint(null);
|
|
5168
5884
|
};
|
|
5169
|
-
const handleDragOver = (0,
|
|
5885
|
+
const handleDragOver = (0, import_react16.useCallback)(
|
|
5170
5886
|
(event) => {
|
|
5171
5887
|
if (!features.allowSymbolDrop) return;
|
|
5172
5888
|
event.preventDefault();
|
|
@@ -5177,7 +5893,7 @@ function PIDCanvas({
|
|
|
5177
5893
|
},
|
|
5178
5894
|
[features.allowSymbolDrop, screenToWorld, svgRef]
|
|
5179
5895
|
);
|
|
5180
|
-
const handleDrop = (0,
|
|
5896
|
+
const handleDrop = (0, import_react16.useCallback)(
|
|
5181
5897
|
(event) => {
|
|
5182
5898
|
if (!features.allowSymbolDrop) return;
|
|
5183
5899
|
event.preventDefault();
|
|
@@ -5190,10 +5906,10 @@ function PIDCanvas({
|
|
|
5190
5906
|
},
|
|
5191
5907
|
[features.allowSymbolDrop, screenToWorld, onSymbolDrop, svgRef]
|
|
5192
5908
|
);
|
|
5193
|
-
const handleDragLeave = (0,
|
|
5909
|
+
const handleDragLeave = (0, import_react16.useCallback)(() => {
|
|
5194
5910
|
setDragOverPosition(null);
|
|
5195
5911
|
}, []);
|
|
5196
|
-
const handleMouseMove = (0,
|
|
5912
|
+
const handleMouseMove = (0, import_react16.useCallback)(
|
|
5197
5913
|
(event) => {
|
|
5198
5914
|
const connectionModeEnabled = features.connectionMode ?? false;
|
|
5199
5915
|
if (connectionModeEnabled) {
|
|
@@ -5230,7 +5946,7 @@ function PIDCanvas({
|
|
|
5230
5946
|
const viewBox = controlledViewBox;
|
|
5231
5947
|
const displayDiagram = localDiagram;
|
|
5232
5948
|
const selectedNode = selectionEnabled && selection.selectedNodeIds.size === 1 ? localDiagram.nodes.find((n) => selection.selectedNodeIds.has(n.id)) || null : null;
|
|
5233
|
-
return /* @__PURE__ */ (0,
|
|
5949
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
5234
5950
|
"div",
|
|
5235
5951
|
{
|
|
5236
5952
|
ref: containerRef,
|
|
@@ -5245,7 +5961,7 @@ function PIDCanvas({
|
|
|
5245
5961
|
},
|
|
5246
5962
|
...props,
|
|
5247
5963
|
children: [
|
|
5248
|
-
/* @__PURE__ */ (0,
|
|
5964
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
5249
5965
|
"svg",
|
|
5250
5966
|
{
|
|
5251
5967
|
ref: svgRef,
|
|
@@ -5264,15 +5980,15 @@ function PIDCanvas({
|
|
|
5264
5980
|
onDrop: handleDrop,
|
|
5265
5981
|
onDragLeave: handleDragLeave,
|
|
5266
5982
|
children: [
|
|
5267
|
-
features.showGrid !== false ? /* @__PURE__ */ (0,
|
|
5268
|
-
/* @__PURE__ */ (0,
|
|
5269
|
-
/* @__PURE__ */ (0,
|
|
5270
|
-
/* @__PURE__ */ (0,
|
|
5271
|
-
/* @__PURE__ */ (0,
|
|
5272
|
-
/* @__PURE__ */ (0,
|
|
5983
|
+
features.showGrid !== false ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
|
|
5984
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("defs", { children: [
|
|
5985
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("pattern", { id: "grid-minor", width: "5", height: "5", patternUnits: "userSpaceOnUse", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("path", { d: "M 5 0 L 0 0 0 5", fill: "none", stroke: "#e5e7eb", strokeWidth: "0.5" }) }),
|
|
5986
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("pattern", { id: "grid-major", width: "25", height: "25", patternUnits: "userSpaceOnUse", children: [
|
|
5987
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("rect", { width: "25", height: "25", fill: "url(#grid-minor)" }),
|
|
5988
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("path", { d: "M 25 0 L 0 0 0 25", fill: "none", stroke: "#d1d5db", strokeWidth: "1" })
|
|
5273
5989
|
] })
|
|
5274
5990
|
] }),
|
|
5275
|
-
/* @__PURE__ */ (0,
|
|
5991
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5276
5992
|
"rect",
|
|
5277
5993
|
{
|
|
5278
5994
|
x: Math.floor(viewBox.x / 25) * 25 - viewBox.width,
|
|
@@ -5282,7 +5998,7 @@ function PIDCanvas({
|
|
|
5282
5998
|
fill: "url(#grid-major)"
|
|
5283
5999
|
}
|
|
5284
6000
|
)
|
|
5285
|
-
] }) : /* @__PURE__ */ (0,
|
|
6001
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5286
6002
|
"rect",
|
|
5287
6003
|
{
|
|
5288
6004
|
x: Math.floor(viewBox.x / 25) * 25 - viewBox.width,
|
|
@@ -5292,7 +6008,7 @@ function PIDCanvas({
|
|
|
5292
6008
|
fill: features.backgroundColor ?? "#ffffff"
|
|
5293
6009
|
}
|
|
5294
6010
|
),
|
|
5295
|
-
/* @__PURE__ */ (0,
|
|
6011
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5296
6012
|
PipeRenderer,
|
|
5297
6013
|
{
|
|
5298
6014
|
pipes: displayDiagram.pipes,
|
|
@@ -5306,12 +6022,12 @@ function PIDCanvas({
|
|
|
5306
6022
|
onPipeSegmentClick: void 0
|
|
5307
6023
|
}
|
|
5308
6024
|
),
|
|
5309
|
-
/* @__PURE__ */ (0,
|
|
6025
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5310
6026
|
NodeRenderer,
|
|
5311
6027
|
{
|
|
5312
6028
|
nodes: displayDiagram.nodes,
|
|
5313
6029
|
selectedNodeIds: selectionEnabled ? selection.selectedNodeIds : void 0,
|
|
5314
|
-
onNodeClick: selectionEnabled || features.connectionMode ? handleNodeClick : void 0,
|
|
6030
|
+
onNodeClick: onNodeClick ? handleNodeClick : selectionEnabled || features.connectionMode ? handleNodeClick : void 0,
|
|
5315
6031
|
onNodeDoubleClick: selectionEnabled ? handleNodeDoubleClick : void 0,
|
|
5316
6032
|
enableDrag: dragEnabled && !isConnecting,
|
|
5317
6033
|
onNodeDragStart: dragEnabled && !isConnecting ? handleNodeDragStart : void 0,
|
|
@@ -5319,7 +6035,7 @@ function PIDCanvas({
|
|
|
5319
6035
|
dragOffset: dragState.offset
|
|
5320
6036
|
}
|
|
5321
6037
|
),
|
|
5322
|
-
(features.editPipeRoutes ?? false) && /* @__PURE__ */ (0,
|
|
6038
|
+
(features.editPipeRoutes ?? false) && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5323
6039
|
PipeRenderer,
|
|
5324
6040
|
{
|
|
5325
6041
|
pipes: displayDiagram.pipes,
|
|
@@ -5336,14 +6052,14 @@ function PIDCanvas({
|
|
|
5336
6052
|
onPipeSegmentClick: handlePipeSegmentClick
|
|
5337
6053
|
}
|
|
5338
6054
|
),
|
|
5339
|
-
telemetryEnabled && telemetry && /* @__PURE__ */ (0,
|
|
6055
|
+
telemetryEnabled && telemetry && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("g", { id: "layer-telemetry", children: displayDiagram.nodes.map((node) => {
|
|
5340
6056
|
const binding = telemetry.get(node.id);
|
|
5341
6057
|
if (!binding) return null;
|
|
5342
6058
|
const symbol = getSymbolDefinition(node.symbolId);
|
|
5343
6059
|
if (!symbol) return null;
|
|
5344
6060
|
const overlayX = node.transform.x + symbol.viewBox.width / 2;
|
|
5345
6061
|
const overlayY = node.transform.y + symbol.viewBox.height + 50;
|
|
5346
|
-
return /* @__PURE__ */ (0,
|
|
6062
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5347
6063
|
DataOverlay,
|
|
5348
6064
|
{
|
|
5349
6065
|
nodeId: node.id,
|
|
@@ -5355,7 +6071,7 @@ function PIDCanvas({
|
|
|
5355
6071
|
`telemetry-${node.id}`
|
|
5356
6072
|
);
|
|
5357
6073
|
}) }),
|
|
5358
|
-
dragOverPosition && /* @__PURE__ */ (0,
|
|
6074
|
+
dragOverPosition && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5359
6075
|
"circle",
|
|
5360
6076
|
{
|
|
5361
6077
|
cx: dragOverPosition.x,
|
|
@@ -5368,7 +6084,7 @@ function PIDCanvas({
|
|
|
5368
6084
|
pointerEvents: "none"
|
|
5369
6085
|
}
|
|
5370
6086
|
),
|
|
5371
|
-
isConnecting && connectionSource && connectionCursor && /* @__PURE__ */ (0,
|
|
6087
|
+
isConnecting && connectionSource && connectionCursor && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("g", { id: "connection-preview", pointerEvents: "none", children: (() => {
|
|
5372
6088
|
const sourceNode = displayDiagram.nodes.find((n) => n.id === connectionSource);
|
|
5373
6089
|
if (!sourceNode) return null;
|
|
5374
6090
|
const symbol = getSymbolDefinition(sourceNode.symbolId);
|
|
@@ -5384,8 +6100,8 @@ function PIDCanvas({
|
|
|
5384
6100
|
}
|
|
5385
6101
|
}
|
|
5386
6102
|
}
|
|
5387
|
-
return /* @__PURE__ */ (0,
|
|
5388
|
-
/* @__PURE__ */ (0,
|
|
6103
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
|
|
6104
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5389
6105
|
"circle",
|
|
5390
6106
|
{
|
|
5391
6107
|
cx: lineStartX,
|
|
@@ -5397,7 +6113,7 @@ function PIDCanvas({
|
|
|
5397
6113
|
opacity: 0.6
|
|
5398
6114
|
}
|
|
5399
6115
|
),
|
|
5400
|
-
/* @__PURE__ */ (0,
|
|
6116
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5401
6117
|
"line",
|
|
5402
6118
|
{
|
|
5403
6119
|
x1: lineStartX,
|
|
@@ -5410,7 +6126,7 @@ function PIDCanvas({
|
|
|
5410
6126
|
opacity: 0.8
|
|
5411
6127
|
}
|
|
5412
6128
|
),
|
|
5413
|
-
/* @__PURE__ */ (0,
|
|
6129
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5414
6130
|
"circle",
|
|
5415
6131
|
{
|
|
5416
6132
|
cx: connectionCursor.x,
|
|
@@ -5422,7 +6138,7 @@ function PIDCanvas({
|
|
|
5422
6138
|
)
|
|
5423
6139
|
] });
|
|
5424
6140
|
})() }),
|
|
5425
|
-
features.connectionMode && /* @__PURE__ */ (0,
|
|
6141
|
+
features.connectionMode && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("g", { id: "port-indicators", children: displayDiagram.nodes.map((node) => {
|
|
5426
6142
|
const symbol = getSymbolDefinition(node.symbolId);
|
|
5427
6143
|
if (!symbol?.ports) return null;
|
|
5428
6144
|
return symbol.ports.map((port) => {
|
|
@@ -5430,8 +6146,8 @@ function PIDCanvas({
|
|
|
5430
6146
|
if (!portPos) return null;
|
|
5431
6147
|
const isHovered = hoveredPort === port.id && hoveredNode === node.id;
|
|
5432
6148
|
const isSourcePort = node.id === connectionSource && port.id === connectionSourcePort;
|
|
5433
|
-
return /* @__PURE__ */ (0,
|
|
5434
|
-
/* @__PURE__ */ (0,
|
|
6149
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("g", { children: [
|
|
6150
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5435
6151
|
"circle",
|
|
5436
6152
|
{
|
|
5437
6153
|
cx: portPos.x,
|
|
@@ -5464,7 +6180,7 @@ function PIDCanvas({
|
|
|
5464
6180
|
}
|
|
5465
6181
|
}
|
|
5466
6182
|
),
|
|
5467
|
-
/* @__PURE__ */ (0,
|
|
6183
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5468
6184
|
"circle",
|
|
5469
6185
|
{
|
|
5470
6186
|
cx: portPos.x,
|
|
@@ -5483,7 +6199,7 @@ function PIDCanvas({
|
|
|
5483
6199
|
]
|
|
5484
6200
|
}
|
|
5485
6201
|
),
|
|
5486
|
-
features.dragNodes && /* @__PURE__ */ (0,
|
|
6202
|
+
features.dragNodes && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5487
6203
|
PositionPanel,
|
|
5488
6204
|
{
|
|
5489
6205
|
selectedNode,
|
|
@@ -5503,16 +6219,16 @@ function PIDCanvas({
|
|
|
5503
6219
|
}
|
|
5504
6220
|
|
|
5505
6221
|
// src/components/SymbolLibrary/SymbolLibrary.tsx
|
|
5506
|
-
var
|
|
5507
|
-
var
|
|
6222
|
+
var import_react17 = require("react");
|
|
6223
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
5508
6224
|
function SymbolLibrary({
|
|
5509
6225
|
className = "",
|
|
5510
6226
|
onSymbolDragStart,
|
|
5511
6227
|
showCategories = true,
|
|
5512
6228
|
categories = ["Valves", "Pumps", "Tanks", "Instruments", "Displays"]
|
|
5513
6229
|
}) {
|
|
5514
|
-
const [selectedCategory, setSelectedCategory] = (0,
|
|
5515
|
-
const [searchQuery, setSearchQuery] = (0,
|
|
6230
|
+
const [selectedCategory, setSelectedCategory] = (0, import_react17.useState)("all");
|
|
6231
|
+
const [searchQuery, setSearchQuery] = (0, import_react17.useState)("");
|
|
5516
6232
|
const symbolIds = getAvailableSymbols();
|
|
5517
6233
|
const allSymbols = symbolIds.map((id) => getSymbolDefinition(id)).filter((symbol) => symbol !== void 0);
|
|
5518
6234
|
const categoryMap = {
|
|
@@ -5533,9 +6249,9 @@ function SymbolLibrary({
|
|
|
5533
6249
|
event.dataTransfer.effectAllowed = "copy";
|
|
5534
6250
|
onSymbolDragStart?.(symbol.id, event);
|
|
5535
6251
|
};
|
|
5536
|
-
return /* @__PURE__ */ (0,
|
|
5537
|
-
/* @__PURE__ */ (0,
|
|
5538
|
-
/* @__PURE__ */ (0,
|
|
6252
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: `symbol-library ${className}`.trim(), style: styles.container, children: [
|
|
6253
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: styles.header, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h3", { style: styles.title, children: "Symbol Library" }) }),
|
|
6254
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: styles.searchContainer, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5539
6255
|
"input",
|
|
5540
6256
|
{
|
|
5541
6257
|
type: "text",
|
|
@@ -5545,8 +6261,8 @@ function SymbolLibrary({
|
|
|
5545
6261
|
style: styles.searchInput
|
|
5546
6262
|
}
|
|
5547
6263
|
) }),
|
|
5548
|
-
showCategories && /* @__PURE__ */ (0,
|
|
5549
|
-
/* @__PURE__ */ (0,
|
|
6264
|
+
showCategories && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: styles.categories, children: [
|
|
6265
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5550
6266
|
"button",
|
|
5551
6267
|
{
|
|
5552
6268
|
onClick: () => setSelectedCategory("all"),
|
|
@@ -5557,7 +6273,7 @@ function SymbolLibrary({
|
|
|
5557
6273
|
children: "All"
|
|
5558
6274
|
}
|
|
5559
6275
|
),
|
|
5560
|
-
categories.map((category) => /* @__PURE__ */ (0,
|
|
6276
|
+
categories.map((category) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5561
6277
|
"button",
|
|
5562
6278
|
{
|
|
5563
6279
|
onClick: () => setSelectedCategory(category),
|
|
@@ -5570,7 +6286,7 @@ function SymbolLibrary({
|
|
|
5570
6286
|
category
|
|
5571
6287
|
))
|
|
5572
6288
|
] }),
|
|
5573
|
-
/* @__PURE__ */ (0,
|
|
6289
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: styles.symbolGrid, children: filteredSymbols.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: styles.emptyState, children: "No symbols found" }) : filteredSymbols.map((symbol) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
5574
6290
|
"div",
|
|
5575
6291
|
{
|
|
5576
6292
|
draggable: true,
|
|
@@ -5578,15 +6294,15 @@ function SymbolLibrary({
|
|
|
5578
6294
|
style: styles.symbolCard,
|
|
5579
6295
|
title: symbol.metadata?.description || symbol.name,
|
|
5580
6296
|
children: [
|
|
5581
|
-
/* @__PURE__ */ (0,
|
|
6297
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: styles.symbolPreview, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5582
6298
|
"svg",
|
|
5583
6299
|
{
|
|
5584
6300
|
viewBox: `${symbol.viewBox.x} ${symbol.viewBox.y} ${symbol.viewBox.width} ${symbol.viewBox.height}`,
|
|
5585
6301
|
style: styles.symbolSvg,
|
|
5586
|
-
children: /* @__PURE__ */ (0,
|
|
6302
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("g", { dangerouslySetInnerHTML: { __html: symbol.svgContent } })
|
|
5587
6303
|
}
|
|
5588
6304
|
) }),
|
|
5589
|
-
/* @__PURE__ */ (0,
|
|
6305
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: styles.symbolName, children: symbol.name })
|
|
5590
6306
|
]
|
|
5591
6307
|
},
|
|
5592
6308
|
symbol.id
|
|
@@ -5695,7 +6411,7 @@ var styles = {
|
|
|
5695
6411
|
};
|
|
5696
6412
|
|
|
5697
6413
|
// src/components/NodeConfigPanel/NodeConfigPanel.tsx
|
|
5698
|
-
var
|
|
6414
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
5699
6415
|
function NodeConfigPanel({
|
|
5700
6416
|
node,
|
|
5701
6417
|
binding,
|
|
@@ -5714,15 +6430,15 @@ function NodeConfigPanel({
|
|
|
5714
6430
|
padding: "20px",
|
|
5715
6431
|
...style
|
|
5716
6432
|
};
|
|
5717
|
-
return /* @__PURE__ */ (0,
|
|
5718
|
-
/* @__PURE__ */ (0,
|
|
6433
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className, style: defaultStyle, children: [
|
|
6434
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("h2", { style: { margin: "0 0 16px 0", fontSize: "1rem", fontWeight: 600 }, children: [
|
|
5719
6435
|
"Configure: ",
|
|
5720
6436
|
node.id
|
|
5721
6437
|
] }),
|
|
5722
|
-
/* @__PURE__ */ (0,
|
|
5723
|
-
/* @__PURE__ */ (0,
|
|
5724
|
-
/* @__PURE__ */ (0,
|
|
5725
|
-
/* @__PURE__ */ (0,
|
|
6438
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { marginBottom: "20px" }, children: [
|
|
6439
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h3", { style: { fontSize: "0.875rem", fontWeight: 600, marginBottom: "8px" }, children: "Node Settings" }),
|
|
6440
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Label:" }),
|
|
6441
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
5726
6442
|
"input",
|
|
5727
6443
|
{
|
|
5728
6444
|
type: "text",
|
|
@@ -5738,10 +6454,10 @@ function NodeConfigPanel({
|
|
|
5738
6454
|
}
|
|
5739
6455
|
}
|
|
5740
6456
|
),
|
|
5741
|
-
/* @__PURE__ */ (0,
|
|
5742
|
-
/* @__PURE__ */ (0,
|
|
5743
|
-
/* @__PURE__ */ (0,
|
|
5744
|
-
/* @__PURE__ */ (0,
|
|
6457
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: "8px" }, children: [
|
|
6458
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
|
|
6459
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Label Offset X:" }),
|
|
6460
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
5745
6461
|
"input",
|
|
5746
6462
|
{
|
|
5747
6463
|
type: "number",
|
|
@@ -5762,9 +6478,9 @@ function NodeConfigPanel({
|
|
|
5762
6478
|
}
|
|
5763
6479
|
)
|
|
5764
6480
|
] }),
|
|
5765
|
-
/* @__PURE__ */ (0,
|
|
5766
|
-
/* @__PURE__ */ (0,
|
|
5767
|
-
/* @__PURE__ */ (0,
|
|
6481
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
|
|
6482
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Label Offset Y:" }),
|
|
6483
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
5768
6484
|
"input",
|
|
5769
6485
|
{
|
|
5770
6486
|
type: "number",
|
|
@@ -5786,9 +6502,9 @@ function NodeConfigPanel({
|
|
|
5786
6502
|
)
|
|
5787
6503
|
] })
|
|
5788
6504
|
] }),
|
|
5789
|
-
/* @__PURE__ */ (0,
|
|
5790
|
-
/* @__PURE__ */ (0,
|
|
5791
|
-
/* @__PURE__ */ (0,
|
|
6505
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
|
|
6506
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Label Font Size:" }),
|
|
6507
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
5792
6508
|
"input",
|
|
5793
6509
|
{
|
|
5794
6510
|
type: "number",
|
|
@@ -5808,9 +6524,9 @@ function NodeConfigPanel({
|
|
|
5808
6524
|
}
|
|
5809
6525
|
)
|
|
5810
6526
|
] }),
|
|
5811
|
-
/* @__PURE__ */ (0,
|
|
5812
|
-
/* @__PURE__ */ (0,
|
|
5813
|
-
/* @__PURE__ */ (0,
|
|
6527
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
|
|
6528
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Rotation (degrees):" }),
|
|
6529
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
5814
6530
|
"input",
|
|
5815
6531
|
{
|
|
5816
6532
|
type: "number",
|
|
@@ -5835,9 +6551,9 @@ function NodeConfigPanel({
|
|
|
5835
6551
|
)
|
|
5836
6552
|
] })
|
|
5837
6553
|
] }),
|
|
5838
|
-
/* @__PURE__ */ (0,
|
|
5839
|
-
/* @__PURE__ */ (0,
|
|
5840
|
-
!binding ? /* @__PURE__ */ (0,
|
|
6554
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { marginBottom: "20px" }, children: [
|
|
6555
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h3", { style: { fontSize: "0.875rem", fontWeight: 600, marginBottom: "8px" }, children: "Telemetry Data" }),
|
|
6556
|
+
!binding ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
5841
6557
|
"button",
|
|
5842
6558
|
{
|
|
5843
6559
|
onClick: () => {
|
|
@@ -5880,9 +6596,9 @@ function NodeConfigPanel({
|
|
|
5880
6596
|
},
|
|
5881
6597
|
children: "+ Add Telemetry"
|
|
5882
6598
|
}
|
|
5883
|
-
) : /* @__PURE__ */ (0,
|
|
5884
|
-
/* @__PURE__ */ (0,
|
|
5885
|
-
/* @__PURE__ */ (0,
|
|
6599
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
6600
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Initial Value:" }),
|
|
6601
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
5886
6602
|
"input",
|
|
5887
6603
|
{
|
|
5888
6604
|
type: "number",
|
|
@@ -5904,8 +6620,8 @@ function NodeConfigPanel({
|
|
|
5904
6620
|
}
|
|
5905
6621
|
}
|
|
5906
6622
|
),
|
|
5907
|
-
/* @__PURE__ */ (0,
|
|
5908
|
-
/* @__PURE__ */ (0,
|
|
6623
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Unit:" }),
|
|
6624
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
5909
6625
|
"input",
|
|
5910
6626
|
{
|
|
5911
6627
|
type: "text",
|
|
@@ -5927,8 +6643,8 @@ function NodeConfigPanel({
|
|
|
5927
6643
|
}
|
|
5928
6644
|
}
|
|
5929
6645
|
),
|
|
5930
|
-
/* @__PURE__ */ (0,
|
|
5931
|
-
/* @__PURE__ */ (0,
|
|
6646
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: [
|
|
6647
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
5932
6648
|
"input",
|
|
5933
6649
|
{
|
|
5934
6650
|
type: "checkbox",
|
|
@@ -5950,8 +6666,8 @@ function NodeConfigPanel({
|
|
|
5950
6666
|
),
|
|
5951
6667
|
"Show Sparkline"
|
|
5952
6668
|
] }),
|
|
5953
|
-
/* @__PURE__ */ (0,
|
|
5954
|
-
/* @__PURE__ */ (0,
|
|
6669
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { marginTop: "12px" }, children: [
|
|
6670
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
5955
6671
|
"label",
|
|
5956
6672
|
{
|
|
5957
6673
|
style: {
|
|
@@ -5963,10 +6679,10 @@ function NodeConfigPanel({
|
|
|
5963
6679
|
children: "Telemetry Position Offset:"
|
|
5964
6680
|
}
|
|
5965
6681
|
),
|
|
5966
|
-
/* @__PURE__ */ (0,
|
|
5967
|
-
/* @__PURE__ */ (0,
|
|
5968
|
-
/* @__PURE__ */ (0,
|
|
5969
|
-
/* @__PURE__ */ (0,
|
|
6682
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: "8px" }, children: [
|
|
6683
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
|
|
6684
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "X Offset:" }),
|
|
6685
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
5970
6686
|
"input",
|
|
5971
6687
|
{
|
|
5972
6688
|
type: "number",
|
|
@@ -5993,9 +6709,9 @@ function NodeConfigPanel({
|
|
|
5993
6709
|
}
|
|
5994
6710
|
)
|
|
5995
6711
|
] }),
|
|
5996
|
-
/* @__PURE__ */ (0,
|
|
5997
|
-
/* @__PURE__ */ (0,
|
|
5998
|
-
/* @__PURE__ */ (0,
|
|
6712
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
|
|
6713
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "Y Offset:" }),
|
|
6714
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
5999
6715
|
"input",
|
|
6000
6716
|
{
|
|
6001
6717
|
type: "number",
|
|
@@ -6023,8 +6739,8 @@ function NodeConfigPanel({
|
|
|
6023
6739
|
)
|
|
6024
6740
|
] })
|
|
6025
6741
|
] }),
|
|
6026
|
-
/* @__PURE__ */ (0,
|
|
6027
|
-
/* @__PURE__ */ (0,
|
|
6742
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { marginTop: "16px" }, children: [
|
|
6743
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6028
6744
|
"label",
|
|
6029
6745
|
{
|
|
6030
6746
|
style: {
|
|
@@ -6036,10 +6752,10 @@ function NodeConfigPanel({
|
|
|
6036
6752
|
children: "Display Colors:"
|
|
6037
6753
|
}
|
|
6038
6754
|
),
|
|
6039
|
-
/* @__PURE__ */ (0,
|
|
6040
|
-
/* @__PURE__ */ (0,
|
|
6041
|
-
/* @__PURE__ */ (0,
|
|
6042
|
-
/* @__PURE__ */ (0,
|
|
6755
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { marginBottom: "8px" }, children: [
|
|
6756
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "Text Color:" }),
|
|
6757
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", gap: "8px", alignItems: "center" }, children: [
|
|
6758
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6043
6759
|
"input",
|
|
6044
6760
|
{
|
|
6045
6761
|
type: "color",
|
|
@@ -6065,7 +6781,7 @@ function NodeConfigPanel({
|
|
|
6065
6781
|
}
|
|
6066
6782
|
}
|
|
6067
6783
|
),
|
|
6068
|
-
/* @__PURE__ */ (0,
|
|
6784
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6069
6785
|
"input",
|
|
6070
6786
|
{
|
|
6071
6787
|
type: "text",
|
|
@@ -6095,10 +6811,10 @@ function NodeConfigPanel({
|
|
|
6095
6811
|
)
|
|
6096
6812
|
] })
|
|
6097
6813
|
] }),
|
|
6098
|
-
binding.display?.showSparkline && /* @__PURE__ */ (0,
|
|
6099
|
-
/* @__PURE__ */ (0,
|
|
6100
|
-
/* @__PURE__ */ (0,
|
|
6101
|
-
/* @__PURE__ */ (0,
|
|
6814
|
+
binding.display?.showSparkline && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { marginBottom: "8px" }, children: [
|
|
6815
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "Sparkline Color:" }),
|
|
6816
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", gap: "8px", alignItems: "center" }, children: [
|
|
6817
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6102
6818
|
"input",
|
|
6103
6819
|
{
|
|
6104
6820
|
type: "color",
|
|
@@ -6124,7 +6840,7 @@ function NodeConfigPanel({
|
|
|
6124
6840
|
}
|
|
6125
6841
|
}
|
|
6126
6842
|
),
|
|
6127
|
-
/* @__PURE__ */ (0,
|
|
6843
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6128
6844
|
"input",
|
|
6129
6845
|
{
|
|
6130
6846
|
type: "text",
|
|
@@ -6154,9 +6870,9 @@ function NodeConfigPanel({
|
|
|
6154
6870
|
)
|
|
6155
6871
|
] })
|
|
6156
6872
|
] }),
|
|
6157
|
-
/* @__PURE__ */ (0,
|
|
6158
|
-
/* @__PURE__ */ (0,
|
|
6159
|
-
/* @__PURE__ */ (0,
|
|
6873
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { marginBottom: "8px" }, children: [
|
|
6874
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "Background:" }),
|
|
6875
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6160
6876
|
"input",
|
|
6161
6877
|
{
|
|
6162
6878
|
type: "text",
|
|
@@ -6184,20 +6900,20 @@ function NodeConfigPanel({
|
|
|
6184
6900
|
}
|
|
6185
6901
|
}
|
|
6186
6902
|
),
|
|
6187
|
-
/* @__PURE__ */ (0,
|
|
6903
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { fontSize: "0.65rem", color: "#6b7280", marginTop: "2px" }, children: "Use 'status' for status-based color or hex code" })
|
|
6188
6904
|
] })
|
|
6189
6905
|
] }),
|
|
6190
6906
|
" "
|
|
6191
6907
|
] })
|
|
6192
6908
|
] })
|
|
6193
6909
|
] }),
|
|
6194
|
-
binding && /* @__PURE__ */ (0,
|
|
6195
|
-
/* @__PURE__ */ (0,
|
|
6910
|
+
binding && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { marginBottom: "20px" }, children: [
|
|
6911
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h3", { style: { fontSize: "0.875rem", fontWeight: 600, marginBottom: "8px" }, children: "Thresholds" }),
|
|
6196
6912
|
["highHigh", "high", "low", "lowLow"].map((key) => {
|
|
6197
6913
|
const label = key === "highHigh" ? "High-High (\u2265)" : key === "high" ? "High (\u2265)" : key === "low" ? "Low (\u2264)" : "Low-Low (\u2264)";
|
|
6198
|
-
return /* @__PURE__ */ (0,
|
|
6199
|
-
/* @__PURE__ */ (0,
|
|
6200
|
-
/* @__PURE__ */ (0,
|
|
6914
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { marginBottom: "8px" }, children: [
|
|
6915
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: label }),
|
|
6916
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6201
6917
|
"input",
|
|
6202
6918
|
{
|
|
6203
6919
|
type: "number",
|
|
@@ -6221,8 +6937,8 @@ function NodeConfigPanel({
|
|
|
6221
6937
|
] }, key);
|
|
6222
6938
|
})
|
|
6223
6939
|
] }),
|
|
6224
|
-
binding && /* @__PURE__ */ (0,
|
|
6225
|
-
/* @__PURE__ */ (0,
|
|
6940
|
+
binding && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { marginBottom: "20px" }, children: [
|
|
6941
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h3", { style: { fontSize: "0.875rem", fontWeight: 600, marginBottom: "8px" }, children: "Status Colors" }),
|
|
6226
6942
|
["normal", "warning", "alarm", "fault", "off"].map((status) => {
|
|
6227
6943
|
const defaultColors = {
|
|
6228
6944
|
normal: "#10b981",
|
|
@@ -6232,13 +6948,13 @@ function NodeConfigPanel({
|
|
|
6232
6948
|
off: "#6b7280"
|
|
6233
6949
|
};
|
|
6234
6950
|
const label = status === "normal" ? "Normal" : status === "warning" ? "Warning" : status === "alarm" ? "Alarm" : status === "fault" ? "Fault" : "Off";
|
|
6235
|
-
return /* @__PURE__ */ (0,
|
|
6236
|
-
/* @__PURE__ */ (0,
|
|
6951
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { marginBottom: "8px" }, children: [
|
|
6952
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: [
|
|
6237
6953
|
label,
|
|
6238
6954
|
":"
|
|
6239
6955
|
] }),
|
|
6240
|
-
/* @__PURE__ */ (0,
|
|
6241
|
-
/* @__PURE__ */ (0,
|
|
6956
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", gap: "8px", alignItems: "center" }, children: [
|
|
6957
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6242
6958
|
"input",
|
|
6243
6959
|
{
|
|
6244
6960
|
type: "color",
|
|
@@ -6259,7 +6975,7 @@ function NodeConfigPanel({
|
|
|
6259
6975
|
}
|
|
6260
6976
|
}
|
|
6261
6977
|
),
|
|
6262
|
-
/* @__PURE__ */ (0,
|
|
6978
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6263
6979
|
"input",
|
|
6264
6980
|
{
|
|
6265
6981
|
type: "text",
|
|
@@ -6286,7 +7002,7 @@ function NodeConfigPanel({
|
|
|
6286
7002
|
] }, status);
|
|
6287
7003
|
})
|
|
6288
7004
|
] }),
|
|
6289
|
-
/* @__PURE__ */ (0,
|
|
7005
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { marginTop: "20px", paddingTop: "20px", borderTop: "1px solid #cbd5e1" }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6290
7006
|
"button",
|
|
6291
7007
|
{
|
|
6292
7008
|
onClick: onRemove,
|
|
@@ -6525,8 +7241,280 @@ var DEFAULT_THRESHOLDS = {
|
|
|
6525
7241
|
lowLow: 15
|
|
6526
7242
|
};
|
|
6527
7243
|
|
|
7244
|
+
// src/diagram/schema/DeviceControlBinding.ts
|
|
7245
|
+
function createControlBinding(nodeId, deviceConfig, actions) {
|
|
7246
|
+
const parametersByMode = {};
|
|
7247
|
+
deviceConfig.parameters.forEach((param) => {
|
|
7248
|
+
const modes = param.modes || deviceConfig.modes.map((m) => m.value);
|
|
7249
|
+
modes.forEach((mode) => {
|
|
7250
|
+
if (!parametersByMode[mode]) {
|
|
7251
|
+
parametersByMode[mode] = [];
|
|
7252
|
+
}
|
|
7253
|
+
parametersByMode[mode].push({
|
|
7254
|
+
id: param.id,
|
|
7255
|
+
label: param.label,
|
|
7256
|
+
unit: param.unit,
|
|
7257
|
+
min: param.min,
|
|
7258
|
+
max: param.max,
|
|
7259
|
+
value: param.value,
|
|
7260
|
+
type: typeof param.value === "number" ? "number" : "string"
|
|
7261
|
+
});
|
|
7262
|
+
});
|
|
7263
|
+
});
|
|
7264
|
+
return {
|
|
7265
|
+
nodeId,
|
|
7266
|
+
tag: deviceConfig.tag,
|
|
7267
|
+
deviceName: deviceConfig.name,
|
|
7268
|
+
deviceType: deviceConfig.type,
|
|
7269
|
+
modes: deviceConfig.modes,
|
|
7270
|
+
state: {
|
|
7271
|
+
currentMode: deviceConfig.currentMode,
|
|
7272
|
+
isRunning: deviceConfig.isRunning,
|
|
7273
|
+
status: deviceConfig.status
|
|
7274
|
+
},
|
|
7275
|
+
parameters: parametersByMode,
|
|
7276
|
+
capabilities: deviceConfig.capabilities,
|
|
7277
|
+
actions
|
|
7278
|
+
};
|
|
7279
|
+
}
|
|
7280
|
+
|
|
7281
|
+
// src/hooks/useDeviceControls.ts
|
|
7282
|
+
var import_react18 = require("react");
|
|
7283
|
+
function useDeviceControls(initialBindings) {
|
|
7284
|
+
const [controls, setControls] = (0, import_react18.useState)(() => {
|
|
7285
|
+
const map = /* @__PURE__ */ new Map();
|
|
7286
|
+
if (initialBindings) {
|
|
7287
|
+
initialBindings.forEach((binding) => {
|
|
7288
|
+
map.set(binding.nodeId, binding);
|
|
7289
|
+
});
|
|
7290
|
+
}
|
|
7291
|
+
return map;
|
|
7292
|
+
});
|
|
7293
|
+
const updateControl = (0, import_react18.useCallback)((nodeId, updates) => {
|
|
7294
|
+
setControls((prev) => {
|
|
7295
|
+
const newMap = new Map(prev);
|
|
7296
|
+
const existing = newMap.get(nodeId);
|
|
7297
|
+
if (existing) {
|
|
7298
|
+
newMap.set(nodeId, { ...existing, ...updates });
|
|
7299
|
+
} else {
|
|
7300
|
+
if ("tag" in updates && "modes" in updates && "state" in updates && "parameters" in updates && "actions" in updates) {
|
|
7301
|
+
newMap.set(nodeId, { nodeId, ...updates });
|
|
7302
|
+
}
|
|
7303
|
+
}
|
|
7304
|
+
return newMap;
|
|
7305
|
+
});
|
|
7306
|
+
}, []);
|
|
7307
|
+
const updateControlBatch = (0, import_react18.useCallback)((updates) => {
|
|
7308
|
+
setControls((prev) => {
|
|
7309
|
+
const newMap = new Map(prev);
|
|
7310
|
+
Object.entries(updates).forEach(([nodeId, update]) => {
|
|
7311
|
+
const existing = newMap.get(nodeId);
|
|
7312
|
+
if (existing) {
|
|
7313
|
+
newMap.set(nodeId, { ...existing, ...update });
|
|
7314
|
+
}
|
|
7315
|
+
});
|
|
7316
|
+
return newMap;
|
|
7317
|
+
});
|
|
7318
|
+
}, []);
|
|
7319
|
+
const updateDeviceState = (0, import_react18.useCallback)(
|
|
7320
|
+
(nodeId, stateUpdates) => {
|
|
7321
|
+
setControls((prev) => {
|
|
7322
|
+
const newMap = new Map(prev);
|
|
7323
|
+
const existing = newMap.get(nodeId);
|
|
7324
|
+
if (existing) {
|
|
7325
|
+
newMap.set(nodeId, {
|
|
7326
|
+
...existing,
|
|
7327
|
+
state: { ...existing.state, ...stateUpdates }
|
|
7328
|
+
});
|
|
7329
|
+
}
|
|
7330
|
+
return newMap;
|
|
7331
|
+
});
|
|
7332
|
+
},
|
|
7333
|
+
[]
|
|
7334
|
+
);
|
|
7335
|
+
const updateParameter = (0, import_react18.useCallback)(
|
|
7336
|
+
(nodeId, parameterId, value) => {
|
|
7337
|
+
setControls((prev) => {
|
|
7338
|
+
const newMap = new Map(prev);
|
|
7339
|
+
const existing = newMap.get(nodeId);
|
|
7340
|
+
if (existing) {
|
|
7341
|
+
const updatedParameters = { ...existing.parameters };
|
|
7342
|
+
Object.keys(updatedParameters).forEach((mode) => {
|
|
7343
|
+
const paramIndex = updatedParameters[mode].findIndex((p) => p.id === parameterId);
|
|
7344
|
+
if (paramIndex !== -1) {
|
|
7345
|
+
updatedParameters[mode] = [...updatedParameters[mode]];
|
|
7346
|
+
updatedParameters[mode][paramIndex] = {
|
|
7347
|
+
...updatedParameters[mode][paramIndex],
|
|
7348
|
+
value
|
|
7349
|
+
};
|
|
7350
|
+
}
|
|
7351
|
+
});
|
|
7352
|
+
newMap.set(nodeId, {
|
|
7353
|
+
...existing,
|
|
7354
|
+
parameters: updatedParameters
|
|
7355
|
+
});
|
|
7356
|
+
}
|
|
7357
|
+
return newMap;
|
|
7358
|
+
});
|
|
7359
|
+
},
|
|
7360
|
+
[]
|
|
7361
|
+
);
|
|
7362
|
+
const setControlBinding = (0, import_react18.useCallback)((binding) => {
|
|
7363
|
+
setControls((prev) => {
|
|
7364
|
+
const newMap = new Map(prev);
|
|
7365
|
+
newMap.set(binding.nodeId, binding);
|
|
7366
|
+
return newMap;
|
|
7367
|
+
});
|
|
7368
|
+
}, []);
|
|
7369
|
+
const removeControlBinding = (0, import_react18.useCallback)((nodeId) => {
|
|
7370
|
+
setControls((prev) => {
|
|
7371
|
+
const newMap = new Map(prev);
|
|
7372
|
+
newMap.delete(nodeId);
|
|
7373
|
+
return newMap;
|
|
7374
|
+
});
|
|
7375
|
+
}, []);
|
|
7376
|
+
const getControlBinding = (0, import_react18.useCallback)(
|
|
7377
|
+
(nodeId) => {
|
|
7378
|
+
return controls.get(nodeId);
|
|
7379
|
+
},
|
|
7380
|
+
[controls]
|
|
7381
|
+
);
|
|
7382
|
+
const sendModeChange = (0, import_react18.useCallback)(
|
|
7383
|
+
async (nodeId, mode) => {
|
|
7384
|
+
const binding = controls.get(nodeId);
|
|
7385
|
+
if (!binding) return;
|
|
7386
|
+
updateDeviceState(nodeId, { currentMode: mode });
|
|
7387
|
+
try {
|
|
7388
|
+
await binding.actions.onModeChange?.(mode);
|
|
7389
|
+
updateDeviceState(nodeId, {
|
|
7390
|
+
lastCommandTime: Date.now(),
|
|
7391
|
+
lastCommandResult: { success: true, message: `Mode changed to ${mode}` }
|
|
7392
|
+
});
|
|
7393
|
+
} catch (error) {
|
|
7394
|
+
updateDeviceState(nodeId, {
|
|
7395
|
+
currentMode: binding.state.currentMode,
|
|
7396
|
+
lastCommandResult: {
|
|
7397
|
+
success: false,
|
|
7398
|
+
message: error instanceof Error ? error.message : "Mode change failed"
|
|
7399
|
+
}
|
|
7400
|
+
});
|
|
7401
|
+
}
|
|
7402
|
+
},
|
|
7403
|
+
[controls, updateDeviceState]
|
|
7404
|
+
);
|
|
7405
|
+
const sendParameterChange = (0, import_react18.useCallback)(
|
|
7406
|
+
async (nodeId, parameterId, value) => {
|
|
7407
|
+
const binding = controls.get(nodeId);
|
|
7408
|
+
if (!binding) return;
|
|
7409
|
+
updateParameter(nodeId, parameterId, value);
|
|
7410
|
+
try {
|
|
7411
|
+
await binding.actions.onParameterChange?.(parameterId, value);
|
|
7412
|
+
updateDeviceState(nodeId, {
|
|
7413
|
+
lastCommandTime: Date.now(),
|
|
7414
|
+
lastCommandResult: { success: true, message: `Parameter ${parameterId} updated` }
|
|
7415
|
+
});
|
|
7416
|
+
} catch (error) {
|
|
7417
|
+
updateDeviceState(nodeId, {
|
|
7418
|
+
lastCommandResult: {
|
|
7419
|
+
success: false,
|
|
7420
|
+
message: error instanceof Error ? error.message : "Parameter change failed"
|
|
7421
|
+
}
|
|
7422
|
+
});
|
|
7423
|
+
}
|
|
7424
|
+
},
|
|
7425
|
+
[controls, updateParameter, updateDeviceState]
|
|
7426
|
+
);
|
|
7427
|
+
const sendStartCommand = (0, import_react18.useCallback)(
|
|
7428
|
+
async (nodeId) => {
|
|
7429
|
+
const binding = controls.get(nodeId);
|
|
7430
|
+
if (!binding) return;
|
|
7431
|
+
updateDeviceState(nodeId, { isRunning: true, status: "starting" });
|
|
7432
|
+
try {
|
|
7433
|
+
await binding.actions.onStart?.();
|
|
7434
|
+
updateDeviceState(nodeId, {
|
|
7435
|
+
status: "normal",
|
|
7436
|
+
lastCommandTime: Date.now(),
|
|
7437
|
+
lastCommandResult: { success: true, message: "Device started" }
|
|
7438
|
+
});
|
|
7439
|
+
} catch (error) {
|
|
7440
|
+
updateDeviceState(nodeId, {
|
|
7441
|
+
isRunning: false,
|
|
7442
|
+
status: "fault",
|
|
7443
|
+
lastCommandResult: {
|
|
7444
|
+
success: false,
|
|
7445
|
+
message: error instanceof Error ? error.message : "Start failed"
|
|
7446
|
+
}
|
|
7447
|
+
});
|
|
7448
|
+
}
|
|
7449
|
+
},
|
|
7450
|
+
[controls, updateDeviceState]
|
|
7451
|
+
);
|
|
7452
|
+
const sendStopCommand = (0, import_react18.useCallback)(
|
|
7453
|
+
async (nodeId) => {
|
|
7454
|
+
const binding = controls.get(nodeId);
|
|
7455
|
+
if (!binding) return;
|
|
7456
|
+
updateDeviceState(nodeId, { isRunning: false, status: "stopping" });
|
|
7457
|
+
try {
|
|
7458
|
+
await binding.actions.onStop?.();
|
|
7459
|
+
updateDeviceState(nodeId, {
|
|
7460
|
+
status: "off",
|
|
7461
|
+
lastCommandTime: Date.now(),
|
|
7462
|
+
lastCommandResult: { success: true, message: "Device stopped" }
|
|
7463
|
+
});
|
|
7464
|
+
} catch (error) {
|
|
7465
|
+
updateDeviceState(nodeId, {
|
|
7466
|
+
isRunning: true,
|
|
7467
|
+
status: "fault",
|
|
7468
|
+
lastCommandResult: {
|
|
7469
|
+
success: false,
|
|
7470
|
+
message: error instanceof Error ? error.message : "Stop failed"
|
|
7471
|
+
}
|
|
7472
|
+
});
|
|
7473
|
+
}
|
|
7474
|
+
},
|
|
7475
|
+
[controls, updateDeviceState]
|
|
7476
|
+
);
|
|
7477
|
+
const sendCustomAction = (0, import_react18.useCallback)(
|
|
7478
|
+
async (nodeId, actionId) => {
|
|
7479
|
+
const binding = controls.get(nodeId);
|
|
7480
|
+
if (!binding) return;
|
|
7481
|
+
try {
|
|
7482
|
+
await binding.actions.onCustomAction?.(actionId);
|
|
7483
|
+
updateDeviceState(nodeId, {
|
|
7484
|
+
lastCommandTime: Date.now(),
|
|
7485
|
+
lastCommandResult: { success: true, message: `Action ${actionId} executed` }
|
|
7486
|
+
});
|
|
7487
|
+
} catch (error) {
|
|
7488
|
+
updateDeviceState(nodeId, {
|
|
7489
|
+
lastCommandResult: {
|
|
7490
|
+
success: false,
|
|
7491
|
+
message: error instanceof Error ? error.message : "Action failed"
|
|
7492
|
+
}
|
|
7493
|
+
});
|
|
7494
|
+
}
|
|
7495
|
+
},
|
|
7496
|
+
[controls, updateDeviceState]
|
|
7497
|
+
);
|
|
7498
|
+
return {
|
|
7499
|
+
controls,
|
|
7500
|
+
updateControl,
|
|
7501
|
+
updateControlBatch,
|
|
7502
|
+
updateDeviceState,
|
|
7503
|
+
updateParameter,
|
|
7504
|
+
setControlBinding,
|
|
7505
|
+
removeControlBinding,
|
|
7506
|
+
getControlBinding,
|
|
7507
|
+
// Command helpers
|
|
7508
|
+
sendModeChange,
|
|
7509
|
+
sendParameterChange,
|
|
7510
|
+
sendStartCommand,
|
|
7511
|
+
sendStopCommand,
|
|
7512
|
+
sendCustomAction
|
|
7513
|
+
};
|
|
7514
|
+
}
|
|
7515
|
+
|
|
6528
7516
|
// src/diagram/hooks/useSimulation.ts
|
|
6529
|
-
var
|
|
7517
|
+
var import_react19 = require("react");
|
|
6530
7518
|
function useSimulation(telemetry, updateTelemetryBatch, options = {}) {
|
|
6531
7519
|
const {
|
|
6532
7520
|
interval = 2e3,
|
|
@@ -6537,7 +7525,7 @@ function useSimulation(telemetry, updateTelemetryBatch, options = {}) {
|
|
|
6537
7525
|
historyLength = 10,
|
|
6538
7526
|
generateValue
|
|
6539
7527
|
} = options;
|
|
6540
|
-
(0,
|
|
7528
|
+
(0, import_react19.useEffect)(() => {
|
|
6541
7529
|
if (!enabled) return;
|
|
6542
7530
|
const intervalId = setInterval(() => {
|
|
6543
7531
|
const updates = [];
|
|
@@ -6595,6 +7583,7 @@ function useSimulation(telemetry, updateTelemetryBatch, options = {}) {
|
|
|
6595
7583
|
ControlPanel,
|
|
6596
7584
|
DEFAULT_THRESHOLDS,
|
|
6597
7585
|
DashboardCard,
|
|
7586
|
+
DeviceControlPanel,
|
|
6598
7587
|
DisplayModeToggle,
|
|
6599
7588
|
EquipmentIndicator,
|
|
6600
7589
|
EquipmentIndicatorWithSparkline,
|
|
@@ -6606,6 +7595,7 @@ function useSimulation(telemetry, updateTelemetryBatch, options = {}) {
|
|
|
6606
7595
|
LeftToggleButton,
|
|
6607
7596
|
LegacyValueEntry,
|
|
6608
7597
|
NodeConfigPanel,
|
|
7598
|
+
NodeControlsPanel,
|
|
6609
7599
|
PIDCanvas,
|
|
6610
7600
|
PanelContent,
|
|
6611
7601
|
PanelTabs,
|
|
@@ -6625,6 +7615,7 @@ function useSimulation(telemetry, updateTelemetryBatch, options = {}) {
|
|
|
6625
7615
|
ZoomButton,
|
|
6626
7616
|
ZoomControls,
|
|
6627
7617
|
calculateThresholdStatus,
|
|
7618
|
+
createControlBinding,
|
|
6628
7619
|
exampleDiagram,
|
|
6629
7620
|
exportDiagram,
|
|
6630
7621
|
generateRoutePoints,
|
|
@@ -6637,6 +7628,7 @@ function useSimulation(telemetry, updateTelemetryBatch, options = {}) {
|
|
|
6637
7628
|
overlayStyles,
|
|
6638
7629
|
registerSymbol,
|
|
6639
7630
|
registerSymbols,
|
|
7631
|
+
useDeviceControls,
|
|
6640
7632
|
useDrag,
|
|
6641
7633
|
useKeyboardShortcuts,
|
|
6642
7634
|
useSelection,
|