Skip to content

feat(dependency-graph): Phase 2 - Directory clustering with expand/collapse#228

Merged
DevanshuNEU merged 4 commits into
OpenCodeIntel:mainfrom
DevanshuNEU:feat/dependency-graph-phase2
Jan 28, 2026
Merged

feat(dependency-graph): Phase 2 - Directory clustering with expand/collapse#228
DevanshuNEU merged 4 commits into
OpenCodeIntel:mainfrom
DevanshuNEU:feat/dependency-graph-phase2

Conversation

@DevanshuNEU

@DevanshuNEU DevanshuNEU commented Jan 27, 2026

Copy link
Copy Markdown
Collaborator

Description

Adds directory clustering to the dependency graph - collapse files by folder for cleaner high-level architecture view.

Changes

New:

  • DirectoryNode.tsx - Collapsible folder node with aggregated metrics
  • Cluster toggle button in toolbar

Updated:

  • GraphToolbar.tsx - Added cluster button
  • index.tsx - Clustering logic, directory expansion state
  • index.css - Smoother animations

Features

  • Click "Cluster" to group files by directory
  • Click folder to expand/collapse
  • Aggregated metrics: file count, deps, risk level
  • Tests filter now catches /tests/ paths
  • Legend repositioned, better UX

Known Limitation

⚠️ ReactFlow (SVG) can feel laggy - WebGL migration planned for Phase 3

Summary by CodeRabbit

Release Notes

  • New Features

    • Added directory clustering to the dependency graph—toggle between flat and grouped-by-folder views.
    • Directories are now expandable and collapsible with visual folder indicators.
    • Display file counts, dependency metrics, and risk levels aggregated at the directory level.
  • Style

    • Enhanced animations and transitions for smoother visual feedback during interactions.

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel

vercel Bot commented Jan 27, 2026

Copy link
Copy Markdown

@DevanshuNEU is attempting to deploy a commit to the Dev's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Jan 27, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Introduces directory-level clustering to the Dependency Graph component, adding a new DirectoryNode component, a cluster-toggle UI button, and graph logic to group files by directory with expandable folder nodes and aggregated metrics including file counts, dependency counts, and risk badges.

Changes

Cohort / File(s) Summary
New Directory Node Component
frontend/src/components/DependencyGraph/DirectoryNode.tsx
New memoized React Flow node component for rendering directory clusters. Implements DirectoryNodeData interface with label, path, file count, and risk metrics. Includes state-driven styling (default, selected, direct, transitive, dimmed), visual state indicators (folder icon, chevron rotation), dynamic dependency/risk coloring, and handles for React Flow connections.
Cluster Toggle UI
frontend/src/components/DependencyGraph/GraphToolbar.tsx
Adds FolderTree icon cluster-toggle button with state-dependent styling and aria-pressed attribute. Updates Tests and Show All buttons with aria-pressed and variant states for improved accessibility and visual feedback.
Core Clustering Logic
frontend/src/components/DependencyGraph/index.tsx
Implements directory clustering state (clusterByDir, expandedDirs) and helper functions (getDirPath, getMaxRisk). Extends test filtering by directory patterns. Adds clustering data generation that groups visible files by directory, creates directory nodes with aggregated metrics, and conditionally renders files based on expansion state. Rebuilds edges to connect directory nodes and files appropriately. Updates layout effects, legend, and interaction handlers for directory expansion/collapse. Prevents impact panel display for directory nodes.
ReactFlow Animation Styles
frontend/src/index.css
Introduces 60fps-optimized transitions and animations for ReactFlow nodes, edges, viewport, and controls. Adds node hover brightness effect, pane grab cursor behavior, and centralized --rf-node-transition timing variable.

Sequence Diagrams

sequenceDiagram
    actor User
    participant Toolbar as GraphToolbar
    participant Graph as DependencyGraph
    participant React as React Flow
    participant DNode as DirectoryNode

    User->>Toolbar: Click Cluster Button
    Toolbar->>Graph: onToggleCluster()
    Graph->>Graph: Update clusterByDir state
    Graph->>Graph: Group files by directory<br/>Create directory node data
    Graph->>Graph: Rebuild edges between<br/>directories/files
    Graph->>React: Update nodes & edges
    React->>DNode: Render DirectoryNode instances
    DNode->>DNode: Show folder icon +<br/>file/dependency counts
    
    User->>DNode: Click Directory Node
    DNode->>Graph: Handle node click
    Graph->>Graph: Toggle expandedDirs state
    Graph->>Graph: Recalculate visibility<br/>and edges
    Graph->>React: Update node/edge rendering
    React->>React: Animate layout change
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 Folders bloom where files once scattered free,
Click and expand each directory tree,
Dependencies dance in clustered delight,
Risk badges glow, risks grouped in sight,
The graph now breathes with hierarchic grace! 🌳✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 55.56% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: adding directory clustering with expand/collapse functionality to the dependency graph, which is the primary feature of this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@frontend/src/components/DependencyGraph/index.tsx`:
- Around line 163-203: clusteredData currently omits directory nodes when a dir
is expanded, so expandedDirs only grows and there is no node to click to
collapse, and dirNodes/counts are wrong; modify the loop that builds dirNodes
(in clusteredData) to always push a directory node for each dirPath (using id
`dir:${dirPath}`) and set its data.isExpanded based on expandedDirs.has(dirPath)
(and data.state accordingly), while still adding individual files to
visibleFiles when expanded; keep fileCount, totalDependents (using
impact.getFileMetrics) and maxRisk (getMaxRisk) computed the same way but ensure
the dir node remains present for expanded dirs so collapse UI and directory
metrics work correctly.
🧹 Nitpick comments (3)
frontend/src/components/DependencyGraph/GraphToolbar.tsx (1)

44-74: Expose toggle state to assistive tech + clarify cluster tooltip.
Consider adding aria-pressed and a stateful tooltip for the cluster toggle (and tests toggle) so screen readers and tooltips reflect the current state.

♿ Suggested tweak
         <Button
           variant={clusterByDir ? 'default' : 'secondary'}
           size="sm"
           onClick={onToggleCluster}
           className="h-8"
-          title="Group files by directory"
+          title={clusterByDir ? 'Ungroup files by directory' : 'Group files by directory'}
+          aria-pressed={clusterByDir}
         >
           <FolderTree className="w-3.5 h-3.5 mr-1.5" />
           Cluster
         </Button>
@@
         <Button
           variant={showTests ? 'secondary' : 'outline'}
           size="sm"
           onClick={onToggleTests}
           className={cn('h-8', !showTests && 'opacity-70 line-through')}
           title={showTests ? 'Click to hide test files' : 'Click to show test files'}
+          aria-pressed={showTests}
         >
frontend/src/components/DependencyGraph/hooks/useDirectoryClustering.ts (1)

48-76: Avoid O(N²) lookups when building clusters.
nodes.find inside the per-directory loop scales poorly on large graphs. A simple id→node map avoids repeated scans.

♻️ Suggested change
   const clusters = useMemo(() => {
     const clusterMap = new Map<string, DirectoryCluster>()
+    const nodeById = new Map(nodes.map(n => [n.id, n]))
@@
-      const nodeData = files.map(f => nodes.find(n => n.id === f)!).filter(Boolean)
+      const nodeData = files
+        .map(f => nodeById.get(f))
+        .filter((n): n is (typeof nodes)[number] => Boolean(n))
frontend/src/components/DependencyGraph/index.tsx (1)

93-104: Consider centralizing dir/risk helpers to avoid drift.
getDirPath / getMaxRisk duplicate logic in the clustering hook; a shared utility would reduce maintenance.

Comment thread frontend/src/components/DependencyGraph/index.tsx
- Add aria-pressed to toggle buttons for accessibility
- Build nodeMap for O(1) lookups in clustering hook
- Always render dir node so expand/collapse works correctly

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@frontend/src/components/DependencyGraph/hooks/useDirectoryClustering.ts`:
- Around line 42-116: The useDirectoryClustering hook is unused and duplicates
logic present in index.tsx; either remove it or consolidate to avoid
duplication. Option A: Delete useDirectoryClustering (and its helpers
getDirectoryPath/getMaxRisk) and update any imports if they exist; Option B:
Replace the inline clustering code in index.tsx with a call to
useDirectoryClustering (keeping helper functions only in the hook) and remove
the duplicated helper implementations from index.tsx; ensure exported symbol
useDirectoryClustering and its API (clusters, rootDirs, getClusterForFile,
toggleCluster) match how index.tsx consumes it and update imports accordingly.
🧹 Nitpick comments (3)
frontend/src/components/DependencyGraph/hooks/useDirectoryClustering.ts (1)

21-40: Helper functions duplicated in index.tsx.

getDirectoryPath, getParentDir, and getMaxRisk are also defined in index.tsx as getDirPath and getMaxRisk. If this hook is intended for use, consider exporting these helpers from a shared location to avoid duplication.

frontend/src/components/DependencyGraph/index.tsx (2)

93-104: Duplicate helper functions — consider extracting to shared module.

getDirPath and getMaxRisk are also defined in useDirectoryClustering.ts. If clustering logic evolves, maintaining two copies could lead to drift.


243-271: File hover highlighting not applied in clustered mode.

In non-clustered mode (lines 298), hoveredFileId upgrades a dimmed node to 'direct' state. This logic is missing for clustered mode, so hovering over files in the ImpactPanel won't highlight them in the graph when clustering is active.

💡 Suggested fix to add hover highlighting in clustered mode
           else if (selectedImpact?.transitiveDependents.includes(node.id)) state = 'transitive'
           else if (selectedNodeId && !selectedNodeId.startsWith('dir:')) state = 'dimmed'
+
+          if (hoveredFileId === node.id && state === 'dimmed') state = 'direct'

           flowNodes.push({

Comment thread frontend/src/components/DependencyGraph/hooks/useDirectoryClustering.ts Outdated
- Remove unused useDirectoryClustering.ts (dead code)
- Add hover highlighting for files in clustered mode
- Keeps helpers in index.tsx (single source of truth)
@vercel

vercel Bot commented Jan 28, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
opencodeintel Ready Ready Preview, Comment Jan 28, 2026 0:22am

@DevanshuNEU DevanshuNEU merged commit 5604d28 into OpenCodeIntel:main Jan 28, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant