ENG-2038 Add admin-flagged node card context menu to Obsidian tldraw - #1255
ENG-2038 Add admin-flagged node card context menu to Obsidian tldraw#1255sid597 wants to merge 5 commits into
Conversation
|
This pull request has been ignored for the connected project Preview Branches by Supabase. |
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
@codex review |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
| {activeTab === "context" ? ( | ||
| <RelationsPanel | ||
| plugin={plugin} | ||
| canvasFile={canvasFile} | ||
| nodeShape={selectedNode} | ||
| embedded | ||
| includeAllDirections | ||
| /> | ||
| ) : ( | ||
| createElement(DefaultStylePanelContentComponent, { styles }) | ||
| )} |
There was a problem hiding this comment.
🔴 Selecting a node card silently edits the canvas note and can append duplicate link blocks
The relations list is now shown automatically whenever a single node card is selected (RelationsPanel at apps/obsidian/src/components/canvas/NodeCardContextMenu.tsx:85-91), and merely showing it writes new link blocks into the canvas note, so users get unexpected file edits just by clicking a card.
Impact: Clicking a node card can modify the saved canvas note without any user action, and repeated re-renders while dragging can append the same link text over and over.
How rendering the relations list triggers vault writes
Each listed related file is rendered as a RelationFileItem, whose mount effect calls checkExistingRelation (apps/obsidian/src/components/canvas/overlays/RelationPanel.tsx:76-90). checkExistingRelation calls ensureBlockRefForFile (apps/obsidian/src/components/canvas/overlays/RelationPanel.tsx:269-273), which, when no existing block ref points at the target file, appends [[link]]\n^uuid to the canvas markdown via app.vault.process (apps/obsidian/src/components/canvas/stores/assetStore.ts:143-155).
Previously this only ran after the user explicitly opened the floating Relations panel via the overlay button (apps/obsidian/src/components/canvas/overlays/RelationOverlay.tsx:80-101). With the new style-panel menu the panel mounts on every single-node selection.
Additionally, checkExistingRelation is re-created on every RelationsPanel render and is in the effect's dependency array, and NodeCardContextMenu re-renders whenever the selected shape record changes (e.g. while dragging, via useValue at apps/obsidian/src/components/canvas/NodeCardContextMenu.tsx:42-46). Because Obsidian's metadataCache updates asynchronously, consecutive invocations can miss the just-written block and append another duplicate block for the same file.
Prompt for agents
Rendering RelationsPanel now happens automatically on node selection (NodeCardContextMenu Context tab), but the panel's per-item relation check has a side effect: checkExistingRelation in apps/obsidian/src/components/canvas/overlays/RelationPanel.tsx calls ensureBlockRefForFile, which appends a new '[[link]]\n^uuid' block to the canvas markdown file (apps/obsidian/src/components/canvas/stores/assetStore.ts) when none exists. This means merely selecting a card mutates the note. It is also re-run on every re-render because checkExistingRelation is re-created each render and is an effect dependency, and metadataCache lag can cause duplicate appends.
Possible approaches: introduce a read-only lookup (e.g. resolve an existing block ref without creating one) for the existence check, and only call ensureBlockRefForFile when the user actually creates a relation; and/or memoize checkExistingRelation (useCallback) so the per-item effect does not re-run on every render.
Was this helpful? React with 👍 or 👎 to provide feedback.
Summary
discourse-nodeis selectedBehavior boundaries
DefaultStylePanel.includeAllDirectionsis explicit at the new menu call site;embeddedcontrols layout only.matchingRelations.slice(0, 1)uses the same predicate and first match as the previous.find(...), and its counterpart lookup is unchanged.ComponentTypecasts are required because tldraw is typed against React 19 while the Obsidian app runs React 18; plain JSX addsTS2786diagnostics. The repository-wide React type mismatch is intentionally out of scope.Scope
This PR changes seven Obsidian production files only. It adds one load-bearing CSS rule and no test command, test framework, dependency, lockfile change, or standalone model layer.
Linear: https://linear.app/discourse-graphs/issue/ENG-2038/add-admin-flagged-node-card-context-menu-to-obsidian-tldraw
Validation
pnpm --filter @discourse-graphs/obsidian build— built with 0 errorsgit diff --check— passed--color-text-3tokenKnown validation gaps
apps/obsidianhas no test harness, and a deferral ticket plus the ticket owner's acceptance are still requiredcheck-typesremains red with the same 20 pre-existing tldraw/React JSX type-identity diagnostics; no diagnostic is introduced inNodeCardContextMenuorRelationPanel