diff --git a/app/components/code-graph.tsx b/app/components/code-graph.tsx index fdf31e5..207ef11 100644 --- a/app/components/code-graph.tsx +++ b/app/components/code-graph.tsx @@ -2,7 +2,7 @@ import { Dispatch, SetStateAction, useEffect, useRef, useState } from "react"; import { Graph, GraphData, Node, Link } from "./model"; import { Toolbar } from "./toolbar"; import { Labels } from "./labels"; -import { Download, GitFork, Search, X } from "lucide-react"; +import { Download, GitFork, Loader2, Search, X } from "lucide-react"; import ElementMenu from "./elementMenu"; import Combobox from "./combobox"; import { toast } from '@/components/ui/use-toast'; @@ -22,6 +22,7 @@ interface Props { data: GraphData, setData: Dispatch>, onFetchGraph: (graphName: string) => Promise, + isFetchingGraph: boolean, onFetchNode: (nodeIds: number[]) => Promise, options: string[] setOptions: Dispatch> @@ -49,9 +50,8 @@ export function CodeGraph({ data, setData, onFetchGraph, + isFetchingGraph, onFetchNode, - options, - setOptions, isShowPath, setPath, chartRef, @@ -82,6 +82,7 @@ export function CodeGraph({ const [commitIndex, setCommitIndex] = useState(0); const [currentCommit, setCurrentCommit] = useState(0); const containerRef = useRef(null); + const [options, setOptions] = useState([]); useEffect(() => { setData({ ...graph.Elements }) @@ -370,10 +371,18 @@ export function CodeGraph({ - :
- -

Select a repo to show its graph here

-
+ : ( + isFetchingGraph ? +
+ +

Fetching graph...

+
+ : +
+ +

Select a repo to show its graph here

+
+ ) } {/* { diff --git a/app/components/combobox.tsx b/app/components/combobox.tsx index c22d933..98eabbb 100644 --- a/app/components/combobox.tsx +++ b/app/components/combobox.tsx @@ -1,5 +1,6 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { toast } from "@/components/ui/use-toast"; +import { Loader2 } from "lucide-react"; import { useEffect, useState } from "react"; interface Props { @@ -13,55 +14,75 @@ interface Props { export default function Combobox({ options, setOptions, selectedValue, onSelectedValue }: Props) { const [open, setOpen] = useState(false) - const [lastOpened, setLastOpened] = useState(); + const [lastFetch, setLastFetch] = useState(); + const [isFetchingOptions, setIsFetchingOptions] = useState(false) const fetchOptions = async () => { - const result = await fetch(`/api/repo`, { - method: 'GET', - }) + setIsFetchingOptions(true) - if (!result.ok) { - toast({ - variant: "destructive", - title: "Uh oh! Something went wrong.", - description: await result.text(), + try { + const result = await fetch(`/api/repo`, { + method: 'GET', }) - return - } - const json = await result.json() - setOptions(json.result) + if (!result.ok) { + toast({ + variant: "destructive", + title: "Uh oh! Something went wrong.", + description: await result.text(), + }) + return + } + + const json = await result.json() + setOptions(json.result) + } finally { + setIsFetchingOptions(false) + } } useEffect(() => { fetchOptions() }, []) + //fetch options when the combobox is opened useEffect(() => { if (!open) return const now = Date.now(); - if (lastOpened && now - lastOpened < 30000) return; - - setLastOpened(now); - + //check if last fetch was less than 30 seconds ago + if (lastFetch && now - lastFetch < 30000) return; + + setLastFetch(now); + fetchOptions() }, [open]) return ( - { - options.length !== 0 && - options.map((option) => ( - - {option} + isFetchingOptions ? + +
+ +

Fetching options...

+
- )) + : options.length !== 0 ? + options.map((option) => ( + + {option} + + )) + : + +

No options found

+
}
diff --git a/app/components/graphView.tsx b/app/components/graphView.tsx index c221e0a..ea9387d 100644 --- a/app/components/graphView.tsx +++ b/app/components/graphView.tsx @@ -352,7 +352,6 @@ export default function GraphView({ onZoom={() => unsetSelectedObjects()} onEngineStop={() => { setCooldownTicks(0) - debugger handleZoomToFit(chartRef, zoomedNodes.length === 1 ? 4 : 1, (n: NodeObject) => zoomedNodes.some(node => node.id === n.id)) setZoomedNodes([]) }} diff --git a/app/page.tsx b/app/page.tsx index c78b490..d434c54 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -82,6 +82,7 @@ export default function Home() { const [activeIndex, setActiveIndex] = useState(0) const [carouselApi, setCarouselApi] = useState() const [zoomedNodes, setZoomedNodes] = useState([]) + const [isFetchingGraph, setIsFetchingGraph] = useState(false) useEffect(() => { if (path?.start?.id && path?.end?.id) { @@ -142,27 +143,31 @@ export default function Home() { async function onFetchGraph(graphName: string) { setGraph(Graph.empty()) + setIsFetchingGraph(true) + try { + const result = await fetch(`/api/repo/${prepareArg(graphName)}`, { + method: 'GET' + }) - const result = await fetch(`/api/repo/${prepareArg(graphName)}`, { - method: 'GET' - }) + if (!result.ok) { + toast({ + variant: "destructive", + title: "Uh oh! Something went wrong.", + description: await result.text(), + }) + return + } - if (!result.ok) { - toast({ - variant: "destructive", - title: "Uh oh! Something went wrong.", - description: await result.text(), - }) - return + const json = await result.json() + const g = Graph.create(json.result.entities, graphName) + setGraph(g) + setIsPathResponse(false) + chatPanel.current?.expand() + // @ts-ignore + window.graph = g + } finally { + setIsFetchingGraph(false) } - - const json = await result.json() - const g = Graph.create(json.result.entities, graphName) - setGraph(g) - setIsPathResponse(false) - chatPanel.current?.expand() - // @ts-ignore - window.graph = g } // Send the user query to the server to expand a node @@ -394,6 +399,7 @@ export default function Home() { options={options} setOptions={setOptions} onFetchGraph={onFetchGraph} + isFetchingGraph={isFetchingGraph} onFetchNode={onFetchNode} setPath={setPath} isShowPath={!!path} @@ -512,6 +518,7 @@ export default function Home() { options={options} setOptions={setOptions} onFetchGraph={onFetchGraph} + isFetchingGraph={isFetchingGraph} onFetchNode={onFetchNode} setPath={setPath} isShowPath={!!path}