1
- import type { RelationNode } from "@/lib/RelationNode"
2
-
3
- import { buildGraphForReferences , getLayoutedElements } from "@/components/graph/helpers"
4
- import { PlainNode } from "@/components/graph/PlainNode"
5
- import { Background , BackgroundVariant , ReactFlow , useEdgesState , useNodesInitialized , useNodesState , useReactFlow } from "@xyflow/react"
6
- import { useCallback , useEffect , useMemo , useRef } from "react"
1
+ import { buildGraphForReferences , getLayoutedElements , ResultPID } from "@/components/graph/helpers"
2
+ import {
3
+ Background ,
4
+ BackgroundVariant ,
5
+ NodeProps ,
6
+ ReactFlow ,
7
+ useEdgesState ,
8
+ useNodesInitialized ,
9
+ useNodesState ,
10
+ useReactFlow ,
11
+ useUpdateNodeInternals
12
+ } from "@xyflow/react"
13
+ import { ComponentType , useCallback , useEffect , useMemo , useRef } from "react"
7
14
import "@xyflow/react/dist/style.css"
8
-
9
- const nodeTypes = {
10
- plain : PlainNode
11
- }
15
+ import { useStore } from "zustand"
16
+ import { resultCache } from "@/lib/ResultCache"
17
+ import { ResultViewWrapper } from "@/components/graph/ResultViewWrapper"
18
+ import { ResultViewProps } from "@elastic/react-search-ui-views"
12
19
13
20
/**
14
21
* Renders an interactive graph for the specified RelationNodes.
15
22
*/
16
- export function RelationsGraph ( props : { base : RelationNode ; referencedBy : RelationNode [ ] ; references : RelationNode [ ] } ) {
23
+ export function RelationsGraph ( props : { base : string ; referencedBy : string [ ] ; references : string [ ] ; resultView : ComponentType < ResultViewProps > } ) {
24
+ const getFromCache = useStore ( resultCache , ( s ) => s . get )
25
+
17
26
const { initialEdges, initialNodes } = useMemo ( ( ) => {
18
- return buildGraphForReferences ( props . base , props . referencedBy , props . references )
19
- } , [ props . base , props . referencedBy , props . references ] )
27
+ const base : ResultPID = { pid : props . base , result : getFromCache ( props . base ) }
28
+ const referencedBy = props . referencedBy . map ( ( pid ) => ( { pid, result : getFromCache ( pid ) } ) )
29
+ const references = props . references . map ( ( pid ) => ( { pid, result : getFromCache ( pid ) } ) )
30
+
31
+ return buildGraphForReferences ( base , referencedBy , references )
32
+ } , [ getFromCache , props . base , props . referencedBy , props . references ] )
33
+
34
+ const nodeTypes = useMemo ( ( ) => {
35
+ return {
36
+ plain : ( nodeProps : NodeProps ) => < ResultViewWrapper { ...nodeProps } resultView = { props . resultView } />
37
+ }
38
+ } , [ props . resultView ] )
20
39
21
40
const [ nodes , setNodes , onNodesChange ] = useNodesState ( initialNodes )
22
41
const [ edges , setEdges , onEdgesChange ] = useEdgesState ( initialEdges )
23
42
const { fitView } = useReactFlow ( )
24
43
const nodesInitialized = useNodesInitialized ( )
44
+ const updateNodeInternals = useUpdateNodeInternals ( )
45
+
46
+ useEffect ( ( ) => {
47
+ setNodes ( initialNodes )
48
+ setEdges ( initialEdges )
49
+ } , [ initialEdges , initialNodes , setEdges , setNodes ] )
25
50
26
51
const onLayout = useCallback ( ( ) => {
27
52
const layouted = getLayoutedElements ( nodes , edges )
@@ -30,9 +55,12 @@ export function RelationsGraph(props: { base: RelationNode; referencedBy: Relati
30
55
setEdges ( [ ...layouted . edges ] )
31
56
32
57
window . requestAnimationFrame ( ( ) => {
33
- fitView ( )
58
+ setTimeout ( ( ) => {
59
+ fitView ( { nodes : [ { id : props . base } ] , duration : 200 , padding : 1 } )
60
+ updateNodeInternals ( nodes . map ( ( n ) => n . id ) )
61
+ } , 100 )
34
62
} )
35
- } , [ nodes , edges , setNodes , setEdges , fitView ] )
63
+ } , [ nodes , edges , setNodes , setEdges , fitView , props . base , updateNodeInternals ] )
36
64
37
65
const onLayoutDebounced = useRef ( onLayout )
38
66
useEffect ( ( ) => {
0 commit comments