@@ -12,8 +12,6 @@ import { render as renderToast } from "roamjs-components/components/Toast";
1212import MenuItemSelect from "roamjs-components/components/MenuItemSelect" ;
1313import AutocompleteInput from "roamjs-components/components/AutocompleteInput" ;
1414import getPageTitleByPageUid from "roamjs-components/queries/getPageTitleByPageUid" ;
15- import getPageUidByPageTitle from "roamjs-components/queries/getPageUidByPageTitle" ;
16- import getAllPageNames from "roamjs-components/queries/getAllPageNames" ;
1715import sendErrorEmail from "~/utils/sendErrorEmail" ;
1816import { getSetting } from "~/utils/extensionSettings" ;
1917import getDiscourseRelations , {
@@ -71,33 +69,45 @@ const CreateRelationDialog = ({
7169
7270 const relKeys = Object . keys ( relDataByTag ) ;
7371 const [ selectedRelationName , setSelectedRelationName ] = useState ( relKeys [ 0 ] ) ;
74- const [ selectedTargetTitle , setSelectedTargetTitle ] = useState < string > ( "" ) ;
75- const [ selectedTargetUid , setSelectedTargetUid ] = useState <
76- string | undefined
77- > ( undefined ) ;
78- const allPages = useMemo ( ( ) => getAllPageNames ( ) . sort ( ) , [ ] ) ;
79- const getFilteredPageNames = ( selectedRelationName : string ) : string [ ] => {
72+ const [ selectedTarget , setSelectedTarget ] = useState < Result > ( {
73+ text : "" ,
74+ uid : "" ,
75+ } ) ;
76+ const pageUidByTitle = useMemo (
77+ ( ) =>
78+ Object . fromEntries (
79+ window . roamAlphaAPI . data . fast . q (
80+ "[:find ?t ?u :where [?p :node/title ?t] [?p :block/uid ?u]]" ,
81+ ) as [ string , string ] [ ] ,
82+ ) ,
83+ [ ] ,
84+ ) ;
85+ const allPages = useMemo (
86+ ( ) =>
87+ Object . entries ( pageUidByTitle ) . map (
88+ ( [ text , uid ] ) : Result => ( { uid, text } ) ,
89+ ) ,
90+ [ pageUidByTitle ] ,
91+ ) ;
92+ const getFilteredPageNames = ( selectedRelationName : string ) : Result [ ] => {
8093 if ( ! relDataByTag [ selectedRelationName ] ?. length ) return [ ] ;
8194 const formats = relDataByTag [ selectedRelationName ] . map ( ( rel ) =>
8295 getDiscourseNodeFormatInnerExpression (
8396 nodesById [ rel . forward ? rel . destination : rel . source ] . format ,
8497 ) ,
8598 ) ;
8699 const re = RegExp ( `^(${ formats . join ( ")|(" ) } )$` , "s" ) ;
87- return allPages . filter ( ( title ) => title . match ( re ) ) ;
100+ return allPages . filter ( ( { text } ) => text . match ( re ) ) ;
88101 } ;
89- const [ pageOptions , setPageOptions ] = useState < string [ ] > (
102+ const [ pageOptions , setPageOptions ] = useState < Result [ ] > (
90103 getFilteredPageNames ( relKeys [ 0 ] ) ,
91104 ) ;
92105
93- const identifyRelationMatch = (
94- targetTitle : string ,
95- targetUid : string ,
96- ) : RelWithDirection | null => {
97- if ( targetTitle . length === 0 ) return null ;
106+ const identifyRelationMatch = ( target : Result ) : RelWithDirection | null => {
107+ if ( target . text . length === 0 ) return null ;
98108 const selectedTargetType = findDiscourseNodeByTitleAndUid ( {
99- uid : targetUid ,
100- title : targetTitle ,
109+ uid : target . uid ,
110+ title : target . text ,
101111 nodes : discourseNodes ,
102112 } ) ;
103113 if ( selectedTargetType === false ) {
@@ -136,16 +146,13 @@ const CreateRelationDialog = ({
136146 } ;
137147
138148 const onCreate = async ( ) : Promise < boolean > => {
139- if ( selectedTargetUid === undefined ) return false ;
140- const relation = identifyRelationMatch (
141- selectedTargetTitle ,
142- selectedTargetUid ,
143- ) ;
149+ if ( selectedTarget . uid === "" ) return false ;
150+ const relation = identifyRelationMatch ( selectedTarget ) ;
144151 if ( relation === null ) return false ;
145152 const result = await createReifiedRelation ( {
146153 relationBlockUid : relation . id ,
147- sourceUid : relation . forward ? sourceNodeUid : selectedTargetUid ,
148- destinationUid : relation . forward ? selectedTargetUid : sourceNodeUid ,
154+ sourceUid : relation . forward ? sourceNodeUid : selectedTarget . uid ,
155+ destinationUid : relation . forward ? selectedTarget . uid : sourceNodeUid ,
149156 } ) ;
150157 return result !== undefined ;
151158 } ;
@@ -183,29 +190,33 @@ const CreateRelationDialog = ({
183190 setSelectedRelationName ( relName ) ;
184191 setPageOptions ( getFilteredPageNames ( relName ) ) ;
185192 if (
186- selectedTargetUid !== undefined &&
187- identifyRelationMatch ( selectedTargetTitle , selectedTargetUid ) === null
193+ selectedTarget . uid !== "" &&
194+ identifyRelationMatch ( selectedTarget ) === null
188195 ) {
189- setSelectedTargetUid ( undefined ) ;
196+ setSelectedTarget ( { text : "" , uid : "" } ) ;
190197 }
191198 } ;
192199
193- const getNodeFromTitle = ( title : string ) : void => {
194- if ( title === selectedTargetTitle ) return ;
195- setSelectedTargetTitle ( title ) ;
196- const uid = getPageUidByPageTitle ( title ) ;
197- if ( uid . length === 0 ) {
198- setSelectedTargetUid ( undefined ) ;
199- return ;
200- }
201- const relation = identifyRelationMatch ( title , uid ) ;
200+ const setResult = ( value : Result ) : void => {
201+ const relation = value . uid . length ? identifyRelationMatch ( value ) : null ;
202202 if ( relation === null ) {
203- setSelectedTargetUid ( undefined ) ;
203+ setSelectedTarget ( { text : value . text , uid : "" } ) ;
204+ } else {
205+ setSelectedTarget ( value ) ;
206+ }
207+ } ;
208+
209+ const setResultFromTitle = ( text : string ) : void => {
210+ const uid = pageUidByTitle [ text ] ;
211+ if ( uid === undefined ) {
212+ setSelectedTarget ( { text, uid : "" } ) ;
204213 return ;
205214 }
206- setSelectedTargetUid ( uid ) ;
215+ setResult ( { text , uid } ) ;
207216 } ;
208217
218+ const itemToQuery = ( r ?: Result ) => ( r ? r . text : "" ) ;
219+
209220 return (
210221 < Dialog
211222 isOpen = { true }
@@ -235,9 +246,10 @@ const CreateRelationDialog = ({
235246 </ div >
236247 < div className = "make-popover-full-width" >
237248 < AutocompleteInput
238- value = { selectedTargetTitle }
239- setValue = { getNodeFromTitle }
240- onBlur = { getNodeFromTitle }
249+ value = { selectedTarget }
250+ itemToQuery = { itemToQuery }
251+ setValue = { setResult }
252+ onBlur = { setResultFromTitle }
241253 placeholder = { "Search for a page..." }
242254 options = { pageOptions }
243255 />
@@ -252,7 +264,7 @@ const CreateRelationDialog = ({
252264 < Button
253265 intent = "primary"
254266 onClick = { onCreateSync }
255- disabled = { ! selectedTargetUid }
267+ disabled = { selectedTarget . uid === "" }
256268 >
257269 Create
258270 </ Button >
0 commit comments