seat-editor 3.4.7 → 3.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/constant.d.ts +1 -1
- package/dist/app/graph-view/page.d.ts +1 -0
- package/dist/app/graph-view/page.js +343 -0
- package/dist/app/graph-view/page.jsx +445 -0
- package/dist/app/graph-view-new/constant.d.ts +581 -0
- package/dist/app/graph-view-new/constant.js +6973 -0
- package/dist/app/graph-view-new/page.d.ts +1 -0
- package/dist/app/graph-view-new/page.js +71 -0
- package/dist/app/graph-view-new/page.jsx +98 -0
- package/dist/app/new-board/page.js +43 -7
- package/dist/app/new-board/page.jsx +45 -12
- package/dist/components/button-tools/index.js +7 -5
- package/dist/components/button-tools/index.jsx +21 -9
- package/dist/components/form-tools/label.js +9 -20
- package/dist/components/form-tools/label.jsx +38 -28
- package/dist/components/form-tools/shape.js +5 -5
- package/dist/components/form-tools/shape.jsx +8 -8
- package/dist/components/layer-v3/index.js +44 -3
- package/dist/components/layer-v3/index.jsx +120 -3
- package/dist/components/layer-v4/index.js +3 -2
- package/dist/components/layer-v4/index.jsx +3 -2
- package/dist/components/layer-v5/constant.d.ts +60 -0
- package/dist/components/layer-v5/constant.js +93 -0
- package/dist/components/layer-v5/index.d.ts +24 -0
- package/dist/components/layer-v5/index.js +927 -0
- package/dist/components/layer-v5/index.jsx +1049 -0
- package/dist/features/board-v3/index.js +350 -72
- package/dist/features/board-v3/index.jsx +369 -75
- package/dist/features/board-v3/resize-element.js +5 -0
- package/dist/features/board-v3/utils.d.ts +8 -0
- package/dist/features/board-v3/utils.js +23 -7
- package/dist/features/package/index.d.ts +2 -0
- package/dist/features/package/index.js +1 -1
- package/dist/features/package/index.jsx +6 -1
- package/dist/features/panel/index.d.ts +8 -0
- package/dist/features/panel/index.js +160 -38
- package/dist/features/panel/index.jsx +173 -46
- package/dist/features/panel/polygon.d.ts +2 -0
- package/dist/features/panel/polygon.js +44 -0
- package/dist/features/panel/polygon.jsx +70 -0
- package/dist/features/panel/select-tool.js +3 -0
- package/dist/features/panel/select-tool.jsx +3 -0
- package/dist/features/panel/selected-group.js +24 -26
- package/dist/features/panel/selected-group.jsx +56 -51
- package/dist/features/panel/text-tool.js +17 -2
- package/dist/features/panel/text-tool.jsx +19 -2
- package/dist/features/panel/upload-tool.js +17 -3
- package/dist/features/panel/upload-tool.jsx +23 -4
- package/dist/features/side-tool/index.js +43 -6
- package/dist/features/side-tool/index.jsx +47 -10
- package/dist/features/view-only-4/connect-handle.d.ts +13 -0
- package/dist/features/view-only-4/connect-handle.js +23 -0
- package/dist/features/view-only-4/connect-handle.jsx +30 -0
- package/dist/features/view-only-4/connection-layer.d.ts +21 -0
- package/dist/features/view-only-4/connection-layer.js +219 -0
- package/dist/features/view-only-4/connection-layer.jsx +291 -0
- package/dist/features/view-only-4/index.d.ts +99 -0
- package/dist/features/view-only-4/index.js +684 -0
- package/dist/features/view-only-4/index.jsx +722 -0
- package/dist/features/view-only-4/integration-guide.d.ts +0 -0
- package/dist/features/view-only-4/integration-guide.js +0 -0
- package/dist/features/view-only-4/use-connection-graph.d.ts +41 -0
- package/dist/features/view-only-4/use-connection-graph.js +182 -0
- package/dist/features/view-only-4/utils.d.ts +74 -0
- package/dist/features/view-only-4/utils.js +106 -0
- package/dist/features/view-only-5/connect-handle.d.ts +30 -0
- package/dist/features/view-only-5/connect-handle.js +88 -0
- package/dist/features/view-only-5/connect-handle.jsx +96 -0
- package/dist/features/view-only-5/connection-layer.d.ts +34 -0
- package/dist/features/view-only-5/connection-layer.js +182 -0
- package/dist/features/view-only-5/connection-layer.jsx +265 -0
- package/dist/features/view-only-5/index.d.ts +102 -0
- package/dist/features/view-only-5/index.js +585 -0
- package/dist/features/view-only-5/index.jsx +614 -0
- package/dist/features/view-only-5/use-connection-graph.d.ts +57 -0
- package/dist/features/view-only-5/use-connection-graph.js +196 -0
- package/dist/features/view-only-5/utils.d.ts +52 -0
- package/dist/features/view-only-5/utils.js +80 -0
- package/dist/features/view-only-6/connect-handle.d.ts +13 -0
- package/dist/features/view-only-6/connect-handle.js +20 -0
- package/dist/features/view-only-6/connect-handle.jsx +21 -0
- package/dist/features/view-only-6/connection-layer.d.ts +22 -0
- package/dist/features/view-only-6/connection-layer.js +191 -0
- package/dist/features/view-only-6/connection-layer.jsx +244 -0
- package/dist/features/view-only-6/index.d.ts +99 -0
- package/dist/features/view-only-6/index.js +687 -0
- package/dist/features/view-only-6/index.jsx +724 -0
- package/dist/features/view-only-6/use-connection-graph.d.ts +26 -0
- package/dist/features/view-only-6/use-connection-graph.js +103 -0
- package/dist/features/view-only-6/utils.d.ts +66 -0
- package/dist/features/view-only-6/utils.js +96 -0
- package/dist/features/view-only-7/connect-handle.d.ts +13 -0
- package/dist/features/view-only-7/connect-handle.js +23 -0
- package/dist/features/view-only-7/connect-handle.jsx +30 -0
- package/dist/features/view-only-7/connection-layer.d.ts +22 -0
- package/dist/features/view-only-7/connection-layer.js +165 -0
- package/dist/features/view-only-7/connection-layer.jsx +217 -0
- package/dist/features/view-only-7/index.d.ts +99 -0
- package/dist/features/view-only-7/index.js +687 -0
- package/dist/features/view-only-7/index.jsx +724 -0
- package/dist/features/view-only-7/use-connection-graph.d.ts +26 -0
- package/dist/features/view-only-7/use-connection-graph.js +104 -0
- package/dist/features/view-only-7/utils.d.ts +69 -0
- package/dist/features/view-only-7/utils.js +144 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/seat-editor.css +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo, useState } from "react";
|
|
3
|
+
import { buildPath, getRectEdge, GRID_SIZE, NODE_WIDTH, NODE_HEIGHT, snap, } from "./utils";
|
|
4
|
+
const LEVEL_COLORS = [
|
|
5
|
+
"#22c55e",
|
|
6
|
+
"#f59e0b",
|
|
7
|
+
"#f97316",
|
|
8
|
+
"#ef4444",
|
|
9
|
+
"#a78bfa",
|
|
10
|
+
"#38bdf8",
|
|
11
|
+
];
|
|
12
|
+
const getLevelColor = (level) => LEVEL_COLORS[Math.min(level, LEVEL_COLORS.length - 1)];
|
|
13
|
+
const floodFill = (seedIds, edges) => {
|
|
14
|
+
const levelMap = new Map();
|
|
15
|
+
const queue = [];
|
|
16
|
+
seedIds.forEach((id) => {
|
|
17
|
+
levelMap.set(id, 0);
|
|
18
|
+
queue.push({ id, level: 0 });
|
|
19
|
+
});
|
|
20
|
+
while (queue.length > 0) {
|
|
21
|
+
const { id, level } = queue.shift();
|
|
22
|
+
edges.forEach((edge) => {
|
|
23
|
+
const neighbors = [];
|
|
24
|
+
if (edge.from === id)
|
|
25
|
+
neighbors.push(edge.to);
|
|
26
|
+
if (edge.to === id)
|
|
27
|
+
neighbors.push(edge.from);
|
|
28
|
+
neighbors.forEach((nId) => {
|
|
29
|
+
if (!levelMap.has(nId)) {
|
|
30
|
+
levelMap.set(nId, level + 1);
|
|
31
|
+
queue.push({ id: nId, level: level + 1 });
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
return levelMap;
|
|
37
|
+
};
|
|
38
|
+
const computePoints = (fromPos, toPos, waypoints) => [fromPos, ...waypoints, toPos];
|
|
39
|
+
// Hitung midpoint kurva quadratic bezier pada t=0.5
|
|
40
|
+
const quadraticMidpoint = (from, to) => {
|
|
41
|
+
const dx = to.x - from.x;
|
|
42
|
+
const dy = to.y - from.y;
|
|
43
|
+
const dist = Math.sqrt(dx * dx + dy * dy);
|
|
44
|
+
const bend = Math.min(dist * 0.35, 80);
|
|
45
|
+
const mx = (from.x + to.x) / 2;
|
|
46
|
+
const my = (from.y + to.y) / 2;
|
|
47
|
+
const cpx = dist > 0 ? mx - (dy / dist) * bend : mx;
|
|
48
|
+
const cpy = dist > 0 ? my + (dx / dist) * bend : my;
|
|
49
|
+
const t = 0.5, mt = 0.5;
|
|
50
|
+
return {
|
|
51
|
+
x: mt * mt * from.x + 2 * mt * t * cpx + t * t * to.x,
|
|
52
|
+
y: mt * mt * from.y + 2 * mt * t * cpy + t * t * to.y,
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
export const ConnectionLayer = ({ edges, selectedEdge, connecting, draggingAnchor, mousePos, isConnectEdge, isSelectNode, getNodeById, onSelectEdge, onDeleteEdge, onStartDragWaypoint, onInsertWaypoint, onRemoveWaypoint, onStartDragAnchor, selectedNodeId, }) => {
|
|
56
|
+
const [hoveredEdge, setHoveredEdge] = useState(null);
|
|
57
|
+
console.log({ selectedEdge });
|
|
58
|
+
const nodeHighlightMap = useMemo(() => {
|
|
59
|
+
if (!selectedEdge)
|
|
60
|
+
return new Map();
|
|
61
|
+
const sel = edges.find((e) => e.id === selectedEdge);
|
|
62
|
+
if (!sel)
|
|
63
|
+
return new Map();
|
|
64
|
+
return floodFill([sel.from, sel.to], edges);
|
|
65
|
+
}, [selectedEdge, edges]);
|
|
66
|
+
const nodeHighlightMapByNode = useMemo(() => {
|
|
67
|
+
if (selectedNodeId) {
|
|
68
|
+
return floodFill([selectedNodeId], edges);
|
|
69
|
+
}
|
|
70
|
+
if (selectedEdge) {
|
|
71
|
+
const sel = edges.find((e) => e.id === selectedEdge);
|
|
72
|
+
if (!sel)
|
|
73
|
+
return new Map();
|
|
74
|
+
return floodFill([sel.from, sel.to], edges);
|
|
75
|
+
}
|
|
76
|
+
return new Map();
|
|
77
|
+
}, [selectedEdge, selectedNodeId, edges]);
|
|
78
|
+
const edgePaths = useMemo(() => {
|
|
79
|
+
const map = new Map();
|
|
80
|
+
edges.forEach((edge) => {
|
|
81
|
+
var _a, _b, _c;
|
|
82
|
+
const fromNode = getNodeById(edge.from);
|
|
83
|
+
const toNode = getNodeById(edge.to);
|
|
84
|
+
if (!fromNode || !toNode)
|
|
85
|
+
return;
|
|
86
|
+
const isDraggingFrom = (draggingAnchor === null || draggingAnchor === void 0 ? void 0 : draggingAnchor.edgeId) === edge.id && draggingAnchor.side === "from";
|
|
87
|
+
const isDraggingTo = (draggingAnchor === null || draggingAnchor === void 0 ? void 0 : draggingAnchor.edgeId) === edge.id && draggingAnchor.side === "to";
|
|
88
|
+
const fromPos = isDraggingFrom
|
|
89
|
+
? mousePos
|
|
90
|
+
: (_a = edge.fromPos) !== null && _a !== void 0 ? _a : getRectEdge(fromNode, toNode, fromNode.width, fromNode.height);
|
|
91
|
+
const toPos = isDraggingTo
|
|
92
|
+
? mousePos
|
|
93
|
+
: (_b = edge.toPos) !== null && _b !== void 0 ? _b : getRectEdge(toNode, fromNode, toNode.width, toNode.height);
|
|
94
|
+
const pts = computePoints(fromPos, toPos, (_c = edge.waypoints) !== null && _c !== void 0 ? _c : []);
|
|
95
|
+
const pathD = buildPath(pts);
|
|
96
|
+
const mid = quadraticMidpoint(fromPos, toPos);
|
|
97
|
+
map.set(edge.id, {
|
|
98
|
+
pathD,
|
|
99
|
+
allPoints: pts,
|
|
100
|
+
fromPos,
|
|
101
|
+
toPos,
|
|
102
|
+
midX: mid.x,
|
|
103
|
+
midY: mid.y,
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
return map;
|
|
107
|
+
}, [edges, getNodeById, draggingAnchor, mousePos]);
|
|
108
|
+
return (_jsxs("g", { id: "connection-layer", children: [Array.from(nodeHighlightMap.entries()).map(([nodeId, level]) => {
|
|
109
|
+
var _a, _b, _c;
|
|
110
|
+
const node = getNodeById(nodeId);
|
|
111
|
+
if (!node)
|
|
112
|
+
return null;
|
|
113
|
+
const w = (_a = node.width) !== null && _a !== void 0 ? _a : NODE_WIDTH;
|
|
114
|
+
const h = (_b = node.height) !== null && _b !== void 0 ? _b : NODE_HEIGHT;
|
|
115
|
+
const rotation = (_c = node.rotation) !== null && _c !== void 0 ? _c : 0;
|
|
116
|
+
const color = getLevelColor(level);
|
|
117
|
+
const padding = 4;
|
|
118
|
+
return (_jsxs("g", { transform: `translate(${node.x}, ${node.y}) rotate(${rotation})`, style: { pointerEvents: "none" }, children: [_jsx("rect", { x: -w / 2 - padding, y: -h / 2 - padding, width: w + padding * 2, height: h + padding * 2, fill: "none", stroke: color, strokeWidth: 8, rx: 5, opacity: 0.08 }), _jsx("rect", { x: -w / 2 - padding, y: -h / 2 - padding, width: w + padding * 2, height: h + padding * 2, fill: "none", stroke: color, strokeWidth: level === 0 ? 2.5 : 1.5, strokeDasharray: level === 0 ? "none" : "5 3", rx: 5, opacity: level === 0 ? 1 : 0.75 }), _jsxs("g", { transform: `translate(${w / 2 + padding - 2}, ${-h / 2 - padding})`, children: [_jsx("circle", { r: 7, fill: color, opacity: 0.9 }), _jsx("text", { textAnchor: "middle", dominantBaseline: "middle", fill: "white", fontSize: 7, fontFamily: "monospace", fontWeight: 700, style: { userSelect: "none" }, children: level })] })] }, `highlight-${nodeId}`));
|
|
119
|
+
}), Array.from(nodeHighlightMapByNode.entries()).map(([nodeId, level]) => {
|
|
120
|
+
var _a, _b, _c;
|
|
121
|
+
const node = getNodeById(nodeId);
|
|
122
|
+
if (!node)
|
|
123
|
+
return null;
|
|
124
|
+
const w = (_a = node.width) !== null && _a !== void 0 ? _a : NODE_WIDTH;
|
|
125
|
+
const h = (_b = node.height) !== null && _b !== void 0 ? _b : NODE_HEIGHT;
|
|
126
|
+
const rotation = (_c = node.rotation) !== null && _c !== void 0 ? _c : 0;
|
|
127
|
+
const color = getLevelColor(level);
|
|
128
|
+
const padding = 4;
|
|
129
|
+
return (_jsxs("g", { transform: `translate(${node.x}, ${node.y}) rotate(${rotation})`, style: { pointerEvents: "none" }, children: [_jsx("rect", { x: -w / 2 - padding, y: -h / 2 - padding, width: w + padding * 2, height: h + padding * 2, fill: "none", stroke: color, strokeWidth: 8, rx: 5, opacity: 0.08 }), _jsx("rect", { x: -w / 2 - padding, y: -h / 2 - padding, width: w + padding * 2, height: h + padding * 2, fill: "none", stroke: color, strokeWidth: level === 0 ? 2.5 : 1.5, strokeDasharray: level === 0 ? "none" : "5 3", rx: 5, opacity: level === 0 ? 1 : 0.75 }), _jsxs("g", { transform: `translate(${w / 2 + padding - 2}, ${-h / 2 - padding})`, children: [_jsx("circle", { r: 7, fill: color, opacity: 0.9 }), _jsx("text", { textAnchor: "middle", dominantBaseline: "middle", fill: "white", fontSize: 7, fontFamily: "monospace", fontWeight: 700, style: { userSelect: "none" }, children: level })] })] }, `highlight-${nodeId}`));
|
|
130
|
+
}), edges.map((edge) => {
|
|
131
|
+
var _a;
|
|
132
|
+
const ep = edgePaths.get(edge.id);
|
|
133
|
+
if (!ep)
|
|
134
|
+
return null;
|
|
135
|
+
const { pathD, allPoints, fromPos, toPos, midX, midY } = ep;
|
|
136
|
+
const isSel = selectedEdge === edge.id;
|
|
137
|
+
const isHov = hoveredEdge === edge.id;
|
|
138
|
+
const fromLevel = nodeHighlightMap.get(edge.from);
|
|
139
|
+
const toLevel = nodeHighlightMap.get(edge.to);
|
|
140
|
+
const isInNetwork = fromLevel !== undefined && toLevel !== undefined;
|
|
141
|
+
console.log({ isInNetwork, fromLevel, toLevel }, selectedEdge, !isSel && !isInNetwork);
|
|
142
|
+
const networkColor = isInNetwork
|
|
143
|
+
? getLevelColor(Math.max(fromLevel, toLevel))
|
|
144
|
+
: "#38bdf8";
|
|
145
|
+
const isDraggingFrom = (draggingAnchor === null || draggingAnchor === void 0 ? void 0 : draggingAnchor.edgeId) === edge.id && draggingAnchor.side === "from";
|
|
146
|
+
const isDraggingTo = (draggingAnchor === null || draggingAnchor === void 0 ? void 0 : draggingAnchor.edgeId) === edge.id && draggingAnchor.side === "to";
|
|
147
|
+
return (_jsxs("g", { children: [_jsx("path", { d: pathD, stroke: "transparent", strokeWidth: 14, fill: "none", style: { cursor: "pointer" }, onClick: (e) => {
|
|
148
|
+
e.stopPropagation();
|
|
149
|
+
onSelectEdge(edge.id);
|
|
150
|
+
}, onMouseEnter: () => setHoveredEdge(edge.id), onMouseLeave: () => setHoveredEdge(null) }), (isSel || isHov) && (_jsx("path", { d: pathD, stroke: isSel ? "#a78bfa" : "#38bdf8", strokeWidth: 8, fill: "none", opacity: isSel ? 0.12 : 0.06, style: { pointerEvents: "none" } })), _jsx("path", { d: pathD, stroke: isSel
|
|
151
|
+
? "#a78bfa"
|
|
152
|
+
: isInNetwork && selectedEdge
|
|
153
|
+
? networkColor
|
|
154
|
+
: "#38bdf8", strokeWidth: isSel ? 2 : isHov ? 2 : 1.5, fill: "none", opacity: selectedEdge && !isSel && !isInNetwork ? 0.25 : 0.9, strokeLinecap: "round", style: { pointerEvents: "none" } }), isSel && (_jsxs("g", { children: [isDraggingFrom && (_jsx("circle", { cx: fromPos.x, cy: fromPos.y, r: 12, fill: "#38bdf8", opacity: 0.15, style: { pointerEvents: "none" } })), _jsx("circle", { cx: fromPos.x, cy: fromPos.y, r: 10, fill: "transparent", style: { cursor: "grab" }, onMouseDown: (e) => {
|
|
155
|
+
e.stopPropagation();
|
|
156
|
+
onStartDragAnchor(e, edge.id, "from");
|
|
157
|
+
} }), _jsx("circle", { cx: fromPos.x, cy: fromPos.y, r: 6, fill: isDraggingFrom ? "#a78bfa" : "#38bdf8", stroke: "#0f172a", strokeWidth: 1.5, style: { pointerEvents: "none" } }), _jsx("circle", { cx: fromPos.x, cy: fromPos.y, r: 2.5, fill: "#0f172a", style: { pointerEvents: "none" } })] })), isSel && (_jsxs("g", { children: [isDraggingTo && (_jsx("circle", { cx: toPos.x, cy: toPos.y, r: 12, fill: "#22c55e", opacity: 0.15, style: { pointerEvents: "none" } })), _jsx("circle", { cx: toPos.x, cy: toPos.y, r: 10, fill: "transparent", style: { cursor: "grab" }, onMouseDown: (e) => {
|
|
158
|
+
e.stopPropagation();
|
|
159
|
+
onStartDragAnchor(e, edge.id, "to");
|
|
160
|
+
} }), _jsx("circle", { cx: toPos.x, cy: toPos.y, r: 6, fill: isDraggingTo ? "#a78bfa" : "#22c55e", stroke: "#0f172a", strokeWidth: 1.5, style: { pointerEvents: "none" } }), _jsx("circle", { cx: toPos.x, cy: toPos.y, r: 2.5, fill: "#0f172a", style: { pointerEvents: "none" } })] })), ((_a = edge.waypoints) !== null && _a !== void 0 ? _a : []).map((wp, i) => (_jsxs("g", { children: [_jsx("circle", { cx: wp.x, cy: wp.y, r: 12, fill: "transparent", style: { cursor: "grab" }, onMouseDown: (e) => onStartDragWaypoint(e, edge.id, i), onContextMenu: (e) => onRemoveWaypoint(e, edge.id, i) }), _jsx("circle", { cx: wp.x, cy: wp.y, r: isSel ? 8 : 5, fill: isSel ? "#1e1b2e" : "#0f172a", stroke: isSel ? "#a78bfa" : "#38bdf8", strokeWidth: isSel ? 2 : 1.2, style: { pointerEvents: "none" } }), _jsx("circle", { cx: wp.x, cy: wp.y, r: isSel ? 3 : 2, fill: isSel ? "#a78bfa" : "#38bdf8", style: { pointerEvents: "none" } })] }, `wp-${i}`))), isSel &&
|
|
161
|
+
isConnectEdge &&
|
|
162
|
+
allPoints.slice(0, -1).map((pt, i) => {
|
|
163
|
+
var _a;
|
|
164
|
+
const next = allPoints[i + 1];
|
|
165
|
+
const mx = snap((pt.x + next.x) / 2);
|
|
166
|
+
const my = snap((pt.y + next.y) / 2);
|
|
167
|
+
const tooClose = ((_a = edge.waypoints) !== null && _a !== void 0 ? _a : []).some((wp) => Math.abs(wp.x - mx) < GRID_SIZE &&
|
|
168
|
+
Math.abs(wp.y - my) < GRID_SIZE);
|
|
169
|
+
if (tooClose)
|
|
170
|
+
return null;
|
|
171
|
+
return (_jsxs("g", { children: [_jsx("circle", { cx: mx, cy: my, r: 10, fill: "transparent", style: { cursor: "crosshair" }, onMouseDown: (e) => onInsertWaypoint(e, edge.id, i, mx, my) }), _jsx("circle", { cx: mx, cy: my, r: 4, fill: "#1e1b2e", stroke: "#a78bfa", strokeWidth: 1, strokeDasharray: "2 2", style: { pointerEvents: "none" } }), _jsx("circle", { cx: mx, cy: my, r: 1.5, fill: "#a78bfa", style: { pointerEvents: "none" } })] }, `mid-${i}`));
|
|
172
|
+
}), isSel && isConnectEdge && (_jsxs("g", { onClick: (e) => {
|
|
173
|
+
e.stopPropagation();
|
|
174
|
+
onDeleteEdge(edge.id);
|
|
175
|
+
}, style: { cursor: "pointer" }, children: [_jsx("rect", { x: midX - 16, y: midY - 10, width: 32, height: 18, rx: 4, fill: "#1e1b2e", stroke: "#a78bfa", strokeWidth: 1, opacity: 0.95 }), _jsx("text", { x: midX, y: midY, textAnchor: "middle", dominantBaseline: "middle", fill: "#a78bfa", fontSize: 9, fontFamily: "monospace", fontWeight: 600, children: "DEL" })] }))] }, edge.id));
|
|
176
|
+
}), connecting &&
|
|
177
|
+
(() => {
|
|
178
|
+
const pts = computePoints(connecting.fromPos, mousePos, []);
|
|
179
|
+
const pathD = buildPath(pts);
|
|
180
|
+
return (_jsxs("g", { children: [_jsx("circle", { cx: connecting.fromPos.x, cy: connecting.fromPos.y, r: 4, fill: "#a78bfa", stroke: "#0f172a", strokeWidth: 0.8, opacity: 0.9, style: { pointerEvents: "none" } }), _jsx("path", { d: pathD, stroke: "#a78bfa", strokeWidth: 1.5, fill: "none", strokeDasharray: "6 3", strokeLinecap: "round", opacity: 0.8, style: { pointerEvents: "none" } })] }));
|
|
181
|
+
})(), draggingAnchor && (_jsx("text", { x: mousePos.x + 14, y: mousePos.y - 8, fill: "#a78bfa", fontSize: 9, fontFamily: "monospace", opacity: 0.8, style: { pointerEvents: "none", userSelect: "none" }, children: "klik node tujuan" }))] }));
|
|
182
|
+
};
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import React, { useMemo, useState } from "react";
|
|
2
|
+
import { buildPath, getRectEdge, GRID_SIZE, NODE_WIDTH, NODE_HEIGHT, snap, } from "./utils";
|
|
3
|
+
const LEVEL_COLORS = [
|
|
4
|
+
"#22c55e",
|
|
5
|
+
"#f59e0b",
|
|
6
|
+
"#f97316",
|
|
7
|
+
"#ef4444",
|
|
8
|
+
"#a78bfa",
|
|
9
|
+
"#38bdf8",
|
|
10
|
+
];
|
|
11
|
+
const getLevelColor = (level) => LEVEL_COLORS[Math.min(level, LEVEL_COLORS.length - 1)];
|
|
12
|
+
const floodFill = (seedIds, edges) => {
|
|
13
|
+
const levelMap = new Map();
|
|
14
|
+
const queue = [];
|
|
15
|
+
seedIds.forEach((id) => {
|
|
16
|
+
levelMap.set(id, 0);
|
|
17
|
+
queue.push({ id, level: 0 });
|
|
18
|
+
});
|
|
19
|
+
while (queue.length > 0) {
|
|
20
|
+
const { id, level } = queue.shift();
|
|
21
|
+
edges.forEach((edge) => {
|
|
22
|
+
const neighbors = [];
|
|
23
|
+
if (edge.from === id)
|
|
24
|
+
neighbors.push(edge.to);
|
|
25
|
+
if (edge.to === id)
|
|
26
|
+
neighbors.push(edge.from);
|
|
27
|
+
neighbors.forEach((nId) => {
|
|
28
|
+
if (!levelMap.has(nId)) {
|
|
29
|
+
levelMap.set(nId, level + 1);
|
|
30
|
+
queue.push({ id: nId, level: level + 1 });
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
return levelMap;
|
|
36
|
+
};
|
|
37
|
+
const computePoints = (fromPos, toPos, waypoints) => [fromPos, ...waypoints, toPos];
|
|
38
|
+
// Hitung midpoint kurva quadratic bezier pada t=0.5
|
|
39
|
+
const quadraticMidpoint = (from, to) => {
|
|
40
|
+
const dx = to.x - from.x;
|
|
41
|
+
const dy = to.y - from.y;
|
|
42
|
+
const dist = Math.sqrt(dx * dx + dy * dy);
|
|
43
|
+
const bend = Math.min(dist * 0.35, 80);
|
|
44
|
+
const mx = (from.x + to.x) / 2;
|
|
45
|
+
const my = (from.y + to.y) / 2;
|
|
46
|
+
const cpx = dist > 0 ? mx - (dy / dist) * bend : mx;
|
|
47
|
+
const cpy = dist > 0 ? my + (dx / dist) * bend : my;
|
|
48
|
+
const t = 0.5, mt = 0.5;
|
|
49
|
+
return {
|
|
50
|
+
x: mt * mt * from.x + 2 * mt * t * cpx + t * t * to.x,
|
|
51
|
+
y: mt * mt * from.y + 2 * mt * t * cpy + t * t * to.y,
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
export const ConnectionLayer = ({ edges, selectedEdge, connecting, draggingAnchor, mousePos, isConnectEdge, isSelectNode, getNodeById, onSelectEdge, onDeleteEdge, onStartDragWaypoint, onInsertWaypoint, onRemoveWaypoint, onStartDragAnchor, selectedNodeId, }) => {
|
|
55
|
+
const [hoveredEdge, setHoveredEdge] = useState(null);
|
|
56
|
+
console.log({ selectedEdge });
|
|
57
|
+
const nodeHighlightMap = useMemo(() => {
|
|
58
|
+
if (!selectedEdge)
|
|
59
|
+
return new Map();
|
|
60
|
+
const sel = edges.find((e) => e.id === selectedEdge);
|
|
61
|
+
if (!sel)
|
|
62
|
+
return new Map();
|
|
63
|
+
return floodFill([sel.from, sel.to], edges);
|
|
64
|
+
}, [selectedEdge, edges]);
|
|
65
|
+
const nodeHighlightMapByNode = useMemo(() => {
|
|
66
|
+
if (selectedNodeId) {
|
|
67
|
+
return floodFill([selectedNodeId], edges);
|
|
68
|
+
}
|
|
69
|
+
if (selectedEdge) {
|
|
70
|
+
const sel = edges.find((e) => e.id === selectedEdge);
|
|
71
|
+
if (!sel)
|
|
72
|
+
return new Map();
|
|
73
|
+
return floodFill([sel.from, sel.to], edges);
|
|
74
|
+
}
|
|
75
|
+
return new Map();
|
|
76
|
+
}, [selectedEdge, selectedNodeId, edges]);
|
|
77
|
+
const edgePaths = useMemo(() => {
|
|
78
|
+
const map = new Map();
|
|
79
|
+
edges.forEach((edge) => {
|
|
80
|
+
var _a, _b, _c;
|
|
81
|
+
const fromNode = getNodeById(edge.from);
|
|
82
|
+
const toNode = getNodeById(edge.to);
|
|
83
|
+
if (!fromNode || !toNode)
|
|
84
|
+
return;
|
|
85
|
+
const isDraggingFrom = (draggingAnchor === null || draggingAnchor === void 0 ? void 0 : draggingAnchor.edgeId) === edge.id && draggingAnchor.side === "from";
|
|
86
|
+
const isDraggingTo = (draggingAnchor === null || draggingAnchor === void 0 ? void 0 : draggingAnchor.edgeId) === edge.id && draggingAnchor.side === "to";
|
|
87
|
+
const fromPos = isDraggingFrom
|
|
88
|
+
? mousePos
|
|
89
|
+
: (_a = edge.fromPos) !== null && _a !== void 0 ? _a : getRectEdge(fromNode, toNode, fromNode.width, fromNode.height);
|
|
90
|
+
const toPos = isDraggingTo
|
|
91
|
+
? mousePos
|
|
92
|
+
: (_b = edge.toPos) !== null && _b !== void 0 ? _b : getRectEdge(toNode, fromNode, toNode.width, toNode.height);
|
|
93
|
+
const pts = computePoints(fromPos, toPos, (_c = edge.waypoints) !== null && _c !== void 0 ? _c : []);
|
|
94
|
+
const pathD = buildPath(pts);
|
|
95
|
+
const mid = quadraticMidpoint(fromPos, toPos);
|
|
96
|
+
map.set(edge.id, {
|
|
97
|
+
pathD,
|
|
98
|
+
allPoints: pts,
|
|
99
|
+
fromPos,
|
|
100
|
+
toPos,
|
|
101
|
+
midX: mid.x,
|
|
102
|
+
midY: mid.y,
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
return map;
|
|
106
|
+
}, [edges, getNodeById, draggingAnchor, mousePos]);
|
|
107
|
+
return (<g id="connection-layer">
|
|
108
|
+
{/* Node highlight flood fill */}
|
|
109
|
+
{Array.from(nodeHighlightMap.entries()).map(([nodeId, level]) => {
|
|
110
|
+
var _a, _b, _c;
|
|
111
|
+
const node = getNodeById(nodeId);
|
|
112
|
+
if (!node)
|
|
113
|
+
return null;
|
|
114
|
+
const w = (_a = node.width) !== null && _a !== void 0 ? _a : NODE_WIDTH;
|
|
115
|
+
const h = (_b = node.height) !== null && _b !== void 0 ? _b : NODE_HEIGHT;
|
|
116
|
+
const rotation = (_c = node.rotation) !== null && _c !== void 0 ? _c : 0;
|
|
117
|
+
const color = getLevelColor(level);
|
|
118
|
+
const padding = 4;
|
|
119
|
+
return (<g key={`highlight-${nodeId}`} transform={`translate(${node.x}, ${node.y}) rotate(${rotation})`} style={{ pointerEvents: "none" }}>
|
|
120
|
+
<rect x={-w / 2 - padding} y={-h / 2 - padding} width={w + padding * 2} height={h + padding * 2} fill="none" stroke={color} strokeWidth={8} rx={5} opacity={0.08}/>
|
|
121
|
+
<rect x={-w / 2 - padding} y={-h / 2 - padding} width={w + padding * 2} height={h + padding * 2} fill="none" stroke={color} strokeWidth={level === 0 ? 2.5 : 1.5} strokeDasharray={level === 0 ? "none" : "5 3"} rx={5} opacity={level === 0 ? 1 : 0.75}/>
|
|
122
|
+
<g transform={`translate(${w / 2 + padding - 2}, ${-h / 2 - padding})`}>
|
|
123
|
+
<circle r={7} fill={color} opacity={0.9}/>
|
|
124
|
+
<text textAnchor="middle" dominantBaseline="middle" fill="white" fontSize={7} fontFamily="monospace" fontWeight={700} style={{ userSelect: "none" }}>
|
|
125
|
+
{level}
|
|
126
|
+
</text>
|
|
127
|
+
</g>
|
|
128
|
+
</g>);
|
|
129
|
+
})}
|
|
130
|
+
|
|
131
|
+
{Array.from(nodeHighlightMapByNode.entries()).map(([nodeId, level]) => {
|
|
132
|
+
var _a, _b, _c;
|
|
133
|
+
const node = getNodeById(nodeId);
|
|
134
|
+
if (!node)
|
|
135
|
+
return null;
|
|
136
|
+
const w = (_a = node.width) !== null && _a !== void 0 ? _a : NODE_WIDTH;
|
|
137
|
+
const h = (_b = node.height) !== null && _b !== void 0 ? _b : NODE_HEIGHT;
|
|
138
|
+
const rotation = (_c = node.rotation) !== null && _c !== void 0 ? _c : 0;
|
|
139
|
+
const color = getLevelColor(level);
|
|
140
|
+
const padding = 4;
|
|
141
|
+
return (<g key={`highlight-${nodeId}`} transform={`translate(${node.x}, ${node.y}) rotate(${rotation})`} style={{ pointerEvents: "none" }}>
|
|
142
|
+
<rect x={-w / 2 - padding} y={-h / 2 - padding} width={w + padding * 2} height={h + padding * 2} fill="none" stroke={color} strokeWidth={8} rx={5} opacity={0.08}/>
|
|
143
|
+
<rect x={-w / 2 - padding} y={-h / 2 - padding} width={w + padding * 2} height={h + padding * 2} fill="none" stroke={color} strokeWidth={level === 0 ? 2.5 : 1.5} strokeDasharray={level === 0 ? "none" : "5 3"} rx={5} opacity={level === 0 ? 1 : 0.75}/>
|
|
144
|
+
<g transform={`translate(${w / 2 + padding - 2}, ${-h / 2 - padding})`}>
|
|
145
|
+
<circle r={7} fill={color} opacity={0.9}/>
|
|
146
|
+
<text textAnchor="middle" dominantBaseline="middle" fill="white" fontSize={7} fontFamily="monospace" fontWeight={700} style={{ userSelect: "none" }}>
|
|
147
|
+
{level}
|
|
148
|
+
</text>
|
|
149
|
+
</g>
|
|
150
|
+
</g>);
|
|
151
|
+
})}
|
|
152
|
+
|
|
153
|
+
{/* Edges */}
|
|
154
|
+
{edges.map((edge) => {
|
|
155
|
+
var _a;
|
|
156
|
+
const ep = edgePaths.get(edge.id);
|
|
157
|
+
if (!ep)
|
|
158
|
+
return null;
|
|
159
|
+
const { pathD, allPoints, fromPos, toPos, midX, midY } = ep;
|
|
160
|
+
const isSel = selectedEdge === edge.id;
|
|
161
|
+
const isHov = hoveredEdge === edge.id;
|
|
162
|
+
const fromLevel = nodeHighlightMap.get(edge.from);
|
|
163
|
+
const toLevel = nodeHighlightMap.get(edge.to);
|
|
164
|
+
const isInNetwork = fromLevel !== undefined && toLevel !== undefined;
|
|
165
|
+
console.log({ isInNetwork, fromLevel, toLevel }, selectedEdge, !isSel && !isInNetwork);
|
|
166
|
+
const networkColor = isInNetwork
|
|
167
|
+
? getLevelColor(Math.max(fromLevel, toLevel))
|
|
168
|
+
: "#38bdf8";
|
|
169
|
+
const isDraggingFrom = (draggingAnchor === null || draggingAnchor === void 0 ? void 0 : draggingAnchor.edgeId) === edge.id && draggingAnchor.side === "from";
|
|
170
|
+
const isDraggingTo = (draggingAnchor === null || draggingAnchor === void 0 ? void 0 : draggingAnchor.edgeId) === edge.id && draggingAnchor.side === "to";
|
|
171
|
+
return (<g key={edge.id}>
|
|
172
|
+
{/* Hit area */}
|
|
173
|
+
<path d={pathD} stroke="transparent" strokeWidth={14} fill="none" style={{ cursor: "pointer" }} onClick={(e) => {
|
|
174
|
+
e.stopPropagation();
|
|
175
|
+
onSelectEdge(edge.id);
|
|
176
|
+
}} onMouseEnter={() => setHoveredEdge(edge.id)} onMouseLeave={() => setHoveredEdge(null)}/>
|
|
177
|
+
|
|
178
|
+
{/* Glow */}
|
|
179
|
+
{(isSel || isHov) && (<path d={pathD} stroke={isSel ? "#a78bfa" : "#38bdf8"} strokeWidth={8} fill="none" opacity={isSel ? 0.12 : 0.06} style={{ pointerEvents: "none" }}/>)}
|
|
180
|
+
|
|
181
|
+
{/* Curve */}
|
|
182
|
+
<path d={pathD} stroke={isSel
|
|
183
|
+
? "#a78bfa"
|
|
184
|
+
: isInNetwork && selectedEdge
|
|
185
|
+
? networkColor
|
|
186
|
+
: "#38bdf8"} strokeWidth={isSel ? 2 : isHov ? 2 : 1.5} fill="none" opacity={selectedEdge && !isSel && !isInNetwork ? 0.25 : 0.9} strokeLinecap="round" style={{ pointerEvents: "none" }}/>
|
|
187
|
+
|
|
188
|
+
{/* FROM dot */}
|
|
189
|
+
{isSel && (<g>
|
|
190
|
+
{isDraggingFrom && (<circle cx={fromPos.x} cy={fromPos.y} r={12} fill="#38bdf8" opacity={0.15} style={{ pointerEvents: "none" }}/>)}
|
|
191
|
+
<circle cx={fromPos.x} cy={fromPos.y} r={10} fill="transparent" style={{ cursor: "grab" }} onMouseDown={(e) => {
|
|
192
|
+
e.stopPropagation();
|
|
193
|
+
onStartDragAnchor(e, edge.id, "from");
|
|
194
|
+
}}/>
|
|
195
|
+
<circle cx={fromPos.x} cy={fromPos.y} r={6} fill={isDraggingFrom ? "#a78bfa" : "#38bdf8"} stroke="#0f172a" strokeWidth={1.5} style={{ pointerEvents: "none" }}/>
|
|
196
|
+
<circle cx={fromPos.x} cy={fromPos.y} r={2.5} fill="#0f172a" style={{ pointerEvents: "none" }}/>
|
|
197
|
+
</g>)}
|
|
198
|
+
|
|
199
|
+
{/* TO dot */}
|
|
200
|
+
{isSel && (<g>
|
|
201
|
+
{isDraggingTo && (<circle cx={toPos.x} cy={toPos.y} r={12} fill="#22c55e" opacity={0.15} style={{ pointerEvents: "none" }}/>)}
|
|
202
|
+
<circle cx={toPos.x} cy={toPos.y} r={10} fill="transparent" style={{ cursor: "grab" }} onMouseDown={(e) => {
|
|
203
|
+
e.stopPropagation();
|
|
204
|
+
onStartDragAnchor(e, edge.id, "to");
|
|
205
|
+
}}/>
|
|
206
|
+
<circle cx={toPos.x} cy={toPos.y} r={6} fill={isDraggingTo ? "#a78bfa" : "#22c55e"} stroke="#0f172a" strokeWidth={1.5} style={{ pointerEvents: "none" }}/>
|
|
207
|
+
<circle cx={toPos.x} cy={toPos.y} r={2.5} fill="#0f172a" style={{ pointerEvents: "none" }}/>
|
|
208
|
+
</g>)}
|
|
209
|
+
|
|
210
|
+
{/* Waypoints */}
|
|
211
|
+
{((_a = edge.waypoints) !== null && _a !== void 0 ? _a : []).map((wp, i) => (<g key={`wp-${i}`}>
|
|
212
|
+
<circle cx={wp.x} cy={wp.y} r={12} fill="transparent" style={{ cursor: "grab" }} onMouseDown={(e) => onStartDragWaypoint(e, edge.id, i)} onContextMenu={(e) => onRemoveWaypoint(e, edge.id, i)}/>
|
|
213
|
+
<circle cx={wp.x} cy={wp.y} r={isSel ? 8 : 5} fill={isSel ? "#1e1b2e" : "#0f172a"} stroke={isSel ? "#a78bfa" : "#38bdf8"} strokeWidth={isSel ? 2 : 1.2} style={{ pointerEvents: "none" }}/>
|
|
214
|
+
<circle cx={wp.x} cy={wp.y} r={isSel ? 3 : 2} fill={isSel ? "#a78bfa" : "#38bdf8"} style={{ pointerEvents: "none" }}/>
|
|
215
|
+
</g>))}
|
|
216
|
+
|
|
217
|
+
{/* Midpoint insert handles */}
|
|
218
|
+
{isSel &&
|
|
219
|
+
isConnectEdge &&
|
|
220
|
+
allPoints.slice(0, -1).map((pt, i) => {
|
|
221
|
+
var _a;
|
|
222
|
+
const next = allPoints[i + 1];
|
|
223
|
+
const mx = snap((pt.x + next.x) / 2);
|
|
224
|
+
const my = snap((pt.y + next.y) / 2);
|
|
225
|
+
const tooClose = ((_a = edge.waypoints) !== null && _a !== void 0 ? _a : []).some((wp) => Math.abs(wp.x - mx) < GRID_SIZE &&
|
|
226
|
+
Math.abs(wp.y - my) < GRID_SIZE);
|
|
227
|
+
if (tooClose)
|
|
228
|
+
return null;
|
|
229
|
+
return (<g key={`mid-${i}`}>
|
|
230
|
+
<circle cx={mx} cy={my} r={10} fill="transparent" style={{ cursor: "crosshair" }} onMouseDown={(e) => onInsertWaypoint(e, edge.id, i, mx, my)}/>
|
|
231
|
+
<circle cx={mx} cy={my} r={4} fill="#1e1b2e" stroke="#a78bfa" strokeWidth={1} strokeDasharray="2 2" style={{ pointerEvents: "none" }}/>
|
|
232
|
+
<circle cx={mx} cy={my} r={1.5} fill="#a78bfa" style={{ pointerEvents: "none" }}/>
|
|
233
|
+
</g>);
|
|
234
|
+
})}
|
|
235
|
+
|
|
236
|
+
{/* DEL badge */}
|
|
237
|
+
{isSel && isConnectEdge && (<g onClick={(e) => {
|
|
238
|
+
e.stopPropagation();
|
|
239
|
+
onDeleteEdge(edge.id);
|
|
240
|
+
}} style={{ cursor: "pointer" }}>
|
|
241
|
+
<rect x={midX - 16} y={midY - 10} width={32} height={18} rx={4} fill="#1e1b2e" stroke="#a78bfa" strokeWidth={1} opacity={0.95}/>
|
|
242
|
+
<text x={midX} y={midY} textAnchor="middle" dominantBaseline="middle" fill="#a78bfa" fontSize={9} fontFamily="monospace" fontWeight={600}>
|
|
243
|
+
DEL
|
|
244
|
+
</text>
|
|
245
|
+
</g>)}
|
|
246
|
+
</g>);
|
|
247
|
+
})}
|
|
248
|
+
|
|
249
|
+
{/* Preview saat connecting */}
|
|
250
|
+
{connecting &&
|
|
251
|
+
(() => {
|
|
252
|
+
const pts = computePoints(connecting.fromPos, mousePos, []);
|
|
253
|
+
const pathD = buildPath(pts);
|
|
254
|
+
return (<g>
|
|
255
|
+
<circle cx={connecting.fromPos.x} cy={connecting.fromPos.y} r={4} fill="#a78bfa" stroke="#0f172a" strokeWidth={0.8} opacity={0.9} style={{ pointerEvents: "none" }}/>
|
|
256
|
+
<path d={pathD} stroke="#a78bfa" strokeWidth={1.5} fill="none" strokeDasharray="6 3" strokeLinecap="round" opacity={0.8} style={{ pointerEvents: "none" }}/>
|
|
257
|
+
</g>);
|
|
258
|
+
})()}
|
|
259
|
+
|
|
260
|
+
{/* Hint drag anchor */}
|
|
261
|
+
{draggingAnchor && (<text x={mousePos.x + 14} y={mousePos.y - 8} fill="#a78bfa" fontSize={9} fontFamily="monospace" opacity={0.8} style={{ pointerEvents: "none", userSelect: "none" }}>
|
|
262
|
+
klik node tujuan
|
|
263
|
+
</text>)}
|
|
264
|
+
</g>);
|
|
265
|
+
};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import React, { CSSProperties, SVGAttributes } from "react";
|
|
2
|
+
import { ReactZoomPanPinchRef, ReactZoomPanPinchProps, ReactZoomPanPinchContentRef } from "react-zoom-pan-pinch";
|
|
3
|
+
import { PropertiesProps } from "../../dto/table";
|
|
4
|
+
import { EventHandleType } from "../../dto/event-handler";
|
|
5
|
+
import { EdgeType } from "./utils";
|
|
6
|
+
export type TableGhost = {
|
|
7
|
+
table: PropertiesProps;
|
|
8
|
+
event: EventHandleType;
|
|
9
|
+
};
|
|
10
|
+
export type TableMatchKey = {
|
|
11
|
+
key: string | number;
|
|
12
|
+
properties?: PropertiesProps;
|
|
13
|
+
className?: string;
|
|
14
|
+
};
|
|
15
|
+
export type TableMatchEvent = {
|
|
16
|
+
event: EventHandleType;
|
|
17
|
+
properties: PropertiesProps;
|
|
18
|
+
};
|
|
19
|
+
export type ComponentProps<T = undefined> = T extends undefined ? PropertiesProps : Omit<PropertiesProps, keyof T> & T;
|
|
20
|
+
export type OnCurrentStateChange<TMeta = undefined> = ({ components, extraComponents, background, boundingBox, }: {
|
|
21
|
+
components: ComponentProps<TMeta>[];
|
|
22
|
+
extraComponents: ComponentProps[];
|
|
23
|
+
background: string;
|
|
24
|
+
boundingBox: PropertiesProps | null;
|
|
25
|
+
}) => void;
|
|
26
|
+
export type TransformProps = React.ForwardRefExoticComponent<Omit<ReactZoomPanPinchProps, "ref"> & React.RefAttributes<ReactZoomPanPinchContentRef>>;
|
|
27
|
+
export type RefLayerView = {
|
|
28
|
+
svgRef: SVGSVGElement;
|
|
29
|
+
transformRef: ReactZoomPanPinchRef;
|
|
30
|
+
containerRef: HTMLDivElement;
|
|
31
|
+
tableGhost: SVGGElement;
|
|
32
|
+
hoverUnderghost: ComponentProps;
|
|
33
|
+
};
|
|
34
|
+
export type TypeActionProps<TMeta = undefined> = {
|
|
35
|
+
targetTable: ComponentProps<TMeta>;
|
|
36
|
+
sourceTable: ComponentProps<TMeta>;
|
|
37
|
+
};
|
|
38
|
+
export interface LayerViewProps<TMeta = undefined> {
|
|
39
|
+
componentProps?: ComponentProps<TMeta>[];
|
|
40
|
+
extraComponentProps?: ComponentProps[];
|
|
41
|
+
onSelectComponent?: (component: ComponentProps<TMeta>) => void;
|
|
42
|
+
onDoubleClick?: (component: ComponentProps<TMeta>) => void;
|
|
43
|
+
mappingKey?: string;
|
|
44
|
+
tableMatchKey?: TableMatchKey[];
|
|
45
|
+
eventMatchTable?: TableMatchEvent[];
|
|
46
|
+
statusKey?: string;
|
|
47
|
+
defaultBackground?: string;
|
|
48
|
+
transformProps?: ReactZoomPanPinchProps;
|
|
49
|
+
containerProps?: React.HTMLAttributes<HTMLDivElement>;
|
|
50
|
+
svgProps?: SVGAttributes<SVGSVGElement>;
|
|
51
|
+
ghostAttributes?: SVGAttributes<SVGGElement>;
|
|
52
|
+
iconTags?: {
|
|
53
|
+
icon: React.JSX.Element;
|
|
54
|
+
key: string;
|
|
55
|
+
}[];
|
|
56
|
+
privilegedTags?: {
|
|
57
|
+
key: string;
|
|
58
|
+
items: string[];
|
|
59
|
+
}[];
|
|
60
|
+
tooltipProps?: {
|
|
61
|
+
className?: string;
|
|
62
|
+
style?: CSSProperties;
|
|
63
|
+
minWidth?: number;
|
|
64
|
+
children: React.ReactNode;
|
|
65
|
+
};
|
|
66
|
+
dragTableBlockKey?: {
|
|
67
|
+
key: string;
|
|
68
|
+
value: string | number | null;
|
|
69
|
+
}[];
|
|
70
|
+
onRightClick?: (e: MouseEvent, component: ComponentProps<TMeta>) => void;
|
|
71
|
+
allowTooltip?: boolean;
|
|
72
|
+
onDrop?: (e: React.MouseEvent<SVGSVGElement>, component: TypeActionProps<TMeta>) => void;
|
|
73
|
+
onSwitch?: (e: MouseEvent, component: TypeActionProps<TMeta>) => void;
|
|
74
|
+
refs?: React.ForwardedRef<RefLayerView>;
|
|
75
|
+
viewStyles?: {
|
|
76
|
+
paddingTop?: number;
|
|
77
|
+
paddingLeft?: number;
|
|
78
|
+
paddingRight?: number;
|
|
79
|
+
paddingBottom?: number;
|
|
80
|
+
};
|
|
81
|
+
loadingRender?: {
|
|
82
|
+
state: boolean;
|
|
83
|
+
element: React.JSX.Element;
|
|
84
|
+
};
|
|
85
|
+
defaultBoundingBox?: PropertiesProps;
|
|
86
|
+
viewOnly?: boolean;
|
|
87
|
+
actionPrivileged?: {
|
|
88
|
+
select?: boolean;
|
|
89
|
+
move?: boolean;
|
|
90
|
+
switch?: boolean;
|
|
91
|
+
drop?: boolean;
|
|
92
|
+
rightClick?: boolean;
|
|
93
|
+
double?: boolean;
|
|
94
|
+
};
|
|
95
|
+
onEdgesChange?: (edges: EdgeType[], table: PropertiesProps[]) => void;
|
|
96
|
+
keyNode?: string;
|
|
97
|
+
isConnectEdge?: boolean;
|
|
98
|
+
isSelectNode?: boolean;
|
|
99
|
+
onMakeSelection?: (component: ComponentProps<TMeta>[]) => void;
|
|
100
|
+
}
|
|
101
|
+
declare const LayerView: <TMeta>(props: LayerViewProps<TMeta>) => import("react/jsx-runtime").JSX.Element;
|
|
102
|
+
export default LayerView;
|