Skip to content

Fix #426 Add loading states #427

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: staging
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 16 additions & 7 deletions app/components/code-graph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -22,6 +22,7 @@ interface Props {
data: GraphData,
setData: Dispatch<SetStateAction<GraphData>>,
onFetchGraph: (graphName: string) => Promise<void>,
isFetchingGraph: boolean,
onFetchNode: (nodeIds: number[]) => Promise<GraphData>,
options: string[]
setOptions: Dispatch<SetStateAction<string[]>>
Expand Down Expand Up @@ -49,9 +50,8 @@ export function CodeGraph({
data,
setData,
onFetchGraph,
isFetchingGraph,
onFetchNode,
options,
setOptions,
isShowPath,
setPath,
chartRef,
Expand Down Expand Up @@ -82,6 +82,7 @@ export function CodeGraph({
const [commitIndex, setCommitIndex] = useState<number>(0);
const [currentCommit, setCurrentCommit] = useState(0);
const containerRef = useRef<HTMLDivElement>(null);
const [options, setOptions] = useState<string[]>([]);

useEffect(() => {
setData({ ...graph.Elements })
Expand Down Expand Up @@ -370,10 +371,18 @@ export function CodeGraph({
</div>
</div>
</div>
: <div className="flex flex-col items-center justify-center h-full text-gray-400">
<GitFork className="md:w-24 md:h-24 w-16 h-16" color="gray" />
<h1 className="md:text-4xl text-2xl text-center">Select a repo to show its graph here</h1>
</div>
: (
isFetchingGraph ?
<div className="flex flex-col items-center justify-center h-full text-gray-400">
<Loader2 className="md:w-24 md:h-24 w-16 h-16 animate-spin" color="gray" />
<h1 className="md:text-4xl text-2xl text-center">Fetching graph...</h1>
</div>
:
<div className="flex flex-col items-center justify-center h-full text-gray-400">
<GitFork className="md:w-24 md:h-24 w-16 h-16" color="gray" />
<h1 className="md:text-4xl text-2xl text-center">Select a repo to show its graph here</h1>
</div>
)
}
</main>
{/* {
Expand Down
67 changes: 44 additions & 23 deletions app/components/combobox.tsx
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -13,55 +14,75 @@ interface Props {
export default function Combobox({ options, setOptions, selectedValue, onSelectedValue }: Props) {

const [open, setOpen] = useState(false)
const [lastOpened, setLastOpened] = useState<number>();
const [lastFetch, setLastFetch] = useState<number>();
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 (
<Select open={open} onOpenChange={setOpen} value={selectedValue} onValueChange={onSelectedValue}>
<Select open={open} onOpenChange={setOpen} disabled={options.length === 0 && !isFetchingOptions} value={isFetchingOptions ? "Fetching options..." : options.length !== 0 ? selectedValue : "No options found"} onValueChange={onSelectedValue}>
<SelectTrigger className="z-10 md:z-0 rounded-md border border-gray-400 md:border-gray-100 focus:ring-0 focus:ring-offset-0">
<SelectValue placeholder="Select a repo" />
</SelectTrigger>
<SelectContent>
{
options.length !== 0 &&
options.map((option) => (
<SelectItem key={option} value={option}>
{option}
isFetchingOptions ?
<SelectItem value="Fetching options...">
<div className="flex flex-row items-center gap-2">
<Loader2 className="w-4 h-4 animate-spin" />
<p>Fetching options...</p>
</div>
</SelectItem>
))
: options.length !== 0 ?
options.map((option) => (
<SelectItem key={option} value={option}>
{option}
</SelectItem>
))
:
<SelectItem value="No options found">
<p>No options found</p>
</SelectItem>
}
</SelectContent>
</Select>
Expand Down
1 change: 0 additions & 1 deletion app/components/graphView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,6 @@ export default function GraphView({
onZoom={() => unsetSelectedObjects()}
onEngineStop={() => {
setCooldownTicks(0)
debugger
handleZoomToFit(chartRef, zoomedNodes.length === 1 ? 4 : 1, (n: NodeObject<Node>) => zoomedNodes.some(node => node.id === n.id))
setZoomedNodes([])
}}
Expand Down
43 changes: 25 additions & 18 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export default function Home() {
const [activeIndex, setActiveIndex] = useState(0)
const [carouselApi, setCarouselApi] = useState<CarouselApi>()
const [zoomedNodes, setZoomedNodes] = useState<Node[]>([])
const [isFetchingGraph, setIsFetchingGraph] = useState(false)

useEffect(() => {
if (path?.start?.id && path?.end?.id) {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -394,6 +399,7 @@ export default function Home() {
options={options}
setOptions={setOptions}
onFetchGraph={onFetchGraph}
isFetchingGraph={isFetchingGraph}
onFetchNode={onFetchNode}
setPath={setPath}
isShowPath={!!path}
Expand Down Expand Up @@ -512,6 +518,7 @@ export default function Home() {
options={options}
setOptions={setOptions}
onFetchGraph={onFetchGraph}
isFetchingGraph={isFetchingGraph}
onFetchNode={onFetchNode}
setPath={setPath}
isShowPath={!!path}
Expand Down
Loading