Skip to content

feat: Graph Filtering and Node Controls#226

Merged
webdevcody merged 9 commits intoAutoMaker-Org:mainfrom
JBotwina:graph-filtering-and-node-controls
Dec 23, 2025
Merged

feat: Graph Filtering and Node Controls#226
webdevcody merged 9 commits intoAutoMaker-Org:mainfrom
JBotwina:graph-filtering-and-node-controls

Conversation

@JBotwina
Copy link
Contributor

@JBotwina JBotwina commented Dec 23, 2025

Summary

  • Add graph filtering system with category, status, and search query filters
  • Implement positive/negative filter modes for highlighting or hiding nodes
  • Add node action controls (start, stop, resume, view logs) to task nodes
  • Enhance edge and node styling with highlight/dim states for filter feedback

Test plan

  • Verify category filter dropdown shows all available categories
  • Verify status filter dropdown filters nodes correctly
  • Test positive filter mode highlights matching nodes
  • Test negative filter mode dims matching nodes
  • Verify node action menu items trigger correct callbacks
  • Check edge highlighting updates when nodes are filtered

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • Added advanced filtering capabilities for graphs (categories and status filters) with toggle controls.
    • Introduced search functionality for graphs with visual highlighting of matched nodes and dependencies.
    • Enhanced task management with start, stop, and resume controls accessible from task dropdowns.
    • Added paused task indicators and status display in task nodes.
    • Visual feedback with animated glowing effects for search matches and dimmed states for filtered-out items.
    • Empty state messaging when filters are active with no matching results.
  • Chores

    • Updated dependencies with new package additions.

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 23, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

This pull request adds filtering and search capabilities to the graph view component along with task lifecycle management. It introduces a new filtering hook (useGraphFilter), adds visual highlighting states for nodes and edges, creates a new GraphFilterControls UI component, and propagates search state and task control callbacks through the component hierarchy. Dependencies include adding usehooks-ts.

Changes

Cohort / File(s) Summary
Dependencies
apps/ui/package.json
Added usehooks-ts dependency; reordered rehype-raw within dependencies list.
Graph View Component Hierarchy
apps/ui/src/components/views/board-view.tsx, apps/ui/src/components/views/graph-view/graph-view.tsx, apps/ui/src/components/views/graph-view/graph-canvas.tsx
Propagated searchQuery, onSearchQueryChange, and task control callbacks (onStartTask, onStopTask, onResumeTask) through component hierarchy; updated GraphCanvasProps to replace onNodeClick with search-focused props and node action callbacks.
Filtering & Highlighting Logic
apps/ui/src/components/views/graph-view/hooks/use-graph-filter.ts, apps/ui/src/components/views/graph-view/hooks/use-graph-nodes.ts, apps/ui/src/components/views/graph-view/hooks/index.ts
Introduced useGraphFilter hook to compute filter results (matched/highlighted nodes and edges); extended useGraphNodes to consume filter results and bind action callbacks; added NodeActionCallbacks interface and enhanced TaskNodeData with filter state flags (isMatched, isHighlighted, isDimmed) and action callback fields.
Graph Visualization Components
apps/ui/src/components/views/graph-view/components/task-node.tsx, apps/ui/src/components/views/graph-view/components/dependency-edge.tsx, apps/ui/src/components/views/graph-view/components/graph-filter-controls.tsx (new), apps/ui/src/components/views/graph-view/components/graph-controls.tsx, apps/ui/src/components/views/graph-view/components/graph-legend.tsx, apps/ui/src/components/views/graph-view/components/index.ts
Enhanced node/edge components with visual states for highlighting/dimming; introduced new GraphFilterControls component with dual-filter UI (categories and status); updated icon usage and styling utilities; exported new filter controls component.
Styling
apps/ui/src/styles/global.css
Added CSS classes for graph highlight states (.graph-node-matched, .graph-node-highlighted, .graph-node-dimmed, .graph-edge-highlighted, .graph-edge-dimmed) with animations; defined @keyframes matched-node-glow pulsing animation; updated reduced-motion media query to exclude animated graph classes.
Index Export
apps/ui/src/components/views/graph-view/index.ts
Reformatted export block to multi-line structure for consistency (no functional changes).

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant SearchUI as Search/Filter UI
    participant GraphCanvas
    participant useGraphFilter as useGraphFilter Hook
    participant GraphNodes as Graph Node Generation
    participant GraphViz as Visual Render

    User->>SearchUI: Input search query or filter
    SearchUI->>GraphCanvas: onSearchQueryChange / filterState update
    GraphCanvas->>useGraphFilter: features, filterState, runningAutoTasks
    useGraphFilter->>useGraphFilter: Compute matched nodes<br/>Traverse ancestors/descendants<br/>Apply category/status filters
    useGraphFilter-->>GraphCanvas: GraphFilterResult<br/>(matchedNodeIds, highlightedNodeIds,<br/>highlightedEdgeIds, hasActiveFilter)
    GraphCanvas->>GraphNodes: filterResult, actionCallbacks
    GraphNodes->>GraphNodes: Build nodes/edges with<br/>isMatched/isHighlighted/isDimmed
    GraphNodes-->>GraphCanvas: Enhanced TaskNodes<br/>& DependencyEdges
    GraphCanvas->>GraphViz: Render with highlighting classes<br/>& action handlers
    GraphViz-->>User: Visual feedback:<br/>matched glow, dimmed grayed,<br/>highlighted path emphasis
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • PR #222: Directly extends the same graph-view codebase with overlapping file modifications (GraphView/GraphCanvas, useGraphNodes, TaskNode/DependencyEdge, hooks), adding filtering and highlighting on top of the original graph-view implementation.
  • PR #216: Modifies the Feature data shape by removing Feature.steps property, which impacts graph visualization consumers and shared UI/domain types.

Suggested labels

Ready-To-Merge, Testers-Requested

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ 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 'feat: Graph Filtering and Node Controls' directly and accurately summarizes the main changes: adding a filtering system for the graph and implementing task node controls (start, stop, resume, view logs).
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @JBotwina, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the graph visualization component by introducing robust filtering capabilities and direct action controls for individual task nodes. Users can now easily narrow down their view of the graph using category, status, and search filters, and choose to either highlight or dim matching elements. Additionally, task nodes are more interactive with new options to manage their lifecycle directly from the graph. These changes aim to improve user experience by providing better control and clarity when navigating complex dependency graphs.

Highlights

  • Graph Filtering System: Introduced a comprehensive graph filtering system allowing users to filter nodes by category, status, and search query. This includes UI controls for selecting multiple categories and statuses.
  • Positive/Negative Filter Modes: Implemented a toggle for filter modes, enabling users to either highlight (positive mode) or dim/hide (negative mode) nodes that match the applied filters. This provides flexible visualization options.
  • Node Action Controls: Added a dropdown menu to task nodes, providing direct actions such as 'Start Task', 'Stop Task', 'Resume Task', 'View Agent Logs', 'View Details', and 'View Branch', enhancing interactivity and control over individual tasks.
  • Enhanced Node and Edge Styling: Updated the visual styling of nodes and edges to provide clear feedback on filter results. Matched nodes feature an animated glow, highlighted nodes and edges are visually emphasized, and non-matching elements are dimmed.
  • New Graph Filter Hook: Developed a new useGraphFilter hook responsible for calculating which nodes and edges should be matched, highlighted, or dimmed based on the current filter state and dependency relationships.
  • Dependency Management Updates: Numerous package-lock.json entries were updated, primarily by adding the "peer": true property to various dependencies, indicating a shift in how peer dependencies are declared or managed.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@JBotwina JBotwina changed the title Graph Filtering and Node Controls feat: Graph Filtering and Node Controls Dec 23, 2025
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a comprehensive filtering and control system for the graph view, which is a great enhancement. The implementation of filtering logic, node actions, and associated UI components is well-structured. However, I've found a critical issue in package.json that will break dependency installation, and a couple of medium-severity issues related to code clarity and a potential bug in the UI. Addressing these will improve the robustness and maintainability of the new features.

…ve onViewBranch

- Added onViewDetails callback to handle feature detail viewing.
- Removed onViewBranch functionality and associated UI elements for a cleaner interface.
@JBotwina JBotwina force-pushed the graph-filtering-and-node-controls branch from 6f3c05c to cb07206 Compare December 23, 2025 00:31
@JBotwina
Copy link
Contributor Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 23, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@JBotwina JBotwina marked this pull request as ready for review December 23, 2025 00:58
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
apps/ui/src/components/views/graph-view/components/graph-filter-controls.tsx (1)

263-295: Add explicit button type attribute.

The button element should have an explicit type="button" attribute to prevent potential issues if this component is ever rendered within a form context. While not critical in the current usage, it's a best practice for semantic clarity.

🔎 Suggested fix
                <button
+                 type="button"
                  onClick={() => onNegativeFilterChange(!isNegativeFilter)}
                  aria-label={
apps/ui/src/components/views/graph-view/graph-view.tsx (1)

49-49: Type cast is reasonable but consider narrowing the Feature type instead.

The cast f.branchName as string | undefined suggests branchName may have a broader type in the Feature interface. If Feature.branchName is actually typed as string | undefined | null, consider updating the interface to match expected runtime values, or add a null check here for safety.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 524a973 and fe6faf9.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (15)
  • apps/ui/package.json
  • apps/ui/src/components/views/board-view.tsx
  • apps/ui/src/components/views/graph-view/components/dependency-edge.tsx
  • apps/ui/src/components/views/graph-view/components/graph-controls.tsx
  • apps/ui/src/components/views/graph-view/components/graph-filter-controls.tsx
  • apps/ui/src/components/views/graph-view/components/graph-legend.tsx
  • apps/ui/src/components/views/graph-view/components/index.ts
  • apps/ui/src/components/views/graph-view/components/task-node.tsx
  • apps/ui/src/components/views/graph-view/graph-canvas.tsx
  • apps/ui/src/components/views/graph-view/graph-view.tsx
  • apps/ui/src/components/views/graph-view/hooks/index.ts
  • apps/ui/src/components/views/graph-view/hooks/use-graph-filter.ts
  • apps/ui/src/components/views/graph-view/hooks/use-graph-nodes.ts
  • apps/ui/src/components/views/graph-view/index.ts
  • apps/ui/src/styles/global.css
🧰 Additional context used
🧬 Code graph analysis (2)
apps/ui/src/components/views/graph-view/components/graph-filter-controls.tsx (4)
apps/ui/src/components/views/graph-view/hooks/use-graph-filter.ts (3)
  • StatusFilterValue (20-20)
  • GraphFilterState (4-9)
  • STATUS_FILTER_OPTIONS (12-18)
apps/ui/src/components/views/graph-view/hooks/index.ts (1)
  • GraphFilterState (9-9)
apps/ui/src/components/views/graph-view/components/index.ts (1)
  • GraphFilterControls (5-5)
apps/ui/src/lib/utils.ts (1)
  • cn (5-7)
apps/ui/src/components/views/graph-view/graph-view.tsx (3)
apps/ui/src/store/app-store.ts (1)
  • Feature (256-272)
apps/ui/src/components/views/graph-view/hooks/use-graph-nodes.ts (1)
  • NodeActionCallbacks (37-43)
apps/ui/src/components/views/graph-view/graph-canvas.tsx (1)
  • GraphCanvas (237-243)
🔇 Additional comments (27)
apps/ui/src/components/views/graph-view/components/graph-controls.tsx (2)

34-34: LGTM! Good styling consistency.

Adding text-popover-foreground ensures proper text color contrast within the popover container, aligning with the design system.


123-129: LGTM! Clean simplification of the lock toggle.

The consolidation of the className using cn(), inline ternary for the icon, and inline tooltip text improve code consistency and readability while preserving behavior.

apps/ui/package.json (1)

81-81: No action required. Version 3.1.1 is the latest version, and no direct vulnerabilities have been found for this package in Snyk's vulnerability database. The dependency is well-established with 1,998,347 weekly downloads and is scored as a key ecosystem project.

apps/ui/src/components/views/graph-view/index.ts (1)

4-9: LGTM!

The multi-line export formatting improves readability with no functional changes.

apps/ui/src/styles/global.css (1)

1052-1117: LGTM!

The new graph filter highlight states are well-structured with proper animation keyframes, hover states, and accessibility support through prefers-reduced-motion. The CSS classes align with the component usage in the filtering feature.

apps/ui/src/components/views/graph-view/components/graph-legend.tsx (2)

2-2: LGTM!

The consolidated import improves code conciseness with no behavioral changes.


47-47: LGTM!

The added text-popover-foreground class ensures consistent text color theming for the legend container.

apps/ui/src/components/views/graph-view/components/index.ts (1)

5-5: LGTM!

The new export properly exposes the GraphFilterControls component as part of the graph-view public API.

apps/ui/src/components/views/graph-view/hooks/index.ts (1)

1-9: LGTM!

The expanded exports properly expose the new filtering hook (useGraphFilter) and node action callbacks (NodeActionCallbacks) needed for the graph filtering and task control features.

apps/ui/src/components/views/board-view.tsx (1)

1039-1045: LGTM!

The new props properly integrate search state and task lifecycle controls into GraphView, maintaining consistency with the existing KanbanBoard implementation. The callback mappings to existing action handlers are correct.

apps/ui/src/components/views/graph-view/components/graph-filter-controls.tsx (2)

63-93: LGTM!

The toggle handlers correctly manage multi-select state for both categories and statuses. The select-all logic properly toggles between empty and fully selected states.


95-108: LGTM!

The label generation logic provides clear, user-friendly button text that adapts based on selection state (none, one, or multiple items).

apps/ui/src/components/views/graph-view/components/dependency-edge.tsx (2)

10-11: LGTM!

The new optional props extend the edge data interface to support filter-driven highlighting and dimming states.


57-104: LGTM!

The highlighting and dimming logic is well-implemented with proper priority handling:

  • Color prioritizes highlighted state over status-based colors
  • Stroke width scales appropriately (highlighted > selected > default > dimmed)
  • Visual effects (shadows, opacity) reinforce the state hierarchy
  • CSS classes align with the global styles for consistent theming
apps/ui/src/components/views/graph-view/graph-view.tsx (1)

77-112: LGTM! Well-structured action callback memoization.

The nodeActionCallbacks object is correctly memoized with all dependencies included. The pattern of looking up features by ID and calling the appropriate handler is clean and maintains a proper separation between ID-based callbacks (used by nodes) and Feature-based callbacks (used by parent components).

apps/ui/src/components/views/graph-view/hooks/use-graph-filter.ts (2)

118-121: Consider: isNegativeFilter alone triggers hasActiveFilter but results in matching all nodes.

When only isNegativeFilter is true (no search, category, or status filters), hasActiveFilter becomes true, but matchedNodeIds will be empty, so the negative inversion at lines 169-175 will select all features. This may be the intended behavior (show everything dimmed except... nothing), but it could be confusing for users. Consider whether isNegativeFilter should only contribute to hasActiveFilter when combined with other filters.


30-67: Well-implemented graph traversal helpers.

The getAncestors and getDescendants functions correctly handle cycles via the visited set, preventing infinite recursion in graphs with circular dependencies. The algorithms are clear and efficient.

apps/ui/src/components/views/graph-view/components/task-node.tsx (3)

213-232: Previous issue resolved: View Logs and View Details now call correct handlers.

The past review flagged that both menu items were calling onViewLogs. This has been fixed - "View Agent Logs" correctly calls data.onViewLogs?.() (line 217) and "View Details" correctly calls data.onViewDetails?.() (line 227).


81-87: LGTM! Clean state derivation with sensible defaults.

Filter highlight states use nullish coalescing for safe defaults, and the isStopped computation correctly identifies paused tasks (in_progress but not actively running).


296-304: Good UX addition for paused task indicator.

The visual feedback for paused tasks (progress bar at 50% + "Paused" label) clearly differentiates from running tasks. The warning color styling is consistent with the paused indicator in the header.

apps/ui/src/components/views/graph-view/graph-canvas.tsx (3)

73-90: LGTM! Well-structured filter state management with debouncing.

The filter state is cleanly organized with local state for categories/statuses/negative mode and a debounced search query (200ms) for performance. The filterState object correctly aggregates all filter criteria for the useGraphFilter hook.


214-230: Good empty state UX with clear call-to-action.

The empty state panel provides helpful feedback when filters yield no results, with a clear "Clear Filters" button to help users recover. The styling is consistent with the rest of the UI.


202-210: GraphFilterControls does not contain a search input and does not need to receive searchQuery.

The GraphFilterControls component is responsible only for category filtering, status filtering, and the negative filter toggle. It does not display or manage a search input field. The searchQuery is handled separately at the GraphCanvas level, where it is debounced and included in filterState for use by the useGraphFilter hook. This is the correct architecture—debouncing is applied before filter calculations, and no immediate UI feedback is lost since the search input that exists elsewhere (controlled externally) can still display user input in real time.

apps/ui/src/components/views/graph-view/hooks/use-graph-nodes.ts (4)

100-114: Non-null assertions are safe here due to conditional checks.

The pattern actionCallbacks?.onViewLogs ? () => actionCallbacks.onViewLogs!(feature.id) : undefined is correct - the non-null assertion is guarded by the truthiness check in the ternary condition.


56-61: Verify actionCallbacks is memoized in parent to prevent unnecessary recalculations.

The useMemo dependency on actionCallbacks (line 153) will cause recalculation if a new object reference is passed on each render. Confirm that GraphView memoizes nodeActionCallbacks (which it does at lines 78-112 in graph-view.tsx). This is correctly implemented.

Also applies to: 153-153


30-35: LGTM! DependencyEdge type correctly extended for filter states.

The edge data type now includes isHighlighted and isDimmed optional booleans, aligning with the node highlight system.


127-127: Edge ID format consistency is critical - verified to match.

The edge ID format ${depId}->${feature.id} matches the format used in use-graph-filter.ts (line 82), ensuring edge highlighting works correctly.

@webdevcody webdevcody merged commit 7618a75 into AutoMaker-Org:main Dec 23, 2025
6 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.

2 participants