From f0ca42db890416d6c8449b5e8b9f992ca2404917 Mon Sep 17 00:00:00 2001 From: Pierre Chalamet Date: Fri, 16 Jan 2026 17:45:04 +0100 Subject: [PATCH] add edges selection --- src/Terrabuild.UI/package.json | 2 +- src/Terrabuild.UI/pnpm-lock.yaml | 39 +++++++++++++------------------- src/Terrabuild.UI/src/App.tsx | 19 ++++++++++++---- 3 files changed, 31 insertions(+), 29 deletions(-) diff --git a/src/Terrabuild.UI/package.json b/src/Terrabuild.UI/package.json index 0610b43a..bb69299e 100644 --- a/src/Terrabuild.UI/package.json +++ b/src/Terrabuild.UI/package.json @@ -16,7 +16,7 @@ "@mantine/hooks": "^8.0.0", "@mantine/notifications": "^8.0.0", "@tabler/icons-react": "^3.19.0", - "dagre": "^0.8.5", + "@dagrejs/dagre": "^1.0.4", "react": "^18.3.1", "react-dom": "^18.3.1", "reactflow": "^11.11.3", diff --git a/src/Terrabuild.UI/pnpm-lock.yaml b/src/Terrabuild.UI/pnpm-lock.yaml index 80bc2d57..00c939fc 100644 --- a/src/Terrabuild.UI/pnpm-lock.yaml +++ b/src/Terrabuild.UI/pnpm-lock.yaml @@ -8,6 +8,9 @@ importers: .: dependencies: + '@dagrejs/dagre': + specifier: ^1.0.4 + version: 1.1.8 '@emotion/react': specifier: ^11.11.4 version: 11.14.0(@types/react@18.3.27)(react@18.3.1) @@ -26,9 +29,6 @@ importers: '@tabler/icons-react': specifier: ^3.19.0 version: 3.36.1(react@18.3.1) - dagre: - specifier: ^0.8.5 - version: 0.8.5 react: specifier: ^18.3.1 version: 18.3.1 @@ -150,6 +150,13 @@ packages: resolution: {integrity: sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==} engines: {node: '>=6.9.0'} + '@dagrejs/dagre@1.1.8': + resolution: {integrity: sha512-5SEDlndt4W/LaVzPYJW+bSmSEZc9EzTf8rJ20WCKvjS5EAZAN0b+x0Yww7VMT4R3Wootkg+X9bUfUxazYw6Blw==} + + '@dagrejs/graphlib@2.2.4': + resolution: {integrity: sha512-mepCf/e9+SKYy1d02/UkvSy6+6MoyXhVxP8lLDfA7BPE1X1d4dR0sZznmbM8/XVJ1GPM+Svnx7Xj6ZweByWUkw==} + engines: {node: '>17.0.0'} + '@emotion/babel-plugin@11.13.5': resolution: {integrity: sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==} @@ -785,9 +792,6 @@ packages: resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==} engines: {node: '>=12'} - dagre@0.8.5: - resolution: {integrity: sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==} - debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} @@ -841,9 +845,6 @@ packages: resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} engines: {node: '>=6'} - graphlib@2.1.8: - resolution: {integrity: sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==} - hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} @@ -881,9 +882,6 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true @@ -1289,6 +1287,12 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 + '@dagrejs/dagre@1.1.8': + dependencies: + '@dagrejs/graphlib': 2.2.4 + + '@dagrejs/graphlib@2.2.4': {} + '@emotion/babel-plugin@11.13.5': dependencies: '@babel/helper-module-imports': 7.28.6 @@ -1919,11 +1923,6 @@ snapshots: d3-selection: 3.0.0 d3-transition: 3.0.1(d3-selection@3.0.0) - dagre@0.8.5: - dependencies: - graphlib: 2.1.8 - lodash: 4.17.21 - debug@4.4.3: dependencies: ms: 2.1.3 @@ -1982,10 +1981,6 @@ snapshots: get-nonce@1.0.1: {} - graphlib@2.1.8: - dependencies: - lodash: 4.17.21 - hasown@2.0.2: dependencies: function-bind: 1.1.2 @@ -2015,8 +2010,6 @@ snapshots: lines-and-columns@1.2.4: {} - lodash@4.17.21: {} - loose-envify@1.4.0: dependencies: js-tokens: 4.0.0 diff --git a/src/Terrabuild.UI/src/App.tsx b/src/Terrabuild.UI/src/App.tsx index 25d952fd..c4d2020f 100644 --- a/src/Terrabuild.UI/src/App.tsx +++ b/src/Terrabuild.UI/src/App.tsx @@ -20,7 +20,7 @@ import { useNodesState, } from "reactflow"; import "reactflow/dist/style.css"; -import dagre from "dagre"; +import dagre from "@dagrejs/dagre"; import { Terminal } from "xterm"; import { FitAddon } from "xterm-addon-fit"; import "xterm/css/xterm.css"; @@ -48,7 +48,7 @@ const nodeHeight = 120; const layoutGraph = (nodes: Node[], edges: Edge[]) => { const graph = new dagre.graphlib.Graph(); graph.setDefaultEdgeLabel(() => ({})); - graph.setGraph({ rankdir: "RL", nodesep: 90, ranksep: 140 }); + graph.setGraph({ rankdir: "RL", nodesep: 100, ranksep: 200, ranker: "longest-path" }); nodes.forEach((node) => { graph.setNode(node.id, { width: nodeWidth, height: nodeHeight }); @@ -284,6 +284,13 @@ const App = () => { setSelectedNodeId(selected ? selected.id : null); }, [nodes]); + useEffect(() => { + if (selectedNodeId === null) { + setSelectedProject(null); + setSelectedTargetKey(null); + } + }, [selectedNodeId]); + useEffect(() => { setNodes((current) => current.map((node) => ({ @@ -468,8 +475,10 @@ const App = () => { setEdges((current) => current.map((edge) => { const isConnected = - draggedNodeId !== null && - (edge.source === draggedNodeId || edge.target === draggedNodeId); + (draggedNodeId !== null && + (edge.source === draggedNodeId || edge.target === draggedNodeId)) || + (selectedNodeId !== null && + (edge.source === selectedNodeId || edge.target === selectedNodeId)); const stroke = isConnected ? highlightStroke : defaultStroke; return { ...edge, @@ -487,7 +496,7 @@ const App = () => { }; }) ); - }, [draggedNodeId, effectiveColorScheme, theme, setEdges]); + }, [draggedNodeId, selectedNodeId, effectiveColorScheme, theme, setEdges]); const nodeCount = graph ? Object.keys(graph.nodes).length : 0; const rootNodeCount = graph?.rootNodes?.length ?? 0;