Skip to content

Conversation

@trangdoan982
Copy link
Collaborator

@trangdoan982 trangdoan982 commented May 7, 2025

https://www.loom.com/share/b76845e3d8934501b6a89fae687e5d95

Summary by CodeRabbit

  • New Features
    • Search now dynamically fetches and filters discourse node types based on user backing.
    • Search results are grouped by dynamic discourse types, with a loading indicator shown during fetch.
    • Debounced search input reduces query frequency for better performance.
    • Improved UI with grouped results, type-based filtering, and robust keyboard navigation.
  • Bug Fixes
    • Enhanced event handling and scroll management for more reliable user interaction.
  • Refactor
    • Replaced static test data with dynamic, query-driven search and filtering.
  • Chores
    • Minor code cleanup for improved maintainability.

@linear
Copy link

linear bot commented May 7, 2025

@vercel
Copy link

vercel bot commented May 7, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

1 Skipped Deployment
Name Status Preview Comments Updated (UTC)
discourse-graph ⬜️ Skipped (Inspect) May 14, 2025 9:17pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented May 7, 2025

📝 Walkthrough

Walkthrough

The changes refactor the DiscourseNodeSearchMenu component to dynamically fetch and filter discourse node types, implement asynchronous loading and debounced search, and update UI and event handling accordingly. Additionally, a utility function for escaping strings is introduced, and a minor formatting change is made in an observer utility file.

Changes

File(s) Change Summary
apps/roam/src/components/DiscourseNodeSearchMenu.tsx Refactored to use dynamically fetched discourse node types, added async loading, debounced search, improved UI, and robust event handling.
apps/roam/src/utils/formatUtils.ts Added escapeCljString utility function for escaping and lowercasing strings.
apps/roam/src/utils/initializeObserversAndListeners.ts Removed a trailing blank line after a variable assignment; no logic changed.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant NodeSearchMenu
  participant RoamAPI

  User->>NodeSearchMenu: Opens search menu
  NodeSearchMenu->>RoamAPI: Fetch discourse node types (async)
  RoamAPI-->>NodeSearchMenu: Return discourse node types
  NodeSearchMenu->>User: Display loading indicator, then show types

  User->>NodeSearchMenu: Types search term (debounced)
  NodeSearchMenu->>RoamAPI: Query nodes by regex for each type
  RoamAPI-->>NodeSearchMenu: Return matching nodes
  NodeSearchMenu->>User: Display grouped search results

  User->>NodeSearchMenu: Selects a result
  NodeSearchMenu->>RoamAPI: Insert node reference, manage cursor/focus
  NodeSearchMenu->>User: Close menu
Loading

Possibly related PRs

  • DiscourseGraphs/discourse-graph#138: Refactored the NodeSearchMenu component, replacing static discourse types with dynamic fetching and enhanced search, forming the foundation for the current changes.

Poem

In the warren of code, a search menu anew,
With types fetched on whim and results in a queue.
No more static carrots, just dynamic delight,
Debounced and escaped, everything feels right.
A hop and a scroll, the results all in view—
This bunny approves of the work that you do!
🥕✨

Note

⚡️ AI Code Reviews for VS Code, Cursor, Windsurf

CodeRabbit now has a plugin for VS Code, Cursor and Windsurf. This brings AI code reviews directly in the code editor. Each commit is reviewed immediately, finding bugs before the PR is raised. Seamless context handoff to your AI code agent ensures that you can easily incorporate review feedback.
Learn more here.


Note

⚡️ Faster reviews with caching

CodeRabbit now supports caching for code and dependencies, helping speed up reviews. This means quicker feedback, reduced wait times, and a smoother review experience overall. Cached data is encrypted and stored securely. This feature will be automatically enabled for all accounts on May 16th. To opt out, configure Review - Disable Cache at either the organization or repository level. If you prefer to disable all data retention across your organization, simply turn off the Data Retention setting under your Organization Settings.
Enjoy the performance boost—your workflow just got faster.

✨ Finishing Touches
  • 📝 Generate Docstrings

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.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai 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:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

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

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @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

Documentation and Community

  • 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.

@trangdoan982
Copy link
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented May 7, 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.

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: 3

🧹 Nitpick comments (5)
apps/roam/src/index.ts (1)

141-144: Consider defensive removal in unload

If another script removes the listener earlier, removeEventListener is still safe, but you might guard with an existence check for symmetry with the registration block (minor).

apps/roam/src/utils/initializeObserversAndListeners.ts (1)

229-234: Minor: listeners array → object mismatch

observers is still an array but listeners is now an object. To keep the API symmetrical you may want to plural-rename to listenerMap or similar.

apps/roam/src/components/DiscourseNodeSearchMenu.tsx (3)

70-84: Potential O(N²) spread in reduce

Using spread inside every .reduce() iteration reallocates and copies the accumulator:

const initialCheckedTypes = allNodeTypes.reduce(
  (acc, type) => ({ ...acc, [type.type]: true }),
  {},
);

For ~hundreds of discourse types this can be noticeably slower.

-const initialCheckedTypes = allNodeTypes.reduce(
-  (acc, type) => ({ ...acc, [type.type]: true }),
-  {},
-);
+const initialCheckedTypes: Record<string, boolean> = {};
+allNodeTypes.forEach((t) => {
+  initialCheckedTypes[t.type] = true;
+});

291-296: Remove redundant !! cast

textarea.closest(...) returns an element | null, which is already truthy/falsy:

-const listeningEl = !!textarea.closest(".rm-reference-item")
-  ? textarea.parentElement
-  : textarea;
+const listeningEl = textarea.closest(".rm-reference-item")
+  ? textarea.parentElement
+  : textarea;
🧰 Tools
🪛 Biome (1.9.4)

[error] 291-291: Avoid redundant double-negation.

It is not necessary to use double-negation when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant double-negation

(lint/complexity/noExtraBooleanCast)


214-219: Analytics event fires before block update completes

posthog.capture is executed synchronously after scheduling updateBlock. If the update fails the analytics becomes misleading. Capture inside the then of updateBlock or use await.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a98ae88 and 0a233d0.

📒 Files selected for processing (3)
  • apps/roam/src/components/DiscourseNodeSearchMenu.tsx (1 hunks)
  • apps/roam/src/index.ts (2 hunks)
  • apps/roam/src/utils/initializeObserversAndListeners.ts (3 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
apps/roam/src/utils/initializeObserversAndListeners.ts (1)
apps/roam/src/components/DiscourseNodeSearchMenu.tsx (1)
  • renderDiscourseNodeSearchMenu (440-459)
🪛 Biome (1.9.4)
apps/roam/src/components/DiscourseNodeSearchMenu.tsx

[error] 291-291: Avoid redundant double-negation.

It is not necessary to use double-negation when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant double-negation

(lint/complexity/noExtraBooleanCast)


[error] 109-109: Avoid the use of spread (...) syntax on accumulators.

Spread syntax should be avoided on accumulators (like those in .reduce) because it causes a time complexity of O(n^2).
Consider methods such as .splice or .push instead.

(lint/performance/noAccumulatingSpread)


[error] 115-115: Avoid the use of spread (...) syntax on accumulators.

Spread syntax should be avoided on accumulators (like those in .reduce) because it causes a time complexity of O(n^2).
Consider methods such as .splice or .push instead.

(lint/performance/noAccumulatingSpread)

🔇 Additional comments (4)
apps/roam/src/index.ts (1)

101-110: ✅ Correctly integrates new search-trigger listener

Nice job updating the destructuring and registering the new discourseNodeSearchTriggerListener. The listener is added and later removed, so no memory-leak concerns here.

apps/roam/src/utils/initializeObserversAndListeners.ts (2)

37-38: Import looks good

New import is scoped and tree-shake-able.


45-50: Good shift from array → named object

Returning a named object ({ pageActionListener, … }) increases clarity and prevents parameter order bugs.

apps/roam/src/components/DiscourseNodeSearchMenu.tsx (1)

255-265: Suppress horizontal-arrow propagation only when needed

Preventing default on ArrowLeft/ArrowRight globally can block users from normal cursor movement in the textarea while the menu is open. Consider handling those keys only when you use them for navigation.

@trangdoan982 trangdoan982 requested a review from mdroidian May 7, 2025 18:25
@trangdoan982 trangdoan982 changed the base branch from main to eng-235-create-dg-summoning-menu May 7, 2025 20:06
@mdroidian
Copy link
Contributor

Until #138 is merged, I'm going to change the base to #138

@mdroidian mdroidian changed the base branch from eng-235-create-dg-summoning-menu to eng-259-observer May 7, 2025 20:19
Copy link
Contributor

@mdroidian mdroidian left a comment

Choose a reason for hiding this comment

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

💥

@trangdoan982 trangdoan982 changed the base branch from eng-259-observer to eng-235-create-dg-summoning-menu May 12, 2025 18:09
@trangdoan982 trangdoan982 requested a review from mdroidian May 13, 2025 22:25
@mdroidian
Copy link
Contributor

mdroidian commented May 15, 2025

@coderabbitai review

@coderabbitai

This comment was marked as duplicate.

1 similar comment
@coderabbitai
Copy link
Contributor

coderabbitai bot commented May 15, 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.

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

♻️ Duplicate comments (1)
apps/roam/src/components/DiscourseNodeSearchMenu.tsx (1)

129-132: O(n²) spread inside reduce – convert to mutable push

Static analysis correctly flags this pattern; each spread copies the accumulator.

-const initialSearchResults = allNodeTypes.reduce(
-  (acc, type) => ({ ...acc, [type.type]: [] }),
-  {},
-);
+const initialSearchResults: Record<string, Result[]> = {};
+allNodeTypes.forEach((t) => {
+  initialSearchResults[t.type] = [];
+});

This brings the complexity down to O(n).

🧰 Tools
🪛 Biome (1.9.4)

[error] 130-130: Avoid the use of spread (...) syntax on accumulators.

Spread syntax should be avoided on accumulators (like those in .reduce) because it causes a time complexity of O(n^2).
Consider methods such as .splice or .push instead.

(lint/performance/noAccumulatingSpread)

🧹 Nitpick comments (3)
apps/roam/src/utils/formatUtils.ts (1)

198-201: Avoid forcing lowercase & broaden escaping scope

escapeCljString silently lower-cases every input, which may unintentionally break case-sensitive searches (includes? is case-sensitive) and alter user supplied text.
Additionally, only back-slashes and double-quotes are escaped – single quotes, back-ticks and new-lines may also appear in user input and break the Clojure string literal.

-export const escapeCljString = (str: string) => {
-  return str.replace(/\\/g, "\\\\").replace(/"/g, '\\"').toLowerCase();
-};
+export const escapeCljString = (str: string) => {
+  // Escape \" \\ \n and leave the original casing intact
+  return str
+    .replace(/\\/g, "\\\\")
+    .replace(/"/g, '\\"')
+    .replace(/\n/g, "\\n");
+};

If a lower-case comparison is required, convert both operands at the call site instead of mutating the original string.

apps/roam/src/components/DiscourseNodeSearchMenu.tsx (2)

65-75: Use browser-compatible timer type

useRef<NodeJS.Timeout> pulls the Node typings; in a browser build this often resolves to number, causing type-mismatch noise. Prefer ReturnType<typeof setTimeout>.

-const searchTimeoutRef = useRef<NodeJS.Timeout | null>(null);
+const searchTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);

469-481: Side-effectful currentGlobalIndex makes render order brittle

Relying on a mutable counter mutated during render couples the visual list to the evaluation order. Use the already-computed allItems array to derive isActive instead:

{searchResults[type.type]?.map((item, localIdx) => {
-  currentGlobalIndex++;
-  const isActive = currentGlobalIndex === activeIndex;
+  const globalIdx = allItems.findIndex((i) => i.item.uid === item.uid);
+  const isActive = globalIdx === activeIndex;

This removes the hidden dependency and works even if render order ever changes.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0a233d0 and 0063494.

📒 Files selected for processing (3)
  • apps/roam/src/components/DiscourseNodeSearchMenu.tsx (7 hunks)
  • apps/roam/src/utils/formatUtils.ts (1 hunks)
  • apps/roam/src/utils/initializeObserversAndListeners.ts (0 hunks)
💤 Files with no reviewable changes (1)
  • apps/roam/src/utils/initializeObserversAndListeners.ts
🧰 Additional context used
🪛 Biome (1.9.4)
apps/roam/src/components/DiscourseNodeSearchMenu.tsx

[error] 130-130: Avoid the use of spread (...) syntax on accumulators.

Spread syntax should be avoided on accumulators (like those in .reduce) because it causes a time complexity of O(n^2).
Consider methods such as .splice or .push instead.

(lint/performance/noAccumulatingSpread)

Copy link
Contributor

@mdroidian mdroidian left a comment

Choose a reason for hiding this comment

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

🔥

@mdroidian mdroidian merged commit 5b410c2 into eng-235-create-dg-summoning-menu May 15, 2025
5 checks passed
@github-project-automation github-project-automation bot moved this to Done in General May 15, 2025
@mdroidian mdroidian deleted the eng-261-menu-query branch May 15, 2025 04:02
mdroidian pushed a commit that referenced this pull request May 27, 2025
* [ENG-259] Create Observer and UI pattern (#138)

* create event listener for @ key

* fix ui

* address PR comments

* cur progress

* current progress

* tested yayyy

* add the checkbox UI

* fix focus issue

* rm logs

* address PR comments

* address PR comments

* [ENG-261] Query function for DG summoning menu (#150)

* cur progress

* current progress

* rm logs

* address PR comments

* address PR comments

* query works

* address PR comments

* address PR comments

* sm change

* [ENG-299] Trigger setting for DG summoning menu (#162)

* setting menu done

* trigger works correctly

* clean up

* address PR comment

* optimize getFocusedBlock()

* address nit comments

* fix bug (#166)

* address PR comments
@coderabbitai coderabbitai bot mentioned this pull request Jun 11, 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.

3 participants