Skip to content

ENG-949: Add query sections to left sidebar#1056

Open
sid597 wants to merge 6 commits into
mainfrom
eng-949-add-query-and-query-results-in-the-left-sidebar-v2
Open

ENG-949: Add query sections to left sidebar#1056
sid597 wants to merge 6 commits into
mainfrom
eng-949-add-query-and-query-results-in-the-left-sidebar-v2

Conversation

@sid597
Copy link
Copy Markdown
Collaborator

@sid597 sid597 commented May 20, 2026

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

Summary by CodeRabbit

  • New Features
    • Query blocks can now be used as dynamic sidebar sections with lazy-loading results.
    • Added customizable alias names for query sections.
    • Added configurable result limits for query section outputs.
    • Added refresh action and collapsible UI with loading/error/empty states.

Review Change Stack

@linear-code
Copy link
Copy Markdown

linear-code Bot commented May 20, 2026

ENG-949

@supabase
Copy link
Copy Markdown

supabase Bot commented May 20, 2026

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 ↗︎.

@sid597
Copy link
Copy Markdown
Collaborator Author

sid597 commented May 20, 2026

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 20, 2026

✅ Actions performed

Full review triggered.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b645caa0f3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/roam/src/utils/getLeftSidebarSettings.ts
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 20, 2026

📝 Walkthrough

Walkthrough

This PR extends the left sidebar to support query-block sections as a new section type. Query sections run Roam queries and display results, with customizable alias names and result limits that persist to Roam blocks. The implementation adds schema fields, parsing utilities, a settings UI for configuration, and a new QuerySectionItem component for rendering.

Changes

Query-block sidebar sections

Layer / File(s) Summary
Schema and data model
apps/roam/src/components/settings/utils/zodSchema.ts, apps/roam/src/utils/getExportSettings.ts, apps/roam/src/components/settings/utils/zodSchema.example.ts
PersonalSectionSchema.Settings adds Alias (string, default "") and "Result-limit" (number, default 0). New StringSettingWithValueUid type and getUidAndStringSettingWithValueUid() function extract and track value UIDs for string settings. Example schemas updated to include new fields.
Settings parsing and detection utilities
apps/roam/src/utils/getLeftSidebarSettings.ts, apps/roam/src/components/settings/utils/accessors.ts
isQueryBlockRef() predicate detects full block references that are not smart-block UIDs. getPersonalSectionSettings() and mergePersonalSectionsWithAccessor() parse and wire Alias and Result-limit from settings trees. Legacy accessor emits new settings-derived properties.
Query-block section settings UI and state persistence
apps/roam/src/components/settings/LeftSidebarPersonalSettings.tsx
sectionsToBlockProps() persists new settings fields. SectionItem detects query-block sections, initializes alias state with debounced updates, and branches rendering to show alias input and settings controls instead of standard child list. addSection() creates settings subtree for query blocks. Settings dialog adds result-limit number panel.
Query section component and sidebar integration
apps/roam/src/components/LeftSidebarView.tsx
New QuerySectionItem component runs queries on open, transforms results into child rows, supports truncation and result limits, renders collapsible header with fold toggle and "more" menu for refresh and go-to-query actions. PersonalSections conditionally routes between QuerySectionItem and PersonalSectionItem based on isQueryBlockRef().

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • DiscourseGraphs/discourse-graph#440: Introduces foundational left-sidebar rendering and PersonalSectionItem behaviors (alias/truncate/fold) that are extended by this PR with additional query-ref section type.
  • DiscourseGraphs/discourse-graph#439: Modifies the same getLeftSidebarSettings.ts settings extraction pipeline; this PR extends it further with query-block detection and result-limit handling.
  • DiscourseGraphs/discourse-graph#804: Modifies the left-sidebar personal settings pipeline in LeftSidebarPersonalSettings.tsx with sync logic that this PR leverages to persist query-block alias and result-limit fields.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main feature addition: enabling query sections in the left sidebar navigation component.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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


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.

Copy link
Copy Markdown
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

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/roam/src/components/settings/LeftSidebarPersonalSettings.tsx`:
- Around line 348-394: The debounce timeout set in handleAliasChange via
aliasUpdateTimeoutRef can fire after the component unmounts; add a cleanup
effect that clears aliasUpdateTimeoutRef.current on unmount to prevent stale
writes. Implement a useEffect with no dependencies (or appropriate lifecycle)
that returns a cleanup function calling
clearTimeout(aliasUpdateTimeoutRef.current) and nulling
aliasUpdateTimeoutRef.current, ensuring handleAliasChange, aliasUpdateTimeoutRef
and any created timeouts are cancelled when the component unmounts.
- Around line 742-753: The default for the new query section "Result-limit" is
inconsistent: the node initialization sets the child text to "10" while the
newSection.settings.resultLimit.value is 10, but the schema/default snapshots
expect 0 (unlimited). Update both the block node initialization (the child text
under node: { text: "Result-limit", children: [...] }) and the
newSection.settings.resultLimit.value (where resultLimit is created with uid:
resultLimitUid) to use 0 so the created section matches the schema/default
snapshots.

In `@apps/roam/src/components/settings/utils/zodSchema.ts`:
- Line 225: The "Result-limit" schema currently uses z.number().default(0) which
permits negative and fractional values; update the Zod schema for the
"Result-limit" field to require a non-negative integer (use Zod integer +
minimum zero validation) while preserving the default of 0 so runtime slicing
cannot receive negatives or decimals.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 7a813ba3-f8cb-4ddd-b71b-630631050145

📥 Commits

Reviewing files that changed from the base of the PR and between 6a7bca8 and b645caa.

📒 Files selected for processing (7)
  • apps/roam/src/components/LeftSidebarView.tsx
  • apps/roam/src/components/settings/LeftSidebarPersonalSettings.tsx
  • apps/roam/src/components/settings/utils/accessors.ts
  • apps/roam/src/components/settings/utils/zodSchema.example.ts
  • apps/roam/src/components/settings/utils/zodSchema.ts
  • apps/roam/src/utils/getExportSettings.ts
  • apps/roam/src/utils/getLeftSidebarSettings.ts

Comment thread apps/roam/src/components/settings/LeftSidebarPersonalSettings.tsx
Comment thread apps/roam/src/components/settings/LeftSidebarPersonalSettings.tsx
Comment thread apps/roam/src/components/settings/utils/zodSchema.ts Outdated
Comment thread apps/roam/src/components/settings/LeftSidebarPersonalSettings.tsx
@sid597
Copy link
Copy Markdown
Collaborator Author

sid597 commented May 22, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5c5f06fd90

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/roam/src/components/LeftSidebarView.tsx Outdated
Comment thread apps/roam/src/components/settings/LeftSidebarPersonalSettings.tsx Outdated
@sid597 sid597 requested a review from mdroidian May 26, 2026 10:37
Copy link
Copy Markdown
Member

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

A couple possible blockers:

  • Could you point to me where the alias is being store in block props? I see createBlock a few places, but no check/handle of use new store settings.
  • we should reuse the query builder observer regex/observer checking logic if possible for {{query block}}

Comment thread apps/roam/src/components/settings/LeftSidebarPersonalSettings.tsx
Comment thread apps/roam/src/components/settings/LeftSidebarPersonalSettings.tsx Outdated
Comment thread apps/roam/src/components/LeftSidebarView.tsx Outdated
Comment thread apps/roam/src/components/LeftSidebarView.tsx Outdated
};

const BLOCK_REF_FULL_MATCH = new RegExp(`^${BLOCK_REF_REGEX.source}$`);
const QUERY_BLOCK_MARKER = /\{\{query block(?::[^}]*)?\}\}/;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This should exist in a few places already. Try to see if we can DRY this.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

the existing spots:

  • parseResultSettings.ts:41 has /{{query block:(.*?)}}/, but that only handles {{query block:alias}}.
  • listActiveQueries.ts:8 checks {{query block}}, but not {{query block:alias}}.
  • resolveQueryBuilderRef.ts:11 checks one known alias: {{query block:${queryRef}}}.
  • initializeObserversAndListeners.ts:146-147 uses createButtonObserver({ attribute: "query-block" }), but that is for rendered DOM buttons, not raw block text.

So there is no existing exported helper that covers both raw block forms: {{query block}} and {{query block:alias}}.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

listActiveQueries should be checking for both. We could reuse it there.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

you mean to fix listActiveQueries and then use that here?

If we do that then there is circular dependency and need more refactoring to circumvent that do we want to do that here? I am fine either way.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What is the circular dependency?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

-> Modify listActiveQueries.ts
-> Import it into getLeftsidebarSettings.ts

Now the import path is:

  getLeftSidebarSettings.ts
    imports listActiveQueries.ts

  listActiveQueries.ts
    imports getQueryPages from QueryPagesPanel.tsx

  QueryPagesPanel.tsx
    imports getPersonalSetting from accessors.ts

  accessors.ts
    imports getLeftSidebarSettings.ts

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ah, no, just export and reuse the QUERY_BLOCK_MARKER

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Should listActiveQueries.ts find both the normal query blocks and query blocks with aliases? currently it only searches for the {{query block}} ?

const BLOCK_REF_FULL_MATCH = new RegExp(`^${BLOCK_REF_REGEX.source}$`);
const QUERY_BLOCK_MARKER = /\{\{query block(?::[^}]*)?\}\}/;

export const isQueryBlockRef = (text: string): boolean => {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

How does the current query block observer handle this? Can we reuse that logic instead of writing it again?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

The current observer watches the button Roam displays for {{query block}} blocks (initializeObserversAndListeners.ts:146-149). In this sidebar path we only have the saved section text, usually a block ref like ((uid)), and need to decide whether to render QuerySectionItem before rendering the sidebar row.

So we dereference the block ref with getTextByBlockUid and check the block text.

Comment thread apps/roam/src/utils/getExportSettings.ts Outdated
};

/* eslint-disable @typescript-eslint/naming-convention */
export const sectionsToBlockProps = (
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@mdroidian For block props we don't do per-setting writes. We map the whole personal left-sidebar settings structure here because we have to update the data locally for the component, but also persist that same structure in block props.

Below, around line 81, we have the syncAllSectionsToBlockProps function which writes this mapped structure to block props via setPersonalSetting. For this query alias path, we build nextSections, update local state with setSections(nextSections), and then call syncAllSectionsToBlockProps(nextSections) around line 426.

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