@kit-data-manager/react-search-component
Version:
All-in-one component for rendering an elastic search UI for searching anything. Built-in support for visualizing related items in a graph and resolving unique identifiers.
60 lines • 3.26 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { GraphUtils } from "../../components/graph/GraphUtils";
import { Background, BackgroundVariant, Controls, MiniMap, ReactFlow, useEdgesState, useNodesInitialized, useNodesState, useReactFlow, useUpdateNodeInternals } from "@xyflow/react";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import "@xyflow/react/dist/style.css";
import { ResultViewWrapper } from "../../components/graph/ResultViewWrapper";
/**
* Renders an interactive graph for the specified results. Results will be fetched from cache via PID. Currently intended for internal use only.
*/
export function RelationsGraph(props) {
const [colorMode, setColorMode] = useState(props.dark ? "dark" : "light");
useEffect(() => {
const dark = document.querySelector("html")?.classList.contains("dark");
// eslint-disable-next-line react-hooks/set-state-in-effect
if (dark === true)
setColorMode("dark");
else
setColorMode("light");
}, []);
const { initialEdges, initialNodes } = useMemo(() => {
return GraphUtils.buildGraphFromNodes(props.nodes);
}, [props.nodes]);
const nodeTypes = useMemo(() => {
return {
result: (nodeProps) => _jsx(ResultViewWrapper, { ...nodeProps, resultView: props.resultView }),
...props.nodeTypes
};
}, [props.nodeTypes, props.resultView]);
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
const { fitView } = useReactFlow();
const nodesInitialized = useNodesInitialized();
const updateNodeInternals = useUpdateNodeInternals();
useEffect(() => {
setNodes(initialNodes);
setEdges(initialEdges);
}, [initialEdges, initialNodes, setEdges, setNodes]);
const onLayout = useCallback(() => {
const layouted = GraphUtils.computeNodeLayout(nodes, edges);
setNodes([...layouted.nodes]);
setEdges([...layouted.edges]);
window.requestAnimationFrame(() => {
setTimeout(() => {
fitView({ nodes: props.options?.focusedNodes?.map((n) => ({ id: n })), duration: 200, padding: 1 });
updateNodeInternals(nodes.map((n) => n.id));
}, 100);
});
}, [nodes, edges, setNodes, setEdges, fitView, props.options?.focusedNodes, updateNodeInternals]);
const onLayoutDebounced = useRef(onLayout);
useEffect(() => {
onLayoutDebounced.current = onLayout;
}, [onLayout]);
useEffect(() => {
if (nodesInitialized) {
onLayoutDebounced.current();
}
}, [nodesInitialized]);
return (_jsxs(ReactFlow, { nodes: nodes, edges: edges, nodeTypes: nodeTypes, onNodesChange: onNodesChange, onEdgesChange: onEdgesChange, proOptions: { hideAttribution: true }, colorMode: colorMode, nodesDraggable: false, nodesConnectable: false, edgesFocusable: false, children: [_jsx(Background, { color: "hsl(var(--rfs-border))", variant: BackgroundVariant.Lines }), _jsx(Controls, {}), _jsx(MiniMap, { zoomable: true, pannable: true, position: "top-left" })] }));
}
//# sourceMappingURL=RelationsGraph.js.map