@procaaso/alphinity-ui-components 1.8.0 → 1.8.2
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 +273 -235
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +82 -68
- package/dist/index.d.ts +82 -68
- package/dist/index.js +130 -92
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3382,7 +3382,10 @@ var ThemeToggle = ({
|
|
|
3382
3382
|
};
|
|
3383
3383
|
|
|
3384
3384
|
// src/components/PIDCanvas/PIDCanvas.tsx
|
|
3385
|
-
var
|
|
3385
|
+
var import_react20 = __toESM(require("react"), 1);
|
|
3386
|
+
|
|
3387
|
+
// src/components/PIDCanvas/NodeRenderer.tsx
|
|
3388
|
+
var import_react10 = __toESM(require("react"), 1);
|
|
3386
3389
|
|
|
3387
3390
|
// src/diagram/symbols/mockSymbolLibrary.ts
|
|
3388
3391
|
var mockSymbolLibrary = {
|
|
@@ -4604,7 +4607,7 @@ function getAvailableSymbols() {
|
|
|
4604
4607
|
|
|
4605
4608
|
// src/components/PIDCanvas/NodeRenderer.tsx
|
|
4606
4609
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
4607
|
-
function
|
|
4610
|
+
function NodeRendererImpl({
|
|
4608
4611
|
nodes: nodes2,
|
|
4609
4612
|
selectedNodeIds,
|
|
4610
4613
|
onNodeClick,
|
|
@@ -4750,10 +4753,12 @@ function NodeRenderer({
|
|
|
4750
4753
|
);
|
|
4751
4754
|
}) });
|
|
4752
4755
|
}
|
|
4756
|
+
var NodeRenderer = import_react10.default.memo(NodeRendererImpl);
|
|
4753
4757
|
|
|
4754
4758
|
// src/components/PIDCanvas/PipeRenderer.tsx
|
|
4759
|
+
var import_react11 = __toESM(require("react"), 1);
|
|
4755
4760
|
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
4756
|
-
function
|
|
4761
|
+
function PipeRendererImpl({
|
|
4757
4762
|
pipes,
|
|
4758
4763
|
selectedPipeIds,
|
|
4759
4764
|
onPipeClick,
|
|
@@ -4930,10 +4935,36 @@ function PipeRenderer({
|
|
|
4930
4935
|
);
|
|
4931
4936
|
}) });
|
|
4932
4937
|
}
|
|
4938
|
+
var PipeRenderer = import_react11.default.memo(PipeRendererImpl);
|
|
4933
4939
|
|
|
4934
4940
|
// src/components/PIDCanvas/DataOverlay.tsx
|
|
4941
|
+
var import_react12 = __toESM(require("react"), 1);
|
|
4935
4942
|
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
4936
|
-
|
|
4943
|
+
var PULSE_KEYFRAME_ID = "pid-data-overlay-pulse-keyframes";
|
|
4944
|
+
var PULSE_ANIMATION = "pid-data-overlay-pulse 1.5s ease-in-out infinite";
|
|
4945
|
+
function ensurePulseKeyframes() {
|
|
4946
|
+
if (typeof document === "undefined") return;
|
|
4947
|
+
if (document.getElementById(PULSE_KEYFRAME_ID)) return;
|
|
4948
|
+
const style = document.createElement("style");
|
|
4949
|
+
style.id = PULSE_KEYFRAME_ID;
|
|
4950
|
+
style.textContent = "@keyframes pid-data-overlay-pulse{0%{opacity:.9}50%{opacity:.3}100%{opacity:.9}}";
|
|
4951
|
+
document.head.appendChild(style);
|
|
4952
|
+
}
|
|
4953
|
+
function renderStatusDot(cx, cy, scale, fill) {
|
|
4954
|
+
ensurePulseKeyframes();
|
|
4955
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4956
|
+
"circle",
|
|
4957
|
+
{
|
|
4958
|
+
className: "pid-data-overlay-status-dot",
|
|
4959
|
+
cx: cx + 35 * scale,
|
|
4960
|
+
cy: cy - 18 * scale,
|
|
4961
|
+
r: 3 * scale,
|
|
4962
|
+
fill,
|
|
4963
|
+
style: { animation: PULSE_ANIMATION }
|
|
4964
|
+
}
|
|
4965
|
+
);
|
|
4966
|
+
}
|
|
4967
|
+
function DataOverlayImpl({
|
|
4937
4968
|
nodeId,
|
|
4938
4969
|
x,
|
|
4939
4970
|
y,
|
|
@@ -4953,6 +4984,24 @@ function DataOverlay({
|
|
|
4953
4984
|
const backgroundColor = display?.backgroundColor;
|
|
4954
4985
|
const offsetX = display?.offsetX ?? 0;
|
|
4955
4986
|
const offsetY = display?.offsetY ?? 0;
|
|
4987
|
+
const sparklinePath = import_react12.default.useMemo(() => {
|
|
4988
|
+
if (!showSparkline || !history || history.length < 2) return "";
|
|
4989
|
+
const width = 70 * scale;
|
|
4990
|
+
const height = 20 * scale;
|
|
4991
|
+
const padding = 5 * scale;
|
|
4992
|
+
const effectiveWidth = width - padding * 2;
|
|
4993
|
+
const effectiveHeight = height - padding * 2;
|
|
4994
|
+
const hasEuRange = scaling?.euLow !== void 0 && scaling?.euHigh !== void 0 && scaling.euHigh !== scaling.euLow;
|
|
4995
|
+
const min = hasEuRange ? scaling.euLow : Math.min(...history);
|
|
4996
|
+
const max = hasEuRange ? scaling.euHigh : Math.max(...history);
|
|
4997
|
+
const range = max - min || 1;
|
|
4998
|
+
const points = history.map((val, i) => {
|
|
4999
|
+
const xPos = i / (history.length - 1) * effectiveWidth + padding;
|
|
5000
|
+
const yPos = height - padding - (val - min) / range * effectiveHeight;
|
|
5001
|
+
return `${xPos.toFixed(2)},${yPos.toFixed(2)}`;
|
|
5002
|
+
});
|
|
5003
|
+
return `M ${points.join(" L ")}`;
|
|
5004
|
+
}, [showSparkline, history, scaling, scale]);
|
|
4956
5005
|
if (!showValue) {
|
|
4957
5006
|
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_jsx_runtime18.Fragment, {});
|
|
4958
5007
|
}
|
|
@@ -4972,24 +5021,6 @@ function DataOverlay({
|
|
|
4972
5021
|
const finalTextColor = textColor || colors.text;
|
|
4973
5022
|
const formattedValue = formatValue(value.value);
|
|
4974
5023
|
const displayText = unit ? `${formattedValue} ${unit}` : formattedValue;
|
|
4975
|
-
const sparklinePath = (() => {
|
|
4976
|
-
if (!showSparkline || !history || history.length < 2) return "";
|
|
4977
|
-
const width = 70 * scale;
|
|
4978
|
-
const height = 20 * scale;
|
|
4979
|
-
const padding = 5 * scale;
|
|
4980
|
-
const effectiveWidth = width - padding * 2;
|
|
4981
|
-
const effectiveHeight = height - padding * 2;
|
|
4982
|
-
const hasEuRange = scaling?.euLow !== void 0 && scaling?.euHigh !== void 0 && scaling.euHigh !== scaling.euLow;
|
|
4983
|
-
const min = hasEuRange ? scaling.euLow : Math.min(...history);
|
|
4984
|
-
const max = hasEuRange ? scaling.euHigh : Math.max(...history);
|
|
4985
|
-
const range = max - min || 1;
|
|
4986
|
-
const points = history.map((val, i) => {
|
|
4987
|
-
const xPos = i / (history.length - 1) * effectiveWidth + padding;
|
|
4988
|
-
const yPos = height - padding - (val - min) / range * effectiveHeight;
|
|
4989
|
-
return `${xPos.toFixed(2)},${yPos.toFixed(2)}`;
|
|
4990
|
-
});
|
|
4991
|
-
return `M ${points.join(" L ")}`;
|
|
4992
|
-
})();
|
|
4993
5024
|
const hasSparkline = showSparkline && sparklinePath;
|
|
4994
5025
|
const overlayHeight = (label ? hasSparkline ? 55 : 30 : hasSparkline ? 47 : 22) * scale;
|
|
4995
5026
|
const overlayWidth = 80 * scale;
|
|
@@ -5037,25 +5068,7 @@ function DataOverlay({
|
|
|
5037
5068
|
children: displayText
|
|
5038
5069
|
}
|
|
5039
5070
|
),
|
|
5040
|
-
showStatus && value.status !== "normal" &&
|
|
5041
|
-
"circle",
|
|
5042
|
-
{
|
|
5043
|
-
cx: displayX + 35 * scale,
|
|
5044
|
-
cy: displayY - 18 * scale,
|
|
5045
|
-
r: 3 * scale,
|
|
5046
|
-
fill: finalTextColor,
|
|
5047
|
-
opacity: "0.9",
|
|
5048
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5049
|
-
"animate",
|
|
5050
|
-
{
|
|
5051
|
-
attributeName: "opacity",
|
|
5052
|
-
values: "0.9;0.3;0.9",
|
|
5053
|
-
dur: "1.5s",
|
|
5054
|
-
repeatCount: "indefinite"
|
|
5055
|
-
}
|
|
5056
|
-
)
|
|
5057
|
-
}
|
|
5058
|
-
),
|
|
5071
|
+
showStatus && value.status !== "normal" && renderStatusDot(displayX, displayY, scale, finalTextColor),
|
|
5059
5072
|
value.quality !== void 0 && value.quality < 100 && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
5060
5073
|
"text",
|
|
5061
5074
|
{
|
|
@@ -5087,9 +5100,10 @@ function DataOverlay({
|
|
|
5087
5100
|
) })
|
|
5088
5101
|
] });
|
|
5089
5102
|
}
|
|
5103
|
+
var DataOverlay = import_react12.default.memo(DataOverlayImpl);
|
|
5090
5104
|
|
|
5091
5105
|
// src/components/PIDCanvas/PositionPanel.tsx
|
|
5092
|
-
var
|
|
5106
|
+
var import_react13 = require("react");
|
|
5093
5107
|
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
5094
5108
|
function PositionPanel({
|
|
5095
5109
|
selectedNode,
|
|
@@ -5098,9 +5112,9 @@ function PositionPanel({
|
|
|
5098
5112
|
onWaypointPositionChange,
|
|
5099
5113
|
position = "top-right"
|
|
5100
5114
|
}) {
|
|
5101
|
-
const [x, setX] = (0,
|
|
5102
|
-
const [y, setY] = (0,
|
|
5103
|
-
(0,
|
|
5115
|
+
const [x, setX] = (0, import_react13.useState)("");
|
|
5116
|
+
const [y, setY] = (0, import_react13.useState)("");
|
|
5117
|
+
(0, import_react13.useEffect)(() => {
|
|
5104
5118
|
if (selectedNode) {
|
|
5105
5119
|
setX(selectedNode.transform.x.toFixed(2));
|
|
5106
5120
|
setY(selectedNode.transform.y.toFixed(2));
|
|
@@ -5226,7 +5240,7 @@ function PositionPanel({
|
|
|
5226
5240
|
}
|
|
5227
5241
|
|
|
5228
5242
|
// src/diagram/hooks/useViewBox.ts
|
|
5229
|
-
var
|
|
5243
|
+
var import_react14 = require("react");
|
|
5230
5244
|
function useViewBox(options) {
|
|
5231
5245
|
const {
|
|
5232
5246
|
initialViewBox,
|
|
@@ -5237,16 +5251,16 @@ function useViewBox(options) {
|
|
|
5237
5251
|
zoomSensitivity = 1e-3,
|
|
5238
5252
|
allowLeftClickPan = true
|
|
5239
5253
|
} = options;
|
|
5240
|
-
const [viewBox, setViewBox] = (0,
|
|
5241
|
-
const svgRef = (0,
|
|
5242
|
-
const isPanningRef = (0,
|
|
5243
|
-
const lastMousePosRef = (0,
|
|
5244
|
-
const spaceKeyDownRef = (0,
|
|
5245
|
-
const lastTouchDistanceRef = (0,
|
|
5246
|
-
const resetViewBox = (0,
|
|
5254
|
+
const [viewBox, setViewBox] = (0, import_react14.useState)(initialViewBox);
|
|
5255
|
+
const svgRef = (0, import_react14.useRef)(null);
|
|
5256
|
+
const isPanningRef = (0, import_react14.useRef)(false);
|
|
5257
|
+
const lastMousePosRef = (0, import_react14.useRef)({ x: 0, y: 0 });
|
|
5258
|
+
const spaceKeyDownRef = (0, import_react14.useRef)(false);
|
|
5259
|
+
const lastTouchDistanceRef = (0, import_react14.useRef)(null);
|
|
5260
|
+
const resetViewBox = (0, import_react14.useCallback)(() => {
|
|
5247
5261
|
setViewBox(initialViewBox);
|
|
5248
5262
|
}, [initialViewBox]);
|
|
5249
|
-
const zoomIn = (0,
|
|
5263
|
+
const zoomIn = (0, import_react14.useCallback)(() => {
|
|
5250
5264
|
setViewBox((prev) => {
|
|
5251
5265
|
const currentZoom = initialViewBox.width / prev.width;
|
|
5252
5266
|
const newZoom = Math.min(1 / minZoom, currentZoom * 1.25);
|
|
@@ -5263,7 +5277,7 @@ function useViewBox(options) {
|
|
|
5263
5277
|
};
|
|
5264
5278
|
});
|
|
5265
5279
|
}, [initialViewBox, minZoom]);
|
|
5266
|
-
const zoomOut = (0,
|
|
5280
|
+
const zoomOut = (0, import_react14.useCallback)(() => {
|
|
5267
5281
|
setViewBox((prev) => {
|
|
5268
5282
|
const currentZoom = initialViewBox.width / prev.width;
|
|
5269
5283
|
const newZoom = Math.max(1 / maxZoom, currentZoom * 0.8);
|
|
@@ -5280,7 +5294,7 @@ function useViewBox(options) {
|
|
|
5280
5294
|
};
|
|
5281
5295
|
});
|
|
5282
5296
|
}, [initialViewBox, maxZoom]);
|
|
5283
|
-
const fitToContent = (0,
|
|
5297
|
+
const fitToContent = (0, import_react14.useCallback)((bounds, padding = 50) => {
|
|
5284
5298
|
const contentWidth = bounds.maxX - bounds.minX;
|
|
5285
5299
|
const contentHeight = bounds.maxY - bounds.minY;
|
|
5286
5300
|
if (contentWidth === 0 || contentHeight === 0) {
|
|
@@ -5308,7 +5322,7 @@ function useViewBox(options) {
|
|
|
5308
5322
|
height: newHeight
|
|
5309
5323
|
});
|
|
5310
5324
|
}, [initialViewBox]);
|
|
5311
|
-
(0,
|
|
5325
|
+
(0, import_react14.useEffect)(() => {
|
|
5312
5326
|
if (!enableZoom || !svgRef.current) return;
|
|
5313
5327
|
const svg = svgRef.current;
|
|
5314
5328
|
const handleWheel = (e) => {
|
|
@@ -5341,7 +5355,7 @@ function useViewBox(options) {
|
|
|
5341
5355
|
svg.addEventListener("wheel", handleWheel, { passive: false });
|
|
5342
5356
|
return () => svg.removeEventListener("wheel", handleWheel);
|
|
5343
5357
|
}, [enableZoom, zoomSensitivity, minZoom, initialViewBox]);
|
|
5344
|
-
(0,
|
|
5358
|
+
(0, import_react14.useEffect)(() => {
|
|
5345
5359
|
if (!enablePan || !svgRef.current) return;
|
|
5346
5360
|
const svg = svgRef.current;
|
|
5347
5361
|
const handleMouseDown = (e) => {
|
|
@@ -5417,7 +5431,7 @@ function useViewBox(options) {
|
|
|
5417
5431
|
window.removeEventListener("keyup", handleKeyUp);
|
|
5418
5432
|
};
|
|
5419
5433
|
}, [enablePan, allowLeftClickPan]);
|
|
5420
|
-
(0,
|
|
5434
|
+
(0, import_react14.useEffect)(() => {
|
|
5421
5435
|
if (!svgRef.current) return;
|
|
5422
5436
|
if (!enablePan && !enableZoom) return;
|
|
5423
5437
|
const svg = svgRef.current;
|
|
@@ -5508,7 +5522,7 @@ function useViewBox(options) {
|
|
|
5508
5522
|
svg.removeEventListener("touchend", handleTouchEnd);
|
|
5509
5523
|
};
|
|
5510
5524
|
}, [enablePan, enableZoom, minZoom, initialViewBox]);
|
|
5511
|
-
const screenToWorld = (0,
|
|
5525
|
+
const screenToWorld = (0, import_react14.useCallback)(
|
|
5512
5526
|
(screenX, screenY) => {
|
|
5513
5527
|
const svg = svgRef.current;
|
|
5514
5528
|
if (!svg) return { x: screenX, y: screenY };
|
|
@@ -5547,15 +5561,15 @@ function useViewBox(options) {
|
|
|
5547
5561
|
}
|
|
5548
5562
|
|
|
5549
5563
|
// src/diagram/hooks/useSelection.ts
|
|
5550
|
-
var
|
|
5564
|
+
var import_react15 = require("react");
|
|
5551
5565
|
function useSelection(options = {}) {
|
|
5552
5566
|
const {
|
|
5553
5567
|
multiSelect = true,
|
|
5554
5568
|
initialSelection = { selectedNodeIds: /* @__PURE__ */ new Set(), selectedPipeIds: /* @__PURE__ */ new Set() },
|
|
5555
5569
|
onSelectionChange
|
|
5556
5570
|
} = options;
|
|
5557
|
-
const [selection, setSelection] = (0,
|
|
5558
|
-
const notifyChange = (0,
|
|
5571
|
+
const [selection, setSelection] = (0, import_react15.useState)(initialSelection);
|
|
5572
|
+
const notifyChange = (0, import_react15.useCallback)(
|
|
5559
5573
|
(newSelection) => {
|
|
5560
5574
|
if (onSelectionChange) {
|
|
5561
5575
|
onSelectionChange(newSelection);
|
|
@@ -5563,15 +5577,15 @@ function useSelection(options = {}) {
|
|
|
5563
5577
|
},
|
|
5564
5578
|
[onSelectionChange]
|
|
5565
5579
|
);
|
|
5566
|
-
const isNodeSelected = (0,
|
|
5580
|
+
const isNodeSelected = (0, import_react15.useCallback)(
|
|
5567
5581
|
(nodeId) => selection.selectedNodeIds.has(nodeId),
|
|
5568
5582
|
[selection.selectedNodeIds]
|
|
5569
5583
|
);
|
|
5570
|
-
const isPipeSelected = (0,
|
|
5584
|
+
const isPipeSelected = (0, import_react15.useCallback)(
|
|
5571
5585
|
(pipeId) => selection.selectedPipeIds.has(pipeId),
|
|
5572
5586
|
[selection.selectedPipeIds]
|
|
5573
5587
|
);
|
|
5574
|
-
const selectNode = (0,
|
|
5588
|
+
const selectNode = (0, import_react15.useCallback)(
|
|
5575
5589
|
(nodeId, isMultiSelect = false) => {
|
|
5576
5590
|
setSelection((prev) => {
|
|
5577
5591
|
const newNodeIds = new Set(isMultiSelect && multiSelect ? prev.selectedNodeIds : []);
|
|
@@ -5590,7 +5604,7 @@ function useSelection(options = {}) {
|
|
|
5590
5604
|
},
|
|
5591
5605
|
[multiSelect, notifyChange]
|
|
5592
5606
|
);
|
|
5593
|
-
const selectPipe = (0,
|
|
5607
|
+
const selectPipe = (0, import_react15.useCallback)(
|
|
5594
5608
|
(pipeId, isMultiSelect = false) => {
|
|
5595
5609
|
setSelection((prev) => {
|
|
5596
5610
|
const newPipeIds = new Set(isMultiSelect && multiSelect ? prev.selectedPipeIds : []);
|
|
@@ -5609,7 +5623,7 @@ function useSelection(options = {}) {
|
|
|
5609
5623
|
},
|
|
5610
5624
|
[multiSelect, notifyChange]
|
|
5611
5625
|
);
|
|
5612
|
-
const clearSelection = (0,
|
|
5626
|
+
const clearSelection = (0, import_react15.useCallback)(() => {
|
|
5613
5627
|
const newSelection = {
|
|
5614
5628
|
selectedNodeIds: /* @__PURE__ */ new Set(),
|
|
5615
5629
|
selectedPipeIds: /* @__PURE__ */ new Set()
|
|
@@ -5617,7 +5631,7 @@ function useSelection(options = {}) {
|
|
|
5617
5631
|
setSelection(newSelection);
|
|
5618
5632
|
notifyChange(newSelection);
|
|
5619
5633
|
}, [notifyChange]);
|
|
5620
|
-
const selectNodes = (0,
|
|
5634
|
+
const selectNodes = (0, import_react15.useCallback)(
|
|
5621
5635
|
(nodeIds) => {
|
|
5622
5636
|
const newSelection = {
|
|
5623
5637
|
selectedNodeIds: new Set(nodeIds),
|
|
@@ -5628,7 +5642,7 @@ function useSelection(options = {}) {
|
|
|
5628
5642
|
},
|
|
5629
5643
|
[notifyChange]
|
|
5630
5644
|
);
|
|
5631
|
-
const selectPipes = (0,
|
|
5645
|
+
const selectPipes = (0, import_react15.useCallback)(
|
|
5632
5646
|
(pipeIds) => {
|
|
5633
5647
|
const newSelection = {
|
|
5634
5648
|
selectedNodeIds: /* @__PURE__ */ new Set(),
|
|
@@ -5652,23 +5666,23 @@ function useSelection(options = {}) {
|
|
|
5652
5666
|
}
|
|
5653
5667
|
|
|
5654
5668
|
// src/diagram/hooks/useTelemetry.ts
|
|
5655
|
-
var
|
|
5669
|
+
var import_react16 = require("react");
|
|
5656
5670
|
function useTelemetry(options = {}) {
|
|
5657
5671
|
const {
|
|
5658
5672
|
initialBindings = [],
|
|
5659
5673
|
onTelemetryChange,
|
|
5660
5674
|
refreshInterval = 0
|
|
5661
5675
|
} = options;
|
|
5662
|
-
const [telemetry, setTelemetry] = (0,
|
|
5676
|
+
const [telemetry, setTelemetry] = (0, import_react16.useState)(() => {
|
|
5663
5677
|
const map = /* @__PURE__ */ new Map();
|
|
5664
5678
|
initialBindings.forEach((binding) => {
|
|
5665
5679
|
map.set(binding.nodeId, binding);
|
|
5666
5680
|
});
|
|
5667
5681
|
return map;
|
|
5668
5682
|
});
|
|
5669
|
-
const telemetryRef = (0,
|
|
5683
|
+
const telemetryRef = (0, import_react16.useRef)(telemetry);
|
|
5670
5684
|
telemetryRef.current = telemetry;
|
|
5671
|
-
const notifyChange = (0,
|
|
5685
|
+
const notifyChange = (0, import_react16.useCallback)(
|
|
5672
5686
|
(newTelemetry) => {
|
|
5673
5687
|
if (onTelemetryChange) {
|
|
5674
5688
|
onTelemetryChange(newTelemetry);
|
|
@@ -5676,7 +5690,7 @@ function useTelemetry(options = {}) {
|
|
|
5676
5690
|
},
|
|
5677
5691
|
[onTelemetryChange]
|
|
5678
5692
|
);
|
|
5679
|
-
const updateTelemetry = (0,
|
|
5693
|
+
const updateTelemetry = (0, import_react16.useCallback)(
|
|
5680
5694
|
(nodeId, value) => {
|
|
5681
5695
|
setTelemetry((prev) => {
|
|
5682
5696
|
const newMap = new Map(prev);
|
|
@@ -5706,7 +5720,7 @@ function useTelemetry(options = {}) {
|
|
|
5706
5720
|
},
|
|
5707
5721
|
[notifyChange]
|
|
5708
5722
|
);
|
|
5709
|
-
const updateTelemetryBatch = (0,
|
|
5723
|
+
const updateTelemetryBatch = (0, import_react16.useCallback)(
|
|
5710
5724
|
(updates) => {
|
|
5711
5725
|
setTelemetry((prev) => {
|
|
5712
5726
|
const newMap = new Map(prev);
|
|
@@ -5760,16 +5774,16 @@ function useTelemetry(options = {}) {
|
|
|
5760
5774
|
},
|
|
5761
5775
|
[notifyChange]
|
|
5762
5776
|
);
|
|
5763
|
-
const getTelemetry = (0,
|
|
5777
|
+
const getTelemetry = (0, import_react16.useCallback)(
|
|
5764
5778
|
(nodeId) => telemetryRef.current.get(nodeId),
|
|
5765
5779
|
[]
|
|
5766
5780
|
);
|
|
5767
|
-
const clearTelemetry = (0,
|
|
5781
|
+
const clearTelemetry = (0, import_react16.useCallback)(() => {
|
|
5768
5782
|
const newMap = /* @__PURE__ */ new Map();
|
|
5769
5783
|
setTelemetry(newMap);
|
|
5770
5784
|
notifyChange(newMap);
|
|
5771
5785
|
}, [notifyChange]);
|
|
5772
|
-
const setBindings = (0,
|
|
5786
|
+
const setBindings = (0, import_react16.useCallback)(
|
|
5773
5787
|
(bindings) => {
|
|
5774
5788
|
const newMap = /* @__PURE__ */ new Map();
|
|
5775
5789
|
bindings.forEach((binding) => {
|
|
@@ -5780,7 +5794,7 @@ function useTelemetry(options = {}) {
|
|
|
5780
5794
|
},
|
|
5781
5795
|
[notifyChange]
|
|
5782
5796
|
);
|
|
5783
|
-
(0,
|
|
5797
|
+
(0, import_react16.useEffect)(() => {
|
|
5784
5798
|
if (refreshInterval <= 0) return;
|
|
5785
5799
|
const intervalId = setInterval(() => {
|
|
5786
5800
|
notifyChange(telemetryRef.current);
|
|
@@ -5798,10 +5812,10 @@ function useTelemetry(options = {}) {
|
|
|
5798
5812
|
}
|
|
5799
5813
|
|
|
5800
5814
|
// src/diagram/hooks/useTelemetryStatus.ts
|
|
5801
|
-
var
|
|
5815
|
+
var import_react17 = require("react");
|
|
5802
5816
|
function useTelemetryStatus(telemetry, diagram, setDiagram, options = {}) {
|
|
5803
5817
|
const { enabled = true, mapStatus } = options;
|
|
5804
|
-
(0,
|
|
5818
|
+
(0, import_react17.useEffect)(() => {
|
|
5805
5819
|
if (!enabled) return;
|
|
5806
5820
|
const defaultMapStatus = (telemetryStatus) => {
|
|
5807
5821
|
switch (telemetryStatus) {
|
|
@@ -5840,7 +5854,7 @@ function useTelemetryStatus(telemetry, diagram, setDiagram, options = {}) {
|
|
|
5840
5854
|
}
|
|
5841
5855
|
|
|
5842
5856
|
// src/diagram/hooks/useDrag.ts
|
|
5843
|
-
var
|
|
5857
|
+
var import_react18 = require("react");
|
|
5844
5858
|
function useDrag(options = {}) {
|
|
5845
5859
|
const {
|
|
5846
5860
|
onDragStart,
|
|
@@ -5850,23 +5864,23 @@ function useDrag(options = {}) {
|
|
|
5850
5864
|
dragThreshold = 3,
|
|
5851
5865
|
screenToWorld = (x, y) => ({ x, y })
|
|
5852
5866
|
} = options;
|
|
5853
|
-
const [dragState, setDragState] = (0,
|
|
5867
|
+
const [dragState, setDragState] = (0, import_react18.useState)({
|
|
5854
5868
|
isDragging: false,
|
|
5855
5869
|
startPosition: null,
|
|
5856
5870
|
offset: { x: 0, y: 0 },
|
|
5857
5871
|
draggedId: null
|
|
5858
5872
|
});
|
|
5859
|
-
const [isListening, setIsListening] = (0,
|
|
5860
|
-
const dragStartRef = (0,
|
|
5861
|
-
const hasMovedRef = (0,
|
|
5862
|
-
const applySnap = (0,
|
|
5873
|
+
const [isListening, setIsListening] = (0, import_react18.useState)(false);
|
|
5874
|
+
const dragStartRef = (0, import_react18.useRef)(null);
|
|
5875
|
+
const hasMovedRef = (0, import_react18.useRef)(false);
|
|
5876
|
+
const applySnap = (0, import_react18.useCallback)(
|
|
5863
5877
|
(value) => {
|
|
5864
5878
|
if (snapToGrid <= 0) return value;
|
|
5865
5879
|
return Math.round(value / snapToGrid) * snapToGrid;
|
|
5866
5880
|
},
|
|
5867
5881
|
[snapToGrid]
|
|
5868
5882
|
);
|
|
5869
|
-
const handleMouseMove = (0,
|
|
5883
|
+
const handleMouseMove = (0, import_react18.useCallback)(
|
|
5870
5884
|
(event) => {
|
|
5871
5885
|
if (!dragStartRef.current) return;
|
|
5872
5886
|
const { id, screenStart: _screenStart, itemPosition, clickOffset } = dragStartRef.current;
|
|
@@ -5907,7 +5921,7 @@ function useDrag(options = {}) {
|
|
|
5907
5921
|
},
|
|
5908
5922
|
[screenToWorld, dragThreshold, applySnap, onDragStart, onDragMove]
|
|
5909
5923
|
);
|
|
5910
|
-
const handleMouseUp = (0,
|
|
5924
|
+
const handleMouseUp = (0, import_react18.useCallback)(
|
|
5911
5925
|
(event) => {
|
|
5912
5926
|
if (!dragStartRef.current || !hasMovedRef.current) {
|
|
5913
5927
|
dragStartRef.current = null;
|
|
@@ -5944,7 +5958,7 @@ function useDrag(options = {}) {
|
|
|
5944
5958
|
},
|
|
5945
5959
|
[screenToWorld, applySnap, onDragEnd]
|
|
5946
5960
|
);
|
|
5947
|
-
const handleTouchMove = (0,
|
|
5961
|
+
const handleTouchMove = (0, import_react18.useCallback)(
|
|
5948
5962
|
(event) => {
|
|
5949
5963
|
if (!dragStartRef.current || event.touches.length !== 1) return;
|
|
5950
5964
|
const touch = event.touches[0];
|
|
@@ -5987,7 +6001,7 @@ function useDrag(options = {}) {
|
|
|
5987
6001
|
},
|
|
5988
6002
|
[screenToWorld, dragThreshold, applySnap, onDragStart, onDragMove]
|
|
5989
6003
|
);
|
|
5990
|
-
const handleTouchEnd = (0,
|
|
6004
|
+
const handleTouchEnd = (0, import_react18.useCallback)(
|
|
5991
6005
|
(event) => {
|
|
5992
6006
|
if (!dragStartRef.current || !hasMovedRef.current) {
|
|
5993
6007
|
dragStartRef.current = null;
|
|
@@ -6025,7 +6039,7 @@ function useDrag(options = {}) {
|
|
|
6025
6039
|
},
|
|
6026
6040
|
[screenToWorld, applySnap, onDragEnd]
|
|
6027
6041
|
);
|
|
6028
|
-
(0,
|
|
6042
|
+
(0, import_react18.useEffect)(() => {
|
|
6029
6043
|
if (!isListening) return;
|
|
6030
6044
|
document.addEventListener("mousemove", handleMouseMove);
|
|
6031
6045
|
document.addEventListener("mouseup", handleMouseUp);
|
|
@@ -6040,7 +6054,7 @@ function useDrag(options = {}) {
|
|
|
6040
6054
|
document.removeEventListener("touchcancel", handleTouchEnd);
|
|
6041
6055
|
};
|
|
6042
6056
|
}, [isListening, handleMouseMove, handleMouseUp, handleTouchMove, handleTouchEnd]);
|
|
6043
|
-
const startDrag = (0,
|
|
6057
|
+
const startDrag = (0, import_react18.useCallback)(
|
|
6044
6058
|
(id, event, itemPosition) => {
|
|
6045
6059
|
event.stopPropagation();
|
|
6046
6060
|
let clientX;
|
|
@@ -6070,7 +6084,7 @@ function useDrag(options = {}) {
|
|
|
6070
6084
|
},
|
|
6071
6085
|
[screenToWorld]
|
|
6072
6086
|
);
|
|
6073
|
-
const cancelDrag = (0,
|
|
6087
|
+
const cancelDrag = (0, import_react18.useCallback)(() => {
|
|
6074
6088
|
dragStartRef.current = null;
|
|
6075
6089
|
hasMovedRef.current = false;
|
|
6076
6090
|
setIsListening(false);
|
|
@@ -6081,7 +6095,7 @@ function useDrag(options = {}) {
|
|
|
6081
6095
|
draggedId: null
|
|
6082
6096
|
});
|
|
6083
6097
|
}, []);
|
|
6084
|
-
const isDraggingItem = (0,
|
|
6098
|
+
const isDraggingItem = (0, import_react18.useCallback)(
|
|
6085
6099
|
(id) => dragState.isDragging && dragState.draggedId === id,
|
|
6086
6100
|
[dragState.isDragging, dragState.draggedId]
|
|
6087
6101
|
);
|
|
@@ -6094,7 +6108,7 @@ function useDrag(options = {}) {
|
|
|
6094
6108
|
}
|
|
6095
6109
|
|
|
6096
6110
|
// src/diagram/hooks/useKeyboardShortcuts.ts
|
|
6097
|
-
var
|
|
6111
|
+
var import_react19 = require("react");
|
|
6098
6112
|
function useKeyboardShortcuts(options) {
|
|
6099
6113
|
const {
|
|
6100
6114
|
onDelete,
|
|
@@ -6105,7 +6119,7 @@ function useKeyboardShortcuts(options) {
|
|
|
6105
6119
|
onSelectAll,
|
|
6106
6120
|
enabled = true
|
|
6107
6121
|
} = options;
|
|
6108
|
-
(0,
|
|
6122
|
+
(0, import_react19.useEffect)(() => {
|
|
6109
6123
|
if (!enabled) return;
|
|
6110
6124
|
const handleKeyDown = (event) => {
|
|
6111
6125
|
const target = event.target;
|
|
@@ -6215,18 +6229,19 @@ function nodeHasPort(node, portId) {
|
|
|
6215
6229
|
|
|
6216
6230
|
// src/components/PIDCanvas/PIDCanvas.tsx
|
|
6217
6231
|
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
6218
|
-
|
|
6232
|
+
var DEFAULT_FEATURES = {
|
|
6233
|
+
pan: true,
|
|
6234
|
+
zoom: true,
|
|
6235
|
+
selection: false,
|
|
6236
|
+
multiSelect: true,
|
|
6237
|
+
telemetry: false,
|
|
6238
|
+
dragNodes: false
|
|
6239
|
+
};
|
|
6240
|
+
function PIDCanvasImpl({
|
|
6219
6241
|
diagram,
|
|
6220
6242
|
className = "",
|
|
6221
6243
|
style,
|
|
6222
|
-
features =
|
|
6223
|
-
pan: true,
|
|
6224
|
-
zoom: true,
|
|
6225
|
-
selection: false,
|
|
6226
|
-
multiSelect: true,
|
|
6227
|
-
telemetry: false,
|
|
6228
|
-
dragNodes: false
|
|
6229
|
-
},
|
|
6244
|
+
features = DEFAULT_FEATURES,
|
|
6230
6245
|
onSelectionChange,
|
|
6231
6246
|
onNodeClick,
|
|
6232
6247
|
onPipeClick,
|
|
@@ -6242,21 +6257,21 @@ function PIDCanvas({
|
|
|
6242
6257
|
statusColorMap,
|
|
6243
6258
|
...props
|
|
6244
6259
|
}) {
|
|
6245
|
-
const [localDiagram, setLocalDiagram] = (0,
|
|
6246
|
-
const [dragOverPosition, setDragOverPosition] = (0,
|
|
6247
|
-
const [isConnecting, setIsConnecting] = (0,
|
|
6248
|
-
const [connectionSource, setConnectionSource] = (0,
|
|
6249
|
-
const [connectionSourcePort, setConnectionSourcePort] = (0,
|
|
6250
|
-
const [connectionCursor, setConnectionCursor] = (0,
|
|
6251
|
-
const [hoveredNode, setHoveredNode] = (0,
|
|
6252
|
-
const [hoveredPort, setHoveredPort] = (0,
|
|
6253
|
-
const [selectedWaypoint, setSelectedWaypoint] = (0,
|
|
6254
|
-
const historyStack = (0,
|
|
6255
|
-
const redoStack = (0,
|
|
6256
|
-
const isUndoRedoAction = (0,
|
|
6257
|
-
const isInternalChange = (0,
|
|
6258
|
-
const lastInternalDiagram = (0,
|
|
6259
|
-
(0,
|
|
6260
|
+
const [localDiagram, setLocalDiagram] = (0, import_react20.useState)(diagram);
|
|
6261
|
+
const [dragOverPosition, setDragOverPosition] = (0, import_react20.useState)(null);
|
|
6262
|
+
const [isConnecting, setIsConnecting] = (0, import_react20.useState)(false);
|
|
6263
|
+
const [connectionSource, setConnectionSource] = (0, import_react20.useState)(null);
|
|
6264
|
+
const [connectionSourcePort, setConnectionSourcePort] = (0, import_react20.useState)(null);
|
|
6265
|
+
const [connectionCursor, setConnectionCursor] = (0, import_react20.useState)(null);
|
|
6266
|
+
const [hoveredNode, setHoveredNode] = (0, import_react20.useState)(null);
|
|
6267
|
+
const [hoveredPort, setHoveredPort] = (0, import_react20.useState)(null);
|
|
6268
|
+
const [selectedWaypoint, setSelectedWaypoint] = (0, import_react20.useState)(null);
|
|
6269
|
+
const historyStack = (0, import_react20.useRef)([]);
|
|
6270
|
+
const redoStack = (0, import_react20.useRef)([]);
|
|
6271
|
+
const isUndoRedoAction = (0, import_react20.useRef)(false);
|
|
6272
|
+
const isInternalChange = (0, import_react20.useRef)(false);
|
|
6273
|
+
const lastInternalDiagram = (0, import_react20.useRef)(null);
|
|
6274
|
+
(0, import_react20.useEffect)(() => {
|
|
6260
6275
|
const isExternal = !isInternalChange.current && diagram !== lastInternalDiagram.current;
|
|
6261
6276
|
if (isExternal) {
|
|
6262
6277
|
setLocalDiagram(diagram);
|
|
@@ -6278,7 +6293,7 @@ function PIDCanvas({
|
|
|
6278
6293
|
enablePan: features.pan ?? true,
|
|
6279
6294
|
enableZoom: features.zoom ?? true
|
|
6280
6295
|
});
|
|
6281
|
-
const calculateContentBounds = (0,
|
|
6296
|
+
const calculateContentBounds = (0, import_react20.useCallback)(() => {
|
|
6282
6297
|
const nodes2 = localDiagram.nodes.filter((n) => n.visible !== false);
|
|
6283
6298
|
if (nodes2.length === 0) {
|
|
6284
6299
|
return null;
|
|
@@ -6301,7 +6316,7 @@ function PIDCanvas({
|
|
|
6301
6316
|
});
|
|
6302
6317
|
return { minX, minY, maxX, maxY };
|
|
6303
6318
|
}, [localDiagram.nodes]);
|
|
6304
|
-
(0,
|
|
6319
|
+
(0, import_react20.useEffect)(() => {
|
|
6305
6320
|
if (onMounted) {
|
|
6306
6321
|
const controls = {
|
|
6307
6322
|
fitToContent: (padding = 50) => {
|
|
@@ -6342,8 +6357,8 @@ function PIDCanvas({
|
|
|
6342
6357
|
});
|
|
6343
6358
|
const dragEnabled = features.dragNodes ?? false;
|
|
6344
6359
|
const selectionEnabled = features.selection ?? false;
|
|
6345
|
-
const containerRef = (0,
|
|
6346
|
-
const pushToHistory = (0,
|
|
6360
|
+
const containerRef = (0, import_react20.useRef)(null);
|
|
6361
|
+
const pushToHistory = (0, import_react20.useCallback)((currentDiagram) => {
|
|
6347
6362
|
if (isUndoRedoAction.current) return;
|
|
6348
6363
|
const snapshot = JSON.parse(JSON.stringify(currentDiagram));
|
|
6349
6364
|
historyStack.current.push(snapshot);
|
|
@@ -6352,7 +6367,7 @@ function PIDCanvas({
|
|
|
6352
6367
|
}
|
|
6353
6368
|
redoStack.current = [];
|
|
6354
6369
|
}, []);
|
|
6355
|
-
const undo = (0,
|
|
6370
|
+
const undo = (0, import_react20.useCallback)(() => {
|
|
6356
6371
|
if (historyStack.current.length === 0) return;
|
|
6357
6372
|
isUndoRedoAction.current = true;
|
|
6358
6373
|
const currentSnapshot = JSON.parse(JSON.stringify(localDiagram));
|
|
@@ -6366,7 +6381,7 @@ function PIDCanvas({
|
|
|
6366
6381
|
isUndoRedoAction.current = false;
|
|
6367
6382
|
}, 0);
|
|
6368
6383
|
}, [localDiagram, onDiagramChange]);
|
|
6369
|
-
const redo = (0,
|
|
6384
|
+
const redo = (0, import_react20.useCallback)(() => {
|
|
6370
6385
|
if (redoStack.current.length === 0) return;
|
|
6371
6386
|
isUndoRedoAction.current = true;
|
|
6372
6387
|
const currentSnapshot = JSON.parse(JSON.stringify(localDiagram));
|
|
@@ -6380,7 +6395,7 @@ function PIDCanvas({
|
|
|
6380
6395
|
isUndoRedoAction.current = false;
|
|
6381
6396
|
}, 0);
|
|
6382
6397
|
}, [localDiagram, onDiagramChange]);
|
|
6383
|
-
(0,
|
|
6398
|
+
(0, import_react20.useEffect)(() => {
|
|
6384
6399
|
const handleKeyDown = (e) => {
|
|
6385
6400
|
const isCtrlOrCmd = e.ctrlKey || e.metaKey;
|
|
6386
6401
|
if (isCtrlOrCmd && e.key === "z" && !e.shiftKey) {
|
|
@@ -6397,7 +6412,7 @@ function PIDCanvas({
|
|
|
6397
6412
|
window.addEventListener("keydown", handleKeyDown);
|
|
6398
6413
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
6399
6414
|
}, [undo, redo]);
|
|
6400
|
-
(0,
|
|
6415
|
+
(0, import_react20.useEffect)(() => {
|
|
6401
6416
|
if (!features.dragNodes) return;
|
|
6402
6417
|
const handleKeyDown = (e) => {
|
|
6403
6418
|
if (selection.selectedNodeIds.size === 0 && !selectedWaypoint) return;
|
|
@@ -6482,7 +6497,7 @@ function PIDCanvas({
|
|
|
6482
6497
|
onNodeMove,
|
|
6483
6498
|
pushToHistory
|
|
6484
6499
|
]);
|
|
6485
|
-
const handlePositionChange = (0,
|
|
6500
|
+
const handlePositionChange = (0, import_react20.useCallback)(
|
|
6486
6501
|
(nodeId, x, y) => {
|
|
6487
6502
|
pushToHistory(localDiagram);
|
|
6488
6503
|
const updatedNodes = localDiagram.nodes.map(
|
|
@@ -6504,7 +6519,7 @@ function PIDCanvas({
|
|
|
6504
6519
|
},
|
|
6505
6520
|
[localDiagram, onDiagramChange, onNodeMove, pushToHistory]
|
|
6506
6521
|
);
|
|
6507
|
-
const handleWaypointPositionChange = (0,
|
|
6522
|
+
const handleWaypointPositionChange = (0, import_react20.useCallback)(
|
|
6508
6523
|
(pipeId, pointIndex, x, y) => {
|
|
6509
6524
|
pushToHistory(localDiagram);
|
|
6510
6525
|
const updatedPipes = localDiagram.pipes.map((pipe) => {
|
|
@@ -6522,7 +6537,7 @@ function PIDCanvas({
|
|
|
6522
6537
|
},
|
|
6523
6538
|
[localDiagram, onDiagramChange, pushToHistory]
|
|
6524
6539
|
);
|
|
6525
|
-
const handleDragEnd = (0,
|
|
6540
|
+
const handleDragEnd = (0, import_react20.useCallback)(
|
|
6526
6541
|
(nodeId, offset, finalPosition) => {
|
|
6527
6542
|
const dragDistance = Math.sqrt(offset.x ** 2 + offset.y ** 2);
|
|
6528
6543
|
if (dragDistance < 2) {
|
|
@@ -6603,7 +6618,7 @@ function PIDCanvas({
|
|
|
6603
6618
|
onDiagramChange?.(updatedDiagram);
|
|
6604
6619
|
}
|
|
6605
6620
|
});
|
|
6606
|
-
const handleNodeDragStart = (0,
|
|
6621
|
+
const handleNodeDragStart = (0, import_react20.useCallback)(
|
|
6607
6622
|
(nodeId, event) => {
|
|
6608
6623
|
const node = localDiagram.nodes.find((n) => n.id === nodeId);
|
|
6609
6624
|
if (!node) return;
|
|
@@ -6611,7 +6626,7 @@ function PIDCanvas({
|
|
|
6611
6626
|
},
|
|
6612
6627
|
[localDiagram.nodes, startDrag]
|
|
6613
6628
|
);
|
|
6614
|
-
const handleWaypointClick = (0,
|
|
6629
|
+
const handleWaypointClick = (0, import_react20.useCallback)(
|
|
6615
6630
|
(pipeId, pointIndex) => {
|
|
6616
6631
|
setSelectedWaypoint({ pipeId, pointIndex });
|
|
6617
6632
|
if (selectionEnabled) {
|
|
@@ -6620,7 +6635,7 @@ function PIDCanvas({
|
|
|
6620
6635
|
},
|
|
6621
6636
|
[selectionEnabled, clearSelection]
|
|
6622
6637
|
);
|
|
6623
|
-
const handleWaypointDragStart = (0,
|
|
6638
|
+
const handleWaypointDragStart = (0, import_react20.useCallback)(
|
|
6624
6639
|
(pipeId, pointIndex, event) => {
|
|
6625
6640
|
const pipe = localDiagram.pipes.find((p) => p.id === pipeId);
|
|
6626
6641
|
if (!pipe || pointIndex >= pipe.routePoints.length) return;
|
|
@@ -6629,7 +6644,7 @@ function PIDCanvas({
|
|
|
6629
6644
|
},
|
|
6630
6645
|
[localDiagram.pipes, startWaypointDrag]
|
|
6631
6646
|
);
|
|
6632
|
-
const handlePipeSegmentClick = (0,
|
|
6647
|
+
const handlePipeSegmentClick = (0, import_react20.useCallback)(
|
|
6633
6648
|
(pipeId, position, segmentIndex) => {
|
|
6634
6649
|
pushToHistory(localDiagram);
|
|
6635
6650
|
const updatedPipes = localDiagram.pipes.map((pipe) => {
|
|
@@ -6648,7 +6663,7 @@ function PIDCanvas({
|
|
|
6648
6663
|
[localDiagram, onDiagramChange, pushToHistory]
|
|
6649
6664
|
);
|
|
6650
6665
|
const telemetryEnabled = features.telemetry ?? false;
|
|
6651
|
-
const handleDelete = (0,
|
|
6666
|
+
const handleDelete = (0, import_react20.useCallback)(() => {
|
|
6652
6667
|
if (!selectionEnabled) return;
|
|
6653
6668
|
const { selectedNodeIds, selectedPipeIds } = selection;
|
|
6654
6669
|
if (selectedNodeIds.size === 0 && selectedPipeIds.size === 0) return;
|
|
@@ -6677,62 +6692,81 @@ function PIDCanvas({
|
|
|
6677
6692
|
onDelete,
|
|
6678
6693
|
pushToHistory
|
|
6679
6694
|
]);
|
|
6680
|
-
const handleCopy = (0,
|
|
6695
|
+
const handleCopy = (0, import_react20.useCallback)(() => {
|
|
6681
6696
|
if (!selectionEnabled) return;
|
|
6682
6697
|
const { selectedNodeIds, selectedPipeIds } = selection;
|
|
6683
6698
|
if (selectedNodeIds.size === 0 && selectedPipeIds.size === 0) return;
|
|
6684
6699
|
onItemsCopied?.(Array.from(selectedNodeIds), Array.from(selectedPipeIds));
|
|
6685
6700
|
}, [selection, selectionEnabled, onItemsCopied]);
|
|
6686
|
-
const handlePaste = (0,
|
|
6701
|
+
const handlePaste = (0, import_react20.useCallback)(() => {
|
|
6687
6702
|
if (!selectionEnabled) return;
|
|
6688
6703
|
onPaste?.();
|
|
6689
6704
|
}, [selectionEnabled, onPaste]);
|
|
6690
|
-
const handleNodeDoubleClick = (
|
|
6691
|
-
|
|
6692
|
-
|
|
6693
|
-
|
|
6694
|
-
|
|
6705
|
+
const handleNodeDoubleClick = (0, import_react20.useCallback)(
|
|
6706
|
+
(nodeId, event) => {
|
|
6707
|
+
if (!selectionEnabled) return;
|
|
6708
|
+
console.log("Node double-clicked:", nodeId);
|
|
6709
|
+
selectNode(nodeId, event.ctrlKey || event.metaKey);
|
|
6710
|
+
},
|
|
6711
|
+
[selectionEnabled, selectNode]
|
|
6712
|
+
);
|
|
6695
6713
|
useKeyboardShortcuts({
|
|
6696
6714
|
enabled: features.keyboardShortcuts ?? false,
|
|
6697
6715
|
onDelete: handleDelete,
|
|
6698
6716
|
onCopy: handleCopy,
|
|
6699
6717
|
onPaste: handlePaste
|
|
6700
6718
|
});
|
|
6701
|
-
const handleNodeClick = (
|
|
6702
|
-
|
|
6703
|
-
|
|
6704
|
-
if (
|
|
6705
|
-
|
|
6706
|
-
|
|
6707
|
-
|
|
6708
|
-
|
|
6709
|
-
|
|
6710
|
-
|
|
6711
|
-
|
|
6712
|
-
|
|
6713
|
-
|
|
6714
|
-
|
|
6715
|
-
|
|
6719
|
+
const handleNodeClick = (0, import_react20.useCallback)(
|
|
6720
|
+
(nodeId, event) => {
|
|
6721
|
+
const connectionModeEnabled = features.connectionMode ?? false;
|
|
6722
|
+
if (connectionModeEnabled && isConnecting) {
|
|
6723
|
+
if (connectionSource && connectionSource !== nodeId) {
|
|
6724
|
+
onPipeCreated?.(
|
|
6725
|
+
connectionSource,
|
|
6726
|
+
nodeId,
|
|
6727
|
+
connectionSourcePort || void 0,
|
|
6728
|
+
hoveredPort || void 0
|
|
6729
|
+
);
|
|
6730
|
+
setIsConnecting(false);
|
|
6731
|
+
setConnectionSource(null);
|
|
6732
|
+
setConnectionSourcePort(null);
|
|
6733
|
+
setConnectionCursor(null);
|
|
6734
|
+
setHoveredPort(null);
|
|
6735
|
+
}
|
|
6736
|
+
return;
|
|
6716
6737
|
}
|
|
6717
|
-
|
|
6718
|
-
|
|
6719
|
-
|
|
6720
|
-
|
|
6721
|
-
|
|
6722
|
-
|
|
6723
|
-
|
|
6724
|
-
|
|
6725
|
-
|
|
6726
|
-
|
|
6727
|
-
}
|
|
6728
|
-
|
|
6729
|
-
|
|
6730
|
-
|
|
6731
|
-
|
|
6732
|
-
|
|
6733
|
-
|
|
6734
|
-
|
|
6735
|
-
|
|
6738
|
+
if (connectionModeEnabled && !isConnecting) {
|
|
6739
|
+
setIsConnecting(true);
|
|
6740
|
+
setConnectionSource(nodeId);
|
|
6741
|
+
setConnectionSourcePort(hoveredPort);
|
|
6742
|
+
return;
|
|
6743
|
+
}
|
|
6744
|
+
if (selectionEnabled) {
|
|
6745
|
+
selectNode(nodeId, event.ctrlKey || event.metaKey);
|
|
6746
|
+
}
|
|
6747
|
+
onNodeClick?.(nodeId);
|
|
6748
|
+
},
|
|
6749
|
+
[
|
|
6750
|
+
features.connectionMode,
|
|
6751
|
+
isConnecting,
|
|
6752
|
+
connectionSource,
|
|
6753
|
+
connectionSourcePort,
|
|
6754
|
+
hoveredPort,
|
|
6755
|
+
onPipeCreated,
|
|
6756
|
+
selectionEnabled,
|
|
6757
|
+
selectNode,
|
|
6758
|
+
onNodeClick
|
|
6759
|
+
]
|
|
6760
|
+
);
|
|
6761
|
+
const handlePipeClick = (0, import_react20.useCallback)(
|
|
6762
|
+
(pipeId, event) => {
|
|
6763
|
+
if (selectionEnabled) {
|
|
6764
|
+
selectPipe(pipeId, event.ctrlKey || event.metaKey);
|
|
6765
|
+
}
|
|
6766
|
+
onPipeClick?.(pipeId);
|
|
6767
|
+
},
|
|
6768
|
+
[selectionEnabled, selectPipe, onPipeClick]
|
|
6769
|
+
);
|
|
6736
6770
|
const handleCanvasClick = (e) => {
|
|
6737
6771
|
const target = e.target;
|
|
6738
6772
|
if (target.closest(".pipe-route-point")) {
|
|
@@ -6743,7 +6777,7 @@ function PIDCanvas({
|
|
|
6743
6777
|
}
|
|
6744
6778
|
setSelectedWaypoint(null);
|
|
6745
6779
|
};
|
|
6746
|
-
const handleDragOver = (0,
|
|
6780
|
+
const handleDragOver = (0, import_react20.useCallback)(
|
|
6747
6781
|
(event) => {
|
|
6748
6782
|
if (!features.allowSymbolDrop) return;
|
|
6749
6783
|
event.preventDefault();
|
|
@@ -6754,7 +6788,7 @@ function PIDCanvas({
|
|
|
6754
6788
|
},
|
|
6755
6789
|
[features.allowSymbolDrop, screenToWorld, svgRef]
|
|
6756
6790
|
);
|
|
6757
|
-
const handleDrop = (0,
|
|
6791
|
+
const handleDrop = (0, import_react20.useCallback)(
|
|
6758
6792
|
(event) => {
|
|
6759
6793
|
if (!features.allowSymbolDrop) return;
|
|
6760
6794
|
event.preventDefault();
|
|
@@ -6767,10 +6801,10 @@ function PIDCanvas({
|
|
|
6767
6801
|
},
|
|
6768
6802
|
[features.allowSymbolDrop, screenToWorld, onSymbolDrop, svgRef]
|
|
6769
6803
|
);
|
|
6770
|
-
const handleDragLeave = (0,
|
|
6804
|
+
const handleDragLeave = (0, import_react20.useCallback)(() => {
|
|
6771
6805
|
setDragOverPosition(null);
|
|
6772
6806
|
}, []);
|
|
6773
|
-
const handleMouseMove = (0,
|
|
6807
|
+
const handleMouseMove = (0, import_react20.useCallback)(
|
|
6774
6808
|
(event) => {
|
|
6775
6809
|
const connectionModeEnabled = features.connectionMode ?? false;
|
|
6776
6810
|
if (connectionModeEnabled) {
|
|
@@ -7080,9 +7114,10 @@ function PIDCanvas({
|
|
|
7080
7114
|
}
|
|
7081
7115
|
);
|
|
7082
7116
|
}
|
|
7117
|
+
var PIDCanvas = import_react20.default.memo(PIDCanvasImpl);
|
|
7083
7118
|
|
|
7084
7119
|
// src/components/SymbolLibrary/SymbolLibrary.tsx
|
|
7085
|
-
var
|
|
7120
|
+
var import_react21 = require("react");
|
|
7086
7121
|
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
7087
7122
|
function SymbolLibrary({
|
|
7088
7123
|
className = "",
|
|
@@ -7090,8 +7125,8 @@ function SymbolLibrary({
|
|
|
7090
7125
|
showCategories = true,
|
|
7091
7126
|
categories = ["Valves", "Pumps", "Tanks", "Instruments", "Displays"]
|
|
7092
7127
|
}) {
|
|
7093
|
-
const [selectedCategory, setSelectedCategory] = (0,
|
|
7094
|
-
const [searchQuery, setSearchQuery] = (0,
|
|
7128
|
+
const [selectedCategory, setSelectedCategory] = (0, import_react21.useState)("all");
|
|
7129
|
+
const [searchQuery, setSearchQuery] = (0, import_react21.useState)("");
|
|
7095
7130
|
const symbolIds = getAvailableSymbols();
|
|
7096
7131
|
const allSymbols = symbolIds.map((id) => getSymbolDefinition(id)).filter((symbol) => symbol !== void 0);
|
|
7097
7132
|
const categoryMap = {
|
|
@@ -8142,13 +8177,13 @@ function createControlBinding(nodeId, deviceConfig, actions) {
|
|
|
8142
8177
|
}
|
|
8143
8178
|
|
|
8144
8179
|
// src/hooks/useDeviceControls.ts
|
|
8145
|
-
var
|
|
8180
|
+
var import_react22 = require("react");
|
|
8146
8181
|
function commandKey(nodeId, kind, suffix) {
|
|
8147
8182
|
return suffix ? `${nodeId}:${kind}:${suffix}` : `${nodeId}:${kind}`;
|
|
8148
8183
|
}
|
|
8149
8184
|
function useDeviceControls(initialBindings, options) {
|
|
8150
8185
|
const { commandTimeoutMs } = options ?? {};
|
|
8151
|
-
const [controls, setControls] = (0,
|
|
8186
|
+
const [controls, setControls] = (0, import_react22.useState)(() => {
|
|
8152
8187
|
const map = /* @__PURE__ */ new Map();
|
|
8153
8188
|
if (initialBindings) {
|
|
8154
8189
|
initialBindings.forEach((binding) => {
|
|
@@ -8157,12 +8192,12 @@ function useDeviceControls(initialBindings, options) {
|
|
|
8157
8192
|
}
|
|
8158
8193
|
return map;
|
|
8159
8194
|
});
|
|
8160
|
-
const pendingRef = (0,
|
|
8161
|
-
const [pendingCommands, setPendingCommands] = (0,
|
|
8162
|
-
const syncPending = (0,
|
|
8195
|
+
const pendingRef = (0, import_react22.useRef)(/* @__PURE__ */ new Map());
|
|
8196
|
+
const [pendingCommands, setPendingCommands] = (0, import_react22.useState)(() => /* @__PURE__ */ new Set());
|
|
8197
|
+
const syncPending = (0, import_react22.useCallback)(() => {
|
|
8163
8198
|
setPendingCommands(new Set(pendingRef.current.keys()));
|
|
8164
8199
|
}, []);
|
|
8165
|
-
const updateControl = (0,
|
|
8200
|
+
const updateControl = (0, import_react22.useCallback)((nodeId, updates) => {
|
|
8166
8201
|
setControls((prev) => {
|
|
8167
8202
|
const newMap = new Map(prev);
|
|
8168
8203
|
const existing = newMap.get(nodeId);
|
|
@@ -8176,7 +8211,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
8176
8211
|
return newMap;
|
|
8177
8212
|
});
|
|
8178
8213
|
}, []);
|
|
8179
|
-
const updateControlBatch = (0,
|
|
8214
|
+
const updateControlBatch = (0, import_react22.useCallback)((updates) => {
|
|
8180
8215
|
setControls((prev) => {
|
|
8181
8216
|
const newMap = new Map(prev);
|
|
8182
8217
|
Object.entries(updates).forEach(([nodeId, update]) => {
|
|
@@ -8188,7 +8223,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
8188
8223
|
return newMap;
|
|
8189
8224
|
});
|
|
8190
8225
|
}, []);
|
|
8191
|
-
const updateDeviceState = (0,
|
|
8226
|
+
const updateDeviceState = (0, import_react22.useCallback)(
|
|
8192
8227
|
(nodeId, stateUpdates) => {
|
|
8193
8228
|
setControls((prev) => {
|
|
8194
8229
|
const newMap = new Map(prev);
|
|
@@ -8204,7 +8239,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
8204
8239
|
},
|
|
8205
8240
|
[]
|
|
8206
8241
|
);
|
|
8207
|
-
const updateParameter = (0,
|
|
8242
|
+
const updateParameter = (0, import_react22.useCallback)(
|
|
8208
8243
|
(nodeId, parameterId, value) => {
|
|
8209
8244
|
setControls((prev) => {
|
|
8210
8245
|
const newMap = new Map(prev);
|
|
@@ -8231,27 +8266,27 @@ function useDeviceControls(initialBindings, options) {
|
|
|
8231
8266
|
},
|
|
8232
8267
|
[]
|
|
8233
8268
|
);
|
|
8234
|
-
const setControlBinding = (0,
|
|
8269
|
+
const setControlBinding = (0, import_react22.useCallback)((binding) => {
|
|
8235
8270
|
setControls((prev) => {
|
|
8236
8271
|
const newMap = new Map(prev);
|
|
8237
8272
|
newMap.set(binding.nodeId, binding);
|
|
8238
8273
|
return newMap;
|
|
8239
8274
|
});
|
|
8240
8275
|
}, []);
|
|
8241
|
-
const removeControlBinding = (0,
|
|
8276
|
+
const removeControlBinding = (0, import_react22.useCallback)((nodeId) => {
|
|
8242
8277
|
setControls((prev) => {
|
|
8243
8278
|
const newMap = new Map(prev);
|
|
8244
8279
|
newMap.delete(nodeId);
|
|
8245
8280
|
return newMap;
|
|
8246
8281
|
});
|
|
8247
8282
|
}, []);
|
|
8248
|
-
const getControlBinding = (0,
|
|
8283
|
+
const getControlBinding = (0, import_react22.useCallback)(
|
|
8249
8284
|
(nodeId) => {
|
|
8250
8285
|
return controls.get(nodeId);
|
|
8251
8286
|
},
|
|
8252
8287
|
[controls]
|
|
8253
8288
|
);
|
|
8254
|
-
const isCommandPending = (0,
|
|
8289
|
+
const isCommandPending = (0, import_react22.useCallback)(
|
|
8255
8290
|
(nodeId, kind) => {
|
|
8256
8291
|
if (kind) {
|
|
8257
8292
|
const prefix2 = `${nodeId}:${kind}`;
|
|
@@ -8268,7 +8303,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
8268
8303
|
},
|
|
8269
8304
|
[pendingCommands]
|
|
8270
8305
|
);
|
|
8271
|
-
const markPending = (0,
|
|
8306
|
+
const markPending = (0, import_react22.useCallback)(
|
|
8272
8307
|
(key, delta) => {
|
|
8273
8308
|
const next = (pendingRef.current.get(key) ?? 0) + delta;
|
|
8274
8309
|
if (next > 0) pendingRef.current.set(key, next);
|
|
@@ -8277,7 +8312,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
8277
8312
|
},
|
|
8278
8313
|
[syncPending]
|
|
8279
8314
|
);
|
|
8280
|
-
const runCommand = (0,
|
|
8315
|
+
const runCommand = (0, import_react22.useCallback)(
|
|
8281
8316
|
async (nodeId, key, invoke, messages) => {
|
|
8282
8317
|
const binding = controls.get(nodeId);
|
|
8283
8318
|
if (!binding) return;
|
|
@@ -8317,7 +8352,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
8317
8352
|
},
|
|
8318
8353
|
[controls, updateDeviceState, markPending, commandTimeoutMs]
|
|
8319
8354
|
);
|
|
8320
|
-
const sendModeChange = (0,
|
|
8355
|
+
const sendModeChange = (0, import_react22.useCallback)(
|
|
8321
8356
|
(nodeId, mode) => runCommand(
|
|
8322
8357
|
nodeId,
|
|
8323
8358
|
commandKey(nodeId, "mode"),
|
|
@@ -8326,7 +8361,7 @@ function useDeviceControls(initialBindings, options) {
|
|
|
8326
8361
|
),
|
|
8327
8362
|
[runCommand]
|
|
8328
8363
|
);
|
|
8329
|
-
const sendParameterChange = (0,
|
|
8364
|
+
const sendParameterChange = (0, import_react22.useCallback)(
|
|
8330
8365
|
(nodeId, parameterId, value) => runCommand(
|
|
8331
8366
|
nodeId,
|
|
8332
8367
|
commandKey(nodeId, "parameter", parameterId),
|
|
@@ -8335,21 +8370,21 @@ function useDeviceControls(initialBindings, options) {
|
|
|
8335
8370
|
),
|
|
8336
8371
|
[runCommand]
|
|
8337
8372
|
);
|
|
8338
|
-
const sendStartCommand = (0,
|
|
8373
|
+
const sendStartCommand = (0, import_react22.useCallback)(
|
|
8339
8374
|
(nodeId) => runCommand(nodeId, commandKey(nodeId, "start"), (binding) => binding.actions.onStart?.(), {
|
|
8340
8375
|
success: "Start command sent",
|
|
8341
8376
|
failure: "Start command failed"
|
|
8342
8377
|
}),
|
|
8343
8378
|
[runCommand]
|
|
8344
8379
|
);
|
|
8345
|
-
const sendStopCommand = (0,
|
|
8380
|
+
const sendStopCommand = (0, import_react22.useCallback)(
|
|
8346
8381
|
(nodeId) => runCommand(nodeId, commandKey(nodeId, "stop"), (binding) => binding.actions.onStop?.(), {
|
|
8347
8382
|
success: "Stop command sent",
|
|
8348
8383
|
failure: "Stop command failed"
|
|
8349
8384
|
}),
|
|
8350
8385
|
[runCommand]
|
|
8351
8386
|
);
|
|
8352
|
-
const sendCustomAction = (0,
|
|
8387
|
+
const sendCustomAction = (0, import_react22.useCallback)(
|
|
8353
8388
|
(nodeId, actionId) => runCommand(
|
|
8354
8389
|
nodeId,
|
|
8355
8390
|
commandKey(nodeId, "action", actionId),
|
|
@@ -8402,9 +8437,9 @@ function createConfigBinding(nodeId, tag, parameters, actions, options) {
|
|
|
8402
8437
|
}
|
|
8403
8438
|
|
|
8404
8439
|
// src/hooks/useDeviceConfigs.ts
|
|
8405
|
-
var
|
|
8440
|
+
var import_react23 = require("react");
|
|
8406
8441
|
function useDeviceConfigs(initialConfigs) {
|
|
8407
|
-
const [configs, setConfigs] = (0,
|
|
8442
|
+
const [configs, setConfigs] = (0, import_react23.useState)(() => {
|
|
8408
8443
|
const map = /* @__PURE__ */ new Map();
|
|
8409
8444
|
if (initialConfigs) {
|
|
8410
8445
|
initialConfigs.forEach((config) => {
|
|
@@ -8413,13 +8448,13 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
8413
8448
|
}
|
|
8414
8449
|
return map;
|
|
8415
8450
|
});
|
|
8416
|
-
const getConfig = (0,
|
|
8451
|
+
const getConfig = (0, import_react23.useCallback)(
|
|
8417
8452
|
(nodeId) => {
|
|
8418
8453
|
return configs.get(nodeId);
|
|
8419
8454
|
},
|
|
8420
8455
|
[configs]
|
|
8421
8456
|
);
|
|
8422
|
-
const updateConfig = (0,
|
|
8457
|
+
const updateConfig = (0, import_react23.useCallback)((nodeId, updates) => {
|
|
8423
8458
|
setConfigs((prev) => {
|
|
8424
8459
|
const newMap = new Map(prev);
|
|
8425
8460
|
const existing = newMap.get(nodeId);
|
|
@@ -8433,7 +8468,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
8433
8468
|
return newMap;
|
|
8434
8469
|
});
|
|
8435
8470
|
}, []);
|
|
8436
|
-
const updateConfigState = (0,
|
|
8471
|
+
const updateConfigState = (0, import_react23.useCallback)((nodeId, stateUpdates) => {
|
|
8437
8472
|
setConfigs((prev) => {
|
|
8438
8473
|
const newMap = new Map(prev);
|
|
8439
8474
|
const existing = newMap.get(nodeId);
|
|
@@ -8446,7 +8481,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
8446
8481
|
return newMap;
|
|
8447
8482
|
});
|
|
8448
8483
|
}, []);
|
|
8449
|
-
const updateConfigBatch = (0,
|
|
8484
|
+
const updateConfigBatch = (0, import_react23.useCallback)((updates) => {
|
|
8450
8485
|
setConfigs((prev) => {
|
|
8451
8486
|
const newMap = new Map(prev);
|
|
8452
8487
|
Object.entries(updates).forEach(([nodeId, update]) => {
|
|
@@ -8458,7 +8493,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
8458
8493
|
return newMap;
|
|
8459
8494
|
});
|
|
8460
8495
|
}, []);
|
|
8461
|
-
const updateParameterValue = (0,
|
|
8496
|
+
const updateParameterValue = (0, import_react23.useCallback)((nodeId, parameterId, value) => {
|
|
8462
8497
|
setConfigs((prev) => {
|
|
8463
8498
|
const newMap = new Map(prev);
|
|
8464
8499
|
const existing = newMap.get(nodeId);
|
|
@@ -8475,7 +8510,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
8475
8510
|
return newMap;
|
|
8476
8511
|
});
|
|
8477
8512
|
}, []);
|
|
8478
|
-
const applyConfig = (0,
|
|
8513
|
+
const applyConfig = (0, import_react23.useCallback)(
|
|
8479
8514
|
async (nodeId) => {
|
|
8480
8515
|
const config = configs.get(nodeId);
|
|
8481
8516
|
if (!config || !config.actions.onApply) {
|
|
@@ -8508,7 +8543,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
8508
8543
|
},
|
|
8509
8544
|
[configs, updateConfigState]
|
|
8510
8545
|
);
|
|
8511
|
-
const saveConfig = (0,
|
|
8546
|
+
const saveConfig = (0, import_react23.useCallback)(
|
|
8512
8547
|
async (nodeId) => {
|
|
8513
8548
|
const config = configs.get(nodeId);
|
|
8514
8549
|
if (!config || !config.actions.onSave) {
|
|
@@ -8542,7 +8577,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
8542
8577
|
},
|
|
8543
8578
|
[configs, updateConfigState]
|
|
8544
8579
|
);
|
|
8545
|
-
const resetConfig = (0,
|
|
8580
|
+
const resetConfig = (0, import_react23.useCallback)(
|
|
8546
8581
|
async (nodeId) => {
|
|
8547
8582
|
const config = configs.get(nodeId);
|
|
8548
8583
|
if (!config) {
|
|
@@ -8572,7 +8607,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
8572
8607
|
},
|
|
8573
8608
|
[configs, updateConfig, updateConfigState]
|
|
8574
8609
|
);
|
|
8575
|
-
const cancelConfig = (0,
|
|
8610
|
+
const cancelConfig = (0, import_react23.useCallback)(
|
|
8576
8611
|
(nodeId) => {
|
|
8577
8612
|
const config = configs.get(nodeId);
|
|
8578
8613
|
if (config?.actions.onCancel) {
|
|
@@ -8581,7 +8616,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
8581
8616
|
},
|
|
8582
8617
|
[configs]
|
|
8583
8618
|
);
|
|
8584
|
-
const validateConfig = (0,
|
|
8619
|
+
const validateConfig = (0, import_react23.useCallback)(
|
|
8585
8620
|
(nodeId) => {
|
|
8586
8621
|
const config = configs.get(nodeId);
|
|
8587
8622
|
if (!config) {
|
|
@@ -8623,21 +8658,21 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
8623
8658
|
},
|
|
8624
8659
|
[configs, updateConfigState]
|
|
8625
8660
|
);
|
|
8626
|
-
const setConfig = (0,
|
|
8661
|
+
const setConfig = (0, import_react23.useCallback)((config) => {
|
|
8627
8662
|
setConfigs((prev) => {
|
|
8628
8663
|
const newMap = new Map(prev);
|
|
8629
8664
|
newMap.set(config.nodeId, config);
|
|
8630
8665
|
return newMap;
|
|
8631
8666
|
});
|
|
8632
8667
|
}, []);
|
|
8633
|
-
const removeConfig = (0,
|
|
8668
|
+
const removeConfig = (0, import_react23.useCallback)((nodeId) => {
|
|
8634
8669
|
setConfigs((prev) => {
|
|
8635
8670
|
const newMap = new Map(prev);
|
|
8636
8671
|
newMap.delete(nodeId);
|
|
8637
8672
|
return newMap;
|
|
8638
8673
|
});
|
|
8639
8674
|
}, []);
|
|
8640
|
-
const clearConfigs = (0,
|
|
8675
|
+
const clearConfigs = (0, import_react23.useCallback)(() => {
|
|
8641
8676
|
setConfigs(/* @__PURE__ */ new Map());
|
|
8642
8677
|
}, []);
|
|
8643
8678
|
return {
|
|
@@ -8659,7 +8694,7 @@ function useDeviceConfigs(initialConfigs) {
|
|
|
8659
8694
|
}
|
|
8660
8695
|
|
|
8661
8696
|
// src/components/DeviceConfigPanel/DeviceConfigPanel.tsx
|
|
8662
|
-
var
|
|
8697
|
+
var import_react24 = require("react");
|
|
8663
8698
|
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
8664
8699
|
function DeviceConfigPanel({
|
|
8665
8700
|
binding,
|
|
@@ -8678,7 +8713,7 @@ function DeviceConfigPanel({
|
|
|
8678
8713
|
showControlsButton = true,
|
|
8679
8714
|
embedded = false
|
|
8680
8715
|
}) {
|
|
8681
|
-
const [localValues, setLocalValues] = (0,
|
|
8716
|
+
const [localValues, setLocalValues] = (0, import_react24.useState)(() => {
|
|
8682
8717
|
if (binding) {
|
|
8683
8718
|
const values = {};
|
|
8684
8719
|
binding.parameters.forEach((param) => {
|
|
@@ -8688,7 +8723,7 @@ function DeviceConfigPanel({
|
|
|
8688
8723
|
}
|
|
8689
8724
|
return {};
|
|
8690
8725
|
});
|
|
8691
|
-
const [collapsedSections, setCollapsedSections] = (0,
|
|
8726
|
+
const [collapsedSections, setCollapsedSections] = (0, import_react24.useState)(() => {
|
|
8692
8727
|
const collapsed = /* @__PURE__ */ new Set();
|
|
8693
8728
|
if (binding?.sections) {
|
|
8694
8729
|
binding.sections.forEach((section) => {
|
|
@@ -8699,9 +8734,9 @@ function DeviceConfigPanel({
|
|
|
8699
8734
|
}
|
|
8700
8735
|
return collapsed;
|
|
8701
8736
|
});
|
|
8702
|
-
const [showToast, setShowToast] = (0,
|
|
8703
|
-
const [bindingId, setBindingId] = (0,
|
|
8704
|
-
const lastResultTimestampRef = (0,
|
|
8737
|
+
const [showToast, setShowToast] = (0, import_react24.useState)(true);
|
|
8738
|
+
const [bindingId, setBindingId] = (0, import_react24.useState)(binding?.nodeId || null);
|
|
8739
|
+
const lastResultTimestampRef = (0, import_react24.useRef)(0);
|
|
8705
8740
|
if (binding && binding.nodeId !== bindingId) {
|
|
8706
8741
|
const values = {};
|
|
8707
8742
|
binding.parameters.forEach((param) => {
|
|
@@ -8717,21 +8752,24 @@ function DeviceConfigPanel({
|
|
|
8717
8752
|
setCollapsedSections(collapsed);
|
|
8718
8753
|
setBindingId(binding.nodeId);
|
|
8719
8754
|
}
|
|
8720
|
-
(0,
|
|
8755
|
+
(0, import_react24.useEffect)(() => {
|
|
8721
8756
|
const currentTimestamp = binding?.state.lastSaved || 0;
|
|
8722
8757
|
if (binding?.state.lastSaveResult && currentTimestamp !== lastResultTimestampRef.current) {
|
|
8723
8758
|
lastResultTimestampRef.current = currentTimestamp;
|
|
8759
|
+
let hideTimer;
|
|
8724
8760
|
const showTimer = setTimeout(() => {
|
|
8725
8761
|
setShowToast(true);
|
|
8726
|
-
|
|
8762
|
+
hideTimer = setTimeout(() => {
|
|
8727
8763
|
setShowToast(false);
|
|
8728
8764
|
}, toastDuration);
|
|
8729
|
-
return () => clearTimeout(hideTimer);
|
|
8730
8765
|
}, 0);
|
|
8731
|
-
return () =>
|
|
8766
|
+
return () => {
|
|
8767
|
+
clearTimeout(showTimer);
|
|
8768
|
+
if (hideTimer) clearTimeout(hideTimer);
|
|
8769
|
+
};
|
|
8732
8770
|
}
|
|
8733
8771
|
}, [binding?.state.lastSaveResult, binding?.state.lastSaved, toastDuration]);
|
|
8734
|
-
const parametersBySection = (0,
|
|
8772
|
+
const parametersBySection = (0, import_react24.useMemo)(() => {
|
|
8735
8773
|
if (!binding) return { _unsectioned: [] };
|
|
8736
8774
|
const groups = { _unsectioned: [] };
|
|
8737
8775
|
binding.parameters.forEach((param) => {
|
|
@@ -8746,7 +8784,7 @@ function DeviceConfigPanel({
|
|
|
8746
8784
|
});
|
|
8747
8785
|
return groups;
|
|
8748
8786
|
}, [binding]);
|
|
8749
|
-
const sortedSections = (0,
|
|
8787
|
+
const sortedSections = (0, import_react24.useMemo)(() => {
|
|
8750
8788
|
if (!binding?.sections) return [];
|
|
8751
8789
|
return [...binding.sections].sort((a, b) => (a.order || 0) - (b.order || 0));
|
|
8752
8790
|
}, [binding]);
|
|
@@ -9362,7 +9400,7 @@ function DeviceConfigPanel({
|
|
|
9362
9400
|
}
|
|
9363
9401
|
|
|
9364
9402
|
// src/diagram/hooks/useSimulation.ts
|
|
9365
|
-
var
|
|
9403
|
+
var import_react25 = require("react");
|
|
9366
9404
|
function useSimulation(telemetry, updateTelemetryBatch, options = {}) {
|
|
9367
9405
|
const {
|
|
9368
9406
|
interval = 2e3,
|
|
@@ -9373,7 +9411,7 @@ function useSimulation(telemetry, updateTelemetryBatch, options = {}) {
|
|
|
9373
9411
|
historyLength = 10,
|
|
9374
9412
|
generateValue
|
|
9375
9413
|
} = options;
|
|
9376
|
-
(0,
|
|
9414
|
+
(0, import_react25.useEffect)(() => {
|
|
9377
9415
|
if (!enabled) return;
|
|
9378
9416
|
const intervalId = setInterval(() => {
|
|
9379
9417
|
const updates = [];
|