Skip to content

ENG-1217: Port section component in left sidebar#804

Merged
sid597 merged 3 commits intoeng-1328-port-small-blueprint-based-misc-settings-into-props-basedfrom
eng-1217-section-components-in-left-sidebarv2
Feb 24, 2026
Merged

ENG-1217: Port section component in left sidebar#804
sid597 merged 3 commits intoeng-1328-port-small-blueprint-based-misc-settings-into-props-basedfrom
eng-1217-section-components-in-left-sidebarv2

Conversation

@sid597
Copy link
Collaborator

@sid597 sid597 commented Feb 20, 2026

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


Open with Devin

Summary by CodeRabbit

  • Bug Fixes

    • Fixed left sidebar page changes not persisting when reordering, adding, or removing pages.
  • Improvements

    • Enhanced synchronization of personal settings to ensure configuration changes are properly saved.
    • Improved flexibility in settings panel configuration options.

@linear
Copy link

linear bot commented Feb 20, 2026

@supabase
Copy link

supabase bot commented Feb 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 sid597 marked this pull request as ready for review February 20, 2026 19:25
Copy link
Collaborator Author

sid597 commented Feb 20, 2026

@coderabbitai full review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 20, 2026

✅ Actions performed

Full review triggered.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 20, 2026

📝 Walkthrough

Walkthrough

The PR migrates left-sidebar settings components to new block-prop driven persistence approaches. Global settings now wire GlobalFlagPanel with setGlobalSetting for page operations (add/move/remove), while personal settings implement PersonalNumberPanel with a new sectionsToBlockProps synchronization layer and setPersonalSetting persistence. Zod schemas are updated to use UID-based identifiers and array-based structures.

Changes

Cohort / File(s) Summary
Global Settings Migration
apps/roam/src/components/settings/LeftSidebarGlobalSettings.tsx
Replaced FlagPanel with GlobalFlagPanel for global-section flags. Added pagesToUids helper to map pages to UIDs. Wired setGlobalSetting persistence for page reorder (movePage), add (addPage), and remove (removePage) operations. Updated state-first-then-persist flow.
Personal Settings Migration
apps/roam/src/components/settings/LeftSidebarPersonalSettings.tsx
Replaced NumberPanel with PersonalNumberPanel. Introduced sectionsToBlockProps and syncAllSectionsToBlockProps helpers to map section config to nested block-props structure. Added sectionsRef shared reference to avoid stale closures. Wired setPersonalSetting persistence across multiple mutation paths (add/move/edit sections, alias changes). Expanded aliasDebounceRef usage for debounced sync operations.
Block Prop Components
apps/roam/src/components/settings/components/BlockPropSettingPanels.tsx
Extended NumberWrapperProps with optional setter?: NumberSetter field. Updated PersonalNumberPanel to destructure and forward setter prop, defaulting to personalAccessors.number.setter when not provided, enabling per-instance setter override.
Schema Updates
apps/roam/src/components/settings/utils/zodSchema.ts
Added required name: string field to PersonalSectionSchema. Replaced Page string with uid: string in Children items. Changed LeftSidebarPersonalSettingsSchema from record<string, ...> (default \{\}) to array of PersonalSectionSchema (default \[\]).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Port section component in left sidebar' directly relates to the main changes in the PR, which involve porting/refactoring section-related components in the left sidebar settings files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


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.

coderabbitai[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

@sid597 sid597 requested a review from mdroidian February 20, 2026 20:00
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.

The audio in the loom is mostly inaudible. Please review the looms before submitting.
Also, a couple files are not formatted again.

There's a single comment asking to explain why caused the PersonalNumberPanel to break the pattern from the others. I think it would be worth exploring that deeper to see if there are alternative solutions prior to breaking the pattern.

export const PersonalNumberPanel = (props: NumberWrapperProps) => (
<BaseNumberPanel {...props} {...personalAccessors.number} />
export const PersonalNumberPanel = ({ setter, ...props }: NumberWrapperProps) => (
<BaseNumberPanel {...props} setter={setter ?? personalAccessors.number.setter} />
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this panel breaking the pattern with setter? What is the reason/need for this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

usually the number panel setters are something that can be reached directly in the tree, but for this case we have an array and insde the array we have the key map. So to get to the numberPanel in this case we have to find the array for which we want to target, therefore we needed a custom setter for it. The standard setter can't target a specific array item so we needed this.

Copy link
Collaborator Author

@sid597 sid597 Feb 23, 2026

Choose a reason for hiding this comment

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

This reminded me we also have an Alias Field in setting and we should be using a similar solution there so I checked, and I was using old flagpanel component so I ported that also with similar logic. Following is a loom video showing its working state (checked the audio and its working sorry for the one not working one)

Another change I did was move this to graphite stack because we needed a baseTextPanel which had debounce built in

https://www.loom.com/share/537a13cccb764c18967f14bf1a7180e5

@sid597 sid597 changed the base branch from main to graphite-base/804 February 23, 2026 10:26
@sid597 sid597 force-pushed the eng-1217-section-components-in-left-sidebarv2 branch from b75a946 to 964b648 Compare February 23, 2026 10:26
@sid597 sid597 changed the base branch from graphite-base/804 to eng-1465-add-enable-dual-read-feature-flag-with-reactive-accessor February 23, 2026 10:27
@sid597 sid597 changed the base branch from eng-1465-add-enable-dual-read-feature-flag-with-reactive-accessor to graphite-base/804 February 23, 2026 10:30
@sid597 sid597 force-pushed the eng-1217-section-components-in-left-sidebarv2 branch from 964b648 to f41175c Compare February 23, 2026 10:30
@sid597 sid597 changed the base branch from graphite-base/804 to eng-1328-port-small-blueprint-based-misc-settings-into-props-based February 23, 2026 10:31
@sid597 sid597 force-pushed the eng-1217-section-components-in-left-sidebarv2 branch from 4d1c4f3 to 4fd71df Compare February 23, 2026 10:40
@sid597 sid597 force-pushed the eng-1328-port-small-blueprint-based-misc-settings-into-props-based branch from 1d2ba62 to 4634da5 Compare February 23, 2026 10:40
@sid597 sid597 requested a review from mdroidian February 23, 2026 11:07
@sid597 sid597 force-pushed the eng-1328-port-small-blueprint-based-misc-settings-into-props-based branch from 4634da5 to 1b440fb Compare February 23, 2026 13:51
@sid597 sid597 force-pushed the eng-1217-section-components-in-left-sidebarv2 branch from 4fd71df to 56ec7bc Compare February 23, 2026 13:51
devin-ai-integration[bot]

This comment was marked as resolved.

@sid597 sid597 force-pushed the eng-1217-section-components-in-left-sidebarv2 branch from 56ec7bc to 5a2778b Compare February 23, 2026 14:13
@sid597 sid597 force-pushed the eng-1328-port-small-blueprint-based-misc-settings-into-props-based branch from 1b440fb to 586c385 Compare February 23, 2026 14:13
@sid597 sid597 force-pushed the eng-1217-section-components-in-left-sidebarv2 branch 3 times, most recently from 307dd54 to 5bcf109 Compare February 23, 2026 15:31
@sid597 sid597 force-pushed the eng-1328-port-small-blueprint-based-misc-settings-into-props-based branch from 84b5f88 to eb2aaa7 Compare February 23, 2026 16:40
@sid597 sid597 force-pushed the eng-1217-section-components-in-left-sidebarv2 branch from 5bcf109 to a679322 Compare February 23, 2026 16:40
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 new potential issue.

⚠️ 1 issue in files not directly in the diff

⚠️ Pull watcher handler uses Object.keys() on array after schema change from record to array (apps/roam/src/components/settings/utils/pullWatchers.ts:128-145)

The "Left sidebar" handler in personalSettingsHandlers calls Object.keys(oldValue || {}) and Object.keys(newValue || {}) to compare sections. This was correct when LeftSidebarPersonalSettings was a record (Record<string, PersonalSection>), but the schema was changed in this PR to an array (PersonalSection[]).

Root Cause

With the new array-based schema (apps/roam/src/components/settings/utils/zodSchema.ts:222-224), PersonalSettings["Left sidebar"] is now PersonalSection[]. Calling Object.keys() on an array returns string indices (["0", "1", ...]) rather than section names.

For example, if the old value had 2 sections and the new value has 3 sections:

  • oldSections = ["0", "1"]
  • newSections = ["0", "1", "2"]
  • addedSections = ["2"] (an index, not a section name)

The comparisons at lines 137-138 (newSections.filter((s) => !oldSections.includes(s))) compare array indices instead of meaningful section identifiers, making the added/removed section detection incorrect.

Impact: The debug logging output for left sidebar personal section changes will show array indices instead of section names, making the pull watcher diagnostics misleading. Since this is currently only used for debug logging (the comment says "stub for testing"), the functional impact is limited.

View 14 additional findings in Devin Review.

Open in Devin Review

@sid597 sid597 force-pushed the eng-1217-section-components-in-left-sidebarv2 branch from a679322 to 79d4150 Compare February 23, 2026 17:53
@sid597 sid597 force-pushed the eng-1328-port-small-blueprint-based-misc-settings-into-props-based branch from eb2aaa7 to 26619e2 Compare February 23, 2026 17:53
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 new potential issue.

⚠️ 1 issue in files not directly in the diff

⚠️ Pull watcher handler uses Object.keys() on array after schema change from record to array (apps/roam/src/components/settings/utils/pullWatchers.ts:128-145)

The "Left sidebar" handler in personalSettingsHandlers calls Object.keys(oldValue || {}) and Object.keys(newValue || {}) to compare sections. This was correct when LeftSidebarPersonalSettings was a record (Record<string, PersonalSection>), but the schema was changed in this PR to an array (PersonalSection[]).

Root Cause

With the new array-based schema (apps/roam/src/components/settings/utils/zodSchema.ts:222-224), PersonalSettings["Left sidebar"] is now PersonalSection[]. Calling Object.keys() on an array returns string indices (["0", "1", ...]) rather than section names.

For example, if the old value had 2 sections and the new value has 3 sections:

  • oldSections = ["0", "1"]
  • newSections = ["0", "1", "2"]
  • addedSections = ["2"] (an index, not a section name)

The comparisons at lines 137-138 (newSections.filter((s) => !oldSections.includes(s))) compare array indices instead of meaningful section identifiers, making the added/removed section detection incorrect.

Impact: The debug logging output for left sidebar personal section changes will show array indices instead of section names, making the pull watcher diagnostics misleading. Since this is currently only used for debug logging (the comment says "stub for testing"), the functional impact is limited.

View 14 additional findings in Devin Review.

Open in Devin Review

@sid597 sid597 force-pushed the eng-1217-section-components-in-left-sidebarv2 branch from 79d4150 to f87715d Compare February 24, 2026 05:46
@sid597 sid597 force-pushed the eng-1328-port-small-blueprint-based-misc-settings-into-props-based branch from 26619e2 to ef60df6 Compare February 24, 2026 05:46
@sid597 sid597 force-pushed the eng-1217-section-components-in-left-sidebarv2 branch from f87715d to b18c761 Compare February 24, 2026 05:48
@sid597 sid597 force-pushed the eng-1328-port-small-blueprint-based-misc-settings-into-props-based branch from ef60df6 to 5d03b39 Compare February 24, 2026 05:48
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 new potential issue.

⚠️ 1 issue in files not directly in the diff

⚠️ Pull watcher handler uses Object.keys() on array after schema change from record to array (apps/roam/src/components/settings/utils/pullWatchers.ts:128-145)

The "Left sidebar" handler in personalSettingsHandlers calls Object.keys(oldValue || {}) and Object.keys(newValue || {}) to compare sections. This was correct when LeftSidebarPersonalSettings was a record (Record<string, PersonalSection>), but the schema was changed in this PR to an array (PersonalSection[]).

Root Cause

With the new array-based schema (apps/roam/src/components/settings/utils/zodSchema.ts:222-224), PersonalSettings["Left sidebar"] is now PersonalSection[]. Calling Object.keys() on an array returns string indices (["0", "1", ...]) rather than section names.

For example, if the old value had 2 sections and the new value has 3 sections:

  • oldSections = ["0", "1"]
  • newSections = ["0", "1", "2"]
  • addedSections = ["2"] (an index, not a section name)

The comparisons at lines 137-138 (newSections.filter((s) => !oldSections.includes(s))) compare array indices instead of meaningful section identifiers, making the added/removed section detection incorrect.

Impact: The debug logging output for left sidebar personal section changes will show array indices instead of section names, making the pull watcher diagnostics misleading. Since this is currently only used for debug logging (the comment says "stub for testing"), the functional impact is limited.

View 14 additional findings in Devin Review.

Open in Devin Review

@sid597 sid597 merged commit b595bdc into eng-1328-port-small-blueprint-based-misc-settings-into-props-based Feb 24, 2026
12 of 13 checks passed
sid597 added a commit that referenced this pull request Feb 24, 2026
  specification, config panel)

  The initial recovery commit claimed to include these but only
  contained
  Chain 2 (#793, #794, #805, #804). Chain 1 lives on separate
  branches
  that weren't in the merge source.

  Applied using `gh pr diff` for each PR in order (#764#765#769).
  init.ts required manual merge — #765 and #769 both modified it
  from the
  same base. Kept #765's safeParse checks inside #769's
  restructured
  initializeSettingsBlockProps.

  - #764 ENG-1280: Port query builder and editor component for
  block props
  - #765 ENG-1291: Port discourse node specification
  - #769 ENG-1290: Port discourse node config panel
sid597 added a commit that referenced this pull request Feb 25, 2026
…#826)

* Land orphaned Graphite stack PRs (#764, #765, #769, #793, #794, #805)

  These PRs were squash-merged into parent branches instead of main
  due to a Graphite stack merge race condition. Their changes never
  landed on main despite showing as merged in Graphite.

  Includes:
  - #764 ENG-1280: Port query builder/editor for block props
  - #765 ENG-1291: Port discourse node specification (dual-write)
  - #769 ENG-1290: Port discourse node config panel
  - #793 ENG-1440: Port page groups settings in suggestive mode
  - #794 ENG-1438: Port keyboard shortcut keys/triggers
  - #805 ENG-1328: Port small blueprint misc settings

* Add #804 ENG-1217: Port section component in left sidebar

* Add #764, #765, #769 (Chain 1 orphaned PRs: query builder,
  specification, config panel)

  The initial recovery commit claimed to include these but only
  contained
  Chain 2 (#793, #794, #805, #804). Chain 1 lives on separate
  branches
  that weren't in the merge source.

  Applied using `gh pr diff` for each PR in order (#764#765#769).
  init.ts required manual merge — #765 and #769 both modified it
  from the
  same base. Kept #765's safeParse checks inside #769's
  restructured
  initializeSettingsBlockProps.

  - #764 ENG-1280: Port query builder and editor component for
  block props
  - #765 ENG-1291: Port discourse node specification
  - #769 ENG-1290: Port discourse node config panel

* fix lint

* prettier
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