@@ -109,13 +109,16 @@ const ModifyNodeDialog = ({
109109 : allNodes . filter ( excludeDefaultNodes ) ;
110110 } , [ includeDefaultNodes ] ) ;
111111
112- const [ selectedNodeType , setSelectedNodeType ] = useState ( ( ) => {
112+ const [ selectedNodeType , setSelectedNodeType ] = useState <
113+ ( typeof discourseNodes ) [ number ] | null
114+ > ( ( ) => {
115+ if ( ! nodeType ) return null ;
113116 const node = discourseNodes . find ( ( n ) => n . type === nodeType ) ;
114- return node || discourseNodes [ 0 ] ;
117+ return node || null ;
115118 } ) ;
116119
117120 const nodeFormat = useMemo ( ( ) => {
118- return selectedNodeType . format || "" ;
121+ return selectedNodeType ? .format || "" ;
119122 } , [ selectedNodeType ] ) ;
120123
121124 const referencedNode = useMemo ( ( ) => {
@@ -160,6 +163,39 @@ const ModifyNodeDialog = ({
160163 if ( contentRequestIdRef . current === req && alive ) {
161164 setOptions ( ( prev ) => ( { ...prev , content : results } ) ) ;
162165 }
166+ } else {
167+ // Query all discourse node types in parallel
168+ const allResults = await Promise . all (
169+ discourseNodes . map ( async ( node ) => {
170+ const conditionUid = window . roamAlphaAPI . util . generateUID ( ) ;
171+ const results = await fireQuery ( {
172+ returnNode : "node" ,
173+ selections : [ ] ,
174+ conditions : [
175+ {
176+ source : "node" ,
177+ relation : "is a" ,
178+ target : node . type ,
179+ uid : conditionUid ,
180+ type : "clause" ,
181+ } ,
182+ ] ,
183+ } ) ;
184+ return results . map ( ( r ) => ( {
185+ ...r ,
186+ _discourseNodeType : node . type ,
187+ } ) ) ;
188+ } ) ,
189+ ) ;
190+ const seen = new Set < string > ( ) ;
191+ const deduped = allResults . flat ( ) . filter ( ( r ) => {
192+ if ( seen . has ( r . uid ) ) return false ;
193+ seen . add ( r . uid ) ;
194+ return true ;
195+ } ) ;
196+ if ( contentRequestIdRef . current === req && alive ) {
197+ setOptions ( ( prev ) => ( { ...prev , content : deduped } ) ) ;
198+ }
163199 }
164200 } catch ( error ) {
165201 if ( contentRequestIdRef . current === req && alive ) {
@@ -226,9 +262,20 @@ const ModifyNodeDialog = ({
226262 } ;
227263 } , [ selectedNodeType , referencedNode ] ) ;
228264
229- const setValue = useCallback ( ( r : Result ) => {
230- setContent ( r ) ;
231- } , [ ] ) ;
265+ const setValue = useCallback (
266+ ( r : Result ) => {
267+ setContent ( r ) ;
268+ if ( ! selectedNodeType && r . uid ) {
269+ const detectedType = ( r as Record < string , unknown > )
270+ . _discourseNodeType as string | undefined ;
271+ if ( detectedType ) {
272+ const nt = discourseNodes . find ( ( n ) => n . type === detectedType ) ;
273+ if ( nt ) setSelectedNodeType ( nt ) ;
274+ }
275+ }
276+ } ,
277+ [ selectedNodeType , discourseNodes ] ,
278+ ) ;
232279
233280 const setReferencedNodeValueCallback = useCallback ( ( r : Result ) => {
234281 setReferencedNodeValue ( r ) ;
@@ -304,9 +351,13 @@ const ModifyNodeDialog = ({
304351
305352 const onSubmit = async ( ) => {
306353 if ( ! content . text . trim ( ) ) return ;
354+ if ( ! selectedNodeType && ! isContentLocked ) {
355+ setError ( "Please select a node type" ) ;
356+ return ;
357+ }
307358 posthog . capture ( "Modify Node Dialog: Submit Triggered" , {
308359 mode,
309- nodeType : selectedNodeType . type ,
360+ nodeType : selectedNodeType ? .type ,
310361 } ) ;
311362 try {
312363 if ( mode === "create" ) {
@@ -326,7 +377,7 @@ const ModifyNodeDialog = ({
326377 await addImageToPage ( {
327378 pageUid,
328379 imageUrl,
329- configPageUid : selectedNodeType . type ,
380+ configPageUid : selectedNodeType ! . type ,
330381 extensionAPI,
331382 } ) ;
332383 }
@@ -373,7 +424,7 @@ const ModifyNodeDialog = ({
373424 } else {
374425 formattedTitle = await getNewDiscourseNodeText ( {
375426 text : content . text . trim ( ) ,
376- nodeType : selectedNodeType . type ,
427+ nodeType : selectedNodeType ! . type ,
377428 blockUid : sourceBlockUid ,
378429 } ) ;
379430 }
@@ -384,7 +435,7 @@ const ModifyNodeDialog = ({
384435 // Create new discourse node
385436 const newPageUid = await createDiscourseNode ( {
386437 text : formattedTitle ,
387- configPageUid : selectedNodeType . type ,
438+ configPageUid : selectedNodeType ! . type ,
388439 extensionAPI,
389440 imageUrl,
390441 } ) ;
@@ -505,6 +556,26 @@ const ModifyNodeDialog = ({
505556 style = { { pointerEvents : "all" } }
506557 >
507558 < div className = { `${ Classes . DIALOG_BODY } flex flex-col gap-4` } >
559+ { /* Content Input */ }
560+ < div className = "w-full" >
561+ < Label > Content</ Label >
562+ < FuzzySelectInput
563+ value = { content }
564+ setValue = { setValue }
565+ options = { options . content }
566+ placeholder = {
567+ loading
568+ ? "..."
569+ : selectedNodeType
570+ ? `Enter a ${ selectedNodeType . text . toLowerCase ( ) } ...`
571+ : "Search all nodes..."
572+ }
573+ mode = { mode }
574+ isLocked = { isContentLocked }
575+ autoFocus = { ! isContentLocked }
576+ />
577+ </ div >
578+
508579 { /* Node Type Selector */ }
509580 < div className = "flex w-full" >
510581 < Label autoFocus = { false } >
@@ -514,15 +585,17 @@ const ModifyNodeDialog = ({
514585 transformItem = { ( t ) =>
515586 discourseNodes . find ( ( n ) => n . type === t ) ?. text || t
516587 }
517- activeItem = { selectedNodeType . type }
588+ activeItem = { selectedNodeType ? .type ?? null }
518589 onItemSelect = { ( t ) => {
519590 const nt = discourseNodes . find ( ( n ) => n . type === t ) ;
520591 if ( nt ) {
521592 setSelectedNodeType ( nt ) ;
522593 setReferencedNodeValue ( { text : "" , uid : "" } ) ;
523594 }
524595 } }
525- disabled = { mode === "edit" || disableNodeTypeChange }
596+ disabled = {
597+ mode === "edit" || disableNodeTypeChange || isContentLocked
598+ }
526599 popoverProps = { { openOnTargetFocus : false } }
527600 className = {
528601 mode === "edit" || disableNodeTypeChange
@@ -533,24 +606,6 @@ const ModifyNodeDialog = ({
533606 </ Label >
534607 </ div >
535608
536- { /* Content Input */ }
537- < div className = "w-full" >
538- < Label > Content</ Label >
539- < FuzzySelectInput
540- value = { content }
541- setValue = { setValue }
542- options = { options . content }
543- placeholder = {
544- loading
545- ? "..."
546- : `Enter a ${ selectedNodeType . text . toLowerCase ( ) } ...`
547- }
548- mode = { mode }
549- isLocked = { isContentLocked }
550- autoFocus = { ! isContentLocked }
551- />
552- </ div >
553-
554609 { /* Referenced Node Input */ }
555610 { referencedNode && ! isContentLocked && mode === "create" && (
556611 < div className = "w-full" >
0 commit comments