Skip to content

Conversation

@sid597
Copy link
Collaborator

@sid597 sid597 commented Sep 13, 2025

To test this pr paste the following in your roam/js/discourse-graph page (change you username)

- Left Sidebar
    - siddharth yadav/Personal-Section
        - CLM
        - July 16th, 2025
            - Settings
                - Truncate-result?
                    - 75
                - Alias
                    - happy day 2
            - Children
                - Test/Home
                - July 16th, 2025
        - 📝 Daily Notes {{Create Today's Entry:SmartBlock:UserDNPToday:RemoveButton=false}} {{Pick A Day:SmartBlock:UserDNPDateSelect:RemoveButton=false}}
            - Settings
                - Truncate-result?
                    - 75
                - Alias
                    - Daily notes
            - Children
    - Global-Section
        - Folded
        - Collapsable
        - Children
            - Canvas
            - May 13th, 2025
image

Summary by CodeRabbit

  • New Features
    • Introduces a customizable left sidebar with Global and Personal sections.
    • Supports collapsible sections and items, with folding/unfolding behavior.
    • Displays aliases and optional truncated labels for cleaner navigation.
    • Opens pages or blocks directly; Shift-click opens in a sidebar or separate window.
  • Chores
    • Automatically initializes the new left sidebar when the UI area is available, replacing the default starred pages view and ensuring proper mounting and cleanup.

@linear
Copy link

linear bot commented Sep 13, 2025

@supabase
Copy link

supabase bot commented Sep 13, 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 ↗︎.

Copy link
Collaborator Author

sid597 commented Sep 13, 2025

@sid597 sid597 changed the title Render left sidebar based on fetched sections and settings ENG-851 Render left sidebar based on fetched sections and settings Sep 13, 2025
@linear
Copy link

linear bot commented Sep 13, 2025

@sid597 sid597 force-pushed the eng-852-render-left-sidebar-based-on-the-fetched-sections-and branch from 885d8da to f7a65f0 Compare September 13, 2025 06:44
@sid597 sid597 marked this pull request as ready for review September 13, 2025 06:45
@sid597
Copy link
Collaborator Author

sid597 commented Sep 13, 2025

@coderabbitai full review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 13, 2025

✅ Actions performed

Full review triggered.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 13, 2025

📝 Walkthrough

Walkthrough

Adds a new React LeftSidebarView component driven by formatted Roam config and a mountLeftSidebar function. Integrates a DOM mutation observer to detect the starred-pages wrapper and mount the custom left sidebar. Implements item opening (blocks/pages), folding/unfolding, collapsible sections, and alias/truncation handling.

Changes

Cohort / File(s) Change Summary
Left sidebar component & mounting
apps/roam/src/components/LeftSidebarView.tsx
Introduces LeftSidebarView UI with Global/Personal sections, reference parsing, opening targets (blocks/pages with shift behaviors), folding toggle logic, and text derivation. Adds mountLeftSidebar to render into dg-left-sidebar-root, replacing default starred pages. Exports: default LeftSidebarView; named mountLeftSidebar(wrapper: HTMLElement): void.
Observer integration
apps/roam/src/utils/initializeObserversAndListeners.ts
Adds leftSidebarObserver to watch for DIV.starred-pages-wrapper in body and invoke mountLeftSidebar on detection. Imports the mounting function and returns the new observer with existing ones.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant DOM as DOM
  participant Observer as leftSidebarObserver
  participant Mount as mountLeftSidebar()
  participant React as LeftSidebarView
  participant Roam as roamAlphaAPI

  DOM->>Observer: Mutation: DIV.starred-pages-wrapper detected
  Observer->>Mount: mountLeftSidebar(container)
  Mount->>React: ReactDOM.render(LeftSidebarView)
  Note over React: Renders Global & Personal sections from formatted config

  rect rgba(230,245,255,0.6)
    note right of React: User interactions
    participant User as User
    User->>React: Click item
    alt Block reference
      React->>Roam: openBlockInSidebar / open block (shift behavior)
    else Page title
      React->>Roam: open page / open outline window (shift behavior)
    end
    User->>React: Toggle chevron
    React->>React: toggleFoldedState (create/delete "Folded" child)
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


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.

Pre-merge checks

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
Title Check ✅ Passed The pull request title "ENG-852 Render left sidebar based on fetched sections and settings" succinctly and accurately describes the primary change — rendering a left sidebar from fetched sections and settings — and aligns with the changes that add LeftSidebarView, mountLeftSidebar, and observer wiring in initializeObserversAndListeners.ts. It is concise, specific, and understandable to a teammate scanning history. The ticket reference is acceptable in a title and does not add noise.

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

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

103-112: Left sidebar observer: make idempotent and drop noisy logging.

Guard against repeated mounts and avoid console spam.

-  const leftSidebarObserver = createHTMLObserver({
+  const leftSidebarObserver = createHTMLObserver({
     tag: "DIV",
     useBody: true,
     className: "starred-pages-wrapper",
-    callback: (el) => {
-      console.log("[DG][LeftSidebar] leftSidebarObserver callback", el);
-      const container = el as HTMLDivElement;
-      mountLeftSidebar(container);
-    },
+    callback: (el) => {
+      const container = el as HTMLDivElement;
+      if (container.querySelector("#dg-left-sidebar-root")) return; // already mounted
+      mountLeftSidebar(container);
+    },
   });
apps/roam/src/components/LeftSidebarView.tsx (4)

30-57: Right sidebar open: verify window payload; avoid ts-expect-error.

Roam’s API typically uses page-uid for page outlines. Replace block-uid and remove the suppression.

-  if (e.shiftKey) {
-    await window.roamAlphaAPI.ui.rightSidebar.addWindow({
-      // @ts-expect-error - todo test
-      // eslint-disable-next-line @typescript-eslint/naming-convention
-      window: { type: "outline", "block-uid": uid },
-    });
-  } else {
+  if (e.shiftKey) {
+    await window.roamAlphaAPI.ui.rightSidebar.addWindow({
+      // eslint-disable-next-line @typescript-eslint/naming-convention
+      window: { type: "outline", "page-uid": uid },
+    });
+  } else {
     await window.roamAlphaAPI.ui.mainWindow.openPage({ page: { uid } });
   }

89-120: Section item accessibility.

Provide button semantics for keyboard users and screen readers.

-        return (
-          <div key={child.uid} className="py-1 pl-1">
-            <div
-              className={
-                "section-child-item page cursor-pointer rounded-sm leading-normal text-gray-600"
-              }
-              onClick={onClick}
-            >
-              {label}
-            </div>
-          </div>
-        );
+        return (
+          <div key={child.uid} className="py-1 pl-1">
+            <div
+              className="section-child-item page cursor-pointer rounded-sm leading-normal text-gray-600"
+              role="button"
+              tabIndex={0}
+              aria-label={`Open ${label}`}
+              onClick={onClick}
+              onKeyDown={(e) => (e.key === "Enter" || e.key === " ") && onClick(e as any)}
+            >
+              {label}
+            </div>
+          </div>
+        );

252-261: Config memoization won’t update on config changes.

useMemo(() => getFormattedConfigTree()..., []) locks the view to initial config. If the config tree refreshes (e.g., via refreshConfigTree()), the sidebar won’t update until remount.

Consider wiring a lightweight pub/sub or an extensionAPI.settings.onChange trigger to force a re-render of this component.


279-289: Minor: preserve existing root classes instead of overwrite.

Switching to classList.add (as above) avoids clobbering future styling. No separate change needed if you adopt the previous diff.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 57e4be1 and d828bda.

📒 Files selected for processing (2)
  • apps/roam/src/components/LeftSidebarView.tsx (1 hunks)
  • apps/roam/src/utils/initializeObserversAndListeners.ts (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
🔇 Additional comments (5)
apps/roam/src/utils/initializeObserversAndListeners.ts (2)

48-48: Import looks good.


343-344: Observer registration LGTM.

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

16-23: parseReference: clarify non-ref inputs.

If text is plain (no [[ ]] or (( ))), extractRef(text) may return the original string; treating it as a page is fine, but verify this matches expected UX (no-op if page doesn’t exist vs. creating/opening).

Would you prefer creating the page when missing?


153-166: Click behavior: shift-click vs. toggle.

Current logic toggles on click unless Shift; good. After fixing fold semantics, ensure the chevron reflects state. No change needed here.


221-229: Global toggle semantics depend on the fixed toggleFoldedState.

After inverting toggleFoldedState, this handler will behave correctly. Nothing else to change.

Please re-test the “Global-Section → Folded” case from the PR instructions to confirm it renders collapsed on load.

@sid597 sid597 requested a review from mdroidian September 13, 2025 10:49
@sid597 sid597 changed the title ENG-851 Render left sidebar based on fetched sections and settings ENG-852 Render left sidebar based on fetched sections and settings Sep 14, 2025
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.

Found some bugs

https://www.loom.com/share/9a552a7c3b83483ab75acdbed38b65a6

I did change 📝 Daily Notes {{Create Today's Entry:SmartBlock:UserDNPToday:RemoveButton=false}} {{Pick A Day:SmartBlock:UserDNPDateSelect:RemoveButton=false}} to a block ref but it would only navigate there ~10% of the time randomly clicking on that header

@sid597 sid597 force-pushed the eng-851-get-left-sidebar-sections-and-settings-from-config-page branch from 57e4be1 to 32f9c22 Compare September 15, 2025 14:21
@sid597 sid597 force-pushed the eng-852-render-left-sidebar-based-on-the-fetched-sections-and branch 2 times, most recently from 9c1db6a to 6b9694d Compare September 15, 2025 14:32
@sid597
Copy link
Collaborator Author

sid597 commented Sep 15, 2025

@sid597 sid597 requested a review from mdroidian September 17, 2025 16:50
@mdroidian
Copy link
Contributor

mdroidian commented Sep 20, 2025

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.

Nice!

Some thoughts here: #440 (comment)

if (!uid) return;
if (e.shiftKey) {
await window.roamAlphaAPI.ui.rightSidebar.addWindow({
// @ts-expect-error - todo test
Copy link
Contributor

Choose a reason for hiding this comment

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

.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

😅 I copied it from other parts of codebase, I was not sure what to do about it so I searched and copied it to atleast keep it consistent if someone searched for it in future

@sid597 sid597 force-pushed the eng-852-render-left-sidebar-based-on-the-fetched-sections-and branch from d72bcb0 to 6517f19 Compare September 20, 2025 04:14
@sid597 sid597 changed the base branch from eng-851-get-left-sidebar-sections-and-settings-from-config-page to graphite-base/440 September 20, 2025 04:24
@sid597 sid597 force-pushed the eng-852-render-left-sidebar-based-on-the-fetched-sections-and branch from 6517f19 to 5efb611 Compare September 20, 2025 04:24
@sid597 sid597 changed the base branch from graphite-base/440 to main September 20, 2025 04:24
@mdroidian mdroidian self-requested a review September 20, 2025 04:31
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.

Wait, @sid597 it looks like this overrides the entire left sidebar if a user has no settings (which will be majority of users until #441)

So we should also add a check to see if left sidebar is enabled or not in the first place before we mount/render

image

@sid597
Copy link
Collaborator Author

sid597 commented Sep 20, 2025

@sid597
Copy link
Collaborator Author

sid597 commented Sep 20, 2025

@mdroidian https://www.loom.com/share/cee226c07fd94db78c612eb10f874723?sid=b10ebc99-b31f-4376-b422-23b01956772d

added (BETA) setting and we only render or mount if its checked

@sid597 sid597 requested a review from mdroidian September 20, 2025 05:58
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.

A few things

  1. I think the "Feature Flag" is going to have to be global for this one. We can make it overridable when we do the settings overhaul, but for the most part it will be turned on for the whole graph. Let's change it to global.

  2. Add the same left padding to headers as children have. Right now headers have no left padding.

image image
  1. Don't show hover/pointer cursor on GLOBAL if it isn't collapsible (because it isn't clickable).

import { render as renderToast } from "roamjs-components/components/Toast";
import refreshConfigTree from "~/utils/refreshConfigTree";
import { refreshAndNotify } from "~/components/LeftSidebarView";
import { memo } from "react";
Copy link
Contributor

Choose a reason for hiding this comment

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

add this to the other react import at the top

@sid597 sid597 requested a review from mdroidian September 25, 2025 11:12
@sid597 sid597 force-pushed the eng-852-render-left-sidebar-based-on-the-fetched-sections-and branch from b64e6e1 to d6e1a10 Compare September 25, 2025 19:49
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.

🚀

After you nix the useEffect, feel free to merge

@sid597
Copy link
Collaborator Author

sid597 commented Sep 26, 2025

@mdroidian you have to merge its blocked for me

@mdroidian mdroidian self-requested a review September 26, 2025 08:09
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 c54a276 into main Sep 26, 2025
6 checks passed
@github-project-automation github-project-automation bot moved this to Done in General Sep 26, 2025
trangdoan982 pushed a commit that referenced this pull request Oct 3, 2025
)

* fix style

* fix styling

* address coderabbit

* fix double click to navigate, shift click to open in sidebar

* address Michael and Johnny review

* 1. Use (BETA) setting, on hover change UI to reflect its clickable state

* ENG-853 left sidebar global and personal settings (#441)

* left sidebar global and personal settings

* address coderabbit

* address ui feedback

* add toast, fix void lint

* text in center

* sync settings and left sidebar rendering

* simplify props

* fix lint

* 1. Address review 2. Use uid instead of username 3. Use settings block for global

* add button for quick settings, full width sections, on click toggles

* use global settings for BETA left sidebar feature

* nix useeffect
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