Skip to content

Fix #426 Add loading states#427

Open
Anchel123 wants to merge 10 commits intostagingfrom
add-loading-states
Open

Fix #426 Add loading states#427
Anchel123 wants to merge 10 commits intostagingfrom
add-loading-states

Conversation

@Anchel123
Copy link
Contributor

@Anchel123 Anchel123 commented Mar 26, 2025

PR Type

Enhancement, Bug fix


Description

  • Added loading indicators for graph fetching and options loading.

    • Introduced isFetchingGraph state for graph loading.
    • Updated CodeGraph to display a spinner during graph fetching.
    • Enhanced Combobox to show a loading state when fetching options.
  • Improved Combobox behavior:

    • Disabled selection when no options are available and not fetching.
    • Added a spinner and message for fetching options.
  • Fixed minor issues and improved user experience:

    • Removed unnecessary debugger statement in GraphView.
    • Enhanced error handling for API fetch failures.

Changes walkthrough 📝

Relevant files
Enhancement
code-graph.tsx
Added loading state and spinner for graph fetching             

app/components/code-graph.tsx

  • Added isFetchingGraph state to manage graph loading.
  • Displayed a spinner when fetching the graph.
  • Updated UI to handle empty graph state more gracefully.
  • +16/-7   
    combobox.tsx
    Enhanced combobox with loading state and error handling   

    app/components/combobox.tsx

  • Added isFetchingOptions state for options loading.
  • Disabled combobox when no options are available.
  • Displayed spinner and messages during options fetching.
  • Improved API fetch error handling.
  • +44/-23 
    page.tsx
    Added graph loading state and improved error handling       

    app/page.tsx

  • Added isFetchingGraph state to manage graph loading.
  • Enhanced error handling for graph fetching API calls.
  • Updated CodeGraph component to use the new loading state.
  • +25/-18 
    Bug fix
    graphView.tsx
    Minor cleanup and zoom behavior improvement                           

    app/components/graphView.tsx

  • Removed unnecessary debugger statement.
  • Improved zoom behavior by resetting zoomed nodes.
  • +0/-1     

    Need help?
  • Type /help how to ... in the comments thread for any questions about Qodo Merge usage.
  • Check out the documentation for more information.
  • PR Summary by Typo

    Overview

    This PR addresses issue #426 by implementing loading states across the application, enhancing user experience during data fetching for graph visualizations and repository selection.

    Key Changes

    • Introduced isFetchingGraph state to display a loading spinner and message while fetching graph data in CodeGraph.tsx.
    • Added isFetchingOptions state and a loading spinner to the repository Combobox.tsx when fetching available repositories, along with a 30-second caching mechanism.
    • Disabled the combobox when options are being fetched or none are found.
    • Integrated the isFetchingGraph state into page.tsx to manage the loading status for graph data.
    • Removed an unnecessary debugger statement from graphView.tsx.

    Work Breakdown

    Category Lines Changed
    New Work 53 (52.0%)
    Churn 17 (16.7%)
    Refactor 32 (31.4%)
    Total Changes 102
    To turn off PR summary, please visit Notification settings.

    Summary by CodeRabbit

    • New Features

      • Loading spinners now display when fetching graph data, providing clear visual feedback during in-progress operations.
      • Loading indicators appear when fetching available repository options from the system.
    • Improvements

      • Repository option fetches are throttled to prevent excessive requests, occurring at most once every 30 seconds.
      • Enhanced overall UI responsiveness and user feedback during all data loading operations.

    - Introduced `isFetchingGraph` state to manage loading state in the graph component.
    - Updated `CodeGraph` to display a loading spinner while fetching the graph.
    - Enhanced `Combobox` to show a loading state when fetching options.
    - Updated the Combobox component to disable the select input when there are no options and not fetching options, improving user experience.
    @vercel
    Copy link

    vercel bot commented Mar 26, 2025

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

    Project Deployment Review Updated (UTC)
    code-graph Error Error Dec 22, 2025 2:36pm

    @coderabbitai
    Copy link
    Contributor

    coderabbitai bot commented Mar 26, 2025

    Warning

    Rate limit exceeded

    @gkorland has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 13 minutes and 15 seconds before requesting another review.

    ⌛ How to resolve this issue?

    After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

    We recommend that you space out your commits to avoid hitting the rate limit.

    🚦 How do rate limits work?

    CodeRabbit enforces hourly rate limits for each developer per organization.

    Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

    Please see our FAQ for further information.

    ℹ️ Review info
    ⚙️ Run configuration

    Configuration used: defaults

    Review profile: CHILL

    Plan: Pro

    Run ID: 0c743e9f-8996-45a8-98ff-7f67d6f44d85

    📥 Commits

    Reviewing files that changed from the base of the PR and between 17706ca and c7fcd10.

    📒 Files selected for processing (3)
    • app/src/App.tsx
    • app/src/components/code-graph.tsx
    • app/src/components/combobox.tsx
    📝 Walkthrough

    Walkthrough

    The changes introduce a new fetching state tracking system for graph operations in the App component, propagating it to CodeGraph to display loading indicators. Additionally, the Combobox component implements throttled repository option fetching with loading visuals and improved error handling.

    Changes

    Cohort / File(s) Summary
    Graph Fetch State Management
    app/src/App.tsx, app/src/components/code-graph.tsx
    Introduces isFetchingGraph state in App to track ongoing graph fetches, passed as a prop to CodeGraph. CodeGraph now displays a loading indicator (Loader2) when isFetchingGraph is true and manages options state locally instead of receiving it as props.
    Repository Options Fetching
    app/src/components/combobox.tsx
    Adds throttled option fetching (30-second intervals), loading state management (isFetchingOptions), visual loading indicators (Loader2 spinner with disabled select), improved error handling via toast notifications, and dedicated UI states for loading and empty options.

    Estimated code review effort

    🎯 3 (Moderate) | ⏱️ ~20 minutes

    Poem

    A loading spinner spins with delight, ✨
    As graphs and options fetch through the night,
    With throttled requests at a measured pace,
    And states well-tracked in each proper place,
    The UI feels smooth, the errors contained,
    User experience greatly maintained! 🐰

    🚥 Pre-merge checks | ✅ 2 | ❌ 1

    ❌ Failed checks (1 warning)

    Check name Status Explanation Resolution
    Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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 accurately summarizes the main change: adding loading states across the application, which aligns with the core modifications to App.tsx, code-graph.tsx, and combobox.tsx.

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

    ✨ Finishing Touches
    🧪 Generate unit tests (beta)
    • Create PR with unit tests
    • Commit unit tests in branch add-loading-states

    Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

    ❤️ Share

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

    @Anchel123 Anchel123 requested a review from barakb March 26, 2025 12:48
    @Anchel123 Anchel123 linked an issue Mar 26, 2025 that may be closed by this pull request
    @qodo-code-review
    Copy link
    Contributor

    Qodo Merge was enabled for this repository. To continue using it, please link your Git account with your Qodo account here.

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    ⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
    🧪 No relevant tests
    🔒 No security concerns identified
    ⚡ Recommended focus areas for review

    Prop Inconsistency

    The component signature has changed with options/setOptions being moved from props to internal state, but the component is still being called with these props in page.tsx.

    const [options, setOptions] = useState<string[]>([]);
    Error Handling

    The error handling in fetchOptions doesn't properly handle network errors (like connection failures) which could cause the loading state to remain indefinitely.

    try {
        const result = await fetch(`/api/repo`, {
            method: 'GET',
        })
    
        if (!result.ok) {
            toast({
                variant: "destructive",
                title: "Uh oh! Something went wrong.",
                description: await result.text(),
            })
            return 
        }
    
        const json = await result.json()
        setOptions(json.result)
    } finally {
        setIsFetchingOptions(false)
    }

    @qodo-code-review
    Copy link
    Contributor

    qodo-code-review bot commented Mar 26, 2025

    Qodo Merge was enabled for this repository. To continue using it, please link your Git account with your Qodo account here.

    PR Code Suggestions ✨

    Explore these optional code suggestions:

    CategorySuggestion                                                                                                                                    Impact
    Possible issue
    Fix parameter mismatch

    The function parameters don't match the Props interface. The options and
    setOptions parameters are missing in the function signature but are used later
    in the component. This mismatch could cause runtime errors.

    app/components/code-graph.tsx [48-58]

     export function CodeGraph({
         graph,
         data,
         setData,
         onFetchGraph,
         isFetchingGraph,
         onFetchNode,
    +    options,
    +    setOptions,
         isShowPath,
         setPath,
         chartRef,
         selectedValue,
    • Apply this suggestion
    Suggestion importance[1-10]: 9

    __

    Why: The function signature is missing the options and setOptions parameters that are defined in the Props interface and used in the component. This mismatch would cause runtime errors when the component tries to access these undefined props.

    High
    Remove duplicate state definition

    This component is redefining options and setOptions as local state, but these
    are also passed as props. This creates a conflict where the local state shadows
    the props, making the component ignore the props values and potentially causing
    inconsistent behavior.

    app/components/code-graph.tsx [85]

    -const [options, setOptions] = useState<string[]>([]);
    +// Remove this line as options and setOptions should be used from props
    +// const [options, setOptions] = useState<string[]>([]);
    • Apply this suggestion
    Suggestion importance[1-10]: 8

    __

    Why: The component defines local state for options and setOptions while also receiving them as props, creating a conflict where the local state shadows the props. This would cause the component to ignore the props values, breaking expected behavior.

    Medium
    Fix invalid select value

    The value prop is using string literals like "Fetching options..." and "No
    options found" which might not exist in the options array. This can cause React
    Select to have an invalid state where the selected value doesn't match any
    available option, potentially causing rendering issues or unexpected behavior.

    app/components/combobox.tsx [63]

    -<Select open={open} onOpenChange={setOpen} disabled={options.length === 0 && !isFetchingOptions} value={isFetchingOptions ? "Fetching options..." : options.length !== 0 ? selectedValue : "No options found"} onValueChange={onSelectedValue}>
    +<Select 
    +  open={open} 
    +  onOpenChange={setOpen} 
    +  disabled={options.length === 0 && !isFetchingOptions} 
    +  value={options.includes(selectedValue) ? selectedValue : ""} 
    +  onValueChange={onSelectedValue}
    +>
    • Apply this suggestion
    Suggestion importance[1-10]: 6

    __

    Why: The current implementation uses string literals as values that don't exist in the options array, which can cause React Select to have an invalid state. The improved code ensures the value is always valid by checking if the selectedValue exists in options.

    Low
    • Update

    AviAvni
    AviAvni previously approved these changes Apr 3, 2025
    @typo-app
    Copy link

    typo-app bot commented Dec 22, 2025

    Static Code Review 📊

    ✅ All quality checks passed!

    Copy link

    @typo-app typo-app bot left a comment

    Choose a reason for hiding this comment

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

    AI Code Review 🤖

    Files Reviewed: 4
    Comments Added: 1
    Lines of Code Analyzed: 134
    Critical Issues: 0

    PR Health: Excellent 🔥

    Give 👍 or 👎 on each review comment to help us improve.

    Resolve merge conflicts:
    - app/components/graphView.tsx: accept deletion (debugger fix already in staging)
    - app/page.tsx: accept deletion, apply isFetchingGraph to app/src/App.tsx
    - app/src/components/code-graph.tsx: merge Loader2+Button imports, add loading spinner
    - app/src/components/combobox.tsx: merge loading state with staging API/headers
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    …tion or class'
    
    Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
    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: 2

    🧹 Nitpick comments (1)
    app/src/components/combobox.tsx (1)

    61-66: Throttle timestamp set before async fetch completes.

    setLastFetch(now) is called before fetchOptions() starts. If the fetch fails, users must still wait 30 seconds before retrying. Consider moving setLastFetch into the try block after a successful fetch, or into finally, so failed fetches don't block immediate retries.

    ♻️ Proposed fix
             //check if last fetch was less than 30 seconds ago
             if (lastFetch && now - lastFetch < 30000) return;
    -        
    -        setLastFetch(now);
    -        
    -        fetchOptions()
    +
    +        fetchOptions().then(() => setLastFetch(now))
         }, [open])

    Or update the timestamp in fetchOptions after success.

    🤖 Prompt for AI Agents
    Verify each finding against the current code and only fix it if needed.
    
    In `@app/src/components/combobox.tsx` around lines 61 - 66, The throttle timestamp
    is set before the async fetch completes, which blocks retries if fetchOptions()
    fails; move the setLastFetch(now) call out of the pre-fetch path and instead
    update lastFetch only after a successful fetch (e.g. inside the try after await
    fetchOptions()) or alternatively in a finally block if you want to always record
    attempts; adjust the code around lastFetch, setLastFetch, fetchOptions and now
    so errors don't prevent immediate retry.
    
    🤖 Prompt for all review comments with AI agents
    Verify each finding against the current code and only fix it if needed.
    
    Inline comments:
    In `@app/src/components/combobox.tsx`:
    - Line 70: The Select is allowing placeholder strings to be chosen (causing
    onSelectedValue to receive "Fetching options..." or "No options found"); update
    the Select usage (component named Select with props
    open/onOpenChange/setOpen/disabled/value/onValueChange) to prevent selection of
    placeholders by disabling the control while options are loading or empty (i.e.,
    include isFetchingOptions in the disabled expression), and ensure the value
    passed is undefined/null when showing a placeholder instead of using the
    placeholder text as the selected value; alternatively remove placeholder items
    from the option list so only real options can be selected and onSelectedValue is
    only called for actual option values.
    - Around line 27-48: The fetch call in the async block that populates options
    can throw network errors which are currently swallowed; wrap the await
    fetch(...) and response handling in a try/catch (or add a catch after the
    existing try/finally) to catch exceptions, call toast with a descriptive error
    message (using the caught error.message) and ensure setIsFetchingOptions(false)
    remains in the finally; update the logic around setOptions(...) so it only runs
    on success and reference the existing symbols fetch(`/api/list_repos`),
    setOptions, setIsFetchingOptions, and toast when implementing the catch and
    toast error handling.
    
    ---
    
    Nitpick comments:
    In `@app/src/components/combobox.tsx`:
    - Around line 61-66: The throttle timestamp is set before the async fetch
    completes, which blocks retries if fetchOptions() fails; move the
    setLastFetch(now) call out of the pre-fetch path and instead update lastFetch
    only after a successful fetch (e.g. inside the try after await fetchOptions())
    or alternatively in a finally block if you want to always record attempts;
    adjust the code around lastFetch, setLastFetch, fetchOptions and now so errors
    don't prevent immediate retry.
    

    ℹ️ Review info
    ⚙️ Run configuration

    Configuration used: defaults

    Review profile: CHILL

    Plan: Pro

    Run ID: 21575903-fc11-444c-b409-d821e572aeac

    📥 Commits

    Reviewing files that changed from the base of the PR and between 887b82f and 17706ca.

    📒 Files selected for processing (3)
    • app/src/App.tsx
    • app/src/components/code-graph.tsx
    • app/src/components/combobox.tsx

    Anchel123 and others added 2 commits March 21, 2026 12:56
    - Introduced `isFetchingGraph` state to manage loading state in the graph component.
    - Updated `CodeGraph` to display a loading spinner while fetching the graph.
    - Enhanced `Combobox` to show a loading state when fetching options.
    …tion or class'
    
    Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
    @gkorland gkorland force-pushed the add-loading-states branch from 17706ca to 1b62f19 Compare March 21, 2026 10:57
    Copy link
    Contributor

    @gkorland gkorland left a comment

    Choose a reason for hiding this comment

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

    Rebased on staging and addressed review comments:

    1. Network error handling: Added catch block in fetchOptions() to show an error toast on fetch failures (network errors were previously swallowed).

    2. Placeholder selection prevention: Disabled the Select during loading (isFetchingOptions) and when no options are available. Changed value to undefined instead of placeholder text so onSelectedValue can never receive placeholder strings.

    3. Rebase conflicts: Resolved conflicts with staging's restructured paths (app/components/app/src/components/), API changes (/api/repo/api/list_repos), and styling updates (text-gray-400text-muted-foreground).

    gkorland and others added 2 commits March 21, 2026 13:35
    Add isFetchingGraph state to App.tsx and pass it to both desktop and
    mobile CodeGraph components. Set true on fetch start, false in finally
    block so the loading spinner renders correctly.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    ext = node.properties['ext']
    path = node.properties['path']
    name = node.properties['name']
    file = File(path, name, ext)
    self.assertIsNotNone(f)
    self.assertEqual(f.properties['name'], 'src.c')
    self.assertEqual(f.properties['ext'], '.c')
    self.assertEqual(File('', 'src.c', '.c'), f)

    def test_add_file(self):
    file = File(Path('/path/to/file.txt'), None)
    file = File('/path/to/file', 'file', 'txt')
    def test_file_add_function(self):
    file = File(Path('/path/to/file.txt'), None)
    self.graph.add_file(file)
    file = File('/path/to/file', 'file', 'txt')
    self.assertIsNotNone(f)
    self.assertEqual(f.properties['name'], 'src.py')
    self.assertEqual(f.properties['ext'], '.py')
    self.assertEqual(File('', 'src.py', '.py'), f)
    from api import Graph
    from api.entities import File
    from typing import List, Optional
    from api import *
    from falkordb import FalkorDB
    from api import Graph
    from api.entities import File
    from typing import List, Optional
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Projects

    None yet

    Development

    Successfully merging this pull request may close these issues.

    Add loading states

    3 participants