@@ -17,6 +17,12 @@ import { getFrontmatterForFile } from "~/components/canvas/shapes/discourseNodeS
1717import { getRelationTypeById } from "~/utils/typeUtils" ;
1818import { showToast } from "~/components/canvas/utils/toastUtils" ;
1919import { DEFAULT_TLDRAW_COLOR } from "~/utils/tldrawColors" ;
20+ import {
21+ getNodeInstanceIdForFile ,
22+ getRelationsForNodeInstanceId ,
23+ getFileForNodeInstanceId ,
24+ addRelation ,
25+ } from "~/utils/relationsStore" ;
2026
2127type GroupedRelation = {
2228 key : string ;
@@ -184,7 +190,7 @@ export const RelationsPanel = ({
184190 setError ( "Linked file not found." ) ;
185191 return ;
186192 }
187- const g = computeRelations ( plugin , file ) ;
193+ const g = await computeRelations ( plugin , file ) ;
188194 setGroups ( g ) ;
189195 } catch ( e ) {
190196 showToast ( {
@@ -346,10 +352,33 @@ export const RelationsPanel = ({
346352 isSource : boolean ,
347353 ) => {
348354 try {
349- const targetNode = await ensureNodeShapeForFile ( targetFile ) ;
350355 const relationType = getRelationTypeById ( plugin , relationTypeId ) ;
351356 const relationLabel = relationType ?. label ?? "" ;
352357
358+ const currentFile = await resolveLinkedFileFromSrc ( {
359+ app : plugin . app ,
360+ canvasFile,
361+ src : nodeShape . props . src ?? "" ,
362+ } ) ;
363+ if ( ! currentFile || ! targetFile ) return ;
364+
365+ const sourceFile = isSource ? currentFile : targetFile ;
366+ const destFile = isSource ? targetFile : currentFile ;
367+ const sourceId = await getNodeInstanceIdForFile ( plugin , sourceFile ) ;
368+ const destId = await getNodeInstanceIdForFile ( plugin , destFile ) ;
369+ if ( ! sourceId || ! destId ) {
370+ showToast ( {
371+ severity : "error" ,
372+ title : "Could Not Resolve Nodes" ,
373+ description :
374+ "Could not resolve node instance IDs for the selected files." ,
375+ targetCanvasId : canvasFile . path ,
376+ } ) ;
377+ return ;
378+ }
379+
380+ const targetNode = await ensureNodeShapeForFile ( targetFile ) ;
381+
353382 const id : TLShapeId = createShapeId ( ) ;
354383
355384 // Determine source and destination nodes
@@ -417,6 +446,17 @@ export const RelationsPanel = ({
417446 isExact : false ,
418447 snap : "none" ,
419448 } ) ;
449+
450+ const { id : relationInstanceId } = await addRelation ( plugin , {
451+ type : relationTypeId ,
452+ source : sourceId ,
453+ destination : destId ,
454+ } ) ;
455+ editor . updateShape ( {
456+ id : shape . id ,
457+ type : shape . type ,
458+ meta : { ...shape . meta , relationInstanceId } ,
459+ } ) ;
420460 } catch ( e ) {
421461 console . error ( "Failed to create relation to file" , e ) ;
422462 showToast ( {
@@ -487,35 +527,36 @@ export const RelationsPanel = ({
487527 ) ;
488528} ;
489529
490- const computeRelations = (
530+ const computeRelations = async (
491531 plugin : DiscourseGraphPlugin ,
492532 file : TFile ,
493- ) : GroupedRelation [ ] => {
533+ ) : Promise < GroupedRelation [ ] > => {
494534 const fileCache = plugin . app . metadataCache . getFileCache ( file ) ;
495535 if ( ! fileCache ?. frontmatter ) return [ ] ;
496536
497537 const activeNodeTypeId = fileCache . frontmatter . nodeTypeId as string ;
498538 if ( ! activeNodeTypeId ) return [ ] ;
499539
540+ const nodeInstanceId = await getNodeInstanceIdForFile ( plugin , file ) ;
541+ if ( ! nodeInstanceId ) return [ ] ;
542+
543+ const relations = await getRelationsForNodeInstanceId (
544+ plugin ,
545+ nodeInstanceId ,
546+ ) ;
500547 const result = new Map < string , GroupedRelation > ( ) ;
501548
502549 for ( const relationType of plugin . settings . relationTypes ) {
503- const frontmatterLinks = fileCache . frontmatter [ relationType . id ] as unknown ;
504- if ( ! frontmatterLinks ) continue ;
505-
506- const links = Array . isArray ( frontmatterLinks )
507- ? ( frontmatterLinks as unknown [ ] )
508- : [ frontmatterLinks ] ;
509-
510- const relation = plugin . settings . discourseRelations . find (
550+ const typeLevelRelation = plugin . settings . discourseRelations . find (
511551 ( rel ) =>
512552 ( rel . sourceId === activeNodeTypeId ||
513553 rel . destinationId === activeNodeTypeId ) &&
514554 rel . relationshipTypeId === relationType . id ,
515555 ) ;
516- if ( ! relation ) continue ;
556+ if ( ! typeLevelRelation ) continue ;
517557
518- const isSource = relation . sourceId === activeNodeTypeId ;
558+ const instanceRels = relations . filter ( ( r ) => r . type === relationType . id ) ;
559+ const isSource = typeLevelRelation . sourceId === activeNodeTypeId ;
519560 const label = isSource ? relationType . label : relationType . complement ;
520561 const key = `${ relationType . id } -${ isSource } ` ;
521562
@@ -529,23 +570,15 @@ const computeRelations = (
529570 } ) ;
530571 }
531572
532- for ( const link of links ) {
533- const match = String ( link ) . match ( / \[ \[ ( .* ?) \] \] / ) ;
534- if ( ! match ) continue ;
535- const linkedFileName = match [ 1 ] ?? "" ;
536- const linked = plugin . app . metadataCache . getFirstLinkpathDest (
537- linkedFileName ,
538- file . path ,
539- ) ;
540- if ( ! linked ) continue ;
541-
542- const group = result . get ( key ) ;
543- if ( group && ! group . linkedFiles . some ( ( f ) => f . path === linked . path ) ) {
573+ const group = result . get ( key ) ! ;
574+ for ( const r of instanceRels ) {
575+ const otherId = r . source === nodeInstanceId ? r . destination : r . source ;
576+ const linked = await getFileForNodeInstanceId ( plugin , otherId ) ;
577+ if ( linked && ! group . linkedFiles . some ( ( f ) => f . path === linked . path ) ) {
544578 group . linkedFiles . push ( linked ) ;
545579 }
546580 }
547581 }
548582
549583 return Array . from ( result . values ( ) ) ;
550584} ;
551-
0 commit comments