From 39814522d79ece83104329ac919ae321166026ed Mon Sep 17 00:00:00 2001 From: Trang Doan Date: Sun, 22 Mar 2026 16:01:32 -0400 Subject: [PATCH] ENG-1315: Disable node type change in canvas create-node modal Prevent node type mismatch by disabling the node type selector when creating nodes from canvas contexts (DiscourseNodeTools, Convert-to, shape select). Non-canvas flows (command palette, node tag popup) remain unaffected. Co-Authored-By: Claude Opus 4.6 --- apps/roam/src/components/ModifyNodeDialog.tsx | 9 ++++++++- apps/roam/src/components/canvas/DiscourseNodeUtil.tsx | 2 ++ apps/roam/src/components/canvas/uiOverrides.tsx | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/apps/roam/src/components/ModifyNodeDialog.tsx b/apps/roam/src/components/ModifyNodeDialog.tsx index 3137e338f..dafd67f07 100644 --- a/apps/roam/src/components/ModifyNodeDialog.tsx +++ b/apps/roam/src/components/ModifyNodeDialog.tsx @@ -47,6 +47,7 @@ export type ModifyNodeDialogProps = { extensionAPI?: OnloadArgs["extensionAPI"]; includeDefaultNodes?: boolean; // Include default nodes (Page, Block) in node type selector imageUrl?: string; // For image conversion from canvas + disableNodeTypeChange?: boolean; // Disable node type selector (e.g. canvas contexts) onSuccess: (result: { text: string; uid: string; @@ -65,6 +66,7 @@ const ModifyNodeDialog = ({ extensionAPI, includeDefaultNodes = false, imageUrl, + disableNodeTypeChange = false, onSuccess, onClose, }: RoamOverlayProps) => { @@ -520,8 +522,13 @@ const ModifyNodeDialog = ({ setReferencedNodeValue({ text: "", uid: "" }); } }} - disabled={mode === "edit"} + disabled={mode === "edit" || disableNodeTypeChange} popoverProps={{ openOnTargetFocus: false }} + className={ + mode === "edit" || disableNodeTypeChange + ? "cursor-not-allowed opacity-50" + : "" + } /> diff --git a/apps/roam/src/components/canvas/DiscourseNodeUtil.tsx b/apps/roam/src/components/canvas/DiscourseNodeUtil.tsx index 263973bbe..863a9c34b 100644 --- a/apps/roam/src/components/canvas/DiscourseNodeUtil.tsx +++ b/apps/roam/src/components/canvas/DiscourseNodeUtil.tsx @@ -530,6 +530,7 @@ export class BaseDiscourseNodeUtil extends BaseBoxShapeUtil : undefined, extensionAPI, includeDefaultNodes: true, + disableNodeTypeChange: true, onSuccess: async ({ text, uid, action }) => { if (action === "edit") { if (isPageUid(shape.props.uid)) @@ -651,6 +652,7 @@ export class BaseDiscourseNodeUtil extends BaseBoxShapeUtil initialValue: { text: cleanedText, uid: "" }, extensionAPI, includeDefaultNodes: true, + disableNodeTypeChange: true, onSuccess: async ({ text, uid }) => { if (!extensionAPI) return; try { diff --git a/apps/roam/src/components/canvas/uiOverrides.tsx b/apps/roam/src/components/canvas/uiOverrides.tsx index 049c84edf..c503ae44d 100644 --- a/apps/roam/src/components/canvas/uiOverrides.tsx +++ b/apps/roam/src/components/canvas/uiOverrides.tsx @@ -162,6 +162,7 @@ export const getOnSelectForShape = ({ initialValue: { text: initialText, uid: "" }, extensionAPI, includeDefaultNodes: true, + disableNodeTypeChange: true, imageUrl, onSuccess: async ({ text, uid }) => { editor.deleteShapes([shape.id]);