Skip to content
Open
Show file tree
Hide file tree
Changes from 6 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
6 changes: 6 additions & 0 deletions app/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ export default function App() {
const [carouselApi, setCarouselApi] = useState<CarouselApi>()
const [zoomedNodes, setZoomedNodes] = useState<Node[]>([])
const [hasHiddenElements, setHasHiddenElements] = useState(false);
const [isFetchingGraph, setIsFetchingGraph] = useState(false)

useEffect(() => {
if (path?.start?.id && path?.end?.id) {
Expand Down Expand Up @@ -153,6 +154,7 @@ export default function App() {
}

async function onFetchGraph(graphName: string) {
setIsFetchingGraph(true)
try {
const result = await fetch(`/api/graph_entities?repo=${prepareArg(graphName)}`, {
method: 'GET',
Expand Down Expand Up @@ -186,6 +188,8 @@ export default function App() {
title: "Uh oh! Something went wrong.",
description: "Failed to load repository graph. Please try again.",
})
} finally {
setIsFetchingGraph(false)
}
}

Expand Down Expand Up @@ -527,6 +531,7 @@ export default function App() {
options={options}
setOptions={setOptions}
onFetchGraph={onFetchGraph}
isFetchingGraph={isFetchingGraph}
onFetchNode={onFetchNode}
setPath={setPath}
isShowPath={!!path}
Expand Down Expand Up @@ -654,6 +659,7 @@ export default function App() {
options={options}
setOptions={setOptions}
onFetchGraph={onFetchGraph}
isFetchingGraph={isFetchingGraph}
onFetchNode={onFetchNode}
setPath={setPath}
isShowPath={!!path}
Expand Down
23 changes: 16 additions & 7 deletions app/src/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 { GitFork, Loader2, Search, X } from "lucide-react";
import { Button } from "@/components/ui/button";
import ElementMenu from "./elementMenu";
import Combobox from "./combobox";
Expand All @@ -28,6 +28,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 @@ -58,9 +59,8 @@ export function CodeGraph({
data,
setData,
onFetchGraph,
isFetchingGraph,
onFetchNode,
options,
setOptions,
isShowPath,
setPath,
canvasRef,
Expand Down Expand Up @@ -93,6 +93,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[]>([]);
Comment thread
Anchel123 marked this conversation as resolved.

useEffect(() => {
setData({ ...graph.Elements })
Expand Down Expand Up @@ -516,10 +517,18 @@ export function CodeGraph({
</div>
</div>
</div>
: <div className="flex flex-col items-center justify-center h-full text-muted-foreground">
<GitFork className="md:w-24 md:h-24 w-16 h-16" />
<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-muted-foreground">
<Loader2 className="md:w-24 md:h-24 w-16 h-16 animate-spin" />
<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-muted-foreground">
<GitFork className="md:w-24 md:h-24 w-16 h-16" />
<h1 className="md:text-4xl text-2xl text-center">Select a repo to show its graph here</h1>
</div>
)
}
</main>
{/* {
Expand Down
73 changes: 47 additions & 26 deletions app/src/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";

const AUTH_HEADERS: HeadersInit = import.meta.env.VITE_SECRET_TOKEN
Expand All @@ -17,58 +18,78 @@ 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/list_repos`, {
method: 'GET',
headers: {
...AUTH_HEADERS,
},
})
setIsFetchingOptions(true)

if (!result.ok) {
toast({
variant: "destructive",
title: "Uh oh! Something went wrong.",
description: await result.text(),
try {
const result = await fetch(`/api/list_repos`, {
method: 'GET',
headers: {
...AUTH_HEADERS,
},
})
return
}

const json = await result.json()
setOptions(json.repositories)
if (!result.ok) {
toast({
variant: "destructive",
title: "Uh oh! Something went wrong.",
description: await result.text(),
})
return
}

const json = await result.json()
setOptions(json.repositories)
} finally {
setIsFetchingOptions(false)
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}

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}>
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
<SelectTrigger className="z-10 md:z-0 rounded-md border border-border focus:ring-1 focus:ring-primary">
<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
Loading