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