@procaaso/alphinity-ui-components 1.3.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +878 -402
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +59 -2
- package/dist/index.d.ts +59 -2
- package/dist/index.js +873 -398
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -935,6 +935,7 @@ function DeviceControlPanel({
|
|
|
935
935
|
toastDuration = 3e3,
|
|
936
936
|
onModeChange,
|
|
937
937
|
onParameterChange,
|
|
938
|
+
onParameterActivate,
|
|
938
939
|
onStart,
|
|
939
940
|
onStop,
|
|
940
941
|
startPending = false,
|
|
@@ -1647,6 +1648,36 @@ function DeviceControlPanel({
|
|
|
1647
1648
|
},
|
|
1648
1649
|
children: param.options?.map((opt) => /* @__PURE__ */ jsx8("option", { value: opt.value, children: opt.label }, opt.value))
|
|
1649
1650
|
}
|
|
1651
|
+
) : onParameterActivate && !param.readOnly ? (
|
|
1652
|
+
// Tappable value: defer editing to the consumer's editor (e.g. a
|
|
1653
|
+
// numpad dialog). Commit happens via onParameterChange.
|
|
1654
|
+
/* @__PURE__ */ jsxs7(
|
|
1655
|
+
"button",
|
|
1656
|
+
{
|
|
1657
|
+
type: "button",
|
|
1658
|
+
onClick: () => onParameterActivate(param.id, localParameterValues[param.id] ?? param.value),
|
|
1659
|
+
style: {
|
|
1660
|
+
width: "100%",
|
|
1661
|
+
height: touchSize,
|
|
1662
|
+
display: "flex",
|
|
1663
|
+
alignItems: "center",
|
|
1664
|
+
backgroundColor: "#ffffff",
|
|
1665
|
+
color: textColor,
|
|
1666
|
+
border: `1px solid ${borderColor}`,
|
|
1667
|
+
borderRadius: "6px",
|
|
1668
|
+
padding: "0 12px",
|
|
1669
|
+
fontSize: `${fontSize.input}px`,
|
|
1670
|
+
fontFamily: "Arial, sans-serif",
|
|
1671
|
+
fontWeight: 600,
|
|
1672
|
+
textAlign: "left",
|
|
1673
|
+
cursor: "pointer"
|
|
1674
|
+
},
|
|
1675
|
+
children: [
|
|
1676
|
+
localParameterValues[param.id] ?? param.value,
|
|
1677
|
+
param.unit ? ` ${param.unit}` : ""
|
|
1678
|
+
]
|
|
1679
|
+
}
|
|
1680
|
+
)
|
|
1650
1681
|
) : /* @__PURE__ */ jsx8(
|
|
1651
1682
|
"input",
|
|
1652
1683
|
{
|
|
@@ -1809,14 +1840,457 @@ function DeviceControlPanel({
|
|
|
1809
1840
|
] });
|
|
1810
1841
|
}
|
|
1811
1842
|
|
|
1843
|
+
// src/components/NumpadDialog/NumpadDialog.tsx
|
|
1844
|
+
import { useState as useState6, useEffect as useEffect3, useCallback as useCallback3, useRef as useRef2, useId } from "react";
|
|
1845
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1846
|
+
var NumpadDialog = ({
|
|
1847
|
+
isOpen,
|
|
1848
|
+
onClose,
|
|
1849
|
+
onApply,
|
|
1850
|
+
deviceName = "",
|
|
1851
|
+
parameterLabel = "Setpoint",
|
|
1852
|
+
unit = "",
|
|
1853
|
+
min = 0,
|
|
1854
|
+
max = 100,
|
|
1855
|
+
precision,
|
|
1856
|
+
currentValue = 0,
|
|
1857
|
+
touchOptimized = true
|
|
1858
|
+
}) => {
|
|
1859
|
+
const [inputValue, setInputValue] = useState6("");
|
|
1860
|
+
const [pristine, setPristine] = useState6(true);
|
|
1861
|
+
const dialogRef = useRef2(null);
|
|
1862
|
+
const titleId = useId();
|
|
1863
|
+
const decimals = precision ?? 1;
|
|
1864
|
+
useEffect3(() => {
|
|
1865
|
+
if (isOpen) {
|
|
1866
|
+
setInputValue(Number(currentValue).toFixed(decimals));
|
|
1867
|
+
setPristine(true);
|
|
1868
|
+
}
|
|
1869
|
+
}, [isOpen, currentValue, decimals]);
|
|
1870
|
+
useEffect3(() => {
|
|
1871
|
+
if (!isOpen) return;
|
|
1872
|
+
const previouslyFocused = document.activeElement;
|
|
1873
|
+
dialogRef.current?.focus();
|
|
1874
|
+
return () => previouslyFocused?.focus?.();
|
|
1875
|
+
}, [isOpen]);
|
|
1876
|
+
useEffect3(() => {
|
|
1877
|
+
if (!isOpen) return;
|
|
1878
|
+
const prevOverflow = document.body.style.overflow;
|
|
1879
|
+
document.body.style.overflow = "hidden";
|
|
1880
|
+
return () => {
|
|
1881
|
+
document.body.style.overflow = prevOverflow;
|
|
1882
|
+
};
|
|
1883
|
+
}, [isOpen]);
|
|
1884
|
+
const handleApply = useCallback3(() => {
|
|
1885
|
+
const n = Number(inputValue);
|
|
1886
|
+
if (inputValue === "" || inputValue === "-" || inputValue === "." || inputValue === "-.") return;
|
|
1887
|
+
if (isNaN(n) || n < min || n > max) return;
|
|
1888
|
+
onApply(Number(n.toFixed(decimals)));
|
|
1889
|
+
}, [inputValue, min, max, onApply, decimals]);
|
|
1890
|
+
const appendDigit = useCallback3(
|
|
1891
|
+
(digit) => {
|
|
1892
|
+
setInputValue((prev) => {
|
|
1893
|
+
const base = pristine ? "" : prev;
|
|
1894
|
+
if (digit === ".") {
|
|
1895
|
+
if (decimals === 0) return base;
|
|
1896
|
+
if (base.includes(".")) return base;
|
|
1897
|
+
if (base === "" || base === "-") return base + "0.";
|
|
1898
|
+
return base + ".";
|
|
1899
|
+
}
|
|
1900
|
+
const dot = base.indexOf(".");
|
|
1901
|
+
if (dot !== -1 && base.length - dot - 1 >= decimals) return base;
|
|
1902
|
+
if (base === "0") return digit;
|
|
1903
|
+
if (base === "-0") return "-" + digit;
|
|
1904
|
+
return base + digit;
|
|
1905
|
+
});
|
|
1906
|
+
if (pristine) setPristine(false);
|
|
1907
|
+
},
|
|
1908
|
+
[pristine, decimals]
|
|
1909
|
+
);
|
|
1910
|
+
const handleBackspace = useCallback3(() => {
|
|
1911
|
+
setPristine(false);
|
|
1912
|
+
setInputValue((prev) => prev.slice(0, -1));
|
|
1913
|
+
}, []);
|
|
1914
|
+
const handleClear = useCallback3(() => {
|
|
1915
|
+
setPristine(false);
|
|
1916
|
+
setInputValue("");
|
|
1917
|
+
}, []);
|
|
1918
|
+
const handleToggleSign = useCallback3(() => {
|
|
1919
|
+
if (min >= 0) return;
|
|
1920
|
+
setPristine(false);
|
|
1921
|
+
setInputValue((prev) => {
|
|
1922
|
+
if (prev.startsWith("-")) return prev.slice(1);
|
|
1923
|
+
if (prev === "" || prev === "0") return "-";
|
|
1924
|
+
return "-" + prev;
|
|
1925
|
+
});
|
|
1926
|
+
}, [min]);
|
|
1927
|
+
const bsTimer = useRef2(null);
|
|
1928
|
+
const bsLongFired = useRef2(false);
|
|
1929
|
+
const clearBsTimer = () => {
|
|
1930
|
+
if (bsTimer.current !== null) {
|
|
1931
|
+
clearTimeout(bsTimer.current);
|
|
1932
|
+
bsTimer.current = null;
|
|
1933
|
+
}
|
|
1934
|
+
};
|
|
1935
|
+
const handleBackspacePointerDown = () => {
|
|
1936
|
+
bsLongFired.current = false;
|
|
1937
|
+
bsTimer.current = window.setTimeout(() => {
|
|
1938
|
+
bsLongFired.current = true;
|
|
1939
|
+
handleClear();
|
|
1940
|
+
}, 500);
|
|
1941
|
+
};
|
|
1942
|
+
const handleBackspaceClick = () => {
|
|
1943
|
+
clearBsTimer();
|
|
1944
|
+
if (bsLongFired.current) {
|
|
1945
|
+
bsLongFired.current = false;
|
|
1946
|
+
return;
|
|
1947
|
+
}
|
|
1948
|
+
handleBackspace();
|
|
1949
|
+
};
|
|
1950
|
+
useEffect3(() => () => clearBsTimer(), []);
|
|
1951
|
+
useEffect3(() => {
|
|
1952
|
+
if (!isOpen) return;
|
|
1953
|
+
const handler = (e) => {
|
|
1954
|
+
if (e.key === "Tab") {
|
|
1955
|
+
const root = dialogRef.current;
|
|
1956
|
+
if (!root) return;
|
|
1957
|
+
const focusable = Array.from(
|
|
1958
|
+
root.querySelectorAll("button:not([disabled])")
|
|
1959
|
+
).filter((el) => el.tabIndex !== -1);
|
|
1960
|
+
if (focusable.length === 0) {
|
|
1961
|
+
e.preventDefault();
|
|
1962
|
+
root.focus();
|
|
1963
|
+
return;
|
|
1964
|
+
}
|
|
1965
|
+
const first = focusable[0];
|
|
1966
|
+
const last = focusable[focusable.length - 1];
|
|
1967
|
+
const active = document.activeElement;
|
|
1968
|
+
if (e.shiftKey) {
|
|
1969
|
+
if (active === first || !root.contains(active)) {
|
|
1970
|
+
e.preventDefault();
|
|
1971
|
+
last.focus();
|
|
1972
|
+
}
|
|
1973
|
+
} else if (active === last || !root.contains(active)) {
|
|
1974
|
+
e.preventDefault();
|
|
1975
|
+
first.focus();
|
|
1976
|
+
}
|
|
1977
|
+
return;
|
|
1978
|
+
}
|
|
1979
|
+
if (e.key === "Enter") {
|
|
1980
|
+
const active = document.activeElement;
|
|
1981
|
+
if (active && active.tagName === "BUTTON" && dialogRef.current?.contains(active)) return;
|
|
1982
|
+
e.preventDefault();
|
|
1983
|
+
handleApply();
|
|
1984
|
+
} else if (e.key === "Escape") {
|
|
1985
|
+
e.preventDefault();
|
|
1986
|
+
onClose();
|
|
1987
|
+
} else if (e.key === "Backspace") {
|
|
1988
|
+
e.preventDefault();
|
|
1989
|
+
handleBackspace();
|
|
1990
|
+
} else if (/^[0-9]$/.test(e.key)) {
|
|
1991
|
+
e.preventDefault();
|
|
1992
|
+
appendDigit(e.key);
|
|
1993
|
+
} else if (e.key === ".") {
|
|
1994
|
+
e.preventDefault();
|
|
1995
|
+
appendDigit(".");
|
|
1996
|
+
} else if (e.key === "-") {
|
|
1997
|
+
e.preventDefault();
|
|
1998
|
+
handleToggleSign();
|
|
1999
|
+
}
|
|
2000
|
+
};
|
|
2001
|
+
window.addEventListener("keydown", handler);
|
|
2002
|
+
return () => window.removeEventListener("keydown", handler);
|
|
2003
|
+
}, [isOpen, handleApply, onClose, handleBackspace, appendDigit, handleToggleSign]);
|
|
2004
|
+
if (!isOpen) return null;
|
|
2005
|
+
const parsed = Number(inputValue);
|
|
2006
|
+
const hasNumber = inputValue !== "" && inputValue !== "-" && inputValue !== "." && inputValue !== "-." && !isNaN(parsed);
|
|
2007
|
+
const belowMin = hasNumber && parsed < min;
|
|
2008
|
+
const aboveMax = hasNumber && parsed > max;
|
|
2009
|
+
const outOfRange = belowMin || aboveMax;
|
|
2010
|
+
const isValid = hasNumber && !outOfRange;
|
|
2011
|
+
const alarmColor = "#dc2626";
|
|
2012
|
+
const limitStyle = (violated) => violated ? { color: alarmColor, fontWeight: 700, background: "#fee2e2", borderRadius: 3, padding: "0 3px" } : {};
|
|
2013
|
+
const keySize = touchOptimized ? 60 : 46;
|
|
2014
|
+
const keyFont = touchOptimized ? 22 : 18;
|
|
2015
|
+
const actionSize = touchOptimized ? 52 : 42;
|
|
2016
|
+
const keyStyle = {
|
|
2017
|
+
minWidth: 52,
|
|
2018
|
+
minHeight: keySize,
|
|
2019
|
+
fontSize: keyFont,
|
|
2020
|
+
fontWeight: 600,
|
|
2021
|
+
borderRadius: 8,
|
|
2022
|
+
border: "1px solid #e2e8f0",
|
|
2023
|
+
background: "#ffffff",
|
|
2024
|
+
color: "#0f172a",
|
|
2025
|
+
cursor: "pointer",
|
|
2026
|
+
display: "flex",
|
|
2027
|
+
alignItems: "center",
|
|
2028
|
+
justifyContent: "center",
|
|
2029
|
+
userSelect: "none",
|
|
2030
|
+
boxShadow: "0 1px 2px rgba(15, 23, 42, 0.06)"
|
|
2031
|
+
};
|
|
2032
|
+
const utilKeyStyle = {
|
|
2033
|
+
flex: 1,
|
|
2034
|
+
minHeight: touchOptimized ? 44 : 38,
|
|
2035
|
+
fontSize: 13,
|
|
2036
|
+
fontWeight: 600,
|
|
2037
|
+
borderRadius: 8,
|
|
2038
|
+
border: "1px solid #e2e8f0",
|
|
2039
|
+
background: "#f8fafc",
|
|
2040
|
+
color: "#64748b",
|
|
2041
|
+
cursor: "pointer",
|
|
2042
|
+
display: "flex",
|
|
2043
|
+
alignItems: "center",
|
|
2044
|
+
justifyContent: "center",
|
|
2045
|
+
userSelect: "none"
|
|
2046
|
+
};
|
|
2047
|
+
const reason = belowMin ? `Below minimum of ${min} ${unit}` : aboveMax ? `Above maximum of ${max} ${unit}` : "Type or tap to change the value";
|
|
2048
|
+
const backspaceInGrid = min >= 0;
|
|
2049
|
+
const BackspaceButton = ({ style, label }) => /* @__PURE__ */ jsx9(
|
|
2050
|
+
"button",
|
|
2051
|
+
{
|
|
2052
|
+
type: "button",
|
|
2053
|
+
className: "np-key",
|
|
2054
|
+
tabIndex: -1,
|
|
2055
|
+
"aria-label": "Backspace",
|
|
2056
|
+
style,
|
|
2057
|
+
onPointerDown: handleBackspacePointerDown,
|
|
2058
|
+
onPointerUp: clearBsTimer,
|
|
2059
|
+
onPointerLeave: clearBsTimer,
|
|
2060
|
+
onClick: handleBackspaceClick,
|
|
2061
|
+
children: label
|
|
2062
|
+
}
|
|
2063
|
+
);
|
|
2064
|
+
return (
|
|
2065
|
+
// Backdrop
|
|
2066
|
+
/* @__PURE__ */ jsxs8(
|
|
2067
|
+
"div",
|
|
2068
|
+
{
|
|
2069
|
+
style: {
|
|
2070
|
+
position: "fixed",
|
|
2071
|
+
top: 0,
|
|
2072
|
+
left: 0,
|
|
2073
|
+
right: 0,
|
|
2074
|
+
bottom: 0,
|
|
2075
|
+
backgroundColor: "rgba(15, 23, 42, 0.4)",
|
|
2076
|
+
zIndex: 1e4,
|
|
2077
|
+
display: "flex",
|
|
2078
|
+
alignItems: "center",
|
|
2079
|
+
justifyContent: "center"
|
|
2080
|
+
},
|
|
2081
|
+
onClick: onClose,
|
|
2082
|
+
children: [
|
|
2083
|
+
/* @__PURE__ */ jsx9("style", { children: `
|
|
2084
|
+
.np-key { transition: background .1s, transform .05s; touch-action: manipulation; }
|
|
2085
|
+
.np-key:active:not(:disabled) { background:#e2e8f0; transform: translateY(1px); }
|
|
2086
|
+
.np-key:focus-visible, .np-action:focus-visible { outline: 3px solid #2563eb; outline-offset: 2px; }
|
|
2087
|
+
@keyframes np-blink { 0%,49%{opacity:1} 50%,100%{opacity:0} }
|
|
2088
|
+
.np-caret { display:inline-block; width:2px; height:1.1em; background:#2563eb; animation: np-blink 1s step-end infinite; }
|
|
2089
|
+
` }),
|
|
2090
|
+
/* @__PURE__ */ jsxs8(
|
|
2091
|
+
"div",
|
|
2092
|
+
{
|
|
2093
|
+
ref: dialogRef,
|
|
2094
|
+
role: "dialog",
|
|
2095
|
+
"aria-modal": "true",
|
|
2096
|
+
"aria-labelledby": titleId,
|
|
2097
|
+
tabIndex: -1,
|
|
2098
|
+
style: {
|
|
2099
|
+
width: touchOptimized ? "340px" : "300px",
|
|
2100
|
+
maxHeight: "90vh",
|
|
2101
|
+
overflow: "auto",
|
|
2102
|
+
background: "#ffffff",
|
|
2103
|
+
borderRadius: 12,
|
|
2104
|
+
border: "1px solid #e2e8f0",
|
|
2105
|
+
boxShadow: "0 10px 40px rgba(15, 23, 42, 0.2)",
|
|
2106
|
+
fontFamily: "'Inter', system-ui, sans-serif",
|
|
2107
|
+
outline: "none"
|
|
2108
|
+
},
|
|
2109
|
+
onClick: (e) => e.stopPropagation(),
|
|
2110
|
+
children: [
|
|
2111
|
+
/* @__PURE__ */ jsx9("div", { style: { padding: "14px 16px 0 16px" }, children: /* @__PURE__ */ jsx9("h3", { id: titleId, style: { margin: 0, fontSize: 15, fontWeight: 700, color: "#0f172a" }, children: deviceName ? `${deviceName} - ${parameterLabel}` : parameterLabel }) }),
|
|
2112
|
+
/* @__PURE__ */ jsxs8("div", { style: { padding: 16, display: "flex", flexDirection: "column", gap: 10 }, children: [
|
|
2113
|
+
/* @__PURE__ */ jsxs8(
|
|
2114
|
+
"div",
|
|
2115
|
+
{
|
|
2116
|
+
style: {
|
|
2117
|
+
display: "flex",
|
|
2118
|
+
justifyContent: "space-between",
|
|
2119
|
+
fontSize: 12,
|
|
2120
|
+
color: "#64748b"
|
|
2121
|
+
},
|
|
2122
|
+
children: [
|
|
2123
|
+
/* @__PURE__ */ jsxs8("span", { children: [
|
|
2124
|
+
"Current: ",
|
|
2125
|
+
currentValue,
|
|
2126
|
+
" ",
|
|
2127
|
+
unit
|
|
2128
|
+
] }),
|
|
2129
|
+
/* @__PURE__ */ jsxs8("span", { children: [
|
|
2130
|
+
"Range: ",
|
|
2131
|
+
/* @__PURE__ */ jsx9("span", { style: limitStyle(belowMin), children: min }),
|
|
2132
|
+
"-",
|
|
2133
|
+
/* @__PURE__ */ jsx9("span", { style: limitStyle(aboveMax), children: max }),
|
|
2134
|
+
" ",
|
|
2135
|
+
unit
|
|
2136
|
+
] })
|
|
2137
|
+
]
|
|
2138
|
+
}
|
|
2139
|
+
),
|
|
2140
|
+
/* @__PURE__ */ jsxs8(
|
|
2141
|
+
"div",
|
|
2142
|
+
{
|
|
2143
|
+
"aria-live": "polite",
|
|
2144
|
+
"aria-atomic": "true",
|
|
2145
|
+
"aria-label": `Entered value ${inputValue || "0"} ${unit}`,
|
|
2146
|
+
style: {
|
|
2147
|
+
background: outOfRange ? "#fef2f2" : "#f8fafc",
|
|
2148
|
+
borderRadius: 8,
|
|
2149
|
+
padding: "10px 14px",
|
|
2150
|
+
fontSize: 28,
|
|
2151
|
+
fontWeight: 700,
|
|
2152
|
+
textAlign: "right",
|
|
2153
|
+
color: outOfRange ? alarmColor : "#0f172a",
|
|
2154
|
+
minHeight: 48,
|
|
2155
|
+
display: "flex",
|
|
2156
|
+
alignItems: "center",
|
|
2157
|
+
justifyContent: "flex-end",
|
|
2158
|
+
gap: 6,
|
|
2159
|
+
border: outOfRange ? "1.5px solid #fca5a5" : "1.5px solid #e2e8f0"
|
|
2160
|
+
},
|
|
2161
|
+
children: [
|
|
2162
|
+
/* @__PURE__ */ jsx9("span", { children: inputValue || "0" }),
|
|
2163
|
+
/* @__PURE__ */ jsx9("span", { className: "np-caret", "aria-hidden": "true" }),
|
|
2164
|
+
/* @__PURE__ */ jsx9("span", { style: { fontSize: 14, color: "#94a3b8", fontWeight: 500 }, children: unit })
|
|
2165
|
+
]
|
|
2166
|
+
}
|
|
2167
|
+
),
|
|
2168
|
+
/* @__PURE__ */ jsx9(
|
|
2169
|
+
"div",
|
|
2170
|
+
{
|
|
2171
|
+
role: "status",
|
|
2172
|
+
"aria-live": "polite",
|
|
2173
|
+
style: {
|
|
2174
|
+
fontSize: 12,
|
|
2175
|
+
color: outOfRange ? alarmColor : "#94a3b8",
|
|
2176
|
+
fontWeight: outOfRange ? 600 : 400,
|
|
2177
|
+
textAlign: "right",
|
|
2178
|
+
minHeight: 16
|
|
2179
|
+
},
|
|
2180
|
+
children: reason
|
|
2181
|
+
}
|
|
2182
|
+
),
|
|
2183
|
+
/* @__PURE__ */ jsxs8("div", { style: { display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 5 }, children: [
|
|
2184
|
+
["7", "8", "9", "4", "5", "6", "1", "2", "3"].map((digit) => /* @__PURE__ */ jsx9(
|
|
2185
|
+
"button",
|
|
2186
|
+
{
|
|
2187
|
+
type: "button",
|
|
2188
|
+
className: "np-key",
|
|
2189
|
+
tabIndex: -1,
|
|
2190
|
+
style: keyStyle,
|
|
2191
|
+
onClick: () => appendDigit(digit),
|
|
2192
|
+
children: digit
|
|
2193
|
+
},
|
|
2194
|
+
digit
|
|
2195
|
+
)),
|
|
2196
|
+
min < 0 ? /* @__PURE__ */ jsx9(
|
|
2197
|
+
"button",
|
|
2198
|
+
{
|
|
2199
|
+
type: "button",
|
|
2200
|
+
className: "np-key",
|
|
2201
|
+
tabIndex: -1,
|
|
2202
|
+
"aria-label": "Toggle sign",
|
|
2203
|
+
style: { ...keyStyle, fontSize: 16, background: "#f8fafc", color: "#64748b" },
|
|
2204
|
+
onClick: handleToggleSign,
|
|
2205
|
+
children: "+/\u2212"
|
|
2206
|
+
}
|
|
2207
|
+
) : /* @__PURE__ */ jsx9(BackspaceButton, { style: { ...keyStyle, fontSize: 20, background: "#f8fafc", color: "#64748b" }, label: "\u232B" }),
|
|
2208
|
+
/* @__PURE__ */ jsx9("button", { type: "button", className: "np-key", tabIndex: -1, style: keyStyle, onClick: () => appendDigit("0"), children: "0" }),
|
|
2209
|
+
/* @__PURE__ */ jsx9(
|
|
2210
|
+
"button",
|
|
2211
|
+
{
|
|
2212
|
+
type: "button",
|
|
2213
|
+
className: "np-key",
|
|
2214
|
+
tabIndex: -1,
|
|
2215
|
+
"aria-label": "Decimal point",
|
|
2216
|
+
style: {
|
|
2217
|
+
...keyStyle,
|
|
2218
|
+
cursor: decimals === 0 ? "not-allowed" : "pointer",
|
|
2219
|
+
opacity: decimals === 0 ? 0.4 : 1
|
|
2220
|
+
},
|
|
2221
|
+
disabled: decimals === 0,
|
|
2222
|
+
onClick: () => appendDigit("."),
|
|
2223
|
+
children: "."
|
|
2224
|
+
}
|
|
2225
|
+
)
|
|
2226
|
+
] }),
|
|
2227
|
+
/* @__PURE__ */ jsxs8("div", { style: { display: "flex", gap: 5 }, children: [
|
|
2228
|
+
/* @__PURE__ */ jsx9("button", { type: "button", className: "np-key", tabIndex: -1, style: utilKeyStyle, onClick: handleClear, children: "Clear" }),
|
|
2229
|
+
!backspaceInGrid && /* @__PURE__ */ jsx9(BackspaceButton, { style: utilKeyStyle, label: "Backspace" })
|
|
2230
|
+
] }),
|
|
2231
|
+
/* @__PURE__ */ jsxs8("div", { style: { display: "flex", gap: 8, marginTop: 2 }, children: [
|
|
2232
|
+
/* @__PURE__ */ jsx9(
|
|
2233
|
+
"button",
|
|
2234
|
+
{
|
|
2235
|
+
type: "button",
|
|
2236
|
+
className: "np-action",
|
|
2237
|
+
onClick: onClose,
|
|
2238
|
+
style: {
|
|
2239
|
+
flex: 1,
|
|
2240
|
+
minHeight: actionSize,
|
|
2241
|
+
borderRadius: 8,
|
|
2242
|
+
border: "1px solid #e2e8f0",
|
|
2243
|
+
background: "#ffffff",
|
|
2244
|
+
color: "#0f172a",
|
|
2245
|
+
fontSize: 14,
|
|
2246
|
+
fontWeight: 600,
|
|
2247
|
+
cursor: "pointer"
|
|
2248
|
+
},
|
|
2249
|
+
children: "Cancel"
|
|
2250
|
+
}
|
|
2251
|
+
),
|
|
2252
|
+
/* @__PURE__ */ jsx9(
|
|
2253
|
+
"button",
|
|
2254
|
+
{
|
|
2255
|
+
type: "button",
|
|
2256
|
+
className: "np-action",
|
|
2257
|
+
onClick: handleApply,
|
|
2258
|
+
disabled: !isValid,
|
|
2259
|
+
"aria-label": isValid ? `Apply ${inputValue} ${unit}` : "Apply (enter a valid value)",
|
|
2260
|
+
style: {
|
|
2261
|
+
flex: 1,
|
|
2262
|
+
minHeight: actionSize,
|
|
2263
|
+
borderRadius: 8,
|
|
2264
|
+
border: "none",
|
|
2265
|
+
background: "#2563eb",
|
|
2266
|
+
color: "#ffffff",
|
|
2267
|
+
fontSize: 14,
|
|
2268
|
+
fontWeight: 600,
|
|
2269
|
+
cursor: isValid ? "pointer" : "not-allowed",
|
|
2270
|
+
opacity: isValid ? 1 : 0.4
|
|
2271
|
+
},
|
|
2272
|
+
children: "Apply"
|
|
2273
|
+
}
|
|
2274
|
+
)
|
|
2275
|
+
] })
|
|
2276
|
+
] })
|
|
2277
|
+
]
|
|
2278
|
+
}
|
|
2279
|
+
)
|
|
2280
|
+
]
|
|
2281
|
+
}
|
|
2282
|
+
)
|
|
2283
|
+
);
|
|
2284
|
+
};
|
|
2285
|
+
|
|
1812
2286
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.tsx
|
|
1813
|
-
import
|
|
2287
|
+
import React7 from "react";
|
|
1814
2288
|
import { Tab } from "@mui/material";
|
|
1815
2289
|
|
|
1816
2290
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.styles.tsx
|
|
1817
2291
|
import { Box, IconButton, Tabs } from "@mui/material";
|
|
1818
2292
|
import styled from "@emotion/styled";
|
|
1819
|
-
import { jsx as
|
|
2293
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
1820
2294
|
var FullscreenContainer = styled(Box)(
|
|
1821
2295
|
({ leftCollapsed, rightCollapsed }) => {
|
|
1822
2296
|
const getGridTemplateAreas = () => {
|
|
@@ -1941,7 +2415,7 @@ var DisplayModeToggle = styled(IconButton)(({ mode }) => ({
|
|
|
1941
2415
|
transform: "translateX(-50%) scale(1.05)"
|
|
1942
2416
|
}
|
|
1943
2417
|
}));
|
|
1944
|
-
var ChevronLeft = () => /* @__PURE__ */
|
|
2418
|
+
var ChevronLeft = () => /* @__PURE__ */ jsx10(
|
|
1945
2419
|
"div",
|
|
1946
2420
|
{
|
|
1947
2421
|
style: {
|
|
@@ -1953,7 +2427,7 @@ var ChevronLeft = () => /* @__PURE__ */ jsx9(
|
|
|
1953
2427
|
}
|
|
1954
2428
|
}
|
|
1955
2429
|
);
|
|
1956
|
-
var ChevronRight = () => /* @__PURE__ */
|
|
2430
|
+
var ChevronRight = () => /* @__PURE__ */ jsx10(
|
|
1957
2431
|
"div",
|
|
1958
2432
|
{
|
|
1959
2433
|
style: {
|
|
@@ -2064,10 +2538,10 @@ var ScrollableSVGWrapper = styled("div")({
|
|
|
2064
2538
|
});
|
|
2065
2539
|
|
|
2066
2540
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.overlays.tsx
|
|
2067
|
-
import { useEffect as
|
|
2541
|
+
import { useEffect as useEffect4, useState as useState7 } from "react";
|
|
2068
2542
|
import { Box as Box2 } from "@mui/material";
|
|
2069
2543
|
import styled2 from "@emotion/styled";
|
|
2070
|
-
import { jsx as
|
|
2544
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
2071
2545
|
var baseOverlayStyles = {
|
|
2072
2546
|
tank: {
|
|
2073
2547
|
background: "linear-gradient(135deg, rgba(69, 90, 120, 0.95) 0%, rgba(52, 73, 94, 0.95) 100%)",
|
|
@@ -2129,8 +2603,8 @@ var SVGLockedOverlay = ({
|
|
|
2129
2603
|
onClick,
|
|
2130
2604
|
containerSelector = ".tff-svg-container"
|
|
2131
2605
|
}) => {
|
|
2132
|
-
const [svgOffset, setSvgOffset] =
|
|
2133
|
-
|
|
2606
|
+
const [svgOffset, setSvgOffset] = useState7({ x: 0, y: 0 });
|
|
2607
|
+
useEffect4(() => {
|
|
2134
2608
|
const updateSvgOffset = () => {
|
|
2135
2609
|
const containerElement = document.querySelector(containerSelector);
|
|
2136
2610
|
const svgElement = containerElement?.querySelector("svg");
|
|
@@ -2150,7 +2624,7 @@ var SVGLockedOverlay = ({
|
|
|
2150
2624
|
const pixelX = svgX + svgOffset.x;
|
|
2151
2625
|
const pixelY = svgY + svgOffset.y;
|
|
2152
2626
|
const appliedStyle = theme ? { ...overlayStyles[theme], ...style } : style;
|
|
2153
|
-
return /* @__PURE__ */
|
|
2627
|
+
return /* @__PURE__ */ jsx11(
|
|
2154
2628
|
Box2,
|
|
2155
2629
|
{
|
|
2156
2630
|
className: `svg-locked-overlay ${className}`.trim(),
|
|
@@ -2214,7 +2688,7 @@ var CardUnit = styled2("div")({
|
|
|
2214
2688
|
});
|
|
2215
2689
|
|
|
2216
2690
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.visuals.tsx
|
|
2217
|
-
import { Fragment as Fragment3, jsx as
|
|
2691
|
+
import { Fragment as Fragment3, jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2218
2692
|
var TrendLine = ({
|
|
2219
2693
|
values,
|
|
2220
2694
|
width = 60,
|
|
@@ -2224,7 +2698,7 @@ var TrendLine = ({
|
|
|
2224
2698
|
backgroundColor = "rgba(255, 255, 255, 0.1)"
|
|
2225
2699
|
}) => {
|
|
2226
2700
|
if (!values || values.length < 2) {
|
|
2227
|
-
return /* @__PURE__ */
|
|
2701
|
+
return /* @__PURE__ */ jsx12(
|
|
2228
2702
|
"div",
|
|
2229
2703
|
{
|
|
2230
2704
|
style: {
|
|
@@ -2236,7 +2710,7 @@ var TrendLine = ({
|
|
|
2236
2710
|
alignItems: "center",
|
|
2237
2711
|
justifyContent: "center"
|
|
2238
2712
|
},
|
|
2239
|
-
children: /* @__PURE__ */
|
|
2713
|
+
children: /* @__PURE__ */ jsx12("span", { style: { fontSize: "8px", color: "#ccc" }, children: "No data" })
|
|
2240
2714
|
}
|
|
2241
2715
|
);
|
|
2242
2716
|
}
|
|
@@ -2248,7 +2722,7 @@ var TrendLine = ({
|
|
|
2248
2722
|
const x = 4 + i / (values.length - 1) * (width - 8);
|
|
2249
2723
|
return i === 0 ? `M ${x} ${y}` : `L ${x} ${y}`;
|
|
2250
2724
|
}).join(" ");
|
|
2251
|
-
return /* @__PURE__ */
|
|
2725
|
+
return /* @__PURE__ */ jsx12(
|
|
2252
2726
|
"div",
|
|
2253
2727
|
{
|
|
2254
2728
|
style: {
|
|
@@ -2259,8 +2733,8 @@ var TrendLine = ({
|
|
|
2259
2733
|
position: "relative",
|
|
2260
2734
|
overflow: "hidden"
|
|
2261
2735
|
},
|
|
2262
|
-
children: /* @__PURE__ */
|
|
2263
|
-
/* @__PURE__ */
|
|
2736
|
+
children: /* @__PURE__ */ jsxs9("svg", { width, height, style: { position: "absolute", top: 0, left: 0 }, children: [
|
|
2737
|
+
/* @__PURE__ */ jsx12(
|
|
2264
2738
|
"path",
|
|
2265
2739
|
{
|
|
2266
2740
|
d: pathData,
|
|
@@ -2271,7 +2745,7 @@ var TrendLine = ({
|
|
|
2271
2745
|
strokeLinejoin: "round"
|
|
2272
2746
|
}
|
|
2273
2747
|
),
|
|
2274
|
-
/* @__PURE__ */
|
|
2748
|
+
/* @__PURE__ */ jsx12(
|
|
2275
2749
|
"circle",
|
|
2276
2750
|
{
|
|
2277
2751
|
cx: 4 + (width - 8),
|
|
@@ -2309,7 +2783,7 @@ var CircularGauge = ({
|
|
|
2309
2783
|
const borderColor = isHex ? hexToRgba(color, 0.9) : color;
|
|
2310
2784
|
const backgroundColor = isHex ? hexToRgba(color, 0.15) : color;
|
|
2311
2785
|
const borderStrokeColor = isHex ? hexToRgba(color, 0.4) : color;
|
|
2312
|
-
return /* @__PURE__ */
|
|
2786
|
+
return /* @__PURE__ */ jsxs9(
|
|
2313
2787
|
"div",
|
|
2314
2788
|
{
|
|
2315
2789
|
style: {
|
|
@@ -2318,7 +2792,7 @@ var CircularGauge = ({
|
|
|
2318
2792
|
alignItems: "center"
|
|
2319
2793
|
},
|
|
2320
2794
|
children: [
|
|
2321
|
-
/* @__PURE__ */
|
|
2795
|
+
/* @__PURE__ */ jsxs9(
|
|
2322
2796
|
"div",
|
|
2323
2797
|
{
|
|
2324
2798
|
style: {
|
|
@@ -2330,8 +2804,8 @@ var CircularGauge = ({
|
|
|
2330
2804
|
border: `1px solid ${borderStrokeColor}`
|
|
2331
2805
|
},
|
|
2332
2806
|
children: [
|
|
2333
|
-
/* @__PURE__ */
|
|
2334
|
-
/* @__PURE__ */
|
|
2807
|
+
/* @__PURE__ */ jsxs9("svg", { width: size, height: size, style: { transform: "rotate(-90deg)" }, children: [
|
|
2808
|
+
/* @__PURE__ */ jsx12(
|
|
2335
2809
|
"circle",
|
|
2336
2810
|
{
|
|
2337
2811
|
cx: size / 2,
|
|
@@ -2342,7 +2816,7 @@ var CircularGauge = ({
|
|
|
2342
2816
|
strokeWidth: 1
|
|
2343
2817
|
}
|
|
2344
2818
|
),
|
|
2345
|
-
/* @__PURE__ */
|
|
2819
|
+
/* @__PURE__ */ jsx12(
|
|
2346
2820
|
"circle",
|
|
2347
2821
|
{
|
|
2348
2822
|
cx: size / 2,
|
|
@@ -2353,7 +2827,7 @@ var CircularGauge = ({
|
|
|
2353
2827
|
fill: "transparent"
|
|
2354
2828
|
}
|
|
2355
2829
|
),
|
|
2356
|
-
/* @__PURE__ */
|
|
2830
|
+
/* @__PURE__ */ jsx12(
|
|
2357
2831
|
"circle",
|
|
2358
2832
|
{
|
|
2359
2833
|
cx: size / 2,
|
|
@@ -2369,7 +2843,7 @@ var CircularGauge = ({
|
|
|
2369
2843
|
}
|
|
2370
2844
|
)
|
|
2371
2845
|
] }),
|
|
2372
|
-
/* @__PURE__ */
|
|
2846
|
+
/* @__PURE__ */ jsxs9(
|
|
2373
2847
|
"div",
|
|
2374
2848
|
{
|
|
2375
2849
|
style: {
|
|
@@ -2385,14 +2859,14 @@ var CircularGauge = ({
|
|
|
2385
2859
|
},
|
|
2386
2860
|
children: [
|
|
2387
2861
|
value.toFixed(1),
|
|
2388
|
-
/* @__PURE__ */
|
|
2862
|
+
/* @__PURE__ */ jsx12("div", { style: { fontSize: "8px", opacity: 0.9, color: "white" }, children: unit })
|
|
2389
2863
|
]
|
|
2390
2864
|
}
|
|
2391
2865
|
)
|
|
2392
2866
|
]
|
|
2393
2867
|
}
|
|
2394
2868
|
),
|
|
2395
|
-
/* @__PURE__ */
|
|
2869
|
+
/* @__PURE__ */ jsx12(
|
|
2396
2870
|
"div",
|
|
2397
2871
|
{
|
|
2398
2872
|
style: {
|
|
@@ -2423,7 +2897,7 @@ var Sparkline = ({ data, width, height, color }) => {
|
|
|
2423
2897
|
const y = height - 8 - (value - min) / range * (height - 8);
|
|
2424
2898
|
return `${x + 4},${y + 4}`;
|
|
2425
2899
|
}).join(" ");
|
|
2426
|
-
return /* @__PURE__ */
|
|
2900
|
+
return /* @__PURE__ */ jsx12(
|
|
2427
2901
|
"div",
|
|
2428
2902
|
{
|
|
2429
2903
|
style: {
|
|
@@ -2437,7 +2911,7 @@ var Sparkline = ({ data, width, height, color }) => {
|
|
|
2437
2911
|
justifyContent: "center",
|
|
2438
2912
|
boxShadow: "0 1px 3px rgba(0, 0, 0, 0.2)"
|
|
2439
2913
|
},
|
|
2440
|
-
children: /* @__PURE__ */
|
|
2914
|
+
children: /* @__PURE__ */ jsx12("svg", { width, height, children: /* @__PURE__ */ jsx12("polyline", { points, fill: "none", stroke: color, strokeWidth: "1.5", opacity: "0.9" }) })
|
|
2441
2915
|
}
|
|
2442
2916
|
);
|
|
2443
2917
|
};
|
|
@@ -2451,8 +2925,8 @@ var EquipmentIndicatorWithSparkline = ({
|
|
|
2451
2925
|
sparklineOffset = { x: 40, y: 0 }
|
|
2452
2926
|
}) => {
|
|
2453
2927
|
const hasSparkline = sparklineData && sparklineData.length > 1 && Math.max(...sparklineData) !== Math.min(...sparklineData);
|
|
2454
|
-
return /* @__PURE__ */
|
|
2455
|
-
/* @__PURE__ */
|
|
2928
|
+
return /* @__PURE__ */ jsxs9(Fragment3, { children: [
|
|
2929
|
+
/* @__PURE__ */ jsx12(SVGLockedOverlay, { svgX, svgY, style: { transform: "translate(-50%, -50%)" }, children: /* @__PURE__ */ jsx12(
|
|
2456
2930
|
"div",
|
|
2457
2931
|
{
|
|
2458
2932
|
style: {
|
|
@@ -2473,7 +2947,7 @@ var EquipmentIndicatorWithSparkline = ({
|
|
|
2473
2947
|
children: label
|
|
2474
2948
|
}
|
|
2475
2949
|
) }),
|
|
2476
|
-
hasSparkline && /* @__PURE__ */
|
|
2950
|
+
hasSparkline && /* @__PURE__ */ jsx12(SVGLockedOverlay, { svgX: svgX + sparklineOffset.x, svgY: svgY + sparklineOffset.y, children: /* @__PURE__ */ jsx12(Sparkline, { data: sparklineData, width: 60, height: 20, color }) })
|
|
2477
2951
|
] });
|
|
2478
2952
|
};
|
|
2479
2953
|
var EquipmentIndicator = ({
|
|
@@ -2486,7 +2960,7 @@ var EquipmentIndicator = ({
|
|
|
2486
2960
|
className
|
|
2487
2961
|
}) => {
|
|
2488
2962
|
const overlayStyle = style !== void 0 ? { transform: "translate(-50%, -50%)", ...style } : { transform: "translate(-50%, -50%)" };
|
|
2489
|
-
return /* @__PURE__ */
|
|
2963
|
+
return /* @__PURE__ */ jsx12(SVGLockedOverlay, { svgX, svgY, style: overlayStyle, className, children: /* @__PURE__ */ jsx12(
|
|
2490
2964
|
"div",
|
|
2491
2965
|
{
|
|
2492
2966
|
style: {
|
|
@@ -2510,7 +2984,7 @@ var EquipmentIndicator = ({
|
|
|
2510
2984
|
};
|
|
2511
2985
|
|
|
2512
2986
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.tsx
|
|
2513
|
-
import { Fragment as Fragment4, jsx as
|
|
2987
|
+
import { Fragment as Fragment4, jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2514
2988
|
function FullscreenWorkspace({
|
|
2515
2989
|
svgContent,
|
|
2516
2990
|
overlays,
|
|
@@ -2538,10 +3012,10 @@ function FullscreenWorkspace({
|
|
|
2538
3012
|
className = "",
|
|
2539
3013
|
...rest
|
|
2540
3014
|
}) {
|
|
2541
|
-
const [leftCollapsedState, setLeftCollapsedState] =
|
|
2542
|
-
const [rightCollapsedState, setRightCollapsedState] =
|
|
2543
|
-
const [internalDisplayMode, setInternalDisplayMode] =
|
|
2544
|
-
const [internalTab, setInternalTab] =
|
|
3015
|
+
const [leftCollapsedState, setLeftCollapsedState] = React7.useState(defaultLeftCollapsed);
|
|
3016
|
+
const [rightCollapsedState, setRightCollapsedState] = React7.useState(defaultRightCollapsed);
|
|
3017
|
+
const [internalDisplayMode, setInternalDisplayMode] = React7.useState(displayMode ?? defaultDisplayMode);
|
|
3018
|
+
const [internalTab, setInternalTab] = React7.useState(
|
|
2545
3019
|
tabs && tabs.length > 0 ? tabs[0].value : ""
|
|
2546
3020
|
);
|
|
2547
3021
|
const leftCollapsed = leftCollapsedProp ?? leftCollapsedState;
|
|
@@ -2549,10 +3023,10 @@ function FullscreenWorkspace({
|
|
|
2549
3023
|
const isDisplayModeControlled = displayMode !== void 0;
|
|
2550
3024
|
const currentDisplayMode = isDisplayModeControlled ? displayMode : internalDisplayMode;
|
|
2551
3025
|
const isTabControlled = activeTab !== void 0 && activeTab !== null;
|
|
2552
|
-
const resolvedTabs =
|
|
3026
|
+
const resolvedTabs = React7.useMemo(() => tabs ?? [], [tabs]);
|
|
2553
3027
|
const defaultTabValue = resolvedTabs.length > 0 ? resolvedTabs[0].value : "";
|
|
2554
3028
|
const currentTab = isTabControlled ? activeTab : internalTab || defaultTabValue;
|
|
2555
|
-
|
|
3029
|
+
React7.useEffect(() => {
|
|
2556
3030
|
if (resolvedTabs.length > 0) {
|
|
2557
3031
|
const values = resolvedTabs.map((tab) => tab.value);
|
|
2558
3032
|
if (!values.includes(currentTab)) {
|
|
@@ -2561,7 +3035,7 @@ function FullscreenWorkspace({
|
|
|
2561
3035
|
}
|
|
2562
3036
|
}
|
|
2563
3037
|
}, [resolvedTabs, activeTab, currentTab, defaultTabValue]);
|
|
2564
|
-
|
|
3038
|
+
React7.useEffect(() => {
|
|
2565
3039
|
if (displayMode !== void 0) {
|
|
2566
3040
|
setInternalDisplayMode(displayMode);
|
|
2567
3041
|
}
|
|
@@ -2596,7 +3070,7 @@ function FullscreenWorkspace({
|
|
|
2596
3070
|
const currentTabContent = resolvedTabs.find((tab) => tab.value === currentTab)?.content ?? null;
|
|
2597
3071
|
const showLeftToggle = Boolean(leftPanel);
|
|
2598
3072
|
const showRightToggle = Boolean(rightPanel);
|
|
2599
|
-
return /* @__PURE__ */
|
|
3073
|
+
return /* @__PURE__ */ jsxs10(
|
|
2600
3074
|
FullscreenContainer,
|
|
2601
3075
|
{
|
|
2602
3076
|
leftCollapsed,
|
|
@@ -2604,25 +3078,25 @@ function FullscreenWorkspace({
|
|
|
2604
3078
|
className: `tff-svg-container ${className}`.trim(),
|
|
2605
3079
|
...rest,
|
|
2606
3080
|
children: [
|
|
2607
|
-
showLeftToggle && /* @__PURE__ */
|
|
3081
|
+
showLeftToggle && /* @__PURE__ */ jsx13(
|
|
2608
3082
|
LeftToggleButton,
|
|
2609
3083
|
{
|
|
2610
3084
|
collapsed: leftCollapsed,
|
|
2611
3085
|
onClick: handleLeftToggle,
|
|
2612
3086
|
"aria-label": leftCollapsed ? "Expand left panel" : "Collapse left panel",
|
|
2613
|
-
children: leftCollapsed ? /* @__PURE__ */
|
|
3087
|
+
children: leftCollapsed ? /* @__PURE__ */ jsx13(ChevronRight, {}) : /* @__PURE__ */ jsx13(ChevronLeft, {})
|
|
2614
3088
|
}
|
|
2615
3089
|
),
|
|
2616
|
-
showRightToggle && /* @__PURE__ */
|
|
3090
|
+
showRightToggle && /* @__PURE__ */ jsx13(
|
|
2617
3091
|
RightToggleButton,
|
|
2618
3092
|
{
|
|
2619
3093
|
collapsed: rightCollapsed,
|
|
2620
3094
|
onClick: handleRightToggle,
|
|
2621
3095
|
"aria-label": rightCollapsed ? "Expand right panel" : "Collapse right panel",
|
|
2622
|
-
children: rightCollapsed ? /* @__PURE__ */
|
|
3096
|
+
children: rightCollapsed ? /* @__PURE__ */ jsx13(ChevronLeft, {}) : /* @__PURE__ */ jsx13(ChevronRight, {})
|
|
2623
3097
|
}
|
|
2624
3098
|
),
|
|
2625
|
-
showDisplayModeToggle && /* @__PURE__ */
|
|
3099
|
+
showDisplayModeToggle && /* @__PURE__ */ jsx13(
|
|
2626
3100
|
DisplayModeToggle,
|
|
2627
3101
|
{
|
|
2628
3102
|
mode: currentDisplayMode,
|
|
@@ -2631,9 +3105,9 @@ function FullscreenWorkspace({
|
|
|
2631
3105
|
children: currentDisplayMode === "dashboard" ? "Dashboard Mode" : "Standard Mode"
|
|
2632
3106
|
}
|
|
2633
3107
|
),
|
|
2634
|
-
/* @__PURE__ */
|
|
2635
|
-
showZoomControls && /* @__PURE__ */
|
|
2636
|
-
/* @__PURE__ */
|
|
3108
|
+
/* @__PURE__ */ jsxs10(SVGArea, { children: [
|
|
3109
|
+
showZoomControls && /* @__PURE__ */ jsxs10(ZoomControls, { children: [
|
|
3110
|
+
/* @__PURE__ */ jsx13(
|
|
2637
3111
|
ZoomButton,
|
|
2638
3112
|
{
|
|
2639
3113
|
onClick: onZoomIn,
|
|
@@ -2643,7 +3117,7 @@ function FullscreenWorkspace({
|
|
|
2643
3117
|
children: "+"
|
|
2644
3118
|
}
|
|
2645
3119
|
),
|
|
2646
|
-
/* @__PURE__ */
|
|
3120
|
+
/* @__PURE__ */ jsx13(
|
|
2647
3121
|
ZoomButton,
|
|
2648
3122
|
{
|
|
2649
3123
|
onClick: onZoomOut,
|
|
@@ -2653,7 +3127,7 @@ function FullscreenWorkspace({
|
|
|
2653
3127
|
children: "-"
|
|
2654
3128
|
}
|
|
2655
3129
|
),
|
|
2656
|
-
onResetZoom && /* @__PURE__ */
|
|
3130
|
+
onResetZoom && /* @__PURE__ */ jsx13(
|
|
2657
3131
|
ZoomButton,
|
|
2658
3132
|
{
|
|
2659
3133
|
onClick: onResetZoom,
|
|
@@ -2664,33 +3138,33 @@ function FullscreenWorkspace({
|
|
|
2664
3138
|
}
|
|
2665
3139
|
)
|
|
2666
3140
|
] }),
|
|
2667
|
-
/* @__PURE__ */
|
|
3141
|
+
/* @__PURE__ */ jsx13(ScrollableSVGWrapper, { className: "svg-scroll-wrapper", children: /* @__PURE__ */ jsxs10(FixedSVGContainer, { className: "svg-container", children: [
|
|
2668
3142
|
svgContent,
|
|
2669
3143
|
overlays
|
|
2670
3144
|
] }) })
|
|
2671
3145
|
] }),
|
|
2672
|
-
/* @__PURE__ */
|
|
2673
|
-
/* @__PURE__ */
|
|
3146
|
+
/* @__PURE__ */ jsx13(LeftPanel, { collapsed: leftCollapsed, children: resolvedTabs.length > 0 ? /* @__PURE__ */ jsxs10(Fragment4, { children: [
|
|
3147
|
+
/* @__PURE__ */ jsx13(
|
|
2674
3148
|
PanelTabs,
|
|
2675
3149
|
{
|
|
2676
3150
|
value: currentTab,
|
|
2677
3151
|
onChange: handleTabChangeInternal,
|
|
2678
3152
|
"aria-label": "Left panel tabs",
|
|
2679
|
-
children: resolvedTabs.map((tab) => /* @__PURE__ */
|
|
3153
|
+
children: resolvedTabs.map((tab) => /* @__PURE__ */ jsx13(Tab, { label: tab.label, value: tab.value }, tab.value))
|
|
2680
3154
|
}
|
|
2681
3155
|
),
|
|
2682
|
-
/* @__PURE__ */
|
|
3156
|
+
/* @__PURE__ */ jsx13(PanelContent, { children: currentTabContent })
|
|
2683
3157
|
] }) : leftPanel }),
|
|
2684
|
-
/* @__PURE__ */
|
|
2685
|
-
/* @__PURE__ */
|
|
3158
|
+
/* @__PURE__ */ jsx13(RightPanel, { collapsed: rightCollapsed, children: rightPanel }),
|
|
3159
|
+
/* @__PURE__ */ jsx13(FooterPanel, { children: footer })
|
|
2686
3160
|
]
|
|
2687
3161
|
}
|
|
2688
3162
|
);
|
|
2689
3163
|
}
|
|
2690
3164
|
|
|
2691
3165
|
// src/theme/ThemeContext.tsx
|
|
2692
|
-
import { createContext, useContext, useState as
|
|
2693
|
-
import { jsx as
|
|
3166
|
+
import { createContext, useContext, useState as useState8, useEffect as useEffect5 } from "react";
|
|
3167
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
2694
3168
|
var ThemeContext = createContext(void 0);
|
|
2695
3169
|
var useTheme = () => {
|
|
2696
3170
|
const context = useContext(ThemeContext);
|
|
@@ -2700,8 +3174,8 @@ var useTheme = () => {
|
|
|
2700
3174
|
return context;
|
|
2701
3175
|
};
|
|
2702
3176
|
var ThemeProvider = ({ children }) => {
|
|
2703
|
-
const [theme, setThemeState] =
|
|
2704
|
-
|
|
3177
|
+
const [theme, setThemeState] = useState8("modern");
|
|
3178
|
+
useEffect5(() => {
|
|
2705
3179
|
document.body.className = "";
|
|
2706
3180
|
document.body.classList.add(`theme-${theme}`);
|
|
2707
3181
|
document.documentElement.className = "";
|
|
@@ -2713,11 +3187,11 @@ var ThemeProvider = ({ children }) => {
|
|
|
2713
3187
|
const setTheme = (newTheme) => {
|
|
2714
3188
|
setThemeState(newTheme);
|
|
2715
3189
|
};
|
|
2716
|
-
return /* @__PURE__ */
|
|
3190
|
+
return /* @__PURE__ */ jsx14(ThemeContext.Provider, { value: { theme, toggleTheme, setTheme }, children });
|
|
2717
3191
|
};
|
|
2718
3192
|
|
|
2719
3193
|
// src/theme/ThemeToggle.tsx
|
|
2720
|
-
import { jsx as
|
|
3194
|
+
import { jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2721
3195
|
var ThemeToggle = ({
|
|
2722
3196
|
size = "medium",
|
|
2723
3197
|
position = "top-right",
|
|
@@ -2788,15 +3262,15 @@ var ThemeToggle = ({
|
|
|
2788
3262
|
transition: "all 0.2s ease",
|
|
2789
3263
|
boxShadow: "0 2px 4px rgba(0, 0, 0, 0.2)"
|
|
2790
3264
|
};
|
|
2791
|
-
return /* @__PURE__ */
|
|
2792
|
-
/* @__PURE__ */
|
|
2793
|
-
/* @__PURE__ */
|
|
2794
|
-
/* @__PURE__ */
|
|
3265
|
+
return /* @__PURE__ */ jsxs11("div", { style: currentStyle, onClick: toggleTheme, className, ...props, children: [
|
|
3266
|
+
/* @__PURE__ */ jsx15("span", { children: theme === "modern" ? "\u{1F3A8} Modern" : "\u{1F3ED} HMI" }),
|
|
3267
|
+
/* @__PURE__ */ jsx15("div", { style: toggleStyle, children: /* @__PURE__ */ jsx15("div", { style: thumbStyle }) }),
|
|
3268
|
+
/* @__PURE__ */ jsx15("span", { style: { fontSize: "0.75rem", opacity: 0.8 }, children: theme === "modern" ? "Industrial Design" : "High Performance" })
|
|
2795
3269
|
] });
|
|
2796
3270
|
};
|
|
2797
3271
|
|
|
2798
3272
|
// src/components/PIDCanvas/PIDCanvas.tsx
|
|
2799
|
-
import { useCallback as
|
|
3273
|
+
import { useCallback as useCallback8, useState as useState14, useEffect as useEffect12, useRef as useRef6 } from "react";
|
|
2800
3274
|
|
|
2801
3275
|
// src/diagram/symbols/mockSymbolLibrary.ts
|
|
2802
3276
|
var mockSymbolLibrary = {
|
|
@@ -4017,7 +4491,7 @@ function getAvailableSymbols() {
|
|
|
4017
4491
|
}
|
|
4018
4492
|
|
|
4019
4493
|
// src/components/PIDCanvas/NodeRenderer.tsx
|
|
4020
|
-
import { jsx as
|
|
4494
|
+
import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
4021
4495
|
function NodeRenderer({
|
|
4022
4496
|
nodes: nodes2,
|
|
4023
4497
|
selectedNodeIds,
|
|
@@ -4029,13 +4503,13 @@ function NodeRenderer({
|
|
|
4029
4503
|
enableDrag = false,
|
|
4030
4504
|
statusColorMap
|
|
4031
4505
|
}) {
|
|
4032
|
-
return /* @__PURE__ */
|
|
4506
|
+
return /* @__PURE__ */ jsx16("g", { id: "layer-nodes", children: nodes2.filter((node) => node.visible !== false).map((node) => {
|
|
4033
4507
|
const symbol = getSymbolDefinition(node.symbolId);
|
|
4034
4508
|
const isSelected = selectedNodeIds?.has(node.id) ?? false;
|
|
4035
4509
|
const isDragging = draggingNodeId === node.id;
|
|
4036
4510
|
if (!symbol) {
|
|
4037
|
-
return /* @__PURE__ */
|
|
4038
|
-
/* @__PURE__ */
|
|
4511
|
+
return /* @__PURE__ */ jsxs12("g", { children: [
|
|
4512
|
+
/* @__PURE__ */ jsx16(
|
|
4039
4513
|
"circle",
|
|
4040
4514
|
{
|
|
4041
4515
|
cx: node.transform.x,
|
|
@@ -4047,7 +4521,7 @@ function NodeRenderer({
|
|
|
4047
4521
|
strokeWidth: "2"
|
|
4048
4522
|
}
|
|
4049
4523
|
),
|
|
4050
|
-
/* @__PURE__ */
|
|
4524
|
+
/* @__PURE__ */ jsx16(
|
|
4051
4525
|
"text",
|
|
4052
4526
|
{
|
|
4053
4527
|
x: node.transform.x,
|
|
@@ -4089,7 +4563,7 @@ function NodeRenderer({
|
|
|
4089
4563
|
const statusEntry = resolveStatusColor(node.status, statusColorMap);
|
|
4090
4564
|
const fillColor = node.customColors?.fill ?? statusEntry.fill;
|
|
4091
4565
|
const strokeColor = node.customColors?.stroke ?? statusEntry.stroke;
|
|
4092
|
-
return /* @__PURE__ */
|
|
4566
|
+
return /* @__PURE__ */ jsxs12(
|
|
4093
4567
|
"g",
|
|
4094
4568
|
{
|
|
4095
4569
|
"data-node-id": node.id,
|
|
@@ -4122,7 +4596,7 @@ function NodeRenderer({
|
|
|
4122
4596
|
}
|
|
4123
4597
|
},
|
|
4124
4598
|
children: [
|
|
4125
|
-
isSelected && /* @__PURE__ */
|
|
4599
|
+
isSelected && /* @__PURE__ */ jsx16(
|
|
4126
4600
|
"rect",
|
|
4127
4601
|
{
|
|
4128
4602
|
x: "-5",
|
|
@@ -4137,7 +4611,7 @@ function NodeRenderer({
|
|
|
4137
4611
|
pointerEvents: "none"
|
|
4138
4612
|
}
|
|
4139
4613
|
),
|
|
4140
|
-
/* @__PURE__ */
|
|
4614
|
+
/* @__PURE__ */ jsx16(
|
|
4141
4615
|
"g",
|
|
4142
4616
|
{
|
|
4143
4617
|
dangerouslySetInnerHTML: { __html: symbol.svgContent },
|
|
@@ -4145,7 +4619,7 @@ function NodeRenderer({
|
|
|
4145
4619
|
style: { pointerEvents: "auto" }
|
|
4146
4620
|
}
|
|
4147
4621
|
),
|
|
4148
|
-
/* @__PURE__ */
|
|
4622
|
+
/* @__PURE__ */ jsx16(
|
|
4149
4623
|
"text",
|
|
4150
4624
|
{
|
|
4151
4625
|
x: symbol.viewBox.width / 2 + (node.labelOffset?.x ?? 0),
|
|
@@ -4166,7 +4640,7 @@ function NodeRenderer({
|
|
|
4166
4640
|
}
|
|
4167
4641
|
|
|
4168
4642
|
// src/components/PIDCanvas/PipeRenderer.tsx
|
|
4169
|
-
import { Fragment as Fragment5, jsx as
|
|
4643
|
+
import { Fragment as Fragment5, jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
4170
4644
|
function PipeRenderer({
|
|
4171
4645
|
pipes,
|
|
4172
4646
|
selectedPipeIds,
|
|
@@ -4181,7 +4655,7 @@ function PipeRenderer({
|
|
|
4181
4655
|
waypointDragOffset,
|
|
4182
4656
|
onPipeSegmentClick
|
|
4183
4657
|
}) {
|
|
4184
|
-
return /* @__PURE__ */
|
|
4658
|
+
return /* @__PURE__ */ jsx17("g", { id: "layer-pipes", children: pipes.filter((pipe) => pipe.visible !== false).map((pipe) => {
|
|
4185
4659
|
const isSelected = selectedPipeIds?.has(pipe.id) ?? false;
|
|
4186
4660
|
const isEditing = enableWaypointEditing && editingPipeId === pipe.id;
|
|
4187
4661
|
const showEditingControls = enableWaypointEditing && isSelected;
|
|
@@ -4200,7 +4674,7 @@ function PipeRenderer({
|
|
|
4200
4674
|
const strokeWidth = isSelected ? (pipeStyle.strokeWidth || 3) + 2 : pipeStyle.strokeWidth || 3;
|
|
4201
4675
|
const strokeDasharray = pipeStyle.strokeDasharray;
|
|
4202
4676
|
const opacity = pipeStyle.opacity !== void 0 ? pipeStyle.opacity : 1;
|
|
4203
|
-
return /* @__PURE__ */
|
|
4677
|
+
return /* @__PURE__ */ jsxs13(
|
|
4204
4678
|
"g",
|
|
4205
4679
|
{
|
|
4206
4680
|
"data-pipe-id": pipe.id,
|
|
@@ -4213,8 +4687,8 @@ function PipeRenderer({
|
|
|
4213
4687
|
cursor: onPipeClick ? "pointer" : "default"
|
|
4214
4688
|
},
|
|
4215
4689
|
children: [
|
|
4216
|
-
!enableWaypointEditing && /* @__PURE__ */
|
|
4217
|
-
onPipeClick && /* @__PURE__ */
|
|
4690
|
+
!enableWaypointEditing && /* @__PURE__ */ jsxs13(Fragment5, { children: [
|
|
4691
|
+
onPipeClick && /* @__PURE__ */ jsx17(
|
|
4218
4692
|
"polyline",
|
|
4219
4693
|
{
|
|
4220
4694
|
points: pointsString,
|
|
@@ -4226,7 +4700,7 @@ function PipeRenderer({
|
|
|
4226
4700
|
pointerEvents: "stroke"
|
|
4227
4701
|
}
|
|
4228
4702
|
),
|
|
4229
|
-
/* @__PURE__ */
|
|
4703
|
+
/* @__PURE__ */ jsx17(
|
|
4230
4704
|
"polyline",
|
|
4231
4705
|
{
|
|
4232
4706
|
points: pointsString,
|
|
@@ -4250,7 +4724,7 @@ function PipeRenderer({
|
|
|
4250
4724
|
const waypointSize = isSelectedWaypoint ? 8 : isDragging ? 8 : showEditingControls ? 6 : isSelected ? 3 : 2;
|
|
4251
4725
|
const waypointOpacity = isSelectedWaypoint ? 1 : isDragging ? 1 : showEditingControls ? 0.9 : isSelected ? 0.8 : 0.5;
|
|
4252
4726
|
const waypointColor = isSelectedWaypoint ? "#3b82f6" : isEndpoint && showEditingControls ? "#f59e0b" : isDragging ? "#10b981" : stroke;
|
|
4253
|
-
return /* @__PURE__ */
|
|
4727
|
+
return /* @__PURE__ */ jsx17(
|
|
4254
4728
|
"circle",
|
|
4255
4729
|
{
|
|
4256
4730
|
cx: point.x,
|
|
@@ -4287,12 +4761,12 @@ function PipeRenderer({
|
|
|
4287
4761
|
`${pipe.id}-point-${idx}`
|
|
4288
4762
|
);
|
|
4289
4763
|
}),
|
|
4290
|
-
showEditingControls && onPipeSegmentClick && displayPoints.length >= 2 && /* @__PURE__ */
|
|
4764
|
+
showEditingControls && onPipeSegmentClick && displayPoints.length >= 2 && /* @__PURE__ */ jsx17(Fragment5, { children: displayPoints.slice(0, -1).map((point, idx) => {
|
|
4291
4765
|
const nextPoint = displayPoints[idx + 1];
|
|
4292
4766
|
const midX = (point.x + nextPoint.x) / 2;
|
|
4293
4767
|
const midY = (point.y + nextPoint.y) / 2;
|
|
4294
|
-
return /* @__PURE__ */
|
|
4295
|
-
/* @__PURE__ */
|
|
4768
|
+
return /* @__PURE__ */ jsxs13("g", { children: [
|
|
4769
|
+
/* @__PURE__ */ jsx17(
|
|
4296
4770
|
"circle",
|
|
4297
4771
|
{
|
|
4298
4772
|
cx: midX,
|
|
@@ -4308,7 +4782,7 @@ function PipeRenderer({
|
|
|
4308
4782
|
}
|
|
4309
4783
|
}
|
|
4310
4784
|
),
|
|
4311
|
-
/* @__PURE__ */
|
|
4785
|
+
/* @__PURE__ */ jsx17(
|
|
4312
4786
|
"circle",
|
|
4313
4787
|
{
|
|
4314
4788
|
cx: midX,
|
|
@@ -4324,7 +4798,7 @@ function PipeRenderer({
|
|
|
4324
4798
|
)
|
|
4325
4799
|
] }, `${pipe.id}-segment-${idx}`);
|
|
4326
4800
|
}) }),
|
|
4327
|
-
pipe.showLabel !== false && pipe.label && pipe.routePoints.length >= 2 && /* @__PURE__ */
|
|
4801
|
+
pipe.showLabel !== false && pipe.label && pipe.routePoints.length >= 2 && /* @__PURE__ */ jsx17(
|
|
4328
4802
|
"text",
|
|
4329
4803
|
{
|
|
4330
4804
|
x: pipe.routePoints[Math.floor(pipe.routePoints.length / 2)].x + (pipe.labelOffset?.x ?? 0),
|
|
@@ -4346,7 +4820,7 @@ function PipeRenderer({
|
|
|
4346
4820
|
}
|
|
4347
4821
|
|
|
4348
4822
|
// src/components/PIDCanvas/DataOverlay.tsx
|
|
4349
|
-
import { Fragment as Fragment6, jsx as
|
|
4823
|
+
import { Fragment as Fragment6, jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
4350
4824
|
function DataOverlay({
|
|
4351
4825
|
nodeId,
|
|
4352
4826
|
x,
|
|
@@ -4368,7 +4842,7 @@ function DataOverlay({
|
|
|
4368
4842
|
const offsetX = display?.offsetX ?? 0;
|
|
4369
4843
|
const offsetY = display?.offsetY ?? 0;
|
|
4370
4844
|
if (!showValue) {
|
|
4371
|
-
return /* @__PURE__ */
|
|
4845
|
+
return /* @__PURE__ */ jsx18(Fragment6, {});
|
|
4372
4846
|
}
|
|
4373
4847
|
const formatValue = (val) => {
|
|
4374
4848
|
if (typeof val === "number") {
|
|
@@ -4409,8 +4883,8 @@ function DataOverlay({
|
|
|
4409
4883
|
const overlayWidth = 80 * scale;
|
|
4410
4884
|
const displayX = x + offsetX;
|
|
4411
4885
|
const displayY = y + offsetY;
|
|
4412
|
-
return /* @__PURE__ */
|
|
4413
|
-
/* @__PURE__ */
|
|
4886
|
+
return /* @__PURE__ */ jsxs14("g", { "data-overlay-node": nodeId, "data-status": value.status, children: [
|
|
4887
|
+
/* @__PURE__ */ jsx18(
|
|
4414
4888
|
"rect",
|
|
4415
4889
|
{
|
|
4416
4890
|
x: displayX - overlayWidth / 2,
|
|
@@ -4425,7 +4899,7 @@ function DataOverlay({
|
|
|
4425
4899
|
filter: "drop-shadow(0 2px 4px rgba(0,0,0,0.2))"
|
|
4426
4900
|
}
|
|
4427
4901
|
),
|
|
4428
|
-
label && /* @__PURE__ */
|
|
4902
|
+
label && /* @__PURE__ */ jsx18(
|
|
4429
4903
|
"text",
|
|
4430
4904
|
{
|
|
4431
4905
|
x: displayX,
|
|
@@ -4438,7 +4912,7 @@ function DataOverlay({
|
|
|
4438
4912
|
children: label
|
|
4439
4913
|
}
|
|
4440
4914
|
),
|
|
4441
|
-
/* @__PURE__ */
|
|
4915
|
+
/* @__PURE__ */ jsx18(
|
|
4442
4916
|
"text",
|
|
4443
4917
|
{
|
|
4444
4918
|
x: displayX,
|
|
@@ -4451,7 +4925,7 @@ function DataOverlay({
|
|
|
4451
4925
|
children: displayText
|
|
4452
4926
|
}
|
|
4453
4927
|
),
|
|
4454
|
-
showStatus && value.status !== "normal" && /* @__PURE__ */
|
|
4928
|
+
showStatus && value.status !== "normal" && /* @__PURE__ */ jsx18(
|
|
4455
4929
|
"circle",
|
|
4456
4930
|
{
|
|
4457
4931
|
cx: displayX + 35 * scale,
|
|
@@ -4459,7 +4933,7 @@ function DataOverlay({
|
|
|
4459
4933
|
r: 3 * scale,
|
|
4460
4934
|
fill: finalTextColor,
|
|
4461
4935
|
opacity: "0.9",
|
|
4462
|
-
children: /* @__PURE__ */
|
|
4936
|
+
children: /* @__PURE__ */ jsx18(
|
|
4463
4937
|
"animate",
|
|
4464
4938
|
{
|
|
4465
4939
|
attributeName: "opacity",
|
|
@@ -4470,7 +4944,7 @@ function DataOverlay({
|
|
|
4470
4944
|
)
|
|
4471
4945
|
}
|
|
4472
4946
|
),
|
|
4473
|
-
value.quality !== void 0 && value.quality < 100 && /* @__PURE__ */
|
|
4947
|
+
value.quality !== void 0 && value.quality < 100 && /* @__PURE__ */ jsxs14(
|
|
4474
4948
|
"text",
|
|
4475
4949
|
{
|
|
4476
4950
|
x: displayX,
|
|
@@ -4487,7 +4961,7 @@ function DataOverlay({
|
|
|
4487
4961
|
]
|
|
4488
4962
|
}
|
|
4489
4963
|
),
|
|
4490
|
-
hasSparkline && /* @__PURE__ */
|
|
4964
|
+
hasSparkline && /* @__PURE__ */ jsx18("g", { transform: `translate(${displayX - 35 * scale}, ${displayY + (label ? 5 : 0) * scale})`, children: /* @__PURE__ */ jsx18(
|
|
4491
4965
|
"path",
|
|
4492
4966
|
{
|
|
4493
4967
|
d: sparklinePath,
|
|
@@ -4503,8 +4977,8 @@ function DataOverlay({
|
|
|
4503
4977
|
}
|
|
4504
4978
|
|
|
4505
4979
|
// src/components/PIDCanvas/PositionPanel.tsx
|
|
4506
|
-
import { useState as
|
|
4507
|
-
import { jsx as
|
|
4980
|
+
import { useState as useState9, useEffect as useEffect6 } from "react";
|
|
4981
|
+
import { jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
4508
4982
|
function PositionPanel({
|
|
4509
4983
|
selectedNode,
|
|
4510
4984
|
selectedWaypoint,
|
|
@@ -4512,9 +4986,9 @@ function PositionPanel({
|
|
|
4512
4986
|
onWaypointPositionChange,
|
|
4513
4987
|
position = "top-right"
|
|
4514
4988
|
}) {
|
|
4515
|
-
const [x, setX] =
|
|
4516
|
-
const [y, setY] =
|
|
4517
|
-
|
|
4989
|
+
const [x, setX] = useState9("");
|
|
4990
|
+
const [y, setY] = useState9("");
|
|
4991
|
+
useEffect6(() => {
|
|
4518
4992
|
if (selectedNode) {
|
|
4519
4993
|
setX(selectedNode.transform.x.toFixed(2));
|
|
4520
4994
|
setY(selectedNode.transform.y.toFixed(2));
|
|
@@ -4573,7 +5047,7 @@ function PositionPanel({
|
|
|
4573
5047
|
"bottom-left": { bottom: 10, left: 10 },
|
|
4574
5048
|
"bottom-right": { bottom: 10, right: 10 }
|
|
4575
5049
|
};
|
|
4576
|
-
return /* @__PURE__ */
|
|
5050
|
+
return /* @__PURE__ */ jsxs15(
|
|
4577
5051
|
"div",
|
|
4578
5052
|
{
|
|
4579
5053
|
style: {
|
|
@@ -4590,11 +5064,11 @@ function PositionPanel({
|
|
|
4590
5064
|
fontSize: "13px"
|
|
4591
5065
|
},
|
|
4592
5066
|
children: [
|
|
4593
|
-
/* @__PURE__ */
|
|
4594
|
-
/* @__PURE__ */
|
|
4595
|
-
/* @__PURE__ */
|
|
4596
|
-
/* @__PURE__ */
|
|
4597
|
-
/* @__PURE__ */
|
|
5067
|
+
/* @__PURE__ */ jsx19("div", { style: { marginBottom: "8px", fontWeight: 600, color: "#333" }, children: "Position" }),
|
|
5068
|
+
/* @__PURE__ */ jsxs15("div", { style: { display: "flex", flexDirection: "column", gap: "8px" }, children: [
|
|
5069
|
+
/* @__PURE__ */ jsxs15("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
|
|
5070
|
+
/* @__PURE__ */ jsx19("label", { style: { width: "16px", color: "#666" }, children: "X:" }),
|
|
5071
|
+
/* @__PURE__ */ jsx19(
|
|
4598
5072
|
"input",
|
|
4599
5073
|
{
|
|
4600
5074
|
type: "number",
|
|
@@ -4612,9 +5086,9 @@ function PositionPanel({
|
|
|
4612
5086
|
}
|
|
4613
5087
|
)
|
|
4614
5088
|
] }),
|
|
4615
|
-
/* @__PURE__ */
|
|
4616
|
-
/* @__PURE__ */
|
|
4617
|
-
/* @__PURE__ */
|
|
5089
|
+
/* @__PURE__ */ jsxs15("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
|
|
5090
|
+
/* @__PURE__ */ jsx19("label", { style: { width: "16px", color: "#666" }, children: "Y:" }),
|
|
5091
|
+
/* @__PURE__ */ jsx19(
|
|
4618
5092
|
"input",
|
|
4619
5093
|
{
|
|
4620
5094
|
type: "number",
|
|
@@ -4633,14 +5107,14 @@ function PositionPanel({
|
|
|
4633
5107
|
)
|
|
4634
5108
|
] })
|
|
4635
5109
|
] }),
|
|
4636
|
-
/* @__PURE__ */
|
|
5110
|
+
/* @__PURE__ */ jsx19("div", { style: { marginTop: "8px", fontSize: "11px", color: "#888" }, children: "Use arrow keys to nudge (\xB11px)" })
|
|
4637
5111
|
]
|
|
4638
5112
|
}
|
|
4639
5113
|
);
|
|
4640
5114
|
}
|
|
4641
5115
|
|
|
4642
5116
|
// src/diagram/hooks/useViewBox.ts
|
|
4643
|
-
import { useState as
|
|
5117
|
+
import { useState as useState10, useCallback as useCallback4, useRef as useRef3, useEffect as useEffect7 } from "react";
|
|
4644
5118
|
function useViewBox(options) {
|
|
4645
5119
|
const {
|
|
4646
5120
|
initialViewBox,
|
|
@@ -4651,16 +5125,16 @@ function useViewBox(options) {
|
|
|
4651
5125
|
zoomSensitivity = 1e-3,
|
|
4652
5126
|
allowLeftClickPan = true
|
|
4653
5127
|
} = options;
|
|
4654
|
-
const [viewBox, setViewBox] =
|
|
4655
|
-
const svgRef =
|
|
4656
|
-
const isPanningRef =
|
|
4657
|
-
const lastMousePosRef =
|
|
4658
|
-
const spaceKeyDownRef =
|
|
4659
|
-
const lastTouchDistanceRef =
|
|
4660
|
-
const resetViewBox =
|
|
5128
|
+
const [viewBox, setViewBox] = useState10(initialViewBox);
|
|
5129
|
+
const svgRef = useRef3(null);
|
|
5130
|
+
const isPanningRef = useRef3(false);
|
|
5131
|
+
const lastMousePosRef = useRef3({ x: 0, y: 0 });
|
|
5132
|
+
const spaceKeyDownRef = useRef3(false);
|
|
5133
|
+
const lastTouchDistanceRef = useRef3(null);
|
|
5134
|
+
const resetViewBox = useCallback4(() => {
|
|
4661
5135
|
setViewBox(initialViewBox);
|
|
4662
5136
|
}, [initialViewBox]);
|
|
4663
|
-
const zoomIn =
|
|
5137
|
+
const zoomIn = useCallback4(() => {
|
|
4664
5138
|
setViewBox((prev) => {
|
|
4665
5139
|
const currentZoom = initialViewBox.width / prev.width;
|
|
4666
5140
|
const newZoom = Math.min(1 / minZoom, currentZoom * 1.25);
|
|
@@ -4677,7 +5151,7 @@ function useViewBox(options) {
|
|
|
4677
5151
|
};
|
|
4678
5152
|
});
|
|
4679
5153
|
}, [initialViewBox, minZoom]);
|
|
4680
|
-
const zoomOut =
|
|
5154
|
+
const zoomOut = useCallback4(() => {
|
|
4681
5155
|
setViewBox((prev) => {
|
|
4682
5156
|
const currentZoom = initialViewBox.width / prev.width;
|
|
4683
5157
|
const newZoom = Math.max(1 / maxZoom, currentZoom * 0.8);
|
|
@@ -4694,7 +5168,7 @@ function useViewBox(options) {
|
|
|
4694
5168
|
};
|
|
4695
5169
|
});
|
|
4696
5170
|
}, [initialViewBox, maxZoom]);
|
|
4697
|
-
const fitToContent =
|
|
5171
|
+
const fitToContent = useCallback4((bounds, padding = 50) => {
|
|
4698
5172
|
const contentWidth = bounds.maxX - bounds.minX;
|
|
4699
5173
|
const contentHeight = bounds.maxY - bounds.minY;
|
|
4700
5174
|
if (contentWidth === 0 || contentHeight === 0) {
|
|
@@ -4722,7 +5196,7 @@ function useViewBox(options) {
|
|
|
4722
5196
|
height: newHeight
|
|
4723
5197
|
});
|
|
4724
5198
|
}, [initialViewBox]);
|
|
4725
|
-
|
|
5199
|
+
useEffect7(() => {
|
|
4726
5200
|
if (!enableZoom || !svgRef.current) return;
|
|
4727
5201
|
const svg = svgRef.current;
|
|
4728
5202
|
const handleWheel = (e) => {
|
|
@@ -4755,7 +5229,7 @@ function useViewBox(options) {
|
|
|
4755
5229
|
svg.addEventListener("wheel", handleWheel, { passive: false });
|
|
4756
5230
|
return () => svg.removeEventListener("wheel", handleWheel);
|
|
4757
5231
|
}, [enableZoom, zoomSensitivity, minZoom, initialViewBox]);
|
|
4758
|
-
|
|
5232
|
+
useEffect7(() => {
|
|
4759
5233
|
if (!enablePan || !svgRef.current) return;
|
|
4760
5234
|
const svg = svgRef.current;
|
|
4761
5235
|
const handleMouseDown = (e) => {
|
|
@@ -4831,7 +5305,7 @@ function useViewBox(options) {
|
|
|
4831
5305
|
window.removeEventListener("keyup", handleKeyUp);
|
|
4832
5306
|
};
|
|
4833
5307
|
}, [enablePan, allowLeftClickPan]);
|
|
4834
|
-
|
|
5308
|
+
useEffect7(() => {
|
|
4835
5309
|
if (!svgRef.current) return;
|
|
4836
5310
|
if (!enablePan && !enableZoom) return;
|
|
4837
5311
|
const svg = svgRef.current;
|
|
@@ -4922,7 +5396,7 @@ function useViewBox(options) {
|
|
|
4922
5396
|
svg.removeEventListener("touchend", handleTouchEnd);
|
|
4923
5397
|
};
|
|
4924
5398
|
}, [enablePan, enableZoom, minZoom, initialViewBox]);
|
|
4925
|
-
const screenToWorld =
|
|
5399
|
+
const screenToWorld = useCallback4(
|
|
4926
5400
|
(screenX, screenY) => {
|
|
4927
5401
|
const svg = svgRef.current;
|
|
4928
5402
|
if (!svg) return { x: screenX, y: screenY };
|
|
@@ -4961,15 +5435,15 @@ function useViewBox(options) {
|
|
|
4961
5435
|
}
|
|
4962
5436
|
|
|
4963
5437
|
// src/diagram/hooks/useSelection.ts
|
|
4964
|
-
import { useState as
|
|
5438
|
+
import { useState as useState11, useCallback as useCallback5 } from "react";
|
|
4965
5439
|
function useSelection(options = {}) {
|
|
4966
5440
|
const {
|
|
4967
5441
|
multiSelect = true,
|
|
4968
5442
|
initialSelection = { selectedNodeIds: /* @__PURE__ */ new Set(), selectedPipeIds: /* @__PURE__ */ new Set() },
|
|
4969
5443
|
onSelectionChange
|
|
4970
5444
|
} = options;
|
|
4971
|
-
const [selection, setSelection] =
|
|
4972
|
-
const notifyChange =
|
|
5445
|
+
const [selection, setSelection] = useState11(initialSelection);
|
|
5446
|
+
const notifyChange = useCallback5(
|
|
4973
5447
|
(newSelection) => {
|
|
4974
5448
|
if (onSelectionChange) {
|
|
4975
5449
|
onSelectionChange(newSelection);
|
|
@@ -4977,15 +5451,15 @@ function useSelection(options = {}) {
|
|
|
4977
5451
|
},
|
|
4978
5452
|
[onSelectionChange]
|
|
4979
5453
|
);
|
|
4980
|
-
const isNodeSelected =
|
|
5454
|
+
const isNodeSelected = useCallback5(
|
|
4981
5455
|
(nodeId) => selection.selectedNodeIds.has(nodeId),
|
|
4982
5456
|
[selection.selectedNodeIds]
|
|
4983
5457
|
);
|
|
4984
|
-
const isPipeSelected =
|
|
5458
|
+
const isPipeSelected = useCallback5(
|
|
4985
5459
|
(pipeId) => selection.selectedPipeIds.has(pipeId),
|
|
4986
5460
|
[selection.selectedPipeIds]
|
|
4987
5461
|
);
|
|
4988
|
-
const selectNode =
|
|
5462
|
+
const selectNode = useCallback5(
|
|
4989
5463
|
(nodeId, isMultiSelect = false) => {
|
|
4990
5464
|
setSelection((prev) => {
|
|
4991
5465
|
const newNodeIds = new Set(isMultiSelect && multiSelect ? prev.selectedNodeIds : []);
|
|
@@ -5004,7 +5478,7 @@ function useSelection(options = {}) {
|
|
|
5004
5478
|
},
|
|
5005
5479
|
[multiSelect, notifyChange]
|
|
5006
5480
|
);
|
|
5007
|
-
const selectPipe =
|
|
5481
|
+
const selectPipe = useCallback5(
|
|
5008
5482
|
(pipeId, isMultiSelect = false) => {
|
|
5009
5483
|
setSelection((prev) => {
|
|
5010
5484
|
const newPipeIds = new Set(isMultiSelect && multiSelect ? prev.selectedPipeIds : []);
|
|
@@ -5023,7 +5497,7 @@ function useSelection(options = {}) {
|
|
|
5023
5497
|
},
|
|
5024
5498
|
[multiSelect, notifyChange]
|
|
5025
5499
|
);
|
|
5026
|
-
const clearSelection =
|
|
5500
|
+
const clearSelection = useCallback5(() => {
|
|
5027
5501
|
const newSelection = {
|
|
5028
5502
|
selectedNodeIds: /* @__PURE__ */ new Set(),
|
|
5029
5503
|
selectedPipeIds: /* @__PURE__ */ new Set()
|
|
@@ -5031,7 +5505,7 @@ function useSelection(options = {}) {
|
|
|
5031
5505
|
setSelection(newSelection);
|
|
5032
5506
|
notifyChange(newSelection);
|
|
5033
5507
|
}, [notifyChange]);
|
|
5034
|
-
const selectNodes =
|
|
5508
|
+
const selectNodes = useCallback5(
|
|
5035
5509
|
(nodeIds) => {
|
|
5036
5510
|
const newSelection = {
|
|
5037
5511
|
selectedNodeIds: new Set(nodeIds),
|
|
@@ -5042,7 +5516,7 @@ function useSelection(options = {}) {
|
|
|
5042
5516
|
},
|
|
5043
5517
|
[notifyChange]
|
|
5044
5518
|
);
|
|
5045
|
-
const selectPipes =
|
|
5519
|
+
const selectPipes = useCallback5(
|
|
5046
5520
|
(pipeIds) => {
|
|
5047
5521
|
const newSelection = {
|
|
5048
5522
|
selectedNodeIds: /* @__PURE__ */ new Set(),
|
|
@@ -5066,23 +5540,23 @@ function useSelection(options = {}) {
|
|
|
5066
5540
|
}
|
|
5067
5541
|
|
|
5068
5542
|
// src/diagram/hooks/useTelemetry.ts
|
|
5069
|
-
import { useState as
|
|
5543
|
+
import { useState as useState12, useCallback as useCallback6, useEffect as useEffect8, useRef as useRef4 } from "react";
|
|
5070
5544
|
function useTelemetry(options = {}) {
|
|
5071
5545
|
const {
|
|
5072
5546
|
initialBindings = [],
|
|
5073
5547
|
onTelemetryChange,
|
|
5074
5548
|
refreshInterval = 0
|
|
5075
5549
|
} = options;
|
|
5076
|
-
const [telemetry, setTelemetry] =
|
|
5550
|
+
const [telemetry, setTelemetry] = useState12(() => {
|
|
5077
5551
|
const map = /* @__PURE__ */ new Map();
|
|
5078
5552
|
initialBindings.forEach((binding) => {
|
|
5079
5553
|
map.set(binding.nodeId, binding);
|
|
5080
5554
|
});
|
|
5081
5555
|
return map;
|
|
5082
5556
|
});
|
|
5083
|
-
const telemetryRef =
|
|
5557
|
+
const telemetryRef = useRef4(telemetry);
|
|
5084
5558
|
telemetryRef.current = telemetry;
|
|
5085
|
-
const notifyChange =
|
|
5559
|
+
const notifyChange = useCallback6(
|
|
5086
5560
|
(newTelemetry) => {
|
|
5087
5561
|
if (onTelemetryChange) {
|
|
5088
5562
|
onTelemetryChange(newTelemetry);
|
|
@@ -5090,7 +5564,7 @@ function useTelemetry(options = {}) {
|
|
|
5090
5564
|
},
|
|
5091
5565
|
[onTelemetryChange]
|
|
5092
5566
|
);
|
|
5093
|
-
const updateTelemetry =
|
|
5567
|
+
const updateTelemetry = useCallback6(
|
|
5094
5568
|
(nodeId, value) => {
|
|
5095
5569
|
setTelemetry((prev) => {
|
|
5096
5570
|
const newMap = new Map(prev);
|
|
@@ -5120,7 +5594,7 @@ function useTelemetry(options = {}) {
|
|
|
5120
5594
|
},
|
|
5121
5595
|
[notifyChange]
|
|
5122
5596
|
);
|
|
5123
|
-
const updateTelemetryBatch =
|
|
5597
|
+
const updateTelemetryBatch = useCallback6(
|
|
5124
5598
|
(updates) => {
|
|
5125
5599
|
setTelemetry((prev) => {
|
|
5126
5600
|
const newMap = new Map(prev);
|
|
@@ -5174,16 +5648,16 @@ function useTelemetry(options = {}) {
|
|
|
5174
5648
|
},
|
|
5175
5649
|
[notifyChange]
|
|
5176
5650
|
);
|
|
5177
|
-
const getTelemetry =
|
|
5651
|
+
const getTelemetry = useCallback6(
|
|
5178
5652
|
(nodeId) => telemetryRef.current.get(nodeId),
|
|
5179
5653
|
[]
|
|
5180
5654
|
);
|
|
5181
|
-
const clearTelemetry =
|
|
5655
|
+
const clearTelemetry = useCallback6(() => {
|
|
5182
5656
|
const newMap = /* @__PURE__ */ new Map();
|
|
5183
5657
|
setTelemetry(newMap);
|
|
5184
5658
|
notifyChange(newMap);
|
|
5185
5659
|
}, [notifyChange]);
|
|
5186
|
-
const setBindings =
|
|
5660
|
+
const setBindings = useCallback6(
|
|
5187
5661
|
(bindings) => {
|
|
5188
5662
|
const newMap = /* @__PURE__ */ new Map();
|
|
5189
5663
|
bindings.forEach((binding) => {
|
|
@@ -5194,7 +5668,7 @@ function useTelemetry(options = {}) {
|
|
|
5194
5668
|
},
|
|
5195
5669
|
[notifyChange]
|
|
5196
5670
|
);
|
|
5197
|
-
|
|
5671
|
+
useEffect8(() => {
|
|
5198
5672
|
if (refreshInterval <= 0) return;
|
|
5199
5673
|
const intervalId = setInterval(() => {
|
|
5200
5674
|
notifyChange(telemetryRef.current);
|
|
@@ -5212,10 +5686,10 @@ function useTelemetry(options = {}) {
|
|
|
5212
5686
|
}
|
|
5213
5687
|
|
|
5214
5688
|
// src/diagram/hooks/useTelemetryStatus.ts
|
|
5215
|
-
import { useEffect as
|
|
5689
|
+
import { useEffect as useEffect9 } from "react";
|
|
5216
5690
|
function useTelemetryStatus(telemetry, diagram, setDiagram, options = {}) {
|
|
5217
5691
|
const { enabled = true, mapStatus } = options;
|
|
5218
|
-
|
|
5692
|
+
useEffect9(() => {
|
|
5219
5693
|
if (!enabled) return;
|
|
5220
5694
|
const defaultMapStatus = (telemetryStatus) => {
|
|
5221
5695
|
switch (telemetryStatus) {
|
|
@@ -5254,7 +5728,7 @@ function useTelemetryStatus(telemetry, diagram, setDiagram, options = {}) {
|
|
|
5254
5728
|
}
|
|
5255
5729
|
|
|
5256
5730
|
// src/diagram/hooks/useDrag.ts
|
|
5257
|
-
import { useState as
|
|
5731
|
+
import { useState as useState13, useCallback as useCallback7, useRef as useRef5, useEffect as useEffect10 } from "react";
|
|
5258
5732
|
function useDrag(options = {}) {
|
|
5259
5733
|
const {
|
|
5260
5734
|
onDragStart,
|
|
@@ -5264,23 +5738,23 @@ function useDrag(options = {}) {
|
|
|
5264
5738
|
dragThreshold = 3,
|
|
5265
5739
|
screenToWorld = (x, y) => ({ x, y })
|
|
5266
5740
|
} = options;
|
|
5267
|
-
const [dragState, setDragState] =
|
|
5741
|
+
const [dragState, setDragState] = useState13({
|
|
5268
5742
|
isDragging: false,
|
|
5269
5743
|
startPosition: null,
|
|
5270
5744
|
offset: { x: 0, y: 0 },
|
|
5271
5745
|
draggedId: null
|
|
5272
5746
|
});
|
|
5273
|
-
const [isListening, setIsListening] =
|
|
5274
|
-
const dragStartRef =
|
|
5275
|
-
const hasMovedRef =
|
|
5276
|
-
const applySnap =
|
|
5747
|
+
const [isListening, setIsListening] = useState13(false);
|
|
5748
|
+
const dragStartRef = useRef5(null);
|
|
5749
|
+
const hasMovedRef = useRef5(false);
|
|
5750
|
+
const applySnap = useCallback7(
|
|
5277
5751
|
(value) => {
|
|
5278
5752
|
if (snapToGrid <= 0) return value;
|
|
5279
5753
|
return Math.round(value / snapToGrid) * snapToGrid;
|
|
5280
5754
|
},
|
|
5281
5755
|
[snapToGrid]
|
|
5282
5756
|
);
|
|
5283
|
-
const handleMouseMove =
|
|
5757
|
+
const handleMouseMove = useCallback7(
|
|
5284
5758
|
(event) => {
|
|
5285
5759
|
if (!dragStartRef.current) return;
|
|
5286
5760
|
const { id, screenStart: _screenStart, itemPosition, clickOffset } = dragStartRef.current;
|
|
@@ -5321,7 +5795,7 @@ function useDrag(options = {}) {
|
|
|
5321
5795
|
},
|
|
5322
5796
|
[screenToWorld, dragThreshold, applySnap, onDragStart, onDragMove]
|
|
5323
5797
|
);
|
|
5324
|
-
const handleMouseUp =
|
|
5798
|
+
const handleMouseUp = useCallback7(
|
|
5325
5799
|
(event) => {
|
|
5326
5800
|
if (!dragStartRef.current || !hasMovedRef.current) {
|
|
5327
5801
|
dragStartRef.current = null;
|
|
@@ -5358,7 +5832,7 @@ function useDrag(options = {}) {
|
|
|
5358
5832
|
},
|
|
5359
5833
|
[screenToWorld, applySnap, onDragEnd]
|
|
5360
5834
|
);
|
|
5361
|
-
const handleTouchMove =
|
|
5835
|
+
const handleTouchMove = useCallback7(
|
|
5362
5836
|
(event) => {
|
|
5363
5837
|
if (!dragStartRef.current || event.touches.length !== 1) return;
|
|
5364
5838
|
const touch = event.touches[0];
|
|
@@ -5401,7 +5875,7 @@ function useDrag(options = {}) {
|
|
|
5401
5875
|
},
|
|
5402
5876
|
[screenToWorld, dragThreshold, applySnap, onDragStart, onDragMove]
|
|
5403
5877
|
);
|
|
5404
|
-
const handleTouchEnd =
|
|
5878
|
+
const handleTouchEnd = useCallback7(
|
|
5405
5879
|
(event) => {
|
|
5406
5880
|
if (!dragStartRef.current || !hasMovedRef.current) {
|
|
5407
5881
|
dragStartRef.current = null;
|
|
@@ -5439,7 +5913,7 @@ function useDrag(options = {}) {
|
|
|
5439
5913
|
},
|
|
5440
5914
|
[screenToWorld, applySnap, onDragEnd]
|
|
5441
5915
|
);
|
|
5442
|
-
|
|
5916
|
+
useEffect10(() => {
|
|
5443
5917
|
if (!isListening) return;
|
|
5444
5918
|
document.addEventListener("mousemove", handleMouseMove);
|
|
5445
5919
|
document.addEventListener("mouseup", handleMouseUp);
|
|
@@ -5454,7 +5928,7 @@ function useDrag(options = {}) {
|
|
|
5454
5928
|
document.removeEventListener("touchcancel", handleTouchEnd);
|
|
5455
5929
|
};
|
|
5456
5930
|
}, [isListening, handleMouseMove, handleMouseUp, handleTouchMove, handleTouchEnd]);
|
|
5457
|
-
const startDrag =
|
|
5931
|
+
const startDrag = useCallback7(
|
|
5458
5932
|
(id, event, itemPosition) => {
|
|
5459
5933
|
event.stopPropagation();
|
|
5460
5934
|
let clientX;
|
|
@@ -5484,7 +5958,7 @@ function useDrag(options = {}) {
|
|
|
5484
5958
|
},
|
|
5485
5959
|
[screenToWorld]
|
|
5486
5960
|
);
|
|
5487
|
-
const cancelDrag =
|
|
5961
|
+
const cancelDrag = useCallback7(() => {
|
|
5488
5962
|
dragStartRef.current = null;
|
|
5489
5963
|
hasMovedRef.current = false;
|
|
5490
5964
|
setIsListening(false);
|
|
@@ -5495,7 +5969,7 @@ function useDrag(options = {}) {
|
|
|
5495
5969
|
draggedId: null
|
|
5496
5970
|
});
|
|
5497
5971
|
}, []);
|
|
5498
|
-
const isDraggingItem =
|
|
5972
|
+
const isDraggingItem = useCallback7(
|
|
5499
5973
|
(id) => dragState.isDragging && dragState.draggedId === id,
|
|
5500
5974
|
[dragState.isDragging, dragState.draggedId]
|
|
5501
5975
|
);
|
|
@@ -5508,7 +5982,7 @@ function useDrag(options = {}) {
|
|
|
5508
5982
|
}
|
|
5509
5983
|
|
|
5510
5984
|
// src/diagram/hooks/useKeyboardShortcuts.ts
|
|
5511
|
-
import { useEffect as
|
|
5985
|
+
import { useEffect as useEffect11 } from "react";
|
|
5512
5986
|
function useKeyboardShortcuts(options) {
|
|
5513
5987
|
const {
|
|
5514
5988
|
onDelete,
|
|
@@ -5519,7 +5993,7 @@ function useKeyboardShortcuts(options) {
|
|
|
5519
5993
|
onSelectAll,
|
|
5520
5994
|
enabled = true
|
|
5521
5995
|
} = options;
|
|
5522
|
-
|
|
5996
|
+
useEffect11(() => {
|
|
5523
5997
|
if (!enabled) return;
|
|
5524
5998
|
const handleKeyDown = (event) => {
|
|
5525
5999
|
const target = event.target;
|
|
@@ -5628,7 +6102,7 @@ function nodeHasPort(node, portId) {
|
|
|
5628
6102
|
}
|
|
5629
6103
|
|
|
5630
6104
|
// src/components/PIDCanvas/PIDCanvas.tsx
|
|
5631
|
-
import { Fragment as Fragment7, jsx as
|
|
6105
|
+
import { Fragment as Fragment7, jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
5632
6106
|
function PIDCanvas({
|
|
5633
6107
|
diagram,
|
|
5634
6108
|
className = "",
|
|
@@ -5656,21 +6130,21 @@ function PIDCanvas({
|
|
|
5656
6130
|
statusColorMap,
|
|
5657
6131
|
...props
|
|
5658
6132
|
}) {
|
|
5659
|
-
const [localDiagram, setLocalDiagram] =
|
|
5660
|
-
const [dragOverPosition, setDragOverPosition] =
|
|
5661
|
-
const [isConnecting, setIsConnecting] =
|
|
5662
|
-
const [connectionSource, setConnectionSource] =
|
|
5663
|
-
const [connectionSourcePort, setConnectionSourcePort] =
|
|
5664
|
-
const [connectionCursor, setConnectionCursor] =
|
|
5665
|
-
const [hoveredNode, setHoveredNode] =
|
|
5666
|
-
const [hoveredPort, setHoveredPort] =
|
|
5667
|
-
const [selectedWaypoint, setSelectedWaypoint] =
|
|
5668
|
-
const historyStack =
|
|
5669
|
-
const redoStack =
|
|
5670
|
-
const isUndoRedoAction =
|
|
5671
|
-
const isInternalChange =
|
|
5672
|
-
const lastInternalDiagram =
|
|
5673
|
-
|
|
6133
|
+
const [localDiagram, setLocalDiagram] = useState14(diagram);
|
|
6134
|
+
const [dragOverPosition, setDragOverPosition] = useState14(null);
|
|
6135
|
+
const [isConnecting, setIsConnecting] = useState14(false);
|
|
6136
|
+
const [connectionSource, setConnectionSource] = useState14(null);
|
|
6137
|
+
const [connectionSourcePort, setConnectionSourcePort] = useState14(null);
|
|
6138
|
+
const [connectionCursor, setConnectionCursor] = useState14(null);
|
|
6139
|
+
const [hoveredNode, setHoveredNode] = useState14(null);
|
|
6140
|
+
const [hoveredPort, setHoveredPort] = useState14(null);
|
|
6141
|
+
const [selectedWaypoint, setSelectedWaypoint] = useState14(null);
|
|
6142
|
+
const historyStack = useRef6([]);
|
|
6143
|
+
const redoStack = useRef6([]);
|
|
6144
|
+
const isUndoRedoAction = useRef6(false);
|
|
6145
|
+
const isInternalChange = useRef6(false);
|
|
6146
|
+
const lastInternalDiagram = useRef6(null);
|
|
6147
|
+
useEffect12(() => {
|
|
5674
6148
|
const isExternal = !isInternalChange.current && diagram !== lastInternalDiagram.current;
|
|
5675
6149
|
if (isExternal) {
|
|
5676
6150
|
setLocalDiagram(diagram);
|
|
@@ -5692,7 +6166,7 @@ function PIDCanvas({
|
|
|
5692
6166
|
enablePan: features.pan ?? true,
|
|
5693
6167
|
enableZoom: features.zoom ?? true
|
|
5694
6168
|
});
|
|
5695
|
-
const calculateContentBounds =
|
|
6169
|
+
const calculateContentBounds = useCallback8(() => {
|
|
5696
6170
|
const nodes2 = localDiagram.nodes.filter((n) => n.visible !== false);
|
|
5697
6171
|
if (nodes2.length === 0) {
|
|
5698
6172
|
return null;
|
|
@@ -5715,7 +6189,7 @@ function PIDCanvas({
|
|
|
5715
6189
|
});
|
|
5716
6190
|
return { minX, minY, maxX, maxY };
|
|
5717
6191
|
}, [localDiagram.nodes]);
|
|
5718
|
-
|
|
6192
|
+
useEffect12(() => {
|
|
5719
6193
|
if (onMounted) {
|
|
5720
6194
|
const controls = {
|
|
5721
6195
|
fitToContent: (padding = 50) => {
|
|
@@ -5756,8 +6230,8 @@ function PIDCanvas({
|
|
|
5756
6230
|
});
|
|
5757
6231
|
const dragEnabled = features.dragNodes ?? false;
|
|
5758
6232
|
const selectionEnabled = features.selection ?? false;
|
|
5759
|
-
const containerRef =
|
|
5760
|
-
const pushToHistory =
|
|
6233
|
+
const containerRef = useRef6(null);
|
|
6234
|
+
const pushToHistory = useCallback8((currentDiagram) => {
|
|
5761
6235
|
if (isUndoRedoAction.current) return;
|
|
5762
6236
|
const snapshot = JSON.parse(JSON.stringify(currentDiagram));
|
|
5763
6237
|
historyStack.current.push(snapshot);
|
|
@@ -5766,7 +6240,7 @@ function PIDCanvas({
|
|
|
5766
6240
|
}
|
|
5767
6241
|
redoStack.current = [];
|
|
5768
6242
|
}, []);
|
|
5769
|
-
const undo =
|
|
6243
|
+
const undo = useCallback8(() => {
|
|
5770
6244
|
if (historyStack.current.length === 0) return;
|
|
5771
6245
|
isUndoRedoAction.current = true;
|
|
5772
6246
|
const currentSnapshot = JSON.parse(JSON.stringify(localDiagram));
|
|
@@ -5780,7 +6254,7 @@ function PIDCanvas({
|
|
|
5780
6254
|
isUndoRedoAction.current = false;
|
|
5781
6255
|
}, 0);
|
|
5782
6256
|
}, [localDiagram, onDiagramChange]);
|
|
5783
|
-
const redo =
|
|
6257
|
+
const redo = useCallback8(() => {
|
|
5784
6258
|
if (redoStack.current.length === 0) return;
|
|
5785
6259
|
isUndoRedoAction.current = true;
|
|
5786
6260
|
const currentSnapshot = JSON.parse(JSON.stringify(localDiagram));
|
|
@@ -5794,7 +6268,7 @@ function PIDCanvas({
|
|
|
5794
6268
|
isUndoRedoAction.current = false;
|
|
5795
6269
|
}, 0);
|
|
5796
6270
|
}, [localDiagram, onDiagramChange]);
|
|
5797
|
-
|
|
6271
|
+
useEffect12(() => {
|
|
5798
6272
|
const handleKeyDown = (e) => {
|
|
5799
6273
|
const isCtrlOrCmd = e.ctrlKey || e.metaKey;
|
|
5800
6274
|
if (isCtrlOrCmd && e.key === "z" && !e.shiftKey) {
|
|
@@ -5811,7 +6285,7 @@ function PIDCanvas({
|
|
|
5811
6285
|
window.addEventListener("keydown", handleKeyDown);
|
|
5812
6286
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
5813
6287
|
}, [undo, redo]);
|
|
5814
|
-
|
|
6288
|
+
useEffect12(() => {
|
|
5815
6289
|
if (!features.dragNodes) return;
|
|
5816
6290
|
const handleKeyDown = (e) => {
|
|
5817
6291
|
if (selection.selectedNodeIds.size === 0 && !selectedWaypoint) return;
|
|
@@ -5896,7 +6370,7 @@ function PIDCanvas({
|
|
|
5896
6370
|
onNodeMove,
|
|
5897
6371
|
pushToHistory
|
|
5898
6372
|
]);
|
|
5899
|
-
const handlePositionChange =
|
|
6373
|
+
const handlePositionChange = useCallback8(
|
|
5900
6374
|
(nodeId, x, y) => {
|
|
5901
6375
|
pushToHistory(localDiagram);
|
|
5902
6376
|
const updatedNodes = localDiagram.nodes.map(
|
|
@@ -5918,7 +6392,7 @@ function PIDCanvas({
|
|
|
5918
6392
|
},
|
|
5919
6393
|
[localDiagram, onDiagramChange, onNodeMove, pushToHistory]
|
|
5920
6394
|
);
|
|
5921
|
-
const handleWaypointPositionChange =
|
|
6395
|
+
const handleWaypointPositionChange = useCallback8(
|
|
5922
6396
|
(pipeId, pointIndex, x, y) => {
|
|
5923
6397
|
pushToHistory(localDiagram);
|
|
5924
6398
|
const updatedPipes = localDiagram.pipes.map((pipe) => {
|
|
@@ -5936,7 +6410,7 @@ function PIDCanvas({
|
|
|
5936
6410
|
},
|
|
5937
6411
|
[localDiagram, onDiagramChange, pushToHistory]
|
|
5938
6412
|
);
|
|
5939
|
-
const handleDragEnd =
|
|
6413
|
+
const handleDragEnd = useCallback8(
|
|
5940
6414
|
(nodeId, offset, finalPosition) => {
|
|
5941
6415
|
const dragDistance = Math.sqrt(offset.x ** 2 + offset.y ** 2);
|
|
5942
6416
|
if (dragDistance < 2) {
|
|
@@ -6017,7 +6491,7 @@ function PIDCanvas({
|
|
|
6017
6491
|
onDiagramChange?.(updatedDiagram);
|
|
6018
6492
|
}
|
|
6019
6493
|
});
|
|
6020
|
-
const handleNodeDragStart =
|
|
6494
|
+
const handleNodeDragStart = useCallback8(
|
|
6021
6495
|
(nodeId, event) => {
|
|
6022
6496
|
const node = localDiagram.nodes.find((n) => n.id === nodeId);
|
|
6023
6497
|
if (!node) return;
|
|
@@ -6025,7 +6499,7 @@ function PIDCanvas({
|
|
|
6025
6499
|
},
|
|
6026
6500
|
[localDiagram.nodes, startDrag]
|
|
6027
6501
|
);
|
|
6028
|
-
const handleWaypointClick =
|
|
6502
|
+
const handleWaypointClick = useCallback8(
|
|
6029
6503
|
(pipeId, pointIndex) => {
|
|
6030
6504
|
setSelectedWaypoint({ pipeId, pointIndex });
|
|
6031
6505
|
if (selectionEnabled) {
|
|
@@ -6034,7 +6508,7 @@ function PIDCanvas({
|
|
|
6034
6508
|
},
|
|
6035
6509
|
[selectionEnabled, clearSelection]
|
|
6036
6510
|
);
|
|
6037
|
-
const handleWaypointDragStart =
|
|
6511
|
+
const handleWaypointDragStart = useCallback8(
|
|
6038
6512
|
(pipeId, pointIndex, event) => {
|
|
6039
6513
|
const pipe = localDiagram.pipes.find((p) => p.id === pipeId);
|
|
6040
6514
|
if (!pipe || pointIndex >= pipe.routePoints.length) return;
|
|
@@ -6043,7 +6517,7 @@ function PIDCanvas({
|
|
|
6043
6517
|
},
|
|
6044
6518
|
[localDiagram.pipes, startWaypointDrag]
|
|
6045
6519
|
);
|
|
6046
|
-
const handlePipeSegmentClick =
|
|
6520
|
+
const handlePipeSegmentClick = useCallback8(
|
|
6047
6521
|
(pipeId, position, segmentIndex) => {
|
|
6048
6522
|
pushToHistory(localDiagram);
|
|
6049
6523
|
const updatedPipes = localDiagram.pipes.map((pipe) => {
|
|
@@ -6062,7 +6536,7 @@ function PIDCanvas({
|
|
|
6062
6536
|
[localDiagram, onDiagramChange, pushToHistory]
|
|
6063
6537
|
);
|
|
6064
6538
|
const telemetryEnabled = features.telemetry ?? false;
|
|
6065
|
-
const handleDelete =
|
|
6539
|
+
const handleDelete = useCallback8(() => {
|
|
6066
6540
|
if (!selectionEnabled) return;
|
|
6067
6541
|
const { selectedNodeIds, selectedPipeIds } = selection;
|
|
6068
6542
|
if (selectedNodeIds.size === 0 && selectedPipeIds.size === 0) return;
|
|
@@ -6091,13 +6565,13 @@ function PIDCanvas({
|
|
|
6091
6565
|
onDelete,
|
|
6092
6566
|
pushToHistory
|
|
6093
6567
|
]);
|
|
6094
|
-
const handleCopy =
|
|
6568
|
+
const handleCopy = useCallback8(() => {
|
|
6095
6569
|
if (!selectionEnabled) return;
|
|
6096
6570
|
const { selectedNodeIds, selectedPipeIds } = selection;
|
|
6097
6571
|
if (selectedNodeIds.size === 0 && selectedPipeIds.size === 0) return;
|
|
6098
6572
|
onItemsCopied?.(Array.from(selectedNodeIds), Array.from(selectedPipeIds));
|
|
6099
6573
|
}, [selection, selectionEnabled, onItemsCopied]);
|
|
6100
|
-
const handlePaste =
|
|
6574
|
+
const handlePaste = useCallback8(() => {
|
|
6101
6575
|
if (!selectionEnabled) return;
|
|
6102
6576
|
onPaste?.();
|
|
6103
6577
|
}, [selectionEnabled, onPaste]);
|
|
@@ -6157,7 +6631,7 @@ function PIDCanvas({
|
|
|
6157
6631
|
}
|
|
6158
6632
|
setSelectedWaypoint(null);
|
|
6159
6633
|
};
|
|
6160
|
-
const handleDragOver =
|
|
6634
|
+
const handleDragOver = useCallback8(
|
|
6161
6635
|
(event) => {
|
|
6162
6636
|
if (!features.allowSymbolDrop) return;
|
|
6163
6637
|
event.preventDefault();
|
|
@@ -6168,7 +6642,7 @@ function PIDCanvas({
|
|
|
6168
6642
|
},
|
|
6169
6643
|
[features.allowSymbolDrop, screenToWorld, svgRef]
|
|
6170
6644
|
);
|
|
6171
|
-
const handleDrop =
|
|
6645
|
+
const handleDrop = useCallback8(
|
|
6172
6646
|
(event) => {
|
|
6173
6647
|
if (!features.allowSymbolDrop) return;
|
|
6174
6648
|
event.preventDefault();
|
|
@@ -6181,10 +6655,10 @@ function PIDCanvas({
|
|
|
6181
6655
|
},
|
|
6182
6656
|
[features.allowSymbolDrop, screenToWorld, onSymbolDrop, svgRef]
|
|
6183
6657
|
);
|
|
6184
|
-
const handleDragLeave =
|
|
6658
|
+
const handleDragLeave = useCallback8(() => {
|
|
6185
6659
|
setDragOverPosition(null);
|
|
6186
6660
|
}, []);
|
|
6187
|
-
const handleMouseMove =
|
|
6661
|
+
const handleMouseMove = useCallback8(
|
|
6188
6662
|
(event) => {
|
|
6189
6663
|
const connectionModeEnabled = features.connectionMode ?? false;
|
|
6190
6664
|
if (connectionModeEnabled) {
|
|
@@ -6221,7 +6695,7 @@ function PIDCanvas({
|
|
|
6221
6695
|
const viewBox = controlledViewBox;
|
|
6222
6696
|
const displayDiagram = localDiagram;
|
|
6223
6697
|
const selectedNode = selectionEnabled && selection.selectedNodeIds.size === 1 ? localDiagram.nodes.find((n) => selection.selectedNodeIds.has(n.id)) || null : null;
|
|
6224
|
-
return /* @__PURE__ */
|
|
6698
|
+
return /* @__PURE__ */ jsxs16(
|
|
6225
6699
|
"div",
|
|
6226
6700
|
{
|
|
6227
6701
|
ref: containerRef,
|
|
@@ -6236,7 +6710,7 @@ function PIDCanvas({
|
|
|
6236
6710
|
},
|
|
6237
6711
|
...props,
|
|
6238
6712
|
children: [
|
|
6239
|
-
/* @__PURE__ */
|
|
6713
|
+
/* @__PURE__ */ jsxs16(
|
|
6240
6714
|
"svg",
|
|
6241
6715
|
{
|
|
6242
6716
|
ref: svgRef,
|
|
@@ -6255,15 +6729,15 @@ function PIDCanvas({
|
|
|
6255
6729
|
onDrop: handleDrop,
|
|
6256
6730
|
onDragLeave: handleDragLeave,
|
|
6257
6731
|
children: [
|
|
6258
|
-
features.showGrid !== false ? /* @__PURE__ */
|
|
6259
|
-
/* @__PURE__ */
|
|
6260
|
-
/* @__PURE__ */
|
|
6261
|
-
/* @__PURE__ */
|
|
6262
|
-
/* @__PURE__ */
|
|
6263
|
-
/* @__PURE__ */
|
|
6732
|
+
features.showGrid !== false ? /* @__PURE__ */ jsxs16(Fragment7, { children: [
|
|
6733
|
+
/* @__PURE__ */ jsxs16("defs", { children: [
|
|
6734
|
+
/* @__PURE__ */ jsx20("pattern", { id: "grid-minor", width: "5", height: "5", patternUnits: "userSpaceOnUse", children: /* @__PURE__ */ jsx20("path", { d: "M 5 0 L 0 0 0 5", fill: "none", stroke: "#e5e7eb", strokeWidth: "0.5" }) }),
|
|
6735
|
+
/* @__PURE__ */ jsxs16("pattern", { id: "grid-major", width: "25", height: "25", patternUnits: "userSpaceOnUse", children: [
|
|
6736
|
+
/* @__PURE__ */ jsx20("rect", { width: "25", height: "25", fill: "url(#grid-minor)" }),
|
|
6737
|
+
/* @__PURE__ */ jsx20("path", { d: "M 25 0 L 0 0 0 25", fill: "none", stroke: "#d1d5db", strokeWidth: "1" })
|
|
6264
6738
|
] })
|
|
6265
6739
|
] }),
|
|
6266
|
-
/* @__PURE__ */
|
|
6740
|
+
/* @__PURE__ */ jsx20(
|
|
6267
6741
|
"rect",
|
|
6268
6742
|
{
|
|
6269
6743
|
x: Math.floor(viewBox.x / 25) * 25 - viewBox.width,
|
|
@@ -6273,7 +6747,7 @@ function PIDCanvas({
|
|
|
6273
6747
|
fill: "url(#grid-major)"
|
|
6274
6748
|
}
|
|
6275
6749
|
)
|
|
6276
|
-
] }) : /* @__PURE__ */
|
|
6750
|
+
] }) : /* @__PURE__ */ jsx20(
|
|
6277
6751
|
"rect",
|
|
6278
6752
|
{
|
|
6279
6753
|
x: Math.floor(viewBox.x / 25) * 25 - viewBox.width,
|
|
@@ -6283,7 +6757,7 @@ function PIDCanvas({
|
|
|
6283
6757
|
fill: features.backgroundColor ?? "#ffffff"
|
|
6284
6758
|
}
|
|
6285
6759
|
),
|
|
6286
|
-
/* @__PURE__ */
|
|
6760
|
+
/* @__PURE__ */ jsx20(
|
|
6287
6761
|
PipeRenderer,
|
|
6288
6762
|
{
|
|
6289
6763
|
pipes: displayDiagram.pipes,
|
|
@@ -6297,7 +6771,7 @@ function PIDCanvas({
|
|
|
6297
6771
|
onPipeSegmentClick: void 0
|
|
6298
6772
|
}
|
|
6299
6773
|
),
|
|
6300
|
-
/* @__PURE__ */
|
|
6774
|
+
/* @__PURE__ */ jsx20(
|
|
6301
6775
|
NodeRenderer,
|
|
6302
6776
|
{
|
|
6303
6777
|
nodes: displayDiagram.nodes,
|
|
@@ -6311,7 +6785,7 @@ function PIDCanvas({
|
|
|
6311
6785
|
statusColorMap
|
|
6312
6786
|
}
|
|
6313
6787
|
),
|
|
6314
|
-
(features.editPipeRoutes ?? false) && /* @__PURE__ */
|
|
6788
|
+
(features.editPipeRoutes ?? false) && /* @__PURE__ */ jsx20(
|
|
6315
6789
|
PipeRenderer,
|
|
6316
6790
|
{
|
|
6317
6791
|
pipes: displayDiagram.pipes,
|
|
@@ -6328,14 +6802,14 @@ function PIDCanvas({
|
|
|
6328
6802
|
onPipeSegmentClick: handlePipeSegmentClick
|
|
6329
6803
|
}
|
|
6330
6804
|
),
|
|
6331
|
-
telemetryEnabled && telemetry && /* @__PURE__ */
|
|
6805
|
+
telemetryEnabled && telemetry && /* @__PURE__ */ jsx20("g", { id: "layer-telemetry", children: displayDiagram.nodes.map((node) => {
|
|
6332
6806
|
const binding = telemetry.get(node.id);
|
|
6333
6807
|
if (!binding) return null;
|
|
6334
6808
|
const symbol = getSymbolDefinition(node.symbolId);
|
|
6335
6809
|
if (!symbol) return null;
|
|
6336
6810
|
const overlayX = node.transform.x + symbol.viewBox.width / 2;
|
|
6337
6811
|
const overlayY = node.transform.y + symbol.viewBox.height + 50;
|
|
6338
|
-
return /* @__PURE__ */
|
|
6812
|
+
return /* @__PURE__ */ jsx20(
|
|
6339
6813
|
DataOverlay,
|
|
6340
6814
|
{
|
|
6341
6815
|
nodeId: node.id,
|
|
@@ -6348,7 +6822,7 @@ function PIDCanvas({
|
|
|
6348
6822
|
`telemetry-${node.id}`
|
|
6349
6823
|
);
|
|
6350
6824
|
}) }),
|
|
6351
|
-
dragOverPosition && /* @__PURE__ */
|
|
6825
|
+
dragOverPosition && /* @__PURE__ */ jsx20(
|
|
6352
6826
|
"circle",
|
|
6353
6827
|
{
|
|
6354
6828
|
cx: dragOverPosition.x,
|
|
@@ -6361,7 +6835,7 @@ function PIDCanvas({
|
|
|
6361
6835
|
pointerEvents: "none"
|
|
6362
6836
|
}
|
|
6363
6837
|
),
|
|
6364
|
-
isConnecting && connectionSource && connectionCursor && /* @__PURE__ */
|
|
6838
|
+
isConnecting && connectionSource && connectionCursor && /* @__PURE__ */ jsx20("g", { id: "connection-preview", pointerEvents: "none", children: (() => {
|
|
6365
6839
|
const sourceNode = displayDiagram.nodes.find((n) => n.id === connectionSource);
|
|
6366
6840
|
if (!sourceNode) return null;
|
|
6367
6841
|
const symbol = getSymbolDefinition(sourceNode.symbolId);
|
|
@@ -6377,8 +6851,8 @@ function PIDCanvas({
|
|
|
6377
6851
|
}
|
|
6378
6852
|
}
|
|
6379
6853
|
}
|
|
6380
|
-
return /* @__PURE__ */
|
|
6381
|
-
/* @__PURE__ */
|
|
6854
|
+
return /* @__PURE__ */ jsxs16(Fragment7, { children: [
|
|
6855
|
+
/* @__PURE__ */ jsx20(
|
|
6382
6856
|
"circle",
|
|
6383
6857
|
{
|
|
6384
6858
|
cx: lineStartX,
|
|
@@ -6390,7 +6864,7 @@ function PIDCanvas({
|
|
|
6390
6864
|
opacity: 0.6
|
|
6391
6865
|
}
|
|
6392
6866
|
),
|
|
6393
|
-
/* @__PURE__ */
|
|
6867
|
+
/* @__PURE__ */ jsx20(
|
|
6394
6868
|
"line",
|
|
6395
6869
|
{
|
|
6396
6870
|
x1: lineStartX,
|
|
@@ -6403,7 +6877,7 @@ function PIDCanvas({
|
|
|
6403
6877
|
opacity: 0.8
|
|
6404
6878
|
}
|
|
6405
6879
|
),
|
|
6406
|
-
/* @__PURE__ */
|
|
6880
|
+
/* @__PURE__ */ jsx20(
|
|
6407
6881
|
"circle",
|
|
6408
6882
|
{
|
|
6409
6883
|
cx: connectionCursor.x,
|
|
@@ -6415,7 +6889,7 @@ function PIDCanvas({
|
|
|
6415
6889
|
)
|
|
6416
6890
|
] });
|
|
6417
6891
|
})() }),
|
|
6418
|
-
features.connectionMode && /* @__PURE__ */
|
|
6892
|
+
features.connectionMode && /* @__PURE__ */ jsx20("g", { id: "port-indicators", children: displayDiagram.nodes.map((node) => {
|
|
6419
6893
|
const symbol = getSymbolDefinition(node.symbolId);
|
|
6420
6894
|
if (!symbol?.ports) return null;
|
|
6421
6895
|
return symbol.ports.map((port) => {
|
|
@@ -6423,8 +6897,8 @@ function PIDCanvas({
|
|
|
6423
6897
|
if (!portPos) return null;
|
|
6424
6898
|
const isHovered = hoveredPort === port.id && hoveredNode === node.id;
|
|
6425
6899
|
const isSourcePort = node.id === connectionSource && port.id === connectionSourcePort;
|
|
6426
|
-
return /* @__PURE__ */
|
|
6427
|
-
/* @__PURE__ */
|
|
6900
|
+
return /* @__PURE__ */ jsxs16("g", { children: [
|
|
6901
|
+
/* @__PURE__ */ jsx20(
|
|
6428
6902
|
"circle",
|
|
6429
6903
|
{
|
|
6430
6904
|
cx: portPos.x,
|
|
@@ -6457,7 +6931,7 @@ function PIDCanvas({
|
|
|
6457
6931
|
}
|
|
6458
6932
|
}
|
|
6459
6933
|
),
|
|
6460
|
-
/* @__PURE__ */
|
|
6934
|
+
/* @__PURE__ */ jsx20(
|
|
6461
6935
|
"circle",
|
|
6462
6936
|
{
|
|
6463
6937
|
cx: portPos.x,
|
|
@@ -6476,7 +6950,7 @@ function PIDCanvas({
|
|
|
6476
6950
|
]
|
|
6477
6951
|
}
|
|
6478
6952
|
),
|
|
6479
|
-
features.dragNodes && /* @__PURE__ */
|
|
6953
|
+
features.dragNodes && /* @__PURE__ */ jsx20(
|
|
6480
6954
|
PositionPanel,
|
|
6481
6955
|
{
|
|
6482
6956
|
selectedNode,
|
|
@@ -6496,16 +6970,16 @@ function PIDCanvas({
|
|
|
6496
6970
|
}
|
|
6497
6971
|
|
|
6498
6972
|
// src/components/SymbolLibrary/SymbolLibrary.tsx
|
|
6499
|
-
import { useState as
|
|
6500
|
-
import { jsx as
|
|
6973
|
+
import { useState as useState15 } from "react";
|
|
6974
|
+
import { jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
6501
6975
|
function SymbolLibrary({
|
|
6502
6976
|
className = "",
|
|
6503
6977
|
onSymbolDragStart,
|
|
6504
6978
|
showCategories = true,
|
|
6505
6979
|
categories = ["Valves", "Pumps", "Tanks", "Instruments", "Displays"]
|
|
6506
6980
|
}) {
|
|
6507
|
-
const [selectedCategory, setSelectedCategory] =
|
|
6508
|
-
const [searchQuery, setSearchQuery] =
|
|
6981
|
+
const [selectedCategory, setSelectedCategory] = useState15("all");
|
|
6982
|
+
const [searchQuery, setSearchQuery] = useState15("");
|
|
6509
6983
|
const symbolIds = getAvailableSymbols();
|
|
6510
6984
|
const allSymbols = symbolIds.map((id) => getSymbolDefinition(id)).filter((symbol) => symbol !== void 0);
|
|
6511
6985
|
const categoryMap = {
|
|
@@ -6526,9 +7000,9 @@ function SymbolLibrary({
|
|
|
6526
7000
|
event.dataTransfer.effectAllowed = "copy";
|
|
6527
7001
|
onSymbolDragStart?.(symbol.id, event);
|
|
6528
7002
|
};
|
|
6529
|
-
return /* @__PURE__ */
|
|
6530
|
-
/* @__PURE__ */
|
|
6531
|
-
/* @__PURE__ */
|
|
7003
|
+
return /* @__PURE__ */ jsxs17("div", { className: `symbol-library ${className}`.trim(), style: styles.container, children: [
|
|
7004
|
+
/* @__PURE__ */ jsx21("div", { style: styles.header, children: /* @__PURE__ */ jsx21("h3", { style: styles.title, children: "Symbol Library" }) }),
|
|
7005
|
+
/* @__PURE__ */ jsx21("div", { style: styles.searchContainer, children: /* @__PURE__ */ jsx21(
|
|
6532
7006
|
"input",
|
|
6533
7007
|
{
|
|
6534
7008
|
type: "text",
|
|
@@ -6538,8 +7012,8 @@ function SymbolLibrary({
|
|
|
6538
7012
|
style: styles.searchInput
|
|
6539
7013
|
}
|
|
6540
7014
|
) }),
|
|
6541
|
-
showCategories && /* @__PURE__ */
|
|
6542
|
-
/* @__PURE__ */
|
|
7015
|
+
showCategories && /* @__PURE__ */ jsxs17("div", { style: styles.categories, children: [
|
|
7016
|
+
/* @__PURE__ */ jsx21(
|
|
6543
7017
|
"button",
|
|
6544
7018
|
{
|
|
6545
7019
|
onClick: () => setSelectedCategory("all"),
|
|
@@ -6550,7 +7024,7 @@ function SymbolLibrary({
|
|
|
6550
7024
|
children: "All"
|
|
6551
7025
|
}
|
|
6552
7026
|
),
|
|
6553
|
-
categories.map((category) => /* @__PURE__ */
|
|
7027
|
+
categories.map((category) => /* @__PURE__ */ jsx21(
|
|
6554
7028
|
"button",
|
|
6555
7029
|
{
|
|
6556
7030
|
onClick: () => setSelectedCategory(category),
|
|
@@ -6563,7 +7037,7 @@ function SymbolLibrary({
|
|
|
6563
7037
|
category
|
|
6564
7038
|
))
|
|
6565
7039
|
] }),
|
|
6566
|
-
/* @__PURE__ */
|
|
7040
|
+
/* @__PURE__ */ jsx21("div", { style: styles.symbolGrid, children: filteredSymbols.length === 0 ? /* @__PURE__ */ jsx21("div", { style: styles.emptyState, children: "No symbols found" }) : filteredSymbols.map((symbol) => /* @__PURE__ */ jsxs17(
|
|
6567
7041
|
"div",
|
|
6568
7042
|
{
|
|
6569
7043
|
draggable: true,
|
|
@@ -6571,15 +7045,15 @@ function SymbolLibrary({
|
|
|
6571
7045
|
style: styles.symbolCard,
|
|
6572
7046
|
title: symbol.metadata?.description || symbol.name,
|
|
6573
7047
|
children: [
|
|
6574
|
-
/* @__PURE__ */
|
|
7048
|
+
/* @__PURE__ */ jsx21("div", { style: styles.symbolPreview, children: /* @__PURE__ */ jsx21(
|
|
6575
7049
|
"svg",
|
|
6576
7050
|
{
|
|
6577
7051
|
viewBox: `${symbol.viewBox.x} ${symbol.viewBox.y} ${symbol.viewBox.width} ${symbol.viewBox.height}`,
|
|
6578
7052
|
style: styles.symbolSvg,
|
|
6579
|
-
children: /* @__PURE__ */
|
|
7053
|
+
children: /* @__PURE__ */ jsx21("g", { dangerouslySetInnerHTML: { __html: symbol.svgContent } })
|
|
6580
7054
|
}
|
|
6581
7055
|
) }),
|
|
6582
|
-
/* @__PURE__ */
|
|
7056
|
+
/* @__PURE__ */ jsx21("div", { style: styles.symbolName, children: symbol.name })
|
|
6583
7057
|
]
|
|
6584
7058
|
},
|
|
6585
7059
|
symbol.id
|
|
@@ -6688,7 +7162,7 @@ var styles = {
|
|
|
6688
7162
|
};
|
|
6689
7163
|
|
|
6690
7164
|
// src/components/NodeConfigPanel/NodeConfigPanel.tsx
|
|
6691
|
-
import { Fragment as Fragment8, jsx as
|
|
7165
|
+
import { Fragment as Fragment8, jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
6692
7166
|
function NodeConfigPanel({
|
|
6693
7167
|
node,
|
|
6694
7168
|
binding,
|
|
@@ -6707,15 +7181,15 @@ function NodeConfigPanel({
|
|
|
6707
7181
|
padding: "20px",
|
|
6708
7182
|
...style
|
|
6709
7183
|
};
|
|
6710
|
-
return /* @__PURE__ */
|
|
6711
|
-
/* @__PURE__ */
|
|
7184
|
+
return /* @__PURE__ */ jsxs18("div", { className, style: defaultStyle, children: [
|
|
7185
|
+
/* @__PURE__ */ jsxs18("h2", { style: { margin: "0 0 16px 0", fontSize: "1rem", fontWeight: 600 }, children: [
|
|
6712
7186
|
"Configure: ",
|
|
6713
7187
|
node.id
|
|
6714
7188
|
] }),
|
|
6715
|
-
/* @__PURE__ */
|
|
6716
|
-
/* @__PURE__ */
|
|
6717
|
-
/* @__PURE__ */
|
|
6718
|
-
/* @__PURE__ */
|
|
7189
|
+
/* @__PURE__ */ jsxs18("div", { style: { marginBottom: "20px" }, children: [
|
|
7190
|
+
/* @__PURE__ */ jsx22("h3", { style: { fontSize: "0.875rem", fontWeight: 600, marginBottom: "8px" }, children: "Node Settings" }),
|
|
7191
|
+
/* @__PURE__ */ jsx22("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Label:" }),
|
|
7192
|
+
/* @__PURE__ */ jsx22(
|
|
6719
7193
|
"input",
|
|
6720
7194
|
{
|
|
6721
7195
|
type: "text",
|
|
@@ -6731,10 +7205,10 @@ function NodeConfigPanel({
|
|
|
6731
7205
|
}
|
|
6732
7206
|
}
|
|
6733
7207
|
),
|
|
6734
|
-
/* @__PURE__ */
|
|
6735
|
-
/* @__PURE__ */
|
|
6736
|
-
/* @__PURE__ */
|
|
6737
|
-
/* @__PURE__ */
|
|
7208
|
+
/* @__PURE__ */ jsxs18("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: "8px" }, children: [
|
|
7209
|
+
/* @__PURE__ */ jsxs18("div", { children: [
|
|
7210
|
+
/* @__PURE__ */ jsx22("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Label Offset X:" }),
|
|
7211
|
+
/* @__PURE__ */ jsx22(
|
|
6738
7212
|
"input",
|
|
6739
7213
|
{
|
|
6740
7214
|
type: "number",
|
|
@@ -6755,9 +7229,9 @@ function NodeConfigPanel({
|
|
|
6755
7229
|
}
|
|
6756
7230
|
)
|
|
6757
7231
|
] }),
|
|
6758
|
-
/* @__PURE__ */
|
|
6759
|
-
/* @__PURE__ */
|
|
6760
|
-
/* @__PURE__ */
|
|
7232
|
+
/* @__PURE__ */ jsxs18("div", { children: [
|
|
7233
|
+
/* @__PURE__ */ jsx22("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Label Offset Y:" }),
|
|
7234
|
+
/* @__PURE__ */ jsx22(
|
|
6761
7235
|
"input",
|
|
6762
7236
|
{
|
|
6763
7237
|
type: "number",
|
|
@@ -6779,9 +7253,9 @@ function NodeConfigPanel({
|
|
|
6779
7253
|
)
|
|
6780
7254
|
] })
|
|
6781
7255
|
] }),
|
|
6782
|
-
/* @__PURE__ */
|
|
6783
|
-
/* @__PURE__ */
|
|
6784
|
-
/* @__PURE__ */
|
|
7256
|
+
/* @__PURE__ */ jsxs18("div", { children: [
|
|
7257
|
+
/* @__PURE__ */ jsx22("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Label Font Size:" }),
|
|
7258
|
+
/* @__PURE__ */ jsx22(
|
|
6785
7259
|
"input",
|
|
6786
7260
|
{
|
|
6787
7261
|
type: "number",
|
|
@@ -6801,9 +7275,9 @@ function NodeConfigPanel({
|
|
|
6801
7275
|
}
|
|
6802
7276
|
)
|
|
6803
7277
|
] }),
|
|
6804
|
-
/* @__PURE__ */
|
|
6805
|
-
/* @__PURE__ */
|
|
6806
|
-
/* @__PURE__ */
|
|
7278
|
+
/* @__PURE__ */ jsxs18("div", { children: [
|
|
7279
|
+
/* @__PURE__ */ jsx22("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Rotation (degrees):" }),
|
|
7280
|
+
/* @__PURE__ */ jsx22(
|
|
6807
7281
|
"input",
|
|
6808
7282
|
{
|
|
6809
7283
|
type: "number",
|
|
@@ -6828,9 +7302,9 @@ function NodeConfigPanel({
|
|
|
6828
7302
|
)
|
|
6829
7303
|
] })
|
|
6830
7304
|
] }),
|
|
6831
|
-
/* @__PURE__ */
|
|
6832
|
-
/* @__PURE__ */
|
|
6833
|
-
!binding ? /* @__PURE__ */
|
|
7305
|
+
/* @__PURE__ */ jsxs18("div", { style: { marginBottom: "20px" }, children: [
|
|
7306
|
+
/* @__PURE__ */ jsx22("h3", { style: { fontSize: "0.875rem", fontWeight: 600, marginBottom: "8px" }, children: "Telemetry Data" }),
|
|
7307
|
+
!binding ? /* @__PURE__ */ jsx22(
|
|
6834
7308
|
"button",
|
|
6835
7309
|
{
|
|
6836
7310
|
onClick: () => {
|
|
@@ -6873,9 +7347,9 @@ function NodeConfigPanel({
|
|
|
6873
7347
|
},
|
|
6874
7348
|
children: "+ Add Telemetry"
|
|
6875
7349
|
}
|
|
6876
|
-
) : /* @__PURE__ */
|
|
6877
|
-
/* @__PURE__ */
|
|
6878
|
-
/* @__PURE__ */
|
|
7350
|
+
) : /* @__PURE__ */ jsxs18(Fragment8, { children: [
|
|
7351
|
+
/* @__PURE__ */ jsx22("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Initial Value:" }),
|
|
7352
|
+
/* @__PURE__ */ jsx22(
|
|
6879
7353
|
"input",
|
|
6880
7354
|
{
|
|
6881
7355
|
type: "number",
|
|
@@ -6897,8 +7371,8 @@ function NodeConfigPanel({
|
|
|
6897
7371
|
}
|
|
6898
7372
|
}
|
|
6899
7373
|
),
|
|
6900
|
-
/* @__PURE__ */
|
|
6901
|
-
/* @__PURE__ */
|
|
7374
|
+
/* @__PURE__ */ jsx22("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Unit:" }),
|
|
7375
|
+
/* @__PURE__ */ jsx22(
|
|
6902
7376
|
"input",
|
|
6903
7377
|
{
|
|
6904
7378
|
type: "text",
|
|
@@ -6920,8 +7394,8 @@ function NodeConfigPanel({
|
|
|
6920
7394
|
}
|
|
6921
7395
|
}
|
|
6922
7396
|
),
|
|
6923
|
-
/* @__PURE__ */
|
|
6924
|
-
/* @__PURE__ */
|
|
7397
|
+
/* @__PURE__ */ jsxs18("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: [
|
|
7398
|
+
/* @__PURE__ */ jsx22(
|
|
6925
7399
|
"input",
|
|
6926
7400
|
{
|
|
6927
7401
|
type: "checkbox",
|
|
@@ -6943,8 +7417,8 @@ function NodeConfigPanel({
|
|
|
6943
7417
|
),
|
|
6944
7418
|
"Show Sparkline"
|
|
6945
7419
|
] }),
|
|
6946
|
-
/* @__PURE__ */
|
|
6947
|
-
/* @__PURE__ */
|
|
7420
|
+
/* @__PURE__ */ jsxs18("div", { style: { marginTop: "12px" }, children: [
|
|
7421
|
+
/* @__PURE__ */ jsx22(
|
|
6948
7422
|
"label",
|
|
6949
7423
|
{
|
|
6950
7424
|
style: {
|
|
@@ -6956,10 +7430,10 @@ function NodeConfigPanel({
|
|
|
6956
7430
|
children: "Telemetry Position Offset:"
|
|
6957
7431
|
}
|
|
6958
7432
|
),
|
|
6959
|
-
/* @__PURE__ */
|
|
6960
|
-
/* @__PURE__ */
|
|
6961
|
-
/* @__PURE__ */
|
|
6962
|
-
/* @__PURE__ */
|
|
7433
|
+
/* @__PURE__ */ jsxs18("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: "8px" }, children: [
|
|
7434
|
+
/* @__PURE__ */ jsxs18("div", { children: [
|
|
7435
|
+
/* @__PURE__ */ jsx22("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "X Offset:" }),
|
|
7436
|
+
/* @__PURE__ */ jsx22(
|
|
6963
7437
|
"input",
|
|
6964
7438
|
{
|
|
6965
7439
|
type: "number",
|
|
@@ -6986,9 +7460,9 @@ function NodeConfigPanel({
|
|
|
6986
7460
|
}
|
|
6987
7461
|
)
|
|
6988
7462
|
] }),
|
|
6989
|
-
/* @__PURE__ */
|
|
6990
|
-
/* @__PURE__ */
|
|
6991
|
-
/* @__PURE__ */
|
|
7463
|
+
/* @__PURE__ */ jsxs18("div", { children: [
|
|
7464
|
+
/* @__PURE__ */ jsx22("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "Y Offset:" }),
|
|
7465
|
+
/* @__PURE__ */ jsx22(
|
|
6992
7466
|
"input",
|
|
6993
7467
|
{
|
|
6994
7468
|
type: "number",
|
|
@@ -7016,8 +7490,8 @@ function NodeConfigPanel({
|
|
|
7016
7490
|
)
|
|
7017
7491
|
] })
|
|
7018
7492
|
] }),
|
|
7019
|
-
/* @__PURE__ */
|
|
7020
|
-
/* @__PURE__ */
|
|
7493
|
+
/* @__PURE__ */ jsxs18("div", { style: { marginTop: "16px" }, children: [
|
|
7494
|
+
/* @__PURE__ */ jsx22(
|
|
7021
7495
|
"label",
|
|
7022
7496
|
{
|
|
7023
7497
|
style: {
|
|
@@ -7029,10 +7503,10 @@ function NodeConfigPanel({
|
|
|
7029
7503
|
children: "Display Colors:"
|
|
7030
7504
|
}
|
|
7031
7505
|
),
|
|
7032
|
-
/* @__PURE__ */
|
|
7033
|
-
/* @__PURE__ */
|
|
7034
|
-
/* @__PURE__ */
|
|
7035
|
-
/* @__PURE__ */
|
|
7506
|
+
/* @__PURE__ */ jsxs18("div", { style: { marginBottom: "8px" }, children: [
|
|
7507
|
+
/* @__PURE__ */ jsx22("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "Text Color:" }),
|
|
7508
|
+
/* @__PURE__ */ jsxs18("div", { style: { display: "flex", gap: "8px", alignItems: "center" }, children: [
|
|
7509
|
+
/* @__PURE__ */ jsx22(
|
|
7036
7510
|
"input",
|
|
7037
7511
|
{
|
|
7038
7512
|
type: "color",
|
|
@@ -7058,7 +7532,7 @@ function NodeConfigPanel({
|
|
|
7058
7532
|
}
|
|
7059
7533
|
}
|
|
7060
7534
|
),
|
|
7061
|
-
/* @__PURE__ */
|
|
7535
|
+
/* @__PURE__ */ jsx22(
|
|
7062
7536
|
"input",
|
|
7063
7537
|
{
|
|
7064
7538
|
type: "text",
|
|
@@ -7088,10 +7562,10 @@ function NodeConfigPanel({
|
|
|
7088
7562
|
)
|
|
7089
7563
|
] })
|
|
7090
7564
|
] }),
|
|
7091
|
-
binding.display?.showSparkline && /* @__PURE__ */
|
|
7092
|
-
/* @__PURE__ */
|
|
7093
|
-
/* @__PURE__ */
|
|
7094
|
-
/* @__PURE__ */
|
|
7565
|
+
binding.display?.showSparkline && /* @__PURE__ */ jsxs18("div", { style: { marginBottom: "8px" }, children: [
|
|
7566
|
+
/* @__PURE__ */ jsx22("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "Sparkline Color:" }),
|
|
7567
|
+
/* @__PURE__ */ jsxs18("div", { style: { display: "flex", gap: "8px", alignItems: "center" }, children: [
|
|
7568
|
+
/* @__PURE__ */ jsx22(
|
|
7095
7569
|
"input",
|
|
7096
7570
|
{
|
|
7097
7571
|
type: "color",
|
|
@@ -7117,7 +7591,7 @@ function NodeConfigPanel({
|
|
|
7117
7591
|
}
|
|
7118
7592
|
}
|
|
7119
7593
|
),
|
|
7120
|
-
/* @__PURE__ */
|
|
7594
|
+
/* @__PURE__ */ jsx22(
|
|
7121
7595
|
"input",
|
|
7122
7596
|
{
|
|
7123
7597
|
type: "text",
|
|
@@ -7147,9 +7621,9 @@ function NodeConfigPanel({
|
|
|
7147
7621
|
)
|
|
7148
7622
|
] })
|
|
7149
7623
|
] }),
|
|
7150
|
-
/* @__PURE__ */
|
|
7151
|
-
/* @__PURE__ */
|
|
7152
|
-
/* @__PURE__ */
|
|
7624
|
+
/* @__PURE__ */ jsxs18("div", { style: { marginBottom: "8px" }, children: [
|
|
7625
|
+
/* @__PURE__ */ jsx22("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "Background:" }),
|
|
7626
|
+
/* @__PURE__ */ jsx22(
|
|
7153
7627
|
"input",
|
|
7154
7628
|
{
|
|
7155
7629
|
type: "text",
|
|
@@ -7177,20 +7651,20 @@ function NodeConfigPanel({
|
|
|
7177
7651
|
}
|
|
7178
7652
|
}
|
|
7179
7653
|
),
|
|
7180
|
-
/* @__PURE__ */
|
|
7654
|
+
/* @__PURE__ */ jsx22("div", { style: { fontSize: "0.65rem", color: "#6b7280", marginTop: "2px" }, children: "Use 'status' for status-based color or hex code" })
|
|
7181
7655
|
] })
|
|
7182
7656
|
] }),
|
|
7183
7657
|
" "
|
|
7184
7658
|
] })
|
|
7185
7659
|
] })
|
|
7186
7660
|
] }),
|
|
7187
|
-
binding && /* @__PURE__ */
|
|
7188
|
-
/* @__PURE__ */
|
|
7661
|
+
binding && /* @__PURE__ */ jsxs18("div", { style: { marginBottom: "20px" }, children: [
|
|
7662
|
+
/* @__PURE__ */ jsx22("h3", { style: { fontSize: "0.875rem", fontWeight: 600, marginBottom: "8px" }, children: "Thresholds" }),
|
|
7189
7663
|
["highHigh", "high", "low", "lowLow"].map((key) => {
|
|
7190
7664
|
const label = key === "highHigh" ? "High-High (\u2265)" : key === "high" ? "High (\u2265)" : key === "low" ? "Low (\u2264)" : "Low-Low (\u2264)";
|
|
7191
|
-
return /* @__PURE__ */
|
|
7192
|
-
/* @__PURE__ */
|
|
7193
|
-
/* @__PURE__ */
|
|
7665
|
+
return /* @__PURE__ */ jsxs18("div", { style: { marginBottom: "8px" }, children: [
|
|
7666
|
+
/* @__PURE__ */ jsx22("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: label }),
|
|
7667
|
+
/* @__PURE__ */ jsx22(
|
|
7194
7668
|
"input",
|
|
7195
7669
|
{
|
|
7196
7670
|
type: "number",
|
|
@@ -7214,8 +7688,8 @@ function NodeConfigPanel({
|
|
|
7214
7688
|
] }, key);
|
|
7215
7689
|
})
|
|
7216
7690
|
] }),
|
|
7217
|
-
binding && /* @__PURE__ */
|
|
7218
|
-
/* @__PURE__ */
|
|
7691
|
+
binding && /* @__PURE__ */ jsxs18("div", { style: { marginBottom: "20px" }, children: [
|
|
7692
|
+
/* @__PURE__ */ jsx22("h3", { style: { fontSize: "0.875rem", fontWeight: 600, marginBottom: "8px" }, children: "Status Colors" }),
|
|
7219
7693
|
["normal", "warning", "alarm", "fault", "off"].map((status) => {
|
|
7220
7694
|
const defaultColors = {
|
|
7221
7695
|
normal: "#10b981",
|
|
@@ -7225,13 +7699,13 @@ function NodeConfigPanel({
|
|
|
7225
7699
|
off: "#6b7280"
|
|
7226
7700
|
};
|
|
7227
7701
|
const label = status === "normal" ? "Normal" : status === "warning" ? "Warning" : status === "alarm" ? "Alarm" : status === "fault" ? "Fault" : "Off";
|
|
7228
|
-
return /* @__PURE__ */
|
|
7229
|
-
/* @__PURE__ */
|
|
7702
|
+
return /* @__PURE__ */ jsxs18("div", { style: { marginBottom: "8px" }, children: [
|
|
7703
|
+
/* @__PURE__ */ jsxs18("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: [
|
|
7230
7704
|
label,
|
|
7231
7705
|
":"
|
|
7232
7706
|
] }),
|
|
7233
|
-
/* @__PURE__ */
|
|
7234
|
-
/* @__PURE__ */
|
|
7707
|
+
/* @__PURE__ */ jsxs18("div", { style: { display: "flex", gap: "8px", alignItems: "center" }, children: [
|
|
7708
|
+
/* @__PURE__ */ jsx22(
|
|
7235
7709
|
"input",
|
|
7236
7710
|
{
|
|
7237
7711
|
type: "color",
|
|
@@ -7252,7 +7726,7 @@ function NodeConfigPanel({
|
|
|
7252
7726
|
}
|
|
7253
7727
|
}
|
|
7254
7728
|
),
|
|
7255
|
-
/* @__PURE__ */
|
|
7729
|
+
/* @__PURE__ */ jsx22(
|
|
7256
7730
|
"input",
|
|
7257
7731
|
{
|
|
7258
7732
|
type: "text",
|
|
@@ -7279,7 +7753,7 @@ function NodeConfigPanel({
|
|
|
7279
7753
|
] }, status);
|
|
7280
7754
|
})
|
|
7281
7755
|
] }),
|
|
7282
|
-
/* @__PURE__ */
|
|
7756
|
+
/* @__PURE__ */ jsx22("div", { style: { marginTop: "20px", paddingTop: "20px", borderTop: "1px solid #cbd5e1" }, children: /* @__PURE__ */ jsx22(
|
|
7283
7757
|
"button",
|
|
7284
7758
|
{
|
|
7285
7759
|
onClick: onRemove,
|
|
@@ -7556,13 +8030,13 @@ function createControlBinding(nodeId, deviceConfig, actions) {
|
|
|
7556
8030
|
}
|
|
7557
8031
|
|
|
7558
8032
|
// src/hooks/useDeviceControls.ts
|
|
7559
|
-
import { useState as
|
|
8033
|
+
import { useState as useState16, useCallback as useCallback9, useRef as useRef7 } from "react";
|
|
7560
8034
|
function commandKey(nodeId, kind, suffix) {
|
|
7561
8035
|
return suffix ? `${nodeId}:${kind}:${suffix}` : `${nodeId}:${kind}`;
|
|
7562
8036
|
}
|
|
7563
8037
|
function useDeviceControls(initialBindings, options) {
|
|
7564
8038
|
const { commandTimeoutMs } = options ?? {};
|
|
7565
|
-
const [controls, setControls] =
|
|
8039
|
+
const [controls, setControls] = useState16(() => {
|
|
7566
8040
|
const map = /* @__PURE__ */ new Map();
|
|
7567
8041
|
if (initialBindings) {
|
|
7568
8042
|
initialBindings.forEach((binding) => {
|
|
@@ -7571,12 +8045,12 @@ function useDeviceControls(initialBindings, options) {
|
|
|
7571
8045
|
}
|
|
7572
8046
|
return map;
|
|
7573
8047
|
});
|
|
7574
|
-
const pendingRef =
|
|
7575
|
-
const [pendingCommands, setPendingCommands] =
|
|
7576
|
-
const syncPending =
|
|
8048
|
+
const pendingRef = useRef7(/* @__PURE__ */ new Map());
|
|
8049
|
+
const [pendingCommands, setPendingCommands] = useState16(() => /* @__PURE__ */ new Set());
|
|
8050
|
+
const syncPending = useCallback9(() => {
|
|
7577
8051
|
setPendingCommands(new Set(pendingRef.current.keys()));
|
|
7578
8052
|
}, []);
|
|
7579
|
-
const updateControl =
|
|
8053
|
+
const updateControl = useCallback9((nodeId, updates) => {
|
|
7580
8054
|
setControls((prev) => {
|
|
7581
8055
|
const newMap = new Map(prev);
|
|
7582
8056
|
const existing = newMap.get(nodeId);
|
|
@@ -7590,7 +8064,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
7590
8064
|
return newMap;
|
|
7591
8065
|
});
|
|
7592
8066
|
}, []);
|
|
7593
|
-
const updateControlBatch =
|
|
8067
|
+
const updateControlBatch = useCallback9((updates) => {
|
|
7594
8068
|
setControls((prev) => {
|
|
7595
8069
|
const newMap = new Map(prev);
|
|
7596
8070
|
Object.entries(updates).forEach(([nodeId, update]) => {
|
|
@@ -7602,7 +8076,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
7602
8076
|
return newMap;
|
|
7603
8077
|
});
|
|
7604
8078
|
}, []);
|
|
7605
|
-
const updateDeviceState =
|
|
8079
|
+
const updateDeviceState = useCallback9(
|
|
7606
8080
|
(nodeId, stateUpdates) => {
|
|
7607
8081
|
setControls((prev) => {
|
|
7608
8082
|
const newMap = new Map(prev);
|
|
@@ -7618,7 +8092,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
7618
8092
|
},
|
|
7619
8093
|
[]
|
|
7620
8094
|
);
|
|
7621
|
-
const updateParameter =
|
|
8095
|
+
const updateParameter = useCallback9(
|
|
7622
8096
|
(nodeId, parameterId, value) => {
|
|
7623
8097
|
setControls((prev) => {
|
|
7624
8098
|
const newMap = new Map(prev);
|
|
@@ -7645,27 +8119,27 @@ function useDeviceControls(initialBindings, options) {
|
|
|
7645
8119
|
},
|
|
7646
8120
|
[]
|
|
7647
8121
|
);
|
|
7648
|
-
const setControlBinding =
|
|
8122
|
+
const setControlBinding = useCallback9((binding) => {
|
|
7649
8123
|
setControls((prev) => {
|
|
7650
8124
|
const newMap = new Map(prev);
|
|
7651
8125
|
newMap.set(binding.nodeId, binding);
|
|
7652
8126
|
return newMap;
|
|
7653
8127
|
});
|
|
7654
8128
|
}, []);
|
|
7655
|
-
const removeControlBinding =
|
|
8129
|
+
const removeControlBinding = useCallback9((nodeId) => {
|
|
7656
8130
|
setControls((prev) => {
|
|
7657
8131
|
const newMap = new Map(prev);
|
|
7658
8132
|
newMap.delete(nodeId);
|
|
7659
8133
|
return newMap;
|
|
7660
8134
|
});
|
|
7661
8135
|
}, []);
|
|
7662
|
-
const getControlBinding =
|
|
8136
|
+
const getControlBinding = useCallback9(
|
|
7663
8137
|
(nodeId) => {
|
|
7664
8138
|
return controls.get(nodeId);
|
|
7665
8139
|
},
|
|
7666
8140
|
[controls]
|
|
7667
8141
|
);
|
|
7668
|
-
const isCommandPending =
|
|
8142
|
+
const isCommandPending = useCallback9(
|
|
7669
8143
|
(nodeId, kind) => {
|
|
7670
8144
|
if (kind) {
|
|
7671
8145
|
const prefix2 = `${nodeId}:${kind}`;
|
|
@@ -7682,7 +8156,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
7682
8156
|
},
|
|
7683
8157
|
[pendingCommands]
|
|
7684
8158
|
);
|
|
7685
|
-
const markPending =
|
|
8159
|
+
const markPending = useCallback9(
|
|
7686
8160
|
(key, delta) => {
|
|
7687
8161
|
const next = (pendingRef.current.get(key) ?? 0) + delta;
|
|
7688
8162
|
if (next > 0) pendingRef.current.set(key, next);
|
|
@@ -7691,7 +8165,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
7691
8165
|
},
|
|
7692
8166
|
[syncPending]
|
|
7693
8167
|
);
|
|
7694
|
-
const runCommand =
|
|
8168
|
+
const runCommand = useCallback9(
|
|
7695
8169
|
async (nodeId, key, invoke, messages) => {
|
|
7696
8170
|
const binding = controls.get(nodeId);
|
|
7697
8171
|
if (!binding) return;
|
|
@@ -7731,7 +8205,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
7731
8205
|
},
|
|
7732
8206
|
[controls, updateDeviceState, markPending, commandTimeoutMs]
|
|
7733
8207
|
);
|
|
7734
|
-
const sendModeChange =
|
|
8208
|
+
const sendModeChange = useCallback9(
|
|
7735
8209
|
(nodeId, mode) => runCommand(
|
|
7736
8210
|
nodeId,
|
|
7737
8211
|
commandKey(nodeId, "mode"),
|
|
@@ -7740,7 +8214,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
7740
8214
|
),
|
|
7741
8215
|
[runCommand]
|
|
7742
8216
|
);
|
|
7743
|
-
const sendParameterChange =
|
|
8217
|
+
const sendParameterChange = useCallback9(
|
|
7744
8218
|
(nodeId, parameterId, value) => runCommand(
|
|
7745
8219
|
nodeId,
|
|
7746
8220
|
commandKey(nodeId, "parameter", parameterId),
|
|
@@ -7749,21 +8223,21 @@ function useDeviceControls(initialBindings, options) {
|
|
|
7749
8223
|
),
|
|
7750
8224
|
[runCommand]
|
|
7751
8225
|
);
|
|
7752
|
-
const sendStartCommand =
|
|
8226
|
+
const sendStartCommand = useCallback9(
|
|
7753
8227
|
(nodeId) => runCommand(nodeId, commandKey(nodeId, "start"), (binding) => binding.actions.onStart?.(), {
|
|
7754
8228
|
success: "Start command sent",
|
|
7755
8229
|
failure: "Start command failed"
|
|
7756
8230
|
}),
|
|
7757
8231
|
[runCommand]
|
|
7758
8232
|
);
|
|
7759
|
-
const sendStopCommand =
|
|
8233
|
+
const sendStopCommand = useCallback9(
|
|
7760
8234
|
(nodeId) => runCommand(nodeId, commandKey(nodeId, "stop"), (binding) => binding.actions.onStop?.(), {
|
|
7761
8235
|
success: "Stop command sent",
|
|
7762
8236
|
failure: "Stop command failed"
|
|
7763
8237
|
}),
|
|
7764
8238
|
[runCommand]
|
|
7765
8239
|
);
|
|
7766
|
-
const sendCustomAction =
|
|
8240
|
+
const sendCustomAction = useCallback9(
|
|
7767
8241
|
(nodeId, actionId) => runCommand(
|
|
7768
8242
|
nodeId,
|
|
7769
8243
|
commandKey(nodeId, "action", actionId),
|
|
@@ -7816,9 +8290,9 @@ function createConfigBinding(nodeId, tag, parameters, actions, options) {
|
|
|
7816
8290
|
}
|
|
7817
8291
|
|
|
7818
8292
|
// src/hooks/useDeviceConfigs.ts
|
|
7819
|
-
import { useState as
|
|
8293
|
+
import { useState as useState17, useCallback as useCallback10 } from "react";
|
|
7820
8294
|
function useDeviceConfigs(initialConfigs) {
|
|
7821
|
-
const [configs, setConfigs] =
|
|
8295
|
+
const [configs, setConfigs] = useState17(() => {
|
|
7822
8296
|
const map = /* @__PURE__ */ new Map();
|
|
7823
8297
|
if (initialConfigs) {
|
|
7824
8298
|
initialConfigs.forEach((config) => {
|
|
@@ -7827,13 +8301,13 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
7827
8301
|
}
|
|
7828
8302
|
return map;
|
|
7829
8303
|
});
|
|
7830
|
-
const getConfig =
|
|
8304
|
+
const getConfig = useCallback10(
|
|
7831
8305
|
(nodeId) => {
|
|
7832
8306
|
return configs.get(nodeId);
|
|
7833
8307
|
},
|
|
7834
8308
|
[configs]
|
|
7835
8309
|
);
|
|
7836
|
-
const updateConfig =
|
|
8310
|
+
const updateConfig = useCallback10((nodeId, updates) => {
|
|
7837
8311
|
setConfigs((prev) => {
|
|
7838
8312
|
const newMap = new Map(prev);
|
|
7839
8313
|
const existing = newMap.get(nodeId);
|
|
@@ -7847,7 +8321,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
7847
8321
|
return newMap;
|
|
7848
8322
|
});
|
|
7849
8323
|
}, []);
|
|
7850
|
-
const updateConfigState =
|
|
8324
|
+
const updateConfigState = useCallback10((nodeId, stateUpdates) => {
|
|
7851
8325
|
setConfigs((prev) => {
|
|
7852
8326
|
const newMap = new Map(prev);
|
|
7853
8327
|
const existing = newMap.get(nodeId);
|
|
@@ -7860,7 +8334,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
7860
8334
|
return newMap;
|
|
7861
8335
|
});
|
|
7862
8336
|
}, []);
|
|
7863
|
-
const updateConfigBatch =
|
|
8337
|
+
const updateConfigBatch = useCallback10((updates) => {
|
|
7864
8338
|
setConfigs((prev) => {
|
|
7865
8339
|
const newMap = new Map(prev);
|
|
7866
8340
|
Object.entries(updates).forEach(([nodeId, update]) => {
|
|
@@ -7872,7 +8346,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
7872
8346
|
return newMap;
|
|
7873
8347
|
});
|
|
7874
8348
|
}, []);
|
|
7875
|
-
const updateParameterValue =
|
|
8349
|
+
const updateParameterValue = useCallback10((nodeId, parameterId, value) => {
|
|
7876
8350
|
setConfigs((prev) => {
|
|
7877
8351
|
const newMap = new Map(prev);
|
|
7878
8352
|
const existing = newMap.get(nodeId);
|
|
@@ -7889,7 +8363,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
7889
8363
|
return newMap;
|
|
7890
8364
|
});
|
|
7891
8365
|
}, []);
|
|
7892
|
-
const applyConfig =
|
|
8366
|
+
const applyConfig = useCallback10(
|
|
7893
8367
|
async (nodeId) => {
|
|
7894
8368
|
const config = configs.get(nodeId);
|
|
7895
8369
|
if (!config || !config.actions.onApply) {
|
|
@@ -7922,7 +8396,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
7922
8396
|
},
|
|
7923
8397
|
[configs, updateConfigState]
|
|
7924
8398
|
);
|
|
7925
|
-
const saveConfig =
|
|
8399
|
+
const saveConfig = useCallback10(
|
|
7926
8400
|
async (nodeId) => {
|
|
7927
8401
|
const config = configs.get(nodeId);
|
|
7928
8402
|
if (!config || !config.actions.onSave) {
|
|
@@ -7956,7 +8430,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
7956
8430
|
},
|
|
7957
8431
|
[configs, updateConfigState]
|
|
7958
8432
|
);
|
|
7959
|
-
const resetConfig =
|
|
8433
|
+
const resetConfig = useCallback10(
|
|
7960
8434
|
async (nodeId) => {
|
|
7961
8435
|
const config = configs.get(nodeId);
|
|
7962
8436
|
if (!config) {
|
|
@@ -7986,7 +8460,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
7986
8460
|
},
|
|
7987
8461
|
[configs, updateConfig, updateConfigState]
|
|
7988
8462
|
);
|
|
7989
|
-
const cancelConfig =
|
|
8463
|
+
const cancelConfig = useCallback10(
|
|
7990
8464
|
(nodeId) => {
|
|
7991
8465
|
const config = configs.get(nodeId);
|
|
7992
8466
|
if (config?.actions.onCancel) {
|
|
@@ -7995,7 +8469,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
7995
8469
|
},
|
|
7996
8470
|
[configs]
|
|
7997
8471
|
);
|
|
7998
|
-
const validateConfig =
|
|
8472
|
+
const validateConfig = useCallback10(
|
|
7999
8473
|
(nodeId) => {
|
|
8000
8474
|
const config = configs.get(nodeId);
|
|
8001
8475
|
if (!config) {
|
|
@@ -8037,21 +8511,21 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
8037
8511
|
},
|
|
8038
8512
|
[configs, updateConfigState]
|
|
8039
8513
|
);
|
|
8040
|
-
const setConfig =
|
|
8514
|
+
const setConfig = useCallback10((config) => {
|
|
8041
8515
|
setConfigs((prev) => {
|
|
8042
8516
|
const newMap = new Map(prev);
|
|
8043
8517
|
newMap.set(config.nodeId, config);
|
|
8044
8518
|
return newMap;
|
|
8045
8519
|
});
|
|
8046
8520
|
}, []);
|
|
8047
|
-
const removeConfig =
|
|
8521
|
+
const removeConfig = useCallback10((nodeId) => {
|
|
8048
8522
|
setConfigs((prev) => {
|
|
8049
8523
|
const newMap = new Map(prev);
|
|
8050
8524
|
newMap.delete(nodeId);
|
|
8051
8525
|
return newMap;
|
|
8052
8526
|
});
|
|
8053
8527
|
}, []);
|
|
8054
|
-
const clearConfigs =
|
|
8528
|
+
const clearConfigs = useCallback10(() => {
|
|
8055
8529
|
setConfigs(/* @__PURE__ */ new Map());
|
|
8056
8530
|
}, []);
|
|
8057
8531
|
return {
|
|
@@ -8073,8 +8547,8 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
8073
8547
|
}
|
|
8074
8548
|
|
|
8075
8549
|
// src/components/DeviceConfigPanel/DeviceConfigPanel.tsx
|
|
8076
|
-
import { useState as
|
|
8077
|
-
import { Fragment as Fragment9, jsx as
|
|
8550
|
+
import { useState as useState18, useEffect as useEffect13, useMemo, useRef as useRef8 } from "react";
|
|
8551
|
+
import { Fragment as Fragment9, jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
8078
8552
|
function DeviceConfigPanel({
|
|
8079
8553
|
binding,
|
|
8080
8554
|
onClose,
|
|
@@ -8092,7 +8566,7 @@ function DeviceConfigPanel({
|
|
|
8092
8566
|
showControlsButton = true,
|
|
8093
8567
|
embedded = false
|
|
8094
8568
|
}) {
|
|
8095
|
-
const [localValues, setLocalValues] =
|
|
8569
|
+
const [localValues, setLocalValues] = useState18(() => {
|
|
8096
8570
|
if (binding) {
|
|
8097
8571
|
const values = {};
|
|
8098
8572
|
binding.parameters.forEach((param) => {
|
|
@@ -8102,7 +8576,7 @@ function DeviceConfigPanel({
|
|
|
8102
8576
|
}
|
|
8103
8577
|
return {};
|
|
8104
8578
|
});
|
|
8105
|
-
const [collapsedSections, setCollapsedSections] =
|
|
8579
|
+
const [collapsedSections, setCollapsedSections] = useState18(() => {
|
|
8106
8580
|
const collapsed = /* @__PURE__ */ new Set();
|
|
8107
8581
|
if (binding?.sections) {
|
|
8108
8582
|
binding.sections.forEach((section) => {
|
|
@@ -8113,9 +8587,9 @@ function DeviceConfigPanel({
|
|
|
8113
8587
|
}
|
|
8114
8588
|
return collapsed;
|
|
8115
8589
|
});
|
|
8116
|
-
const [showToast, setShowToast] =
|
|
8117
|
-
const [bindingId, setBindingId] =
|
|
8118
|
-
const lastResultTimestampRef =
|
|
8590
|
+
const [showToast, setShowToast] = useState18(true);
|
|
8591
|
+
const [bindingId, setBindingId] = useState18(binding?.nodeId || null);
|
|
8592
|
+
const lastResultTimestampRef = useRef8(0);
|
|
8119
8593
|
if (binding && binding.nodeId !== bindingId) {
|
|
8120
8594
|
const values = {};
|
|
8121
8595
|
binding.parameters.forEach((param) => {
|
|
@@ -8131,7 +8605,7 @@ function DeviceConfigPanel({
|
|
|
8131
8605
|
setCollapsedSections(collapsed);
|
|
8132
8606
|
setBindingId(binding.nodeId);
|
|
8133
8607
|
}
|
|
8134
|
-
|
|
8608
|
+
useEffect13(() => {
|
|
8135
8609
|
const currentTimestamp = binding?.state.lastSaved || 0;
|
|
8136
8610
|
if (binding?.state.lastSaveResult && currentTimestamp !== lastResultTimestampRef.current) {
|
|
8137
8611
|
lastResultTimestampRef.current = currentTimestamp;
|
|
@@ -8236,14 +8710,14 @@ function DeviceConfigPanel({
|
|
|
8236
8710
|
const value = localValues[param.id];
|
|
8237
8711
|
const error = binding.state.errors?.[param.id];
|
|
8238
8712
|
const isDisabled = param.readOnly || param.enabled === false;
|
|
8239
|
-
return /* @__PURE__ */
|
|
8713
|
+
return /* @__PURE__ */ jsxs19(
|
|
8240
8714
|
"div",
|
|
8241
8715
|
{
|
|
8242
8716
|
style: {
|
|
8243
8717
|
marginBottom: spacing.marginBottom
|
|
8244
8718
|
},
|
|
8245
8719
|
children: [
|
|
8246
|
-
/* @__PURE__ */
|
|
8720
|
+
/* @__PURE__ */ jsxs19(
|
|
8247
8721
|
"label",
|
|
8248
8722
|
{
|
|
8249
8723
|
style: {
|
|
@@ -8258,8 +8732,8 @@ function DeviceConfigPanel({
|
|
|
8258
8732
|
},
|
|
8259
8733
|
children: [
|
|
8260
8734
|
param.label,
|
|
8261
|
-
param.required && /* @__PURE__ */
|
|
8262
|
-
param.unit && /* @__PURE__ */
|
|
8735
|
+
param.required && /* @__PURE__ */ jsx23("span", { style: { color: errorColor }, children: " *" }),
|
|
8736
|
+
param.unit && /* @__PURE__ */ jsxs19("span", { style: { color: mutedTextColor, fontWeight: "normal" }, children: [
|
|
8263
8737
|
" (",
|
|
8264
8738
|
param.unit,
|
|
8265
8739
|
")"
|
|
@@ -8267,7 +8741,7 @@ function DeviceConfigPanel({
|
|
|
8267
8741
|
]
|
|
8268
8742
|
}
|
|
8269
8743
|
),
|
|
8270
|
-
param.description && /* @__PURE__ */
|
|
8744
|
+
param.description && /* @__PURE__ */ jsx23(
|
|
8271
8745
|
"div",
|
|
8272
8746
|
{
|
|
8273
8747
|
style: {
|
|
@@ -8279,7 +8753,7 @@ function DeviceConfigPanel({
|
|
|
8279
8753
|
children: param.description
|
|
8280
8754
|
}
|
|
8281
8755
|
),
|
|
8282
|
-
param.type === "number" && /* @__PURE__ */
|
|
8756
|
+
param.type === "number" && /* @__PURE__ */ jsx23(
|
|
8283
8757
|
"input",
|
|
8284
8758
|
{
|
|
8285
8759
|
type: "number",
|
|
@@ -8303,7 +8777,7 @@ function DeviceConfigPanel({
|
|
|
8303
8777
|
}
|
|
8304
8778
|
}
|
|
8305
8779
|
),
|
|
8306
|
-
param.type === "string" && /* @__PURE__ */
|
|
8780
|
+
param.type === "string" && /* @__PURE__ */ jsx23(
|
|
8307
8781
|
"input",
|
|
8308
8782
|
{
|
|
8309
8783
|
type: "text",
|
|
@@ -8324,7 +8798,7 @@ function DeviceConfigPanel({
|
|
|
8324
8798
|
}
|
|
8325
8799
|
}
|
|
8326
8800
|
),
|
|
8327
|
-
param.type === "boolean" && /* @__PURE__ */
|
|
8801
|
+
param.type === "boolean" && /* @__PURE__ */ jsxs19(
|
|
8328
8802
|
"label",
|
|
8329
8803
|
{
|
|
8330
8804
|
style: {
|
|
@@ -8334,7 +8808,7 @@ function DeviceConfigPanel({
|
|
|
8334
8808
|
cursor: isDisabled ? "not-allowed" : "pointer"
|
|
8335
8809
|
},
|
|
8336
8810
|
children: [
|
|
8337
|
-
/* @__PURE__ */
|
|
8811
|
+
/* @__PURE__ */ jsx23(
|
|
8338
8812
|
"input",
|
|
8339
8813
|
{
|
|
8340
8814
|
type: "checkbox",
|
|
@@ -8348,11 +8822,11 @@ function DeviceConfigPanel({
|
|
|
8348
8822
|
}
|
|
8349
8823
|
}
|
|
8350
8824
|
),
|
|
8351
|
-
/* @__PURE__ */
|
|
8825
|
+
/* @__PURE__ */ jsx23("span", { style: { fontSize: `${fontSize.value}px`, color: textColor }, children: value ? "Enabled" : "Disabled" })
|
|
8352
8826
|
]
|
|
8353
8827
|
}
|
|
8354
8828
|
),
|
|
8355
|
-
param.type === "select" && /* @__PURE__ */
|
|
8829
|
+
param.type === "select" && /* @__PURE__ */ jsx23(
|
|
8356
8830
|
"select",
|
|
8357
8831
|
{
|
|
8358
8832
|
value: value ?? "",
|
|
@@ -8370,10 +8844,10 @@ function DeviceConfigPanel({
|
|
|
8370
8844
|
borderRadius: "2px",
|
|
8371
8845
|
outline: "none"
|
|
8372
8846
|
},
|
|
8373
|
-
children: param.options?.map((option) => /* @__PURE__ */
|
|
8847
|
+
children: param.options?.map((option) => /* @__PURE__ */ jsx23("option", { value: option.value, children: option.label }, option.value))
|
|
8374
8848
|
}
|
|
8375
8849
|
),
|
|
8376
|
-
error && /* @__PURE__ */
|
|
8850
|
+
error && /* @__PURE__ */ jsx23(
|
|
8377
8851
|
"div",
|
|
8378
8852
|
{
|
|
8379
8853
|
style: {
|
|
@@ -8393,7 +8867,7 @@ function DeviceConfigPanel({
|
|
|
8393
8867
|
const renderSection = (section) => {
|
|
8394
8868
|
const params = parametersBySection[section.id] || [];
|
|
8395
8869
|
const isCollapsed = collapsedSections.has(section.id);
|
|
8396
|
-
return /* @__PURE__ */
|
|
8870
|
+
return /* @__PURE__ */ jsxs19(
|
|
8397
8871
|
"div",
|
|
8398
8872
|
{
|
|
8399
8873
|
style: {
|
|
@@ -8403,7 +8877,7 @@ function DeviceConfigPanel({
|
|
|
8403
8877
|
backgroundColor: surfaceColor
|
|
8404
8878
|
},
|
|
8405
8879
|
children: [
|
|
8406
|
-
/* @__PURE__ */
|
|
8880
|
+
/* @__PURE__ */ jsxs19(
|
|
8407
8881
|
"div",
|
|
8408
8882
|
{
|
|
8409
8883
|
onClick: () => section.collapsible && toggleSection(section.id),
|
|
@@ -8416,8 +8890,8 @@ function DeviceConfigPanel({
|
|
|
8416
8890
|
alignItems: "center"
|
|
8417
8891
|
},
|
|
8418
8892
|
children: [
|
|
8419
|
-
/* @__PURE__ */
|
|
8420
|
-
/* @__PURE__ */
|
|
8893
|
+
/* @__PURE__ */ jsxs19("div", { children: [
|
|
8894
|
+
/* @__PURE__ */ jsxs19(
|
|
8421
8895
|
"div",
|
|
8422
8896
|
{
|
|
8423
8897
|
style: {
|
|
@@ -8429,12 +8903,12 @@ function DeviceConfigPanel({
|
|
|
8429
8903
|
letterSpacing: "0.5px"
|
|
8430
8904
|
},
|
|
8431
8905
|
children: [
|
|
8432
|
-
section.icon && /* @__PURE__ */
|
|
8906
|
+
section.icon && /* @__PURE__ */ jsx23("span", { style: { marginRight: "8px" }, children: section.icon }),
|
|
8433
8907
|
section.title
|
|
8434
8908
|
]
|
|
8435
8909
|
}
|
|
8436
8910
|
),
|
|
8437
|
-
section.description && /* @__PURE__ */
|
|
8911
|
+
section.description && /* @__PURE__ */ jsx23(
|
|
8438
8912
|
"div",
|
|
8439
8913
|
{
|
|
8440
8914
|
style: {
|
|
@@ -8447,11 +8921,11 @@ function DeviceConfigPanel({
|
|
|
8447
8921
|
}
|
|
8448
8922
|
)
|
|
8449
8923
|
] }),
|
|
8450
|
-
section.collapsible && /* @__PURE__ */
|
|
8924
|
+
section.collapsible && /* @__PURE__ */ jsx23("span", { style: { fontSize: "16px", color: mutedTextColor }, children: isCollapsed ? "\u25BC" : "\u25B2" })
|
|
8451
8925
|
]
|
|
8452
8926
|
}
|
|
8453
8927
|
),
|
|
8454
|
-
!isCollapsed && /* @__PURE__ */
|
|
8928
|
+
!isCollapsed && /* @__PURE__ */ jsx23("div", { style: { padding: spacing.padding }, children: params.map(renderParameter) })
|
|
8455
8929
|
]
|
|
8456
8930
|
},
|
|
8457
8931
|
section.id
|
|
@@ -8510,9 +8984,9 @@ function DeviceConfigPanel({
|
|
|
8510
8984
|
const showSave = binding.display?.showSave !== false && binding.actions.onSave;
|
|
8511
8985
|
const showReset = binding.display?.showReset !== false && binding.actions.onReset;
|
|
8512
8986
|
const showCancel = binding.display?.showCancel !== false;
|
|
8513
|
-
return /* @__PURE__ */
|
|
8514
|
-
/* @__PURE__ */
|
|
8515
|
-
/* @__PURE__ */
|
|
8987
|
+
return /* @__PURE__ */ jsxs19(Fragment9, { children: [
|
|
8988
|
+
/* @__PURE__ */ jsxs19("div", { style: panelStyle, className: binding.display?.className, children: [
|
|
8989
|
+
/* @__PURE__ */ jsxs19(
|
|
8516
8990
|
"div",
|
|
8517
8991
|
{
|
|
8518
8992
|
style: {
|
|
@@ -8524,8 +8998,8 @@ function DeviceConfigPanel({
|
|
|
8524
8998
|
borderBottom: `2px solid ${borderColor}`
|
|
8525
8999
|
},
|
|
8526
9000
|
children: [
|
|
8527
|
-
/* @__PURE__ */
|
|
8528
|
-
/* @__PURE__ */
|
|
9001
|
+
/* @__PURE__ */ jsxs19("div", { children: [
|
|
9002
|
+
/* @__PURE__ */ jsx23(
|
|
8529
9003
|
"h3",
|
|
8530
9004
|
{
|
|
8531
9005
|
style: {
|
|
@@ -8545,7 +9019,7 @@ function DeviceConfigPanel({
|
|
|
8545
9019
|
children: titleText.length > 25 ? titleText.slice(0, 25) + "..." : titleText
|
|
8546
9020
|
}
|
|
8547
9021
|
),
|
|
8548
|
-
binding.display?.subtitle && /* @__PURE__ */
|
|
9022
|
+
binding.display?.subtitle && /* @__PURE__ */ jsx23(
|
|
8549
9023
|
"div",
|
|
8550
9024
|
{
|
|
8551
9025
|
style: {
|
|
@@ -8558,8 +9032,8 @@ function DeviceConfigPanel({
|
|
|
8558
9032
|
}
|
|
8559
9033
|
)
|
|
8560
9034
|
] }),
|
|
8561
|
-
/* @__PURE__ */
|
|
8562
|
-
showControlsButton && onOpenControls && /* @__PURE__ */
|
|
9035
|
+
/* @__PURE__ */ jsxs19("div", { style: { display: "flex", gap: "8px" }, children: [
|
|
9036
|
+
showControlsButton && onOpenControls && /* @__PURE__ */ jsx23(
|
|
8563
9037
|
"button",
|
|
8564
9038
|
{
|
|
8565
9039
|
onClick: onOpenControls,
|
|
@@ -8582,7 +9056,7 @@ function DeviceConfigPanel({
|
|
|
8582
9056
|
children: "CTRL"
|
|
8583
9057
|
}
|
|
8584
9058
|
),
|
|
8585
|
-
onUndock && /* @__PURE__ */
|
|
9059
|
+
onUndock && /* @__PURE__ */ jsx23(
|
|
8586
9060
|
"button",
|
|
8587
9061
|
{
|
|
8588
9062
|
onClick: onUndock,
|
|
@@ -8603,7 +9077,7 @@ function DeviceConfigPanel({
|
|
|
8603
9077
|
children: undockIcon
|
|
8604
9078
|
}
|
|
8605
9079
|
),
|
|
8606
|
-
/* @__PURE__ */
|
|
9080
|
+
/* @__PURE__ */ jsx23(
|
|
8607
9081
|
"button",
|
|
8608
9082
|
{
|
|
8609
9083
|
onClick: onClose,
|
|
@@ -8626,7 +9100,7 @@ function DeviceConfigPanel({
|
|
|
8626
9100
|
]
|
|
8627
9101
|
}
|
|
8628
9102
|
),
|
|
8629
|
-
binding.state.isDirty && /* @__PURE__ */
|
|
9103
|
+
binding.state.isDirty && /* @__PURE__ */ jsx23(
|
|
8630
9104
|
"div",
|
|
8631
9105
|
{
|
|
8632
9106
|
style: {
|
|
@@ -8641,11 +9115,11 @@ function DeviceConfigPanel({
|
|
|
8641
9115
|
children: "Unsaved changes"
|
|
8642
9116
|
}
|
|
8643
9117
|
),
|
|
8644
|
-
/* @__PURE__ */
|
|
9118
|
+
/* @__PURE__ */ jsx23("div", { style: { flex: 1, overflowY: "auto", marginBottom: spacing.marginBottom }, children: sortedSections.length > 0 ? sortedSections.map(renderSection) : (
|
|
8645
9119
|
/* Render unsectioned parameters */
|
|
8646
|
-
/* @__PURE__ */
|
|
9120
|
+
/* @__PURE__ */ jsx23("div", { children: parametersBySection._unsectioned?.map(renderParameter) })
|
|
8647
9121
|
) }),
|
|
8648
|
-
/* @__PURE__ */
|
|
9122
|
+
/* @__PURE__ */ jsxs19(
|
|
8649
9123
|
"div",
|
|
8650
9124
|
{
|
|
8651
9125
|
style: {
|
|
@@ -8656,7 +9130,7 @@ function DeviceConfigPanel({
|
|
|
8656
9130
|
flexWrap: "wrap"
|
|
8657
9131
|
},
|
|
8658
9132
|
children: [
|
|
8659
|
-
showApply && /* @__PURE__ */
|
|
9133
|
+
showApply && /* @__PURE__ */ jsx23(
|
|
8660
9134
|
"button",
|
|
8661
9135
|
{
|
|
8662
9136
|
onClick: handleApply,
|
|
@@ -8679,7 +9153,7 @@ function DeviceConfigPanel({
|
|
|
8679
9153
|
children: binding.state.isSaving ? "Applying..." : "Apply"
|
|
8680
9154
|
}
|
|
8681
9155
|
),
|
|
8682
|
-
showSave && /* @__PURE__ */
|
|
9156
|
+
showSave && /* @__PURE__ */ jsx23(
|
|
8683
9157
|
"button",
|
|
8684
9158
|
{
|
|
8685
9159
|
onClick: handleSave,
|
|
@@ -8702,7 +9176,7 @@ function DeviceConfigPanel({
|
|
|
8702
9176
|
children: binding.state.isSaving ? "Saving..." : "Save"
|
|
8703
9177
|
}
|
|
8704
9178
|
),
|
|
8705
|
-
showReset && /* @__PURE__ */
|
|
9179
|
+
showReset && /* @__PURE__ */ jsx23(
|
|
8706
9180
|
"button",
|
|
8707
9181
|
{
|
|
8708
9182
|
onClick: handleReset,
|
|
@@ -8725,7 +9199,7 @@ function DeviceConfigPanel({
|
|
|
8725
9199
|
children: "Reset"
|
|
8726
9200
|
}
|
|
8727
9201
|
),
|
|
8728
|
-
showCancel && /* @__PURE__ */
|
|
9202
|
+
showCancel && /* @__PURE__ */ jsx23(
|
|
8729
9203
|
"button",
|
|
8730
9204
|
{
|
|
8731
9205
|
onClick: handleCancel,
|
|
@@ -8752,7 +9226,7 @@ function DeviceConfigPanel({
|
|
|
8752
9226
|
}
|
|
8753
9227
|
)
|
|
8754
9228
|
] }),
|
|
8755
|
-
binding.state.lastSaveResult && showToast && /* @__PURE__ */
|
|
9229
|
+
binding.state.lastSaveResult && showToast && /* @__PURE__ */ jsx23(
|
|
8756
9230
|
"div",
|
|
8757
9231
|
{
|
|
8758
9232
|
style: {
|
|
@@ -8776,7 +9250,7 @@ function DeviceConfigPanel({
|
|
|
8776
9250
|
}
|
|
8777
9251
|
|
|
8778
9252
|
// src/diagram/hooks/useSimulation.ts
|
|
8779
|
-
import { useEffect as
|
|
9253
|
+
import { useEffect as useEffect14 } from "react";
|
|
8780
9254
|
function useSimulation(telemetry, updateTelemetryBatch, options = {}) {
|
|
8781
9255
|
const {
|
|
8782
9256
|
interval = 2e3,
|
|
@@ -8787,7 +9261,7 @@ function useSimulation(telemetry, updateTelemetryBatch, options = {}) {
|
|
|
8787
9261
|
historyLength = 10,
|
|
8788
9262
|
generateValue
|
|
8789
9263
|
} = options;
|
|
8790
|
-
|
|
9264
|
+
useEffect14(() => {
|
|
8791
9265
|
if (!enabled) return;
|
|
8792
9266
|
const intervalId = setInterval(() => {
|
|
8793
9267
|
const updates = [];
|
|
@@ -8859,6 +9333,7 @@ export {
|
|
|
8859
9333
|
LegacyValueEntry,
|
|
8860
9334
|
NodeConfigPanel,
|
|
8861
9335
|
NodeControlsPanel,
|
|
9336
|
+
NumpadDialog,
|
|
8862
9337
|
PIDCanvas,
|
|
8863
9338
|
PanelContent,
|
|
8864
9339
|
PanelTabs,
|