From 5b4a18f4fbab942c2e934cc208f2ecdb5d243df3 Mon Sep 17 00:00:00 2001 From: Matthew Valancy Date: Sat, 20 Jun 2026 01:00:34 -0700 Subject: [PATCH] fix(graph): inline node editor no longer drops r/R keystrokes (data corruption) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two document-level keydown shortcuts ('r'/'R' → refreshTextVisibility; Shift+R → reinit) fired even while the user was typing in the inline node-title editor, silently swallowing every r/R character and PERSISTING the corrupted title to the DB (e.g. "Marketing Roadmap" → "Maketing oadmap"). Guard both handlers to bail when the event target is an editable field (INPUT/TEXTAREA/contenteditable) — the same guard the undo shortcut already uses. Found by the live Cloudflare in-depth audit (verified, root-caused). Verified live-dev: typing "Marketing Roadmap RRR" into the inline editor now persists exactly; web typecheck clean. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../web/src/components/InteractiveGraphVisualization.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/web/src/components/InteractiveGraphVisualization.tsx b/packages/web/src/components/InteractiveGraphVisualization.tsx index 2780e8f0..bce2b4eb 100644 --- a/packages/web/src/components/InteractiveGraphVisualization.tsx +++ b/packages/web/src/components/InteractiveGraphVisualization.tsx @@ -983,6 +983,10 @@ export function InteractiveGraphVisualization({ onResetLayout, onNodeSelected, i // Manual text refresh shortcut (R key) if (event.key === 'r' || event.key === 'R') { + // Never steal the keystroke while the user is typing in a field (e.g. the + // inline node-title editor) — otherwise titles lose every r/R character. + const t = event.target as HTMLElement | null; + if (t && (t.tagName === 'INPUT' || t.tagName === 'TEXTAREA' || t.isContentEditable)) return; if (!event.ctrlKey && !event.metaKey && !event.altKey) { // Only plain R key event.preventDefault(); refreshTextVisibility(); @@ -4780,6 +4784,8 @@ export function InteractiveGraphVisualization({ onResetLayout, onNodeSelected, i useEffect(() => { const handleKeyDown = (event: KeyboardEvent) => { if (event.key === 'R' && event.shiftKey) { + const t = event.target as HTMLElement | null; + if (t && (t.tagName === 'INPUT' || t.tagName === 'TEXTAREA' || t.isContentEditable)) return; event.preventDefault(); setReinitTrigger(prev => prev + 1); }