@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.js
CHANGED
|
@@ -707,14 +707,723 @@ var StatusIndicator = ({
|
|
|
707
707
|
] });
|
|
708
708
|
};
|
|
709
709
|
|
|
710
|
+
// src/components/NodeControlsPanel/NodeControlsPanel.tsx
|
|
711
|
+
import { Fragment, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
712
|
+
var NodeControlsPanel = ({
|
|
713
|
+
config,
|
|
714
|
+
onClose,
|
|
715
|
+
position = "bottom",
|
|
716
|
+
touchOptimized = true,
|
|
717
|
+
className = "",
|
|
718
|
+
style,
|
|
719
|
+
...props
|
|
720
|
+
}) => {
|
|
721
|
+
if (!config) return null;
|
|
722
|
+
const isBottom = position === "bottom";
|
|
723
|
+
const touchClass = touchOptimized ? "touch-optimized" : "";
|
|
724
|
+
const containerStyle = {
|
|
725
|
+
position: "fixed",
|
|
726
|
+
zIndex: 9999,
|
|
727
|
+
background: "white",
|
|
728
|
+
boxShadow: "0 -4px 16px rgba(0, 0, 0, 0.15)",
|
|
729
|
+
borderRadius: isBottom ? "16px 16px 0 0" : "0",
|
|
730
|
+
animation: isBottom ? "slideUp 0.3s ease-out" : "slideInRight 0.3s ease-out",
|
|
731
|
+
display: "flex",
|
|
732
|
+
flexDirection: "column",
|
|
733
|
+
...isBottom ? {
|
|
734
|
+
left: 0,
|
|
735
|
+
right: 0,
|
|
736
|
+
bottom: 0,
|
|
737
|
+
maxHeight: "70vh",
|
|
738
|
+
borderTop: "1px solid #e5e7eb"
|
|
739
|
+
} : {
|
|
740
|
+
right: 0,
|
|
741
|
+
top: 0,
|
|
742
|
+
bottom: 0,
|
|
743
|
+
width: touchOptimized ? "400px" : "320px",
|
|
744
|
+
borderLeft: "1px solid #e5e7eb"
|
|
745
|
+
},
|
|
746
|
+
...style
|
|
747
|
+
};
|
|
748
|
+
const headerStyle = {
|
|
749
|
+
display: "flex",
|
|
750
|
+
alignItems: "center",
|
|
751
|
+
justifyContent: "space-between",
|
|
752
|
+
padding: touchOptimized ? "1.25rem 1.5rem" : "1rem",
|
|
753
|
+
borderBottom: "2px solid #e5e7eb",
|
|
754
|
+
background: "#f9fafb",
|
|
755
|
+
flexShrink: 0
|
|
756
|
+
};
|
|
757
|
+
const titleStyle = {
|
|
758
|
+
margin: 0,
|
|
759
|
+
fontSize: touchOptimized ? "1.5rem" : "1.25rem",
|
|
760
|
+
fontWeight: 600,
|
|
761
|
+
color: "#111827"
|
|
762
|
+
};
|
|
763
|
+
const closeButtonStyle = {
|
|
764
|
+
background: "#ef4444",
|
|
765
|
+
color: "white",
|
|
766
|
+
border: "none",
|
|
767
|
+
borderRadius: "8px",
|
|
768
|
+
width: touchOptimized ? "56px" : "44px",
|
|
769
|
+
height: touchOptimized ? "56px" : "44px",
|
|
770
|
+
fontSize: touchOptimized ? "1.75rem" : "1.5rem",
|
|
771
|
+
fontWeight: "bold",
|
|
772
|
+
cursor: "pointer",
|
|
773
|
+
display: "flex",
|
|
774
|
+
alignItems: "center",
|
|
775
|
+
justifyContent: "center",
|
|
776
|
+
transition: "all 0.2s ease",
|
|
777
|
+
flexShrink: 0
|
|
778
|
+
};
|
|
779
|
+
const contentStyle = {
|
|
780
|
+
padding: touchOptimized ? "1.5rem" : "1rem",
|
|
781
|
+
overflowY: "auto",
|
|
782
|
+
flex: 1
|
|
783
|
+
};
|
|
784
|
+
return /* @__PURE__ */ jsxs6(Fragment, { children: [
|
|
785
|
+
/* @__PURE__ */ jsx7(
|
|
786
|
+
"div",
|
|
787
|
+
{
|
|
788
|
+
style: {
|
|
789
|
+
position: "fixed",
|
|
790
|
+
inset: 0,
|
|
791
|
+
background: "rgba(0, 0, 0, 0.3)",
|
|
792
|
+
zIndex: 9998,
|
|
793
|
+
animation: "fadeIn 0.3s ease-out"
|
|
794
|
+
},
|
|
795
|
+
onClick: onClose
|
|
796
|
+
}
|
|
797
|
+
),
|
|
798
|
+
/* @__PURE__ */ jsxs6(
|
|
799
|
+
"div",
|
|
800
|
+
{
|
|
801
|
+
className: `node-controls-panel ${touchClass} ${className}`.trim(),
|
|
802
|
+
style: containerStyle,
|
|
803
|
+
...props,
|
|
804
|
+
children: [
|
|
805
|
+
/* @__PURE__ */ jsxs6("div", { style: headerStyle, children: [
|
|
806
|
+
/* @__PURE__ */ jsx7("h2", { style: titleStyle, children: config.title }),
|
|
807
|
+
/* @__PURE__ */ jsx7(
|
|
808
|
+
"button",
|
|
809
|
+
{
|
|
810
|
+
style: closeButtonStyle,
|
|
811
|
+
onClick: onClose,
|
|
812
|
+
onMouseEnter: (e) => {
|
|
813
|
+
e.currentTarget.style.background = "#dc2626";
|
|
814
|
+
e.currentTarget.style.transform = "scale(1.05)";
|
|
815
|
+
},
|
|
816
|
+
onMouseLeave: (e) => {
|
|
817
|
+
e.currentTarget.style.background = "#ef4444";
|
|
818
|
+
e.currentTarget.style.transform = "scale(1)";
|
|
819
|
+
},
|
|
820
|
+
"aria-label": "Close",
|
|
821
|
+
children: "\u2715"
|
|
822
|
+
}
|
|
823
|
+
)
|
|
824
|
+
] }),
|
|
825
|
+
/* @__PURE__ */ jsx7("div", { style: contentStyle, children: /* @__PURE__ */ jsx7(
|
|
826
|
+
ControlPanel,
|
|
827
|
+
{
|
|
828
|
+
title: config.nodeId,
|
|
829
|
+
selectedMode: config.currentMode,
|
|
830
|
+
modeOptions: config.modes,
|
|
831
|
+
onModeChange: config.onModeChange,
|
|
832
|
+
setpointValue: config.setpoint,
|
|
833
|
+
onSetpointChange: config.onSetpointChange,
|
|
834
|
+
secondSetpointValue: config.secondSetpoint,
|
|
835
|
+
onSecondSetpointChange: config.onSecondSetpointChange,
|
|
836
|
+
modeConfigs: config.modeConfigs,
|
|
837
|
+
status: config.status,
|
|
838
|
+
setpointReadOnly: config.readOnly,
|
|
839
|
+
showStartStopButtons: !!(config.onStart || config.onStop),
|
|
840
|
+
isRunning: config.isRunning,
|
|
841
|
+
onStart: config.onStart,
|
|
842
|
+
onStop: config.onStop,
|
|
843
|
+
startButtonText: config.startButtonText,
|
|
844
|
+
stopButtonText: config.stopButtonText,
|
|
845
|
+
size: touchOptimized ? "large" : "medium"
|
|
846
|
+
}
|
|
847
|
+
) })
|
|
848
|
+
]
|
|
849
|
+
}
|
|
850
|
+
),
|
|
851
|
+
/* @__PURE__ */ jsx7("style", { children: `
|
|
852
|
+
@keyframes slideUp {
|
|
853
|
+
from {
|
|
854
|
+
transform: translateY(100%);
|
|
855
|
+
opacity: 0;
|
|
856
|
+
}
|
|
857
|
+
to {
|
|
858
|
+
transform: translateY(0);
|
|
859
|
+
opacity: 1;
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
@keyframes slideInRight {
|
|
864
|
+
from {
|
|
865
|
+
transform: translateX(100%);
|
|
866
|
+
opacity: 0;
|
|
867
|
+
}
|
|
868
|
+
to {
|
|
869
|
+
transform: translateX(0);
|
|
870
|
+
opacity: 1;
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
@keyframes fadeIn {
|
|
875
|
+
from {
|
|
876
|
+
opacity: 0;
|
|
877
|
+
}
|
|
878
|
+
to {
|
|
879
|
+
opacity: 1;
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
.node-controls-panel.touch-optimized button {
|
|
884
|
+
min-height: 56px;
|
|
885
|
+
font-size: 1.125rem;
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
.node-controls-panel.touch-optimized input {
|
|
889
|
+
min-height: 56px;
|
|
890
|
+
font-size: 1.125rem;
|
|
891
|
+
}
|
|
892
|
+
` })
|
|
893
|
+
] });
|
|
894
|
+
};
|
|
895
|
+
|
|
896
|
+
// src/components/DeviceControlPanel/DeviceControlPanel.tsx
|
|
897
|
+
import { useState as useState5, useEffect as useEffect2 } from "react";
|
|
898
|
+
import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
899
|
+
function DeviceControlPanel({
|
|
900
|
+
binding,
|
|
901
|
+
onClose,
|
|
902
|
+
position = "bottom",
|
|
903
|
+
touchOptimized = true,
|
|
904
|
+
onModeChange,
|
|
905
|
+
onParameterChange,
|
|
906
|
+
onStart,
|
|
907
|
+
onStop,
|
|
908
|
+
onCustomAction
|
|
909
|
+
}) {
|
|
910
|
+
const [localParameterValues, setLocalParameterValues] = useState5({});
|
|
911
|
+
useEffect2(() => {
|
|
912
|
+
if (binding) {
|
|
913
|
+
const currentParams2 = binding.parameters[binding.state.currentMode] || [];
|
|
914
|
+
const values = {};
|
|
915
|
+
currentParams2.forEach((param) => {
|
|
916
|
+
values[param.id] = param.value;
|
|
917
|
+
});
|
|
918
|
+
setLocalParameterValues(values);
|
|
919
|
+
}
|
|
920
|
+
}, [binding, binding?.state.currentMode]);
|
|
921
|
+
if (!binding) return null;
|
|
922
|
+
const currentMode = binding.state.currentMode;
|
|
923
|
+
const currentParams = binding.parameters[currentMode] || [];
|
|
924
|
+
const touchSize = touchOptimized ? 56 : 40;
|
|
925
|
+
const currentModeObj = binding.modes.find((m) => m.value === currentMode);
|
|
926
|
+
const activeCapabilities = currentModeObj?.capabilities ?? binding.capabilities ?? {};
|
|
927
|
+
const backgroundColor = binding.theme?.backgroundColor || "#edeeef";
|
|
928
|
+
const surfaceColor = "#f5f6f7";
|
|
929
|
+
const borderColor = "#d2d2d2";
|
|
930
|
+
const textColor = binding.theme?.textColor || "#000000";
|
|
931
|
+
const mutedTextColor = "#666666";
|
|
932
|
+
const selectedColor = "#b4d0fe";
|
|
933
|
+
const statusColors = {
|
|
934
|
+
normal: binding.theme?.statusColors?.normal || "#888888",
|
|
935
|
+
// Gray (no alarm)
|
|
936
|
+
warning: binding.theme?.statusColors?.warning || "#FFD700",
|
|
937
|
+
// Yellow
|
|
938
|
+
alarm: binding.theme?.statusColors?.alarm || "#FF0000",
|
|
939
|
+
// Red
|
|
940
|
+
fault: binding.theme?.statusColors?.fault || "#FF0000",
|
|
941
|
+
// Red
|
|
942
|
+
off: binding.theme?.statusColors?.off || "#666666",
|
|
943
|
+
// Dark gray
|
|
944
|
+
starting: binding.theme?.statusColors?.starting || "#90EE90",
|
|
945
|
+
// Light green
|
|
946
|
+
stopping: binding.theme?.statusColors?.stopping || "#FFD700"
|
|
947
|
+
// Yellow
|
|
948
|
+
};
|
|
949
|
+
const statusColor = statusColors[binding.state.status || "normal"];
|
|
950
|
+
const handleModeChange = (mode) => {
|
|
951
|
+
onModeChange?.(mode);
|
|
952
|
+
};
|
|
953
|
+
const handleParameterCommit = (parameterId, value) => {
|
|
954
|
+
onParameterChange?.(parameterId, value);
|
|
955
|
+
};
|
|
956
|
+
const handleParameterInput = (parameterId, value) => {
|
|
957
|
+
setLocalParameterValues((prev) => ({ ...prev, [parameterId]: value }));
|
|
958
|
+
};
|
|
959
|
+
const panelStyle = {
|
|
960
|
+
position: "fixed",
|
|
961
|
+
...position === "bottom" ? {
|
|
962
|
+
bottom: 0,
|
|
963
|
+
left: 0,
|
|
964
|
+
right: 0,
|
|
965
|
+
animation: "slideUp 0.3s ease-out"
|
|
966
|
+
} : {
|
|
967
|
+
right: 0,
|
|
968
|
+
top: 0,
|
|
969
|
+
bottom: 0,
|
|
970
|
+
width: "400px",
|
|
971
|
+
animation: "slideIn 0.3s ease-out"
|
|
972
|
+
},
|
|
973
|
+
backgroundColor,
|
|
974
|
+
color: textColor,
|
|
975
|
+
borderRadius: position === "bottom" ? "8px 8px 0 0" : "8px 0 0 8px",
|
|
976
|
+
boxShadow: "none",
|
|
977
|
+
border: `2px solid ${borderColor}`,
|
|
978
|
+
padding: "20px",
|
|
979
|
+
zIndex: 9999,
|
|
980
|
+
maxHeight: position === "bottom" ? "70vh" : "100vh",
|
|
981
|
+
overflowY: "auto",
|
|
982
|
+
...binding.display?.style
|
|
983
|
+
};
|
|
984
|
+
const titleText = binding.display?.title || binding.deviceName || binding.tag || binding.nodeId;
|
|
985
|
+
return /* @__PURE__ */ jsx8(Fragment2, { children: /* @__PURE__ */ jsxs7("div", { style: panelStyle, className: binding.display?.className, children: [
|
|
986
|
+
/* @__PURE__ */ jsxs7(
|
|
987
|
+
"div",
|
|
988
|
+
{
|
|
989
|
+
style: {
|
|
990
|
+
display: "flex",
|
|
991
|
+
justifyContent: "space-between",
|
|
992
|
+
alignItems: "center",
|
|
993
|
+
marginBottom: "16px",
|
|
994
|
+
paddingBottom: "12px",
|
|
995
|
+
borderBottom: `2px solid ${borderColor}`
|
|
996
|
+
},
|
|
997
|
+
children: [
|
|
998
|
+
/* @__PURE__ */ jsxs7("div", { children: [
|
|
999
|
+
/* @__PURE__ */ jsx8(
|
|
1000
|
+
"h3",
|
|
1001
|
+
{
|
|
1002
|
+
style: {
|
|
1003
|
+
margin: 0,
|
|
1004
|
+
fontSize: "14px",
|
|
1005
|
+
fontWeight: 600,
|
|
1006
|
+
fontFamily: "Arial, sans-serif",
|
|
1007
|
+
letterSpacing: "0.5px",
|
|
1008
|
+
textTransform: "uppercase",
|
|
1009
|
+
color: textColor
|
|
1010
|
+
},
|
|
1011
|
+
children: titleText
|
|
1012
|
+
}
|
|
1013
|
+
),
|
|
1014
|
+
binding.deviceType && /* @__PURE__ */ jsx8(
|
|
1015
|
+
"div",
|
|
1016
|
+
{
|
|
1017
|
+
style: {
|
|
1018
|
+
fontSize: "11px",
|
|
1019
|
+
color: mutedTextColor,
|
|
1020
|
+
marginTop: "4px",
|
|
1021
|
+
fontFamily: "Arial, sans-serif"
|
|
1022
|
+
},
|
|
1023
|
+
children: binding.deviceType
|
|
1024
|
+
}
|
|
1025
|
+
)
|
|
1026
|
+
] }),
|
|
1027
|
+
/* @__PURE__ */ jsx8(
|
|
1028
|
+
"button",
|
|
1029
|
+
{
|
|
1030
|
+
onClick: onClose,
|
|
1031
|
+
style: {
|
|
1032
|
+
width: touchSize * 0.7,
|
|
1033
|
+
height: touchSize * 0.7,
|
|
1034
|
+
backgroundColor: surfaceColor,
|
|
1035
|
+
color: textColor,
|
|
1036
|
+
border: `2px solid ${borderColor}`,
|
|
1037
|
+
borderRadius: "2px",
|
|
1038
|
+
fontSize: "18px",
|
|
1039
|
+
cursor: "pointer",
|
|
1040
|
+
fontWeight: "bold",
|
|
1041
|
+
fontFamily: "Arial, sans-serif"
|
|
1042
|
+
},
|
|
1043
|
+
children: "\xD7"
|
|
1044
|
+
}
|
|
1045
|
+
)
|
|
1046
|
+
]
|
|
1047
|
+
}
|
|
1048
|
+
),
|
|
1049
|
+
binding.state.status && /* @__PURE__ */ jsxs7(
|
|
1050
|
+
"div",
|
|
1051
|
+
{
|
|
1052
|
+
style: {
|
|
1053
|
+
display: "flex",
|
|
1054
|
+
alignItems: "center",
|
|
1055
|
+
gap: "12px",
|
|
1056
|
+
padding: "10px 12px",
|
|
1057
|
+
backgroundColor: surfaceColor,
|
|
1058
|
+
border: `1px solid ${borderColor}`,
|
|
1059
|
+
borderRadius: "6px",
|
|
1060
|
+
marginBottom: "16px"
|
|
1061
|
+
},
|
|
1062
|
+
children: [
|
|
1063
|
+
/* @__PURE__ */ jsx8(
|
|
1064
|
+
"div",
|
|
1065
|
+
{
|
|
1066
|
+
style: {
|
|
1067
|
+
width: "10px",
|
|
1068
|
+
height: "10px",
|
|
1069
|
+
borderRadius: "50%",
|
|
1070
|
+
backgroundColor: statusColor,
|
|
1071
|
+
border: "1px solid #333"
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
),
|
|
1075
|
+
/* @__PURE__ */ jsxs7("div", { style: { flex: 1 }, children: [
|
|
1076
|
+
/* @__PURE__ */ jsx8(
|
|
1077
|
+
"div",
|
|
1078
|
+
{
|
|
1079
|
+
style: {
|
|
1080
|
+
fontWeight: 600,
|
|
1081
|
+
textTransform: "uppercase",
|
|
1082
|
+
fontSize: "11px",
|
|
1083
|
+
fontFamily: "Arial, sans-serif",
|
|
1084
|
+
letterSpacing: "0.5px",
|
|
1085
|
+
color: textColor
|
|
1086
|
+
},
|
|
1087
|
+
children: binding.state.status
|
|
1088
|
+
}
|
|
1089
|
+
),
|
|
1090
|
+
binding.state.statusMessage && /* @__PURE__ */ jsx8(
|
|
1091
|
+
"div",
|
|
1092
|
+
{
|
|
1093
|
+
style: {
|
|
1094
|
+
fontSize: "10px",
|
|
1095
|
+
color: mutedTextColor,
|
|
1096
|
+
marginTop: "2px",
|
|
1097
|
+
fontFamily: "Arial, sans-serif"
|
|
1098
|
+
},
|
|
1099
|
+
children: binding.state.statusMessage
|
|
1100
|
+
}
|
|
1101
|
+
)
|
|
1102
|
+
] }),
|
|
1103
|
+
binding.state.isRunning !== void 0 && /* @__PURE__ */ jsx8(
|
|
1104
|
+
"div",
|
|
1105
|
+
{
|
|
1106
|
+
style: {
|
|
1107
|
+
padding: "4px 10px",
|
|
1108
|
+
backgroundColor: binding.state.isRunning ? selectedColor : surfaceColor,
|
|
1109
|
+
border: `1px solid ${borderColor}`,
|
|
1110
|
+
borderRadius: "2px",
|
|
1111
|
+
fontSize: "10px",
|
|
1112
|
+
fontWeight: 600,
|
|
1113
|
+
fontFamily: "Arial, sans-serif",
|
|
1114
|
+
letterSpacing: "0.5px",
|
|
1115
|
+
color: textColor
|
|
1116
|
+
},
|
|
1117
|
+
children: binding.state.isRunning ? "RUNNING" : "STOPPED"
|
|
1118
|
+
}
|
|
1119
|
+
)
|
|
1120
|
+
]
|
|
1121
|
+
}
|
|
1122
|
+
),
|
|
1123
|
+
binding.display?.showModeSelector !== false && binding.modes.length > 0 && /* @__PURE__ */ jsxs7("div", { style: { marginBottom: "16px" }, children: [
|
|
1124
|
+
/* @__PURE__ */ jsx8(
|
|
1125
|
+
"label",
|
|
1126
|
+
{
|
|
1127
|
+
style: {
|
|
1128
|
+
display: "block",
|
|
1129
|
+
marginBottom: "8px",
|
|
1130
|
+
fontSize: "11px",
|
|
1131
|
+
fontWeight: 600,
|
|
1132
|
+
textTransform: "uppercase",
|
|
1133
|
+
letterSpacing: "0.5px",
|
|
1134
|
+
fontFamily: "Arial, sans-serif",
|
|
1135
|
+
color: mutedTextColor
|
|
1136
|
+
},
|
|
1137
|
+
children: "Mode"
|
|
1138
|
+
}
|
|
1139
|
+
),
|
|
1140
|
+
/* @__PURE__ */ jsx8("div", { style: { display: "flex", gap: "6px", flexWrap: "wrap" }, children: binding.modes.map((mode) => {
|
|
1141
|
+
const isSelected = mode.value === currentMode;
|
|
1142
|
+
const isEnabled = mode.enabled !== false;
|
|
1143
|
+
return /* @__PURE__ */ jsx8(
|
|
1144
|
+
"button",
|
|
1145
|
+
{
|
|
1146
|
+
onClick: () => isEnabled && handleModeChange(mode.value),
|
|
1147
|
+
disabled: !isEnabled,
|
|
1148
|
+
style: {
|
|
1149
|
+
flex: 1,
|
|
1150
|
+
minWidth: "80px",
|
|
1151
|
+
height: touchSize,
|
|
1152
|
+
backgroundColor: isSelected ? selectedColor : surfaceColor,
|
|
1153
|
+
color: isSelected ? "#000000" : textColor,
|
|
1154
|
+
border: `1px solid ${isSelected ? "#b4d0fe" : borderColor}`,
|
|
1155
|
+
borderRadius: "6px",
|
|
1156
|
+
fontSize: "11px",
|
|
1157
|
+
fontWeight: 600,
|
|
1158
|
+
fontFamily: "Arial, sans-serif",
|
|
1159
|
+
letterSpacing: "0.5px",
|
|
1160
|
+
textTransform: "uppercase",
|
|
1161
|
+
cursor: isEnabled ? "pointer" : "not-allowed",
|
|
1162
|
+
opacity: isEnabled ? 1 : 0.4
|
|
1163
|
+
},
|
|
1164
|
+
children: mode.label
|
|
1165
|
+
},
|
|
1166
|
+
mode.value
|
|
1167
|
+
);
|
|
1168
|
+
}) })
|
|
1169
|
+
] }),
|
|
1170
|
+
currentParams.length > 0 && /* @__PURE__ */ jsxs7("div", { style: { marginBottom: "16px" }, children: [
|
|
1171
|
+
/* @__PURE__ */ jsx8(
|
|
1172
|
+
"label",
|
|
1173
|
+
{
|
|
1174
|
+
style: {
|
|
1175
|
+
display: "block",
|
|
1176
|
+
marginBottom: "8px",
|
|
1177
|
+
fontSize: "11px",
|
|
1178
|
+
fontWeight: 600,
|
|
1179
|
+
textTransform: "uppercase",
|
|
1180
|
+
letterSpacing: "0.5px",
|
|
1181
|
+
fontFamily: "Arial, sans-serif",
|
|
1182
|
+
color: mutedTextColor
|
|
1183
|
+
},
|
|
1184
|
+
children: "Parameters"
|
|
1185
|
+
}
|
|
1186
|
+
),
|
|
1187
|
+
currentParams.map((param) => /* @__PURE__ */ jsxs7(
|
|
1188
|
+
"div",
|
|
1189
|
+
{
|
|
1190
|
+
style: {
|
|
1191
|
+
marginBottom: "10px",
|
|
1192
|
+
padding: "10px",
|
|
1193
|
+
backgroundColor: surfaceColor,
|
|
1194
|
+
border: `1px solid ${borderColor}`,
|
|
1195
|
+
borderRadius: "6px"
|
|
1196
|
+
},
|
|
1197
|
+
children: [
|
|
1198
|
+
/* @__PURE__ */ jsxs7(
|
|
1199
|
+
"div",
|
|
1200
|
+
{
|
|
1201
|
+
style: { display: "flex", justifyContent: "space-between", marginBottom: "8px" },
|
|
1202
|
+
children: [
|
|
1203
|
+
/* @__PURE__ */ jsx8(
|
|
1204
|
+
"span",
|
|
1205
|
+
{
|
|
1206
|
+
style: {
|
|
1207
|
+
fontSize: "11px",
|
|
1208
|
+
fontWeight: 600,
|
|
1209
|
+
textTransform: "uppercase",
|
|
1210
|
+
letterSpacing: "0.5px",
|
|
1211
|
+
fontFamily: "Arial, sans-serif",
|
|
1212
|
+
color: mutedTextColor
|
|
1213
|
+
},
|
|
1214
|
+
children: param.label
|
|
1215
|
+
}
|
|
1216
|
+
),
|
|
1217
|
+
/* @__PURE__ */ jsxs7(
|
|
1218
|
+
"span",
|
|
1219
|
+
{
|
|
1220
|
+
style: {
|
|
1221
|
+
fontSize: "13px",
|
|
1222
|
+
fontWeight: 700,
|
|
1223
|
+
fontFamily: "Arial, sans-serif",
|
|
1224
|
+
color: textColor
|
|
1225
|
+
},
|
|
1226
|
+
children: [
|
|
1227
|
+
localParameterValues[param.id] ?? param.value,
|
|
1228
|
+
" ",
|
|
1229
|
+
param.unit && /* @__PURE__ */ jsx8("span", { style: { color: mutedTextColor, fontSize: "10px", fontWeight: 600 }, children: param.unit })
|
|
1230
|
+
]
|
|
1231
|
+
}
|
|
1232
|
+
)
|
|
1233
|
+
]
|
|
1234
|
+
}
|
|
1235
|
+
),
|
|
1236
|
+
param.type === "boolean" ? /* @__PURE__ */ jsx8(
|
|
1237
|
+
"button",
|
|
1238
|
+
{
|
|
1239
|
+
onClick: () => {
|
|
1240
|
+
const newValue = !localParameterValues[param.id];
|
|
1241
|
+
handleParameterInput(param.id, newValue);
|
|
1242
|
+
handleParameterCommit(param.id, newValue);
|
|
1243
|
+
},
|
|
1244
|
+
disabled: param.readOnly,
|
|
1245
|
+
style: {
|
|
1246
|
+
width: "100%",
|
|
1247
|
+
height: touchSize,
|
|
1248
|
+
backgroundColor: localParameterValues[param.id] ? "#3f3f46" : surfaceColor,
|
|
1249
|
+
color: localParameterValues[param.id] ? textColor : mutedTextColor,
|
|
1250
|
+
border: `1px solid ${localParameterValues[param.id] ? "#52525b" : borderColor}`,
|
|
1251
|
+
borderRadius: "4px",
|
|
1252
|
+
fontSize: "12px",
|
|
1253
|
+
fontWeight: 600,
|
|
1254
|
+
fontFamily: "monospace",
|
|
1255
|
+
letterSpacing: "0.5px",
|
|
1256
|
+
cursor: param.readOnly ? "not-allowed" : "pointer",
|
|
1257
|
+
transition: "all 0.15s"
|
|
1258
|
+
},
|
|
1259
|
+
children: localParameterValues[param.id] ? "ON" : "OFF"
|
|
1260
|
+
}
|
|
1261
|
+
) : param.type === "select" ? /* @__PURE__ */ jsx8(
|
|
1262
|
+
"select",
|
|
1263
|
+
{
|
|
1264
|
+
value: localParameterValues[param.id] || param.value,
|
|
1265
|
+
onChange: (e) => {
|
|
1266
|
+
handleParameterInput(param.id, e.target.value);
|
|
1267
|
+
handleParameterCommit(param.id, e.target.value);
|
|
1268
|
+
},
|
|
1269
|
+
disabled: param.readOnly,
|
|
1270
|
+
style: {
|
|
1271
|
+
width: "100%",
|
|
1272
|
+
height: touchSize,
|
|
1273
|
+
backgroundColor: surfaceColor,
|
|
1274
|
+
color: textColor,
|
|
1275
|
+
border: `1px solid ${borderColor}`,
|
|
1276
|
+
borderRadius: "4px",
|
|
1277
|
+
padding: "0 12px",
|
|
1278
|
+
fontSize: "12px",
|
|
1279
|
+
fontFamily: "monospace",
|
|
1280
|
+
cursor: "pointer"
|
|
1281
|
+
},
|
|
1282
|
+
children: param.options?.map((opt) => /* @__PURE__ */ jsx8("option", { value: opt.value, children: opt.label }, opt.value))
|
|
1283
|
+
}
|
|
1284
|
+
) : /* @__PURE__ */ jsx8(
|
|
1285
|
+
"input",
|
|
1286
|
+
{
|
|
1287
|
+
type: param.type === "number" ? "number" : "text",
|
|
1288
|
+
value: localParameterValues[param.id] ?? param.value,
|
|
1289
|
+
onChange: (e) => handleParameterInput(
|
|
1290
|
+
param.id,
|
|
1291
|
+
param.type === "number" ? +e.target.value : e.target.value
|
|
1292
|
+
),
|
|
1293
|
+
onBlur: () => handleParameterCommit(param.id, localParameterValues[param.id]),
|
|
1294
|
+
disabled: param.readOnly,
|
|
1295
|
+
min: param.min,
|
|
1296
|
+
max: param.max,
|
|
1297
|
+
step: param.step,
|
|
1298
|
+
style: {
|
|
1299
|
+
width: "100%",
|
|
1300
|
+
height: touchSize,
|
|
1301
|
+
backgroundColor: "#ffffff",
|
|
1302
|
+
color: textColor,
|
|
1303
|
+
border: `1px solid ${borderColor}`,
|
|
1304
|
+
borderRadius: "6px",
|
|
1305
|
+
padding: "0 12px",
|
|
1306
|
+
fontSize: "14px",
|
|
1307
|
+
fontFamily: "Arial, sans-serif",
|
|
1308
|
+
fontWeight: 600
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
)
|
|
1312
|
+
]
|
|
1313
|
+
},
|
|
1314
|
+
param.id
|
|
1315
|
+
))
|
|
1316
|
+
] }),
|
|
1317
|
+
binding.display?.showStartStop !== false && (activeCapabilities?.canStart || activeCapabilities?.canStop) && /* @__PURE__ */ jsxs7("div", { style: { display: "flex", gap: "8px", marginBottom: "16px" }, children: [
|
|
1318
|
+
activeCapabilities?.canStart && /* @__PURE__ */ jsx8(
|
|
1319
|
+
"button",
|
|
1320
|
+
{
|
|
1321
|
+
onClick: onStart,
|
|
1322
|
+
disabled: binding.state.isRunning,
|
|
1323
|
+
style: {
|
|
1324
|
+
flex: 1,
|
|
1325
|
+
height: touchSize,
|
|
1326
|
+
backgroundColor: binding.state.isRunning ? "#a3a3a3" : "#10b981",
|
|
1327
|
+
color: "#ffffff",
|
|
1328
|
+
border: "none",
|
|
1329
|
+
borderRadius: "6px",
|
|
1330
|
+
fontSize: "12px",
|
|
1331
|
+
fontWeight: 700,
|
|
1332
|
+
fontFamily: "Arial, sans-serif",
|
|
1333
|
+
letterSpacing: "0.5px",
|
|
1334
|
+
cursor: binding.state.isRunning ? "not-allowed" : "pointer",
|
|
1335
|
+
opacity: binding.state.isRunning ? 0.5 : 1
|
|
1336
|
+
},
|
|
1337
|
+
children: "START"
|
|
1338
|
+
}
|
|
1339
|
+
),
|
|
1340
|
+
activeCapabilities?.canStop && /* @__PURE__ */ jsx8(
|
|
1341
|
+
"button",
|
|
1342
|
+
{
|
|
1343
|
+
onClick: onStop,
|
|
1344
|
+
disabled: !binding.state.isRunning,
|
|
1345
|
+
style: {
|
|
1346
|
+
flex: 1,
|
|
1347
|
+
height: touchSize,
|
|
1348
|
+
backgroundColor: !binding.state.isRunning ? "#a3a3a3" : "#ef4444",
|
|
1349
|
+
color: "#ffffff",
|
|
1350
|
+
border: "none",
|
|
1351
|
+
borderRadius: "6px",
|
|
1352
|
+
fontSize: "12px",
|
|
1353
|
+
fontWeight: 700,
|
|
1354
|
+
fontFamily: "Arial, sans-serif",
|
|
1355
|
+
letterSpacing: "0.5px",
|
|
1356
|
+
cursor: !binding.state.isRunning ? "not-allowed" : "pointer",
|
|
1357
|
+
opacity: !binding.state.isRunning ? 0.5 : 1
|
|
1358
|
+
},
|
|
1359
|
+
children: "STOP"
|
|
1360
|
+
}
|
|
1361
|
+
)
|
|
1362
|
+
] }),
|
|
1363
|
+
activeCapabilities?.customActions && activeCapabilities.customActions.length > 0 && /* @__PURE__ */ jsx8("div", { style: { display: "flex", flexWrap: "wrap", gap: "8px" }, children: activeCapabilities.customActions.map((action) => /* @__PURE__ */ jsxs7(
|
|
1364
|
+
"button",
|
|
1365
|
+
{
|
|
1366
|
+
onClick: () => onCustomAction?.(action.id),
|
|
1367
|
+
style: {
|
|
1368
|
+
flex: 1,
|
|
1369
|
+
minWidth: "120px",
|
|
1370
|
+
height: touchSize,
|
|
1371
|
+
backgroundColor: surfaceColor,
|
|
1372
|
+
color: textColor,
|
|
1373
|
+
border: `1px solid ${borderColor}`,
|
|
1374
|
+
borderRadius: "6px",
|
|
1375
|
+
fontSize: "11px",
|
|
1376
|
+
fontWeight: 600,
|
|
1377
|
+
fontFamily: "monospace",
|
|
1378
|
+
letterSpacing: "0.5px",
|
|
1379
|
+
textTransform: "uppercase",
|
|
1380
|
+
cursor: "pointer",
|
|
1381
|
+
transition: "all 0.15s"
|
|
1382
|
+
},
|
|
1383
|
+
children: [
|
|
1384
|
+
action.icon && /* @__PURE__ */ jsx8("span", { style: { marginRight: "6px" }, children: action.icon }),
|
|
1385
|
+
action.label
|
|
1386
|
+
]
|
|
1387
|
+
},
|
|
1388
|
+
action.id
|
|
1389
|
+
)) }),
|
|
1390
|
+
binding.state.lastCommandResult && /* @__PURE__ */ jsx8(
|
|
1391
|
+
"div",
|
|
1392
|
+
{
|
|
1393
|
+
style: {
|
|
1394
|
+
marginTop: "16px",
|
|
1395
|
+
padding: "10px 12px",
|
|
1396
|
+
backgroundColor: surfaceColor,
|
|
1397
|
+
border: `1px solid ${binding.state.lastCommandResult.success ? "#52525b" : borderColor}`,
|
|
1398
|
+
borderRadius: "4px",
|
|
1399
|
+
fontSize: "11px",
|
|
1400
|
+
fontFamily: "monospace",
|
|
1401
|
+
color: binding.state.lastCommandResult.success ? textColor : mutedTextColor
|
|
1402
|
+
},
|
|
1403
|
+
children: binding.state.lastCommandResult.message
|
|
1404
|
+
}
|
|
1405
|
+
),
|
|
1406
|
+
/* @__PURE__ */ jsx8("style", { children: `
|
|
1407
|
+
@keyframes slideUp {
|
|
1408
|
+
from { transform: translateY(100%); }
|
|
1409
|
+
to { transform: translateY(0); }
|
|
1410
|
+
}
|
|
1411
|
+
@keyframes slideIn {
|
|
1412
|
+
from { transform: translateX(100%); }
|
|
1413
|
+
to { transform: translateX(0); }
|
|
1414
|
+
}
|
|
1415
|
+
` })
|
|
1416
|
+
] }) });
|
|
1417
|
+
}
|
|
1418
|
+
|
|
710
1419
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.tsx
|
|
711
|
-
import
|
|
1420
|
+
import React6 from "react";
|
|
712
1421
|
import { Tab } from "@mui/material";
|
|
713
1422
|
|
|
714
1423
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.styles.tsx
|
|
715
1424
|
import { Box, IconButton, Tabs } from "@mui/material";
|
|
716
1425
|
import styled from "@emotion/styled";
|
|
717
|
-
import { jsx as
|
|
1426
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
718
1427
|
var FullscreenContainer = styled(Box)(
|
|
719
1428
|
({ leftCollapsed, rightCollapsed }) => {
|
|
720
1429
|
const getGridTemplateAreas = () => {
|
|
@@ -839,7 +1548,7 @@ var DisplayModeToggle = styled(IconButton)(({ mode }) => ({
|
|
|
839
1548
|
transform: "translateX(-50%) scale(1.05)"
|
|
840
1549
|
}
|
|
841
1550
|
}));
|
|
842
|
-
var ChevronLeft = () => /* @__PURE__ */
|
|
1551
|
+
var ChevronLeft = () => /* @__PURE__ */ jsx9(
|
|
843
1552
|
"div",
|
|
844
1553
|
{
|
|
845
1554
|
style: {
|
|
@@ -851,7 +1560,7 @@ var ChevronLeft = () => /* @__PURE__ */ jsx7(
|
|
|
851
1560
|
}
|
|
852
1561
|
}
|
|
853
1562
|
);
|
|
854
|
-
var ChevronRight = () => /* @__PURE__ */
|
|
1563
|
+
var ChevronRight = () => /* @__PURE__ */ jsx9(
|
|
855
1564
|
"div",
|
|
856
1565
|
{
|
|
857
1566
|
style: {
|
|
@@ -962,10 +1671,10 @@ var ScrollableSVGWrapper = styled("div")({
|
|
|
962
1671
|
});
|
|
963
1672
|
|
|
964
1673
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.overlays.tsx
|
|
965
|
-
import { useEffect as
|
|
1674
|
+
import { useEffect as useEffect3, useState as useState6 } from "react";
|
|
966
1675
|
import { Box as Box2 } from "@mui/material";
|
|
967
1676
|
import styled2 from "@emotion/styled";
|
|
968
|
-
import { jsx as
|
|
1677
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
969
1678
|
var baseOverlayStyles = {
|
|
970
1679
|
tank: {
|
|
971
1680
|
background: "linear-gradient(135deg, rgba(69, 90, 120, 0.95) 0%, rgba(52, 73, 94, 0.95) 100%)",
|
|
@@ -1027,8 +1736,8 @@ var SVGLockedOverlay = ({
|
|
|
1027
1736
|
onClick,
|
|
1028
1737
|
containerSelector = ".tff-svg-container"
|
|
1029
1738
|
}) => {
|
|
1030
|
-
const [svgOffset, setSvgOffset] =
|
|
1031
|
-
|
|
1739
|
+
const [svgOffset, setSvgOffset] = useState6({ x: 0, y: 0 });
|
|
1740
|
+
useEffect3(() => {
|
|
1032
1741
|
const updateSvgOffset = () => {
|
|
1033
1742
|
const containerElement = document.querySelector(containerSelector);
|
|
1034
1743
|
const svgElement = containerElement?.querySelector("svg");
|
|
@@ -1048,7 +1757,7 @@ var SVGLockedOverlay = ({
|
|
|
1048
1757
|
const pixelX = svgX + svgOffset.x;
|
|
1049
1758
|
const pixelY = svgY + svgOffset.y;
|
|
1050
1759
|
const appliedStyle = theme ? { ...overlayStyles[theme], ...style } : style;
|
|
1051
|
-
return /* @__PURE__ */
|
|
1760
|
+
return /* @__PURE__ */ jsx10(
|
|
1052
1761
|
Box2,
|
|
1053
1762
|
{
|
|
1054
1763
|
className: `svg-locked-overlay ${className}`.trim(),
|
|
@@ -1112,7 +1821,7 @@ var CardUnit = styled2("div")({
|
|
|
1112
1821
|
});
|
|
1113
1822
|
|
|
1114
1823
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.visuals.tsx
|
|
1115
|
-
import { Fragment, jsx as
|
|
1824
|
+
import { Fragment as Fragment3, jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1116
1825
|
var TrendLine = ({
|
|
1117
1826
|
values,
|
|
1118
1827
|
width = 60,
|
|
@@ -1122,7 +1831,7 @@ var TrendLine = ({
|
|
|
1122
1831
|
backgroundColor = "rgba(255, 255, 255, 0.1)"
|
|
1123
1832
|
}) => {
|
|
1124
1833
|
if (!values || values.length < 2) {
|
|
1125
|
-
return /* @__PURE__ */
|
|
1834
|
+
return /* @__PURE__ */ jsx11(
|
|
1126
1835
|
"div",
|
|
1127
1836
|
{
|
|
1128
1837
|
style: {
|
|
@@ -1134,7 +1843,7 @@ var TrendLine = ({
|
|
|
1134
1843
|
alignItems: "center",
|
|
1135
1844
|
justifyContent: "center"
|
|
1136
1845
|
},
|
|
1137
|
-
children: /* @__PURE__ */
|
|
1846
|
+
children: /* @__PURE__ */ jsx11("span", { style: { fontSize: "8px", color: "#ccc" }, children: "No data" })
|
|
1138
1847
|
}
|
|
1139
1848
|
);
|
|
1140
1849
|
}
|
|
@@ -1146,7 +1855,7 @@ var TrendLine = ({
|
|
|
1146
1855
|
const x = 4 + i / (values.length - 1) * (width - 8);
|
|
1147
1856
|
return i === 0 ? `M ${x} ${y}` : `L ${x} ${y}`;
|
|
1148
1857
|
}).join(" ");
|
|
1149
|
-
return /* @__PURE__ */
|
|
1858
|
+
return /* @__PURE__ */ jsx11(
|
|
1150
1859
|
"div",
|
|
1151
1860
|
{
|
|
1152
1861
|
style: {
|
|
@@ -1157,8 +1866,8 @@ var TrendLine = ({
|
|
|
1157
1866
|
position: "relative",
|
|
1158
1867
|
overflow: "hidden"
|
|
1159
1868
|
},
|
|
1160
|
-
children: /* @__PURE__ */
|
|
1161
|
-
/* @__PURE__ */
|
|
1869
|
+
children: /* @__PURE__ */ jsxs8("svg", { width, height, style: { position: "absolute", top: 0, left: 0 }, children: [
|
|
1870
|
+
/* @__PURE__ */ jsx11(
|
|
1162
1871
|
"path",
|
|
1163
1872
|
{
|
|
1164
1873
|
d: pathData,
|
|
@@ -1169,7 +1878,7 @@ var TrendLine = ({
|
|
|
1169
1878
|
strokeLinejoin: "round"
|
|
1170
1879
|
}
|
|
1171
1880
|
),
|
|
1172
|
-
/* @__PURE__ */
|
|
1881
|
+
/* @__PURE__ */ jsx11(
|
|
1173
1882
|
"circle",
|
|
1174
1883
|
{
|
|
1175
1884
|
cx: 4 + (width - 8),
|
|
@@ -1207,7 +1916,7 @@ var CircularGauge = ({
|
|
|
1207
1916
|
const borderColor = isHex ? hexToRgba(color, 0.9) : color;
|
|
1208
1917
|
const backgroundColor = isHex ? hexToRgba(color, 0.15) : color;
|
|
1209
1918
|
const borderStrokeColor = isHex ? hexToRgba(color, 0.4) : color;
|
|
1210
|
-
return /* @__PURE__ */
|
|
1919
|
+
return /* @__PURE__ */ jsxs8(
|
|
1211
1920
|
"div",
|
|
1212
1921
|
{
|
|
1213
1922
|
style: {
|
|
@@ -1216,7 +1925,7 @@ var CircularGauge = ({
|
|
|
1216
1925
|
alignItems: "center"
|
|
1217
1926
|
},
|
|
1218
1927
|
children: [
|
|
1219
|
-
/* @__PURE__ */
|
|
1928
|
+
/* @__PURE__ */ jsxs8(
|
|
1220
1929
|
"div",
|
|
1221
1930
|
{
|
|
1222
1931
|
style: {
|
|
@@ -1228,8 +1937,8 @@ var CircularGauge = ({
|
|
|
1228
1937
|
border: `1px solid ${borderStrokeColor}`
|
|
1229
1938
|
},
|
|
1230
1939
|
children: [
|
|
1231
|
-
/* @__PURE__ */
|
|
1232
|
-
/* @__PURE__ */
|
|
1940
|
+
/* @__PURE__ */ jsxs8("svg", { width: size, height: size, style: { transform: "rotate(-90deg)" }, children: [
|
|
1941
|
+
/* @__PURE__ */ jsx11(
|
|
1233
1942
|
"circle",
|
|
1234
1943
|
{
|
|
1235
1944
|
cx: size / 2,
|
|
@@ -1240,7 +1949,7 @@ var CircularGauge = ({
|
|
|
1240
1949
|
strokeWidth: 1
|
|
1241
1950
|
}
|
|
1242
1951
|
),
|
|
1243
|
-
/* @__PURE__ */
|
|
1952
|
+
/* @__PURE__ */ jsx11(
|
|
1244
1953
|
"circle",
|
|
1245
1954
|
{
|
|
1246
1955
|
cx: size / 2,
|
|
@@ -1251,7 +1960,7 @@ var CircularGauge = ({
|
|
|
1251
1960
|
fill: "transparent"
|
|
1252
1961
|
}
|
|
1253
1962
|
),
|
|
1254
|
-
/* @__PURE__ */
|
|
1963
|
+
/* @__PURE__ */ jsx11(
|
|
1255
1964
|
"circle",
|
|
1256
1965
|
{
|
|
1257
1966
|
cx: size / 2,
|
|
@@ -1267,7 +1976,7 @@ var CircularGauge = ({
|
|
|
1267
1976
|
}
|
|
1268
1977
|
)
|
|
1269
1978
|
] }),
|
|
1270
|
-
/* @__PURE__ */
|
|
1979
|
+
/* @__PURE__ */ jsxs8(
|
|
1271
1980
|
"div",
|
|
1272
1981
|
{
|
|
1273
1982
|
style: {
|
|
@@ -1283,14 +1992,14 @@ var CircularGauge = ({
|
|
|
1283
1992
|
},
|
|
1284
1993
|
children: [
|
|
1285
1994
|
value.toFixed(1),
|
|
1286
|
-
/* @__PURE__ */
|
|
1995
|
+
/* @__PURE__ */ jsx11("div", { style: { fontSize: "8px", opacity: 0.9, color: "white" }, children: unit })
|
|
1287
1996
|
]
|
|
1288
1997
|
}
|
|
1289
1998
|
)
|
|
1290
1999
|
]
|
|
1291
2000
|
}
|
|
1292
2001
|
),
|
|
1293
|
-
/* @__PURE__ */
|
|
2002
|
+
/* @__PURE__ */ jsx11(
|
|
1294
2003
|
"div",
|
|
1295
2004
|
{
|
|
1296
2005
|
style: {
|
|
@@ -1321,7 +2030,7 @@ var Sparkline = ({ data, width, height, color }) => {
|
|
|
1321
2030
|
const y = height - 8 - (value - min) / range * (height - 8);
|
|
1322
2031
|
return `${x + 4},${y + 4}`;
|
|
1323
2032
|
}).join(" ");
|
|
1324
|
-
return /* @__PURE__ */
|
|
2033
|
+
return /* @__PURE__ */ jsx11(
|
|
1325
2034
|
"div",
|
|
1326
2035
|
{
|
|
1327
2036
|
style: {
|
|
@@ -1335,7 +2044,7 @@ var Sparkline = ({ data, width, height, color }) => {
|
|
|
1335
2044
|
justifyContent: "center",
|
|
1336
2045
|
boxShadow: "0 1px 3px rgba(0, 0, 0, 0.2)"
|
|
1337
2046
|
},
|
|
1338
|
-
children: /* @__PURE__ */
|
|
2047
|
+
children: /* @__PURE__ */ jsx11("svg", { width, height, children: /* @__PURE__ */ jsx11("polyline", { points, fill: "none", stroke: color, strokeWidth: "1.5", opacity: "0.9" }) })
|
|
1339
2048
|
}
|
|
1340
2049
|
);
|
|
1341
2050
|
};
|
|
@@ -1349,8 +2058,8 @@ var EquipmentIndicatorWithSparkline = ({
|
|
|
1349
2058
|
sparklineOffset = { x: 40, y: 0 }
|
|
1350
2059
|
}) => {
|
|
1351
2060
|
const hasSparkline = sparklineData && sparklineData.length > 1 && Math.max(...sparklineData) !== Math.min(...sparklineData);
|
|
1352
|
-
return /* @__PURE__ */
|
|
1353
|
-
/* @__PURE__ */
|
|
2061
|
+
return /* @__PURE__ */ jsxs8(Fragment3, { children: [
|
|
2062
|
+
/* @__PURE__ */ jsx11(SVGLockedOverlay, { svgX, svgY, style: { transform: "translate(-50%, -50%)" }, children: /* @__PURE__ */ jsx11(
|
|
1354
2063
|
"div",
|
|
1355
2064
|
{
|
|
1356
2065
|
style: {
|
|
@@ -1371,7 +2080,7 @@ var EquipmentIndicatorWithSparkline = ({
|
|
|
1371
2080
|
children: label
|
|
1372
2081
|
}
|
|
1373
2082
|
) }),
|
|
1374
|
-
hasSparkline && /* @__PURE__ */
|
|
2083
|
+
hasSparkline && /* @__PURE__ */ jsx11(SVGLockedOverlay, { svgX: svgX + sparklineOffset.x, svgY: svgY + sparklineOffset.y, children: /* @__PURE__ */ jsx11(Sparkline, { data: sparklineData, width: 60, height: 20, color }) })
|
|
1375
2084
|
] });
|
|
1376
2085
|
};
|
|
1377
2086
|
var EquipmentIndicator = ({
|
|
@@ -1384,7 +2093,7 @@ var EquipmentIndicator = ({
|
|
|
1384
2093
|
className
|
|
1385
2094
|
}) => {
|
|
1386
2095
|
const overlayStyle = style !== void 0 ? { transform: "translate(-50%, -50%)", ...style } : { transform: "translate(-50%, -50%)" };
|
|
1387
|
-
return /* @__PURE__ */
|
|
2096
|
+
return /* @__PURE__ */ jsx11(SVGLockedOverlay, { svgX, svgY, style: overlayStyle, className, children: /* @__PURE__ */ jsx11(
|
|
1388
2097
|
"div",
|
|
1389
2098
|
{
|
|
1390
2099
|
style: {
|
|
@@ -1408,7 +2117,7 @@ var EquipmentIndicator = ({
|
|
|
1408
2117
|
};
|
|
1409
2118
|
|
|
1410
2119
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.tsx
|
|
1411
|
-
import { Fragment as
|
|
2120
|
+
import { Fragment as Fragment4, jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1412
2121
|
function FullscreenWorkspace({
|
|
1413
2122
|
svgContent,
|
|
1414
2123
|
overlays,
|
|
@@ -1436,10 +2145,10 @@ function FullscreenWorkspace({
|
|
|
1436
2145
|
className = "",
|
|
1437
2146
|
...rest
|
|
1438
2147
|
}) {
|
|
1439
|
-
const [leftCollapsedState, setLeftCollapsedState] =
|
|
1440
|
-
const [rightCollapsedState, setRightCollapsedState] =
|
|
1441
|
-
const [internalDisplayMode, setInternalDisplayMode] =
|
|
1442
|
-
const [internalTab, setInternalTab] =
|
|
2148
|
+
const [leftCollapsedState, setLeftCollapsedState] = React6.useState(defaultLeftCollapsed);
|
|
2149
|
+
const [rightCollapsedState, setRightCollapsedState] = React6.useState(defaultRightCollapsed);
|
|
2150
|
+
const [internalDisplayMode, setInternalDisplayMode] = React6.useState(displayMode ?? defaultDisplayMode);
|
|
2151
|
+
const [internalTab, setInternalTab] = React6.useState(
|
|
1443
2152
|
tabs && tabs.length > 0 ? tabs[0].value : ""
|
|
1444
2153
|
);
|
|
1445
2154
|
const leftCollapsed = leftCollapsedProp ?? leftCollapsedState;
|
|
@@ -1447,10 +2156,10 @@ function FullscreenWorkspace({
|
|
|
1447
2156
|
const isDisplayModeControlled = displayMode !== void 0;
|
|
1448
2157
|
const currentDisplayMode = isDisplayModeControlled ? displayMode : internalDisplayMode;
|
|
1449
2158
|
const isTabControlled = activeTab !== void 0 && activeTab !== null;
|
|
1450
|
-
const resolvedTabs =
|
|
2159
|
+
const resolvedTabs = React6.useMemo(() => tabs ?? [], [tabs]);
|
|
1451
2160
|
const defaultTabValue = resolvedTabs.length > 0 ? resolvedTabs[0].value : "";
|
|
1452
2161
|
const currentTab = isTabControlled ? activeTab : internalTab || defaultTabValue;
|
|
1453
|
-
|
|
2162
|
+
React6.useEffect(() => {
|
|
1454
2163
|
if (resolvedTabs.length > 0) {
|
|
1455
2164
|
const values = resolvedTabs.map((tab) => tab.value);
|
|
1456
2165
|
if (!values.includes(currentTab)) {
|
|
@@ -1459,7 +2168,7 @@ function FullscreenWorkspace({
|
|
|
1459
2168
|
}
|
|
1460
2169
|
}
|
|
1461
2170
|
}, [resolvedTabs, activeTab, currentTab, defaultTabValue]);
|
|
1462
|
-
|
|
2171
|
+
React6.useEffect(() => {
|
|
1463
2172
|
if (displayMode !== void 0) {
|
|
1464
2173
|
setInternalDisplayMode(displayMode);
|
|
1465
2174
|
}
|
|
@@ -1494,7 +2203,7 @@ function FullscreenWorkspace({
|
|
|
1494
2203
|
const currentTabContent = resolvedTabs.find((tab) => tab.value === currentTab)?.content ?? null;
|
|
1495
2204
|
const showLeftToggle = Boolean(leftPanel);
|
|
1496
2205
|
const showRightToggle = Boolean(rightPanel);
|
|
1497
|
-
return /* @__PURE__ */
|
|
2206
|
+
return /* @__PURE__ */ jsxs9(
|
|
1498
2207
|
FullscreenContainer,
|
|
1499
2208
|
{
|
|
1500
2209
|
leftCollapsed,
|
|
@@ -1502,25 +2211,25 @@ function FullscreenWorkspace({
|
|
|
1502
2211
|
className: `tff-svg-container ${className}`.trim(),
|
|
1503
2212
|
...rest,
|
|
1504
2213
|
children: [
|
|
1505
|
-
showLeftToggle && /* @__PURE__ */
|
|
2214
|
+
showLeftToggle && /* @__PURE__ */ jsx12(
|
|
1506
2215
|
LeftToggleButton,
|
|
1507
2216
|
{
|
|
1508
2217
|
collapsed: leftCollapsed,
|
|
1509
2218
|
onClick: handleLeftToggle,
|
|
1510
2219
|
"aria-label": leftCollapsed ? "Expand left panel" : "Collapse left panel",
|
|
1511
|
-
children: leftCollapsed ? /* @__PURE__ */
|
|
2220
|
+
children: leftCollapsed ? /* @__PURE__ */ jsx12(ChevronRight, {}) : /* @__PURE__ */ jsx12(ChevronLeft, {})
|
|
1512
2221
|
}
|
|
1513
2222
|
),
|
|
1514
|
-
showRightToggle && /* @__PURE__ */
|
|
2223
|
+
showRightToggle && /* @__PURE__ */ jsx12(
|
|
1515
2224
|
RightToggleButton,
|
|
1516
2225
|
{
|
|
1517
2226
|
collapsed: rightCollapsed,
|
|
1518
2227
|
onClick: handleRightToggle,
|
|
1519
2228
|
"aria-label": rightCollapsed ? "Expand right panel" : "Collapse right panel",
|
|
1520
|
-
children: rightCollapsed ? /* @__PURE__ */
|
|
2229
|
+
children: rightCollapsed ? /* @__PURE__ */ jsx12(ChevronLeft, {}) : /* @__PURE__ */ jsx12(ChevronRight, {})
|
|
1521
2230
|
}
|
|
1522
2231
|
),
|
|
1523
|
-
showDisplayModeToggle && /* @__PURE__ */
|
|
2232
|
+
showDisplayModeToggle && /* @__PURE__ */ jsx12(
|
|
1524
2233
|
DisplayModeToggle,
|
|
1525
2234
|
{
|
|
1526
2235
|
mode: currentDisplayMode,
|
|
@@ -1529,9 +2238,9 @@ function FullscreenWorkspace({
|
|
|
1529
2238
|
children: currentDisplayMode === "dashboard" ? "Dashboard Mode" : "Standard Mode"
|
|
1530
2239
|
}
|
|
1531
2240
|
),
|
|
1532
|
-
/* @__PURE__ */
|
|
1533
|
-
showZoomControls && /* @__PURE__ */
|
|
1534
|
-
/* @__PURE__ */
|
|
2241
|
+
/* @__PURE__ */ jsxs9(SVGArea, { children: [
|
|
2242
|
+
showZoomControls && /* @__PURE__ */ jsxs9(ZoomControls, { children: [
|
|
2243
|
+
/* @__PURE__ */ jsx12(
|
|
1535
2244
|
ZoomButton,
|
|
1536
2245
|
{
|
|
1537
2246
|
onClick: onZoomIn,
|
|
@@ -1541,7 +2250,7 @@ function FullscreenWorkspace({
|
|
|
1541
2250
|
children: "+"
|
|
1542
2251
|
}
|
|
1543
2252
|
),
|
|
1544
|
-
/* @__PURE__ */
|
|
2253
|
+
/* @__PURE__ */ jsx12(
|
|
1545
2254
|
ZoomButton,
|
|
1546
2255
|
{
|
|
1547
2256
|
onClick: onZoomOut,
|
|
@@ -1551,7 +2260,7 @@ function FullscreenWorkspace({
|
|
|
1551
2260
|
children: "-"
|
|
1552
2261
|
}
|
|
1553
2262
|
),
|
|
1554
|
-
onResetZoom && /* @__PURE__ */
|
|
2263
|
+
onResetZoom && /* @__PURE__ */ jsx12(
|
|
1555
2264
|
ZoomButton,
|
|
1556
2265
|
{
|
|
1557
2266
|
onClick: onResetZoom,
|
|
@@ -1562,33 +2271,33 @@ function FullscreenWorkspace({
|
|
|
1562
2271
|
}
|
|
1563
2272
|
)
|
|
1564
2273
|
] }),
|
|
1565
|
-
/* @__PURE__ */
|
|
2274
|
+
/* @__PURE__ */ jsx12(ScrollableSVGWrapper, { className: "svg-scroll-wrapper", children: /* @__PURE__ */ jsxs9(FixedSVGContainer, { className: "svg-container", children: [
|
|
1566
2275
|
svgContent,
|
|
1567
2276
|
overlays
|
|
1568
2277
|
] }) })
|
|
1569
2278
|
] }),
|
|
1570
|
-
/* @__PURE__ */
|
|
1571
|
-
/* @__PURE__ */
|
|
2279
|
+
/* @__PURE__ */ jsx12(LeftPanel, { collapsed: leftCollapsed, children: resolvedTabs.length > 0 ? /* @__PURE__ */ jsxs9(Fragment4, { children: [
|
|
2280
|
+
/* @__PURE__ */ jsx12(
|
|
1572
2281
|
PanelTabs,
|
|
1573
2282
|
{
|
|
1574
2283
|
value: currentTab,
|
|
1575
2284
|
onChange: handleTabChangeInternal,
|
|
1576
2285
|
"aria-label": "Left panel tabs",
|
|
1577
|
-
children: resolvedTabs.map((tab) => /* @__PURE__ */
|
|
2286
|
+
children: resolvedTabs.map((tab) => /* @__PURE__ */ jsx12(Tab, { label: tab.label, value: tab.value }, tab.value))
|
|
1578
2287
|
}
|
|
1579
2288
|
),
|
|
1580
|
-
/* @__PURE__ */
|
|
2289
|
+
/* @__PURE__ */ jsx12(PanelContent, { children: currentTabContent })
|
|
1581
2290
|
] }) : leftPanel }),
|
|
1582
|
-
/* @__PURE__ */
|
|
1583
|
-
/* @__PURE__ */
|
|
2291
|
+
/* @__PURE__ */ jsx12(RightPanel, { collapsed: rightCollapsed, children: rightPanel }),
|
|
2292
|
+
/* @__PURE__ */ jsx12(FooterPanel, { children: footer })
|
|
1584
2293
|
]
|
|
1585
2294
|
}
|
|
1586
2295
|
);
|
|
1587
2296
|
}
|
|
1588
2297
|
|
|
1589
2298
|
// src/theme/ThemeContext.tsx
|
|
1590
|
-
import { createContext, useContext, useState as
|
|
1591
|
-
import { jsx as
|
|
2299
|
+
import { createContext, useContext, useState as useState7, useEffect as useEffect4 } from "react";
|
|
2300
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
1592
2301
|
var ThemeContext = createContext(void 0);
|
|
1593
2302
|
var useTheme = () => {
|
|
1594
2303
|
const context = useContext(ThemeContext);
|
|
@@ -1598,8 +2307,8 @@ var useTheme = () => {
|
|
|
1598
2307
|
return context;
|
|
1599
2308
|
};
|
|
1600
2309
|
var ThemeProvider = ({ children }) => {
|
|
1601
|
-
const [theme, setThemeState] =
|
|
1602
|
-
|
|
2310
|
+
const [theme, setThemeState] = useState7("modern");
|
|
2311
|
+
useEffect4(() => {
|
|
1603
2312
|
document.body.className = "";
|
|
1604
2313
|
document.body.classList.add(`theme-${theme}`);
|
|
1605
2314
|
document.documentElement.className = "";
|
|
@@ -1611,11 +2320,11 @@ var ThemeProvider = ({ children }) => {
|
|
|
1611
2320
|
const setTheme = (newTheme) => {
|
|
1612
2321
|
setThemeState(newTheme);
|
|
1613
2322
|
};
|
|
1614
|
-
return /* @__PURE__ */
|
|
2323
|
+
return /* @__PURE__ */ jsx13(ThemeContext.Provider, { value: { theme, toggleTheme, setTheme }, children });
|
|
1615
2324
|
};
|
|
1616
2325
|
|
|
1617
2326
|
// src/theme/ThemeToggle.tsx
|
|
1618
|
-
import { jsx as
|
|
2327
|
+
import { jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1619
2328
|
var ThemeToggle = ({
|
|
1620
2329
|
size = "medium",
|
|
1621
2330
|
position = "top-right",
|
|
@@ -1686,15 +2395,15 @@ var ThemeToggle = ({
|
|
|
1686
2395
|
transition: "all 0.2s ease",
|
|
1687
2396
|
boxShadow: "0 2px 4px rgba(0, 0, 0, 0.2)"
|
|
1688
2397
|
};
|
|
1689
|
-
return /* @__PURE__ */
|
|
1690
|
-
/* @__PURE__ */
|
|
1691
|
-
/* @__PURE__ */
|
|
1692
|
-
/* @__PURE__ */
|
|
2398
|
+
return /* @__PURE__ */ jsxs10("div", { style: currentStyle, onClick: toggleTheme, className, ...props, children: [
|
|
2399
|
+
/* @__PURE__ */ jsx14("span", { children: theme === "modern" ? "\u{1F3A8} Modern" : "\u{1F3ED} HMI" }),
|
|
2400
|
+
/* @__PURE__ */ jsx14("div", { style: toggleStyle, children: /* @__PURE__ */ jsx14("div", { style: thumbStyle }) }),
|
|
2401
|
+
/* @__PURE__ */ jsx14("span", { style: { fontSize: "0.75rem", opacity: 0.8 }, children: theme === "modern" ? "Industrial Design" : "High Performance" })
|
|
1693
2402
|
] });
|
|
1694
2403
|
};
|
|
1695
2404
|
|
|
1696
2405
|
// src/components/PIDCanvas/PIDCanvas.tsx
|
|
1697
|
-
import { useCallback as useCallback7, useState as
|
|
2406
|
+
import { useCallback as useCallback7, useState as useState13, useEffect as useEffect11, useRef as useRef5 } from "react";
|
|
1698
2407
|
|
|
1699
2408
|
// src/diagram/symbols/mockSymbolLibrary.ts
|
|
1700
2409
|
var mockSymbolLibrary = {
|
|
@@ -2915,7 +3624,7 @@ function getAvailableSymbols() {
|
|
|
2915
3624
|
}
|
|
2916
3625
|
|
|
2917
3626
|
// src/components/PIDCanvas/NodeRenderer.tsx
|
|
2918
|
-
import { jsx as
|
|
3627
|
+
import { jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2919
3628
|
function NodeRenderer({
|
|
2920
3629
|
nodes: nodes2,
|
|
2921
3630
|
selectedNodeIds,
|
|
@@ -2926,13 +3635,13 @@ function NodeRenderer({
|
|
|
2926
3635
|
dragOffset = { x: 0, y: 0 },
|
|
2927
3636
|
enableDrag = false
|
|
2928
3637
|
}) {
|
|
2929
|
-
return /* @__PURE__ */
|
|
3638
|
+
return /* @__PURE__ */ jsx15("g", { id: "layer-nodes", children: nodes2.filter((node) => node.visible !== false).map((node) => {
|
|
2930
3639
|
const symbol = getSymbolDefinition(node.symbolId);
|
|
2931
3640
|
const isSelected = selectedNodeIds?.has(node.id) ?? false;
|
|
2932
3641
|
const isDragging = draggingNodeId === node.id;
|
|
2933
3642
|
if (!symbol) {
|
|
2934
|
-
return /* @__PURE__ */
|
|
2935
|
-
/* @__PURE__ */
|
|
3643
|
+
return /* @__PURE__ */ jsxs11("g", { children: [
|
|
3644
|
+
/* @__PURE__ */ jsx15(
|
|
2936
3645
|
"circle",
|
|
2937
3646
|
{
|
|
2938
3647
|
cx: node.transform.x,
|
|
@@ -2944,7 +3653,7 @@ function NodeRenderer({
|
|
|
2944
3653
|
strokeWidth: "2"
|
|
2945
3654
|
}
|
|
2946
3655
|
),
|
|
2947
|
-
/* @__PURE__ */
|
|
3656
|
+
/* @__PURE__ */ jsx15(
|
|
2948
3657
|
"text",
|
|
2949
3658
|
{
|
|
2950
3659
|
x: node.transform.x,
|
|
@@ -3001,7 +3710,7 @@ function NodeRenderer({
|
|
|
3001
3710
|
};
|
|
3002
3711
|
const fillColor = node.customColors?.fill ?? getStatusColor(node.status);
|
|
3003
3712
|
const strokeColor = node.customColors?.stroke ?? "rgb(0, 0, 0)";
|
|
3004
|
-
return /* @__PURE__ */
|
|
3713
|
+
return /* @__PURE__ */ jsxs11(
|
|
3005
3714
|
"g",
|
|
3006
3715
|
{
|
|
3007
3716
|
"data-node-id": node.id,
|
|
@@ -3034,7 +3743,7 @@ function NodeRenderer({
|
|
|
3034
3743
|
}
|
|
3035
3744
|
},
|
|
3036
3745
|
children: [
|
|
3037
|
-
isSelected && /* @__PURE__ */
|
|
3746
|
+
isSelected && /* @__PURE__ */ jsx15(
|
|
3038
3747
|
"rect",
|
|
3039
3748
|
{
|
|
3040
3749
|
x: "-5",
|
|
@@ -3049,7 +3758,7 @@ function NodeRenderer({
|
|
|
3049
3758
|
pointerEvents: "none"
|
|
3050
3759
|
}
|
|
3051
3760
|
),
|
|
3052
|
-
/* @__PURE__ */
|
|
3761
|
+
/* @__PURE__ */ jsx15(
|
|
3053
3762
|
"g",
|
|
3054
3763
|
{
|
|
3055
3764
|
dangerouslySetInnerHTML: { __html: symbol.svgContent },
|
|
@@ -3057,7 +3766,7 @@ function NodeRenderer({
|
|
|
3057
3766
|
style: { pointerEvents: "auto" }
|
|
3058
3767
|
}
|
|
3059
3768
|
),
|
|
3060
|
-
/* @__PURE__ */
|
|
3769
|
+
/* @__PURE__ */ jsx15(
|
|
3061
3770
|
"text",
|
|
3062
3771
|
{
|
|
3063
3772
|
x: symbol.viewBox.width / 2 + (node.labelOffset?.x ?? 0),
|
|
@@ -3078,7 +3787,7 @@ function NodeRenderer({
|
|
|
3078
3787
|
}
|
|
3079
3788
|
|
|
3080
3789
|
// src/components/PIDCanvas/PipeRenderer.tsx
|
|
3081
|
-
import { Fragment as
|
|
3790
|
+
import { Fragment as Fragment5, jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
3082
3791
|
function PipeRenderer({
|
|
3083
3792
|
pipes,
|
|
3084
3793
|
selectedPipeIds,
|
|
@@ -3093,7 +3802,7 @@ function PipeRenderer({
|
|
|
3093
3802
|
waypointDragOffset,
|
|
3094
3803
|
onPipeSegmentClick
|
|
3095
3804
|
}) {
|
|
3096
|
-
return /* @__PURE__ */
|
|
3805
|
+
return /* @__PURE__ */ jsx16("g", { id: "layer-pipes", children: pipes.filter((pipe) => pipe.visible !== false).map((pipe) => {
|
|
3097
3806
|
const isSelected = selectedPipeIds?.has(pipe.id) ?? false;
|
|
3098
3807
|
const isEditing = enableWaypointEditing && editingPipeId === pipe.id;
|
|
3099
3808
|
const showEditingControls = enableWaypointEditing && isSelected;
|
|
@@ -3112,7 +3821,7 @@ function PipeRenderer({
|
|
|
3112
3821
|
const strokeWidth = isSelected ? (pipeStyle.strokeWidth || 3) + 2 : pipeStyle.strokeWidth || 3;
|
|
3113
3822
|
const strokeDasharray = pipeStyle.strokeDasharray;
|
|
3114
3823
|
const opacity = pipeStyle.opacity !== void 0 ? pipeStyle.opacity : 1;
|
|
3115
|
-
return /* @__PURE__ */
|
|
3824
|
+
return /* @__PURE__ */ jsxs12(
|
|
3116
3825
|
"g",
|
|
3117
3826
|
{
|
|
3118
3827
|
"data-pipe-id": pipe.id,
|
|
@@ -3125,8 +3834,8 @@ function PipeRenderer({
|
|
|
3125
3834
|
cursor: onPipeClick ? "pointer" : "default"
|
|
3126
3835
|
},
|
|
3127
3836
|
children: [
|
|
3128
|
-
!enableWaypointEditing && /* @__PURE__ */
|
|
3129
|
-
onPipeClick && /* @__PURE__ */
|
|
3837
|
+
!enableWaypointEditing && /* @__PURE__ */ jsxs12(Fragment5, { children: [
|
|
3838
|
+
onPipeClick && /* @__PURE__ */ jsx16(
|
|
3130
3839
|
"polyline",
|
|
3131
3840
|
{
|
|
3132
3841
|
points: pointsString,
|
|
@@ -3138,7 +3847,7 @@ function PipeRenderer({
|
|
|
3138
3847
|
pointerEvents: "stroke"
|
|
3139
3848
|
}
|
|
3140
3849
|
),
|
|
3141
|
-
/* @__PURE__ */
|
|
3850
|
+
/* @__PURE__ */ jsx16(
|
|
3142
3851
|
"polyline",
|
|
3143
3852
|
{
|
|
3144
3853
|
points: pointsString,
|
|
@@ -3162,7 +3871,7 @@ function PipeRenderer({
|
|
|
3162
3871
|
const waypointSize = isSelectedWaypoint ? 8 : isDragging ? 8 : showEditingControls ? 6 : isSelected ? 3 : 2;
|
|
3163
3872
|
const waypointOpacity = isSelectedWaypoint ? 1 : isDragging ? 1 : showEditingControls ? 0.9 : isSelected ? 0.8 : 0.5;
|
|
3164
3873
|
const waypointColor = isSelectedWaypoint ? "#3b82f6" : isEndpoint && showEditingControls ? "#f59e0b" : isDragging ? "#10b981" : stroke;
|
|
3165
|
-
return /* @__PURE__ */
|
|
3874
|
+
return /* @__PURE__ */ jsx16(
|
|
3166
3875
|
"circle",
|
|
3167
3876
|
{
|
|
3168
3877
|
cx: point.x,
|
|
@@ -3199,12 +3908,12 @@ function PipeRenderer({
|
|
|
3199
3908
|
`${pipe.id}-point-${idx}`
|
|
3200
3909
|
);
|
|
3201
3910
|
}),
|
|
3202
|
-
showEditingControls && onPipeSegmentClick && displayPoints.length >= 2 && /* @__PURE__ */
|
|
3911
|
+
showEditingControls && onPipeSegmentClick && displayPoints.length >= 2 && /* @__PURE__ */ jsx16(Fragment5, { children: displayPoints.slice(0, -1).map((point, idx) => {
|
|
3203
3912
|
const nextPoint = displayPoints[idx + 1];
|
|
3204
3913
|
const midX = (point.x + nextPoint.x) / 2;
|
|
3205
3914
|
const midY = (point.y + nextPoint.y) / 2;
|
|
3206
|
-
return /* @__PURE__ */
|
|
3207
|
-
/* @__PURE__ */
|
|
3915
|
+
return /* @__PURE__ */ jsxs12("g", { children: [
|
|
3916
|
+
/* @__PURE__ */ jsx16(
|
|
3208
3917
|
"circle",
|
|
3209
3918
|
{
|
|
3210
3919
|
cx: midX,
|
|
@@ -3220,7 +3929,7 @@ function PipeRenderer({
|
|
|
3220
3929
|
}
|
|
3221
3930
|
}
|
|
3222
3931
|
),
|
|
3223
|
-
/* @__PURE__ */
|
|
3932
|
+
/* @__PURE__ */ jsx16(
|
|
3224
3933
|
"circle",
|
|
3225
3934
|
{
|
|
3226
3935
|
cx: midX,
|
|
@@ -3236,7 +3945,7 @@ function PipeRenderer({
|
|
|
3236
3945
|
)
|
|
3237
3946
|
] }, `${pipe.id}-segment-${idx}`);
|
|
3238
3947
|
}) }),
|
|
3239
|
-
pipe.showLabel !== false && pipe.label && pipe.routePoints.length >= 2 && /* @__PURE__ */
|
|
3948
|
+
pipe.showLabel !== false && pipe.label && pipe.routePoints.length >= 2 && /* @__PURE__ */ jsx16(
|
|
3240
3949
|
"text",
|
|
3241
3950
|
{
|
|
3242
3951
|
x: pipe.routePoints[Math.floor(pipe.routePoints.length / 2)].x + (pipe.labelOffset?.x ?? 0),
|
|
@@ -3258,7 +3967,7 @@ function PipeRenderer({
|
|
|
3258
3967
|
}
|
|
3259
3968
|
|
|
3260
3969
|
// src/components/PIDCanvas/DataOverlay.tsx
|
|
3261
|
-
import { Fragment as
|
|
3970
|
+
import { Fragment as Fragment6, jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
3262
3971
|
function DataOverlay({
|
|
3263
3972
|
nodeId,
|
|
3264
3973
|
x,
|
|
@@ -3278,7 +3987,7 @@ function DataOverlay({
|
|
|
3278
3987
|
const offsetX = display?.offsetX ?? 0;
|
|
3279
3988
|
const offsetY = display?.offsetY ?? 0;
|
|
3280
3989
|
if (!showValue) {
|
|
3281
|
-
return /* @__PURE__ */
|
|
3990
|
+
return /* @__PURE__ */ jsx17(Fragment6, {});
|
|
3282
3991
|
}
|
|
3283
3992
|
const formatValue = (val) => {
|
|
3284
3993
|
if (typeof val === "number") {
|
|
@@ -3296,9 +4005,14 @@ function DataOverlay({
|
|
|
3296
4005
|
fault: { bg: "#dc2626", text: "#ffffff", border: "#b91c1c" },
|
|
3297
4006
|
off: { bg: "#6b7280", text: "#ffffff", border: "#4b5563" }
|
|
3298
4007
|
};
|
|
3299
|
-
const
|
|
3300
|
-
|
|
3301
|
-
|
|
4008
|
+
const getStatusColors = () => {
|
|
4009
|
+
const customColor = telemetry.statusColors?.[value.status];
|
|
4010
|
+
if (customColor) {
|
|
4011
|
+
return { bg: customColor, text: "#ffffff", border: customColor };
|
|
4012
|
+
}
|
|
4013
|
+
return defaultStatusColors[value.status] || defaultStatusColors.normal;
|
|
4014
|
+
};
|
|
4015
|
+
const statusColors = getStatusColors();
|
|
3302
4016
|
const colors = backgroundColor && backgroundColor !== "status" ? { bg: backgroundColor, text: textColor || "#ffffff", border: backgroundColor } : statusColors;
|
|
3303
4017
|
const finalTextColor = textColor || colors.text;
|
|
3304
4018
|
const formattedValue = formatValue(value.value);
|
|
@@ -3325,8 +4039,8 @@ function DataOverlay({
|
|
|
3325
4039
|
const overlayWidth = 80 * scale;
|
|
3326
4040
|
const displayX = x + offsetX;
|
|
3327
4041
|
const displayY = y + offsetY;
|
|
3328
|
-
return /* @__PURE__ */
|
|
3329
|
-
/* @__PURE__ */
|
|
4042
|
+
return /* @__PURE__ */ jsxs13("g", { "data-overlay-node": nodeId, "data-status": value.status, children: [
|
|
4043
|
+
/* @__PURE__ */ jsx17(
|
|
3330
4044
|
"rect",
|
|
3331
4045
|
{
|
|
3332
4046
|
x: displayX - overlayWidth / 2,
|
|
@@ -3341,7 +4055,7 @@ function DataOverlay({
|
|
|
3341
4055
|
filter: "drop-shadow(0 2px 4px rgba(0,0,0,0.2))"
|
|
3342
4056
|
}
|
|
3343
4057
|
),
|
|
3344
|
-
label && /* @__PURE__ */
|
|
4058
|
+
label && /* @__PURE__ */ jsx17(
|
|
3345
4059
|
"text",
|
|
3346
4060
|
{
|
|
3347
4061
|
x: displayX,
|
|
@@ -3354,7 +4068,7 @@ function DataOverlay({
|
|
|
3354
4068
|
children: label
|
|
3355
4069
|
}
|
|
3356
4070
|
),
|
|
3357
|
-
/* @__PURE__ */
|
|
4071
|
+
/* @__PURE__ */ jsx17(
|
|
3358
4072
|
"text",
|
|
3359
4073
|
{
|
|
3360
4074
|
x: displayX,
|
|
@@ -3367,7 +4081,7 @@ function DataOverlay({
|
|
|
3367
4081
|
children: displayText
|
|
3368
4082
|
}
|
|
3369
4083
|
),
|
|
3370
|
-
showStatus && value.status !== "normal" && /* @__PURE__ */
|
|
4084
|
+
showStatus && value.status !== "normal" && /* @__PURE__ */ jsx17(
|
|
3371
4085
|
"circle",
|
|
3372
4086
|
{
|
|
3373
4087
|
cx: displayX + 35 * scale,
|
|
@@ -3375,7 +4089,7 @@ function DataOverlay({
|
|
|
3375
4089
|
r: 3 * scale,
|
|
3376
4090
|
fill: finalTextColor,
|
|
3377
4091
|
opacity: "0.9",
|
|
3378
|
-
children: /* @__PURE__ */
|
|
4092
|
+
children: /* @__PURE__ */ jsx17(
|
|
3379
4093
|
"animate",
|
|
3380
4094
|
{
|
|
3381
4095
|
attributeName: "opacity",
|
|
@@ -3386,7 +4100,7 @@ function DataOverlay({
|
|
|
3386
4100
|
)
|
|
3387
4101
|
}
|
|
3388
4102
|
),
|
|
3389
|
-
value.quality !== void 0 && value.quality < 100 && /* @__PURE__ */
|
|
4103
|
+
value.quality !== void 0 && value.quality < 100 && /* @__PURE__ */ jsxs13(
|
|
3390
4104
|
"text",
|
|
3391
4105
|
{
|
|
3392
4106
|
x: displayX,
|
|
@@ -3403,7 +4117,7 @@ function DataOverlay({
|
|
|
3403
4117
|
]
|
|
3404
4118
|
}
|
|
3405
4119
|
),
|
|
3406
|
-
hasSparkline && /* @__PURE__ */
|
|
4120
|
+
hasSparkline && /* @__PURE__ */ jsx17("g", { transform: `translate(${displayX - 35 * scale}, ${displayY + (label ? 5 : 0) * scale})`, children: /* @__PURE__ */ jsx17(
|
|
3407
4121
|
"path",
|
|
3408
4122
|
{
|
|
3409
4123
|
d: sparklinePath,
|
|
@@ -3419,8 +4133,8 @@ function DataOverlay({
|
|
|
3419
4133
|
}
|
|
3420
4134
|
|
|
3421
4135
|
// src/components/PIDCanvas/PositionPanel.tsx
|
|
3422
|
-
import { useState as
|
|
3423
|
-
import { jsx as
|
|
4136
|
+
import { useState as useState8, useEffect as useEffect5 } from "react";
|
|
4137
|
+
import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
3424
4138
|
function PositionPanel({
|
|
3425
4139
|
selectedNode,
|
|
3426
4140
|
selectedWaypoint,
|
|
@@ -3428,9 +4142,9 @@ function PositionPanel({
|
|
|
3428
4142
|
onWaypointPositionChange,
|
|
3429
4143
|
position = "top-right"
|
|
3430
4144
|
}) {
|
|
3431
|
-
const [x, setX] =
|
|
3432
|
-
const [y, setY] =
|
|
3433
|
-
|
|
4145
|
+
const [x, setX] = useState8("");
|
|
4146
|
+
const [y, setY] = useState8("");
|
|
4147
|
+
useEffect5(() => {
|
|
3434
4148
|
if (selectedNode) {
|
|
3435
4149
|
setX(selectedNode.transform.x.toFixed(2));
|
|
3436
4150
|
setY(selectedNode.transform.y.toFixed(2));
|
|
@@ -3489,7 +4203,7 @@ function PositionPanel({
|
|
|
3489
4203
|
"bottom-left": { bottom: 10, left: 10 },
|
|
3490
4204
|
"bottom-right": { bottom: 10, right: 10 }
|
|
3491
4205
|
};
|
|
3492
|
-
return /* @__PURE__ */
|
|
4206
|
+
return /* @__PURE__ */ jsxs14(
|
|
3493
4207
|
"div",
|
|
3494
4208
|
{
|
|
3495
4209
|
style: {
|
|
@@ -3506,11 +4220,11 @@ function PositionPanel({
|
|
|
3506
4220
|
fontSize: "13px"
|
|
3507
4221
|
},
|
|
3508
4222
|
children: [
|
|
3509
|
-
/* @__PURE__ */
|
|
3510
|
-
/* @__PURE__ */
|
|
3511
|
-
/* @__PURE__ */
|
|
3512
|
-
/* @__PURE__ */
|
|
3513
|
-
/* @__PURE__ */
|
|
4223
|
+
/* @__PURE__ */ jsx18("div", { style: { marginBottom: "8px", fontWeight: 600, color: "#333" }, children: "Position" }),
|
|
4224
|
+
/* @__PURE__ */ jsxs14("div", { style: { display: "flex", flexDirection: "column", gap: "8px" }, children: [
|
|
4225
|
+
/* @__PURE__ */ jsxs14("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
|
|
4226
|
+
/* @__PURE__ */ jsx18("label", { style: { width: "16px", color: "#666" }, children: "X:" }),
|
|
4227
|
+
/* @__PURE__ */ jsx18(
|
|
3514
4228
|
"input",
|
|
3515
4229
|
{
|
|
3516
4230
|
type: "number",
|
|
@@ -3528,9 +4242,9 @@ function PositionPanel({
|
|
|
3528
4242
|
}
|
|
3529
4243
|
)
|
|
3530
4244
|
] }),
|
|
3531
|
-
/* @__PURE__ */
|
|
3532
|
-
/* @__PURE__ */
|
|
3533
|
-
/* @__PURE__ */
|
|
4245
|
+
/* @__PURE__ */ jsxs14("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
|
|
4246
|
+
/* @__PURE__ */ jsx18("label", { style: { width: "16px", color: "#666" }, children: "Y:" }),
|
|
4247
|
+
/* @__PURE__ */ jsx18(
|
|
3534
4248
|
"input",
|
|
3535
4249
|
{
|
|
3536
4250
|
type: "number",
|
|
@@ -3549,14 +4263,14 @@ function PositionPanel({
|
|
|
3549
4263
|
)
|
|
3550
4264
|
] })
|
|
3551
4265
|
] }),
|
|
3552
|
-
/* @__PURE__ */
|
|
4266
|
+
/* @__PURE__ */ jsx18("div", { style: { marginTop: "8px", fontSize: "11px", color: "#888" }, children: "Use arrow keys to nudge (\xB11px)" })
|
|
3553
4267
|
]
|
|
3554
4268
|
}
|
|
3555
4269
|
);
|
|
3556
4270
|
}
|
|
3557
4271
|
|
|
3558
4272
|
// src/diagram/hooks/useViewBox.ts
|
|
3559
|
-
import { useState as
|
|
4273
|
+
import { useState as useState9, useCallback as useCallback3, useRef as useRef2, useEffect as useEffect6 } from "react";
|
|
3560
4274
|
function useViewBox(options) {
|
|
3561
4275
|
const {
|
|
3562
4276
|
initialViewBox,
|
|
@@ -3567,7 +4281,7 @@ function useViewBox(options) {
|
|
|
3567
4281
|
zoomSensitivity = 1e-3,
|
|
3568
4282
|
allowLeftClickPan = true
|
|
3569
4283
|
} = options;
|
|
3570
|
-
const [viewBox, setViewBox] =
|
|
4284
|
+
const [viewBox, setViewBox] = useState9(initialViewBox);
|
|
3571
4285
|
const svgRef = useRef2(null);
|
|
3572
4286
|
const isPanningRef = useRef2(false);
|
|
3573
4287
|
const lastMousePosRef = useRef2({ x: 0, y: 0 });
|
|
@@ -3638,7 +4352,7 @@ function useViewBox(options) {
|
|
|
3638
4352
|
height: newHeight
|
|
3639
4353
|
});
|
|
3640
4354
|
}, [initialViewBox]);
|
|
3641
|
-
|
|
4355
|
+
useEffect6(() => {
|
|
3642
4356
|
if (!enableZoom || !svgRef.current) return;
|
|
3643
4357
|
const svg = svgRef.current;
|
|
3644
4358
|
const handleWheel = (e) => {
|
|
@@ -3671,7 +4385,7 @@ function useViewBox(options) {
|
|
|
3671
4385
|
svg.addEventListener("wheel", handleWheel, { passive: false });
|
|
3672
4386
|
return () => svg.removeEventListener("wheel", handleWheel);
|
|
3673
4387
|
}, [enableZoom, zoomSensitivity, minZoom, initialViewBox]);
|
|
3674
|
-
|
|
4388
|
+
useEffect6(() => {
|
|
3675
4389
|
if (!enablePan || !svgRef.current) return;
|
|
3676
4390
|
const svg = svgRef.current;
|
|
3677
4391
|
const handleMouseDown = (e) => {
|
|
@@ -3747,7 +4461,7 @@ function useViewBox(options) {
|
|
|
3747
4461
|
window.removeEventListener("keyup", handleKeyUp);
|
|
3748
4462
|
};
|
|
3749
4463
|
}, [enablePan, allowLeftClickPan]);
|
|
3750
|
-
|
|
4464
|
+
useEffect6(() => {
|
|
3751
4465
|
if (!svgRef.current) return;
|
|
3752
4466
|
if (!enablePan && !enableZoom) return;
|
|
3753
4467
|
const svg = svgRef.current;
|
|
@@ -3877,14 +4591,14 @@ function useViewBox(options) {
|
|
|
3877
4591
|
}
|
|
3878
4592
|
|
|
3879
4593
|
// src/diagram/hooks/useSelection.ts
|
|
3880
|
-
import { useState as
|
|
4594
|
+
import { useState as useState10, useCallback as useCallback4 } from "react";
|
|
3881
4595
|
function useSelection(options = {}) {
|
|
3882
4596
|
const {
|
|
3883
4597
|
multiSelect = true,
|
|
3884
4598
|
initialSelection = { selectedNodeIds: /* @__PURE__ */ new Set(), selectedPipeIds: /* @__PURE__ */ new Set() },
|
|
3885
4599
|
onSelectionChange
|
|
3886
4600
|
} = options;
|
|
3887
|
-
const [selection, setSelection] =
|
|
4601
|
+
const [selection, setSelection] = useState10(initialSelection);
|
|
3888
4602
|
const notifyChange = useCallback4(
|
|
3889
4603
|
(newSelection) => {
|
|
3890
4604
|
if (onSelectionChange) {
|
|
@@ -3982,14 +4696,14 @@ function useSelection(options = {}) {
|
|
|
3982
4696
|
}
|
|
3983
4697
|
|
|
3984
4698
|
// src/diagram/hooks/useTelemetry.ts
|
|
3985
|
-
import { useState as
|
|
4699
|
+
import { useState as useState11, useCallback as useCallback5, useEffect as useEffect7, useRef as useRef3 } from "react";
|
|
3986
4700
|
function useTelemetry(options = {}) {
|
|
3987
4701
|
const {
|
|
3988
4702
|
initialBindings = [],
|
|
3989
4703
|
onTelemetryChange,
|
|
3990
4704
|
refreshInterval = 0
|
|
3991
4705
|
} = options;
|
|
3992
|
-
const [telemetry, setTelemetry] =
|
|
4706
|
+
const [telemetry, setTelemetry] = useState11(() => {
|
|
3993
4707
|
const map = /* @__PURE__ */ new Map();
|
|
3994
4708
|
initialBindings.forEach((binding) => {
|
|
3995
4709
|
map.set(binding.nodeId, binding);
|
|
@@ -4110,7 +4824,7 @@ function useTelemetry(options = {}) {
|
|
|
4110
4824
|
},
|
|
4111
4825
|
[notifyChange]
|
|
4112
4826
|
);
|
|
4113
|
-
|
|
4827
|
+
useEffect7(() => {
|
|
4114
4828
|
if (refreshInterval <= 0) return;
|
|
4115
4829
|
const intervalId = setInterval(() => {
|
|
4116
4830
|
notifyChange(telemetryRef.current);
|
|
@@ -4128,10 +4842,10 @@ function useTelemetry(options = {}) {
|
|
|
4128
4842
|
}
|
|
4129
4843
|
|
|
4130
4844
|
// src/diagram/hooks/useTelemetryStatus.ts
|
|
4131
|
-
import { useEffect as
|
|
4845
|
+
import { useEffect as useEffect8 } from "react";
|
|
4132
4846
|
function useTelemetryStatus(telemetry, diagram, setDiagram, options = {}) {
|
|
4133
4847
|
const { enabled = true, mapStatus } = options;
|
|
4134
|
-
|
|
4848
|
+
useEffect8(() => {
|
|
4135
4849
|
if (!enabled) return;
|
|
4136
4850
|
const defaultMapStatus = (telemetryStatus) => {
|
|
4137
4851
|
switch (telemetryStatus) {
|
|
@@ -4170,7 +4884,7 @@ function useTelemetryStatus(telemetry, diagram, setDiagram, options = {}) {
|
|
|
4170
4884
|
}
|
|
4171
4885
|
|
|
4172
4886
|
// src/diagram/hooks/useDrag.ts
|
|
4173
|
-
import { useState as
|
|
4887
|
+
import { useState as useState12, useCallback as useCallback6, useRef as useRef4, useEffect as useEffect9 } from "react";
|
|
4174
4888
|
function useDrag(options = {}) {
|
|
4175
4889
|
const {
|
|
4176
4890
|
onDragStart,
|
|
@@ -4180,13 +4894,13 @@ function useDrag(options = {}) {
|
|
|
4180
4894
|
dragThreshold = 3,
|
|
4181
4895
|
screenToWorld = (x, y) => ({ x, y })
|
|
4182
4896
|
} = options;
|
|
4183
|
-
const [dragState, setDragState] =
|
|
4897
|
+
const [dragState, setDragState] = useState12({
|
|
4184
4898
|
isDragging: false,
|
|
4185
4899
|
startPosition: null,
|
|
4186
4900
|
offset: { x: 0, y: 0 },
|
|
4187
4901
|
draggedId: null
|
|
4188
4902
|
});
|
|
4189
|
-
const [isListening, setIsListening] =
|
|
4903
|
+
const [isListening, setIsListening] = useState12(false);
|
|
4190
4904
|
const dragStartRef = useRef4(null);
|
|
4191
4905
|
const hasMovedRef = useRef4(false);
|
|
4192
4906
|
const applySnap = useCallback6(
|
|
@@ -4355,7 +5069,7 @@ function useDrag(options = {}) {
|
|
|
4355
5069
|
},
|
|
4356
5070
|
[screenToWorld, applySnap, onDragEnd]
|
|
4357
5071
|
);
|
|
4358
|
-
|
|
5072
|
+
useEffect9(() => {
|
|
4359
5073
|
if (!isListening) return;
|
|
4360
5074
|
document.addEventListener("mousemove", handleMouseMove);
|
|
4361
5075
|
document.addEventListener("mouseup", handleMouseUp);
|
|
@@ -4424,7 +5138,7 @@ function useDrag(options = {}) {
|
|
|
4424
5138
|
}
|
|
4425
5139
|
|
|
4426
5140
|
// src/diagram/hooks/useKeyboardShortcuts.ts
|
|
4427
|
-
import { useEffect as
|
|
5141
|
+
import { useEffect as useEffect10 } from "react";
|
|
4428
5142
|
function useKeyboardShortcuts(options) {
|
|
4429
5143
|
const {
|
|
4430
5144
|
onDelete,
|
|
@@ -4435,7 +5149,7 @@ function useKeyboardShortcuts(options) {
|
|
|
4435
5149
|
onSelectAll,
|
|
4436
5150
|
enabled = true
|
|
4437
5151
|
} = options;
|
|
4438
|
-
|
|
5152
|
+
useEffect10(() => {
|
|
4439
5153
|
if (!enabled) return;
|
|
4440
5154
|
const handleKeyDown = (event) => {
|
|
4441
5155
|
const target = event.target;
|
|
@@ -4544,7 +5258,7 @@ function nodeHasPort(node, portId) {
|
|
|
4544
5258
|
}
|
|
4545
5259
|
|
|
4546
5260
|
// src/components/PIDCanvas/PIDCanvas.tsx
|
|
4547
|
-
import { Fragment as
|
|
5261
|
+
import { Fragment as Fragment7, jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
4548
5262
|
function PIDCanvas({
|
|
4549
5263
|
diagram,
|
|
4550
5264
|
className = "",
|
|
@@ -4571,21 +5285,21 @@ function PIDCanvas({
|
|
|
4571
5285
|
telemetry,
|
|
4572
5286
|
...props
|
|
4573
5287
|
}) {
|
|
4574
|
-
const [localDiagram, setLocalDiagram] =
|
|
4575
|
-
const [dragOverPosition, setDragOverPosition] =
|
|
4576
|
-
const [isConnecting, setIsConnecting] =
|
|
4577
|
-
const [connectionSource, setConnectionSource] =
|
|
4578
|
-
const [connectionSourcePort, setConnectionSourcePort] =
|
|
4579
|
-
const [connectionCursor, setConnectionCursor] =
|
|
4580
|
-
const [hoveredNode, setHoveredNode] =
|
|
4581
|
-
const [hoveredPort, setHoveredPort] =
|
|
4582
|
-
const [selectedWaypoint, setSelectedWaypoint] =
|
|
5288
|
+
const [localDiagram, setLocalDiagram] = useState13(diagram);
|
|
5289
|
+
const [dragOverPosition, setDragOverPosition] = useState13(null);
|
|
5290
|
+
const [isConnecting, setIsConnecting] = useState13(false);
|
|
5291
|
+
const [connectionSource, setConnectionSource] = useState13(null);
|
|
5292
|
+
const [connectionSourcePort, setConnectionSourcePort] = useState13(null);
|
|
5293
|
+
const [connectionCursor, setConnectionCursor] = useState13(null);
|
|
5294
|
+
const [hoveredNode, setHoveredNode] = useState13(null);
|
|
5295
|
+
const [hoveredPort, setHoveredPort] = useState13(null);
|
|
5296
|
+
const [selectedWaypoint, setSelectedWaypoint] = useState13(null);
|
|
4583
5297
|
const historyStack = useRef5([]);
|
|
4584
5298
|
const redoStack = useRef5([]);
|
|
4585
5299
|
const isUndoRedoAction = useRef5(false);
|
|
4586
5300
|
const isInternalChange = useRef5(false);
|
|
4587
5301
|
const lastInternalDiagram = useRef5(null);
|
|
4588
|
-
|
|
5302
|
+
useEffect11(() => {
|
|
4589
5303
|
const isExternal = !isInternalChange.current && diagram !== lastInternalDiagram.current;
|
|
4590
5304
|
if (isExternal) {
|
|
4591
5305
|
setLocalDiagram(diagram);
|
|
@@ -4630,7 +5344,7 @@ function PIDCanvas({
|
|
|
4630
5344
|
});
|
|
4631
5345
|
return { minX, minY, maxX, maxY };
|
|
4632
5346
|
}, [localDiagram.nodes]);
|
|
4633
|
-
|
|
5347
|
+
useEffect11(() => {
|
|
4634
5348
|
if (onMounted) {
|
|
4635
5349
|
const controls = {
|
|
4636
5350
|
fitToContent: (padding = 50) => {
|
|
@@ -4709,7 +5423,7 @@ function PIDCanvas({
|
|
|
4709
5423
|
isUndoRedoAction.current = false;
|
|
4710
5424
|
}, 0);
|
|
4711
5425
|
}, [localDiagram, onDiagramChange]);
|
|
4712
|
-
|
|
5426
|
+
useEffect11(() => {
|
|
4713
5427
|
const handleKeyDown = (e) => {
|
|
4714
5428
|
const isCtrlOrCmd = e.ctrlKey || e.metaKey;
|
|
4715
5429
|
if (isCtrlOrCmd && e.key === "z" && !e.shiftKey) {
|
|
@@ -4726,7 +5440,7 @@ function PIDCanvas({
|
|
|
4726
5440
|
window.addEventListener("keydown", handleKeyDown);
|
|
4727
5441
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
4728
5442
|
}, [undo, redo]);
|
|
4729
|
-
|
|
5443
|
+
useEffect11(() => {
|
|
4730
5444
|
if (!features.dragNodes) return;
|
|
4731
5445
|
const handleKeyDown = (e) => {
|
|
4732
5446
|
if (selection.selectedNodeIds.size === 0 && !selectedWaypoint) return;
|
|
@@ -5136,7 +5850,7 @@ function PIDCanvas({
|
|
|
5136
5850
|
const viewBox = controlledViewBox;
|
|
5137
5851
|
const displayDiagram = localDiagram;
|
|
5138
5852
|
const selectedNode = selectionEnabled && selection.selectedNodeIds.size === 1 ? localDiagram.nodes.find((n) => selection.selectedNodeIds.has(n.id)) || null : null;
|
|
5139
|
-
return /* @__PURE__ */
|
|
5853
|
+
return /* @__PURE__ */ jsxs15(
|
|
5140
5854
|
"div",
|
|
5141
5855
|
{
|
|
5142
5856
|
ref: containerRef,
|
|
@@ -5151,7 +5865,7 @@ function PIDCanvas({
|
|
|
5151
5865
|
},
|
|
5152
5866
|
...props,
|
|
5153
5867
|
children: [
|
|
5154
|
-
/* @__PURE__ */
|
|
5868
|
+
/* @__PURE__ */ jsxs15(
|
|
5155
5869
|
"svg",
|
|
5156
5870
|
{
|
|
5157
5871
|
ref: svgRef,
|
|
@@ -5170,15 +5884,15 @@ function PIDCanvas({
|
|
|
5170
5884
|
onDrop: handleDrop,
|
|
5171
5885
|
onDragLeave: handleDragLeave,
|
|
5172
5886
|
children: [
|
|
5173
|
-
features.showGrid !== false ? /* @__PURE__ */
|
|
5174
|
-
/* @__PURE__ */
|
|
5175
|
-
/* @__PURE__ */
|
|
5176
|
-
/* @__PURE__ */
|
|
5177
|
-
/* @__PURE__ */
|
|
5178
|
-
/* @__PURE__ */
|
|
5887
|
+
features.showGrid !== false ? /* @__PURE__ */ jsxs15(Fragment7, { children: [
|
|
5888
|
+
/* @__PURE__ */ jsxs15("defs", { children: [
|
|
5889
|
+
/* @__PURE__ */ jsx19("pattern", { id: "grid-minor", width: "5", height: "5", patternUnits: "userSpaceOnUse", children: /* @__PURE__ */ jsx19("path", { d: "M 5 0 L 0 0 0 5", fill: "none", stroke: "#e5e7eb", strokeWidth: "0.5" }) }),
|
|
5890
|
+
/* @__PURE__ */ jsxs15("pattern", { id: "grid-major", width: "25", height: "25", patternUnits: "userSpaceOnUse", children: [
|
|
5891
|
+
/* @__PURE__ */ jsx19("rect", { width: "25", height: "25", fill: "url(#grid-minor)" }),
|
|
5892
|
+
/* @__PURE__ */ jsx19("path", { d: "M 25 0 L 0 0 0 25", fill: "none", stroke: "#d1d5db", strokeWidth: "1" })
|
|
5179
5893
|
] })
|
|
5180
5894
|
] }),
|
|
5181
|
-
/* @__PURE__ */
|
|
5895
|
+
/* @__PURE__ */ jsx19(
|
|
5182
5896
|
"rect",
|
|
5183
5897
|
{
|
|
5184
5898
|
x: Math.floor(viewBox.x / 25) * 25 - viewBox.width,
|
|
@@ -5188,7 +5902,7 @@ function PIDCanvas({
|
|
|
5188
5902
|
fill: "url(#grid-major)"
|
|
5189
5903
|
}
|
|
5190
5904
|
)
|
|
5191
|
-
] }) : /* @__PURE__ */
|
|
5905
|
+
] }) : /* @__PURE__ */ jsx19(
|
|
5192
5906
|
"rect",
|
|
5193
5907
|
{
|
|
5194
5908
|
x: Math.floor(viewBox.x / 25) * 25 - viewBox.width,
|
|
@@ -5198,7 +5912,7 @@ function PIDCanvas({
|
|
|
5198
5912
|
fill: features.backgroundColor ?? "#ffffff"
|
|
5199
5913
|
}
|
|
5200
5914
|
),
|
|
5201
|
-
/* @__PURE__ */
|
|
5915
|
+
/* @__PURE__ */ jsx19(
|
|
5202
5916
|
PipeRenderer,
|
|
5203
5917
|
{
|
|
5204
5918
|
pipes: displayDiagram.pipes,
|
|
@@ -5212,12 +5926,12 @@ function PIDCanvas({
|
|
|
5212
5926
|
onPipeSegmentClick: void 0
|
|
5213
5927
|
}
|
|
5214
5928
|
),
|
|
5215
|
-
/* @__PURE__ */
|
|
5929
|
+
/* @__PURE__ */ jsx19(
|
|
5216
5930
|
NodeRenderer,
|
|
5217
5931
|
{
|
|
5218
5932
|
nodes: displayDiagram.nodes,
|
|
5219
5933
|
selectedNodeIds: selectionEnabled ? selection.selectedNodeIds : void 0,
|
|
5220
|
-
onNodeClick: selectionEnabled || features.connectionMode ? handleNodeClick : void 0,
|
|
5934
|
+
onNodeClick: onNodeClick ? handleNodeClick : selectionEnabled || features.connectionMode ? handleNodeClick : void 0,
|
|
5221
5935
|
onNodeDoubleClick: selectionEnabled ? handleNodeDoubleClick : void 0,
|
|
5222
5936
|
enableDrag: dragEnabled && !isConnecting,
|
|
5223
5937
|
onNodeDragStart: dragEnabled && !isConnecting ? handleNodeDragStart : void 0,
|
|
@@ -5225,7 +5939,7 @@ function PIDCanvas({
|
|
|
5225
5939
|
dragOffset: dragState.offset
|
|
5226
5940
|
}
|
|
5227
5941
|
),
|
|
5228
|
-
(features.editPipeRoutes ?? false) && /* @__PURE__ */
|
|
5942
|
+
(features.editPipeRoutes ?? false) && /* @__PURE__ */ jsx19(
|
|
5229
5943
|
PipeRenderer,
|
|
5230
5944
|
{
|
|
5231
5945
|
pipes: displayDiagram.pipes,
|
|
@@ -5242,14 +5956,14 @@ function PIDCanvas({
|
|
|
5242
5956
|
onPipeSegmentClick: handlePipeSegmentClick
|
|
5243
5957
|
}
|
|
5244
5958
|
),
|
|
5245
|
-
telemetryEnabled && telemetry && /* @__PURE__ */
|
|
5959
|
+
telemetryEnabled && telemetry && /* @__PURE__ */ jsx19("g", { id: "layer-telemetry", children: displayDiagram.nodes.map((node) => {
|
|
5246
5960
|
const binding = telemetry.get(node.id);
|
|
5247
5961
|
if (!binding) return null;
|
|
5248
5962
|
const symbol = getSymbolDefinition(node.symbolId);
|
|
5249
5963
|
if (!symbol) return null;
|
|
5250
5964
|
const overlayX = node.transform.x + symbol.viewBox.width / 2;
|
|
5251
5965
|
const overlayY = node.transform.y + symbol.viewBox.height + 50;
|
|
5252
|
-
return /* @__PURE__ */
|
|
5966
|
+
return /* @__PURE__ */ jsx19(
|
|
5253
5967
|
DataOverlay,
|
|
5254
5968
|
{
|
|
5255
5969
|
nodeId: node.id,
|
|
@@ -5261,7 +5975,7 @@ function PIDCanvas({
|
|
|
5261
5975
|
`telemetry-${node.id}`
|
|
5262
5976
|
);
|
|
5263
5977
|
}) }),
|
|
5264
|
-
dragOverPosition && /* @__PURE__ */
|
|
5978
|
+
dragOverPosition && /* @__PURE__ */ jsx19(
|
|
5265
5979
|
"circle",
|
|
5266
5980
|
{
|
|
5267
5981
|
cx: dragOverPosition.x,
|
|
@@ -5274,7 +5988,7 @@ function PIDCanvas({
|
|
|
5274
5988
|
pointerEvents: "none"
|
|
5275
5989
|
}
|
|
5276
5990
|
),
|
|
5277
|
-
isConnecting && connectionSource && connectionCursor && /* @__PURE__ */
|
|
5991
|
+
isConnecting && connectionSource && connectionCursor && /* @__PURE__ */ jsx19("g", { id: "connection-preview", pointerEvents: "none", children: (() => {
|
|
5278
5992
|
const sourceNode = displayDiagram.nodes.find((n) => n.id === connectionSource);
|
|
5279
5993
|
if (!sourceNode) return null;
|
|
5280
5994
|
const symbol = getSymbolDefinition(sourceNode.symbolId);
|
|
@@ -5290,8 +6004,8 @@ function PIDCanvas({
|
|
|
5290
6004
|
}
|
|
5291
6005
|
}
|
|
5292
6006
|
}
|
|
5293
|
-
return /* @__PURE__ */
|
|
5294
|
-
/* @__PURE__ */
|
|
6007
|
+
return /* @__PURE__ */ jsxs15(Fragment7, { children: [
|
|
6008
|
+
/* @__PURE__ */ jsx19(
|
|
5295
6009
|
"circle",
|
|
5296
6010
|
{
|
|
5297
6011
|
cx: lineStartX,
|
|
@@ -5303,7 +6017,7 @@ function PIDCanvas({
|
|
|
5303
6017
|
opacity: 0.6
|
|
5304
6018
|
}
|
|
5305
6019
|
),
|
|
5306
|
-
/* @__PURE__ */
|
|
6020
|
+
/* @__PURE__ */ jsx19(
|
|
5307
6021
|
"line",
|
|
5308
6022
|
{
|
|
5309
6023
|
x1: lineStartX,
|
|
@@ -5316,7 +6030,7 @@ function PIDCanvas({
|
|
|
5316
6030
|
opacity: 0.8
|
|
5317
6031
|
}
|
|
5318
6032
|
),
|
|
5319
|
-
/* @__PURE__ */
|
|
6033
|
+
/* @__PURE__ */ jsx19(
|
|
5320
6034
|
"circle",
|
|
5321
6035
|
{
|
|
5322
6036
|
cx: connectionCursor.x,
|
|
@@ -5328,7 +6042,7 @@ function PIDCanvas({
|
|
|
5328
6042
|
)
|
|
5329
6043
|
] });
|
|
5330
6044
|
})() }),
|
|
5331
|
-
features.connectionMode && /* @__PURE__ */
|
|
6045
|
+
features.connectionMode && /* @__PURE__ */ jsx19("g", { id: "port-indicators", children: displayDiagram.nodes.map((node) => {
|
|
5332
6046
|
const symbol = getSymbolDefinition(node.symbolId);
|
|
5333
6047
|
if (!symbol?.ports) return null;
|
|
5334
6048
|
return symbol.ports.map((port) => {
|
|
@@ -5336,8 +6050,8 @@ function PIDCanvas({
|
|
|
5336
6050
|
if (!portPos) return null;
|
|
5337
6051
|
const isHovered = hoveredPort === port.id && hoveredNode === node.id;
|
|
5338
6052
|
const isSourcePort = node.id === connectionSource && port.id === connectionSourcePort;
|
|
5339
|
-
return /* @__PURE__ */
|
|
5340
|
-
/* @__PURE__ */
|
|
6053
|
+
return /* @__PURE__ */ jsxs15("g", { children: [
|
|
6054
|
+
/* @__PURE__ */ jsx19(
|
|
5341
6055
|
"circle",
|
|
5342
6056
|
{
|
|
5343
6057
|
cx: portPos.x,
|
|
@@ -5370,7 +6084,7 @@ function PIDCanvas({
|
|
|
5370
6084
|
}
|
|
5371
6085
|
}
|
|
5372
6086
|
),
|
|
5373
|
-
/* @__PURE__ */
|
|
6087
|
+
/* @__PURE__ */ jsx19(
|
|
5374
6088
|
"circle",
|
|
5375
6089
|
{
|
|
5376
6090
|
cx: portPos.x,
|
|
@@ -5389,7 +6103,7 @@ function PIDCanvas({
|
|
|
5389
6103
|
]
|
|
5390
6104
|
}
|
|
5391
6105
|
),
|
|
5392
|
-
features.dragNodes && /* @__PURE__ */
|
|
6106
|
+
features.dragNodes && /* @__PURE__ */ jsx19(
|
|
5393
6107
|
PositionPanel,
|
|
5394
6108
|
{
|
|
5395
6109
|
selectedNode,
|
|
@@ -5409,16 +6123,16 @@ function PIDCanvas({
|
|
|
5409
6123
|
}
|
|
5410
6124
|
|
|
5411
6125
|
// src/components/SymbolLibrary/SymbolLibrary.tsx
|
|
5412
|
-
import { useState as
|
|
5413
|
-
import { jsx as
|
|
6126
|
+
import { useState as useState14 } from "react";
|
|
6127
|
+
import { jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
5414
6128
|
function SymbolLibrary({
|
|
5415
6129
|
className = "",
|
|
5416
6130
|
onSymbolDragStart,
|
|
5417
6131
|
showCategories = true,
|
|
5418
6132
|
categories = ["Valves", "Pumps", "Tanks", "Instruments", "Displays"]
|
|
5419
6133
|
}) {
|
|
5420
|
-
const [selectedCategory, setSelectedCategory] =
|
|
5421
|
-
const [searchQuery, setSearchQuery] =
|
|
6134
|
+
const [selectedCategory, setSelectedCategory] = useState14("all");
|
|
6135
|
+
const [searchQuery, setSearchQuery] = useState14("");
|
|
5422
6136
|
const symbolIds = getAvailableSymbols();
|
|
5423
6137
|
const allSymbols = symbolIds.map((id) => getSymbolDefinition(id)).filter((symbol) => symbol !== void 0);
|
|
5424
6138
|
const categoryMap = {
|
|
@@ -5439,9 +6153,9 @@ function SymbolLibrary({
|
|
|
5439
6153
|
event.dataTransfer.effectAllowed = "copy";
|
|
5440
6154
|
onSymbolDragStart?.(symbol.id, event);
|
|
5441
6155
|
};
|
|
5442
|
-
return /* @__PURE__ */
|
|
5443
|
-
/* @__PURE__ */
|
|
5444
|
-
/* @__PURE__ */
|
|
6156
|
+
return /* @__PURE__ */ jsxs16("div", { className: `symbol-library ${className}`.trim(), style: styles.container, children: [
|
|
6157
|
+
/* @__PURE__ */ jsx20("div", { style: styles.header, children: /* @__PURE__ */ jsx20("h3", { style: styles.title, children: "Symbol Library" }) }),
|
|
6158
|
+
/* @__PURE__ */ jsx20("div", { style: styles.searchContainer, children: /* @__PURE__ */ jsx20(
|
|
5445
6159
|
"input",
|
|
5446
6160
|
{
|
|
5447
6161
|
type: "text",
|
|
@@ -5451,8 +6165,8 @@ function SymbolLibrary({
|
|
|
5451
6165
|
style: styles.searchInput
|
|
5452
6166
|
}
|
|
5453
6167
|
) }),
|
|
5454
|
-
showCategories && /* @__PURE__ */
|
|
5455
|
-
/* @__PURE__ */
|
|
6168
|
+
showCategories && /* @__PURE__ */ jsxs16("div", { style: styles.categories, children: [
|
|
6169
|
+
/* @__PURE__ */ jsx20(
|
|
5456
6170
|
"button",
|
|
5457
6171
|
{
|
|
5458
6172
|
onClick: () => setSelectedCategory("all"),
|
|
@@ -5463,7 +6177,7 @@ function SymbolLibrary({
|
|
|
5463
6177
|
children: "All"
|
|
5464
6178
|
}
|
|
5465
6179
|
),
|
|
5466
|
-
categories.map((category) => /* @__PURE__ */
|
|
6180
|
+
categories.map((category) => /* @__PURE__ */ jsx20(
|
|
5467
6181
|
"button",
|
|
5468
6182
|
{
|
|
5469
6183
|
onClick: () => setSelectedCategory(category),
|
|
@@ -5476,7 +6190,7 @@ function SymbolLibrary({
|
|
|
5476
6190
|
category
|
|
5477
6191
|
))
|
|
5478
6192
|
] }),
|
|
5479
|
-
/* @__PURE__ */
|
|
6193
|
+
/* @__PURE__ */ jsx20("div", { style: styles.symbolGrid, children: filteredSymbols.length === 0 ? /* @__PURE__ */ jsx20("div", { style: styles.emptyState, children: "No symbols found" }) : filteredSymbols.map((symbol) => /* @__PURE__ */ jsxs16(
|
|
5480
6194
|
"div",
|
|
5481
6195
|
{
|
|
5482
6196
|
draggable: true,
|
|
@@ -5484,15 +6198,15 @@ function SymbolLibrary({
|
|
|
5484
6198
|
style: styles.symbolCard,
|
|
5485
6199
|
title: symbol.metadata?.description || symbol.name,
|
|
5486
6200
|
children: [
|
|
5487
|
-
/* @__PURE__ */
|
|
6201
|
+
/* @__PURE__ */ jsx20("div", { style: styles.symbolPreview, children: /* @__PURE__ */ jsx20(
|
|
5488
6202
|
"svg",
|
|
5489
6203
|
{
|
|
5490
6204
|
viewBox: `${symbol.viewBox.x} ${symbol.viewBox.y} ${symbol.viewBox.width} ${symbol.viewBox.height}`,
|
|
5491
6205
|
style: styles.symbolSvg,
|
|
5492
|
-
children: /* @__PURE__ */
|
|
6206
|
+
children: /* @__PURE__ */ jsx20("g", { dangerouslySetInnerHTML: { __html: symbol.svgContent } })
|
|
5493
6207
|
}
|
|
5494
6208
|
) }),
|
|
5495
|
-
/* @__PURE__ */
|
|
6209
|
+
/* @__PURE__ */ jsx20("div", { style: styles.symbolName, children: symbol.name })
|
|
5496
6210
|
]
|
|
5497
6211
|
},
|
|
5498
6212
|
symbol.id
|
|
@@ -5601,7 +6315,7 @@ var styles = {
|
|
|
5601
6315
|
};
|
|
5602
6316
|
|
|
5603
6317
|
// src/components/NodeConfigPanel/NodeConfigPanel.tsx
|
|
5604
|
-
import { Fragment as
|
|
6318
|
+
import { Fragment as Fragment8, jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
5605
6319
|
function NodeConfigPanel({
|
|
5606
6320
|
node,
|
|
5607
6321
|
binding,
|
|
@@ -5620,15 +6334,15 @@ function NodeConfigPanel({
|
|
|
5620
6334
|
padding: "20px",
|
|
5621
6335
|
...style
|
|
5622
6336
|
};
|
|
5623
|
-
return /* @__PURE__ */
|
|
5624
|
-
/* @__PURE__ */
|
|
6337
|
+
return /* @__PURE__ */ jsxs17("div", { className, style: defaultStyle, children: [
|
|
6338
|
+
/* @__PURE__ */ jsxs17("h2", { style: { margin: "0 0 16px 0", fontSize: "1rem", fontWeight: 600 }, children: [
|
|
5625
6339
|
"Configure: ",
|
|
5626
6340
|
node.id
|
|
5627
6341
|
] }),
|
|
5628
|
-
/* @__PURE__ */
|
|
5629
|
-
/* @__PURE__ */
|
|
5630
|
-
/* @__PURE__ */
|
|
5631
|
-
/* @__PURE__ */
|
|
6342
|
+
/* @__PURE__ */ jsxs17("div", { style: { marginBottom: "20px" }, children: [
|
|
6343
|
+
/* @__PURE__ */ jsx21("h3", { style: { fontSize: "0.875rem", fontWeight: 600, marginBottom: "8px" }, children: "Node Settings" }),
|
|
6344
|
+
/* @__PURE__ */ jsx21("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Label:" }),
|
|
6345
|
+
/* @__PURE__ */ jsx21(
|
|
5632
6346
|
"input",
|
|
5633
6347
|
{
|
|
5634
6348
|
type: "text",
|
|
@@ -5644,10 +6358,10 @@ function NodeConfigPanel({
|
|
|
5644
6358
|
}
|
|
5645
6359
|
}
|
|
5646
6360
|
),
|
|
5647
|
-
/* @__PURE__ */
|
|
5648
|
-
/* @__PURE__ */
|
|
5649
|
-
/* @__PURE__ */
|
|
5650
|
-
/* @__PURE__ */
|
|
6361
|
+
/* @__PURE__ */ jsxs17("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: "8px" }, children: [
|
|
6362
|
+
/* @__PURE__ */ jsxs17("div", { children: [
|
|
6363
|
+
/* @__PURE__ */ jsx21("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Label Offset X:" }),
|
|
6364
|
+
/* @__PURE__ */ jsx21(
|
|
5651
6365
|
"input",
|
|
5652
6366
|
{
|
|
5653
6367
|
type: "number",
|
|
@@ -5668,9 +6382,9 @@ function NodeConfigPanel({
|
|
|
5668
6382
|
}
|
|
5669
6383
|
)
|
|
5670
6384
|
] }),
|
|
5671
|
-
/* @__PURE__ */
|
|
5672
|
-
/* @__PURE__ */
|
|
5673
|
-
/* @__PURE__ */
|
|
6385
|
+
/* @__PURE__ */ jsxs17("div", { children: [
|
|
6386
|
+
/* @__PURE__ */ jsx21("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Label Offset Y:" }),
|
|
6387
|
+
/* @__PURE__ */ jsx21(
|
|
5674
6388
|
"input",
|
|
5675
6389
|
{
|
|
5676
6390
|
type: "number",
|
|
@@ -5692,9 +6406,9 @@ function NodeConfigPanel({
|
|
|
5692
6406
|
)
|
|
5693
6407
|
] })
|
|
5694
6408
|
] }),
|
|
5695
|
-
/* @__PURE__ */
|
|
5696
|
-
/* @__PURE__ */
|
|
5697
|
-
/* @__PURE__ */
|
|
6409
|
+
/* @__PURE__ */ jsxs17("div", { children: [
|
|
6410
|
+
/* @__PURE__ */ jsx21("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Label Font Size:" }),
|
|
6411
|
+
/* @__PURE__ */ jsx21(
|
|
5698
6412
|
"input",
|
|
5699
6413
|
{
|
|
5700
6414
|
type: "number",
|
|
@@ -5714,9 +6428,9 @@ function NodeConfigPanel({
|
|
|
5714
6428
|
}
|
|
5715
6429
|
)
|
|
5716
6430
|
] }),
|
|
5717
|
-
/* @__PURE__ */
|
|
5718
|
-
/* @__PURE__ */
|
|
5719
|
-
/* @__PURE__ */
|
|
6431
|
+
/* @__PURE__ */ jsxs17("div", { children: [
|
|
6432
|
+
/* @__PURE__ */ jsx21("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Rotation (degrees):" }),
|
|
6433
|
+
/* @__PURE__ */ jsx21(
|
|
5720
6434
|
"input",
|
|
5721
6435
|
{
|
|
5722
6436
|
type: "number",
|
|
@@ -5741,9 +6455,9 @@ function NodeConfigPanel({
|
|
|
5741
6455
|
)
|
|
5742
6456
|
] })
|
|
5743
6457
|
] }),
|
|
5744
|
-
/* @__PURE__ */
|
|
5745
|
-
/* @__PURE__ */
|
|
5746
|
-
!binding ? /* @__PURE__ */
|
|
6458
|
+
/* @__PURE__ */ jsxs17("div", { style: { marginBottom: "20px" }, children: [
|
|
6459
|
+
/* @__PURE__ */ jsx21("h3", { style: { fontSize: "0.875rem", fontWeight: 600, marginBottom: "8px" }, children: "Telemetry Data" }),
|
|
6460
|
+
!binding ? /* @__PURE__ */ jsx21(
|
|
5747
6461
|
"button",
|
|
5748
6462
|
{
|
|
5749
6463
|
onClick: () => {
|
|
@@ -5786,9 +6500,9 @@ function NodeConfigPanel({
|
|
|
5786
6500
|
},
|
|
5787
6501
|
children: "+ Add Telemetry"
|
|
5788
6502
|
}
|
|
5789
|
-
) : /* @__PURE__ */
|
|
5790
|
-
/* @__PURE__ */
|
|
5791
|
-
/* @__PURE__ */
|
|
6503
|
+
) : /* @__PURE__ */ jsxs17(Fragment8, { children: [
|
|
6504
|
+
/* @__PURE__ */ jsx21("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Initial Value:" }),
|
|
6505
|
+
/* @__PURE__ */ jsx21(
|
|
5792
6506
|
"input",
|
|
5793
6507
|
{
|
|
5794
6508
|
type: "number",
|
|
@@ -5810,8 +6524,8 @@ function NodeConfigPanel({
|
|
|
5810
6524
|
}
|
|
5811
6525
|
}
|
|
5812
6526
|
),
|
|
5813
|
-
/* @__PURE__ */
|
|
5814
|
-
/* @__PURE__ */
|
|
6527
|
+
/* @__PURE__ */ jsx21("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Unit:" }),
|
|
6528
|
+
/* @__PURE__ */ jsx21(
|
|
5815
6529
|
"input",
|
|
5816
6530
|
{
|
|
5817
6531
|
type: "text",
|
|
@@ -5833,8 +6547,8 @@ function NodeConfigPanel({
|
|
|
5833
6547
|
}
|
|
5834
6548
|
}
|
|
5835
6549
|
),
|
|
5836
|
-
/* @__PURE__ */
|
|
5837
|
-
/* @__PURE__ */
|
|
6550
|
+
/* @__PURE__ */ jsxs17("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: [
|
|
6551
|
+
/* @__PURE__ */ jsx21(
|
|
5838
6552
|
"input",
|
|
5839
6553
|
{
|
|
5840
6554
|
type: "checkbox",
|
|
@@ -5856,8 +6570,8 @@ function NodeConfigPanel({
|
|
|
5856
6570
|
),
|
|
5857
6571
|
"Show Sparkline"
|
|
5858
6572
|
] }),
|
|
5859
|
-
/* @__PURE__ */
|
|
5860
|
-
/* @__PURE__ */
|
|
6573
|
+
/* @__PURE__ */ jsxs17("div", { style: { marginTop: "12px" }, children: [
|
|
6574
|
+
/* @__PURE__ */ jsx21(
|
|
5861
6575
|
"label",
|
|
5862
6576
|
{
|
|
5863
6577
|
style: {
|
|
@@ -5869,10 +6583,10 @@ function NodeConfigPanel({
|
|
|
5869
6583
|
children: "Telemetry Position Offset:"
|
|
5870
6584
|
}
|
|
5871
6585
|
),
|
|
5872
|
-
/* @__PURE__ */
|
|
5873
|
-
/* @__PURE__ */
|
|
5874
|
-
/* @__PURE__ */
|
|
5875
|
-
/* @__PURE__ */
|
|
6586
|
+
/* @__PURE__ */ jsxs17("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: "8px" }, children: [
|
|
6587
|
+
/* @__PURE__ */ jsxs17("div", { children: [
|
|
6588
|
+
/* @__PURE__ */ jsx21("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "X Offset:" }),
|
|
6589
|
+
/* @__PURE__ */ jsx21(
|
|
5876
6590
|
"input",
|
|
5877
6591
|
{
|
|
5878
6592
|
type: "number",
|
|
@@ -5899,9 +6613,9 @@ function NodeConfigPanel({
|
|
|
5899
6613
|
}
|
|
5900
6614
|
)
|
|
5901
6615
|
] }),
|
|
5902
|
-
/* @__PURE__ */
|
|
5903
|
-
/* @__PURE__ */
|
|
5904
|
-
/* @__PURE__ */
|
|
6616
|
+
/* @__PURE__ */ jsxs17("div", { children: [
|
|
6617
|
+
/* @__PURE__ */ jsx21("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "Y Offset:" }),
|
|
6618
|
+
/* @__PURE__ */ jsx21(
|
|
5905
6619
|
"input",
|
|
5906
6620
|
{
|
|
5907
6621
|
type: "number",
|
|
@@ -5929,8 +6643,8 @@ function NodeConfigPanel({
|
|
|
5929
6643
|
)
|
|
5930
6644
|
] })
|
|
5931
6645
|
] }),
|
|
5932
|
-
/* @__PURE__ */
|
|
5933
|
-
/* @__PURE__ */
|
|
6646
|
+
/* @__PURE__ */ jsxs17("div", { style: { marginTop: "16px" }, children: [
|
|
6647
|
+
/* @__PURE__ */ jsx21(
|
|
5934
6648
|
"label",
|
|
5935
6649
|
{
|
|
5936
6650
|
style: {
|
|
@@ -5942,10 +6656,10 @@ function NodeConfigPanel({
|
|
|
5942
6656
|
children: "Display Colors:"
|
|
5943
6657
|
}
|
|
5944
6658
|
),
|
|
5945
|
-
/* @__PURE__ */
|
|
5946
|
-
/* @__PURE__ */
|
|
5947
|
-
/* @__PURE__ */
|
|
5948
|
-
/* @__PURE__ */
|
|
6659
|
+
/* @__PURE__ */ jsxs17("div", { style: { marginBottom: "8px" }, children: [
|
|
6660
|
+
/* @__PURE__ */ jsx21("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "Text Color:" }),
|
|
6661
|
+
/* @__PURE__ */ jsxs17("div", { style: { display: "flex", gap: "8px", alignItems: "center" }, children: [
|
|
6662
|
+
/* @__PURE__ */ jsx21(
|
|
5949
6663
|
"input",
|
|
5950
6664
|
{
|
|
5951
6665
|
type: "color",
|
|
@@ -5971,7 +6685,7 @@ function NodeConfigPanel({
|
|
|
5971
6685
|
}
|
|
5972
6686
|
}
|
|
5973
6687
|
),
|
|
5974
|
-
/* @__PURE__ */
|
|
6688
|
+
/* @__PURE__ */ jsx21(
|
|
5975
6689
|
"input",
|
|
5976
6690
|
{
|
|
5977
6691
|
type: "text",
|
|
@@ -6001,10 +6715,10 @@ function NodeConfigPanel({
|
|
|
6001
6715
|
)
|
|
6002
6716
|
] })
|
|
6003
6717
|
] }),
|
|
6004
|
-
binding.display?.showSparkline && /* @__PURE__ */
|
|
6005
|
-
/* @__PURE__ */
|
|
6006
|
-
/* @__PURE__ */
|
|
6007
|
-
/* @__PURE__ */
|
|
6718
|
+
binding.display?.showSparkline && /* @__PURE__ */ jsxs17("div", { style: { marginBottom: "8px" }, children: [
|
|
6719
|
+
/* @__PURE__ */ jsx21("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "Sparkline Color:" }),
|
|
6720
|
+
/* @__PURE__ */ jsxs17("div", { style: { display: "flex", gap: "8px", alignItems: "center" }, children: [
|
|
6721
|
+
/* @__PURE__ */ jsx21(
|
|
6008
6722
|
"input",
|
|
6009
6723
|
{
|
|
6010
6724
|
type: "color",
|
|
@@ -6030,7 +6744,7 @@ function NodeConfigPanel({
|
|
|
6030
6744
|
}
|
|
6031
6745
|
}
|
|
6032
6746
|
),
|
|
6033
|
-
/* @__PURE__ */
|
|
6747
|
+
/* @__PURE__ */ jsx21(
|
|
6034
6748
|
"input",
|
|
6035
6749
|
{
|
|
6036
6750
|
type: "text",
|
|
@@ -6060,9 +6774,9 @@ function NodeConfigPanel({
|
|
|
6060
6774
|
)
|
|
6061
6775
|
] })
|
|
6062
6776
|
] }),
|
|
6063
|
-
/* @__PURE__ */
|
|
6064
|
-
/* @__PURE__ */
|
|
6065
|
-
/* @__PURE__ */
|
|
6777
|
+
/* @__PURE__ */ jsxs17("div", { style: { marginBottom: "8px" }, children: [
|
|
6778
|
+
/* @__PURE__ */ jsx21("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "Background:" }),
|
|
6779
|
+
/* @__PURE__ */ jsx21(
|
|
6066
6780
|
"input",
|
|
6067
6781
|
{
|
|
6068
6782
|
type: "text",
|
|
@@ -6090,20 +6804,20 @@ function NodeConfigPanel({
|
|
|
6090
6804
|
}
|
|
6091
6805
|
}
|
|
6092
6806
|
),
|
|
6093
|
-
/* @__PURE__ */
|
|
6807
|
+
/* @__PURE__ */ jsx21("div", { style: { fontSize: "0.65rem", color: "#6b7280", marginTop: "2px" }, children: "Use 'status' for status-based color or hex code" })
|
|
6094
6808
|
] })
|
|
6095
6809
|
] }),
|
|
6096
6810
|
" "
|
|
6097
6811
|
] })
|
|
6098
6812
|
] })
|
|
6099
6813
|
] }),
|
|
6100
|
-
binding && /* @__PURE__ */
|
|
6101
|
-
/* @__PURE__ */
|
|
6814
|
+
binding && /* @__PURE__ */ jsxs17("div", { style: { marginBottom: "20px" }, children: [
|
|
6815
|
+
/* @__PURE__ */ jsx21("h3", { style: { fontSize: "0.875rem", fontWeight: 600, marginBottom: "8px" }, children: "Thresholds" }),
|
|
6102
6816
|
["highHigh", "high", "low", "lowLow"].map((key) => {
|
|
6103
6817
|
const label = key === "highHigh" ? "High-High (\u2265)" : key === "high" ? "High (\u2265)" : key === "low" ? "Low (\u2264)" : "Low-Low (\u2264)";
|
|
6104
|
-
return /* @__PURE__ */
|
|
6105
|
-
/* @__PURE__ */
|
|
6106
|
-
/* @__PURE__ */
|
|
6818
|
+
return /* @__PURE__ */ jsxs17("div", { style: { marginBottom: "8px" }, children: [
|
|
6819
|
+
/* @__PURE__ */ jsx21("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: label }),
|
|
6820
|
+
/* @__PURE__ */ jsx21(
|
|
6107
6821
|
"input",
|
|
6108
6822
|
{
|
|
6109
6823
|
type: "number",
|
|
@@ -6127,8 +6841,8 @@ function NodeConfigPanel({
|
|
|
6127
6841
|
] }, key);
|
|
6128
6842
|
})
|
|
6129
6843
|
] }),
|
|
6130
|
-
binding && /* @__PURE__ */
|
|
6131
|
-
/* @__PURE__ */
|
|
6844
|
+
binding && /* @__PURE__ */ jsxs17("div", { style: { marginBottom: "20px" }, children: [
|
|
6845
|
+
/* @__PURE__ */ jsx21("h3", { style: { fontSize: "0.875rem", fontWeight: 600, marginBottom: "8px" }, children: "Status Colors" }),
|
|
6132
6846
|
["normal", "warning", "alarm", "fault", "off"].map((status) => {
|
|
6133
6847
|
const defaultColors = {
|
|
6134
6848
|
normal: "#10b981",
|
|
@@ -6138,13 +6852,13 @@ function NodeConfigPanel({
|
|
|
6138
6852
|
off: "#6b7280"
|
|
6139
6853
|
};
|
|
6140
6854
|
const label = status === "normal" ? "Normal" : status === "warning" ? "Warning" : status === "alarm" ? "Alarm" : status === "fault" ? "Fault" : "Off";
|
|
6141
|
-
return /* @__PURE__ */
|
|
6142
|
-
/* @__PURE__ */
|
|
6855
|
+
return /* @__PURE__ */ jsxs17("div", { style: { marginBottom: "8px" }, children: [
|
|
6856
|
+
/* @__PURE__ */ jsxs17("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: [
|
|
6143
6857
|
label,
|
|
6144
6858
|
":"
|
|
6145
6859
|
] }),
|
|
6146
|
-
/* @__PURE__ */
|
|
6147
|
-
/* @__PURE__ */
|
|
6860
|
+
/* @__PURE__ */ jsxs17("div", { style: { display: "flex", gap: "8px", alignItems: "center" }, children: [
|
|
6861
|
+
/* @__PURE__ */ jsx21(
|
|
6148
6862
|
"input",
|
|
6149
6863
|
{
|
|
6150
6864
|
type: "color",
|
|
@@ -6165,7 +6879,7 @@ function NodeConfigPanel({
|
|
|
6165
6879
|
}
|
|
6166
6880
|
}
|
|
6167
6881
|
),
|
|
6168
|
-
/* @__PURE__ */
|
|
6882
|
+
/* @__PURE__ */ jsx21(
|
|
6169
6883
|
"input",
|
|
6170
6884
|
{
|
|
6171
6885
|
type: "text",
|
|
@@ -6192,7 +6906,7 @@ function NodeConfigPanel({
|
|
|
6192
6906
|
] }, status);
|
|
6193
6907
|
})
|
|
6194
6908
|
] }),
|
|
6195
|
-
/* @__PURE__ */
|
|
6909
|
+
/* @__PURE__ */ jsx21("div", { style: { marginTop: "20px", paddingTop: "20px", borderTop: "1px solid #cbd5e1" }, children: /* @__PURE__ */ jsx21(
|
|
6196
6910
|
"button",
|
|
6197
6911
|
{
|
|
6198
6912
|
onClick: onRemove,
|
|
@@ -6431,8 +7145,280 @@ var DEFAULT_THRESHOLDS = {
|
|
|
6431
7145
|
lowLow: 15
|
|
6432
7146
|
};
|
|
6433
7147
|
|
|
7148
|
+
// src/diagram/schema/DeviceControlBinding.ts
|
|
7149
|
+
function createControlBinding(nodeId, deviceConfig, actions) {
|
|
7150
|
+
const parametersByMode = {};
|
|
7151
|
+
deviceConfig.parameters.forEach((param) => {
|
|
7152
|
+
const modes = param.modes || deviceConfig.modes.map((m) => m.value);
|
|
7153
|
+
modes.forEach((mode) => {
|
|
7154
|
+
if (!parametersByMode[mode]) {
|
|
7155
|
+
parametersByMode[mode] = [];
|
|
7156
|
+
}
|
|
7157
|
+
parametersByMode[mode].push({
|
|
7158
|
+
id: param.id,
|
|
7159
|
+
label: param.label,
|
|
7160
|
+
unit: param.unit,
|
|
7161
|
+
min: param.min,
|
|
7162
|
+
max: param.max,
|
|
7163
|
+
value: param.value,
|
|
7164
|
+
type: typeof param.value === "number" ? "number" : "string"
|
|
7165
|
+
});
|
|
7166
|
+
});
|
|
7167
|
+
});
|
|
7168
|
+
return {
|
|
7169
|
+
nodeId,
|
|
7170
|
+
tag: deviceConfig.tag,
|
|
7171
|
+
deviceName: deviceConfig.name,
|
|
7172
|
+
deviceType: deviceConfig.type,
|
|
7173
|
+
modes: deviceConfig.modes,
|
|
7174
|
+
state: {
|
|
7175
|
+
currentMode: deviceConfig.currentMode,
|
|
7176
|
+
isRunning: deviceConfig.isRunning,
|
|
7177
|
+
status: deviceConfig.status
|
|
7178
|
+
},
|
|
7179
|
+
parameters: parametersByMode,
|
|
7180
|
+
capabilities: deviceConfig.capabilities,
|
|
7181
|
+
actions
|
|
7182
|
+
};
|
|
7183
|
+
}
|
|
7184
|
+
|
|
7185
|
+
// src/hooks/useDeviceControls.ts
|
|
7186
|
+
import { useState as useState15, useCallback as useCallback8 } from "react";
|
|
7187
|
+
function useDeviceControls(initialBindings) {
|
|
7188
|
+
const [controls, setControls] = useState15(() => {
|
|
7189
|
+
const map = /* @__PURE__ */ new Map();
|
|
7190
|
+
if (initialBindings) {
|
|
7191
|
+
initialBindings.forEach((binding) => {
|
|
7192
|
+
map.set(binding.nodeId, binding);
|
|
7193
|
+
});
|
|
7194
|
+
}
|
|
7195
|
+
return map;
|
|
7196
|
+
});
|
|
7197
|
+
const updateControl = useCallback8((nodeId, updates) => {
|
|
7198
|
+
setControls((prev) => {
|
|
7199
|
+
const newMap = new Map(prev);
|
|
7200
|
+
const existing = newMap.get(nodeId);
|
|
7201
|
+
if (existing) {
|
|
7202
|
+
newMap.set(nodeId, { ...existing, ...updates });
|
|
7203
|
+
} else {
|
|
7204
|
+
if ("tag" in updates && "modes" in updates && "state" in updates && "parameters" in updates && "actions" in updates) {
|
|
7205
|
+
newMap.set(nodeId, { nodeId, ...updates });
|
|
7206
|
+
}
|
|
7207
|
+
}
|
|
7208
|
+
return newMap;
|
|
7209
|
+
});
|
|
7210
|
+
}, []);
|
|
7211
|
+
const updateControlBatch = useCallback8((updates) => {
|
|
7212
|
+
setControls((prev) => {
|
|
7213
|
+
const newMap = new Map(prev);
|
|
7214
|
+
Object.entries(updates).forEach(([nodeId, update]) => {
|
|
7215
|
+
const existing = newMap.get(nodeId);
|
|
7216
|
+
if (existing) {
|
|
7217
|
+
newMap.set(nodeId, { ...existing, ...update });
|
|
7218
|
+
}
|
|
7219
|
+
});
|
|
7220
|
+
return newMap;
|
|
7221
|
+
});
|
|
7222
|
+
}, []);
|
|
7223
|
+
const updateDeviceState = useCallback8(
|
|
7224
|
+
(nodeId, stateUpdates) => {
|
|
7225
|
+
setControls((prev) => {
|
|
7226
|
+
const newMap = new Map(prev);
|
|
7227
|
+
const existing = newMap.get(nodeId);
|
|
7228
|
+
if (existing) {
|
|
7229
|
+
newMap.set(nodeId, {
|
|
7230
|
+
...existing,
|
|
7231
|
+
state: { ...existing.state, ...stateUpdates }
|
|
7232
|
+
});
|
|
7233
|
+
}
|
|
7234
|
+
return newMap;
|
|
7235
|
+
});
|
|
7236
|
+
},
|
|
7237
|
+
[]
|
|
7238
|
+
);
|
|
7239
|
+
const updateParameter = useCallback8(
|
|
7240
|
+
(nodeId, parameterId, value) => {
|
|
7241
|
+
setControls((prev) => {
|
|
7242
|
+
const newMap = new Map(prev);
|
|
7243
|
+
const existing = newMap.get(nodeId);
|
|
7244
|
+
if (existing) {
|
|
7245
|
+
const updatedParameters = { ...existing.parameters };
|
|
7246
|
+
Object.keys(updatedParameters).forEach((mode) => {
|
|
7247
|
+
const paramIndex = updatedParameters[mode].findIndex((p) => p.id === parameterId);
|
|
7248
|
+
if (paramIndex !== -1) {
|
|
7249
|
+
updatedParameters[mode] = [...updatedParameters[mode]];
|
|
7250
|
+
updatedParameters[mode][paramIndex] = {
|
|
7251
|
+
...updatedParameters[mode][paramIndex],
|
|
7252
|
+
value
|
|
7253
|
+
};
|
|
7254
|
+
}
|
|
7255
|
+
});
|
|
7256
|
+
newMap.set(nodeId, {
|
|
7257
|
+
...existing,
|
|
7258
|
+
parameters: updatedParameters
|
|
7259
|
+
});
|
|
7260
|
+
}
|
|
7261
|
+
return newMap;
|
|
7262
|
+
});
|
|
7263
|
+
},
|
|
7264
|
+
[]
|
|
7265
|
+
);
|
|
7266
|
+
const setControlBinding = useCallback8((binding) => {
|
|
7267
|
+
setControls((prev) => {
|
|
7268
|
+
const newMap = new Map(prev);
|
|
7269
|
+
newMap.set(binding.nodeId, binding);
|
|
7270
|
+
return newMap;
|
|
7271
|
+
});
|
|
7272
|
+
}, []);
|
|
7273
|
+
const removeControlBinding = useCallback8((nodeId) => {
|
|
7274
|
+
setControls((prev) => {
|
|
7275
|
+
const newMap = new Map(prev);
|
|
7276
|
+
newMap.delete(nodeId);
|
|
7277
|
+
return newMap;
|
|
7278
|
+
});
|
|
7279
|
+
}, []);
|
|
7280
|
+
const getControlBinding = useCallback8(
|
|
7281
|
+
(nodeId) => {
|
|
7282
|
+
return controls.get(nodeId);
|
|
7283
|
+
},
|
|
7284
|
+
[controls]
|
|
7285
|
+
);
|
|
7286
|
+
const sendModeChange = useCallback8(
|
|
7287
|
+
async (nodeId, mode) => {
|
|
7288
|
+
const binding = controls.get(nodeId);
|
|
7289
|
+
if (!binding) return;
|
|
7290
|
+
updateDeviceState(nodeId, { currentMode: mode });
|
|
7291
|
+
try {
|
|
7292
|
+
await binding.actions.onModeChange?.(mode);
|
|
7293
|
+
updateDeviceState(nodeId, {
|
|
7294
|
+
lastCommandTime: Date.now(),
|
|
7295
|
+
lastCommandResult: { success: true, message: `Mode changed to ${mode}` }
|
|
7296
|
+
});
|
|
7297
|
+
} catch (error) {
|
|
7298
|
+
updateDeviceState(nodeId, {
|
|
7299
|
+
currentMode: binding.state.currentMode,
|
|
7300
|
+
lastCommandResult: {
|
|
7301
|
+
success: false,
|
|
7302
|
+
message: error instanceof Error ? error.message : "Mode change failed"
|
|
7303
|
+
}
|
|
7304
|
+
});
|
|
7305
|
+
}
|
|
7306
|
+
},
|
|
7307
|
+
[controls, updateDeviceState]
|
|
7308
|
+
);
|
|
7309
|
+
const sendParameterChange = useCallback8(
|
|
7310
|
+
async (nodeId, parameterId, value) => {
|
|
7311
|
+
const binding = controls.get(nodeId);
|
|
7312
|
+
if (!binding) return;
|
|
7313
|
+
updateParameter(nodeId, parameterId, value);
|
|
7314
|
+
try {
|
|
7315
|
+
await binding.actions.onParameterChange?.(parameterId, value);
|
|
7316
|
+
updateDeviceState(nodeId, {
|
|
7317
|
+
lastCommandTime: Date.now(),
|
|
7318
|
+
lastCommandResult: { success: true, message: `Parameter ${parameterId} updated` }
|
|
7319
|
+
});
|
|
7320
|
+
} catch (error) {
|
|
7321
|
+
updateDeviceState(nodeId, {
|
|
7322
|
+
lastCommandResult: {
|
|
7323
|
+
success: false,
|
|
7324
|
+
message: error instanceof Error ? error.message : "Parameter change failed"
|
|
7325
|
+
}
|
|
7326
|
+
});
|
|
7327
|
+
}
|
|
7328
|
+
},
|
|
7329
|
+
[controls, updateParameter, updateDeviceState]
|
|
7330
|
+
);
|
|
7331
|
+
const sendStartCommand = useCallback8(
|
|
7332
|
+
async (nodeId) => {
|
|
7333
|
+
const binding = controls.get(nodeId);
|
|
7334
|
+
if (!binding) return;
|
|
7335
|
+
updateDeviceState(nodeId, { isRunning: true, status: "starting" });
|
|
7336
|
+
try {
|
|
7337
|
+
await binding.actions.onStart?.();
|
|
7338
|
+
updateDeviceState(nodeId, {
|
|
7339
|
+
status: "normal",
|
|
7340
|
+
lastCommandTime: Date.now(),
|
|
7341
|
+
lastCommandResult: { success: true, message: "Device started" }
|
|
7342
|
+
});
|
|
7343
|
+
} catch (error) {
|
|
7344
|
+
updateDeviceState(nodeId, {
|
|
7345
|
+
isRunning: false,
|
|
7346
|
+
status: "fault",
|
|
7347
|
+
lastCommandResult: {
|
|
7348
|
+
success: false,
|
|
7349
|
+
message: error instanceof Error ? error.message : "Start failed"
|
|
7350
|
+
}
|
|
7351
|
+
});
|
|
7352
|
+
}
|
|
7353
|
+
},
|
|
7354
|
+
[controls, updateDeviceState]
|
|
7355
|
+
);
|
|
7356
|
+
const sendStopCommand = useCallback8(
|
|
7357
|
+
async (nodeId) => {
|
|
7358
|
+
const binding = controls.get(nodeId);
|
|
7359
|
+
if (!binding) return;
|
|
7360
|
+
updateDeviceState(nodeId, { isRunning: false, status: "stopping" });
|
|
7361
|
+
try {
|
|
7362
|
+
await binding.actions.onStop?.();
|
|
7363
|
+
updateDeviceState(nodeId, {
|
|
7364
|
+
status: "off",
|
|
7365
|
+
lastCommandTime: Date.now(),
|
|
7366
|
+
lastCommandResult: { success: true, message: "Device stopped" }
|
|
7367
|
+
});
|
|
7368
|
+
} catch (error) {
|
|
7369
|
+
updateDeviceState(nodeId, {
|
|
7370
|
+
isRunning: true,
|
|
7371
|
+
status: "fault",
|
|
7372
|
+
lastCommandResult: {
|
|
7373
|
+
success: false,
|
|
7374
|
+
message: error instanceof Error ? error.message : "Stop failed"
|
|
7375
|
+
}
|
|
7376
|
+
});
|
|
7377
|
+
}
|
|
7378
|
+
},
|
|
7379
|
+
[controls, updateDeviceState]
|
|
7380
|
+
);
|
|
7381
|
+
const sendCustomAction = useCallback8(
|
|
7382
|
+
async (nodeId, actionId) => {
|
|
7383
|
+
const binding = controls.get(nodeId);
|
|
7384
|
+
if (!binding) return;
|
|
7385
|
+
try {
|
|
7386
|
+
await binding.actions.onCustomAction?.(actionId);
|
|
7387
|
+
updateDeviceState(nodeId, {
|
|
7388
|
+
lastCommandTime: Date.now(),
|
|
7389
|
+
lastCommandResult: { success: true, message: `Action ${actionId} executed` }
|
|
7390
|
+
});
|
|
7391
|
+
} catch (error) {
|
|
7392
|
+
updateDeviceState(nodeId, {
|
|
7393
|
+
lastCommandResult: {
|
|
7394
|
+
success: false,
|
|
7395
|
+
message: error instanceof Error ? error.message : "Action failed"
|
|
7396
|
+
}
|
|
7397
|
+
});
|
|
7398
|
+
}
|
|
7399
|
+
},
|
|
7400
|
+
[controls, updateDeviceState]
|
|
7401
|
+
);
|
|
7402
|
+
return {
|
|
7403
|
+
controls,
|
|
7404
|
+
updateControl,
|
|
7405
|
+
updateControlBatch,
|
|
7406
|
+
updateDeviceState,
|
|
7407
|
+
updateParameter,
|
|
7408
|
+
setControlBinding,
|
|
7409
|
+
removeControlBinding,
|
|
7410
|
+
getControlBinding,
|
|
7411
|
+
// Command helpers
|
|
7412
|
+
sendModeChange,
|
|
7413
|
+
sendParameterChange,
|
|
7414
|
+
sendStartCommand,
|
|
7415
|
+
sendStopCommand,
|
|
7416
|
+
sendCustomAction
|
|
7417
|
+
};
|
|
7418
|
+
}
|
|
7419
|
+
|
|
6434
7420
|
// src/diagram/hooks/useSimulation.ts
|
|
6435
|
-
import { useEffect as
|
|
7421
|
+
import { useEffect as useEffect12 } from "react";
|
|
6436
7422
|
function useSimulation(telemetry, updateTelemetryBatch, options = {}) {
|
|
6437
7423
|
const {
|
|
6438
7424
|
interval = 2e3,
|
|
@@ -6443,7 +7429,7 @@ function useSimulation(telemetry, updateTelemetryBatch, options = {}) {
|
|
|
6443
7429
|
historyLength = 10,
|
|
6444
7430
|
generateValue
|
|
6445
7431
|
} = options;
|
|
6446
|
-
|
|
7432
|
+
useEffect12(() => {
|
|
6447
7433
|
if (!enabled) return;
|
|
6448
7434
|
const intervalId = setInterval(() => {
|
|
6449
7435
|
const updates = [];
|
|
@@ -6500,6 +7486,7 @@ export {
|
|
|
6500
7486
|
ControlPanel,
|
|
6501
7487
|
DEFAULT_THRESHOLDS,
|
|
6502
7488
|
DashboardCard,
|
|
7489
|
+
DeviceControlPanel,
|
|
6503
7490
|
DisplayModeToggle,
|
|
6504
7491
|
EquipmentIndicator,
|
|
6505
7492
|
EquipmentIndicatorWithSparkline,
|
|
@@ -6511,6 +7498,7 @@ export {
|
|
|
6511
7498
|
LeftToggleButton,
|
|
6512
7499
|
LegacyValueEntry,
|
|
6513
7500
|
NodeConfigPanel,
|
|
7501
|
+
NodeControlsPanel,
|
|
6514
7502
|
PIDCanvas,
|
|
6515
7503
|
PanelContent,
|
|
6516
7504
|
PanelTabs,
|
|
@@ -6530,6 +7518,7 @@ export {
|
|
|
6530
7518
|
ZoomButton,
|
|
6531
7519
|
ZoomControls,
|
|
6532
7520
|
calculateThresholdStatus,
|
|
7521
|
+
createControlBinding,
|
|
6533
7522
|
exampleDiagram,
|
|
6534
7523
|
exportDiagram,
|
|
6535
7524
|
generateRoutePoints,
|
|
@@ -6542,6 +7531,7 @@ export {
|
|
|
6542
7531
|
overlayStyles,
|
|
6543
7532
|
registerSymbol,
|
|
6544
7533
|
registerSymbols,
|
|
7534
|
+
useDeviceControls,
|
|
6545
7535
|
useDrag,
|
|
6546
7536
|
useKeyboardShortcuts,
|
|
6547
7537
|
useSelection,
|