Skip to content

Conversation

@mdroidian
Copy link
Contributor

@mdroidian mdroidian commented Aug 29, 2025

image
  • Replaced promise chaining with async/await and try/catch for improved error handling.
  • Simplified the fetching logic for main and referenced node options.
  • Updated useEffect dependencies for better clarity and performance.
  • Changed referencedNode retrieval to use useMemo for optimization.

Summary by CodeRabbit

  • Bug Fixes

    • Resolved intermittent loading and synchronization issues in label suggestions.
    • Ensured suggestions refresh correctly when node type or referenced node changes.
  • Performance & UX

    • Faster, more responsive autocomplete with smoother updates.
    • Consistent loading indicator and reduced UI flicker.
  • Refactor

    • Streamlined data loading with a clearer async flow.
    • Improved state derivation using memoization for referenced nodes.
    • Added basic error handling to avoid silent failures.

- Replaced promise chaining with async/await and try/catch for improved error handling.
- Simplified the fetching logic for main and referenced node options.
- Updated useEffect dependencies for better clarity and performance.
- Changed referencedNode retrieval to use useMemo for optimization.
@linear
Copy link

linear bot commented Aug 29, 2025

@supabase
Copy link

supabase bot commented Aug 29, 2025

This pull request has been ignored for the connected project zytfjzqyijgagqxrzbmz because there are no changes detected in packages/database/supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@mdroidian
Copy link
Contributor Author

@CodeRabbit full review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 29, 2025

✅ Actions performed

Full review triggered.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 29, 2025

📝 Walkthrough

Walkthrough

Refactors LabelDialogAutocomplete to use an async fetchOptions with async/await and proper loading/error handling, replacing timer- and promise-chained logic. Adds memoized referencedNode computation in LabelDialog. Updates effects and props wiring. Introduces separate queries for main nodeType and optional referenced node type.

Changes

Cohort / File(s) Summary
Canvas Label Dialog async data fetching
apps/roam/src/components/canvas/LabelDialog.tsx
- Replaced setTimeout/.then chain with async fetchOptions using try/catch/finally and loading state toggling
- Generates per-request UIDs; performs awaited fireQuery calls for nodeType and optionally referenced node type
- Updates options and referencedNodeOptions accordingly; logs errors
- Updated useEffect deps (nodeType, isAddReferencedNode, referencedNode)
- Replaced getReferencedNodeInFormat with useMemo-derived referencedNode; passed to LabelDialogAutocomplete

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User
  participant LD as LabelDialog
  participant LDA as LabelDialogAutocomplete
  participant Q as fireQuery

  U->>LD: Open Label Dialog
  LD->>LD: useMemo compute referencedNode
  LD->>LDA: Render with nodeType, isAddReferencedNode, referencedNode

  rect rgba(200,230,255,0.3)
    note right of LDA: Fetch main options
    LDA->>LDA: setLoading(true)
    LDA->>Q: fireQuery(nodeType, uid₁)
    Q-->>LDA: options
    LDA->>LDA: setOptions(...)
    LDA->>LDA: setLoading(false)
  end

  alt isAddReferencedNode && referencedNode
    rect rgba(220,255,220,0.3)
      note right of LDA: Fetch referenced node options
      LDA->>LDA: setLoading(true)
      LDA->>Q: fireQuery(referencedNode.nodeType, uid₂)
      Q-->>LDA: referenced options
      LDA->>LDA: setReferencedNodeOptions(...)
      LDA->>LDA: setLoading(false)
    end
  else No referenced fetch
    note right of LDA: Skip referenced fetch
  end

  opt Error case
    LDA->>LDA: catch -> console.error(...)
    LDA->>LDA: setLoading(false)
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.


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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbit in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbit in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbit gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbit read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbit help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbit ignore or @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbit summary or @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbit or @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/roam/src/components/canvas/LabelDialog.tsx (1)

328-347: Avoid dynamic RegExp usage and variable shadowing in LabelDialog.tsx

  • In the useMemo block (around lines 335–343), rename the inner referencedNode to refNode and replace the unsafe regex test with a case-insensitive string comparison:
-    const referencedNode = Object.values(discourseContext.nodes).find(
-      ({ text }) => new RegExp(text, "i").test(val),
-    );
-    if (referencedNode) {
-      return { name: referencedNode.text, nodeType: referencedNode.type };
+    const refNode = Object.values(discourseContext.nodes).find(
+      ({ text }) => text.toLowerCase() === val.toLowerCase(),
+    );
+    if (refNode) {
+      return { name: refNode.text, nodeType: refNode.type };
  • In the setValue callback (around line 133), replace the dynamic regex with a direct comparison:
-  if (
-    referencedNode &&
-    new RegExp(referencedNode.name, "i").test(val) &&
-    isAddReferencedNode
-  )
+  if (
+    referencedNode &&
+    referencedNode.name.toLowerCase() === val.toLowerCase() &&
+    isAddReferencedNode
+  )
🧹 Nitpick comments (1)
apps/roam/src/components/canvas/LabelDialog.tsx (1)

221-224: Prefer e.currentTarget over e.target in Checkbox onChange

Using e.target can be wrong when events bubble from nested elements. currentTarget is the checkbox.

- onChange={(e) => {
-   const checked = e.target as HTMLInputElement;
-   setIsEditExistingLabel(checked.checked);
- }}
+ onChange={(e) => setIsEditExistingLabel(e.currentTarget.checked)}
- onChange={(e) => {
-   const checked = e.target as HTMLInputElement;
-   setAddReferencedNode(checked.checked);
- }}
+ onChange={(e) => setAddReferencedNode(e.currentTarget.checked)}

Also applies to: 238-241

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 6bcad0d and c5889f9.

📒 Files selected for processing (1)
  • apps/roam/src/components/canvas/LabelDialog.tsx (3 hunks)

- Introduced request ID tracking to prevent stale state updates during asynchronous fetching.
- Added cleanup logic in useEffect to manage component lifecycle and avoid memory leaks.
- Improved error handling to ensure console errors are logged only for the latest request.
- Maintained existing async/await structure for fetching options, enhancing clarity and performance.
@mdroidian mdroidian merged commit e8c4576 into main Aug 29, 2025
5 checks passed
@github-project-automation github-project-automation bot moved this to Done in General Aug 29, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

No open projects
Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants