@@ -230,6 +230,11 @@ function DependencyGraphInner({ repoId, apiUrl, apiKey }: DependencyGraphProps)
230230 let flowEdges : Edge [ ] = [ ]
231231
232232 if ( clusterByDir && clusteredData ) {
233+ // Safety: only apply selection highlighting if the selected node is actually visible
234+ const effectiveSelectedIdCluster = selectedNodeId &&
235+ ( clusteredData . visibleFiles . has ( selectedNodeId ) || selectedNodeId . startsWith ( 'dir:' ) )
236+ ? selectedNodeId : null
237+
233238 // Add directory nodes
234239 clusteredData . dirNodes . forEach ( dir => {
235240 flowNodes . push ( {
@@ -248,10 +253,10 @@ function DependencyGraphInner({ repoId, apiUrl, apiKey }: DependencyGraphProps)
248253 const metrics = impact . getFileMetrics ( node . id )
249254
250255 let state : GraphNodeData [ 'state' ] = 'default'
251- if ( selectedNodeId === node . id ) state = 'selected'
256+ if ( effectiveSelectedIdCluster === node . id ) state = 'selected'
252257 else if ( selectedImpact ?. directDependents . includes ( node . id ) ) state = 'direct'
253258 else if ( selectedImpact ?. transitiveDependents . includes ( node . id ) ) state = 'transitive'
254- else if ( selectedNodeId && ! selectedNodeId . startsWith ( 'dir:' ) ) state = 'dimmed'
259+ else if ( effectiveSelectedIdCluster && ! effectiveSelectedIdCluster . startsWith ( 'dir:' ) ) state = 'dimmed'
255260
256261 // Hover highlighting in clustered mode
257262 if ( hoveredFileId === node . id && state === 'dimmed' ) state = 'direct'
@@ -284,15 +289,18 @@ function DependencyGraphInner({ repoId, apiUrl, apiKey }: DependencyGraphProps)
284289 } )
285290 } else {
286291 // Non-clustered mode (original logic)
292+ // Safety: only apply selection highlighting if the selected node is actually visible
293+ const effectiveSelectedId = selectedNodeId && visibleNodeIds . has ( selectedNodeId ) ? selectedNodeId : null
294+
287295 flowNodes = rawGraphData . nodes
288296 . filter ( ( node : any ) => visibleNodeIds . has ( node . id ) )
289297 . map ( ( node : any ) => {
290298 const fileName = node . label || node . id . split ( '/' ) . pop ( )
291299 const metrics = impact . getFileMetrics ( node . id )
292300
293301 let state : GraphNodeData [ 'state' ] = 'default'
294- if ( selectedNodeId ) {
295- if ( node . id === selectedNodeId ) state = 'selected'
302+ if ( effectiveSelectedId ) {
303+ if ( node . id === effectiveSelectedId ) state = 'selected'
296304 else if ( selectedImpact ?. directDependents . includes ( node . id ) ) state = 'direct'
297305 else if ( selectedImpact ?. transitiveDependents . includes ( node . id ) ) state = 'transitive'
298306 else state = 'dimmed'
@@ -321,9 +329,9 @@ function DependencyGraphInner({ repoId, apiUrl, apiKey }: DependencyGraphProps)
321329 . filter ( ( edge : any ) => visibleNodeIds . has ( edge . source ) && visibleNodeIds . has ( edge . target ) )
322330 . map ( ( edge : any ) => {
323331 let edgeState : 'default' | 'highlighted' | 'dimmed' | 'incoming' | 'outgoing' = 'default'
324- if ( selectedNodeId ) {
325- if ( edge . source === selectedNodeId ) edgeState = 'outgoing'
326- else if ( edge . target === selectedNodeId ) edgeState = 'incoming'
332+ if ( effectiveSelectedId ) {
333+ if ( edge . source === effectiveSelectedId ) edgeState = 'outgoing'
334+ else if ( edge . target === effectiveSelectedId ) edgeState = 'incoming'
327335 else edgeState = 'dimmed'
328336 }
329337
@@ -369,12 +377,26 @@ function DependencyGraphInner({ repoId, apiUrl, apiKey }: DependencyGraphProps)
369377 } , [ ] )
370378
371379 const handlePanelFileClick = useCallback ( ( fileId : string ) => {
380+ // Only select if the file is currently visible in the graph
381+ // Otherwise clicking on a non-visible dependent breaks the view
382+ if ( ! visibleNodeIds . has ( fileId ) ) {
383+ // If not visible, enable "show all" to make it visible first
384+ if ( ! showAll ) {
385+ setShowAll ( true )
386+ // Small delay to let the nodes render, then select
387+ setTimeout ( ( ) => {
388+ setSelectedNodeId ( fileId )
389+ } , 100 )
390+ return
391+ }
392+ }
393+
372394 setSelectedNodeId ( fileId )
373395 const node = nodes . find ( n => n . id === fileId )
374396 if ( node ) {
375397 fitView ( { nodes : [ node ] , padding : 0.5 , duration : 300 } )
376398 }
377- } , [ nodes , fitView ] )
399+ } , [ nodes , fitView , visibleNodeIds , showAll ] )
378400
379401 const handleResetView = useCallback ( ( ) => {
380402 setSelectedNodeId ( null )
0 commit comments