seat-editor 3.6.25 → 3.6.27
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/graph-view-new/page.js +9 -2
- package/dist/app/graph-view-new/page.jsx +9 -2
- package/dist/features/view-only-5/connect-handle.d.ts +18 -0
- package/dist/features/view-only-5/connect-handle.js +13 -15
- package/dist/features/view-only-5/connect-handle.jsx +13 -15
- package/dist/features/view-only-5/connection-layer.d.ts +4 -0
- package/dist/features/view-only-5/connection-layer.js +58 -9
- package/dist/features/view-only-5/connection-layer.jsx +58 -9
- package/dist/features/view-only-5/index.d.ts +4 -0
- package/dist/features/view-only-5/index.js +24 -4
- package/dist/features/view-only-5/index.jsx +24 -4
- package/dist/features/view-only-5/use-connection-graph.d.ts +7 -1
- package/dist/features/view-only-5/use-connection-graph.js +87 -4
- package/dist/features/view-only-5/utils.d.ts +2 -0
- package/package.json +1 -1
|
@@ -17,7 +17,8 @@ export default function GraphView() {
|
|
|
17
17
|
double: false,
|
|
18
18
|
selection: false,
|
|
19
19
|
selectNode: false,
|
|
20
|
-
connectingNode:
|
|
20
|
+
connectingNode: true,
|
|
21
|
+
dragTransferTable: false
|
|
21
22
|
});
|
|
22
23
|
const [isSelectNode, setIsSelectNode] = useState(false);
|
|
23
24
|
const [sections, setSections] = useState([
|
|
@@ -105,6 +106,10 @@ export default function GraphView() {
|
|
|
105
106
|
key: "connectingNode",
|
|
106
107
|
name: "Connecting Node",
|
|
107
108
|
},
|
|
109
|
+
{
|
|
110
|
+
key: "dragTransferTable",
|
|
111
|
+
name: "Drag Transfer Table",
|
|
112
|
+
}
|
|
108
113
|
];
|
|
109
114
|
const [dataDrag, setDataDrag] = useState(null);
|
|
110
115
|
console.log({ dataDrag });
|
|
@@ -164,5 +169,7 @@ export default function GraphView() {
|
|
|
164
169
|
selection: selection
|
|
165
170
|
}, onRightClick: (e, data) => {
|
|
166
171
|
console.log({ e, data });
|
|
167
|
-
}, allowTooltip: true
|
|
172
|
+
}, allowTooltip: true, onHoldTable: (e, data) => {
|
|
173
|
+
console.log({ e, data });
|
|
174
|
+
}, showConnection: true }), _jsxs("div", { className: "w-1/5 p-4", onMouseMove: handleMouseMove, onMouseLeave: handleMouseLeave, children: [_jsx("div", { id: "table" }), _jsxs("div", { className: "rounded-lg bg-white p-4", children: [_jsx("h1", { className: "text-2xl font-bold", children: "Section" }), sections.map((section) => (_jsxs("div", { className: clsx("font-bold text-white rounded-md p-2 cursor-pointer", sectionActive === section.id && "!bg-blue-500"), style: { backgroundColor: section.color }, onClick: () => setSectionActive(section.id), children: [_jsx("h2", { className: "text-lg", children: section.name }), section.items.length > 0 && (_jsx("ul", { className: "list-disc pl-5 bg-opacity-50 bg-white p-2 rounded ", children: section.items.map((item) => (_jsx("li", { children: item.name }, item.id))) }))] }, section.id)))] })] }), _jsx("div", { className: "w-1/5 p-4", children: _jsx("div", { className: "rounded-lg bg-white p-4", children: _jsx("h1", { className: "text-2xl font-bold", children: "Nodes" }) }) })] }) }));
|
|
168
175
|
}
|
|
@@ -16,7 +16,8 @@ export default function GraphView() {
|
|
|
16
16
|
double: false,
|
|
17
17
|
selection: false,
|
|
18
18
|
selectNode: false,
|
|
19
|
-
connectingNode:
|
|
19
|
+
connectingNode: true,
|
|
20
|
+
dragTransferTable: false
|
|
20
21
|
});
|
|
21
22
|
const [isSelectNode, setIsSelectNode] = useState(false);
|
|
22
23
|
const [sections, setSections] = useState([
|
|
@@ -104,6 +105,10 @@ export default function GraphView() {
|
|
|
104
105
|
key: "connectingNode",
|
|
105
106
|
name: "Connecting Node",
|
|
106
107
|
},
|
|
108
|
+
{
|
|
109
|
+
key: "dragTransferTable",
|
|
110
|
+
name: "Drag Transfer Table",
|
|
111
|
+
}
|
|
107
112
|
];
|
|
108
113
|
const [dataDrag, setDataDrag] = useState(null);
|
|
109
114
|
console.log({ dataDrag });
|
|
@@ -170,7 +175,9 @@ export default function GraphView() {
|
|
|
170
175
|
selection: selection
|
|
171
176
|
}} onRightClick={(e, data) => {
|
|
172
177
|
console.log({ e, data });
|
|
173
|
-
}} allowTooltip={true}
|
|
178
|
+
}} allowTooltip={true} onHoldTable={(e, data) => {
|
|
179
|
+
console.log({ e, data });
|
|
180
|
+
}} showConnection={true}/>
|
|
174
181
|
<div className="w-1/5 p-4" onMouseMove={handleMouseMove} onMouseLeave={handleMouseLeave}>
|
|
175
182
|
<div id="table"/>
|
|
176
183
|
<div className="rounded-lg bg-white p-4">
|
|
@@ -11,10 +11,12 @@ type Props = {
|
|
|
11
11
|
onStartConnect: (nodeId: string, clickPos: {
|
|
12
12
|
x: number;
|
|
13
13
|
y: number;
|
|
14
|
+
name: string;
|
|
14
15
|
}) => void;
|
|
15
16
|
onEndConnect: (nodeId: string, clickPos: {
|
|
16
17
|
x: number;
|
|
17
18
|
y: number;
|
|
19
|
+
name: string;
|
|
18
20
|
}) => void;
|
|
19
21
|
isConnectEdge?: boolean;
|
|
20
22
|
onSelectNode: (nodeId: string) => void;
|
|
@@ -30,8 +32,24 @@ type Props = {
|
|
|
30
32
|
fromPos: {
|
|
31
33
|
x: number;
|
|
32
34
|
y: number;
|
|
35
|
+
name: string;
|
|
33
36
|
};
|
|
34
37
|
} | null;
|
|
38
|
+
showConnection?: boolean;
|
|
39
|
+
};
|
|
40
|
+
export declare const getLocalAnchors: (w: number, h: number) => {
|
|
41
|
+
x: number;
|
|
42
|
+
y: number;
|
|
43
|
+
name: string;
|
|
44
|
+
}[];
|
|
45
|
+
export declare const nearestAnchor: (lx: number, ly: number, anchors: {
|
|
46
|
+
x: number;
|
|
47
|
+
y: number;
|
|
48
|
+
name: string;
|
|
49
|
+
}[]) => {
|
|
50
|
+
x: number;
|
|
51
|
+
y: number;
|
|
52
|
+
name: string;
|
|
35
53
|
};
|
|
36
54
|
export declare const ConnectHandle: React.FC<Props>;
|
|
37
55
|
export {};
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useState } from "react";
|
|
3
3
|
// 4 titik per sisi dalam local space
|
|
4
|
-
const getLocalAnchors = (w, h) => {
|
|
4
|
+
export const getLocalAnchors = (w, h) => {
|
|
5
5
|
const hw = w / 2;
|
|
6
6
|
const hh = h / 2;
|
|
7
7
|
return [
|
|
8
|
-
{ x: 0, y: -hh }, //
|
|
9
|
-
{ x: hw, y: 0 }, //
|
|
10
|
-
{ x: 0, y: hh }, //
|
|
11
|
-
{ x: -hw, y: 0 }, //
|
|
8
|
+
{ x: 0, y: -hh, name: "top" }, // index 0
|
|
9
|
+
{ x: hw, y: 0, name: "right" }, // index 1
|
|
10
|
+
{ x: 0, y: hh, name: "bottom" }, // index 2
|
|
11
|
+
{ x: -hw, y: 0, name: "left" }, // index 3
|
|
12
12
|
];
|
|
13
13
|
};
|
|
14
|
-
const nearestAnchor = (lx, ly, anchors) => {
|
|
14
|
+
export const nearestAnchor = (lx, ly, anchors) => {
|
|
15
15
|
let best = anchors[0];
|
|
16
16
|
let bestD = Infinity;
|
|
17
17
|
for (const a of anchors) {
|
|
@@ -21,9 +21,9 @@ const nearestAnchor = (lx, ly, anchors) => {
|
|
|
21
21
|
best = a;
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
|
-
return best;
|
|
24
|
+
return best; // Sekarang mengembalikan objek lengkap termasuk property 'name'
|
|
25
25
|
};
|
|
26
|
-
export const ConnectHandle = ({ cx, cy, width, height, nodeId, rotation = 0, isConnecting, isDraggingAnchor, onStartConnect, onEndConnect, isConnectEdge, onSelectNode, isSelectNode, onSelectEdge, edges, connecting, }) => {
|
|
26
|
+
export const ConnectHandle = ({ cx, cy, width, height, nodeId, rotation = 0, isConnecting, isDraggingAnchor, onStartConnect, onEndConnect, isConnectEdge, onSelectNode, isSelectNode, onSelectEdge, edges, connecting, showConnection }) => {
|
|
27
27
|
const hw = width / 2;
|
|
28
28
|
const hh = height / 2;
|
|
29
29
|
const [hovered, setHovered] = useState(false);
|
|
@@ -45,24 +45,24 @@ export const ConnectHandle = ({ cx, cy, width, height, nodeId, rotation = 0, isC
|
|
|
45
45
|
y: dx * Math.sin(rad) + dy * Math.cos(rad),
|
|
46
46
|
};
|
|
47
47
|
};
|
|
48
|
-
const toWorld = (lx, ly) => {
|
|
48
|
+
const toWorld = (lx, ly, name) => {
|
|
49
49
|
const rad = (rotation * Math.PI) / 180;
|
|
50
50
|
return {
|
|
51
51
|
x: cx + lx * Math.cos(rad) - ly * Math.sin(rad),
|
|
52
52
|
y: cy + lx * Math.sin(rad) + ly * Math.cos(rad),
|
|
53
|
+
name,
|
|
53
54
|
};
|
|
54
55
|
};
|
|
55
56
|
useEffect(() => {
|
|
56
57
|
if (!isActiveSelectEdge) {
|
|
57
58
|
onSelectEdge && onSelectEdge("");
|
|
58
|
-
onSelectEdge && onSelectNode("");
|
|
59
59
|
}
|
|
60
60
|
}, [isActiveSelectEdge]);
|
|
61
61
|
const handlePointerDown = (e) => {
|
|
62
62
|
e.stopPropagation();
|
|
63
63
|
const local = toLocalPos(e);
|
|
64
64
|
const snapped = nearestAnchor(local.x, local.y, anchors);
|
|
65
|
-
const worldPos = toWorld(snapped.x, snapped.y);
|
|
65
|
+
const worldPos = toWorld(snapped.x, snapped.y, snapped.name);
|
|
66
66
|
if (isActiveSelectEdge) {
|
|
67
67
|
const findEdge = edges.find((e) => e.from === nodeId || e.to === nodeId);
|
|
68
68
|
onSelectEdge(findEdge === null || findEdge === void 0 ? void 0 : findEdge.id);
|
|
@@ -77,14 +77,12 @@ export const ConnectHandle = ({ cx, cy, width, height, nodeId, rotation = 0, isC
|
|
|
77
77
|
onStartConnect(nodeId, worldPos);
|
|
78
78
|
}
|
|
79
79
|
};
|
|
80
|
+
if (!showConnection)
|
|
81
|
+
return null;
|
|
80
82
|
return (_jsxs("g", { transform: `translate(${cx}, ${cy}) rotate(${rotation})`, children: [_jsx("rect", { x: -hw - 4, y: -hh - 4, width: width + 8, height: height + 8, fill: "transparent", stroke: isActive ? "#a78bfa" : hovered ? "#38bdf8" : "transparent", strokeWidth: isActive ? 2 : 1.5, strokeDasharray: isActive ? "4 2" : "none", rx: 4, style: { pointerEvents: "none" } }), _jsx("rect", { x: -hw - 4, y: -hh - 4, width: width + 8, height: height + 8, fill: "transparent", style: {
|
|
81
83
|
cursor: isConnectEdge ? "crosshair" : "pointer",
|
|
82
84
|
pointerEvents: isConnectEdge ? "all" : "none",
|
|
83
85
|
}, onMouseEnter: () => setHovered(true), onMouseLeave: () => setHovered(false), onPointerDown: (e) => {
|
|
84
|
-
// console.log({ isConnectEdge, isSelectNode });
|
|
85
|
-
// console.log({ isConnectEdge, isSelectNode })
|
|
86
|
-
// if (!isConnectEdge ) return;
|
|
87
|
-
// if (!isSelectNode) return;
|
|
88
86
|
handlePointerDown(e);
|
|
89
87
|
} }), ((hovered && isConnectEdge) || isActive) &&
|
|
90
88
|
anchors.map((a, i) => (_jsx("circle", { cx: a.x, cy: a.y, r: 3, fill: isActive ? "#a78bfa" : "#38bdf8", opacity: 0.5, style: { pointerEvents: "none" } }, i)))] }));
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import React, { useEffect, useState } from "react";
|
|
2
2
|
// 4 titik per sisi dalam local space
|
|
3
|
-
const getLocalAnchors = (w, h) => {
|
|
3
|
+
export const getLocalAnchors = (w, h) => {
|
|
4
4
|
const hw = w / 2;
|
|
5
5
|
const hh = h / 2;
|
|
6
6
|
return [
|
|
7
|
-
{ x: 0, y: -hh }, //
|
|
8
|
-
{ x: hw, y: 0 }, //
|
|
9
|
-
{ x: 0, y: hh }, //
|
|
10
|
-
{ x: -hw, y: 0 }, //
|
|
7
|
+
{ x: 0, y: -hh, name: "top" }, // index 0
|
|
8
|
+
{ x: hw, y: 0, name: "right" }, // index 1
|
|
9
|
+
{ x: 0, y: hh, name: "bottom" }, // index 2
|
|
10
|
+
{ x: -hw, y: 0, name: "left" }, // index 3
|
|
11
11
|
];
|
|
12
12
|
};
|
|
13
|
-
const nearestAnchor = (lx, ly, anchors) => {
|
|
13
|
+
export const nearestAnchor = (lx, ly, anchors) => {
|
|
14
14
|
let best = anchors[0];
|
|
15
15
|
let bestD = Infinity;
|
|
16
16
|
for (const a of anchors) {
|
|
@@ -20,9 +20,9 @@ const nearestAnchor = (lx, ly, anchors) => {
|
|
|
20
20
|
best = a;
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
|
-
return best;
|
|
23
|
+
return best; // Sekarang mengembalikan objek lengkap termasuk property 'name'
|
|
24
24
|
};
|
|
25
|
-
export const ConnectHandle = ({ cx, cy, width, height, nodeId, rotation = 0, isConnecting, isDraggingAnchor, onStartConnect, onEndConnect, isConnectEdge, onSelectNode, isSelectNode, onSelectEdge, edges, connecting, }) => {
|
|
25
|
+
export const ConnectHandle = ({ cx, cy, width, height, nodeId, rotation = 0, isConnecting, isDraggingAnchor, onStartConnect, onEndConnect, isConnectEdge, onSelectNode, isSelectNode, onSelectEdge, edges, connecting, showConnection }) => {
|
|
26
26
|
const hw = width / 2;
|
|
27
27
|
const hh = height / 2;
|
|
28
28
|
const [hovered, setHovered] = useState(false);
|
|
@@ -44,24 +44,24 @@ export const ConnectHandle = ({ cx, cy, width, height, nodeId, rotation = 0, isC
|
|
|
44
44
|
y: dx * Math.sin(rad) + dy * Math.cos(rad),
|
|
45
45
|
};
|
|
46
46
|
};
|
|
47
|
-
const toWorld = (lx, ly) => {
|
|
47
|
+
const toWorld = (lx, ly, name) => {
|
|
48
48
|
const rad = (rotation * Math.PI) / 180;
|
|
49
49
|
return {
|
|
50
50
|
x: cx + lx * Math.cos(rad) - ly * Math.sin(rad),
|
|
51
51
|
y: cy + lx * Math.sin(rad) + ly * Math.cos(rad),
|
|
52
|
+
name,
|
|
52
53
|
};
|
|
53
54
|
};
|
|
54
55
|
useEffect(() => {
|
|
55
56
|
if (!isActiveSelectEdge) {
|
|
56
57
|
onSelectEdge && onSelectEdge("");
|
|
57
|
-
onSelectEdge && onSelectNode("");
|
|
58
58
|
}
|
|
59
59
|
}, [isActiveSelectEdge]);
|
|
60
60
|
const handlePointerDown = (e) => {
|
|
61
61
|
e.stopPropagation();
|
|
62
62
|
const local = toLocalPos(e);
|
|
63
63
|
const snapped = nearestAnchor(local.x, local.y, anchors);
|
|
64
|
-
const worldPos = toWorld(snapped.x, snapped.y);
|
|
64
|
+
const worldPos = toWorld(snapped.x, snapped.y, snapped.name);
|
|
65
65
|
if (isActiveSelectEdge) {
|
|
66
66
|
const findEdge = edges.find((e) => e.from === nodeId || e.to === nodeId);
|
|
67
67
|
onSelectEdge(findEdge === null || findEdge === void 0 ? void 0 : findEdge.id);
|
|
@@ -76,6 +76,8 @@ export const ConnectHandle = ({ cx, cy, width, height, nodeId, rotation = 0, isC
|
|
|
76
76
|
onStartConnect(nodeId, worldPos);
|
|
77
77
|
}
|
|
78
78
|
};
|
|
79
|
+
if (!showConnection)
|
|
80
|
+
return null;
|
|
79
81
|
return (<g transform={`translate(${cx}, ${cy}) rotate(${rotation})`}>
|
|
80
82
|
{/* Border visual */}
|
|
81
83
|
<rect x={-hw - 4} y={-hh - 4} width={width + 8} height={height + 8} fill="transparent" stroke={isActive ? "#a78bfa" : hovered ? "#38bdf8" : "transparent"} strokeWidth={isActive ? 2 : 1.5} strokeDasharray={isActive ? "4 2" : "none"} rx={4} style={{ pointerEvents: "none" }}/>
|
|
@@ -85,10 +87,6 @@ export const ConnectHandle = ({ cx, cy, width, height, nodeId, rotation = 0, isC
|
|
|
85
87
|
cursor: isConnectEdge ? "crosshair" : "pointer",
|
|
86
88
|
pointerEvents: isConnectEdge ? "all" : "none",
|
|
87
89
|
}} onMouseEnter={() => setHovered(true)} onMouseLeave={() => setHovered(false)} onPointerDown={(e) => {
|
|
88
|
-
// console.log({ isConnectEdge, isSelectNode });
|
|
89
|
-
// console.log({ isConnectEdge, isSelectNode })
|
|
90
|
-
// if (!isConnectEdge ) return;
|
|
91
|
-
// if (!isSelectNode) return;
|
|
92
90
|
handlePointerDown(e);
|
|
93
91
|
}}/>
|
|
94
92
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { EdgeType, NodeType } from "./utils";
|
|
3
|
+
import { ComponentProps } from "../view-only-3";
|
|
3
4
|
export type DraggingAnchor = {
|
|
4
5
|
edgeId: string;
|
|
5
6
|
side: "from" | "to";
|
|
@@ -12,6 +13,7 @@ type Props = {
|
|
|
12
13
|
fromPos: {
|
|
13
14
|
x: number;
|
|
14
15
|
y: number;
|
|
16
|
+
name: string;
|
|
15
17
|
};
|
|
16
18
|
} | null;
|
|
17
19
|
draggingAnchor: DraggingAnchor | null;
|
|
@@ -28,6 +30,8 @@ type Props = {
|
|
|
28
30
|
onStartDragAnchor: (e: React.MouseEvent, edgeId: string, side: "from" | "to") => void;
|
|
29
31
|
isConnectEdge: boolean;
|
|
30
32
|
selectedNodeId: string | null;
|
|
33
|
+
showConnection?: boolean;
|
|
34
|
+
renderedElements?: ComponentProps[];
|
|
31
35
|
};
|
|
32
36
|
export declare const ConnectionLayer: React.FC<Props>;
|
|
33
37
|
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useMemo, useState } from "react";
|
|
3
|
-
import { buildPath, getRectEdge, GRID_SIZE, NODE_WIDTH, NODE_HEIGHT, snap, } from "./utils";
|
|
3
|
+
import { buildPath, getRectEdge, GRID_SIZE, NODE_WIDTH, NODE_HEIGHT, snap, rotatePoint, } from "./utils";
|
|
4
4
|
const LEVEL_COLORS = [
|
|
5
5
|
"#22c55e",
|
|
6
6
|
"#f59e0b",
|
|
@@ -52,9 +52,8 @@ const quadraticMidpoint = (from, to) => {
|
|
|
52
52
|
y: mt * mt * from.y + 2 * mt * t * cpy + t * t * to.y,
|
|
53
53
|
};
|
|
54
54
|
};
|
|
55
|
-
export const ConnectionLayer = ({ edges, selectedEdge, connecting, draggingAnchor, mousePos, isConnectEdge, getNodeById, onSelectEdge, onDeleteEdge, onStartDragWaypoint, onInsertWaypoint, onRemoveWaypoint, onStartDragAnchor, selectedNodeId, }) => {
|
|
55
|
+
export const ConnectionLayer = ({ edges, selectedEdge, connecting, draggingAnchor, mousePos, isConnectEdge, getNodeById, onSelectEdge, onDeleteEdge, onStartDragWaypoint, onInsertWaypoint, onRemoveWaypoint, onStartDragAnchor, selectedNodeId, showConnection, renderedElements, }) => {
|
|
56
56
|
const [hoveredEdge, setHoveredEdge] = useState(null);
|
|
57
|
-
// console.log({ selectedEdge})
|
|
58
57
|
const nodeHighlightMap = useMemo(() => {
|
|
59
58
|
if (!selectedEdge)
|
|
60
59
|
return new Map();
|
|
@@ -105,6 +104,18 @@ export const ConnectionLayer = ({ edges, selectedEdge, connecting, draggingAncho
|
|
|
105
104
|
});
|
|
106
105
|
return map;
|
|
107
106
|
}, [edges, getNodeById, draggingAnchor, mousePos]);
|
|
107
|
+
if (!showConnection) {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
// const toLocalPos = ({ cx, cy, rotation }) => {
|
|
111
|
+
// const dx = world.x - cx;
|
|
112
|
+
// const dy = world.y - cy;
|
|
113
|
+
// const rad = -(rotation * Math.PI) / 180;
|
|
114
|
+
// return {
|
|
115
|
+
// x: dx * Math.cos(rad) - dy * Math.sin(rad),
|
|
116
|
+
// y: dx * Math.sin(rad) + dy * Math.cos(rad),
|
|
117
|
+
// };
|
|
118
|
+
// };
|
|
108
119
|
return (_jsxs("g", { id: "connection-layer", children: [Array.from(nodeHighlightMap.entries()).map(([nodeId, level]) => {
|
|
109
120
|
var _a, _b, _c;
|
|
110
121
|
const node = getNodeById(nodeId);
|
|
@@ -143,8 +154,10 @@ export const ConnectionLayer = ({ edges, selectedEdge, connecting, draggingAncho
|
|
|
143
154
|
: "#38bdf8";
|
|
144
155
|
const isDraggingFrom = (draggingAnchor === null || draggingAnchor === void 0 ? void 0 : draggingAnchor.edgeId) === edge.id && draggingAnchor.side === "from";
|
|
145
156
|
const isDraggingTo = (draggingAnchor === null || draggingAnchor === void 0 ? void 0 : draggingAnchor.edgeId) === edge.id && draggingAnchor.side === "to";
|
|
146
|
-
// const currentConnection =
|
|
147
|
-
const isNotRing1 = connecting &&
|
|
157
|
+
// const currentConnection =
|
|
158
|
+
const isNotRing1 = connecting &&
|
|
159
|
+
(connecting === null || connecting === void 0 ? void 0 : connecting.fromId) !== edge.from &&
|
|
160
|
+
(connecting === null || connecting === void 0 ? void 0 : connecting.fromId) !== edge.to;
|
|
148
161
|
return (_jsxs("g", { children: [_jsx("path", { d: pathD, stroke: "transparent", strokeWidth: 14, fill: "none", style: { cursor: "pointer" }, onClick: (e) => {
|
|
149
162
|
e.stopPropagation();
|
|
150
163
|
onSelectEdge(edge.id);
|
|
@@ -152,7 +165,9 @@ export const ConnectionLayer = ({ edges, selectedEdge, connecting, draggingAncho
|
|
|
152
165
|
? "#a78bfa"
|
|
153
166
|
: isInNetwork && selectedEdge
|
|
154
167
|
? networkColor
|
|
155
|
-
: "#38bdf8", strokeWidth: isSel ? 2 : isHov ? 2 : 1.5, fill: "none", opacity: (selectedEdge && !isSel && !isInNetwork) || isNotRing1
|
|
168
|
+
: "#38bdf8", strokeWidth: isSel ? 2 : isHov ? 2 : 1.5, fill: "none", opacity: (selectedEdge && !isSel && !isInNetwork) || isNotRing1
|
|
169
|
+
? 0.2
|
|
170
|
+
: 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) => {
|
|
156
171
|
e.stopPropagation();
|
|
157
172
|
onStartDragAnchor(e, edge.id, "from");
|
|
158
173
|
} }), _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) => {
|
|
@@ -176,9 +191,43 @@ export const ConnectionLayer = ({ edges, selectedEdge, connecting, draggingAncho
|
|
|
176
191
|
}, 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));
|
|
177
192
|
}), connecting &&
|
|
178
193
|
(() => {
|
|
179
|
-
|
|
180
|
-
|
|
194
|
+
const findSourceTarget = renderedElements === null || renderedElements === void 0 ? void 0 : renderedElements.find((el) => el.id === connecting.fromId);
|
|
195
|
+
if (!findSourceTarget)
|
|
196
|
+
return null;
|
|
197
|
+
const { x, y, rotation, width, height } = findSourceTarget;
|
|
198
|
+
const rotated = rotatePoint(width / 2, height / 2, rotation !== null && rotation !== void 0 ? rotation : 0);
|
|
199
|
+
const w = width !== null && width !== void 0 ? width : NODE_WIDTH;
|
|
200
|
+
const h = height !== null && height !== void 0 ? height : NODE_HEIGHT;
|
|
201
|
+
const cx = x + rotated.x;
|
|
202
|
+
const cy = y + rotated.y;
|
|
203
|
+
// 3. Tentukan koordinat local space berdasarkan name/side
|
|
204
|
+
let lx = 0;
|
|
205
|
+
let ly = 0;
|
|
206
|
+
const hw = w / 2;
|
|
207
|
+
const hh = h / 2;
|
|
208
|
+
if (connecting.fromPos.name === "top") {
|
|
209
|
+
lx = 0;
|
|
210
|
+
ly = -hh;
|
|
211
|
+
}
|
|
212
|
+
else if (connecting.fromPos.name === "right") {
|
|
213
|
+
lx = hw;
|
|
214
|
+
ly = 0;
|
|
215
|
+
}
|
|
216
|
+
else if (connecting.fromPos.name === "bottom") {
|
|
217
|
+
lx = 0;
|
|
218
|
+
ly = hh;
|
|
219
|
+
}
|
|
220
|
+
else if (connecting.fromPos.name === "left") {
|
|
221
|
+
lx = -hw;
|
|
222
|
+
ly = 0;
|
|
223
|
+
}
|
|
224
|
+
const rad = (rotation * Math.PI) / 180;
|
|
225
|
+
const fromPos = {
|
|
226
|
+
x: cx + lx * Math.cos(rad) - ly * Math.sin(rad),
|
|
227
|
+
y: cy + lx * Math.sin(rad) + ly * Math.cos(rad),
|
|
228
|
+
};
|
|
229
|
+
const pts = computePoints(fromPos, mousePos, []);
|
|
181
230
|
const pathD = buildPath(pts);
|
|
182
|
-
return (_jsxs("g", { children: [_jsx("circle", { cx:
|
|
231
|
+
return (_jsxs("g", { children: [_jsx("circle", { cx: fromPos === null || fromPos === void 0 ? void 0 : fromPos.x, cy: fromPos === null || fromPos === void 0 ? void 0 : 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" } })] }));
|
|
183
232
|
})(), 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" }))] }));
|
|
184
233
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useMemo, useState } from "react";
|
|
2
|
-
import { buildPath, getRectEdge, GRID_SIZE, NODE_WIDTH, NODE_HEIGHT, snap, } from "./utils";
|
|
2
|
+
import { buildPath, getRectEdge, GRID_SIZE, NODE_WIDTH, NODE_HEIGHT, snap, rotatePoint, } from "./utils";
|
|
3
3
|
const LEVEL_COLORS = [
|
|
4
4
|
"#22c55e",
|
|
5
5
|
"#f59e0b",
|
|
@@ -51,9 +51,8 @@ const quadraticMidpoint = (from, to) => {
|
|
|
51
51
|
y: mt * mt * from.y + 2 * mt * t * cpy + t * t * to.y,
|
|
52
52
|
};
|
|
53
53
|
};
|
|
54
|
-
export const ConnectionLayer = ({ edges, selectedEdge, connecting, draggingAnchor, mousePos, isConnectEdge, getNodeById, onSelectEdge, onDeleteEdge, onStartDragWaypoint, onInsertWaypoint, onRemoveWaypoint, onStartDragAnchor, selectedNodeId, }) => {
|
|
54
|
+
export const ConnectionLayer = ({ edges, selectedEdge, connecting, draggingAnchor, mousePos, isConnectEdge, getNodeById, onSelectEdge, onDeleteEdge, onStartDragWaypoint, onInsertWaypoint, onRemoveWaypoint, onStartDragAnchor, selectedNodeId, showConnection, renderedElements, }) => {
|
|
55
55
|
const [hoveredEdge, setHoveredEdge] = useState(null);
|
|
56
|
-
// console.log({ selectedEdge})
|
|
57
56
|
const nodeHighlightMap = useMemo(() => {
|
|
58
57
|
if (!selectedEdge)
|
|
59
58
|
return new Map();
|
|
@@ -104,6 +103,18 @@ export const ConnectionLayer = ({ edges, selectedEdge, connecting, draggingAncho
|
|
|
104
103
|
});
|
|
105
104
|
return map;
|
|
106
105
|
}, [edges, getNodeById, draggingAnchor, mousePos]);
|
|
106
|
+
if (!showConnection) {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
// const toLocalPos = ({ cx, cy, rotation }) => {
|
|
110
|
+
// const dx = world.x - cx;
|
|
111
|
+
// const dy = world.y - cy;
|
|
112
|
+
// const rad = -(rotation * Math.PI) / 180;
|
|
113
|
+
// return {
|
|
114
|
+
// x: dx * Math.cos(rad) - dy * Math.sin(rad),
|
|
115
|
+
// y: dx * Math.sin(rad) + dy * Math.cos(rad),
|
|
116
|
+
// };
|
|
117
|
+
// };
|
|
107
118
|
return (<g id="connection-layer">
|
|
108
119
|
{/* Node highlight flood fill */}
|
|
109
120
|
{Array.from(nodeHighlightMap.entries()).map(([nodeId, level]) => {
|
|
@@ -167,8 +178,10 @@ export const ConnectionLayer = ({ edges, selectedEdge, connecting, draggingAncho
|
|
|
167
178
|
: "#38bdf8";
|
|
168
179
|
const isDraggingFrom = (draggingAnchor === null || draggingAnchor === void 0 ? void 0 : draggingAnchor.edgeId) === edge.id && draggingAnchor.side === "from";
|
|
169
180
|
const isDraggingTo = (draggingAnchor === null || draggingAnchor === void 0 ? void 0 : draggingAnchor.edgeId) === edge.id && draggingAnchor.side === "to";
|
|
170
|
-
// const currentConnection =
|
|
171
|
-
const isNotRing1 = connecting &&
|
|
181
|
+
// const currentConnection =
|
|
182
|
+
const isNotRing1 = connecting &&
|
|
183
|
+
(connecting === null || connecting === void 0 ? void 0 : connecting.fromId) !== edge.from &&
|
|
184
|
+
(connecting === null || connecting === void 0 ? void 0 : connecting.fromId) !== edge.to;
|
|
172
185
|
return (<g key={edge.id}>
|
|
173
186
|
{/* Hit area */}
|
|
174
187
|
<path d={pathD} stroke="transparent" strokeWidth={14} fill="none" style={{ cursor: "pointer" }} onClick={(e) => {
|
|
@@ -184,7 +197,9 @@ export const ConnectionLayer = ({ edges, selectedEdge, connecting, draggingAncho
|
|
|
184
197
|
? "#a78bfa"
|
|
185
198
|
: isInNetwork && selectedEdge
|
|
186
199
|
? networkColor
|
|
187
|
-
: "#38bdf8"} strokeWidth={isSel ? 2 : isHov ? 2 : 1.5} fill="none" opacity={(selectedEdge && !isSel && !isInNetwork) || isNotRing1
|
|
200
|
+
: "#38bdf8"} strokeWidth={isSel ? 2 : isHov ? 2 : 1.5} fill="none" opacity={(selectedEdge && !isSel && !isInNetwork) || isNotRing1
|
|
201
|
+
? 0.2
|
|
202
|
+
: 0.9} strokeLinecap="round" style={{ pointerEvents: "none" }}/>
|
|
188
203
|
|
|
189
204
|
{/* FROM dot */}
|
|
190
205
|
{isSel && (<g>
|
|
@@ -250,11 +265,45 @@ export const ConnectionLayer = ({ edges, selectedEdge, connecting, draggingAncho
|
|
|
250
265
|
{/* Preview saat connecting */}
|
|
251
266
|
{connecting &&
|
|
252
267
|
(() => {
|
|
253
|
-
|
|
254
|
-
|
|
268
|
+
const findSourceTarget = renderedElements === null || renderedElements === void 0 ? void 0 : renderedElements.find((el) => el.id === connecting.fromId);
|
|
269
|
+
if (!findSourceTarget)
|
|
270
|
+
return null;
|
|
271
|
+
const { x, y, rotation, width, height } = findSourceTarget;
|
|
272
|
+
const rotated = rotatePoint(width / 2, height / 2, rotation !== null && rotation !== void 0 ? rotation : 0);
|
|
273
|
+
const w = width !== null && width !== void 0 ? width : NODE_WIDTH;
|
|
274
|
+
const h = height !== null && height !== void 0 ? height : NODE_HEIGHT;
|
|
275
|
+
const cx = x + rotated.x;
|
|
276
|
+
const cy = y + rotated.y;
|
|
277
|
+
// 3. Tentukan koordinat local space berdasarkan name/side
|
|
278
|
+
let lx = 0;
|
|
279
|
+
let ly = 0;
|
|
280
|
+
const hw = w / 2;
|
|
281
|
+
const hh = h / 2;
|
|
282
|
+
if (connecting.fromPos.name === "top") {
|
|
283
|
+
lx = 0;
|
|
284
|
+
ly = -hh;
|
|
285
|
+
}
|
|
286
|
+
else if (connecting.fromPos.name === "right") {
|
|
287
|
+
lx = hw;
|
|
288
|
+
ly = 0;
|
|
289
|
+
}
|
|
290
|
+
else if (connecting.fromPos.name === "bottom") {
|
|
291
|
+
lx = 0;
|
|
292
|
+
ly = hh;
|
|
293
|
+
}
|
|
294
|
+
else if (connecting.fromPos.name === "left") {
|
|
295
|
+
lx = -hw;
|
|
296
|
+
ly = 0;
|
|
297
|
+
}
|
|
298
|
+
const rad = (rotation * Math.PI) / 180;
|
|
299
|
+
const fromPos = {
|
|
300
|
+
x: cx + lx * Math.cos(rad) - ly * Math.sin(rad),
|
|
301
|
+
y: cy + lx * Math.sin(rad) + ly * Math.cos(rad),
|
|
302
|
+
};
|
|
303
|
+
const pts = computePoints(fromPos, mousePos, []);
|
|
255
304
|
const pathD = buildPath(pts);
|
|
256
305
|
return (<g>
|
|
257
|
-
<circle cx={
|
|
306
|
+
<circle cx={fromPos === null || fromPos === void 0 ? void 0 : fromPos.x} cy={fromPos === null || fromPos === void 0 ? void 0 : fromPos.y} r={4} fill="#a78bfa" stroke="#0f172a" strokeWidth={0.8} opacity={0.9} style={{ pointerEvents: "none" }}/>
|
|
258
307
|
<path d={pathD} stroke="#a78bfa" strokeWidth={1.5} fill="none" strokeDasharray="6 3" strokeLinecap="round" opacity={0.8} style={{ pointerEvents: "none" }}/>
|
|
259
308
|
</g>);
|
|
260
309
|
})()}
|
|
@@ -100,6 +100,7 @@ export interface LayerViewProps<TMeta = undefined> {
|
|
|
100
100
|
dragTable?: boolean;
|
|
101
101
|
selectNode?: boolean;
|
|
102
102
|
connectingNode?: boolean;
|
|
103
|
+
dragTransferTable?: boolean;
|
|
103
104
|
};
|
|
104
105
|
onEdgesChange?: (edges: EdgeType[], table: PropertiesProps[]) => void;
|
|
105
106
|
keyNode?: string;
|
|
@@ -112,6 +113,9 @@ export interface LayerViewProps<TMeta = undefined> {
|
|
|
112
113
|
dataKey: string;
|
|
113
114
|
selection: Record<number, string[]>;
|
|
114
115
|
};
|
|
116
|
+
onHoldTable?: (e: React.PointerEvent<SVGSVGElement>, component: ComponentProps<TMeta>[]) => void;
|
|
117
|
+
showConnection?: boolean;
|
|
118
|
+
initialEdges?: EdgeType[];
|
|
115
119
|
}
|
|
116
120
|
declare const LayerView: <TMeta>(props: LayerViewProps<TMeta>) => import("react/jsx-runtime").JSX.Element;
|
|
117
121
|
export default LayerView;
|
|
@@ -28,7 +28,8 @@ const LayerView = (props) => {
|
|
|
28
28
|
dragTable: false,
|
|
29
29
|
selectNode: false,
|
|
30
30
|
connectingNode: false,
|
|
31
|
-
|
|
31
|
+
dragTransferTable: false,
|
|
32
|
+
}, onMakeSelection, groupSelection, onHoldTable, showConnection } = props;
|
|
32
33
|
const widthTooltip = (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.minWidth) || 168;
|
|
33
34
|
const tableGhost = useRef(null);
|
|
34
35
|
const hoverUnderghostId = useRef(null);
|
|
@@ -266,6 +267,7 @@ const LayerView = (props) => {
|
|
|
266
267
|
setSelectedLines(null);
|
|
267
268
|
}
|
|
268
269
|
}, [actionPrivileged]);
|
|
270
|
+
const timerRef = useRef(null);
|
|
269
271
|
const handlePointerDown = (e) => {
|
|
270
272
|
var _a, _b, _c;
|
|
271
273
|
const svg = svgRef.current;
|
|
@@ -286,7 +288,7 @@ const LayerView = (props) => {
|
|
|
286
288
|
const downInOutSelection = hadSelection && makeSelection && e.button !== 2;
|
|
287
289
|
const unSelectAll = hadSelection && e.button === 2 && targetGroup && !targetSelectionGroup;
|
|
288
290
|
const hasSelectionDownOutSelection = !targetSelectionGroup && targetGroup && hadSelection;
|
|
289
|
-
if (downOutTable) {
|
|
291
|
+
if (downOutTable || (!targetGroup && !targetSelectionGroup)) {
|
|
290
292
|
if (graph.connecting) {
|
|
291
293
|
graph.cancelConnect();
|
|
292
294
|
}
|
|
@@ -318,6 +320,23 @@ const LayerView = (props) => {
|
|
|
318
320
|
setTooltip((prev) => (Object.assign(Object.assign({}, prev), { visible: false })));
|
|
319
321
|
return;
|
|
320
322
|
}
|
|
323
|
+
if ((actionPrivileged === null || actionPrivileged === void 0 ? void 0 : actionPrivileged.dragTransferTable) && e.button === 0) {
|
|
324
|
+
const targetGroup = e.target.closest("g[data-id]");
|
|
325
|
+
const targetSelectionGroup = e.target.closest("g[data-selection]");
|
|
326
|
+
if (targetGroup) {
|
|
327
|
+
const dataId = JSON.parse(targetGroup.getAttribute("data-id") || "{}");
|
|
328
|
+
const findDayaById = originalData({ id: dataId, type: "find" });
|
|
329
|
+
timerRef.current = setTimeout(() => {
|
|
330
|
+
onHoldTable && onHoldTable(e, [findDayaById]);
|
|
331
|
+
}, 1000);
|
|
332
|
+
}
|
|
333
|
+
if (targetSelectionGroup) {
|
|
334
|
+
const tableData = dataElementSelectionGroupRef.current;
|
|
335
|
+
timerRef.current = setTimeout(() => {
|
|
336
|
+
onHoldTable && onHoldTable(e, tableData);
|
|
337
|
+
}, 1000);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
321
340
|
let ghost = targetGroup === null || targetGroup === void 0 ? void 0 : targetGroup.cloneNode(true);
|
|
322
341
|
const ghostId = JSON.parse((targetGroup === null || targetGroup === void 0 ? void 0 : targetGroup.getAttribute("data-id")) || "{}");
|
|
323
342
|
const allowedDrag = (!(props === null || props === void 0 ? void 0 : props.dragTableBlockKey)
|
|
@@ -630,6 +649,7 @@ const LayerView = (props) => {
|
|
|
630
649
|
mappingKey,
|
|
631
650
|
tableMatchKey,
|
|
632
651
|
statusKey,
|
|
652
|
+
initialEdges: props === null || props === void 0 ? void 0 : props.initialEdges,
|
|
633
653
|
});
|
|
634
654
|
// ─── Render ───────────────────────────────────────────────────────────────
|
|
635
655
|
const hasBoundingBox = hasBoundingBoxRef.current;
|
|
@@ -664,7 +684,7 @@ const LayerView = (props) => {
|
|
|
664
684
|
userSelect: "none",
|
|
665
685
|
} }, props.svgProps, { children: [_jsx("rect", { width: "100%", height: "100%", fill: "url(#biggrid)" }), hasBoundingBox && (_jsx("defs", { children: _jsx("clipPath", { id: "contentCrop", children: _jsx("rect", { x: boundingBox.minX, y: boundingBox.minY, width: boundingBox.width, height: boundingBox.height }) }) })), _jsx("g", { id: "main-layer", clipPath: "url(#contentCrop)", children: _jsx(Layers, { components: [...extraComponentsEditor, ...renderedElements], selectedTable: selectedTable,
|
|
666
686
|
// iconTags={iconTags}
|
|
667
|
-
eventMatchTable: eventMatchTable, privilegedTags: privilegedTags, selectionLines: selectedLines }) }), _jsx(ConnectionLayer, { edges: graph.edges, selectedEdge: graph.selectedEdge, connecting: graph.connecting, draggingAnchor: graph.draggingAnchor, mousePos: graph.mousePos, getNodeById: getNodeById, onSelectEdge: graph.selectEdge, onDeleteEdge: graph.deleteEdge, onStartDragWaypoint: graph.startDragWaypoint, onInsertWaypoint: graph.insertWaypoint, onRemoveWaypoint: graph.removeWaypoint, onStartDragAnchor: graph.startDragAnchor, isConnectEdge: actionPrivileged.connectingNode, selectedNodeId: graph.selectedNode }), renderedElements.map((item) => {
|
|
687
|
+
eventMatchTable: eventMatchTable, privilegedTags: privilegedTags, selectionLines: selectedLines }) }), _jsx(ConnectionLayer, { edges: graph.edges, selectedEdge: graph.selectedEdge, connecting: graph.connecting, draggingAnchor: graph.draggingAnchor, mousePos: graph.mousePos, getNodeById: getNodeById, onSelectEdge: graph.selectEdge, onDeleteEdge: graph.deleteEdge, onStartDragWaypoint: graph.startDragWaypoint, onInsertWaypoint: graph.insertWaypoint, onRemoveWaypoint: graph.removeWaypoint, onStartDragAnchor: graph.startDragAnchor, isConnectEdge: actionPrivileged.connectingNode, selectedNodeId: graph.selectedNode, showConnection: showConnection, renderedElements: renderedElements }), renderedElements.map((item) => {
|
|
668
688
|
var _a, _b, _c, _d;
|
|
669
689
|
const rotated = rotatePoint(item.width / 2, item.height / 2, (_a = item.rotation) !== null && _a !== void 0 ? _a : 0);
|
|
670
690
|
return (_jsx(ConnectHandle, {
|
|
@@ -674,7 +694,7 @@ const LayerView = (props) => {
|
|
|
674
694
|
graph.updateAnchor(nodeId, clickPos);
|
|
675
695
|
else
|
|
676
696
|
graph.endConnect(nodeId, clickPos);
|
|
677
|
-
}, isConnectEdge: actionPrivileged.connectingNode, onSelectNode: graph.selectNode, isSelectNode: actionPrivileged.selectNode, onSelectEdge: graph.selectEdge, edges: graph.edges }, item.id));
|
|
697
|
+
}, isConnectEdge: actionPrivileged.connectingNode, onSelectNode: graph.selectNode, isSelectNode: actionPrivileged.selectNode, onSelectEdge: graph.selectEdge, edges: graph.edges, showConnection: showConnection }, item.id));
|
|
678
698
|
})] })), tooltip.visible && (_jsx("div", { className: `seat-editor tooltip-container ${tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.className}`, style: Object.assign({ top: tooltip.y, left: tooltip.x, transform: `scale(${1 / scale})`, transformOrigin: "top left", minWidth: widthTooltip + "px" }, tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.style), children: tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.children }))] }) }))] })));
|
|
679
699
|
};
|
|
680
700
|
export default LayerView;
|
|
@@ -27,7 +27,8 @@ const LayerView = (props) => {
|
|
|
27
27
|
dragTable: false,
|
|
28
28
|
selectNode: false,
|
|
29
29
|
connectingNode: false,
|
|
30
|
-
|
|
30
|
+
dragTransferTable: false,
|
|
31
|
+
}, onMakeSelection, groupSelection, onHoldTable, showConnection } = props;
|
|
31
32
|
const widthTooltip = (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.minWidth) || 168;
|
|
32
33
|
const tableGhost = useRef(null);
|
|
33
34
|
const hoverUnderghostId = useRef(null);
|
|
@@ -265,6 +266,7 @@ const LayerView = (props) => {
|
|
|
265
266
|
setSelectedLines(null);
|
|
266
267
|
}
|
|
267
268
|
}, [actionPrivileged]);
|
|
269
|
+
const timerRef = useRef(null);
|
|
268
270
|
const handlePointerDown = (e) => {
|
|
269
271
|
var _a, _b, _c;
|
|
270
272
|
const svg = svgRef.current;
|
|
@@ -285,7 +287,7 @@ const LayerView = (props) => {
|
|
|
285
287
|
const downInOutSelection = hadSelection && makeSelection && e.button !== 2;
|
|
286
288
|
const unSelectAll = hadSelection && e.button === 2 && targetGroup && !targetSelectionGroup;
|
|
287
289
|
const hasSelectionDownOutSelection = !targetSelectionGroup && targetGroup && hadSelection;
|
|
288
|
-
if (downOutTable) {
|
|
290
|
+
if (downOutTable || (!targetGroup && !targetSelectionGroup)) {
|
|
289
291
|
if (graph.connecting) {
|
|
290
292
|
graph.cancelConnect();
|
|
291
293
|
}
|
|
@@ -317,6 +319,23 @@ const LayerView = (props) => {
|
|
|
317
319
|
setTooltip((prev) => (Object.assign(Object.assign({}, prev), { visible: false })));
|
|
318
320
|
return;
|
|
319
321
|
}
|
|
322
|
+
if ((actionPrivileged === null || actionPrivileged === void 0 ? void 0 : actionPrivileged.dragTransferTable) && e.button === 0) {
|
|
323
|
+
const targetGroup = e.target.closest("g[data-id]");
|
|
324
|
+
const targetSelectionGroup = e.target.closest("g[data-selection]");
|
|
325
|
+
if (targetGroup) {
|
|
326
|
+
const dataId = JSON.parse(targetGroup.getAttribute("data-id") || "{}");
|
|
327
|
+
const findDayaById = originalData({ id: dataId, type: "find" });
|
|
328
|
+
timerRef.current = setTimeout(() => {
|
|
329
|
+
onHoldTable && onHoldTable(e, [findDayaById]);
|
|
330
|
+
}, 1000);
|
|
331
|
+
}
|
|
332
|
+
if (targetSelectionGroup) {
|
|
333
|
+
const tableData = dataElementSelectionGroupRef.current;
|
|
334
|
+
timerRef.current = setTimeout(() => {
|
|
335
|
+
onHoldTable && onHoldTable(e, tableData);
|
|
336
|
+
}, 1000);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
320
339
|
let ghost = targetGroup === null || targetGroup === void 0 ? void 0 : targetGroup.cloneNode(true);
|
|
321
340
|
const ghostId = JSON.parse((targetGroup === null || targetGroup === void 0 ? void 0 : targetGroup.getAttribute("data-id")) || "{}");
|
|
322
341
|
const allowedDrag = (!(props === null || props === void 0 ? void 0 : props.dragTableBlockKey)
|
|
@@ -629,6 +648,7 @@ const LayerView = (props) => {
|
|
|
629
648
|
mappingKey,
|
|
630
649
|
tableMatchKey,
|
|
631
650
|
statusKey,
|
|
651
|
+
initialEdges: props === null || props === void 0 ? void 0 : props.initialEdges,
|
|
632
652
|
});
|
|
633
653
|
// ─── Render ───────────────────────────────────────────────────────────────
|
|
634
654
|
const hasBoundingBox = hasBoundingBoxRef.current;
|
|
@@ -683,7 +703,7 @@ const LayerView = (props) => {
|
|
|
683
703
|
eventMatchTable={eventMatchTable} privilegedTags={privilegedTags} selectionLines={selectedLines}/>
|
|
684
704
|
</g>
|
|
685
705
|
|
|
686
|
-
<ConnectionLayer edges={graph.edges} selectedEdge={graph.selectedEdge} connecting={graph.connecting} draggingAnchor={graph.draggingAnchor} mousePos={graph.mousePos} getNodeById={getNodeById} onSelectEdge={graph.selectEdge} onDeleteEdge={graph.deleteEdge} onStartDragWaypoint={graph.startDragWaypoint} onInsertWaypoint={graph.insertWaypoint} onRemoveWaypoint={graph.removeWaypoint} onStartDragAnchor={graph.startDragAnchor} isConnectEdge={actionPrivileged.connectingNode} selectedNodeId={graph.selectedNode}/>
|
|
706
|
+
<ConnectionLayer edges={graph.edges} selectedEdge={graph.selectedEdge} connecting={graph.connecting} draggingAnchor={graph.draggingAnchor} mousePos={graph.mousePos} getNodeById={getNodeById} onSelectEdge={graph.selectEdge} onDeleteEdge={graph.deleteEdge} onStartDragWaypoint={graph.startDragWaypoint} onInsertWaypoint={graph.insertWaypoint} onRemoveWaypoint={graph.removeWaypoint} onStartDragAnchor={graph.startDragAnchor} isConnectEdge={actionPrivileged.connectingNode} selectedNodeId={graph.selectedNode} showConnection={showConnection} renderedElements={renderedElements}/>
|
|
687
707
|
|
|
688
708
|
{renderedElements.map((item) => {
|
|
689
709
|
var _a, _b, _c, _d;
|
|
@@ -695,7 +715,7 @@ const LayerView = (props) => {
|
|
|
695
715
|
graph.updateAnchor(nodeId, clickPos);
|
|
696
716
|
else
|
|
697
717
|
graph.endConnect(nodeId, clickPos);
|
|
698
|
-
}} isConnectEdge={actionPrivileged.connectingNode} onSelectNode={graph.selectNode} isSelectNode={actionPrivileged.selectNode} onSelectEdge={graph.selectEdge} edges={graph.edges}/>);
|
|
718
|
+
}} isConnectEdge={actionPrivileged.connectingNode} onSelectNode={graph.selectNode} isSelectNode={actionPrivileged.selectNode} onSelectEdge={graph.selectEdge} edges={graph.edges} showConnection={showConnection}/>);
|
|
699
719
|
})}
|
|
700
720
|
</svg>
|
|
701
721
|
|
|
@@ -11,8 +11,10 @@ export type UseConnectionGraphOptions = {
|
|
|
11
11
|
mappingKey?: string;
|
|
12
12
|
tableMatchKey?: TableMatchKey[];
|
|
13
13
|
statusKey?: string;
|
|
14
|
+
showConnection?: boolean;
|
|
15
|
+
initialEdges?: EdgeType[];
|
|
14
16
|
};
|
|
15
|
-
export declare const useConnectionGraph: ({ svgRef,
|
|
17
|
+
export declare const useConnectionGraph: ({ svgRef, onEdgesChange, keyNode, mappingKey, initialEdges, }: UseConnectionGraphOptions) => {
|
|
16
18
|
edges: EdgeType[];
|
|
17
19
|
setEdges: React.Dispatch<React.SetStateAction<EdgeType[]>>;
|
|
18
20
|
selectedEdge: string;
|
|
@@ -22,6 +24,7 @@ export declare const useConnectionGraph: ({ svgRef, getNodeById, onEdgesChange,
|
|
|
22
24
|
fromPos: {
|
|
23
25
|
x: number;
|
|
24
26
|
y: number;
|
|
27
|
+
name: string;
|
|
25
28
|
};
|
|
26
29
|
};
|
|
27
30
|
draggingAnchor: DraggingAnchor;
|
|
@@ -32,16 +35,19 @@ export declare const useConnectionGraph: ({ svgRef, getNodeById, onEdgesChange,
|
|
|
32
35
|
startConnect: (fromId: string, fromPos: {
|
|
33
36
|
x: number;
|
|
34
37
|
y: number;
|
|
38
|
+
name: string;
|
|
35
39
|
}) => void;
|
|
36
40
|
endConnect: (toId: string, toPos: {
|
|
37
41
|
x: number;
|
|
38
42
|
y: number;
|
|
43
|
+
name: string;
|
|
39
44
|
}) => void;
|
|
40
45
|
cancelConnect: () => void;
|
|
41
46
|
startDragAnchor: (e: React.MouseEvent, edgeId: string, side: "from" | "to") => void;
|
|
42
47
|
updateAnchor: (targetNodeId: string, newPos: {
|
|
43
48
|
x: number;
|
|
44
49
|
y: number;
|
|
50
|
+
name: string;
|
|
45
51
|
}) => void;
|
|
46
52
|
cancelDragAnchor: () => void;
|
|
47
53
|
startDragWaypoint: (e: React.MouseEvent, edgeId: string, index: number) => void;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// use-connection-graph.ts
|
|
2
2
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
3
|
-
import { snap } from "./utils";
|
|
3
|
+
import { rotatePoint, snap } from "./utils";
|
|
4
4
|
import { useAppSelector } from "../../hooks/use-redux";
|
|
5
|
-
export const useConnectionGraph = ({ svgRef,
|
|
5
|
+
export const useConnectionGraph = ({ svgRef, onEdgesChange, keyNode, mappingKey, initialEdges, }) => {
|
|
6
6
|
const components = useAppSelector((state) => state.board.components);
|
|
7
7
|
const [edges, setEdges] = useState([]);
|
|
8
8
|
const [selectedEdge, setSelectedEdge] = useState(null);
|
|
@@ -124,7 +124,7 @@ export const useConnectionGraph = ({ svgRef, getNodeById, onEdgesChange, keyNode
|
|
|
124
124
|
return Object.assign(Object.assign({}, ed), { waypoints: ed.waypoints.filter((_, i) => i !== index) });
|
|
125
125
|
}));
|
|
126
126
|
}, []);
|
|
127
|
-
// __ Select Table
|
|
127
|
+
// __ Select Table
|
|
128
128
|
const selectNode = useCallback((nodeId) => setSelectedNode(nodeId), []);
|
|
129
129
|
// ── Select / delete ──────────────────────────────────────────────
|
|
130
130
|
const selectEdge = useCallback((id) => setSelectedEdge(id), []);
|
|
@@ -168,6 +168,89 @@ export const useConnectionGraph = ({ svgRef, getNodeById, onEdgesChange, keyNode
|
|
|
168
168
|
});
|
|
169
169
|
onEdgesChange === null || onEdgesChange === void 0 ? void 0 : onEdgesChange(edges, result);
|
|
170
170
|
}, [edges]);
|
|
171
|
+
// initialize edges
|
|
172
|
+
useEffect(() => {
|
|
173
|
+
if (initialEdges) {
|
|
174
|
+
//process initial edges
|
|
175
|
+
const allElements = components === null || components === void 0 ? void 0 : components.map((table) => {
|
|
176
|
+
if (mappingKey && (table === null || table === void 0 ? void 0 : table[mappingKey])) {
|
|
177
|
+
return Object.assign({}, table);
|
|
178
|
+
}
|
|
179
|
+
return Object.assign({}, table);
|
|
180
|
+
});
|
|
181
|
+
// const findSourceTarget = allElements?.find(
|
|
182
|
+
// (el) => el.id === connecting.fromId
|
|
183
|
+
// );
|
|
184
|
+
const transformAllEdges = initialEdges === null || initialEdges === void 0 ? void 0 : initialEdges.map((edge) => {
|
|
185
|
+
const fromElement = allElements === null || allElements === void 0 ? void 0 : allElements.find((el) => el.id === edge.from);
|
|
186
|
+
if (!fromElement)
|
|
187
|
+
return null;
|
|
188
|
+
const { x: fromX, y: fromY, rotation: fromRotation, width: fromWidth, height: fromHeight, } = fromElement;
|
|
189
|
+
const fromRotated = rotatePoint(fromWidth / 2, fromHeight / 2, fromRotation !== null && fromRotation !== void 0 ? fromRotation : 0);
|
|
190
|
+
const fromCx = fromX + fromRotated.x;
|
|
191
|
+
const fromCy = fromY + fromRotated.y;
|
|
192
|
+
let fromLx = 0;
|
|
193
|
+
let fromLy = 0;
|
|
194
|
+
const fromHw = fromWidth / 2;
|
|
195
|
+
const fromHh = fromHeight / 2;
|
|
196
|
+
if (edge.fromPos.name === "top") {
|
|
197
|
+
fromLx = 0;
|
|
198
|
+
fromLy = -fromHh;
|
|
199
|
+
}
|
|
200
|
+
else if (connecting.fromPos.name === "right") {
|
|
201
|
+
fromLx = fromHw;
|
|
202
|
+
fromLy = 0;
|
|
203
|
+
}
|
|
204
|
+
else if (connecting.fromPos.name === "bottom") {
|
|
205
|
+
fromLx = 0;
|
|
206
|
+
fromLy = fromHh;
|
|
207
|
+
}
|
|
208
|
+
else if (connecting.fromPos.name === "left") {
|
|
209
|
+
fromLx = -fromHw;
|
|
210
|
+
fromLy = 0;
|
|
211
|
+
}
|
|
212
|
+
const rad = (fromRotation * Math.PI) / 180;
|
|
213
|
+
const fromPos = {
|
|
214
|
+
x: fromCx + fromLx * Math.cos(rad) - fromLy * Math.sin(rad),
|
|
215
|
+
y: fromCy + fromLx * Math.sin(rad) + fromLy * Math.cos(rad),
|
|
216
|
+
};
|
|
217
|
+
const toElement = allElements === null || allElements === void 0 ? void 0 : allElements.find((el) => el.id === edge.to);
|
|
218
|
+
if (!toElement)
|
|
219
|
+
return null;
|
|
220
|
+
const { x: toX, y: toY, rotation: toRotation, width: toWidth, height: toHeight, } = toElement;
|
|
221
|
+
const toRotated = rotatePoint(toWidth / 2, toHeight / 2, toRotation !== null && toRotation !== void 0 ? toRotation : 0);
|
|
222
|
+
const toCx = toX + toRotated.x;
|
|
223
|
+
const toCy = toY + toRotated.y;
|
|
224
|
+
let toLx = 0;
|
|
225
|
+
let toLy = 0;
|
|
226
|
+
const toHw = toWidth / 2;
|
|
227
|
+
const toHh = toHeight / 2;
|
|
228
|
+
if (edge.toPos.name === "top") {
|
|
229
|
+
toLx = 0;
|
|
230
|
+
toLy = -toHh;
|
|
231
|
+
}
|
|
232
|
+
else if (edge.toPos.name === "right") {
|
|
233
|
+
toLx = toHw;
|
|
234
|
+
toLy = 0;
|
|
235
|
+
}
|
|
236
|
+
else if (edge.toPos.name === "bottom") {
|
|
237
|
+
toLx = 0;
|
|
238
|
+
toLy = toHh;
|
|
239
|
+
}
|
|
240
|
+
else if (edge.toPos.name === "left") {
|
|
241
|
+
toLx = -toHw;
|
|
242
|
+
toLy = 0;
|
|
243
|
+
}
|
|
244
|
+
const rad2 = (toRotation * Math.PI) / 180;
|
|
245
|
+
const toPos = {
|
|
246
|
+
x: toCx + toLx * Math.cos(rad2) - toLy * Math.sin(rad2),
|
|
247
|
+
y: toCy + toLx * Math.sin(rad2) + toLy * Math.cos(rad2),
|
|
248
|
+
};
|
|
249
|
+
return Object.assign(Object.assign({}, edge), { from: fromElement.id, to: toElement.id, fromPos,
|
|
250
|
+
toPos });
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
}, [initialEdges]);
|
|
171
254
|
return {
|
|
172
255
|
edges,
|
|
173
256
|
setEdges,
|
|
@@ -191,6 +274,6 @@ export const useConnectionGraph = ({ svgRef, getNodeById, onEdgesChange, keyNode
|
|
|
191
274
|
clearSelection,
|
|
192
275
|
onMouseMove,
|
|
193
276
|
onMouseUp,
|
|
194
|
-
selectNode
|
|
277
|
+
selectNode,
|
|
195
278
|
};
|
|
196
279
|
};
|