diff --git a/src/components/SearchInput/index.tsx b/src/components/SearchInput/index.tsx index 6b76c25e4ab..705fc2a3aa6 100644 --- a/src/components/SearchInput/index.tsx +++ b/src/components/SearchInput/index.tsx @@ -4,9 +4,11 @@ import { getHotkeyHandler } from "@mantine/hooks"; import ReactGA from "react-ga4"; import { AiOutlineSearch } from "react-icons/ai"; import { useFocusNode } from "src/hooks/useFocusNode"; +import useGraph from "src/store/useGraph"; export const SearchInput: React.FC = () => { const [searchValue, setValue, skip, nodeCount, currentNode] = useFocusNode(); + const setSearchInputValue = useGraph(state => state.setSearchInputValue); return ( { id="search-node" w={180} value={searchValue} - onChange={e => setValue(e.currentTarget.value)} + onChange={e => { + setValue(e.currentTarget.value); + setSearchInputValue(e.currentTarget.value); + }} onFocus={() => ReactGA.event({ action: "focus_node_search", category: "User" })} placeholder="Search Node" onKeyDown={getHotkeyHandler([["Enter", skip]])} diff --git a/src/containers/Views/GraphView/index.tsx b/src/containers/Views/GraphView/index.tsx index d8771d39b1b..d91930a95e4 100644 --- a/src/containers/Views/GraphView/index.tsx +++ b/src/containers/Views/GraphView/index.tsx @@ -8,6 +8,7 @@ import { ElkRoot } from "reaflow/dist/layout/useLayout"; import { useLongPress } from "use-long-press"; import { CustomNode } from "src/containers/Views/GraphView/CustomNode"; import { ViewMode } from "src/enums/viewMode.enum"; +import { useFocusNode } from "src/hooks/useFocusNode"; import useToggleHide from "src/hooks/useToggleHide"; import { Loading } from "src/layout/Loading"; import useConfig from "src/store/useConfig"; @@ -163,7 +164,8 @@ export const Graph = ({ isWidget = false }: GraphProps) => { const gesturesEnabled = useConfig(state => state.gesturesEnabled); const rulersEnabled = useConfig(state => state.rulersEnabled); const setViewMode = useConfig(state => state.setViewMode); - + const searchInputValue = useGraph(state => state.searchInputValue); + const [, setValue] = useFocusNode(); const callback = React.useCallback(() => { const canvas = document.querySelector(".jsoncrack-canvas") as HTMLDivElement | null; canvas?.classList.add("dragging"); @@ -209,7 +211,10 @@ export const Graph = ({ isWidget = false }: GraphProps) => { {...bindLongPress()} > debouncedOnZoomChangeHandler()} + onUpdated={() => { + setValue(searchInputValue); + debouncedOnZoomChangeHandler(); + }} onCreate={setViewPort} onContextMenu={e => e.preventDefault()} treatTwoFingerTrackPadGesturesLikeTouch={gesturesEnabled} diff --git a/src/hooks/useFocusNode.ts b/src/hooks/useFocusNode.ts index 24b92e3eccb..af79b2044fd 100644 --- a/src/hooks/useFocusNode.ts +++ b/src/hooks/useFocusNode.ts @@ -11,7 +11,8 @@ export const useFocusNode = () => { const [debouncedValue] = useDebouncedValue(value, 600); const skip = () => setSelectedNode(current => (current + 1) % nodeCount); - + const matchedNodes: NodeListOf = searchQuery(`span[data-key*='${debouncedValue}' i]`); + const matchedNode: Element | null = matchedNodes[selectedNode] || null; React.useEffect(() => { if (!value) { cleanupHighlight(); @@ -21,8 +22,6 @@ export const useFocusNode = () => { } if (!viewPort || !debouncedValue) return; - const matchedNodes: NodeListOf = searchQuery(`span[data-key*='${debouncedValue}' i]`); - const matchedNode: Element | null = matchedNodes[selectedNode] || null; cleanupHighlight(); @@ -37,7 +36,7 @@ export const useFocusNode = () => { setSelectedNode(0); setNodeCount(0); } - }, [selectedNode, debouncedValue, value, viewPort]); + }, [selectedNode, debouncedValue, value, viewPort, matchedNodes]); return [value, setValue, skip, nodeCount, selectedNode] as const; }; diff --git a/src/store/useGraph.ts b/src/store/useGraph.ts index 075744f91ac..0c97d8ee8ad 100644 --- a/src/store/useGraph.ts +++ b/src/store/useGraph.ts @@ -21,6 +21,7 @@ export interface Graph { collapsedParents: string[]; selectedNode: NodeData | null; path: string; + searchInputValue: string; } const initialStates: Graph = { @@ -37,6 +38,7 @@ const initialStates: Graph = { collapsedParents: [], selectedNode: null, path: "", + searchInputValue:"", }; interface GraphActions { @@ -59,6 +61,7 @@ interface GraphActions { centerView: () => void; clearGraph: () => void; setZoomFactor: (zoomFactor: number) => void; + setSearchInputValue: (searchInputValue: string) => void; } const useGraph = create((set, get) => ({ @@ -214,6 +217,7 @@ const useGraph = create((set, get) => ({ }, toggleFullscreen: fullscreen => set({ fullscreen }), setViewPort: viewPort => set({ viewPort }), + setSearchInputValue: searchInputValue => set({ searchInputValue }), })); export default useGraph;