@procaaso/alphinity-ui-components 1.4.0 → 1.7.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 +847 -402
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +50 -1
- package/dist/index.d.ts +50 -1
- package/dist/index.js +842 -398
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -53,6 +53,7 @@ __export(index_exports, {
|
|
|
53
53
|
LegacyValueEntry: () => LegacyValueEntry,
|
|
54
54
|
NodeConfigPanel: () => NodeConfigPanel,
|
|
55
55
|
NodeControlsPanel: () => NodeControlsPanel,
|
|
56
|
+
NumpadDialog: () => NumpadDialog,
|
|
56
57
|
PIDCanvas: () => PIDCanvas,
|
|
57
58
|
PanelContent: () => PanelContent,
|
|
58
59
|
PanelTabs: () => PanelTabs,
|
|
@@ -1943,14 +1944,457 @@ function DeviceControlPanel({
|
|
|
1943
1944
|
] });
|
|
1944
1945
|
}
|
|
1945
1946
|
|
|
1947
|
+
// src/components/NumpadDialog/NumpadDialog.tsx
|
|
1948
|
+
var import_react6 = require("react");
|
|
1949
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1950
|
+
var NumpadDialog = ({
|
|
1951
|
+
isOpen,
|
|
1952
|
+
onClose,
|
|
1953
|
+
onApply,
|
|
1954
|
+
deviceName = "",
|
|
1955
|
+
parameterLabel = "Setpoint",
|
|
1956
|
+
unit = "",
|
|
1957
|
+
min = 0,
|
|
1958
|
+
max = 100,
|
|
1959
|
+
precision,
|
|
1960
|
+
currentValue = 0,
|
|
1961
|
+
touchOptimized = true
|
|
1962
|
+
}) => {
|
|
1963
|
+
const [inputValue, setInputValue] = (0, import_react6.useState)("");
|
|
1964
|
+
const [pristine, setPristine] = (0, import_react6.useState)(true);
|
|
1965
|
+
const dialogRef = (0, import_react6.useRef)(null);
|
|
1966
|
+
const titleId = (0, import_react6.useId)();
|
|
1967
|
+
const decimals = precision ?? 1;
|
|
1968
|
+
(0, import_react6.useEffect)(() => {
|
|
1969
|
+
if (isOpen) {
|
|
1970
|
+
setInputValue(Number(currentValue).toFixed(decimals));
|
|
1971
|
+
setPristine(true);
|
|
1972
|
+
}
|
|
1973
|
+
}, [isOpen, currentValue, decimals]);
|
|
1974
|
+
(0, import_react6.useEffect)(() => {
|
|
1975
|
+
if (!isOpen) return;
|
|
1976
|
+
const previouslyFocused = document.activeElement;
|
|
1977
|
+
dialogRef.current?.focus();
|
|
1978
|
+
return () => previouslyFocused?.focus?.();
|
|
1979
|
+
}, [isOpen]);
|
|
1980
|
+
(0, import_react6.useEffect)(() => {
|
|
1981
|
+
if (!isOpen) return;
|
|
1982
|
+
const prevOverflow = document.body.style.overflow;
|
|
1983
|
+
document.body.style.overflow = "hidden";
|
|
1984
|
+
return () => {
|
|
1985
|
+
document.body.style.overflow = prevOverflow;
|
|
1986
|
+
};
|
|
1987
|
+
}, [isOpen]);
|
|
1988
|
+
const handleApply = (0, import_react6.useCallback)(() => {
|
|
1989
|
+
const n = Number(inputValue);
|
|
1990
|
+
if (inputValue === "" || inputValue === "-" || inputValue === "." || inputValue === "-.") return;
|
|
1991
|
+
if (isNaN(n) || n < min || n > max) return;
|
|
1992
|
+
onApply(Number(n.toFixed(decimals)));
|
|
1993
|
+
}, [inputValue, min, max, onApply, decimals]);
|
|
1994
|
+
const appendDigit = (0, import_react6.useCallback)(
|
|
1995
|
+
(digit) => {
|
|
1996
|
+
setInputValue((prev) => {
|
|
1997
|
+
const base = pristine ? "" : prev;
|
|
1998
|
+
if (digit === ".") {
|
|
1999
|
+
if (decimals === 0) return base;
|
|
2000
|
+
if (base.includes(".")) return base;
|
|
2001
|
+
if (base === "" || base === "-") return base + "0.";
|
|
2002
|
+
return base + ".";
|
|
2003
|
+
}
|
|
2004
|
+
const dot = base.indexOf(".");
|
|
2005
|
+
if (dot !== -1 && base.length - dot - 1 >= decimals) return base;
|
|
2006
|
+
if (base === "0") return digit;
|
|
2007
|
+
if (base === "-0") return "-" + digit;
|
|
2008
|
+
return base + digit;
|
|
2009
|
+
});
|
|
2010
|
+
if (pristine) setPristine(false);
|
|
2011
|
+
},
|
|
2012
|
+
[pristine, decimals]
|
|
2013
|
+
);
|
|
2014
|
+
const handleBackspace = (0, import_react6.useCallback)(() => {
|
|
2015
|
+
setPristine(false);
|
|
2016
|
+
setInputValue((prev) => prev.slice(0, -1));
|
|
2017
|
+
}, []);
|
|
2018
|
+
const handleClear = (0, import_react6.useCallback)(() => {
|
|
2019
|
+
setPristine(false);
|
|
2020
|
+
setInputValue("");
|
|
2021
|
+
}, []);
|
|
2022
|
+
const handleToggleSign = (0, import_react6.useCallback)(() => {
|
|
2023
|
+
if (min >= 0) return;
|
|
2024
|
+
setPristine(false);
|
|
2025
|
+
setInputValue((prev) => {
|
|
2026
|
+
if (prev.startsWith("-")) return prev.slice(1);
|
|
2027
|
+
if (prev === "" || prev === "0") return "-";
|
|
2028
|
+
return "-" + prev;
|
|
2029
|
+
});
|
|
2030
|
+
}, [min]);
|
|
2031
|
+
const bsTimer = (0, import_react6.useRef)(null);
|
|
2032
|
+
const bsLongFired = (0, import_react6.useRef)(false);
|
|
2033
|
+
const clearBsTimer = () => {
|
|
2034
|
+
if (bsTimer.current !== null) {
|
|
2035
|
+
clearTimeout(bsTimer.current);
|
|
2036
|
+
bsTimer.current = null;
|
|
2037
|
+
}
|
|
2038
|
+
};
|
|
2039
|
+
const handleBackspacePointerDown = () => {
|
|
2040
|
+
bsLongFired.current = false;
|
|
2041
|
+
bsTimer.current = window.setTimeout(() => {
|
|
2042
|
+
bsLongFired.current = true;
|
|
2043
|
+
handleClear();
|
|
2044
|
+
}, 500);
|
|
2045
|
+
};
|
|
2046
|
+
const handleBackspaceClick = () => {
|
|
2047
|
+
clearBsTimer();
|
|
2048
|
+
if (bsLongFired.current) {
|
|
2049
|
+
bsLongFired.current = false;
|
|
2050
|
+
return;
|
|
2051
|
+
}
|
|
2052
|
+
handleBackspace();
|
|
2053
|
+
};
|
|
2054
|
+
(0, import_react6.useEffect)(() => () => clearBsTimer(), []);
|
|
2055
|
+
(0, import_react6.useEffect)(() => {
|
|
2056
|
+
if (!isOpen) return;
|
|
2057
|
+
const handler = (e) => {
|
|
2058
|
+
if (e.key === "Tab") {
|
|
2059
|
+
const root = dialogRef.current;
|
|
2060
|
+
if (!root) return;
|
|
2061
|
+
const focusable = Array.from(
|
|
2062
|
+
root.querySelectorAll("button:not([disabled])")
|
|
2063
|
+
).filter((el) => el.tabIndex !== -1);
|
|
2064
|
+
if (focusable.length === 0) {
|
|
2065
|
+
e.preventDefault();
|
|
2066
|
+
root.focus();
|
|
2067
|
+
return;
|
|
2068
|
+
}
|
|
2069
|
+
const first = focusable[0];
|
|
2070
|
+
const last = focusable[focusable.length - 1];
|
|
2071
|
+
const active = document.activeElement;
|
|
2072
|
+
if (e.shiftKey) {
|
|
2073
|
+
if (active === first || !root.contains(active)) {
|
|
2074
|
+
e.preventDefault();
|
|
2075
|
+
last.focus();
|
|
2076
|
+
}
|
|
2077
|
+
} else if (active === last || !root.contains(active)) {
|
|
2078
|
+
e.preventDefault();
|
|
2079
|
+
first.focus();
|
|
2080
|
+
}
|
|
2081
|
+
return;
|
|
2082
|
+
}
|
|
2083
|
+
if (e.key === "Enter") {
|
|
2084
|
+
const active = document.activeElement;
|
|
2085
|
+
if (active && active.tagName === "BUTTON" && dialogRef.current?.contains(active)) return;
|
|
2086
|
+
e.preventDefault();
|
|
2087
|
+
handleApply();
|
|
2088
|
+
} else if (e.key === "Escape") {
|
|
2089
|
+
e.preventDefault();
|
|
2090
|
+
onClose();
|
|
2091
|
+
} else if (e.key === "Backspace") {
|
|
2092
|
+
e.preventDefault();
|
|
2093
|
+
handleBackspace();
|
|
2094
|
+
} else if (/^[0-9]$/.test(e.key)) {
|
|
2095
|
+
e.preventDefault();
|
|
2096
|
+
appendDigit(e.key);
|
|
2097
|
+
} else if (e.key === ".") {
|
|
2098
|
+
e.preventDefault();
|
|
2099
|
+
appendDigit(".");
|
|
2100
|
+
} else if (e.key === "-") {
|
|
2101
|
+
e.preventDefault();
|
|
2102
|
+
handleToggleSign();
|
|
2103
|
+
}
|
|
2104
|
+
};
|
|
2105
|
+
window.addEventListener("keydown", handler);
|
|
2106
|
+
return () => window.removeEventListener("keydown", handler);
|
|
2107
|
+
}, [isOpen, handleApply, onClose, handleBackspace, appendDigit, handleToggleSign]);
|
|
2108
|
+
if (!isOpen) return null;
|
|
2109
|
+
const parsed = Number(inputValue);
|
|
2110
|
+
const hasNumber = inputValue !== "" && inputValue !== "-" && inputValue !== "." && inputValue !== "-." && !isNaN(parsed);
|
|
2111
|
+
const belowMin = hasNumber && parsed < min;
|
|
2112
|
+
const aboveMax = hasNumber && parsed > max;
|
|
2113
|
+
const outOfRange = belowMin || aboveMax;
|
|
2114
|
+
const isValid = hasNumber && !outOfRange;
|
|
2115
|
+
const alarmColor = "#dc2626";
|
|
2116
|
+
const limitStyle = (violated) => violated ? { color: alarmColor, fontWeight: 700, background: "#fee2e2", borderRadius: 3, padding: "0 3px" } : {};
|
|
2117
|
+
const keySize = touchOptimized ? 60 : 46;
|
|
2118
|
+
const keyFont = touchOptimized ? 22 : 18;
|
|
2119
|
+
const actionSize = touchOptimized ? 52 : 42;
|
|
2120
|
+
const keyStyle = {
|
|
2121
|
+
minWidth: 52,
|
|
2122
|
+
minHeight: keySize,
|
|
2123
|
+
fontSize: keyFont,
|
|
2124
|
+
fontWeight: 600,
|
|
2125
|
+
borderRadius: 8,
|
|
2126
|
+
border: "1px solid #e2e8f0",
|
|
2127
|
+
background: "#ffffff",
|
|
2128
|
+
color: "#0f172a",
|
|
2129
|
+
cursor: "pointer",
|
|
2130
|
+
display: "flex",
|
|
2131
|
+
alignItems: "center",
|
|
2132
|
+
justifyContent: "center",
|
|
2133
|
+
userSelect: "none",
|
|
2134
|
+
boxShadow: "0 1px 2px rgba(15, 23, 42, 0.06)"
|
|
2135
|
+
};
|
|
2136
|
+
const utilKeyStyle = {
|
|
2137
|
+
flex: 1,
|
|
2138
|
+
minHeight: touchOptimized ? 44 : 38,
|
|
2139
|
+
fontSize: 13,
|
|
2140
|
+
fontWeight: 600,
|
|
2141
|
+
borderRadius: 8,
|
|
2142
|
+
border: "1px solid #e2e8f0",
|
|
2143
|
+
background: "#f8fafc",
|
|
2144
|
+
color: "#64748b",
|
|
2145
|
+
cursor: "pointer",
|
|
2146
|
+
display: "flex",
|
|
2147
|
+
alignItems: "center",
|
|
2148
|
+
justifyContent: "center",
|
|
2149
|
+
userSelect: "none"
|
|
2150
|
+
};
|
|
2151
|
+
const reason = belowMin ? `Below minimum of ${min} ${unit}` : aboveMax ? `Above maximum of ${max} ${unit}` : "Type or tap to change the value";
|
|
2152
|
+
const backspaceInGrid = min >= 0;
|
|
2153
|
+
const BackspaceButton = ({ style, label }) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2154
|
+
"button",
|
|
2155
|
+
{
|
|
2156
|
+
type: "button",
|
|
2157
|
+
className: "np-key",
|
|
2158
|
+
tabIndex: -1,
|
|
2159
|
+
"aria-label": "Backspace",
|
|
2160
|
+
style,
|
|
2161
|
+
onPointerDown: handleBackspacePointerDown,
|
|
2162
|
+
onPointerUp: clearBsTimer,
|
|
2163
|
+
onPointerLeave: clearBsTimer,
|
|
2164
|
+
onClick: handleBackspaceClick,
|
|
2165
|
+
children: label
|
|
2166
|
+
}
|
|
2167
|
+
);
|
|
2168
|
+
return (
|
|
2169
|
+
// Backdrop
|
|
2170
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
2171
|
+
"div",
|
|
2172
|
+
{
|
|
2173
|
+
style: {
|
|
2174
|
+
position: "fixed",
|
|
2175
|
+
top: 0,
|
|
2176
|
+
left: 0,
|
|
2177
|
+
right: 0,
|
|
2178
|
+
bottom: 0,
|
|
2179
|
+
backgroundColor: "rgba(15, 23, 42, 0.4)",
|
|
2180
|
+
zIndex: 1e4,
|
|
2181
|
+
display: "flex",
|
|
2182
|
+
alignItems: "center",
|
|
2183
|
+
justifyContent: "center"
|
|
2184
|
+
},
|
|
2185
|
+
onClick: onClose,
|
|
2186
|
+
children: [
|
|
2187
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("style", { children: `
|
|
2188
|
+
.np-key { transition: background .1s, transform .05s; touch-action: manipulation; }
|
|
2189
|
+
.np-key:active:not(:disabled) { background:#e2e8f0; transform: translateY(1px); }
|
|
2190
|
+
.np-key:focus-visible, .np-action:focus-visible { outline: 3px solid #2563eb; outline-offset: 2px; }
|
|
2191
|
+
@keyframes np-blink { 0%,49%{opacity:1} 50%,100%{opacity:0} }
|
|
2192
|
+
.np-caret { display:inline-block; width:2px; height:1.1em; background:#2563eb; animation: np-blink 1s step-end infinite; }
|
|
2193
|
+
` }),
|
|
2194
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
2195
|
+
"div",
|
|
2196
|
+
{
|
|
2197
|
+
ref: dialogRef,
|
|
2198
|
+
role: "dialog",
|
|
2199
|
+
"aria-modal": "true",
|
|
2200
|
+
"aria-labelledby": titleId,
|
|
2201
|
+
tabIndex: -1,
|
|
2202
|
+
style: {
|
|
2203
|
+
width: touchOptimized ? "340px" : "300px",
|
|
2204
|
+
maxHeight: "90vh",
|
|
2205
|
+
overflow: "auto",
|
|
2206
|
+
background: "#ffffff",
|
|
2207
|
+
borderRadius: 12,
|
|
2208
|
+
border: "1px solid #e2e8f0",
|
|
2209
|
+
boxShadow: "0 10px 40px rgba(15, 23, 42, 0.2)",
|
|
2210
|
+
fontFamily: "'Inter', system-ui, sans-serif",
|
|
2211
|
+
outline: "none"
|
|
2212
|
+
},
|
|
2213
|
+
onClick: (e) => e.stopPropagation(),
|
|
2214
|
+
children: [
|
|
2215
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { padding: "14px 16px 0 16px" }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h3", { id: titleId, style: { margin: 0, fontSize: 15, fontWeight: 700, color: "#0f172a" }, children: deviceName ? `${deviceName} - ${parameterLabel}` : parameterLabel }) }),
|
|
2216
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { padding: 16, display: "flex", flexDirection: "column", gap: 10 }, children: [
|
|
2217
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
2218
|
+
"div",
|
|
2219
|
+
{
|
|
2220
|
+
style: {
|
|
2221
|
+
display: "flex",
|
|
2222
|
+
justifyContent: "space-between",
|
|
2223
|
+
fontSize: 12,
|
|
2224
|
+
color: "#64748b"
|
|
2225
|
+
},
|
|
2226
|
+
children: [
|
|
2227
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
|
|
2228
|
+
"Current: ",
|
|
2229
|
+
currentValue,
|
|
2230
|
+
" ",
|
|
2231
|
+
unit
|
|
2232
|
+
] }),
|
|
2233
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
|
|
2234
|
+
"Range: ",
|
|
2235
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: limitStyle(belowMin), children: min }),
|
|
2236
|
+
"-",
|
|
2237
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: limitStyle(aboveMax), children: max }),
|
|
2238
|
+
" ",
|
|
2239
|
+
unit
|
|
2240
|
+
] })
|
|
2241
|
+
]
|
|
2242
|
+
}
|
|
2243
|
+
),
|
|
2244
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
2245
|
+
"div",
|
|
2246
|
+
{
|
|
2247
|
+
"aria-live": "polite",
|
|
2248
|
+
"aria-atomic": "true",
|
|
2249
|
+
"aria-label": `Entered value ${inputValue || "0"} ${unit}`,
|
|
2250
|
+
style: {
|
|
2251
|
+
background: outOfRange ? "#fef2f2" : "#f8fafc",
|
|
2252
|
+
borderRadius: 8,
|
|
2253
|
+
padding: "10px 14px",
|
|
2254
|
+
fontSize: 28,
|
|
2255
|
+
fontWeight: 700,
|
|
2256
|
+
textAlign: "right",
|
|
2257
|
+
color: outOfRange ? alarmColor : "#0f172a",
|
|
2258
|
+
minHeight: 48,
|
|
2259
|
+
display: "flex",
|
|
2260
|
+
alignItems: "center",
|
|
2261
|
+
justifyContent: "flex-end",
|
|
2262
|
+
gap: 6,
|
|
2263
|
+
border: outOfRange ? "1.5px solid #fca5a5" : "1.5px solid #e2e8f0"
|
|
2264
|
+
},
|
|
2265
|
+
children: [
|
|
2266
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: inputValue || "0" }),
|
|
2267
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "np-caret", "aria-hidden": "true" }),
|
|
2268
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { fontSize: 14, color: "#94a3b8", fontWeight: 500 }, children: unit })
|
|
2269
|
+
]
|
|
2270
|
+
}
|
|
2271
|
+
),
|
|
2272
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2273
|
+
"div",
|
|
2274
|
+
{
|
|
2275
|
+
role: "status",
|
|
2276
|
+
"aria-live": "polite",
|
|
2277
|
+
style: {
|
|
2278
|
+
fontSize: 12,
|
|
2279
|
+
color: outOfRange ? alarmColor : "#94a3b8",
|
|
2280
|
+
fontWeight: outOfRange ? 600 : 400,
|
|
2281
|
+
textAlign: "right",
|
|
2282
|
+
minHeight: 16
|
|
2283
|
+
},
|
|
2284
|
+
children: reason
|
|
2285
|
+
}
|
|
2286
|
+
),
|
|
2287
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 5 }, children: [
|
|
2288
|
+
["7", "8", "9", "4", "5", "6", "1", "2", "3"].map((digit) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2289
|
+
"button",
|
|
2290
|
+
{
|
|
2291
|
+
type: "button",
|
|
2292
|
+
className: "np-key",
|
|
2293
|
+
tabIndex: -1,
|
|
2294
|
+
style: keyStyle,
|
|
2295
|
+
onClick: () => appendDigit(digit),
|
|
2296
|
+
children: digit
|
|
2297
|
+
},
|
|
2298
|
+
digit
|
|
2299
|
+
)),
|
|
2300
|
+
min < 0 ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2301
|
+
"button",
|
|
2302
|
+
{
|
|
2303
|
+
type: "button",
|
|
2304
|
+
className: "np-key",
|
|
2305
|
+
tabIndex: -1,
|
|
2306
|
+
"aria-label": "Toggle sign",
|
|
2307
|
+
style: { ...keyStyle, fontSize: 16, background: "#f8fafc", color: "#64748b" },
|
|
2308
|
+
onClick: handleToggleSign,
|
|
2309
|
+
children: "+/\u2212"
|
|
2310
|
+
}
|
|
2311
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(BackspaceButton, { style: { ...keyStyle, fontSize: 20, background: "#f8fafc", color: "#64748b" }, label: "\u232B" }),
|
|
2312
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", className: "np-key", tabIndex: -1, style: keyStyle, onClick: () => appendDigit("0"), children: "0" }),
|
|
2313
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2314
|
+
"button",
|
|
2315
|
+
{
|
|
2316
|
+
type: "button",
|
|
2317
|
+
className: "np-key",
|
|
2318
|
+
tabIndex: -1,
|
|
2319
|
+
"aria-label": "Decimal point",
|
|
2320
|
+
style: {
|
|
2321
|
+
...keyStyle,
|
|
2322
|
+
cursor: decimals === 0 ? "not-allowed" : "pointer",
|
|
2323
|
+
opacity: decimals === 0 ? 0.4 : 1
|
|
2324
|
+
},
|
|
2325
|
+
disabled: decimals === 0,
|
|
2326
|
+
onClick: () => appendDigit("."),
|
|
2327
|
+
children: "."
|
|
2328
|
+
}
|
|
2329
|
+
)
|
|
2330
|
+
] }),
|
|
2331
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { display: "flex", gap: 5 }, children: [
|
|
2332
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", className: "np-key", tabIndex: -1, style: utilKeyStyle, onClick: handleClear, children: "Clear" }),
|
|
2333
|
+
!backspaceInGrid && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(BackspaceButton, { style: utilKeyStyle, label: "Backspace" })
|
|
2334
|
+
] }),
|
|
2335
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { display: "flex", gap: 8, marginTop: 2 }, children: [
|
|
2336
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2337
|
+
"button",
|
|
2338
|
+
{
|
|
2339
|
+
type: "button",
|
|
2340
|
+
className: "np-action",
|
|
2341
|
+
onClick: onClose,
|
|
2342
|
+
style: {
|
|
2343
|
+
flex: 1,
|
|
2344
|
+
minHeight: actionSize,
|
|
2345
|
+
borderRadius: 8,
|
|
2346
|
+
border: "1px solid #e2e8f0",
|
|
2347
|
+
background: "#ffffff",
|
|
2348
|
+
color: "#0f172a",
|
|
2349
|
+
fontSize: 14,
|
|
2350
|
+
fontWeight: 600,
|
|
2351
|
+
cursor: "pointer"
|
|
2352
|
+
},
|
|
2353
|
+
children: "Cancel"
|
|
2354
|
+
}
|
|
2355
|
+
),
|
|
2356
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2357
|
+
"button",
|
|
2358
|
+
{
|
|
2359
|
+
type: "button",
|
|
2360
|
+
className: "np-action",
|
|
2361
|
+
onClick: handleApply,
|
|
2362
|
+
disabled: !isValid,
|
|
2363
|
+
"aria-label": isValid ? `Apply ${inputValue} ${unit}` : "Apply (enter a valid value)",
|
|
2364
|
+
style: {
|
|
2365
|
+
flex: 1,
|
|
2366
|
+
minHeight: actionSize,
|
|
2367
|
+
borderRadius: 8,
|
|
2368
|
+
border: "none",
|
|
2369
|
+
background: "#2563eb",
|
|
2370
|
+
color: "#ffffff",
|
|
2371
|
+
fontSize: 14,
|
|
2372
|
+
fontWeight: 600,
|
|
2373
|
+
cursor: isValid ? "pointer" : "not-allowed",
|
|
2374
|
+
opacity: isValid ? 1 : 0.4
|
|
2375
|
+
},
|
|
2376
|
+
children: "Apply"
|
|
2377
|
+
}
|
|
2378
|
+
)
|
|
2379
|
+
] })
|
|
2380
|
+
] })
|
|
2381
|
+
]
|
|
2382
|
+
}
|
|
2383
|
+
)
|
|
2384
|
+
]
|
|
2385
|
+
}
|
|
2386
|
+
)
|
|
2387
|
+
);
|
|
2388
|
+
};
|
|
2389
|
+
|
|
1946
2390
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.tsx
|
|
1947
|
-
var
|
|
2391
|
+
var import_react8 = __toESM(require("react"), 1);
|
|
1948
2392
|
var import_material3 = require("@mui/material");
|
|
1949
2393
|
|
|
1950
2394
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.styles.tsx
|
|
1951
2395
|
var import_material = require("@mui/material");
|
|
1952
2396
|
var import_styled = __toESM(require("@emotion/styled"), 1);
|
|
1953
|
-
var
|
|
2397
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1954
2398
|
var FullscreenContainer = (0, import_styled.default)(import_material.Box)(
|
|
1955
2399
|
({ leftCollapsed, rightCollapsed }) => {
|
|
1956
2400
|
const getGridTemplateAreas = () => {
|
|
@@ -2075,7 +2519,7 @@ var DisplayModeToggle = (0, import_styled.default)(import_material.IconButton)((
|
|
|
2075
2519
|
transform: "translateX(-50%) scale(1.05)"
|
|
2076
2520
|
}
|
|
2077
2521
|
}));
|
|
2078
|
-
var ChevronLeft = () => /* @__PURE__ */ (0,
|
|
2522
|
+
var ChevronLeft = () => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2079
2523
|
"div",
|
|
2080
2524
|
{
|
|
2081
2525
|
style: {
|
|
@@ -2087,7 +2531,7 @@ var ChevronLeft = () => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
|
2087
2531
|
}
|
|
2088
2532
|
}
|
|
2089
2533
|
);
|
|
2090
|
-
var ChevronRight = () => /* @__PURE__ */ (0,
|
|
2534
|
+
var ChevronRight = () => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2091
2535
|
"div",
|
|
2092
2536
|
{
|
|
2093
2537
|
style: {
|
|
@@ -2198,10 +2642,10 @@ var ScrollableSVGWrapper = (0, import_styled.default)("div")({
|
|
|
2198
2642
|
});
|
|
2199
2643
|
|
|
2200
2644
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.overlays.tsx
|
|
2201
|
-
var
|
|
2645
|
+
var import_react7 = require("react");
|
|
2202
2646
|
var import_material2 = require("@mui/material");
|
|
2203
2647
|
var import_styled2 = __toESM(require("@emotion/styled"), 1);
|
|
2204
|
-
var
|
|
2648
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2205
2649
|
var baseOverlayStyles = {
|
|
2206
2650
|
tank: {
|
|
2207
2651
|
background: "linear-gradient(135deg, rgba(69, 90, 120, 0.95) 0%, rgba(52, 73, 94, 0.95) 100%)",
|
|
@@ -2263,8 +2707,8 @@ var SVGLockedOverlay = ({
|
|
|
2263
2707
|
onClick,
|
|
2264
2708
|
containerSelector = ".tff-svg-container"
|
|
2265
2709
|
}) => {
|
|
2266
|
-
const [svgOffset, setSvgOffset] = (0,
|
|
2267
|
-
(0,
|
|
2710
|
+
const [svgOffset, setSvgOffset] = (0, import_react7.useState)({ x: 0, y: 0 });
|
|
2711
|
+
(0, import_react7.useEffect)(() => {
|
|
2268
2712
|
const updateSvgOffset = () => {
|
|
2269
2713
|
const containerElement = document.querySelector(containerSelector);
|
|
2270
2714
|
const svgElement = containerElement?.querySelector("svg");
|
|
@@ -2284,7 +2728,7 @@ var SVGLockedOverlay = ({
|
|
|
2284
2728
|
const pixelX = svgX + svgOffset.x;
|
|
2285
2729
|
const pixelY = svgY + svgOffset.y;
|
|
2286
2730
|
const appliedStyle = theme ? { ...overlayStyles[theme], ...style } : style;
|
|
2287
|
-
return /* @__PURE__ */ (0,
|
|
2731
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2288
2732
|
import_material2.Box,
|
|
2289
2733
|
{
|
|
2290
2734
|
className: `svg-locked-overlay ${className}`.trim(),
|
|
@@ -2348,7 +2792,7 @@ var CardUnit = (0, import_styled2.default)("div")({
|
|
|
2348
2792
|
});
|
|
2349
2793
|
|
|
2350
2794
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.visuals.tsx
|
|
2351
|
-
var
|
|
2795
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2352
2796
|
var TrendLine = ({
|
|
2353
2797
|
values,
|
|
2354
2798
|
width = 60,
|
|
@@ -2358,7 +2802,7 @@ var TrendLine = ({
|
|
|
2358
2802
|
backgroundColor = "rgba(255, 255, 255, 0.1)"
|
|
2359
2803
|
}) => {
|
|
2360
2804
|
if (!values || values.length < 2) {
|
|
2361
|
-
return /* @__PURE__ */ (0,
|
|
2805
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2362
2806
|
"div",
|
|
2363
2807
|
{
|
|
2364
2808
|
style: {
|
|
@@ -2370,7 +2814,7 @@ var TrendLine = ({
|
|
|
2370
2814
|
alignItems: "center",
|
|
2371
2815
|
justifyContent: "center"
|
|
2372
2816
|
},
|
|
2373
|
-
children: /* @__PURE__ */ (0,
|
|
2817
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { style: { fontSize: "8px", color: "#ccc" }, children: "No data" })
|
|
2374
2818
|
}
|
|
2375
2819
|
);
|
|
2376
2820
|
}
|
|
@@ -2382,7 +2826,7 @@ var TrendLine = ({
|
|
|
2382
2826
|
const x = 4 + i / (values.length - 1) * (width - 8);
|
|
2383
2827
|
return i === 0 ? `M ${x} ${y}` : `L ${x} ${y}`;
|
|
2384
2828
|
}).join(" ");
|
|
2385
|
-
return /* @__PURE__ */ (0,
|
|
2829
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2386
2830
|
"div",
|
|
2387
2831
|
{
|
|
2388
2832
|
style: {
|
|
@@ -2393,8 +2837,8 @@ var TrendLine = ({
|
|
|
2393
2837
|
position: "relative",
|
|
2394
2838
|
overflow: "hidden"
|
|
2395
2839
|
},
|
|
2396
|
-
children: /* @__PURE__ */ (0,
|
|
2397
|
-
/* @__PURE__ */ (0,
|
|
2840
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("svg", { width, height, style: { position: "absolute", top: 0, left: 0 }, children: [
|
|
2841
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2398
2842
|
"path",
|
|
2399
2843
|
{
|
|
2400
2844
|
d: pathData,
|
|
@@ -2405,7 +2849,7 @@ var TrendLine = ({
|
|
|
2405
2849
|
strokeLinejoin: "round"
|
|
2406
2850
|
}
|
|
2407
2851
|
),
|
|
2408
|
-
/* @__PURE__ */ (0,
|
|
2852
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2409
2853
|
"circle",
|
|
2410
2854
|
{
|
|
2411
2855
|
cx: 4 + (width - 8),
|
|
@@ -2443,7 +2887,7 @@ var CircularGauge = ({
|
|
|
2443
2887
|
const borderColor = isHex ? hexToRgba(color, 0.9) : color;
|
|
2444
2888
|
const backgroundColor = isHex ? hexToRgba(color, 0.15) : color;
|
|
2445
2889
|
const borderStrokeColor = isHex ? hexToRgba(color, 0.4) : color;
|
|
2446
|
-
return /* @__PURE__ */ (0,
|
|
2890
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
2447
2891
|
"div",
|
|
2448
2892
|
{
|
|
2449
2893
|
style: {
|
|
@@ -2452,7 +2896,7 @@ var CircularGauge = ({
|
|
|
2452
2896
|
alignItems: "center"
|
|
2453
2897
|
},
|
|
2454
2898
|
children: [
|
|
2455
|
-
/* @__PURE__ */ (0,
|
|
2899
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
2456
2900
|
"div",
|
|
2457
2901
|
{
|
|
2458
2902
|
style: {
|
|
@@ -2464,8 +2908,8 @@ var CircularGauge = ({
|
|
|
2464
2908
|
border: `1px solid ${borderStrokeColor}`
|
|
2465
2909
|
},
|
|
2466
2910
|
children: [
|
|
2467
|
-
/* @__PURE__ */ (0,
|
|
2468
|
-
/* @__PURE__ */ (0,
|
|
2911
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("svg", { width: size, height: size, style: { transform: "rotate(-90deg)" }, children: [
|
|
2912
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2469
2913
|
"circle",
|
|
2470
2914
|
{
|
|
2471
2915
|
cx: size / 2,
|
|
@@ -2476,7 +2920,7 @@ var CircularGauge = ({
|
|
|
2476
2920
|
strokeWidth: 1
|
|
2477
2921
|
}
|
|
2478
2922
|
),
|
|
2479
|
-
/* @__PURE__ */ (0,
|
|
2923
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2480
2924
|
"circle",
|
|
2481
2925
|
{
|
|
2482
2926
|
cx: size / 2,
|
|
@@ -2487,7 +2931,7 @@ var CircularGauge = ({
|
|
|
2487
2931
|
fill: "transparent"
|
|
2488
2932
|
}
|
|
2489
2933
|
),
|
|
2490
|
-
/* @__PURE__ */ (0,
|
|
2934
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2491
2935
|
"circle",
|
|
2492
2936
|
{
|
|
2493
2937
|
cx: size / 2,
|
|
@@ -2503,7 +2947,7 @@ var CircularGauge = ({
|
|
|
2503
2947
|
}
|
|
2504
2948
|
)
|
|
2505
2949
|
] }),
|
|
2506
|
-
/* @__PURE__ */ (0,
|
|
2950
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
2507
2951
|
"div",
|
|
2508
2952
|
{
|
|
2509
2953
|
style: {
|
|
@@ -2519,14 +2963,14 @@ var CircularGauge = ({
|
|
|
2519
2963
|
},
|
|
2520
2964
|
children: [
|
|
2521
2965
|
value.toFixed(1),
|
|
2522
|
-
/* @__PURE__ */ (0,
|
|
2966
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { style: { fontSize: "8px", opacity: 0.9, color: "white" }, children: unit })
|
|
2523
2967
|
]
|
|
2524
2968
|
}
|
|
2525
2969
|
)
|
|
2526
2970
|
]
|
|
2527
2971
|
}
|
|
2528
2972
|
),
|
|
2529
|
-
/* @__PURE__ */ (0,
|
|
2973
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2530
2974
|
"div",
|
|
2531
2975
|
{
|
|
2532
2976
|
style: {
|
|
@@ -2557,7 +3001,7 @@ var Sparkline = ({ data, width, height, color }) => {
|
|
|
2557
3001
|
const y = height - 8 - (value - min) / range * (height - 8);
|
|
2558
3002
|
return `${x + 4},${y + 4}`;
|
|
2559
3003
|
}).join(" ");
|
|
2560
|
-
return /* @__PURE__ */ (0,
|
|
3004
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2561
3005
|
"div",
|
|
2562
3006
|
{
|
|
2563
3007
|
style: {
|
|
@@ -2571,7 +3015,7 @@ var Sparkline = ({ data, width, height, color }) => {
|
|
|
2571
3015
|
justifyContent: "center",
|
|
2572
3016
|
boxShadow: "0 1px 3px rgba(0, 0, 0, 0.2)"
|
|
2573
3017
|
},
|
|
2574
|
-
children: /* @__PURE__ */ (0,
|
|
3018
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("svg", { width, height, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("polyline", { points, fill: "none", stroke: color, strokeWidth: "1.5", opacity: "0.9" }) })
|
|
2575
3019
|
}
|
|
2576
3020
|
);
|
|
2577
3021
|
};
|
|
@@ -2585,8 +3029,8 @@ var EquipmentIndicatorWithSparkline = ({
|
|
|
2585
3029
|
sparklineOffset = { x: 40, y: 0 }
|
|
2586
3030
|
}) => {
|
|
2587
3031
|
const hasSparkline = sparklineData && sparklineData.length > 1 && Math.max(...sparklineData) !== Math.min(...sparklineData);
|
|
2588
|
-
return /* @__PURE__ */ (0,
|
|
2589
|
-
/* @__PURE__ */ (0,
|
|
3032
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
|
|
3033
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SVGLockedOverlay, { svgX, svgY, style: { transform: "translate(-50%, -50%)" }, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2590
3034
|
"div",
|
|
2591
3035
|
{
|
|
2592
3036
|
style: {
|
|
@@ -2607,7 +3051,7 @@ var EquipmentIndicatorWithSparkline = ({
|
|
|
2607
3051
|
children: label
|
|
2608
3052
|
}
|
|
2609
3053
|
) }),
|
|
2610
|
-
hasSparkline && /* @__PURE__ */ (0,
|
|
3054
|
+
hasSparkline && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SVGLockedOverlay, { svgX: svgX + sparklineOffset.x, svgY: svgY + sparklineOffset.y, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Sparkline, { data: sparklineData, width: 60, height: 20, color }) })
|
|
2611
3055
|
] });
|
|
2612
3056
|
};
|
|
2613
3057
|
var EquipmentIndicator = ({
|
|
@@ -2620,7 +3064,7 @@ var EquipmentIndicator = ({
|
|
|
2620
3064
|
className
|
|
2621
3065
|
}) => {
|
|
2622
3066
|
const overlayStyle = style !== void 0 ? { transform: "translate(-50%, -50%)", ...style } : { transform: "translate(-50%, -50%)" };
|
|
2623
|
-
return /* @__PURE__ */ (0,
|
|
3067
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SVGLockedOverlay, { svgX, svgY, style: overlayStyle, className, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2624
3068
|
"div",
|
|
2625
3069
|
{
|
|
2626
3070
|
style: {
|
|
@@ -2644,7 +3088,7 @@ var EquipmentIndicator = ({
|
|
|
2644
3088
|
};
|
|
2645
3089
|
|
|
2646
3090
|
// src/components/layout/FullscreenWorkspace/FullscreenWorkspace.tsx
|
|
2647
|
-
var
|
|
3091
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2648
3092
|
function FullscreenWorkspace({
|
|
2649
3093
|
svgContent,
|
|
2650
3094
|
overlays,
|
|
@@ -2672,10 +3116,10 @@ function FullscreenWorkspace({
|
|
|
2672
3116
|
className = "",
|
|
2673
3117
|
...rest
|
|
2674
3118
|
}) {
|
|
2675
|
-
const [leftCollapsedState, setLeftCollapsedState] =
|
|
2676
|
-
const [rightCollapsedState, setRightCollapsedState] =
|
|
2677
|
-
const [internalDisplayMode, setInternalDisplayMode] =
|
|
2678
|
-
const [internalTab, setInternalTab] =
|
|
3119
|
+
const [leftCollapsedState, setLeftCollapsedState] = import_react8.default.useState(defaultLeftCollapsed);
|
|
3120
|
+
const [rightCollapsedState, setRightCollapsedState] = import_react8.default.useState(defaultRightCollapsed);
|
|
3121
|
+
const [internalDisplayMode, setInternalDisplayMode] = import_react8.default.useState(displayMode ?? defaultDisplayMode);
|
|
3122
|
+
const [internalTab, setInternalTab] = import_react8.default.useState(
|
|
2679
3123
|
tabs && tabs.length > 0 ? tabs[0].value : ""
|
|
2680
3124
|
);
|
|
2681
3125
|
const leftCollapsed = leftCollapsedProp ?? leftCollapsedState;
|
|
@@ -2683,10 +3127,10 @@ function FullscreenWorkspace({
|
|
|
2683
3127
|
const isDisplayModeControlled = displayMode !== void 0;
|
|
2684
3128
|
const currentDisplayMode = isDisplayModeControlled ? displayMode : internalDisplayMode;
|
|
2685
3129
|
const isTabControlled = activeTab !== void 0 && activeTab !== null;
|
|
2686
|
-
const resolvedTabs =
|
|
3130
|
+
const resolvedTabs = import_react8.default.useMemo(() => tabs ?? [], [tabs]);
|
|
2687
3131
|
const defaultTabValue = resolvedTabs.length > 0 ? resolvedTabs[0].value : "";
|
|
2688
3132
|
const currentTab = isTabControlled ? activeTab : internalTab || defaultTabValue;
|
|
2689
|
-
|
|
3133
|
+
import_react8.default.useEffect(() => {
|
|
2690
3134
|
if (resolvedTabs.length > 0) {
|
|
2691
3135
|
const values = resolvedTabs.map((tab) => tab.value);
|
|
2692
3136
|
if (!values.includes(currentTab)) {
|
|
@@ -2695,7 +3139,7 @@ function FullscreenWorkspace({
|
|
|
2695
3139
|
}
|
|
2696
3140
|
}
|
|
2697
3141
|
}, [resolvedTabs, activeTab, currentTab, defaultTabValue]);
|
|
2698
|
-
|
|
3142
|
+
import_react8.default.useEffect(() => {
|
|
2699
3143
|
if (displayMode !== void 0) {
|
|
2700
3144
|
setInternalDisplayMode(displayMode);
|
|
2701
3145
|
}
|
|
@@ -2730,7 +3174,7 @@ function FullscreenWorkspace({
|
|
|
2730
3174
|
const currentTabContent = resolvedTabs.find((tab) => tab.value === currentTab)?.content ?? null;
|
|
2731
3175
|
const showLeftToggle = Boolean(leftPanel);
|
|
2732
3176
|
const showRightToggle = Boolean(rightPanel);
|
|
2733
|
-
return /* @__PURE__ */ (0,
|
|
3177
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
2734
3178
|
FullscreenContainer,
|
|
2735
3179
|
{
|
|
2736
3180
|
leftCollapsed,
|
|
@@ -2738,25 +3182,25 @@ function FullscreenWorkspace({
|
|
|
2738
3182
|
className: `tff-svg-container ${className}`.trim(),
|
|
2739
3183
|
...rest,
|
|
2740
3184
|
children: [
|
|
2741
|
-
showLeftToggle && /* @__PURE__ */ (0,
|
|
3185
|
+
showLeftToggle && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2742
3186
|
LeftToggleButton,
|
|
2743
3187
|
{
|
|
2744
3188
|
collapsed: leftCollapsed,
|
|
2745
3189
|
onClick: handleLeftToggle,
|
|
2746
3190
|
"aria-label": leftCollapsed ? "Expand left panel" : "Collapse left panel",
|
|
2747
|
-
children: leftCollapsed ? /* @__PURE__ */ (0,
|
|
3191
|
+
children: leftCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ChevronRight, {}) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ChevronLeft, {})
|
|
2748
3192
|
}
|
|
2749
3193
|
),
|
|
2750
|
-
showRightToggle && /* @__PURE__ */ (0,
|
|
3194
|
+
showRightToggle && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2751
3195
|
RightToggleButton,
|
|
2752
3196
|
{
|
|
2753
3197
|
collapsed: rightCollapsed,
|
|
2754
3198
|
onClick: handleRightToggle,
|
|
2755
3199
|
"aria-label": rightCollapsed ? "Expand right panel" : "Collapse right panel",
|
|
2756
|
-
children: rightCollapsed ? /* @__PURE__ */ (0,
|
|
3200
|
+
children: rightCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ChevronLeft, {}) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ChevronRight, {})
|
|
2757
3201
|
}
|
|
2758
3202
|
),
|
|
2759
|
-
showDisplayModeToggle && /* @__PURE__ */ (0,
|
|
3203
|
+
showDisplayModeToggle && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2760
3204
|
DisplayModeToggle,
|
|
2761
3205
|
{
|
|
2762
3206
|
mode: currentDisplayMode,
|
|
@@ -2765,9 +3209,9 @@ function FullscreenWorkspace({
|
|
|
2765
3209
|
children: currentDisplayMode === "dashboard" ? "Dashboard Mode" : "Standard Mode"
|
|
2766
3210
|
}
|
|
2767
3211
|
),
|
|
2768
|
-
/* @__PURE__ */ (0,
|
|
2769
|
-
showZoomControls && /* @__PURE__ */ (0,
|
|
2770
|
-
/* @__PURE__ */ (0,
|
|
3212
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(SVGArea, { children: [
|
|
3213
|
+
showZoomControls && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(ZoomControls, { children: [
|
|
3214
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2771
3215
|
ZoomButton,
|
|
2772
3216
|
{
|
|
2773
3217
|
onClick: onZoomIn,
|
|
@@ -2777,7 +3221,7 @@ function FullscreenWorkspace({
|
|
|
2777
3221
|
children: "+"
|
|
2778
3222
|
}
|
|
2779
3223
|
),
|
|
2780
|
-
/* @__PURE__ */ (0,
|
|
3224
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2781
3225
|
ZoomButton,
|
|
2782
3226
|
{
|
|
2783
3227
|
onClick: onZoomOut,
|
|
@@ -2787,7 +3231,7 @@ function FullscreenWorkspace({
|
|
|
2787
3231
|
children: "-"
|
|
2788
3232
|
}
|
|
2789
3233
|
),
|
|
2790
|
-
onResetZoom && /* @__PURE__ */ (0,
|
|
3234
|
+
onResetZoom && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2791
3235
|
ZoomButton,
|
|
2792
3236
|
{
|
|
2793
3237
|
onClick: onResetZoom,
|
|
@@ -2798,44 +3242,44 @@ function FullscreenWorkspace({
|
|
|
2798
3242
|
}
|
|
2799
3243
|
)
|
|
2800
3244
|
] }),
|
|
2801
|
-
/* @__PURE__ */ (0,
|
|
3245
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ScrollableSVGWrapper, { className: "svg-scroll-wrapper", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(FixedSVGContainer, { className: "svg-container", children: [
|
|
2802
3246
|
svgContent,
|
|
2803
3247
|
overlays
|
|
2804
3248
|
] }) })
|
|
2805
3249
|
] }),
|
|
2806
|
-
/* @__PURE__ */ (0,
|
|
2807
|
-
/* @__PURE__ */ (0,
|
|
3250
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(LeftPanel, { collapsed: leftCollapsed, children: resolvedTabs.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
3251
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2808
3252
|
PanelTabs,
|
|
2809
3253
|
{
|
|
2810
3254
|
value: currentTab,
|
|
2811
3255
|
onChange: handleTabChangeInternal,
|
|
2812
3256
|
"aria-label": "Left panel tabs",
|
|
2813
|
-
children: resolvedTabs.map((tab) => /* @__PURE__ */ (0,
|
|
3257
|
+
children: resolvedTabs.map((tab) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_material3.Tab, { label: tab.label, value: tab.value }, tab.value))
|
|
2814
3258
|
}
|
|
2815
3259
|
),
|
|
2816
|
-
/* @__PURE__ */ (0,
|
|
3260
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PanelContent, { children: currentTabContent })
|
|
2817
3261
|
] }) : leftPanel }),
|
|
2818
|
-
/* @__PURE__ */ (0,
|
|
2819
|
-
/* @__PURE__ */ (0,
|
|
3262
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(RightPanel, { collapsed: rightCollapsed, children: rightPanel }),
|
|
3263
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(FooterPanel, { children: footer })
|
|
2820
3264
|
]
|
|
2821
3265
|
}
|
|
2822
3266
|
);
|
|
2823
3267
|
}
|
|
2824
3268
|
|
|
2825
3269
|
// src/theme/ThemeContext.tsx
|
|
2826
|
-
var
|
|
2827
|
-
var
|
|
2828
|
-
var ThemeContext = (0,
|
|
3270
|
+
var import_react9 = require("react");
|
|
3271
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
3272
|
+
var ThemeContext = (0, import_react9.createContext)(void 0);
|
|
2829
3273
|
var useTheme = () => {
|
|
2830
|
-
const context = (0,
|
|
3274
|
+
const context = (0, import_react9.useContext)(ThemeContext);
|
|
2831
3275
|
if (!context) {
|
|
2832
3276
|
throw new Error("useTheme must be used within a ThemeProvider");
|
|
2833
3277
|
}
|
|
2834
3278
|
return context;
|
|
2835
3279
|
};
|
|
2836
3280
|
var ThemeProvider = ({ children }) => {
|
|
2837
|
-
const [theme, setThemeState] = (0,
|
|
2838
|
-
(0,
|
|
3281
|
+
const [theme, setThemeState] = (0, import_react9.useState)("modern");
|
|
3282
|
+
(0, import_react9.useEffect)(() => {
|
|
2839
3283
|
document.body.className = "";
|
|
2840
3284
|
document.body.classList.add(`theme-${theme}`);
|
|
2841
3285
|
document.documentElement.className = "";
|
|
@@ -2847,11 +3291,11 @@ var ThemeProvider = ({ children }) => {
|
|
|
2847
3291
|
const setTheme = (newTheme) => {
|
|
2848
3292
|
setThemeState(newTheme);
|
|
2849
3293
|
};
|
|
2850
|
-
return /* @__PURE__ */ (0,
|
|
3294
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ThemeContext.Provider, { value: { theme, toggleTheme, setTheme }, children });
|
|
2851
3295
|
};
|
|
2852
3296
|
|
|
2853
3297
|
// src/theme/ThemeToggle.tsx
|
|
2854
|
-
var
|
|
3298
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
2855
3299
|
var ThemeToggle = ({
|
|
2856
3300
|
size = "medium",
|
|
2857
3301
|
position = "top-right",
|
|
@@ -2922,15 +3366,15 @@ var ThemeToggle = ({
|
|
|
2922
3366
|
transition: "all 0.2s ease",
|
|
2923
3367
|
boxShadow: "0 2px 4px rgba(0, 0, 0, 0.2)"
|
|
2924
3368
|
};
|
|
2925
|
-
return /* @__PURE__ */ (0,
|
|
2926
|
-
/* @__PURE__ */ (0,
|
|
2927
|
-
/* @__PURE__ */ (0,
|
|
2928
|
-
/* @__PURE__ */ (0,
|
|
3369
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: currentStyle, onClick: toggleTheme, className, ...props, children: [
|
|
3370
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { children: theme === "modern" ? "\u{1F3A8} Modern" : "\u{1F3ED} HMI" }),
|
|
3371
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: toggleStyle, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: thumbStyle }) }),
|
|
3372
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { style: { fontSize: "0.75rem", opacity: 0.8 }, children: theme === "modern" ? "Industrial Design" : "High Performance" })
|
|
2929
3373
|
] });
|
|
2930
3374
|
};
|
|
2931
3375
|
|
|
2932
3376
|
// src/components/PIDCanvas/PIDCanvas.tsx
|
|
2933
|
-
var
|
|
3377
|
+
var import_react17 = require("react");
|
|
2934
3378
|
|
|
2935
3379
|
// src/diagram/symbols/mockSymbolLibrary.ts
|
|
2936
3380
|
var mockSymbolLibrary = {
|
|
@@ -4151,7 +4595,7 @@ function getAvailableSymbols() {
|
|
|
4151
4595
|
}
|
|
4152
4596
|
|
|
4153
4597
|
// src/components/PIDCanvas/NodeRenderer.tsx
|
|
4154
|
-
var
|
|
4598
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
4155
4599
|
function NodeRenderer({
|
|
4156
4600
|
nodes: nodes2,
|
|
4157
4601
|
selectedNodeIds,
|
|
@@ -4163,13 +4607,13 @@ function NodeRenderer({
|
|
|
4163
4607
|
enableDrag = false,
|
|
4164
4608
|
statusColorMap
|
|
4165
4609
|
}) {
|
|
4166
|
-
return /* @__PURE__ */ (0,
|
|
4610
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("g", { id: "layer-nodes", children: nodes2.filter((node) => node.visible !== false).map((node) => {
|
|
4167
4611
|
const symbol = getSymbolDefinition(node.symbolId);
|
|
4168
4612
|
const isSelected = selectedNodeIds?.has(node.id) ?? false;
|
|
4169
4613
|
const isDragging = draggingNodeId === node.id;
|
|
4170
4614
|
if (!symbol) {
|
|
4171
|
-
return /* @__PURE__ */ (0,
|
|
4172
|
-
/* @__PURE__ */ (0,
|
|
4615
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("g", { children: [
|
|
4616
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
4173
4617
|
"circle",
|
|
4174
4618
|
{
|
|
4175
4619
|
cx: node.transform.x,
|
|
@@ -4181,7 +4625,7 @@ function NodeRenderer({
|
|
|
4181
4625
|
strokeWidth: "2"
|
|
4182
4626
|
}
|
|
4183
4627
|
),
|
|
4184
|
-
/* @__PURE__ */ (0,
|
|
4628
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
4185
4629
|
"text",
|
|
4186
4630
|
{
|
|
4187
4631
|
x: node.transform.x,
|
|
@@ -4223,7 +4667,7 @@ function NodeRenderer({
|
|
|
4223
4667
|
const statusEntry = resolveStatusColor(node.status, statusColorMap);
|
|
4224
4668
|
const fillColor = node.customColors?.fill ?? statusEntry.fill;
|
|
4225
4669
|
const strokeColor = node.customColors?.stroke ?? statusEntry.stroke;
|
|
4226
|
-
return /* @__PURE__ */ (0,
|
|
4670
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
4227
4671
|
"g",
|
|
4228
4672
|
{
|
|
4229
4673
|
"data-node-id": node.id,
|
|
@@ -4256,7 +4700,7 @@ function NodeRenderer({
|
|
|
4256
4700
|
}
|
|
4257
4701
|
},
|
|
4258
4702
|
children: [
|
|
4259
|
-
isSelected && /* @__PURE__ */ (0,
|
|
4703
|
+
isSelected && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
4260
4704
|
"rect",
|
|
4261
4705
|
{
|
|
4262
4706
|
x: "-5",
|
|
@@ -4271,7 +4715,7 @@ function NodeRenderer({
|
|
|
4271
4715
|
pointerEvents: "none"
|
|
4272
4716
|
}
|
|
4273
4717
|
),
|
|
4274
|
-
/* @__PURE__ */ (0,
|
|
4718
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
4275
4719
|
"g",
|
|
4276
4720
|
{
|
|
4277
4721
|
dangerouslySetInnerHTML: { __html: symbol.svgContent },
|
|
@@ -4279,7 +4723,7 @@ function NodeRenderer({
|
|
|
4279
4723
|
style: { pointerEvents: "auto" }
|
|
4280
4724
|
}
|
|
4281
4725
|
),
|
|
4282
|
-
/* @__PURE__ */ (0,
|
|
4726
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
4283
4727
|
"text",
|
|
4284
4728
|
{
|
|
4285
4729
|
x: symbol.viewBox.width / 2 + (node.labelOffset?.x ?? 0),
|
|
@@ -4300,7 +4744,7 @@ function NodeRenderer({
|
|
|
4300
4744
|
}
|
|
4301
4745
|
|
|
4302
4746
|
// src/components/PIDCanvas/PipeRenderer.tsx
|
|
4303
|
-
var
|
|
4747
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
4304
4748
|
function PipeRenderer({
|
|
4305
4749
|
pipes,
|
|
4306
4750
|
selectedPipeIds,
|
|
@@ -4315,7 +4759,7 @@ function PipeRenderer({
|
|
|
4315
4759
|
waypointDragOffset,
|
|
4316
4760
|
onPipeSegmentClick
|
|
4317
4761
|
}) {
|
|
4318
|
-
return /* @__PURE__ */ (0,
|
|
4762
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("g", { id: "layer-pipes", children: pipes.filter((pipe) => pipe.visible !== false).map((pipe) => {
|
|
4319
4763
|
const isSelected = selectedPipeIds?.has(pipe.id) ?? false;
|
|
4320
4764
|
const isEditing = enableWaypointEditing && editingPipeId === pipe.id;
|
|
4321
4765
|
const showEditingControls = enableWaypointEditing && isSelected;
|
|
@@ -4334,7 +4778,7 @@ function PipeRenderer({
|
|
|
4334
4778
|
const strokeWidth = isSelected ? (pipeStyle.strokeWidth || 3) + 2 : pipeStyle.strokeWidth || 3;
|
|
4335
4779
|
const strokeDasharray = pipeStyle.strokeDasharray;
|
|
4336
4780
|
const opacity = pipeStyle.opacity !== void 0 ? pipeStyle.opacity : 1;
|
|
4337
|
-
return /* @__PURE__ */ (0,
|
|
4781
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
4338
4782
|
"g",
|
|
4339
4783
|
{
|
|
4340
4784
|
"data-pipe-id": pipe.id,
|
|
@@ -4347,8 +4791,8 @@ function PipeRenderer({
|
|
|
4347
4791
|
cursor: onPipeClick ? "pointer" : "default"
|
|
4348
4792
|
},
|
|
4349
4793
|
children: [
|
|
4350
|
-
!enableWaypointEditing && /* @__PURE__ */ (0,
|
|
4351
|
-
onPipeClick && /* @__PURE__ */ (0,
|
|
4794
|
+
!enableWaypointEditing && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
4795
|
+
onPipeClick && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
4352
4796
|
"polyline",
|
|
4353
4797
|
{
|
|
4354
4798
|
points: pointsString,
|
|
@@ -4360,7 +4804,7 @@ function PipeRenderer({
|
|
|
4360
4804
|
pointerEvents: "stroke"
|
|
4361
4805
|
}
|
|
4362
4806
|
),
|
|
4363
|
-
/* @__PURE__ */ (0,
|
|
4807
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
4364
4808
|
"polyline",
|
|
4365
4809
|
{
|
|
4366
4810
|
points: pointsString,
|
|
@@ -4384,7 +4828,7 @@ function PipeRenderer({
|
|
|
4384
4828
|
const waypointSize = isSelectedWaypoint ? 8 : isDragging ? 8 : showEditingControls ? 6 : isSelected ? 3 : 2;
|
|
4385
4829
|
const waypointOpacity = isSelectedWaypoint ? 1 : isDragging ? 1 : showEditingControls ? 0.9 : isSelected ? 0.8 : 0.5;
|
|
4386
4830
|
const waypointColor = isSelectedWaypoint ? "#3b82f6" : isEndpoint && showEditingControls ? "#f59e0b" : isDragging ? "#10b981" : stroke;
|
|
4387
|
-
return /* @__PURE__ */ (0,
|
|
4831
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
4388
4832
|
"circle",
|
|
4389
4833
|
{
|
|
4390
4834
|
cx: point.x,
|
|
@@ -4421,12 +4865,12 @@ function PipeRenderer({
|
|
|
4421
4865
|
`${pipe.id}-point-${idx}`
|
|
4422
4866
|
);
|
|
4423
4867
|
}),
|
|
4424
|
-
showEditingControls && onPipeSegmentClick && displayPoints.length >= 2 && /* @__PURE__ */ (0,
|
|
4868
|
+
showEditingControls && onPipeSegmentClick && displayPoints.length >= 2 && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_jsx_runtime17.Fragment, { children: displayPoints.slice(0, -1).map((point, idx) => {
|
|
4425
4869
|
const nextPoint = displayPoints[idx + 1];
|
|
4426
4870
|
const midX = (point.x + nextPoint.x) / 2;
|
|
4427
4871
|
const midY = (point.y + nextPoint.y) / 2;
|
|
4428
|
-
return /* @__PURE__ */ (0,
|
|
4429
|
-
/* @__PURE__ */ (0,
|
|
4872
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("g", { children: [
|
|
4873
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
4430
4874
|
"circle",
|
|
4431
4875
|
{
|
|
4432
4876
|
cx: midX,
|
|
@@ -4442,7 +4886,7 @@ function PipeRenderer({
|
|
|
4442
4886
|
}
|
|
4443
4887
|
}
|
|
4444
4888
|
),
|
|
4445
|
-
/* @__PURE__ */ (0,
|
|
4889
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
4446
4890
|
"circle",
|
|
4447
4891
|
{
|
|
4448
4892
|
cx: midX,
|
|
@@ -4458,7 +4902,7 @@ function PipeRenderer({
|
|
|
4458
4902
|
)
|
|
4459
4903
|
] }, `${pipe.id}-segment-${idx}`);
|
|
4460
4904
|
}) }),
|
|
4461
|
-
pipe.showLabel !== false && pipe.label && pipe.routePoints.length >= 2 && /* @__PURE__ */ (0,
|
|
4905
|
+
pipe.showLabel !== false && pipe.label && pipe.routePoints.length >= 2 && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
4462
4906
|
"text",
|
|
4463
4907
|
{
|
|
4464
4908
|
x: pipe.routePoints[Math.floor(pipe.routePoints.length / 2)].x + (pipe.labelOffset?.x ?? 0),
|
|
@@ -4480,7 +4924,7 @@ function PipeRenderer({
|
|
|
4480
4924
|
}
|
|
4481
4925
|
|
|
4482
4926
|
// src/components/PIDCanvas/DataOverlay.tsx
|
|
4483
|
-
var
|
|
4927
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
4484
4928
|
function DataOverlay({
|
|
4485
4929
|
nodeId,
|
|
4486
4930
|
x,
|
|
@@ -4502,7 +4946,7 @@ function DataOverlay({
|
|
|
4502
4946
|
const offsetX = display?.offsetX ?? 0;
|
|
4503
4947
|
const offsetY = display?.offsetY ?? 0;
|
|
4504
4948
|
if (!showValue) {
|
|
4505
|
-
return /* @__PURE__ */ (0,
|
|
4949
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_jsx_runtime18.Fragment, {});
|
|
4506
4950
|
}
|
|
4507
4951
|
const formatValue = (val) => {
|
|
4508
4952
|
if (typeof val === "number") {
|
|
@@ -4543,8 +4987,8 @@ function DataOverlay({
|
|
|
4543
4987
|
const overlayWidth = 80 * scale;
|
|
4544
4988
|
const displayX = x + offsetX;
|
|
4545
4989
|
const displayY = y + offsetY;
|
|
4546
|
-
return /* @__PURE__ */ (0,
|
|
4547
|
-
/* @__PURE__ */ (0,
|
|
4990
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("g", { "data-overlay-node": nodeId, "data-status": value.status, children: [
|
|
4991
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4548
4992
|
"rect",
|
|
4549
4993
|
{
|
|
4550
4994
|
x: displayX - overlayWidth / 2,
|
|
@@ -4559,7 +5003,7 @@ function DataOverlay({
|
|
|
4559
5003
|
filter: "drop-shadow(0 2px 4px rgba(0,0,0,0.2))"
|
|
4560
5004
|
}
|
|
4561
5005
|
),
|
|
4562
|
-
label && /* @__PURE__ */ (0,
|
|
5006
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4563
5007
|
"text",
|
|
4564
5008
|
{
|
|
4565
5009
|
x: displayX,
|
|
@@ -4572,7 +5016,7 @@ function DataOverlay({
|
|
|
4572
5016
|
children: label
|
|
4573
5017
|
}
|
|
4574
5018
|
),
|
|
4575
|
-
/* @__PURE__ */ (0,
|
|
5019
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4576
5020
|
"text",
|
|
4577
5021
|
{
|
|
4578
5022
|
x: displayX,
|
|
@@ -4585,7 +5029,7 @@ function DataOverlay({
|
|
|
4585
5029
|
children: displayText
|
|
4586
5030
|
}
|
|
4587
5031
|
),
|
|
4588
|
-
showStatus && value.status !== "normal" && /* @__PURE__ */ (0,
|
|
5032
|
+
showStatus && value.status !== "normal" && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4589
5033
|
"circle",
|
|
4590
5034
|
{
|
|
4591
5035
|
cx: displayX + 35 * scale,
|
|
@@ -4593,7 +5037,7 @@ function DataOverlay({
|
|
|
4593
5037
|
r: 3 * scale,
|
|
4594
5038
|
fill: finalTextColor,
|
|
4595
5039
|
opacity: "0.9",
|
|
4596
|
-
children: /* @__PURE__ */ (0,
|
|
5040
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4597
5041
|
"animate",
|
|
4598
5042
|
{
|
|
4599
5043
|
attributeName: "opacity",
|
|
@@ -4604,7 +5048,7 @@ function DataOverlay({
|
|
|
4604
5048
|
)
|
|
4605
5049
|
}
|
|
4606
5050
|
),
|
|
4607
|
-
value.quality !== void 0 && value.quality < 100 && /* @__PURE__ */ (0,
|
|
5051
|
+
value.quality !== void 0 && value.quality < 100 && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
4608
5052
|
"text",
|
|
4609
5053
|
{
|
|
4610
5054
|
x: displayX,
|
|
@@ -4621,7 +5065,7 @@ function DataOverlay({
|
|
|
4621
5065
|
]
|
|
4622
5066
|
}
|
|
4623
5067
|
),
|
|
4624
|
-
hasSparkline && /* @__PURE__ */ (0,
|
|
5068
|
+
hasSparkline && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("g", { transform: `translate(${displayX - 35 * scale}, ${displayY + (label ? 5 : 0) * scale})`, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4625
5069
|
"path",
|
|
4626
5070
|
{
|
|
4627
5071
|
d: sparklinePath,
|
|
@@ -4637,8 +5081,8 @@ function DataOverlay({
|
|
|
4637
5081
|
}
|
|
4638
5082
|
|
|
4639
5083
|
// src/components/PIDCanvas/PositionPanel.tsx
|
|
4640
|
-
var
|
|
4641
|
-
var
|
|
5084
|
+
var import_react10 = require("react");
|
|
5085
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
4642
5086
|
function PositionPanel({
|
|
4643
5087
|
selectedNode,
|
|
4644
5088
|
selectedWaypoint,
|
|
@@ -4646,9 +5090,9 @@ function PositionPanel({
|
|
|
4646
5090
|
onWaypointPositionChange,
|
|
4647
5091
|
position = "top-right"
|
|
4648
5092
|
}) {
|
|
4649
|
-
const [x, setX] = (0,
|
|
4650
|
-
const [y, setY] = (0,
|
|
4651
|
-
(0,
|
|
5093
|
+
const [x, setX] = (0, import_react10.useState)("");
|
|
5094
|
+
const [y, setY] = (0, import_react10.useState)("");
|
|
5095
|
+
(0, import_react10.useEffect)(() => {
|
|
4652
5096
|
if (selectedNode) {
|
|
4653
5097
|
setX(selectedNode.transform.x.toFixed(2));
|
|
4654
5098
|
setY(selectedNode.transform.y.toFixed(2));
|
|
@@ -4707,7 +5151,7 @@ function PositionPanel({
|
|
|
4707
5151
|
"bottom-left": { bottom: 10, left: 10 },
|
|
4708
5152
|
"bottom-right": { bottom: 10, right: 10 }
|
|
4709
5153
|
};
|
|
4710
|
-
return /* @__PURE__ */ (0,
|
|
5154
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
4711
5155
|
"div",
|
|
4712
5156
|
{
|
|
4713
5157
|
style: {
|
|
@@ -4724,11 +5168,11 @@ function PositionPanel({
|
|
|
4724
5168
|
fontSize: "13px"
|
|
4725
5169
|
},
|
|
4726
5170
|
children: [
|
|
4727
|
-
/* @__PURE__ */ (0,
|
|
4728
|
-
/* @__PURE__ */ (0,
|
|
4729
|
-
/* @__PURE__ */ (0,
|
|
4730
|
-
/* @__PURE__ */ (0,
|
|
4731
|
-
/* @__PURE__ */ (0,
|
|
5171
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: { marginBottom: "8px", fontWeight: 600, color: "#333" }, children: "Position" }),
|
|
5172
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "8px" }, children: [
|
|
5173
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
|
|
5174
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("label", { style: { width: "16px", color: "#666" }, children: "X:" }),
|
|
5175
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4732
5176
|
"input",
|
|
4733
5177
|
{
|
|
4734
5178
|
type: "number",
|
|
@@ -4746,9 +5190,9 @@ function PositionPanel({
|
|
|
4746
5190
|
}
|
|
4747
5191
|
)
|
|
4748
5192
|
] }),
|
|
4749
|
-
/* @__PURE__ */ (0,
|
|
4750
|
-
/* @__PURE__ */ (0,
|
|
4751
|
-
/* @__PURE__ */ (0,
|
|
5193
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
|
|
5194
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("label", { style: { width: "16px", color: "#666" }, children: "Y:" }),
|
|
5195
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4752
5196
|
"input",
|
|
4753
5197
|
{
|
|
4754
5198
|
type: "number",
|
|
@@ -4767,14 +5211,14 @@ function PositionPanel({
|
|
|
4767
5211
|
)
|
|
4768
5212
|
] })
|
|
4769
5213
|
] }),
|
|
4770
|
-
/* @__PURE__ */ (0,
|
|
5214
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: { marginTop: "8px", fontSize: "11px", color: "#888" }, children: "Use arrow keys to nudge (\xB11px)" })
|
|
4771
5215
|
]
|
|
4772
5216
|
}
|
|
4773
5217
|
);
|
|
4774
5218
|
}
|
|
4775
5219
|
|
|
4776
5220
|
// src/diagram/hooks/useViewBox.ts
|
|
4777
|
-
var
|
|
5221
|
+
var import_react11 = require("react");
|
|
4778
5222
|
function useViewBox(options) {
|
|
4779
5223
|
const {
|
|
4780
5224
|
initialViewBox,
|
|
@@ -4785,16 +5229,16 @@ function useViewBox(options) {
|
|
|
4785
5229
|
zoomSensitivity = 1e-3,
|
|
4786
5230
|
allowLeftClickPan = true
|
|
4787
5231
|
} = options;
|
|
4788
|
-
const [viewBox, setViewBox] = (0,
|
|
4789
|
-
const svgRef = (0,
|
|
4790
|
-
const isPanningRef = (0,
|
|
4791
|
-
const lastMousePosRef = (0,
|
|
4792
|
-
const spaceKeyDownRef = (0,
|
|
4793
|
-
const lastTouchDistanceRef = (0,
|
|
4794
|
-
const resetViewBox = (0,
|
|
5232
|
+
const [viewBox, setViewBox] = (0, import_react11.useState)(initialViewBox);
|
|
5233
|
+
const svgRef = (0, import_react11.useRef)(null);
|
|
5234
|
+
const isPanningRef = (0, import_react11.useRef)(false);
|
|
5235
|
+
const lastMousePosRef = (0, import_react11.useRef)({ x: 0, y: 0 });
|
|
5236
|
+
const spaceKeyDownRef = (0, import_react11.useRef)(false);
|
|
5237
|
+
const lastTouchDistanceRef = (0, import_react11.useRef)(null);
|
|
5238
|
+
const resetViewBox = (0, import_react11.useCallback)(() => {
|
|
4795
5239
|
setViewBox(initialViewBox);
|
|
4796
5240
|
}, [initialViewBox]);
|
|
4797
|
-
const zoomIn = (0,
|
|
5241
|
+
const zoomIn = (0, import_react11.useCallback)(() => {
|
|
4798
5242
|
setViewBox((prev) => {
|
|
4799
5243
|
const currentZoom = initialViewBox.width / prev.width;
|
|
4800
5244
|
const newZoom = Math.min(1 / minZoom, currentZoom * 1.25);
|
|
@@ -4811,7 +5255,7 @@ function useViewBox(options) {
|
|
|
4811
5255
|
};
|
|
4812
5256
|
});
|
|
4813
5257
|
}, [initialViewBox, minZoom]);
|
|
4814
|
-
const zoomOut = (0,
|
|
5258
|
+
const zoomOut = (0, import_react11.useCallback)(() => {
|
|
4815
5259
|
setViewBox((prev) => {
|
|
4816
5260
|
const currentZoom = initialViewBox.width / prev.width;
|
|
4817
5261
|
const newZoom = Math.max(1 / maxZoom, currentZoom * 0.8);
|
|
@@ -4828,7 +5272,7 @@ function useViewBox(options) {
|
|
|
4828
5272
|
};
|
|
4829
5273
|
});
|
|
4830
5274
|
}, [initialViewBox, maxZoom]);
|
|
4831
|
-
const fitToContent = (0,
|
|
5275
|
+
const fitToContent = (0, import_react11.useCallback)((bounds, padding = 50) => {
|
|
4832
5276
|
const contentWidth = bounds.maxX - bounds.minX;
|
|
4833
5277
|
const contentHeight = bounds.maxY - bounds.minY;
|
|
4834
5278
|
if (contentWidth === 0 || contentHeight === 0) {
|
|
@@ -4856,7 +5300,7 @@ function useViewBox(options) {
|
|
|
4856
5300
|
height: newHeight
|
|
4857
5301
|
});
|
|
4858
5302
|
}, [initialViewBox]);
|
|
4859
|
-
(0,
|
|
5303
|
+
(0, import_react11.useEffect)(() => {
|
|
4860
5304
|
if (!enableZoom || !svgRef.current) return;
|
|
4861
5305
|
const svg = svgRef.current;
|
|
4862
5306
|
const handleWheel = (e) => {
|
|
@@ -4889,7 +5333,7 @@ function useViewBox(options) {
|
|
|
4889
5333
|
svg.addEventListener("wheel", handleWheel, { passive: false });
|
|
4890
5334
|
return () => svg.removeEventListener("wheel", handleWheel);
|
|
4891
5335
|
}, [enableZoom, zoomSensitivity, minZoom, initialViewBox]);
|
|
4892
|
-
(0,
|
|
5336
|
+
(0, import_react11.useEffect)(() => {
|
|
4893
5337
|
if (!enablePan || !svgRef.current) return;
|
|
4894
5338
|
const svg = svgRef.current;
|
|
4895
5339
|
const handleMouseDown = (e) => {
|
|
@@ -4965,7 +5409,7 @@ function useViewBox(options) {
|
|
|
4965
5409
|
window.removeEventListener("keyup", handleKeyUp);
|
|
4966
5410
|
};
|
|
4967
5411
|
}, [enablePan, allowLeftClickPan]);
|
|
4968
|
-
(0,
|
|
5412
|
+
(0, import_react11.useEffect)(() => {
|
|
4969
5413
|
if (!svgRef.current) return;
|
|
4970
5414
|
if (!enablePan && !enableZoom) return;
|
|
4971
5415
|
const svg = svgRef.current;
|
|
@@ -5056,7 +5500,7 @@ function useViewBox(options) {
|
|
|
5056
5500
|
svg.removeEventListener("touchend", handleTouchEnd);
|
|
5057
5501
|
};
|
|
5058
5502
|
}, [enablePan, enableZoom, minZoom, initialViewBox]);
|
|
5059
|
-
const screenToWorld = (0,
|
|
5503
|
+
const screenToWorld = (0, import_react11.useCallback)(
|
|
5060
5504
|
(screenX, screenY) => {
|
|
5061
5505
|
const svg = svgRef.current;
|
|
5062
5506
|
if (!svg) return { x: screenX, y: screenY };
|
|
@@ -5095,15 +5539,15 @@ function useViewBox(options) {
|
|
|
5095
5539
|
}
|
|
5096
5540
|
|
|
5097
5541
|
// src/diagram/hooks/useSelection.ts
|
|
5098
|
-
var
|
|
5542
|
+
var import_react12 = require("react");
|
|
5099
5543
|
function useSelection(options = {}) {
|
|
5100
5544
|
const {
|
|
5101
5545
|
multiSelect = true,
|
|
5102
5546
|
initialSelection = { selectedNodeIds: /* @__PURE__ */ new Set(), selectedPipeIds: /* @__PURE__ */ new Set() },
|
|
5103
5547
|
onSelectionChange
|
|
5104
5548
|
} = options;
|
|
5105
|
-
const [selection, setSelection] = (0,
|
|
5106
|
-
const notifyChange = (0,
|
|
5549
|
+
const [selection, setSelection] = (0, import_react12.useState)(initialSelection);
|
|
5550
|
+
const notifyChange = (0, import_react12.useCallback)(
|
|
5107
5551
|
(newSelection) => {
|
|
5108
5552
|
if (onSelectionChange) {
|
|
5109
5553
|
onSelectionChange(newSelection);
|
|
@@ -5111,15 +5555,15 @@ function useSelection(options = {}) {
|
|
|
5111
5555
|
},
|
|
5112
5556
|
[onSelectionChange]
|
|
5113
5557
|
);
|
|
5114
|
-
const isNodeSelected = (0,
|
|
5558
|
+
const isNodeSelected = (0, import_react12.useCallback)(
|
|
5115
5559
|
(nodeId) => selection.selectedNodeIds.has(nodeId),
|
|
5116
5560
|
[selection.selectedNodeIds]
|
|
5117
5561
|
);
|
|
5118
|
-
const isPipeSelected = (0,
|
|
5562
|
+
const isPipeSelected = (0, import_react12.useCallback)(
|
|
5119
5563
|
(pipeId) => selection.selectedPipeIds.has(pipeId),
|
|
5120
5564
|
[selection.selectedPipeIds]
|
|
5121
5565
|
);
|
|
5122
|
-
const selectNode = (0,
|
|
5566
|
+
const selectNode = (0, import_react12.useCallback)(
|
|
5123
5567
|
(nodeId, isMultiSelect = false) => {
|
|
5124
5568
|
setSelection((prev) => {
|
|
5125
5569
|
const newNodeIds = new Set(isMultiSelect && multiSelect ? prev.selectedNodeIds : []);
|
|
@@ -5138,7 +5582,7 @@ function useSelection(options = {}) {
|
|
|
5138
5582
|
},
|
|
5139
5583
|
[multiSelect, notifyChange]
|
|
5140
5584
|
);
|
|
5141
|
-
const selectPipe = (0,
|
|
5585
|
+
const selectPipe = (0, import_react12.useCallback)(
|
|
5142
5586
|
(pipeId, isMultiSelect = false) => {
|
|
5143
5587
|
setSelection((prev) => {
|
|
5144
5588
|
const newPipeIds = new Set(isMultiSelect && multiSelect ? prev.selectedPipeIds : []);
|
|
@@ -5157,7 +5601,7 @@ function useSelection(options = {}) {
|
|
|
5157
5601
|
},
|
|
5158
5602
|
[multiSelect, notifyChange]
|
|
5159
5603
|
);
|
|
5160
|
-
const clearSelection = (0,
|
|
5604
|
+
const clearSelection = (0, import_react12.useCallback)(() => {
|
|
5161
5605
|
const newSelection = {
|
|
5162
5606
|
selectedNodeIds: /* @__PURE__ */ new Set(),
|
|
5163
5607
|
selectedPipeIds: /* @__PURE__ */ new Set()
|
|
@@ -5165,7 +5609,7 @@ function useSelection(options = {}) {
|
|
|
5165
5609
|
setSelection(newSelection);
|
|
5166
5610
|
notifyChange(newSelection);
|
|
5167
5611
|
}, [notifyChange]);
|
|
5168
|
-
const selectNodes = (0,
|
|
5612
|
+
const selectNodes = (0, import_react12.useCallback)(
|
|
5169
5613
|
(nodeIds) => {
|
|
5170
5614
|
const newSelection = {
|
|
5171
5615
|
selectedNodeIds: new Set(nodeIds),
|
|
@@ -5176,7 +5620,7 @@ function useSelection(options = {}) {
|
|
|
5176
5620
|
},
|
|
5177
5621
|
[notifyChange]
|
|
5178
5622
|
);
|
|
5179
|
-
const selectPipes = (0,
|
|
5623
|
+
const selectPipes = (0, import_react12.useCallback)(
|
|
5180
5624
|
(pipeIds) => {
|
|
5181
5625
|
const newSelection = {
|
|
5182
5626
|
selectedNodeIds: /* @__PURE__ */ new Set(),
|
|
@@ -5200,23 +5644,23 @@ function useSelection(options = {}) {
|
|
|
5200
5644
|
}
|
|
5201
5645
|
|
|
5202
5646
|
// src/diagram/hooks/useTelemetry.ts
|
|
5203
|
-
var
|
|
5647
|
+
var import_react13 = require("react");
|
|
5204
5648
|
function useTelemetry(options = {}) {
|
|
5205
5649
|
const {
|
|
5206
5650
|
initialBindings = [],
|
|
5207
5651
|
onTelemetryChange,
|
|
5208
5652
|
refreshInterval = 0
|
|
5209
5653
|
} = options;
|
|
5210
|
-
const [telemetry, setTelemetry] = (0,
|
|
5654
|
+
const [telemetry, setTelemetry] = (0, import_react13.useState)(() => {
|
|
5211
5655
|
const map = /* @__PURE__ */ new Map();
|
|
5212
5656
|
initialBindings.forEach((binding) => {
|
|
5213
5657
|
map.set(binding.nodeId, binding);
|
|
5214
5658
|
});
|
|
5215
5659
|
return map;
|
|
5216
5660
|
});
|
|
5217
|
-
const telemetryRef = (0,
|
|
5661
|
+
const telemetryRef = (0, import_react13.useRef)(telemetry);
|
|
5218
5662
|
telemetryRef.current = telemetry;
|
|
5219
|
-
const notifyChange = (0,
|
|
5663
|
+
const notifyChange = (0, import_react13.useCallback)(
|
|
5220
5664
|
(newTelemetry) => {
|
|
5221
5665
|
if (onTelemetryChange) {
|
|
5222
5666
|
onTelemetryChange(newTelemetry);
|
|
@@ -5224,7 +5668,7 @@ function useTelemetry(options = {}) {
|
|
|
5224
5668
|
},
|
|
5225
5669
|
[onTelemetryChange]
|
|
5226
5670
|
);
|
|
5227
|
-
const updateTelemetry = (0,
|
|
5671
|
+
const updateTelemetry = (0, import_react13.useCallback)(
|
|
5228
5672
|
(nodeId, value) => {
|
|
5229
5673
|
setTelemetry((prev) => {
|
|
5230
5674
|
const newMap = new Map(prev);
|
|
@@ -5254,7 +5698,7 @@ function useTelemetry(options = {}) {
|
|
|
5254
5698
|
},
|
|
5255
5699
|
[notifyChange]
|
|
5256
5700
|
);
|
|
5257
|
-
const updateTelemetryBatch = (0,
|
|
5701
|
+
const updateTelemetryBatch = (0, import_react13.useCallback)(
|
|
5258
5702
|
(updates) => {
|
|
5259
5703
|
setTelemetry((prev) => {
|
|
5260
5704
|
const newMap = new Map(prev);
|
|
@@ -5308,16 +5752,16 @@ function useTelemetry(options = {}) {
|
|
|
5308
5752
|
},
|
|
5309
5753
|
[notifyChange]
|
|
5310
5754
|
);
|
|
5311
|
-
const getTelemetry = (0,
|
|
5755
|
+
const getTelemetry = (0, import_react13.useCallback)(
|
|
5312
5756
|
(nodeId) => telemetryRef.current.get(nodeId),
|
|
5313
5757
|
[]
|
|
5314
5758
|
);
|
|
5315
|
-
const clearTelemetry = (0,
|
|
5759
|
+
const clearTelemetry = (0, import_react13.useCallback)(() => {
|
|
5316
5760
|
const newMap = /* @__PURE__ */ new Map();
|
|
5317
5761
|
setTelemetry(newMap);
|
|
5318
5762
|
notifyChange(newMap);
|
|
5319
5763
|
}, [notifyChange]);
|
|
5320
|
-
const setBindings = (0,
|
|
5764
|
+
const setBindings = (0, import_react13.useCallback)(
|
|
5321
5765
|
(bindings) => {
|
|
5322
5766
|
const newMap = /* @__PURE__ */ new Map();
|
|
5323
5767
|
bindings.forEach((binding) => {
|
|
@@ -5328,7 +5772,7 @@ function useTelemetry(options = {}) {
|
|
|
5328
5772
|
},
|
|
5329
5773
|
[notifyChange]
|
|
5330
5774
|
);
|
|
5331
|
-
(0,
|
|
5775
|
+
(0, import_react13.useEffect)(() => {
|
|
5332
5776
|
if (refreshInterval <= 0) return;
|
|
5333
5777
|
const intervalId = setInterval(() => {
|
|
5334
5778
|
notifyChange(telemetryRef.current);
|
|
@@ -5346,10 +5790,10 @@ function useTelemetry(options = {}) {
|
|
|
5346
5790
|
}
|
|
5347
5791
|
|
|
5348
5792
|
// src/diagram/hooks/useTelemetryStatus.ts
|
|
5349
|
-
var
|
|
5793
|
+
var import_react14 = require("react");
|
|
5350
5794
|
function useTelemetryStatus(telemetry, diagram, setDiagram, options = {}) {
|
|
5351
5795
|
const { enabled = true, mapStatus } = options;
|
|
5352
|
-
(0,
|
|
5796
|
+
(0, import_react14.useEffect)(() => {
|
|
5353
5797
|
if (!enabled) return;
|
|
5354
5798
|
const defaultMapStatus = (telemetryStatus) => {
|
|
5355
5799
|
switch (telemetryStatus) {
|
|
@@ -5388,7 +5832,7 @@ function useTelemetryStatus(telemetry, diagram, setDiagram, options = {}) {
|
|
|
5388
5832
|
}
|
|
5389
5833
|
|
|
5390
5834
|
// src/diagram/hooks/useDrag.ts
|
|
5391
|
-
var
|
|
5835
|
+
var import_react15 = require("react");
|
|
5392
5836
|
function useDrag(options = {}) {
|
|
5393
5837
|
const {
|
|
5394
5838
|
onDragStart,
|
|
@@ -5398,23 +5842,23 @@ function useDrag(options = {}) {
|
|
|
5398
5842
|
dragThreshold = 3,
|
|
5399
5843
|
screenToWorld = (x, y) => ({ x, y })
|
|
5400
5844
|
} = options;
|
|
5401
|
-
const [dragState, setDragState] = (0,
|
|
5845
|
+
const [dragState, setDragState] = (0, import_react15.useState)({
|
|
5402
5846
|
isDragging: false,
|
|
5403
5847
|
startPosition: null,
|
|
5404
5848
|
offset: { x: 0, y: 0 },
|
|
5405
5849
|
draggedId: null
|
|
5406
5850
|
});
|
|
5407
|
-
const [isListening, setIsListening] = (0,
|
|
5408
|
-
const dragStartRef = (0,
|
|
5409
|
-
const hasMovedRef = (0,
|
|
5410
|
-
const applySnap = (0,
|
|
5851
|
+
const [isListening, setIsListening] = (0, import_react15.useState)(false);
|
|
5852
|
+
const dragStartRef = (0, import_react15.useRef)(null);
|
|
5853
|
+
const hasMovedRef = (0, import_react15.useRef)(false);
|
|
5854
|
+
const applySnap = (0, import_react15.useCallback)(
|
|
5411
5855
|
(value) => {
|
|
5412
5856
|
if (snapToGrid <= 0) return value;
|
|
5413
5857
|
return Math.round(value / snapToGrid) * snapToGrid;
|
|
5414
5858
|
},
|
|
5415
5859
|
[snapToGrid]
|
|
5416
5860
|
);
|
|
5417
|
-
const handleMouseMove = (0,
|
|
5861
|
+
const handleMouseMove = (0, import_react15.useCallback)(
|
|
5418
5862
|
(event) => {
|
|
5419
5863
|
if (!dragStartRef.current) return;
|
|
5420
5864
|
const { id, screenStart: _screenStart, itemPosition, clickOffset } = dragStartRef.current;
|
|
@@ -5455,7 +5899,7 @@ function useDrag(options = {}) {
|
|
|
5455
5899
|
},
|
|
5456
5900
|
[screenToWorld, dragThreshold, applySnap, onDragStart, onDragMove]
|
|
5457
5901
|
);
|
|
5458
|
-
const handleMouseUp = (0,
|
|
5902
|
+
const handleMouseUp = (0, import_react15.useCallback)(
|
|
5459
5903
|
(event) => {
|
|
5460
5904
|
if (!dragStartRef.current || !hasMovedRef.current) {
|
|
5461
5905
|
dragStartRef.current = null;
|
|
@@ -5492,7 +5936,7 @@ function useDrag(options = {}) {
|
|
|
5492
5936
|
},
|
|
5493
5937
|
[screenToWorld, applySnap, onDragEnd]
|
|
5494
5938
|
);
|
|
5495
|
-
const handleTouchMove = (0,
|
|
5939
|
+
const handleTouchMove = (0, import_react15.useCallback)(
|
|
5496
5940
|
(event) => {
|
|
5497
5941
|
if (!dragStartRef.current || event.touches.length !== 1) return;
|
|
5498
5942
|
const touch = event.touches[0];
|
|
@@ -5535,7 +5979,7 @@ function useDrag(options = {}) {
|
|
|
5535
5979
|
},
|
|
5536
5980
|
[screenToWorld, dragThreshold, applySnap, onDragStart, onDragMove]
|
|
5537
5981
|
);
|
|
5538
|
-
const handleTouchEnd = (0,
|
|
5982
|
+
const handleTouchEnd = (0, import_react15.useCallback)(
|
|
5539
5983
|
(event) => {
|
|
5540
5984
|
if (!dragStartRef.current || !hasMovedRef.current) {
|
|
5541
5985
|
dragStartRef.current = null;
|
|
@@ -5573,7 +6017,7 @@ function useDrag(options = {}) {
|
|
|
5573
6017
|
},
|
|
5574
6018
|
[screenToWorld, applySnap, onDragEnd]
|
|
5575
6019
|
);
|
|
5576
|
-
(0,
|
|
6020
|
+
(0, import_react15.useEffect)(() => {
|
|
5577
6021
|
if (!isListening) return;
|
|
5578
6022
|
document.addEventListener("mousemove", handleMouseMove);
|
|
5579
6023
|
document.addEventListener("mouseup", handleMouseUp);
|
|
@@ -5588,7 +6032,7 @@ function useDrag(options = {}) {
|
|
|
5588
6032
|
document.removeEventListener("touchcancel", handleTouchEnd);
|
|
5589
6033
|
};
|
|
5590
6034
|
}, [isListening, handleMouseMove, handleMouseUp, handleTouchMove, handleTouchEnd]);
|
|
5591
|
-
const startDrag = (0,
|
|
6035
|
+
const startDrag = (0, import_react15.useCallback)(
|
|
5592
6036
|
(id, event, itemPosition) => {
|
|
5593
6037
|
event.stopPropagation();
|
|
5594
6038
|
let clientX;
|
|
@@ -5618,7 +6062,7 @@ function useDrag(options = {}) {
|
|
|
5618
6062
|
},
|
|
5619
6063
|
[screenToWorld]
|
|
5620
6064
|
);
|
|
5621
|
-
const cancelDrag = (0,
|
|
6065
|
+
const cancelDrag = (0, import_react15.useCallback)(() => {
|
|
5622
6066
|
dragStartRef.current = null;
|
|
5623
6067
|
hasMovedRef.current = false;
|
|
5624
6068
|
setIsListening(false);
|
|
@@ -5629,7 +6073,7 @@ function useDrag(options = {}) {
|
|
|
5629
6073
|
draggedId: null
|
|
5630
6074
|
});
|
|
5631
6075
|
}, []);
|
|
5632
|
-
const isDraggingItem = (0,
|
|
6076
|
+
const isDraggingItem = (0, import_react15.useCallback)(
|
|
5633
6077
|
(id) => dragState.isDragging && dragState.draggedId === id,
|
|
5634
6078
|
[dragState.isDragging, dragState.draggedId]
|
|
5635
6079
|
);
|
|
@@ -5642,7 +6086,7 @@ function useDrag(options = {}) {
|
|
|
5642
6086
|
}
|
|
5643
6087
|
|
|
5644
6088
|
// src/diagram/hooks/useKeyboardShortcuts.ts
|
|
5645
|
-
var
|
|
6089
|
+
var import_react16 = require("react");
|
|
5646
6090
|
function useKeyboardShortcuts(options) {
|
|
5647
6091
|
const {
|
|
5648
6092
|
onDelete,
|
|
@@ -5653,7 +6097,7 @@ function useKeyboardShortcuts(options) {
|
|
|
5653
6097
|
onSelectAll,
|
|
5654
6098
|
enabled = true
|
|
5655
6099
|
} = options;
|
|
5656
|
-
(0,
|
|
6100
|
+
(0, import_react16.useEffect)(() => {
|
|
5657
6101
|
if (!enabled) return;
|
|
5658
6102
|
const handleKeyDown = (event) => {
|
|
5659
6103
|
const target = event.target;
|
|
@@ -5762,7 +6206,7 @@ function nodeHasPort(node, portId) {
|
|
|
5762
6206
|
}
|
|
5763
6207
|
|
|
5764
6208
|
// src/components/PIDCanvas/PIDCanvas.tsx
|
|
5765
|
-
var
|
|
6209
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
5766
6210
|
function PIDCanvas({
|
|
5767
6211
|
diagram,
|
|
5768
6212
|
className = "",
|
|
@@ -5790,21 +6234,21 @@ function PIDCanvas({
|
|
|
5790
6234
|
statusColorMap,
|
|
5791
6235
|
...props
|
|
5792
6236
|
}) {
|
|
5793
|
-
const [localDiagram, setLocalDiagram] = (0,
|
|
5794
|
-
const [dragOverPosition, setDragOverPosition] = (0,
|
|
5795
|
-
const [isConnecting, setIsConnecting] = (0,
|
|
5796
|
-
const [connectionSource, setConnectionSource] = (0,
|
|
5797
|
-
const [connectionSourcePort, setConnectionSourcePort] = (0,
|
|
5798
|
-
const [connectionCursor, setConnectionCursor] = (0,
|
|
5799
|
-
const [hoveredNode, setHoveredNode] = (0,
|
|
5800
|
-
const [hoveredPort, setHoveredPort] = (0,
|
|
5801
|
-
const [selectedWaypoint, setSelectedWaypoint] = (0,
|
|
5802
|
-
const historyStack = (0,
|
|
5803
|
-
const redoStack = (0,
|
|
5804
|
-
const isUndoRedoAction = (0,
|
|
5805
|
-
const isInternalChange = (0,
|
|
5806
|
-
const lastInternalDiagram = (0,
|
|
5807
|
-
(0,
|
|
6237
|
+
const [localDiagram, setLocalDiagram] = (0, import_react17.useState)(diagram);
|
|
6238
|
+
const [dragOverPosition, setDragOverPosition] = (0, import_react17.useState)(null);
|
|
6239
|
+
const [isConnecting, setIsConnecting] = (0, import_react17.useState)(false);
|
|
6240
|
+
const [connectionSource, setConnectionSource] = (0, import_react17.useState)(null);
|
|
6241
|
+
const [connectionSourcePort, setConnectionSourcePort] = (0, import_react17.useState)(null);
|
|
6242
|
+
const [connectionCursor, setConnectionCursor] = (0, import_react17.useState)(null);
|
|
6243
|
+
const [hoveredNode, setHoveredNode] = (0, import_react17.useState)(null);
|
|
6244
|
+
const [hoveredPort, setHoveredPort] = (0, import_react17.useState)(null);
|
|
6245
|
+
const [selectedWaypoint, setSelectedWaypoint] = (0, import_react17.useState)(null);
|
|
6246
|
+
const historyStack = (0, import_react17.useRef)([]);
|
|
6247
|
+
const redoStack = (0, import_react17.useRef)([]);
|
|
6248
|
+
const isUndoRedoAction = (0, import_react17.useRef)(false);
|
|
6249
|
+
const isInternalChange = (0, import_react17.useRef)(false);
|
|
6250
|
+
const lastInternalDiagram = (0, import_react17.useRef)(null);
|
|
6251
|
+
(0, import_react17.useEffect)(() => {
|
|
5808
6252
|
const isExternal = !isInternalChange.current && diagram !== lastInternalDiagram.current;
|
|
5809
6253
|
if (isExternal) {
|
|
5810
6254
|
setLocalDiagram(diagram);
|
|
@@ -5826,7 +6270,7 @@ function PIDCanvas({
|
|
|
5826
6270
|
enablePan: features.pan ?? true,
|
|
5827
6271
|
enableZoom: features.zoom ?? true
|
|
5828
6272
|
});
|
|
5829
|
-
const calculateContentBounds = (0,
|
|
6273
|
+
const calculateContentBounds = (0, import_react17.useCallback)(() => {
|
|
5830
6274
|
const nodes2 = localDiagram.nodes.filter((n) => n.visible !== false);
|
|
5831
6275
|
if (nodes2.length === 0) {
|
|
5832
6276
|
return null;
|
|
@@ -5849,7 +6293,7 @@ function PIDCanvas({
|
|
|
5849
6293
|
});
|
|
5850
6294
|
return { minX, minY, maxX, maxY };
|
|
5851
6295
|
}, [localDiagram.nodes]);
|
|
5852
|
-
(0,
|
|
6296
|
+
(0, import_react17.useEffect)(() => {
|
|
5853
6297
|
if (onMounted) {
|
|
5854
6298
|
const controls = {
|
|
5855
6299
|
fitToContent: (padding = 50) => {
|
|
@@ -5890,8 +6334,8 @@ function PIDCanvas({
|
|
|
5890
6334
|
});
|
|
5891
6335
|
const dragEnabled = features.dragNodes ?? false;
|
|
5892
6336
|
const selectionEnabled = features.selection ?? false;
|
|
5893
|
-
const containerRef = (0,
|
|
5894
|
-
const pushToHistory = (0,
|
|
6337
|
+
const containerRef = (0, import_react17.useRef)(null);
|
|
6338
|
+
const pushToHistory = (0, import_react17.useCallback)((currentDiagram) => {
|
|
5895
6339
|
if (isUndoRedoAction.current) return;
|
|
5896
6340
|
const snapshot = JSON.parse(JSON.stringify(currentDiagram));
|
|
5897
6341
|
historyStack.current.push(snapshot);
|
|
@@ -5900,7 +6344,7 @@ function PIDCanvas({
|
|
|
5900
6344
|
}
|
|
5901
6345
|
redoStack.current = [];
|
|
5902
6346
|
}, []);
|
|
5903
|
-
const undo = (0,
|
|
6347
|
+
const undo = (0, import_react17.useCallback)(() => {
|
|
5904
6348
|
if (historyStack.current.length === 0) return;
|
|
5905
6349
|
isUndoRedoAction.current = true;
|
|
5906
6350
|
const currentSnapshot = JSON.parse(JSON.stringify(localDiagram));
|
|
@@ -5914,7 +6358,7 @@ function PIDCanvas({
|
|
|
5914
6358
|
isUndoRedoAction.current = false;
|
|
5915
6359
|
}, 0);
|
|
5916
6360
|
}, [localDiagram, onDiagramChange]);
|
|
5917
|
-
const redo = (0,
|
|
6361
|
+
const redo = (0, import_react17.useCallback)(() => {
|
|
5918
6362
|
if (redoStack.current.length === 0) return;
|
|
5919
6363
|
isUndoRedoAction.current = true;
|
|
5920
6364
|
const currentSnapshot = JSON.parse(JSON.stringify(localDiagram));
|
|
@@ -5928,7 +6372,7 @@ function PIDCanvas({
|
|
|
5928
6372
|
isUndoRedoAction.current = false;
|
|
5929
6373
|
}, 0);
|
|
5930
6374
|
}, [localDiagram, onDiagramChange]);
|
|
5931
|
-
(0,
|
|
6375
|
+
(0, import_react17.useEffect)(() => {
|
|
5932
6376
|
const handleKeyDown = (e) => {
|
|
5933
6377
|
const isCtrlOrCmd = e.ctrlKey || e.metaKey;
|
|
5934
6378
|
if (isCtrlOrCmd && e.key === "z" && !e.shiftKey) {
|
|
@@ -5945,7 +6389,7 @@ function PIDCanvas({
|
|
|
5945
6389
|
window.addEventListener("keydown", handleKeyDown);
|
|
5946
6390
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
5947
6391
|
}, [undo, redo]);
|
|
5948
|
-
(0,
|
|
6392
|
+
(0, import_react17.useEffect)(() => {
|
|
5949
6393
|
if (!features.dragNodes) return;
|
|
5950
6394
|
const handleKeyDown = (e) => {
|
|
5951
6395
|
if (selection.selectedNodeIds.size === 0 && !selectedWaypoint) return;
|
|
@@ -6030,7 +6474,7 @@ function PIDCanvas({
|
|
|
6030
6474
|
onNodeMove,
|
|
6031
6475
|
pushToHistory
|
|
6032
6476
|
]);
|
|
6033
|
-
const handlePositionChange = (0,
|
|
6477
|
+
const handlePositionChange = (0, import_react17.useCallback)(
|
|
6034
6478
|
(nodeId, x, y) => {
|
|
6035
6479
|
pushToHistory(localDiagram);
|
|
6036
6480
|
const updatedNodes = localDiagram.nodes.map(
|
|
@@ -6052,7 +6496,7 @@ function PIDCanvas({
|
|
|
6052
6496
|
},
|
|
6053
6497
|
[localDiagram, onDiagramChange, onNodeMove, pushToHistory]
|
|
6054
6498
|
);
|
|
6055
|
-
const handleWaypointPositionChange = (0,
|
|
6499
|
+
const handleWaypointPositionChange = (0, import_react17.useCallback)(
|
|
6056
6500
|
(pipeId, pointIndex, x, y) => {
|
|
6057
6501
|
pushToHistory(localDiagram);
|
|
6058
6502
|
const updatedPipes = localDiagram.pipes.map((pipe) => {
|
|
@@ -6070,7 +6514,7 @@ function PIDCanvas({
|
|
|
6070
6514
|
},
|
|
6071
6515
|
[localDiagram, onDiagramChange, pushToHistory]
|
|
6072
6516
|
);
|
|
6073
|
-
const handleDragEnd = (0,
|
|
6517
|
+
const handleDragEnd = (0, import_react17.useCallback)(
|
|
6074
6518
|
(nodeId, offset, finalPosition) => {
|
|
6075
6519
|
const dragDistance = Math.sqrt(offset.x ** 2 + offset.y ** 2);
|
|
6076
6520
|
if (dragDistance < 2) {
|
|
@@ -6151,7 +6595,7 @@ function PIDCanvas({
|
|
|
6151
6595
|
onDiagramChange?.(updatedDiagram);
|
|
6152
6596
|
}
|
|
6153
6597
|
});
|
|
6154
|
-
const handleNodeDragStart = (0,
|
|
6598
|
+
const handleNodeDragStart = (0, import_react17.useCallback)(
|
|
6155
6599
|
(nodeId, event) => {
|
|
6156
6600
|
const node = localDiagram.nodes.find((n) => n.id === nodeId);
|
|
6157
6601
|
if (!node) return;
|
|
@@ -6159,7 +6603,7 @@ function PIDCanvas({
|
|
|
6159
6603
|
},
|
|
6160
6604
|
[localDiagram.nodes, startDrag]
|
|
6161
6605
|
);
|
|
6162
|
-
const handleWaypointClick = (0,
|
|
6606
|
+
const handleWaypointClick = (0, import_react17.useCallback)(
|
|
6163
6607
|
(pipeId, pointIndex) => {
|
|
6164
6608
|
setSelectedWaypoint({ pipeId, pointIndex });
|
|
6165
6609
|
if (selectionEnabled) {
|
|
@@ -6168,7 +6612,7 @@ function PIDCanvas({
|
|
|
6168
6612
|
},
|
|
6169
6613
|
[selectionEnabled, clearSelection]
|
|
6170
6614
|
);
|
|
6171
|
-
const handleWaypointDragStart = (0,
|
|
6615
|
+
const handleWaypointDragStart = (0, import_react17.useCallback)(
|
|
6172
6616
|
(pipeId, pointIndex, event) => {
|
|
6173
6617
|
const pipe = localDiagram.pipes.find((p) => p.id === pipeId);
|
|
6174
6618
|
if (!pipe || pointIndex >= pipe.routePoints.length) return;
|
|
@@ -6177,7 +6621,7 @@ function PIDCanvas({
|
|
|
6177
6621
|
},
|
|
6178
6622
|
[localDiagram.pipes, startWaypointDrag]
|
|
6179
6623
|
);
|
|
6180
|
-
const handlePipeSegmentClick = (0,
|
|
6624
|
+
const handlePipeSegmentClick = (0, import_react17.useCallback)(
|
|
6181
6625
|
(pipeId, position, segmentIndex) => {
|
|
6182
6626
|
pushToHistory(localDiagram);
|
|
6183
6627
|
const updatedPipes = localDiagram.pipes.map((pipe) => {
|
|
@@ -6196,7 +6640,7 @@ function PIDCanvas({
|
|
|
6196
6640
|
[localDiagram, onDiagramChange, pushToHistory]
|
|
6197
6641
|
);
|
|
6198
6642
|
const telemetryEnabled = features.telemetry ?? false;
|
|
6199
|
-
const handleDelete = (0,
|
|
6643
|
+
const handleDelete = (0, import_react17.useCallback)(() => {
|
|
6200
6644
|
if (!selectionEnabled) return;
|
|
6201
6645
|
const { selectedNodeIds, selectedPipeIds } = selection;
|
|
6202
6646
|
if (selectedNodeIds.size === 0 && selectedPipeIds.size === 0) return;
|
|
@@ -6225,13 +6669,13 @@ function PIDCanvas({
|
|
|
6225
6669
|
onDelete,
|
|
6226
6670
|
pushToHistory
|
|
6227
6671
|
]);
|
|
6228
|
-
const handleCopy = (0,
|
|
6672
|
+
const handleCopy = (0, import_react17.useCallback)(() => {
|
|
6229
6673
|
if (!selectionEnabled) return;
|
|
6230
6674
|
const { selectedNodeIds, selectedPipeIds } = selection;
|
|
6231
6675
|
if (selectedNodeIds.size === 0 && selectedPipeIds.size === 0) return;
|
|
6232
6676
|
onItemsCopied?.(Array.from(selectedNodeIds), Array.from(selectedPipeIds));
|
|
6233
6677
|
}, [selection, selectionEnabled, onItemsCopied]);
|
|
6234
|
-
const handlePaste = (0,
|
|
6678
|
+
const handlePaste = (0, import_react17.useCallback)(() => {
|
|
6235
6679
|
if (!selectionEnabled) return;
|
|
6236
6680
|
onPaste?.();
|
|
6237
6681
|
}, [selectionEnabled, onPaste]);
|
|
@@ -6291,7 +6735,7 @@ function PIDCanvas({
|
|
|
6291
6735
|
}
|
|
6292
6736
|
setSelectedWaypoint(null);
|
|
6293
6737
|
};
|
|
6294
|
-
const handleDragOver = (0,
|
|
6738
|
+
const handleDragOver = (0, import_react17.useCallback)(
|
|
6295
6739
|
(event) => {
|
|
6296
6740
|
if (!features.allowSymbolDrop) return;
|
|
6297
6741
|
event.preventDefault();
|
|
@@ -6302,7 +6746,7 @@ function PIDCanvas({
|
|
|
6302
6746
|
},
|
|
6303
6747
|
[features.allowSymbolDrop, screenToWorld, svgRef]
|
|
6304
6748
|
);
|
|
6305
|
-
const handleDrop = (0,
|
|
6749
|
+
const handleDrop = (0, import_react17.useCallback)(
|
|
6306
6750
|
(event) => {
|
|
6307
6751
|
if (!features.allowSymbolDrop) return;
|
|
6308
6752
|
event.preventDefault();
|
|
@@ -6315,10 +6759,10 @@ function PIDCanvas({
|
|
|
6315
6759
|
},
|
|
6316
6760
|
[features.allowSymbolDrop, screenToWorld, onSymbolDrop, svgRef]
|
|
6317
6761
|
);
|
|
6318
|
-
const handleDragLeave = (0,
|
|
6762
|
+
const handleDragLeave = (0, import_react17.useCallback)(() => {
|
|
6319
6763
|
setDragOverPosition(null);
|
|
6320
6764
|
}, []);
|
|
6321
|
-
const handleMouseMove = (0,
|
|
6765
|
+
const handleMouseMove = (0, import_react17.useCallback)(
|
|
6322
6766
|
(event) => {
|
|
6323
6767
|
const connectionModeEnabled = features.connectionMode ?? false;
|
|
6324
6768
|
if (connectionModeEnabled) {
|
|
@@ -6355,7 +6799,7 @@ function PIDCanvas({
|
|
|
6355
6799
|
const viewBox = controlledViewBox;
|
|
6356
6800
|
const displayDiagram = localDiagram;
|
|
6357
6801
|
const selectedNode = selectionEnabled && selection.selectedNodeIds.size === 1 ? localDiagram.nodes.find((n) => selection.selectedNodeIds.has(n.id)) || null : null;
|
|
6358
|
-
return /* @__PURE__ */ (0,
|
|
6802
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
6359
6803
|
"div",
|
|
6360
6804
|
{
|
|
6361
6805
|
ref: containerRef,
|
|
@@ -6370,7 +6814,7 @@ function PIDCanvas({
|
|
|
6370
6814
|
},
|
|
6371
6815
|
...props,
|
|
6372
6816
|
children: [
|
|
6373
|
-
/* @__PURE__ */ (0,
|
|
6817
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
6374
6818
|
"svg",
|
|
6375
6819
|
{
|
|
6376
6820
|
ref: svgRef,
|
|
@@ -6389,15 +6833,15 @@ function PIDCanvas({
|
|
|
6389
6833
|
onDrop: handleDrop,
|
|
6390
6834
|
onDragLeave: handleDragLeave,
|
|
6391
6835
|
children: [
|
|
6392
|
-
features.showGrid !== false ? /* @__PURE__ */ (0,
|
|
6393
|
-
/* @__PURE__ */ (0,
|
|
6394
|
-
/* @__PURE__ */ (0,
|
|
6395
|
-
/* @__PURE__ */ (0,
|
|
6396
|
-
/* @__PURE__ */ (0,
|
|
6397
|
-
/* @__PURE__ */ (0,
|
|
6836
|
+
features.showGrid !== false ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
|
|
6837
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("defs", { children: [
|
|
6838
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("pattern", { id: "grid-minor", width: "5", height: "5", patternUnits: "userSpaceOnUse", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("path", { d: "M 5 0 L 0 0 0 5", fill: "none", stroke: "#e5e7eb", strokeWidth: "0.5" }) }),
|
|
6839
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("pattern", { id: "grid-major", width: "25", height: "25", patternUnits: "userSpaceOnUse", children: [
|
|
6840
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("rect", { width: "25", height: "25", fill: "url(#grid-minor)" }),
|
|
6841
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("path", { d: "M 25 0 L 0 0 0 25", fill: "none", stroke: "#d1d5db", strokeWidth: "1" })
|
|
6398
6842
|
] })
|
|
6399
6843
|
] }),
|
|
6400
|
-
/* @__PURE__ */ (0,
|
|
6844
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
6401
6845
|
"rect",
|
|
6402
6846
|
{
|
|
6403
6847
|
x: Math.floor(viewBox.x / 25) * 25 - viewBox.width,
|
|
@@ -6407,7 +6851,7 @@ function PIDCanvas({
|
|
|
6407
6851
|
fill: "url(#grid-major)"
|
|
6408
6852
|
}
|
|
6409
6853
|
)
|
|
6410
|
-
] }) : /* @__PURE__ */ (0,
|
|
6854
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
6411
6855
|
"rect",
|
|
6412
6856
|
{
|
|
6413
6857
|
x: Math.floor(viewBox.x / 25) * 25 - viewBox.width,
|
|
@@ -6417,7 +6861,7 @@ function PIDCanvas({
|
|
|
6417
6861
|
fill: features.backgroundColor ?? "#ffffff"
|
|
6418
6862
|
}
|
|
6419
6863
|
),
|
|
6420
|
-
/* @__PURE__ */ (0,
|
|
6864
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
6421
6865
|
PipeRenderer,
|
|
6422
6866
|
{
|
|
6423
6867
|
pipes: displayDiagram.pipes,
|
|
@@ -6431,7 +6875,7 @@ function PIDCanvas({
|
|
|
6431
6875
|
onPipeSegmentClick: void 0
|
|
6432
6876
|
}
|
|
6433
6877
|
),
|
|
6434
|
-
/* @__PURE__ */ (0,
|
|
6878
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
6435
6879
|
NodeRenderer,
|
|
6436
6880
|
{
|
|
6437
6881
|
nodes: displayDiagram.nodes,
|
|
@@ -6445,7 +6889,7 @@ function PIDCanvas({
|
|
|
6445
6889
|
statusColorMap
|
|
6446
6890
|
}
|
|
6447
6891
|
),
|
|
6448
|
-
(features.editPipeRoutes ?? false) && /* @__PURE__ */ (0,
|
|
6892
|
+
(features.editPipeRoutes ?? false) && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
6449
6893
|
PipeRenderer,
|
|
6450
6894
|
{
|
|
6451
6895
|
pipes: displayDiagram.pipes,
|
|
@@ -6462,14 +6906,14 @@ function PIDCanvas({
|
|
|
6462
6906
|
onPipeSegmentClick: handlePipeSegmentClick
|
|
6463
6907
|
}
|
|
6464
6908
|
),
|
|
6465
|
-
telemetryEnabled && telemetry && /* @__PURE__ */ (0,
|
|
6909
|
+
telemetryEnabled && telemetry && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("g", { id: "layer-telemetry", children: displayDiagram.nodes.map((node) => {
|
|
6466
6910
|
const binding = telemetry.get(node.id);
|
|
6467
6911
|
if (!binding) return null;
|
|
6468
6912
|
const symbol = getSymbolDefinition(node.symbolId);
|
|
6469
6913
|
if (!symbol) return null;
|
|
6470
6914
|
const overlayX = node.transform.x + symbol.viewBox.width / 2;
|
|
6471
6915
|
const overlayY = node.transform.y + symbol.viewBox.height + 50;
|
|
6472
|
-
return /* @__PURE__ */ (0,
|
|
6916
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
6473
6917
|
DataOverlay,
|
|
6474
6918
|
{
|
|
6475
6919
|
nodeId: node.id,
|
|
@@ -6482,7 +6926,7 @@ function PIDCanvas({
|
|
|
6482
6926
|
`telemetry-${node.id}`
|
|
6483
6927
|
);
|
|
6484
6928
|
}) }),
|
|
6485
|
-
dragOverPosition && /* @__PURE__ */ (0,
|
|
6929
|
+
dragOverPosition && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
6486
6930
|
"circle",
|
|
6487
6931
|
{
|
|
6488
6932
|
cx: dragOverPosition.x,
|
|
@@ -6495,7 +6939,7 @@ function PIDCanvas({
|
|
|
6495
6939
|
pointerEvents: "none"
|
|
6496
6940
|
}
|
|
6497
6941
|
),
|
|
6498
|
-
isConnecting && connectionSource && connectionCursor && /* @__PURE__ */ (0,
|
|
6942
|
+
isConnecting && connectionSource && connectionCursor && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("g", { id: "connection-preview", pointerEvents: "none", children: (() => {
|
|
6499
6943
|
const sourceNode = displayDiagram.nodes.find((n) => n.id === connectionSource);
|
|
6500
6944
|
if (!sourceNode) return null;
|
|
6501
6945
|
const symbol = getSymbolDefinition(sourceNode.symbolId);
|
|
@@ -6511,8 +6955,8 @@ function PIDCanvas({
|
|
|
6511
6955
|
}
|
|
6512
6956
|
}
|
|
6513
6957
|
}
|
|
6514
|
-
return /* @__PURE__ */ (0,
|
|
6515
|
-
/* @__PURE__ */ (0,
|
|
6958
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
|
|
6959
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
6516
6960
|
"circle",
|
|
6517
6961
|
{
|
|
6518
6962
|
cx: lineStartX,
|
|
@@ -6524,7 +6968,7 @@ function PIDCanvas({
|
|
|
6524
6968
|
opacity: 0.6
|
|
6525
6969
|
}
|
|
6526
6970
|
),
|
|
6527
|
-
/* @__PURE__ */ (0,
|
|
6971
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
6528
6972
|
"line",
|
|
6529
6973
|
{
|
|
6530
6974
|
x1: lineStartX,
|
|
@@ -6537,7 +6981,7 @@ function PIDCanvas({
|
|
|
6537
6981
|
opacity: 0.8
|
|
6538
6982
|
}
|
|
6539
6983
|
),
|
|
6540
|
-
/* @__PURE__ */ (0,
|
|
6984
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
6541
6985
|
"circle",
|
|
6542
6986
|
{
|
|
6543
6987
|
cx: connectionCursor.x,
|
|
@@ -6549,7 +6993,7 @@ function PIDCanvas({
|
|
|
6549
6993
|
)
|
|
6550
6994
|
] });
|
|
6551
6995
|
})() }),
|
|
6552
|
-
features.connectionMode && /* @__PURE__ */ (0,
|
|
6996
|
+
features.connectionMode && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("g", { id: "port-indicators", children: displayDiagram.nodes.map((node) => {
|
|
6553
6997
|
const symbol = getSymbolDefinition(node.symbolId);
|
|
6554
6998
|
if (!symbol?.ports) return null;
|
|
6555
6999
|
return symbol.ports.map((port) => {
|
|
@@ -6557,8 +7001,8 @@ function PIDCanvas({
|
|
|
6557
7001
|
if (!portPos) return null;
|
|
6558
7002
|
const isHovered = hoveredPort === port.id && hoveredNode === node.id;
|
|
6559
7003
|
const isSourcePort = node.id === connectionSource && port.id === connectionSourcePort;
|
|
6560
|
-
return /* @__PURE__ */ (0,
|
|
6561
|
-
/* @__PURE__ */ (0,
|
|
7004
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("g", { children: [
|
|
7005
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
6562
7006
|
"circle",
|
|
6563
7007
|
{
|
|
6564
7008
|
cx: portPos.x,
|
|
@@ -6591,7 +7035,7 @@ function PIDCanvas({
|
|
|
6591
7035
|
}
|
|
6592
7036
|
}
|
|
6593
7037
|
),
|
|
6594
|
-
/* @__PURE__ */ (0,
|
|
7038
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
6595
7039
|
"circle",
|
|
6596
7040
|
{
|
|
6597
7041
|
cx: portPos.x,
|
|
@@ -6610,7 +7054,7 @@ function PIDCanvas({
|
|
|
6610
7054
|
]
|
|
6611
7055
|
}
|
|
6612
7056
|
),
|
|
6613
|
-
features.dragNodes && /* @__PURE__ */ (0,
|
|
7057
|
+
features.dragNodes && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
6614
7058
|
PositionPanel,
|
|
6615
7059
|
{
|
|
6616
7060
|
selectedNode,
|
|
@@ -6630,16 +7074,16 @@ function PIDCanvas({
|
|
|
6630
7074
|
}
|
|
6631
7075
|
|
|
6632
7076
|
// src/components/SymbolLibrary/SymbolLibrary.tsx
|
|
6633
|
-
var
|
|
6634
|
-
var
|
|
7077
|
+
var import_react18 = require("react");
|
|
7078
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
6635
7079
|
function SymbolLibrary({
|
|
6636
7080
|
className = "",
|
|
6637
7081
|
onSymbolDragStart,
|
|
6638
7082
|
showCategories = true,
|
|
6639
7083
|
categories = ["Valves", "Pumps", "Tanks", "Instruments", "Displays"]
|
|
6640
7084
|
}) {
|
|
6641
|
-
const [selectedCategory, setSelectedCategory] = (0,
|
|
6642
|
-
const [searchQuery, setSearchQuery] = (0,
|
|
7085
|
+
const [selectedCategory, setSelectedCategory] = (0, import_react18.useState)("all");
|
|
7086
|
+
const [searchQuery, setSearchQuery] = (0, import_react18.useState)("");
|
|
6643
7087
|
const symbolIds = getAvailableSymbols();
|
|
6644
7088
|
const allSymbols = symbolIds.map((id) => getSymbolDefinition(id)).filter((symbol) => symbol !== void 0);
|
|
6645
7089
|
const categoryMap = {
|
|
@@ -6660,9 +7104,9 @@ function SymbolLibrary({
|
|
|
6660
7104
|
event.dataTransfer.effectAllowed = "copy";
|
|
6661
7105
|
onSymbolDragStart?.(symbol.id, event);
|
|
6662
7106
|
};
|
|
6663
|
-
return /* @__PURE__ */ (0,
|
|
6664
|
-
/* @__PURE__ */ (0,
|
|
6665
|
-
/* @__PURE__ */ (0,
|
|
7107
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: `symbol-library ${className}`.trim(), style: styles.container, children: [
|
|
7108
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: styles.header, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h3", { style: styles.title, children: "Symbol Library" }) }),
|
|
7109
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: styles.searchContainer, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6666
7110
|
"input",
|
|
6667
7111
|
{
|
|
6668
7112
|
type: "text",
|
|
@@ -6672,8 +7116,8 @@ function SymbolLibrary({
|
|
|
6672
7116
|
style: styles.searchInput
|
|
6673
7117
|
}
|
|
6674
7118
|
) }),
|
|
6675
|
-
showCategories && /* @__PURE__ */ (0,
|
|
6676
|
-
/* @__PURE__ */ (0,
|
|
7119
|
+
showCategories && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: styles.categories, children: [
|
|
7120
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6677
7121
|
"button",
|
|
6678
7122
|
{
|
|
6679
7123
|
onClick: () => setSelectedCategory("all"),
|
|
@@ -6684,7 +7128,7 @@ function SymbolLibrary({
|
|
|
6684
7128
|
children: "All"
|
|
6685
7129
|
}
|
|
6686
7130
|
),
|
|
6687
|
-
categories.map((category) => /* @__PURE__ */ (0,
|
|
7131
|
+
categories.map((category) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6688
7132
|
"button",
|
|
6689
7133
|
{
|
|
6690
7134
|
onClick: () => setSelectedCategory(category),
|
|
@@ -6697,7 +7141,7 @@ function SymbolLibrary({
|
|
|
6697
7141
|
category
|
|
6698
7142
|
))
|
|
6699
7143
|
] }),
|
|
6700
|
-
/* @__PURE__ */ (0,
|
|
7144
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: styles.symbolGrid, children: filteredSymbols.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: styles.emptyState, children: "No symbols found" }) : filteredSymbols.map((symbol) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
6701
7145
|
"div",
|
|
6702
7146
|
{
|
|
6703
7147
|
draggable: true,
|
|
@@ -6705,15 +7149,15 @@ function SymbolLibrary({
|
|
|
6705
7149
|
style: styles.symbolCard,
|
|
6706
7150
|
title: symbol.metadata?.description || symbol.name,
|
|
6707
7151
|
children: [
|
|
6708
|
-
/* @__PURE__ */ (0,
|
|
7152
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: styles.symbolPreview, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6709
7153
|
"svg",
|
|
6710
7154
|
{
|
|
6711
7155
|
viewBox: `${symbol.viewBox.x} ${symbol.viewBox.y} ${symbol.viewBox.width} ${symbol.viewBox.height}`,
|
|
6712
7156
|
style: styles.symbolSvg,
|
|
6713
|
-
children: /* @__PURE__ */ (0,
|
|
7157
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("g", { dangerouslySetInnerHTML: { __html: symbol.svgContent } })
|
|
6714
7158
|
}
|
|
6715
7159
|
) }),
|
|
6716
|
-
/* @__PURE__ */ (0,
|
|
7160
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: styles.symbolName, children: symbol.name })
|
|
6717
7161
|
]
|
|
6718
7162
|
},
|
|
6719
7163
|
symbol.id
|
|
@@ -6822,7 +7266,7 @@ var styles = {
|
|
|
6822
7266
|
};
|
|
6823
7267
|
|
|
6824
7268
|
// src/components/NodeConfigPanel/NodeConfigPanel.tsx
|
|
6825
|
-
var
|
|
7269
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
6826
7270
|
function NodeConfigPanel({
|
|
6827
7271
|
node,
|
|
6828
7272
|
binding,
|
|
@@ -6841,15 +7285,15 @@ function NodeConfigPanel({
|
|
|
6841
7285
|
padding: "20px",
|
|
6842
7286
|
...style
|
|
6843
7287
|
};
|
|
6844
|
-
return /* @__PURE__ */ (0,
|
|
6845
|
-
/* @__PURE__ */ (0,
|
|
7288
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className, style: defaultStyle, children: [
|
|
7289
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("h2", { style: { margin: "0 0 16px 0", fontSize: "1rem", fontWeight: 600 }, children: [
|
|
6846
7290
|
"Configure: ",
|
|
6847
7291
|
node.id
|
|
6848
7292
|
] }),
|
|
6849
|
-
/* @__PURE__ */ (0,
|
|
6850
|
-
/* @__PURE__ */ (0,
|
|
6851
|
-
/* @__PURE__ */ (0,
|
|
6852
|
-
/* @__PURE__ */ (0,
|
|
7293
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { marginBottom: "20px" }, children: [
|
|
7294
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h3", { style: { fontSize: "0.875rem", fontWeight: 600, marginBottom: "8px" }, children: "Node Settings" }),
|
|
7295
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Label:" }),
|
|
7296
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
6853
7297
|
"input",
|
|
6854
7298
|
{
|
|
6855
7299
|
type: "text",
|
|
@@ -6865,10 +7309,10 @@ function NodeConfigPanel({
|
|
|
6865
7309
|
}
|
|
6866
7310
|
}
|
|
6867
7311
|
),
|
|
6868
|
-
/* @__PURE__ */ (0,
|
|
6869
|
-
/* @__PURE__ */ (0,
|
|
6870
|
-
/* @__PURE__ */ (0,
|
|
6871
|
-
/* @__PURE__ */ (0,
|
|
7312
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: "8px" }, children: [
|
|
7313
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { children: [
|
|
7314
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Label Offset X:" }),
|
|
7315
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
6872
7316
|
"input",
|
|
6873
7317
|
{
|
|
6874
7318
|
type: "number",
|
|
@@ -6889,9 +7333,9 @@ function NodeConfigPanel({
|
|
|
6889
7333
|
}
|
|
6890
7334
|
)
|
|
6891
7335
|
] }),
|
|
6892
|
-
/* @__PURE__ */ (0,
|
|
6893
|
-
/* @__PURE__ */ (0,
|
|
6894
|
-
/* @__PURE__ */ (0,
|
|
7336
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { children: [
|
|
7337
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Label Offset Y:" }),
|
|
7338
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
6895
7339
|
"input",
|
|
6896
7340
|
{
|
|
6897
7341
|
type: "number",
|
|
@@ -6913,9 +7357,9 @@ function NodeConfigPanel({
|
|
|
6913
7357
|
)
|
|
6914
7358
|
] })
|
|
6915
7359
|
] }),
|
|
6916
|
-
/* @__PURE__ */ (0,
|
|
6917
|
-
/* @__PURE__ */ (0,
|
|
6918
|
-
/* @__PURE__ */ (0,
|
|
7360
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { children: [
|
|
7361
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Label Font Size:" }),
|
|
7362
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
6919
7363
|
"input",
|
|
6920
7364
|
{
|
|
6921
7365
|
type: "number",
|
|
@@ -6935,9 +7379,9 @@ function NodeConfigPanel({
|
|
|
6935
7379
|
}
|
|
6936
7380
|
)
|
|
6937
7381
|
] }),
|
|
6938
|
-
/* @__PURE__ */ (0,
|
|
6939
|
-
/* @__PURE__ */ (0,
|
|
6940
|
-
/* @__PURE__ */ (0,
|
|
7382
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { children: [
|
|
7383
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Rotation (degrees):" }),
|
|
7384
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
6941
7385
|
"input",
|
|
6942
7386
|
{
|
|
6943
7387
|
type: "number",
|
|
@@ -6962,9 +7406,9 @@ function NodeConfigPanel({
|
|
|
6962
7406
|
)
|
|
6963
7407
|
] })
|
|
6964
7408
|
] }),
|
|
6965
|
-
/* @__PURE__ */ (0,
|
|
6966
|
-
/* @__PURE__ */ (0,
|
|
6967
|
-
!binding ? /* @__PURE__ */ (0,
|
|
7409
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { marginBottom: "20px" }, children: [
|
|
7410
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h3", { style: { fontSize: "0.875rem", fontWeight: 600, marginBottom: "8px" }, children: "Telemetry Data" }),
|
|
7411
|
+
!binding ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
6968
7412
|
"button",
|
|
6969
7413
|
{
|
|
6970
7414
|
onClick: () => {
|
|
@@ -7007,9 +7451,9 @@ function NodeConfigPanel({
|
|
|
7007
7451
|
},
|
|
7008
7452
|
children: "+ Add Telemetry"
|
|
7009
7453
|
}
|
|
7010
|
-
) : /* @__PURE__ */ (0,
|
|
7011
|
-
/* @__PURE__ */ (0,
|
|
7012
|
-
/* @__PURE__ */ (0,
|
|
7454
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
7455
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Initial Value:" }),
|
|
7456
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7013
7457
|
"input",
|
|
7014
7458
|
{
|
|
7015
7459
|
type: "number",
|
|
@@ -7031,8 +7475,8 @@ function NodeConfigPanel({
|
|
|
7031
7475
|
}
|
|
7032
7476
|
}
|
|
7033
7477
|
),
|
|
7034
|
-
/* @__PURE__ */ (0,
|
|
7035
|
-
/* @__PURE__ */ (0,
|
|
7478
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: "Unit:" }),
|
|
7479
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7036
7480
|
"input",
|
|
7037
7481
|
{
|
|
7038
7482
|
type: "text",
|
|
@@ -7054,8 +7498,8 @@ function NodeConfigPanel({
|
|
|
7054
7498
|
}
|
|
7055
7499
|
}
|
|
7056
7500
|
),
|
|
7057
|
-
/* @__PURE__ */ (0,
|
|
7058
|
-
/* @__PURE__ */ (0,
|
|
7501
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: [
|
|
7502
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7059
7503
|
"input",
|
|
7060
7504
|
{
|
|
7061
7505
|
type: "checkbox",
|
|
@@ -7077,8 +7521,8 @@ function NodeConfigPanel({
|
|
|
7077
7521
|
),
|
|
7078
7522
|
"Show Sparkline"
|
|
7079
7523
|
] }),
|
|
7080
|
-
/* @__PURE__ */ (0,
|
|
7081
|
-
/* @__PURE__ */ (0,
|
|
7524
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { marginTop: "12px" }, children: [
|
|
7525
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7082
7526
|
"label",
|
|
7083
7527
|
{
|
|
7084
7528
|
style: {
|
|
@@ -7090,10 +7534,10 @@ function NodeConfigPanel({
|
|
|
7090
7534
|
children: "Telemetry Position Offset:"
|
|
7091
7535
|
}
|
|
7092
7536
|
),
|
|
7093
|
-
/* @__PURE__ */ (0,
|
|
7094
|
-
/* @__PURE__ */ (0,
|
|
7095
|
-
/* @__PURE__ */ (0,
|
|
7096
|
-
/* @__PURE__ */ (0,
|
|
7537
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: "8px" }, children: [
|
|
7538
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { children: [
|
|
7539
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "X Offset:" }),
|
|
7540
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7097
7541
|
"input",
|
|
7098
7542
|
{
|
|
7099
7543
|
type: "number",
|
|
@@ -7120,9 +7564,9 @@ function NodeConfigPanel({
|
|
|
7120
7564
|
}
|
|
7121
7565
|
)
|
|
7122
7566
|
] }),
|
|
7123
|
-
/* @__PURE__ */ (0,
|
|
7124
|
-
/* @__PURE__ */ (0,
|
|
7125
|
-
/* @__PURE__ */ (0,
|
|
7567
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { children: [
|
|
7568
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "Y Offset:" }),
|
|
7569
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7126
7570
|
"input",
|
|
7127
7571
|
{
|
|
7128
7572
|
type: "number",
|
|
@@ -7150,8 +7594,8 @@ function NodeConfigPanel({
|
|
|
7150
7594
|
)
|
|
7151
7595
|
] })
|
|
7152
7596
|
] }),
|
|
7153
|
-
/* @__PURE__ */ (0,
|
|
7154
|
-
/* @__PURE__ */ (0,
|
|
7597
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { marginTop: "16px" }, children: [
|
|
7598
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7155
7599
|
"label",
|
|
7156
7600
|
{
|
|
7157
7601
|
style: {
|
|
@@ -7163,10 +7607,10 @@ function NodeConfigPanel({
|
|
|
7163
7607
|
children: "Display Colors:"
|
|
7164
7608
|
}
|
|
7165
7609
|
),
|
|
7166
|
-
/* @__PURE__ */ (0,
|
|
7167
|
-
/* @__PURE__ */ (0,
|
|
7168
|
-
/* @__PURE__ */ (0,
|
|
7169
|
-
/* @__PURE__ */ (0,
|
|
7610
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { marginBottom: "8px" }, children: [
|
|
7611
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "Text Color:" }),
|
|
7612
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { display: "flex", gap: "8px", alignItems: "center" }, children: [
|
|
7613
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7170
7614
|
"input",
|
|
7171
7615
|
{
|
|
7172
7616
|
type: "color",
|
|
@@ -7192,7 +7636,7 @@ function NodeConfigPanel({
|
|
|
7192
7636
|
}
|
|
7193
7637
|
}
|
|
7194
7638
|
),
|
|
7195
|
-
/* @__PURE__ */ (0,
|
|
7639
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7196
7640
|
"input",
|
|
7197
7641
|
{
|
|
7198
7642
|
type: "text",
|
|
@@ -7222,10 +7666,10 @@ function NodeConfigPanel({
|
|
|
7222
7666
|
)
|
|
7223
7667
|
] })
|
|
7224
7668
|
] }),
|
|
7225
|
-
binding.display?.showSparkline && /* @__PURE__ */ (0,
|
|
7226
|
-
/* @__PURE__ */ (0,
|
|
7227
|
-
/* @__PURE__ */ (0,
|
|
7228
|
-
/* @__PURE__ */ (0,
|
|
7669
|
+
binding.display?.showSparkline && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { marginBottom: "8px" }, children: [
|
|
7670
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "Sparkline Color:" }),
|
|
7671
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { display: "flex", gap: "8px", alignItems: "center" }, children: [
|
|
7672
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7229
7673
|
"input",
|
|
7230
7674
|
{
|
|
7231
7675
|
type: "color",
|
|
@@ -7251,7 +7695,7 @@ function NodeConfigPanel({
|
|
|
7251
7695
|
}
|
|
7252
7696
|
}
|
|
7253
7697
|
),
|
|
7254
|
-
/* @__PURE__ */ (0,
|
|
7698
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7255
7699
|
"input",
|
|
7256
7700
|
{
|
|
7257
7701
|
type: "text",
|
|
@@ -7281,9 +7725,9 @@ function NodeConfigPanel({
|
|
|
7281
7725
|
)
|
|
7282
7726
|
] })
|
|
7283
7727
|
] }),
|
|
7284
|
-
/* @__PURE__ */ (0,
|
|
7285
|
-
/* @__PURE__ */ (0,
|
|
7286
|
-
/* @__PURE__ */ (0,
|
|
7728
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { marginBottom: "8px" }, children: [
|
|
7729
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("label", { style: { fontSize: "0.7rem", display: "block", marginBottom: "4px" }, children: "Background:" }),
|
|
7730
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7287
7731
|
"input",
|
|
7288
7732
|
{
|
|
7289
7733
|
type: "text",
|
|
@@ -7311,20 +7755,20 @@ function NodeConfigPanel({
|
|
|
7311
7755
|
}
|
|
7312
7756
|
}
|
|
7313
7757
|
),
|
|
7314
|
-
/* @__PURE__ */ (0,
|
|
7758
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { fontSize: "0.65rem", color: "#6b7280", marginTop: "2px" }, children: "Use 'status' for status-based color or hex code" })
|
|
7315
7759
|
] })
|
|
7316
7760
|
] }),
|
|
7317
7761
|
" "
|
|
7318
7762
|
] })
|
|
7319
7763
|
] })
|
|
7320
7764
|
] }),
|
|
7321
|
-
binding && /* @__PURE__ */ (0,
|
|
7322
|
-
/* @__PURE__ */ (0,
|
|
7765
|
+
binding && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { marginBottom: "20px" }, children: [
|
|
7766
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h3", { style: { fontSize: "0.875rem", fontWeight: 600, marginBottom: "8px" }, children: "Thresholds" }),
|
|
7323
7767
|
["highHigh", "high", "low", "lowLow"].map((key) => {
|
|
7324
7768
|
const label = key === "highHigh" ? "High-High (\u2265)" : key === "high" ? "High (\u2265)" : key === "low" ? "Low (\u2264)" : "Low-Low (\u2264)";
|
|
7325
|
-
return /* @__PURE__ */ (0,
|
|
7326
|
-
/* @__PURE__ */ (0,
|
|
7327
|
-
/* @__PURE__ */ (0,
|
|
7769
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { marginBottom: "8px" }, children: [
|
|
7770
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: label }),
|
|
7771
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7328
7772
|
"input",
|
|
7329
7773
|
{
|
|
7330
7774
|
type: "number",
|
|
@@ -7348,8 +7792,8 @@ function NodeConfigPanel({
|
|
|
7348
7792
|
] }, key);
|
|
7349
7793
|
})
|
|
7350
7794
|
] }),
|
|
7351
|
-
binding && /* @__PURE__ */ (0,
|
|
7352
|
-
/* @__PURE__ */ (0,
|
|
7795
|
+
binding && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { marginBottom: "20px" }, children: [
|
|
7796
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h3", { style: { fontSize: "0.875rem", fontWeight: 600, marginBottom: "8px" }, children: "Status Colors" }),
|
|
7353
7797
|
["normal", "warning", "alarm", "fault", "off"].map((status) => {
|
|
7354
7798
|
const defaultColors = {
|
|
7355
7799
|
normal: "#10b981",
|
|
@@ -7359,13 +7803,13 @@ function NodeConfigPanel({
|
|
|
7359
7803
|
off: "#6b7280"
|
|
7360
7804
|
};
|
|
7361
7805
|
const label = status === "normal" ? "Normal" : status === "warning" ? "Warning" : status === "alarm" ? "Alarm" : status === "fault" ? "Fault" : "Off";
|
|
7362
|
-
return /* @__PURE__ */ (0,
|
|
7363
|
-
/* @__PURE__ */ (0,
|
|
7806
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { marginBottom: "8px" }, children: [
|
|
7807
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("label", { style: { fontSize: "0.75rem", display: "block", marginBottom: "4px" }, children: [
|
|
7364
7808
|
label,
|
|
7365
7809
|
":"
|
|
7366
7810
|
] }),
|
|
7367
|
-
/* @__PURE__ */ (0,
|
|
7368
|
-
/* @__PURE__ */ (0,
|
|
7811
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { display: "flex", gap: "8px", alignItems: "center" }, children: [
|
|
7812
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7369
7813
|
"input",
|
|
7370
7814
|
{
|
|
7371
7815
|
type: "color",
|
|
@@ -7386,7 +7830,7 @@ function NodeConfigPanel({
|
|
|
7386
7830
|
}
|
|
7387
7831
|
}
|
|
7388
7832
|
),
|
|
7389
|
-
/* @__PURE__ */ (0,
|
|
7833
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7390
7834
|
"input",
|
|
7391
7835
|
{
|
|
7392
7836
|
type: "text",
|
|
@@ -7413,7 +7857,7 @@ function NodeConfigPanel({
|
|
|
7413
7857
|
] }, status);
|
|
7414
7858
|
})
|
|
7415
7859
|
] }),
|
|
7416
|
-
/* @__PURE__ */ (0,
|
|
7860
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { marginTop: "20px", paddingTop: "20px", borderTop: "1px solid #cbd5e1" }, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7417
7861
|
"button",
|
|
7418
7862
|
{
|
|
7419
7863
|
onClick: onRemove,
|
|
@@ -7690,13 +8134,13 @@ function createControlBinding(nodeId, deviceConfig, actions) {
|
|
|
7690
8134
|
}
|
|
7691
8135
|
|
|
7692
8136
|
// src/hooks/useDeviceControls.ts
|
|
7693
|
-
var
|
|
8137
|
+
var import_react19 = require("react");
|
|
7694
8138
|
function commandKey(nodeId, kind, suffix) {
|
|
7695
8139
|
return suffix ? `${nodeId}:${kind}:${suffix}` : `${nodeId}:${kind}`;
|
|
7696
8140
|
}
|
|
7697
8141
|
function useDeviceControls(initialBindings, options) {
|
|
7698
8142
|
const { commandTimeoutMs } = options ?? {};
|
|
7699
|
-
const [controls, setControls] = (0,
|
|
8143
|
+
const [controls, setControls] = (0, import_react19.useState)(() => {
|
|
7700
8144
|
const map = /* @__PURE__ */ new Map();
|
|
7701
8145
|
if (initialBindings) {
|
|
7702
8146
|
initialBindings.forEach((binding) => {
|
|
@@ -7705,12 +8149,12 @@ function useDeviceControls(initialBindings, options) {
|
|
|
7705
8149
|
}
|
|
7706
8150
|
return map;
|
|
7707
8151
|
});
|
|
7708
|
-
const pendingRef = (0,
|
|
7709
|
-
const [pendingCommands, setPendingCommands] = (0,
|
|
7710
|
-
const syncPending = (0,
|
|
8152
|
+
const pendingRef = (0, import_react19.useRef)(/* @__PURE__ */ new Map());
|
|
8153
|
+
const [pendingCommands, setPendingCommands] = (0, import_react19.useState)(() => /* @__PURE__ */ new Set());
|
|
8154
|
+
const syncPending = (0, import_react19.useCallback)(() => {
|
|
7711
8155
|
setPendingCommands(new Set(pendingRef.current.keys()));
|
|
7712
8156
|
}, []);
|
|
7713
|
-
const updateControl = (0,
|
|
8157
|
+
const updateControl = (0, import_react19.useCallback)((nodeId, updates) => {
|
|
7714
8158
|
setControls((prev) => {
|
|
7715
8159
|
const newMap = new Map(prev);
|
|
7716
8160
|
const existing = newMap.get(nodeId);
|
|
@@ -7724,7 +8168,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
7724
8168
|
return newMap;
|
|
7725
8169
|
});
|
|
7726
8170
|
}, []);
|
|
7727
|
-
const updateControlBatch = (0,
|
|
8171
|
+
const updateControlBatch = (0, import_react19.useCallback)((updates) => {
|
|
7728
8172
|
setControls((prev) => {
|
|
7729
8173
|
const newMap = new Map(prev);
|
|
7730
8174
|
Object.entries(updates).forEach(([nodeId, update]) => {
|
|
@@ -7736,7 +8180,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
7736
8180
|
return newMap;
|
|
7737
8181
|
});
|
|
7738
8182
|
}, []);
|
|
7739
|
-
const updateDeviceState = (0,
|
|
8183
|
+
const updateDeviceState = (0, import_react19.useCallback)(
|
|
7740
8184
|
(nodeId, stateUpdates) => {
|
|
7741
8185
|
setControls((prev) => {
|
|
7742
8186
|
const newMap = new Map(prev);
|
|
@@ -7752,7 +8196,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
7752
8196
|
},
|
|
7753
8197
|
[]
|
|
7754
8198
|
);
|
|
7755
|
-
const updateParameter = (0,
|
|
8199
|
+
const updateParameter = (0, import_react19.useCallback)(
|
|
7756
8200
|
(nodeId, parameterId, value) => {
|
|
7757
8201
|
setControls((prev) => {
|
|
7758
8202
|
const newMap = new Map(prev);
|
|
@@ -7779,27 +8223,27 @@ function useDeviceControls(initialBindings, options) {
|
|
|
7779
8223
|
},
|
|
7780
8224
|
[]
|
|
7781
8225
|
);
|
|
7782
|
-
const setControlBinding = (0,
|
|
8226
|
+
const setControlBinding = (0, import_react19.useCallback)((binding) => {
|
|
7783
8227
|
setControls((prev) => {
|
|
7784
8228
|
const newMap = new Map(prev);
|
|
7785
8229
|
newMap.set(binding.nodeId, binding);
|
|
7786
8230
|
return newMap;
|
|
7787
8231
|
});
|
|
7788
8232
|
}, []);
|
|
7789
|
-
const removeControlBinding = (0,
|
|
8233
|
+
const removeControlBinding = (0, import_react19.useCallback)((nodeId) => {
|
|
7790
8234
|
setControls((prev) => {
|
|
7791
8235
|
const newMap = new Map(prev);
|
|
7792
8236
|
newMap.delete(nodeId);
|
|
7793
8237
|
return newMap;
|
|
7794
8238
|
});
|
|
7795
8239
|
}, []);
|
|
7796
|
-
const getControlBinding = (0,
|
|
8240
|
+
const getControlBinding = (0, import_react19.useCallback)(
|
|
7797
8241
|
(nodeId) => {
|
|
7798
8242
|
return controls.get(nodeId);
|
|
7799
8243
|
},
|
|
7800
8244
|
[controls]
|
|
7801
8245
|
);
|
|
7802
|
-
const isCommandPending = (0,
|
|
8246
|
+
const isCommandPending = (0, import_react19.useCallback)(
|
|
7803
8247
|
(nodeId, kind) => {
|
|
7804
8248
|
if (kind) {
|
|
7805
8249
|
const prefix2 = `${nodeId}:${kind}`;
|
|
@@ -7816,7 +8260,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
7816
8260
|
},
|
|
7817
8261
|
[pendingCommands]
|
|
7818
8262
|
);
|
|
7819
|
-
const markPending = (0,
|
|
8263
|
+
const markPending = (0, import_react19.useCallback)(
|
|
7820
8264
|
(key, delta) => {
|
|
7821
8265
|
const next = (pendingRef.current.get(key) ?? 0) + delta;
|
|
7822
8266
|
if (next > 0) pendingRef.current.set(key, next);
|
|
@@ -7825,7 +8269,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
7825
8269
|
},
|
|
7826
8270
|
[syncPending]
|
|
7827
8271
|
);
|
|
7828
|
-
const runCommand = (0,
|
|
8272
|
+
const runCommand = (0, import_react19.useCallback)(
|
|
7829
8273
|
async (nodeId, key, invoke, messages) => {
|
|
7830
8274
|
const binding = controls.get(nodeId);
|
|
7831
8275
|
if (!binding) return;
|
|
@@ -7865,7 +8309,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
7865
8309
|
},
|
|
7866
8310
|
[controls, updateDeviceState, markPending, commandTimeoutMs]
|
|
7867
8311
|
);
|
|
7868
|
-
const sendModeChange = (0,
|
|
8312
|
+
const sendModeChange = (0, import_react19.useCallback)(
|
|
7869
8313
|
(nodeId, mode) => runCommand(
|
|
7870
8314
|
nodeId,
|
|
7871
8315
|
commandKey(nodeId, "mode"),
|
|
@@ -7874,7 +8318,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
7874
8318
|
),
|
|
7875
8319
|
[runCommand]
|
|
7876
8320
|
);
|
|
7877
|
-
const sendParameterChange = (0,
|
|
8321
|
+
const sendParameterChange = (0, import_react19.useCallback)(
|
|
7878
8322
|
(nodeId, parameterId, value) => runCommand(
|
|
7879
8323
|
nodeId,
|
|
7880
8324
|
commandKey(nodeId, "parameter", parameterId),
|
|
@@ -7883,21 +8327,21 @@ function useDeviceControls(initialBindings, options) {
|
|
|
7883
8327
|
),
|
|
7884
8328
|
[runCommand]
|
|
7885
8329
|
);
|
|
7886
|
-
const sendStartCommand = (0,
|
|
8330
|
+
const sendStartCommand = (0, import_react19.useCallback)(
|
|
7887
8331
|
(nodeId) => runCommand(nodeId, commandKey(nodeId, "start"), (binding) => binding.actions.onStart?.(), {
|
|
7888
8332
|
success: "Start command sent",
|
|
7889
8333
|
failure: "Start command failed"
|
|
7890
8334
|
}),
|
|
7891
8335
|
[runCommand]
|
|
7892
8336
|
);
|
|
7893
|
-
const sendStopCommand = (0,
|
|
8337
|
+
const sendStopCommand = (0, import_react19.useCallback)(
|
|
7894
8338
|
(nodeId) => runCommand(nodeId, commandKey(nodeId, "stop"), (binding) => binding.actions.onStop?.(), {
|
|
7895
8339
|
success: "Stop command sent",
|
|
7896
8340
|
failure: "Stop command failed"
|
|
7897
8341
|
}),
|
|
7898
8342
|
[runCommand]
|
|
7899
8343
|
);
|
|
7900
|
-
const sendCustomAction = (0,
|
|
8344
|
+
const sendCustomAction = (0, import_react19.useCallback)(
|
|
7901
8345
|
(nodeId, actionId) => runCommand(
|
|
7902
8346
|
nodeId,
|
|
7903
8347
|
commandKey(nodeId, "action", actionId),
|
|
@@ -7950,9 +8394,9 @@ function createConfigBinding(nodeId, tag, parameters, actions, options) {
|
|
|
7950
8394
|
}
|
|
7951
8395
|
|
|
7952
8396
|
// src/hooks/useDeviceConfigs.ts
|
|
7953
|
-
var
|
|
8397
|
+
var import_react20 = require("react");
|
|
7954
8398
|
function useDeviceConfigs(initialConfigs) {
|
|
7955
|
-
const [configs, setConfigs] = (0,
|
|
8399
|
+
const [configs, setConfigs] = (0, import_react20.useState)(() => {
|
|
7956
8400
|
const map = /* @__PURE__ */ new Map();
|
|
7957
8401
|
if (initialConfigs) {
|
|
7958
8402
|
initialConfigs.forEach((config) => {
|
|
@@ -7961,13 +8405,13 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
7961
8405
|
}
|
|
7962
8406
|
return map;
|
|
7963
8407
|
});
|
|
7964
|
-
const getConfig = (0,
|
|
8408
|
+
const getConfig = (0, import_react20.useCallback)(
|
|
7965
8409
|
(nodeId) => {
|
|
7966
8410
|
return configs.get(nodeId);
|
|
7967
8411
|
},
|
|
7968
8412
|
[configs]
|
|
7969
8413
|
);
|
|
7970
|
-
const updateConfig = (0,
|
|
8414
|
+
const updateConfig = (0, import_react20.useCallback)((nodeId, updates) => {
|
|
7971
8415
|
setConfigs((prev) => {
|
|
7972
8416
|
const newMap = new Map(prev);
|
|
7973
8417
|
const existing = newMap.get(nodeId);
|
|
@@ -7981,7 +8425,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
7981
8425
|
return newMap;
|
|
7982
8426
|
});
|
|
7983
8427
|
}, []);
|
|
7984
|
-
const updateConfigState = (0,
|
|
8428
|
+
const updateConfigState = (0, import_react20.useCallback)((nodeId, stateUpdates) => {
|
|
7985
8429
|
setConfigs((prev) => {
|
|
7986
8430
|
const newMap = new Map(prev);
|
|
7987
8431
|
const existing = newMap.get(nodeId);
|
|
@@ -7994,7 +8438,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
7994
8438
|
return newMap;
|
|
7995
8439
|
});
|
|
7996
8440
|
}, []);
|
|
7997
|
-
const updateConfigBatch = (0,
|
|
8441
|
+
const updateConfigBatch = (0, import_react20.useCallback)((updates) => {
|
|
7998
8442
|
setConfigs((prev) => {
|
|
7999
8443
|
const newMap = new Map(prev);
|
|
8000
8444
|
Object.entries(updates).forEach(([nodeId, update]) => {
|
|
@@ -8006,7 +8450,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
8006
8450
|
return newMap;
|
|
8007
8451
|
});
|
|
8008
8452
|
}, []);
|
|
8009
|
-
const updateParameterValue = (0,
|
|
8453
|
+
const updateParameterValue = (0, import_react20.useCallback)((nodeId, parameterId, value) => {
|
|
8010
8454
|
setConfigs((prev) => {
|
|
8011
8455
|
const newMap = new Map(prev);
|
|
8012
8456
|
const existing = newMap.get(nodeId);
|
|
@@ -8023,7 +8467,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
8023
8467
|
return newMap;
|
|
8024
8468
|
});
|
|
8025
8469
|
}, []);
|
|
8026
|
-
const applyConfig = (0,
|
|
8470
|
+
const applyConfig = (0, import_react20.useCallback)(
|
|
8027
8471
|
async (nodeId) => {
|
|
8028
8472
|
const config = configs.get(nodeId);
|
|
8029
8473
|
if (!config || !config.actions.onApply) {
|
|
@@ -8056,7 +8500,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
8056
8500
|
},
|
|
8057
8501
|
[configs, updateConfigState]
|
|
8058
8502
|
);
|
|
8059
|
-
const saveConfig = (0,
|
|
8503
|
+
const saveConfig = (0, import_react20.useCallback)(
|
|
8060
8504
|
async (nodeId) => {
|
|
8061
8505
|
const config = configs.get(nodeId);
|
|
8062
8506
|
if (!config || !config.actions.onSave) {
|
|
@@ -8090,7 +8534,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
8090
8534
|
},
|
|
8091
8535
|
[configs, updateConfigState]
|
|
8092
8536
|
);
|
|
8093
|
-
const resetConfig = (0,
|
|
8537
|
+
const resetConfig = (0, import_react20.useCallback)(
|
|
8094
8538
|
async (nodeId) => {
|
|
8095
8539
|
const config = configs.get(nodeId);
|
|
8096
8540
|
if (!config) {
|
|
@@ -8120,7 +8564,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
8120
8564
|
},
|
|
8121
8565
|
[configs, updateConfig, updateConfigState]
|
|
8122
8566
|
);
|
|
8123
|
-
const cancelConfig = (0,
|
|
8567
|
+
const cancelConfig = (0, import_react20.useCallback)(
|
|
8124
8568
|
(nodeId) => {
|
|
8125
8569
|
const config = configs.get(nodeId);
|
|
8126
8570
|
if (config?.actions.onCancel) {
|
|
@@ -8129,7 +8573,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
8129
8573
|
},
|
|
8130
8574
|
[configs]
|
|
8131
8575
|
);
|
|
8132
|
-
const validateConfig = (0,
|
|
8576
|
+
const validateConfig = (0, import_react20.useCallback)(
|
|
8133
8577
|
(nodeId) => {
|
|
8134
8578
|
const config = configs.get(nodeId);
|
|
8135
8579
|
if (!config) {
|
|
@@ -8171,21 +8615,21 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
8171
8615
|
},
|
|
8172
8616
|
[configs, updateConfigState]
|
|
8173
8617
|
);
|
|
8174
|
-
const setConfig = (0,
|
|
8618
|
+
const setConfig = (0, import_react20.useCallback)((config) => {
|
|
8175
8619
|
setConfigs((prev) => {
|
|
8176
8620
|
const newMap = new Map(prev);
|
|
8177
8621
|
newMap.set(config.nodeId, config);
|
|
8178
8622
|
return newMap;
|
|
8179
8623
|
});
|
|
8180
8624
|
}, []);
|
|
8181
|
-
const removeConfig = (0,
|
|
8625
|
+
const removeConfig = (0, import_react20.useCallback)((nodeId) => {
|
|
8182
8626
|
setConfigs((prev) => {
|
|
8183
8627
|
const newMap = new Map(prev);
|
|
8184
8628
|
newMap.delete(nodeId);
|
|
8185
8629
|
return newMap;
|
|
8186
8630
|
});
|
|
8187
8631
|
}, []);
|
|
8188
|
-
const clearConfigs = (0,
|
|
8632
|
+
const clearConfigs = (0, import_react20.useCallback)(() => {
|
|
8189
8633
|
setConfigs(/* @__PURE__ */ new Map());
|
|
8190
8634
|
}, []);
|
|
8191
8635
|
return {
|
|
@@ -8207,8 +8651,8 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
8207
8651
|
}
|
|
8208
8652
|
|
|
8209
8653
|
// src/components/DeviceConfigPanel/DeviceConfigPanel.tsx
|
|
8210
|
-
var
|
|
8211
|
-
var
|
|
8654
|
+
var import_react21 = require("react");
|
|
8655
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
8212
8656
|
function DeviceConfigPanel({
|
|
8213
8657
|
binding,
|
|
8214
8658
|
onClose,
|
|
@@ -8226,7 +8670,7 @@ function DeviceConfigPanel({
|
|
|
8226
8670
|
showControlsButton = true,
|
|
8227
8671
|
embedded = false
|
|
8228
8672
|
}) {
|
|
8229
|
-
const [localValues, setLocalValues] = (0,
|
|
8673
|
+
const [localValues, setLocalValues] = (0, import_react21.useState)(() => {
|
|
8230
8674
|
if (binding) {
|
|
8231
8675
|
const values = {};
|
|
8232
8676
|
binding.parameters.forEach((param) => {
|
|
@@ -8236,7 +8680,7 @@ function DeviceConfigPanel({
|
|
|
8236
8680
|
}
|
|
8237
8681
|
return {};
|
|
8238
8682
|
});
|
|
8239
|
-
const [collapsedSections, setCollapsedSections] = (0,
|
|
8683
|
+
const [collapsedSections, setCollapsedSections] = (0, import_react21.useState)(() => {
|
|
8240
8684
|
const collapsed = /* @__PURE__ */ new Set();
|
|
8241
8685
|
if (binding?.sections) {
|
|
8242
8686
|
binding.sections.forEach((section) => {
|
|
@@ -8247,9 +8691,9 @@ function DeviceConfigPanel({
|
|
|
8247
8691
|
}
|
|
8248
8692
|
return collapsed;
|
|
8249
8693
|
});
|
|
8250
|
-
const [showToast, setShowToast] = (0,
|
|
8251
|
-
const [bindingId, setBindingId] = (0,
|
|
8252
|
-
const lastResultTimestampRef = (0,
|
|
8694
|
+
const [showToast, setShowToast] = (0, import_react21.useState)(true);
|
|
8695
|
+
const [bindingId, setBindingId] = (0, import_react21.useState)(binding?.nodeId || null);
|
|
8696
|
+
const lastResultTimestampRef = (0, import_react21.useRef)(0);
|
|
8253
8697
|
if (binding && binding.nodeId !== bindingId) {
|
|
8254
8698
|
const values = {};
|
|
8255
8699
|
binding.parameters.forEach((param) => {
|
|
@@ -8265,7 +8709,7 @@ function DeviceConfigPanel({
|
|
|
8265
8709
|
setCollapsedSections(collapsed);
|
|
8266
8710
|
setBindingId(binding.nodeId);
|
|
8267
8711
|
}
|
|
8268
|
-
(0,
|
|
8712
|
+
(0, import_react21.useEffect)(() => {
|
|
8269
8713
|
const currentTimestamp = binding?.state.lastSaved || 0;
|
|
8270
8714
|
if (binding?.state.lastSaveResult && currentTimestamp !== lastResultTimestampRef.current) {
|
|
8271
8715
|
lastResultTimestampRef.current = currentTimestamp;
|
|
@@ -8279,7 +8723,7 @@ function DeviceConfigPanel({
|
|
|
8279
8723
|
return () => clearTimeout(showTimer);
|
|
8280
8724
|
}
|
|
8281
8725
|
}, [binding?.state.lastSaveResult, binding?.state.lastSaved, toastDuration]);
|
|
8282
|
-
const parametersBySection = (0,
|
|
8726
|
+
const parametersBySection = (0, import_react21.useMemo)(() => {
|
|
8283
8727
|
if (!binding) return { _unsectioned: [] };
|
|
8284
8728
|
const groups = { _unsectioned: [] };
|
|
8285
8729
|
binding.parameters.forEach((param) => {
|
|
@@ -8294,7 +8738,7 @@ function DeviceConfigPanel({
|
|
|
8294
8738
|
});
|
|
8295
8739
|
return groups;
|
|
8296
8740
|
}, [binding]);
|
|
8297
|
-
const sortedSections = (0,
|
|
8741
|
+
const sortedSections = (0, import_react21.useMemo)(() => {
|
|
8298
8742
|
if (!binding?.sections) return [];
|
|
8299
8743
|
return [...binding.sections].sort((a, b) => (a.order || 0) - (b.order || 0));
|
|
8300
8744
|
}, [binding]);
|
|
@@ -8370,14 +8814,14 @@ function DeviceConfigPanel({
|
|
|
8370
8814
|
const value = localValues[param.id];
|
|
8371
8815
|
const error = binding.state.errors?.[param.id];
|
|
8372
8816
|
const isDisabled = param.readOnly || param.enabled === false;
|
|
8373
|
-
return /* @__PURE__ */ (0,
|
|
8817
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
8374
8818
|
"div",
|
|
8375
8819
|
{
|
|
8376
8820
|
style: {
|
|
8377
8821
|
marginBottom: spacing.marginBottom
|
|
8378
8822
|
},
|
|
8379
8823
|
children: [
|
|
8380
|
-
/* @__PURE__ */ (0,
|
|
8824
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
8381
8825
|
"label",
|
|
8382
8826
|
{
|
|
8383
8827
|
style: {
|
|
@@ -8392,8 +8836,8 @@ function DeviceConfigPanel({
|
|
|
8392
8836
|
},
|
|
8393
8837
|
children: [
|
|
8394
8838
|
param.label,
|
|
8395
|
-
param.required && /* @__PURE__ */ (0,
|
|
8396
|
-
param.unit && /* @__PURE__ */ (0,
|
|
8839
|
+
param.required && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { style: { color: errorColor }, children: " *" }),
|
|
8840
|
+
param.unit && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("span", { style: { color: mutedTextColor, fontWeight: "normal" }, children: [
|
|
8397
8841
|
" (",
|
|
8398
8842
|
param.unit,
|
|
8399
8843
|
")"
|
|
@@ -8401,7 +8845,7 @@ function DeviceConfigPanel({
|
|
|
8401
8845
|
]
|
|
8402
8846
|
}
|
|
8403
8847
|
),
|
|
8404
|
-
param.description && /* @__PURE__ */ (0,
|
|
8848
|
+
param.description && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8405
8849
|
"div",
|
|
8406
8850
|
{
|
|
8407
8851
|
style: {
|
|
@@ -8413,7 +8857,7 @@ function DeviceConfigPanel({
|
|
|
8413
8857
|
children: param.description
|
|
8414
8858
|
}
|
|
8415
8859
|
),
|
|
8416
|
-
param.type === "number" && /* @__PURE__ */ (0,
|
|
8860
|
+
param.type === "number" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8417
8861
|
"input",
|
|
8418
8862
|
{
|
|
8419
8863
|
type: "number",
|
|
@@ -8437,7 +8881,7 @@ function DeviceConfigPanel({
|
|
|
8437
8881
|
}
|
|
8438
8882
|
}
|
|
8439
8883
|
),
|
|
8440
|
-
param.type === "string" && /* @__PURE__ */ (0,
|
|
8884
|
+
param.type === "string" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8441
8885
|
"input",
|
|
8442
8886
|
{
|
|
8443
8887
|
type: "text",
|
|
@@ -8458,7 +8902,7 @@ function DeviceConfigPanel({
|
|
|
8458
8902
|
}
|
|
8459
8903
|
}
|
|
8460
8904
|
),
|
|
8461
|
-
param.type === "boolean" && /* @__PURE__ */ (0,
|
|
8905
|
+
param.type === "boolean" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
8462
8906
|
"label",
|
|
8463
8907
|
{
|
|
8464
8908
|
style: {
|
|
@@ -8468,7 +8912,7 @@ function DeviceConfigPanel({
|
|
|
8468
8912
|
cursor: isDisabled ? "not-allowed" : "pointer"
|
|
8469
8913
|
},
|
|
8470
8914
|
children: [
|
|
8471
|
-
/* @__PURE__ */ (0,
|
|
8915
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8472
8916
|
"input",
|
|
8473
8917
|
{
|
|
8474
8918
|
type: "checkbox",
|
|
@@ -8482,11 +8926,11 @@ function DeviceConfigPanel({
|
|
|
8482
8926
|
}
|
|
8483
8927
|
}
|
|
8484
8928
|
),
|
|
8485
|
-
/* @__PURE__ */ (0,
|
|
8929
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { style: { fontSize: `${fontSize.value}px`, color: textColor }, children: value ? "Enabled" : "Disabled" })
|
|
8486
8930
|
]
|
|
8487
8931
|
}
|
|
8488
8932
|
),
|
|
8489
|
-
param.type === "select" && /* @__PURE__ */ (0,
|
|
8933
|
+
param.type === "select" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8490
8934
|
"select",
|
|
8491
8935
|
{
|
|
8492
8936
|
value: value ?? "",
|
|
@@ -8504,10 +8948,10 @@ function DeviceConfigPanel({
|
|
|
8504
8948
|
borderRadius: "2px",
|
|
8505
8949
|
outline: "none"
|
|
8506
8950
|
},
|
|
8507
|
-
children: param.options?.map((option) => /* @__PURE__ */ (0,
|
|
8951
|
+
children: param.options?.map((option) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("option", { value: option.value, children: option.label }, option.value))
|
|
8508
8952
|
}
|
|
8509
8953
|
),
|
|
8510
|
-
error && /* @__PURE__ */ (0,
|
|
8954
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8511
8955
|
"div",
|
|
8512
8956
|
{
|
|
8513
8957
|
style: {
|
|
@@ -8527,7 +8971,7 @@ function DeviceConfigPanel({
|
|
|
8527
8971
|
const renderSection = (section) => {
|
|
8528
8972
|
const params = parametersBySection[section.id] || [];
|
|
8529
8973
|
const isCollapsed = collapsedSections.has(section.id);
|
|
8530
|
-
return /* @__PURE__ */ (0,
|
|
8974
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
8531
8975
|
"div",
|
|
8532
8976
|
{
|
|
8533
8977
|
style: {
|
|
@@ -8537,7 +8981,7 @@ function DeviceConfigPanel({
|
|
|
8537
8981
|
backgroundColor: surfaceColor
|
|
8538
8982
|
},
|
|
8539
8983
|
children: [
|
|
8540
|
-
/* @__PURE__ */ (0,
|
|
8984
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
8541
8985
|
"div",
|
|
8542
8986
|
{
|
|
8543
8987
|
onClick: () => section.collapsible && toggleSection(section.id),
|
|
@@ -8550,8 +8994,8 @@ function DeviceConfigPanel({
|
|
|
8550
8994
|
alignItems: "center"
|
|
8551
8995
|
},
|
|
8552
8996
|
children: [
|
|
8553
|
-
/* @__PURE__ */ (0,
|
|
8554
|
-
/* @__PURE__ */ (0,
|
|
8997
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { children: [
|
|
8998
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
8555
8999
|
"div",
|
|
8556
9000
|
{
|
|
8557
9001
|
style: {
|
|
@@ -8563,12 +9007,12 @@ function DeviceConfigPanel({
|
|
|
8563
9007
|
letterSpacing: "0.5px"
|
|
8564
9008
|
},
|
|
8565
9009
|
children: [
|
|
8566
|
-
section.icon && /* @__PURE__ */ (0,
|
|
9010
|
+
section.icon && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { style: { marginRight: "8px" }, children: section.icon }),
|
|
8567
9011
|
section.title
|
|
8568
9012
|
]
|
|
8569
9013
|
}
|
|
8570
9014
|
),
|
|
8571
|
-
section.description && /* @__PURE__ */ (0,
|
|
9015
|
+
section.description && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8572
9016
|
"div",
|
|
8573
9017
|
{
|
|
8574
9018
|
style: {
|
|
@@ -8581,11 +9025,11 @@ function DeviceConfigPanel({
|
|
|
8581
9025
|
}
|
|
8582
9026
|
)
|
|
8583
9027
|
] }),
|
|
8584
|
-
section.collapsible && /* @__PURE__ */ (0,
|
|
9028
|
+
section.collapsible && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { style: { fontSize: "16px", color: mutedTextColor }, children: isCollapsed ? "\u25BC" : "\u25B2" })
|
|
8585
9029
|
]
|
|
8586
9030
|
}
|
|
8587
9031
|
),
|
|
8588
|
-
!isCollapsed && /* @__PURE__ */ (0,
|
|
9032
|
+
!isCollapsed && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { padding: spacing.padding }, children: params.map(renderParameter) })
|
|
8589
9033
|
]
|
|
8590
9034
|
},
|
|
8591
9035
|
section.id
|
|
@@ -8644,9 +9088,9 @@ function DeviceConfigPanel({
|
|
|
8644
9088
|
const showSave = binding.display?.showSave !== false && binding.actions.onSave;
|
|
8645
9089
|
const showReset = binding.display?.showReset !== false && binding.actions.onReset;
|
|
8646
9090
|
const showCancel = binding.display?.showCancel !== false;
|
|
8647
|
-
return /* @__PURE__ */ (0,
|
|
8648
|
-
/* @__PURE__ */ (0,
|
|
8649
|
-
/* @__PURE__ */ (0,
|
|
9091
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
9092
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: panelStyle, className: binding.display?.className, children: [
|
|
9093
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
8650
9094
|
"div",
|
|
8651
9095
|
{
|
|
8652
9096
|
style: {
|
|
@@ -8658,8 +9102,8 @@ function DeviceConfigPanel({
|
|
|
8658
9102
|
borderBottom: `2px solid ${borderColor}`
|
|
8659
9103
|
},
|
|
8660
9104
|
children: [
|
|
8661
|
-
/* @__PURE__ */ (0,
|
|
8662
|
-
/* @__PURE__ */ (0,
|
|
9105
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { children: [
|
|
9106
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8663
9107
|
"h3",
|
|
8664
9108
|
{
|
|
8665
9109
|
style: {
|
|
@@ -8679,7 +9123,7 @@ function DeviceConfigPanel({
|
|
|
8679
9123
|
children: titleText.length > 25 ? titleText.slice(0, 25) + "..." : titleText
|
|
8680
9124
|
}
|
|
8681
9125
|
),
|
|
8682
|
-
binding.display?.subtitle && /* @__PURE__ */ (0,
|
|
9126
|
+
binding.display?.subtitle && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8683
9127
|
"div",
|
|
8684
9128
|
{
|
|
8685
9129
|
style: {
|
|
@@ -8692,8 +9136,8 @@ function DeviceConfigPanel({
|
|
|
8692
9136
|
}
|
|
8693
9137
|
)
|
|
8694
9138
|
] }),
|
|
8695
|
-
/* @__PURE__ */ (0,
|
|
8696
|
-
showControlsButton && onOpenControls && /* @__PURE__ */ (0,
|
|
9139
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { display: "flex", gap: "8px" }, children: [
|
|
9140
|
+
showControlsButton && onOpenControls && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8697
9141
|
"button",
|
|
8698
9142
|
{
|
|
8699
9143
|
onClick: onOpenControls,
|
|
@@ -8716,7 +9160,7 @@ function DeviceConfigPanel({
|
|
|
8716
9160
|
children: "CTRL"
|
|
8717
9161
|
}
|
|
8718
9162
|
),
|
|
8719
|
-
onUndock && /* @__PURE__ */ (0,
|
|
9163
|
+
onUndock && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8720
9164
|
"button",
|
|
8721
9165
|
{
|
|
8722
9166
|
onClick: onUndock,
|
|
@@ -8737,7 +9181,7 @@ function DeviceConfigPanel({
|
|
|
8737
9181
|
children: undockIcon
|
|
8738
9182
|
}
|
|
8739
9183
|
),
|
|
8740
|
-
/* @__PURE__ */ (0,
|
|
9184
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8741
9185
|
"button",
|
|
8742
9186
|
{
|
|
8743
9187
|
onClick: onClose,
|
|
@@ -8760,7 +9204,7 @@ function DeviceConfigPanel({
|
|
|
8760
9204
|
]
|
|
8761
9205
|
}
|
|
8762
9206
|
),
|
|
8763
|
-
binding.state.isDirty && /* @__PURE__ */ (0,
|
|
9207
|
+
binding.state.isDirty && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8764
9208
|
"div",
|
|
8765
9209
|
{
|
|
8766
9210
|
style: {
|
|
@@ -8775,11 +9219,11 @@ function DeviceConfigPanel({
|
|
|
8775
9219
|
children: "Unsaved changes"
|
|
8776
9220
|
}
|
|
8777
9221
|
),
|
|
8778
|
-
/* @__PURE__ */ (0,
|
|
9222
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { flex: 1, overflowY: "auto", marginBottom: spacing.marginBottom }, children: sortedSections.length > 0 ? sortedSections.map(renderSection) : (
|
|
8779
9223
|
/* Render unsectioned parameters */
|
|
8780
|
-
/* @__PURE__ */ (0,
|
|
9224
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { children: parametersBySection._unsectioned?.map(renderParameter) })
|
|
8781
9225
|
) }),
|
|
8782
|
-
/* @__PURE__ */ (0,
|
|
9226
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
8783
9227
|
"div",
|
|
8784
9228
|
{
|
|
8785
9229
|
style: {
|
|
@@ -8790,7 +9234,7 @@ function DeviceConfigPanel({
|
|
|
8790
9234
|
flexWrap: "wrap"
|
|
8791
9235
|
},
|
|
8792
9236
|
children: [
|
|
8793
|
-
showApply && /* @__PURE__ */ (0,
|
|
9237
|
+
showApply && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8794
9238
|
"button",
|
|
8795
9239
|
{
|
|
8796
9240
|
onClick: handleApply,
|
|
@@ -8813,7 +9257,7 @@ function DeviceConfigPanel({
|
|
|
8813
9257
|
children: binding.state.isSaving ? "Applying..." : "Apply"
|
|
8814
9258
|
}
|
|
8815
9259
|
),
|
|
8816
|
-
showSave && /* @__PURE__ */ (0,
|
|
9260
|
+
showSave && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8817
9261
|
"button",
|
|
8818
9262
|
{
|
|
8819
9263
|
onClick: handleSave,
|
|
@@ -8836,7 +9280,7 @@ function DeviceConfigPanel({
|
|
|
8836
9280
|
children: binding.state.isSaving ? "Saving..." : "Save"
|
|
8837
9281
|
}
|
|
8838
9282
|
),
|
|
8839
|
-
showReset && /* @__PURE__ */ (0,
|
|
9283
|
+
showReset && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8840
9284
|
"button",
|
|
8841
9285
|
{
|
|
8842
9286
|
onClick: handleReset,
|
|
@@ -8859,7 +9303,7 @@ function DeviceConfigPanel({
|
|
|
8859
9303
|
children: "Reset"
|
|
8860
9304
|
}
|
|
8861
9305
|
),
|
|
8862
|
-
showCancel && /* @__PURE__ */ (0,
|
|
9306
|
+
showCancel && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8863
9307
|
"button",
|
|
8864
9308
|
{
|
|
8865
9309
|
onClick: handleCancel,
|
|
@@ -8886,7 +9330,7 @@ function DeviceConfigPanel({
|
|
|
8886
9330
|
}
|
|
8887
9331
|
)
|
|
8888
9332
|
] }),
|
|
8889
|
-
binding.state.lastSaveResult && showToast && /* @__PURE__ */ (0,
|
|
9333
|
+
binding.state.lastSaveResult && showToast && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8890
9334
|
"div",
|
|
8891
9335
|
{
|
|
8892
9336
|
style: {
|
|
@@ -8910,7 +9354,7 @@ function DeviceConfigPanel({
|
|
|
8910
9354
|
}
|
|
8911
9355
|
|
|
8912
9356
|
// src/diagram/hooks/useSimulation.ts
|
|
8913
|
-
var
|
|
9357
|
+
var import_react22 = require("react");
|
|
8914
9358
|
function useSimulation(telemetry, updateTelemetryBatch, options = {}) {
|
|
8915
9359
|
const {
|
|
8916
9360
|
interval = 2e3,
|
|
@@ -8921,7 +9365,7 @@ function useSimulation(telemetry, updateTelemetryBatch, options = {}) {
|
|
|
8921
9365
|
historyLength = 10,
|
|
8922
9366
|
generateValue
|
|
8923
9367
|
} = options;
|
|
8924
|
-
(0,
|
|
9368
|
+
(0, import_react22.useEffect)(() => {
|
|
8925
9369
|
if (!enabled) return;
|
|
8926
9370
|
const intervalId = setInterval(() => {
|
|
8927
9371
|
const updates = [];
|
|
@@ -8994,6 +9438,7 @@ function useSimulation(telemetry, updateTelemetryBatch, options = {}) {
|
|
|
8994
9438
|
LegacyValueEntry,
|
|
8995
9439
|
NodeConfigPanel,
|
|
8996
9440
|
NodeControlsPanel,
|
|
9441
|
+
NumpadDialog,
|
|
8997
9442
|
PIDCanvas,
|
|
8998
9443
|
PanelContent,
|
|
8999
9444
|
PanelTabs,
|