Skip to content

Conversation

@trangdoan982
Copy link
Collaborator

@trangdoan982 trangdoan982 commented Oct 3, 2025

Summary by CodeRabbit

  • New Features
    • Shift-click on a discourse node now opens its linked note directly, with a brief debounce to prevent accidental repeats.
    • Clear in-app toasts provide feedback for success and error states (e.g., missing link, unavailable canvas cache, resolution failures).
    • Automatically clears the current selection after opening the linked note for a smoother workflow.

trangdoan982 and others added 30 commits September 1, 2025 14:06
* cleaned

* sm

* address PR comments
* data persistence to the file

* error handling

* address PR comments

* address some PR comments

* address other PR comments

* address PR comments
* current state

* works now

* clean up

* address PR comments

* address PR reviews

* cleanup

* fix styling issues

* address PR comments
* current state

* works now

* clean up

* address PR comments

* address PR reviews

* fix styling issues

* latest progress

* update new shape

* shape defined

* address PR comments

* sm address PR review

* current progress

* reorg

* address other PR comments

* clean

* simplify flow

* address PR comments
* eng-604: create node flow

* pwd
* eng-658-add-existing-nodes-flow

* address PR comments

* small changes
https://www.loom.com/share/3641f2a642714b0d849262344e8c6ee5?sid=0614c657-e541-4bfd-92df-9b1aa60945b6

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- New Features
  - Added a Relations overlay on the canvas that shows a “Relations” button when a discourse node is selected.
  - Introduced a Relations panel to view and manage relations for the selected node, including adding or removing links, with clear loading/error states.
  - Overlay appears above the canvas without disrupting existing tools.

- Chores
  - Consolidated relation-type lookup into shared utilities and updated imports. No user-facing changes.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
* add color setting

* address PR reviews

* address PR commens
* add documentation

* fix sm styling

* address PR comments
* eng-812 : Update database cli tools: supabase, vercel, cucumber.

* newer cucumber constrains node
added light/dark cover image
* Refactor Tldraw component to handle maximization state and viewport updates

- Introduced `handleMaximizedChange` to manage fullscreen toggling and DOM manipulation.
- Added `updateViewportScreenBounds` for viewport updates using Tldraw's built-in methods.
- Updated styles to support maximized state in Tldraw canvas.
- Removed unnecessary `maximized` state from props in `createUiOverrides`.

* - Renamed `setMaximized` to `toggleMaximized` for clarity in both Tldraw and uiOverrides components.

* Optimize viewport updates in Tldraw component by wrapping DOM measurements in requestAnimationFrame for smoother performance.
* use getDiscourseNodes

* Eng-737 use node color to style node tags (#424)

* modify dom only for node tags

* add background color to a nodetag

* use it as color not background color

* remove unused refresh

* Roam: ENG-693 handle node tags with # in front and update placeholder to use # (#420)

* use text not tag

* Move the new block as first child of the current block (#422)
* settings for context and page groups

* node settings

* address review

* fix node creation if it does not exist

* remove unused, refactor

* address coderabbit review

* unify spelling, handle fallback

* sync

* address coderabbit code

* address lint errors

* use async instead of backend

* address review

* address review

* bug fixes

* bug fixes

* unused import

* Add an input type for platform accounts
Add functions to upsert platform accounts (individually or in bulk)
Keep the old create_account_in_space function as a shim for now.
Use the new upsert_account in upsert_documents and upsert_content,
allowing for more complete inline information.

* Add an input type for platform accounts
Add functions to upsert platform accounts (individually or in bulk)
Keep the old create_account_in_space function as a shim for now.
Use the new upsert_account in upsert_documents and upsert_content,
allowing for more complete inline information.

* Add an input type for platform accounts
Add functions to upsert platform accounts (individually or in bulk)
Keep the old create_account_in_space function as a shim for now.
Use the new upsert_account in upsert_documents and upsert_content,
allowing for more complete inline information.

* bulk upsert accounts, use database function imports

* add comment for future

* use better import method

* commonjs-to-esm

* fix merge errors, fix tree config setting extraction, test functionality, fix functionality

* add progress toaster, use space existence condition for on load sync

* defaultvalue

* address review, leaving out update embeddings from here

* update embeddings

* ENG-818: Declare dbDotEnv as mjs explicitly

* reverting create a new pr for update embeddings

---------

Co-authored-by: Marc-Antoine Parent <maparent@acm.org>
* Refactor font settings in Export and Discourse components to use "sans" and size "s" for consistency across the application.

* Update Export component to set default size to "s" for consistency in export settings.
* ENG-847 compile roam against db ts
* Also make utils and ui co-compile rather than build. Adjust turbo dependencies.
* ENG-821 Rewrite createEnv.mts to be more resilient. (#434)
Specifically, allows it to be called in a non-dev environment.
* Do not overwrite name with empty name

* document upsert_accounts_in_space
* Utility query functions for the database
* Use localIds as keys for node queries. Cache corresponding dbIds for efficiency.
Some typechecks now require a newer typescript.
* Refactor ESLint configuration to streamline plugin usage and enforce consistent type definitions. Removed redundant plugin declarations and updated rules for better clarity and adherence to coding standards.

* Remove commented-out ESLint directive
maparent and others added 15 commits October 3, 2025 16:07
Update to supabase and vercel client libraries
* * Missing eslint.config in utils
* Apply sqlruff lints
* One valid lint on migrate.ts
* Tweak lint rules to allow `while (true)`
* Wrong lint base in @repo/database
* remove eslint9-dependent setting.
* declare eslint as module
* extract suggestive mode personal setting

* add home setting

* remove console log
* Refactor Tldraw component to remove unused TLDRAW_DATA_ATTRIBUTE and simplify canvas rendering logic. Update styles to use :has() for conditionally hiding Roam Blocks based on canvas presence.

* Enhance Tldraw component by adding early return to prevent duplicate canvas container appending. This improves rendering logic and maintains clean DOM structure.
#460)

* Add default tags for Claim and Evidence nodes in defaultDiscourseNodes.ts

* Add generateTagPlaceholder function to create dynamic tag placeholders for nodes in NodeConfig component in the format of abc-candidate

* missed #
* Convert to PNPM.
* Package files have to be more explicit in their dependencies.
* pnpm workspace definition.
* nuclear option: Use the react->@types/react@18 for tsc.
* Patch for @blueprintjs/core@3.50.4 and adjust versioning for dependencies. (#425)

---------

Co-authored-by: Michael Gartner <mclicks@gmail.com>

some coderabbit suggestions, update pnpm to 10.15.1, remove some unneeded changes, comments

* regenerate pnpm-lock after rebase

* include eslint as specific dependency in various package.json. Put eslint in catalog.

* patch @blueprint/select. pnpm-workspace.yaml got normalized in the process

---------

Co-authored-by: Michael Gartner <mclicks@gmail.com>
Now that we have a newer database in production, the CLI should follow.
Unfortunately, after having tried this, my local supabase install now fails with the earlier version.
(I did try zapping all my supabase docker data, and I still cannot use the older version anymore.)
* normalize tag comparison in observer

* use existing getCleanTag
* cleaned

* sm

* address PR comments
* data persistence to the file

* error handling

* address PR comments

* address some PR comments

* address other PR comments

* address PR comments
@supabase
Copy link

supabase bot commented Oct 3, 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

This stack of pull requests is managed by Graphite. Learn more about stacking.

@trangdoan982 trangdoan982 changed the title add Shift click ability [Eng-928] Shift + Click to open discourse node Oct 3, 2025
@linear
Copy link

linear bot commented Oct 3, 2025

@trangdoan982 trangdoan982 force-pushed the 10-03-add_shift_click_ability branch from 0da76ca to cda1da2 Compare October 3, 2025 20:26
@trangdoan982
Copy link
Collaborator Author

@coderabbitai full review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 3, 2025

✅ Actions performed

Full review triggered.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 3, 2025

📝 Walkthrough

Walkthrough

Implements shift-click handling on canvas pointer_up to open a discourse-node’s linked file via block reference, with debounce, selection guards, cache checks, and toast-based feedback. Adds related imports, refs, and utilities. Converts TldrawPreviewProps from interface to type alias without changing fields.

Changes

Cohort / File(s) Summary of changes
Shift-click discourse-node activation
apps/obsidian/src/components/canvas/TldrawViewComponent.tsx
Added pointer_up shift-click flow: debounce via lastShiftClickRef/SHIFT_CLICK_DEBOUNCE_MS; detect DiscourseNodeShape under cursor; enforce single-node selection; extract blockRefId; read canvas file cache; resolve linked file via assetStore; open on success; clear selection; show toasts on missing/failed states; error logging.
Type and plumbing updates
apps/obsidian/src/components/canvas/TldrawViewComponent.tsx
Converted interface TldrawPreviewProps → type alias TldrawPreviewProps with same fields (store, file, assetStore). Added imports: DiscourseNodeShape, extractBlockRefId, resolveLinkedTFileByBlockRef, showToast. Initialized saveTimeoutRef (nullable), editorRef (null default).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant Canvas as TldrawViewComponent
  participant Store as TLStore
  participant Asset as ObsidianTLAssetStore
  participant Obsidian as App
  participant Toast as Toasts

  User->>Canvas: pointer_up (Shift held)
  alt Debounced within 300ms
    Canvas->>Toast: show "Please wait…" / ignore
  else Proceed
    Canvas->>Store: hit-test shape under cursor
    Store-->>Canvas: shape or none
    alt Not a DiscourseNode or none/multiple selected
      Canvas->>Toast: warn "Select a single discourse-node"
    else DiscourseNode selected
      Canvas->>Canvas: extractBlockRefId(node)
      alt No blockRefId
        Canvas->>Toast: warn "No block reference"
      else Has blockRefId
        Canvas->>Obsidian: read canvas file cache
        alt Cache unavailable
          Canvas->>Toast: error "Canvas cache unavailable"
        else Cache available
          Canvas->>Asset: resolveLinkedTFileByBlockRef(blockRefId, cache)
          alt Resolve success
            Asset-->>Canvas: TFile
            Canvas->>Obsidian: open file
            Obsidian-->>Canvas: opened
            Canvas->>Store: clear selection
          else Resolve failure
            Asset-->>Canvas: error/undefined
            Canvas->>Toast: error "Linked file not found"
          end
        end
      end
    end
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Pre-merge checks

✅ 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 clearly identifies the main feature addition of enabling shift-click to open a discourse node and includes the ticket identifier, making it concise, specific, and directly related to the primary change.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

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

🧹 Nitpick comments (1)
apps/obsidian/src/components/canvas/TldrawViewComponent.tsx (1)

226-234: Redundant ?? undefined operation.

On line 226, shape.props.src ?? undefined is redundant. If shape.props.src is null or undefined, the nullish coalescing operator returns undefined, which is the same as just passing shape.props.src directly.

Apply this diff to simplify:

-          const blockRefId = extractBlockRefId(shape.props.src ?? undefined);
+          const blockRefId = extractBlockRefId(shape.props.src);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 47fd2e4 and cda1da2.

📒 Files selected for processing (1)
  • apps/obsidian/src/components/canvas/TldrawViewComponent.tsx (3 hunks)
🔇 Additional comments (7)
apps/obsidian/src/components/canvas/TldrawViewComponent.tsx (7)

45-50: LGTM! Imports support the shift-click feature.

All new imports are used in the shift-click handler logic.


52-56: LGTM! Type alias conversion is semantically equivalent.

The conversion from interface to type alias has no functional impact. Both declarations define the same shape.


69-73: LGTM! Refs and debounce constant are well-defined.

The debounce interval of 300ms is appropriate for preventing accidental double-clicks. Explicit null initialization for saveTimeoutRef and editorRef provides clarity.


202-210: LGTM! Debouncing logic is correctly implemented.

The debounce mechanism properly prevents double-clicks within 300ms.


182-281: Well-integrated shift-click handler.

The shift-click functionality is cleanly integrated into the existing event handling system without disrupting the relation creation logic. The use of toasts for user feedback is consistent with the rest of the codebase.


246-277: Clarify newLeaf usage in openLinkText
You’re passing true to always open in a new pane; elsewhere (e.g. createNode.ts uses false, RelationshipSection.tsx omits the flag) calls default to the current pane. Confirm if forcing a new leaf here (TldrawViewComponent.tsx:262) is intentional or should match existing behavior.


217-224: Clarify shift-click open behavior
In the shift-click handler we bail when more than one discourse node is selected but don’t verify that the clicked node is the one selected. Should we only open when the clicked shape’s ID matches the single selected node (e.g. if (selectedDiscourseNodes[0].id !== shape.id) return;)?

Comment on lines +211 to +215
const shape = editor.getShapeAtPoint(
editor.inputs.currentPagePoint,
) as DiscourseNodeShape;

if (!shape || shape.type !== "discourse-node") return;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Unsafe type assertion on shape.

The type assertion as DiscourseNodeShape on line 213 is unsafe. getShapeAtPoint returns a shape of unknown type, and while line 215 checks the type at runtime, TypeScript doesn't narrow the type from the assertion.

Consider narrowing the type after the runtime check:

-          const shape = editor.getShapeAtPoint(
-            editor.inputs.currentPagePoint,
-          ) as DiscourseNodeShape;
+          const shape = editor.getShapeAtPoint(
+            editor.inputs.currentPagePoint,
+          );

           if (!shape || shape.type !== "discourse-node") return;
+          
+          // Now we know shape is a discourse-node
+          const discourseNode = shape as DiscourseNodeShape;

Then use discourseNode instead of shape in the subsequent code.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const shape = editor.getShapeAtPoint(
editor.inputs.currentPagePoint,
) as DiscourseNodeShape;
if (!shape || shape.type !== "discourse-node") return;
const shape = editor.getShapeAtPoint(
editor.inputs.currentPagePoint,
);
if (!shape || shape.type !== "discourse-node") return;
// Now we know shape is a discourse-node
const discourseNode = shape as DiscourseNodeShape;
🤖 Prompt for AI Agents
In apps/obsidian/src/components/canvas/TldrawViewComponent.tsx around lines
211-215, remove the unsafe inline cast "as DiscourseNodeShape" on the result of
getShapeAtPoint; instead keep the runtime type check (if (!shape || shape.type
!== "discourse-node") return;) and then narrow the type afterwards by creating a
new const like "const discourseNode = shape as DiscourseNodeShape" (or use a
type predicate helper) and use discourseNode in subsequent code—this preserves
the runtime guard and confines the assertion to a safe, post-check assignment.

@github-project-automation github-project-automation bot moved this to Done in General Oct 10, 2025
@trangdoan982 trangdoan982 deleted the 10-03-add_shift_click_ability branch October 10, 2025 01:35
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.

7 participants