Skip to content

ENG-2256 Implement new relation menu empty state - #1491

Merged
trangdoan982 merged 3 commits into
mainfrom
eng-2256-implement-new-relation-menu-empty-state
Oct 2, 2026
Merged

trangdoan982 merged 3 commits into
mainfrom
eng-2256-implement-new-relation-menu-empty-state

Conversation

@trangdoan982

@trangdoan982 trangdoan982 commented Sep 27, 2026 •

Copy link
Copy Markdown
Member

https://entire.io/gh/DiscourseGraphs/discourse-graph/trails/31

Reviewer brief

  • Result: Dragging an arrow between two node types with no relation types now opens the relation type menu with Add existing… and Create new. The populated menu shows the same two actions in a flyout behind a "+" in the header.
  • Review focus: the pending arrow is saved while the menu is open, so it's tagged with meta.pendingRelationMenu, and DragHandleOverlay deletes tagged leftovers on mount (fixes the Devin thread). Also, DragHandleOverlay.tsx no longer removes the arrow for pairs with no relation types. It still removes it when either node has no node type, now with the toast "Both nodes need a node type to create a relation".
  • Risk or follow-up:
    • Known limit: Add existing… and Create new do nothing yet. ENG-2257 wires the picker and ENG-2258 wires the create dialog. The three PRs are stacked and should merge close together; the ENG-2256 Linear comment records this.
    • Known limit: when the arrow ends near the right edge of the canvas, tldraw's style panel is drawn over the menu and can cover the "+". This predates the PR, and a follow-up is filed.
    • The new flyout uses the dropdown's existing hardcoded gray colors, not Obsidian CSS variables, to match the current menu.

Look at the "no types" branch: it's the new path. The other path is unchanged apart from the "+".

flowchart LR
  A[Drag arrow to a discourse node] --> B{DragHandleOverlay:<br/>both nodes have nodeTypeId?}
  B -- no --> T[Remove arrow, toast:<br/>'Both nodes need a node type']
  B -- yes --> C[RelationTypeDropdown:<br/>getValidRelationTypesForNodePair]
  C -- no types --> D[Empty state:<br/>Add existing… / Create new]
  C -- some types --> E[Type list + '+' in header]
  E -- click '+' --> F[Flyout inside dropdownRef:<br/>Add existing… / Create new]
  F -- Escape --> E
Loading
Verification

pnpm ci:validate passes. Live checks ran in Obsidian over CDP (dg-obsidian-cdp-verify) with real pointer input.

Scenario Input Expected Actual Pass
Empty pair Drag Question → Claim (no relation types) Menu with both actions, no "+", arrow kept, no toast As expected ✅
Empty pair action Click Add existing… Menu stays open As expected ✅
Populated "+" Drag Evidence → Claim, click "+" twice Flyout opens, then closes As expected ✅
Flyout item Click Create new in flyout Menu and flyout stay open As expected ✅
Escape order Escape, then Escape First closes flyout only; second closes menu and deletes arrow As expected ✅
Pick a type Click supports Relation created with type, color, label and toast As expected; relations.json 49 → 50 ✅
Outside click Click empty canvas Menu closes, arrow deleted As expected ✅
Node without type Drag to a node with no nodeTypeId Arrow removed, toast "Both nodes need a node type…" As expected ✅
Layout Inspect action buttons and "+" Actions left-aligned; "+" 22 × 22 justify-content: flex-start; 22 × 22 ✅
Abandoned arrow Open menu on empty pair, wait 2.5s, close and reopen canvas Pending arrow deleted on reopen, and the deletion is saved No arrow in store or saved file ✅
Picked arrow survives Pick supports, wait 2.5s, close and reopen canvas Arrow kept with its type; pendingRelationMenu: false As expected; relation still in relations.json ✅
Dismiss after fix Menu open, Escape twice Arrow deleted As expected ✅
Scenario Screenshot
Empty pair opens menu with both actions Empty pair opens menu with both actions
Populated pair: + opens the flyout Populated pair: + opens the flyout
First Escape closes the flyout only First Escape closes the flyout only
Picking a type still creates the relation Picking a type still creates the relation
Node without a type: arrow removed with toast Node without a type: arrow removed with toast

No unit tests were added. The change is UI wiring, which the Vitest scope in apps/obsidian/AGENTS.md excludes.

Not verified: the last two edits (removing a code comment, and changing the header text to Relation type, which still displays as all caps) weren't re-run live, since neither changes behavior or rendering.

Loom video

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

Scope check

  • Ran $scope-check against the ENG ticket and final diff.
  • Scope beyond Done When: None. Done When (3) is deferred on purpose: the actions are rendered but not wired. ENG-2257 (Add existing) and ENG-2258 (Create new) wire them in this stack. The team accepted this; see the ENG-2256 Linear comment. The new toast for nodes without a node type replaces the old guard's message, which no longer fits once pairs with no relation types reach the menu.

Standards check

  • Ran $dg-pr-adherence-check against the final diff and PR metadata.

I fixed two findings: the code comment about the ticket split moved to this brief, and the header is now in sentence case. The hardcoded gray colors are left as is to match the existing dropdown. The Loom video is still missing.

Local delegated full review

  • Ran a comprehensive review of the entire final diff in a subagent with a fresh context. Use $dg-delegated-full-review when no other full-review workflow is available.

No findings.

🤖 Generated with Claude Code


Devin Review

@vercel

vercel Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
discourse-graph Ready Ready Preview Oct 2, 2026 7:41pm UTC

Request Review

@supabase

supabase Bot commented Sep 27, 2026

Copy link
Copy Markdown

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

@linear-code

linear-code Bot commented Sep 27, 2026

Copy link
Copy Markdown

ENG-2256

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Devin Review found 1 potential issue.

1 flag not posted on this PR by your GitHub settings — view it in Devin Review. (Configure)

Devin Review

Comment thread apps/obsidian/src/components/canvas/overlays/DragHandleOverlay.tsx
}, []);

// A pending arrow found on mount was abandoned when the canvas last closed
useEffect(() => {

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.

Why can't we remove the arrow based on the action, whether you click away from the canvas or unfocus or something? Why do we have to catch it on the next canvas load?

trangdoan982 and others added 3 commits October 2, 2026 15:29
Open the relation type menu for node-type pairs with no relation types,
showing Add existing… and Create new. The populated menu exposes the same
actions behind a "+" flyout. The actions are wired in ENG-2257/ENG-2258.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Entire-Checkpoint: 01M3J7D2EQ0H3DABC2RRBSB0J8
The save loop persists the pending arrow while the relation type menu is
open. Tag it in shape meta, clear the tag on pick, and delete tagged
leftovers when the overlay mounts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Entire-Checkpoint: 01M3J8XJJDB6JNC6JZZXN4FMSQ
… the canvas

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Entire-Checkpoint: 01M3Q8WG83DQNA246QGTM0X0YP
@trangdoan982
trangdoan982 force-pushed the eng-2256-implement-new-relation-menu-empty-state branch from 6ff29b6 to 3ec7d51 Compare October 2, 2026 19:39
@trangdoan982
trangdoan982 merged commit 6a49904 into main Oct 2, 2026
9 checks passed
@trangdoan982
trangdoan982 deleted the eng-2256-implement-new-relation-menu-empty-state branch October 2, 2026 20:56

This branch was successfully deployed

1 active deployment
Preview — 3ec7d51a Deployed Oct 2, 2026 by vercel[bot]
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