diff --git a/apps/roam/src/components/ModifyNodeDialog.tsx b/apps/roam/src/components/ModifyNodeDialog.tsx index 3137e338f..a765cd418 100644 --- a/apps/roam/src/components/ModifyNodeDialog.tsx +++ b/apps/roam/src/components/ModifyNodeDialog.tsx @@ -107,13 +107,16 @@ const ModifyNodeDialog = ({ : allNodes.filter(excludeDefaultNodes); }, [includeDefaultNodes]); - const [selectedNodeType, setSelectedNodeType] = useState(() => { + const [selectedNodeType, setSelectedNodeType] = useState< + (typeof discourseNodes)[number] | null + >(() => { + if (!nodeType) return null; const node = discourseNodes.find((n) => n.type === nodeType); - return node || discourseNodes[0]; + return node || null; }); const nodeFormat = useMemo(() => { - return selectedNodeType.format || ""; + return selectedNodeType?.format || ""; }, [selectedNodeType]); const referencedNode = useMemo(() => { @@ -158,6 +161,39 @@ const ModifyNodeDialog = ({ if (contentRequestIdRef.current === req && alive) { setOptions((prev) => ({ ...prev, content: results })); } + } else { + // Query all discourse node types in parallel + const allResults = await Promise.all( + discourseNodes.map(async (node) => { + const conditionUid = window.roamAlphaAPI.util.generateUID(); + const results = await fireQuery({ + returnNode: "node", + selections: [], + conditions: [ + { + source: "node", + relation: "is a", + target: node.type, + uid: conditionUid, + type: "clause", + }, + ], + }); + return results.map((r) => ({ + ...r, + _discourseNodeType: node.type, + })); + }), + ); + const seen = new Set(); + const deduped = allResults.flat().filter((r) => { + if (seen.has(r.uid)) return false; + seen.add(r.uid); + return true; + }); + if (contentRequestIdRef.current === req && alive) { + setOptions((prev) => ({ ...prev, content: deduped })); + } } } catch (error) { if (contentRequestIdRef.current === req && alive) { @@ -224,9 +260,20 @@ const ModifyNodeDialog = ({ }; }, [selectedNodeType, referencedNode]); - const setValue = useCallback((r: Result) => { - setContent(r); - }, []); + const setValue = useCallback( + (r: Result) => { + setContent(r); + if (!selectedNodeType && r.uid) { + const detectedType = (r as Record) + ._discourseNodeType as string | undefined; + if (detectedType) { + const nt = discourseNodes.find((n) => n.type === detectedType); + if (nt) setSelectedNodeType(nt); + } + } + }, + [selectedNodeType, discourseNodes], + ); const setReferencedNodeValueCallback = useCallback((r: Result) => { setReferencedNodeValue(r); @@ -302,9 +349,13 @@ const ModifyNodeDialog = ({ const onSubmit = async () => { if (!content.text.trim()) return; + if (!selectedNodeType && !isContentLocked) { + setError("Please select a node type"); + return; + } posthog.capture("Modify Node Dialog: Submit Triggered", { mode, - nodeType: selectedNodeType.type, + nodeType: selectedNodeType?.type, }); try { if (mode === "create") { @@ -324,7 +375,7 @@ const ModifyNodeDialog = ({ await addImageToPage({ pageUid, imageUrl, - configPageUid: selectedNodeType.type, + configPageUid: selectedNodeType!.type, extensionAPI, }); } @@ -371,7 +422,7 @@ const ModifyNodeDialog = ({ } else { formattedTitle = await getNewDiscourseNodeText({ text: content.text.trim(), - nodeType: selectedNodeType.type, + nodeType: selectedNodeType!.type, blockUid: sourceBlockUid, }); } @@ -382,7 +433,7 @@ const ModifyNodeDialog = ({ // Create new discourse node const newPageUid = await createDiscourseNode({ text: formattedTitle, - configPageUid: selectedNodeType.type, + configPageUid: selectedNodeType!.type, extensionAPI, imageUrl, }); @@ -503,6 +554,26 @@ const ModifyNodeDialog = ({ style={{ pointerEvents: "all" }} >
+ {/* Content Input */} +
+ + +
+ {/* Node Type Selector */}
- {/* Content Input */} -
- - -
- {/* Referenced Node Input */} {referencedNode && !isContentLocked && mode === "create" && (
diff --git a/apps/roam/src/utils/registerCommandPaletteCommands.ts b/apps/roam/src/utils/registerCommandPaletteCommands.ts index 6e5dbf61e..2eb143229 100644 --- a/apps/roam/src/utils/registerCommandPaletteCommands.ts +++ b/apps/roam/src/utils/registerCommandPaletteCommands.ts @@ -189,19 +189,9 @@ export const registerCommandPaletteCommands = (onloadArgs: OnloadArgs) => { const selectionStart = uid ? getSelectionStartForBlock(uid) : 0; - const defaultNodeType = - getDiscourseNodes().filter(excludeDefaultNodes)[0]?.type; - if (!defaultNodeType) { - renderToast({ - id: "create-discourse-node-command-no-types", - content: "No discourse node types found in settings.", - }); - return; - } - renderModifyNodeDialog({ mode: "create", - nodeType: defaultNodeType, + nodeType: "", initialValue: { text: "", uid: "" }, extensionAPI, onSuccess: async (result) => {