Skip to content

Commit 695f432

Browse files
authored
Merge branch 'staging' into dependabot/npm_and_yarn/staging/radix-ui/react-select-2.1.2
2 parents a08ed4d + cacb58d commit 695f432

File tree

18 files changed

+587
-450
lines changed

18 files changed

+587
-450
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { NextRequest, NextResponse } from "next/server";
2+
3+
export async function GET(request: NextRequest, { params }: { params: { graph: string } }) {
4+
5+
try {
6+
const result = await fetch(`${process.env.BEAKEND_URL}/list_commits`, {
7+
method: 'POST',
8+
body: JSON.stringify({ repo: params.graph }),
9+
headers: {
10+
"Authorization": process.env.SECRET_TOKEN!,
11+
"Content-Type": 'application/json'
12+
}
13+
})
14+
15+
if (!result.ok) {
16+
throw new Error(await result.text())
17+
}
18+
19+
const json = await result.json()
20+
21+
return NextResponse.json({ result: json }, { status: 200 })
22+
} catch (err) {
23+
return NextResponse.json({ message: (err as Error).message }, { status: 400 })
24+
}
25+
}
26+
27+
export async function POST(request: NextRequest, { params }: { params: { graph: string } }) {
28+
29+
}

app/api/repo/[graph]/info/route.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { NextRequest, NextResponse } from "next/server";
2+
3+
export async function GET(request: NextRequest, { params }: { params: { graph: string } }) {
4+
5+
try {
6+
const result = await fetch(`${process.env.BACKEND_URL}/repo_info`, {
7+
method: 'POST',
8+
body: JSON.stringify({ repo: params.graph }),
9+
headers: {
10+
"Authorization": process.env.SECRET_TOKEN!,
11+
"Content-Type": 'application/json'
12+
}
13+
})
14+
15+
if (!result.ok) {
16+
throw new Error(await result.text())
17+
}
18+
19+
const json = await result.json()
20+
21+
return NextResponse.json({ result: json }, { status: 200 })
22+
} catch (err) {
23+
return NextResponse.json({ message: (err as Error).message }, { status: 400 })
24+
}
25+
}

app/api/repo/[graph]/neighbors/route.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ import { NextRequest, NextResponse } from "next/server";
22

33
export async function POST(request: NextRequest, { params }: { params: { graph: string } }) {
44

5-
const { nodeIds } = await request.json();
5+
const nodeIds = (await request.json()).nodeIds.map((id: string) => Number(id));
66
const graphId = params.graph;
7+
78
try {
8-
99
const result = await fetch(`${process.env.BACKEND_URL}/get_neighbors`, {
1010
method: 'POST',
1111
body: JSON.stringify({ node_ids: nodeIds, repo: graphId }),

app/api/repo/[graph]/route.ts

Lines changed: 16 additions & 215 deletions
Large diffs are not rendered by default.

app/components/Input.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export default function Input({ value, onValueChange, handelSubmit, graph, icon,
4545
return
4646
}
4747

48-
const result = await fetch(`/api/repo/${graph.Id}/?prefix=${value}&type=autoComplete`, {
48+
const result = await fetch(`/api/repo/${graph.Id}/?prefix=${value}`, {
4949
method: 'POST'
5050
})
5151

@@ -91,15 +91,15 @@ export default function Input({ value, onValueChange, handelSubmit, graph, icon,
9191
case "ArrowUp": {
9292
e.preventDefault()
9393
setSelectedOption(prev => {
94-
containerRef.current?.scrollTo({ behavior: 'smooth', top: (prev <= 0 ? options.length - 1 : prev - 1) * 64 })
94+
containerRef.current?.scrollTo({ behavior: 'smooth', top: (prev <= 0 ? options.length - 1 : prev - 1) * containerRef.current.children[0].clientHeight })
9595
return prev <= 0 ? options.length - 1 : prev - 1
9696
})
9797
return
9898
}
9999
case "ArrowDown": {
100100
e.preventDefault()
101101
setSelectedOption(prev => {
102-
containerRef.current?.scrollTo({ behavior: 'smooth', top: ((prev + 1) % options.length) * 64 })
102+
containerRef.current?.scrollTo({ behavior: 'smooth', top: ((prev + 1) % options.length) * containerRef.current.children[0].clientHeight })
103103
return (prev + 1) % options.length
104104
})
105105
return
@@ -144,6 +144,7 @@ export default function Input({ value, onValueChange, handelSubmit, graph, icon,
144144
<div
145145
ref={containerRef}
146146
className="z-10 w-full bg-white absolute flex flex-col pointer-events-auto border rounded-md max-h-[50dvh] overflow-y-auto overflow-x-hidden p-2 gap-2"
147+
data-name='search-bar-list'
147148
style={{
148149
top: (inputRef.current?.clientHeight || 0) + 16
149150
}}
@@ -162,7 +163,6 @@ export default function Input({ value, onValueChange, handelSubmit, graph, icon,
162163
selectedOption === index && "bg-gray-100"
163164
)}
164165
onMouseEnter={() => setSelectedOption(index)}
165-
onMouseLeave={() => setSelectedOption(-1)}
166166
onClick={() => {
167167
onValueChange({ name: option.properties.name, id: option.id })
168168
handelSubmit && handelSubmit(option)

app/components/chat.tsx

Lines changed: 59 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import { toast } from "@/components/ui/use-toast";
22
import { Dispatch, FormEvent, MutableRefObject, SetStateAction, useEffect, useRef, useState } from "react";
33
import Image from "next/image";
4-
import { AlignLeft, ArrowRight, ChevronDown, Lightbulb, Undo2 } from "lucide-react";
4+
import { AlignLeft, ArrowDown, ArrowRight, ChevronDown, Lightbulb, Undo2 } from "lucide-react";
55
import { Path } from "../page";
66
import Input from "./Input";
77
import { Graph } from "./model";
88
import { cn } from "@/lib/utils";
99
import { LAYOUT } from "./code-graph";
1010
import { TypeAnimation } from "react-type-animation";
11+
import { DropdownMenu, DropdownMenuContent, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
1112

1213
enum MessageTypes {
1314
Query,
@@ -35,6 +36,14 @@ interface Props {
3536
setIsPath: (isPathResponse: boolean) => void
3637
}
3738

39+
const SUGGESTIONS = [
40+
"List a few recursive functions",
41+
"What is the name of the most used method?",
42+
"Who is calling the most used method?",
43+
"Which function has the largest number of arguments? List a few arguments",
44+
"Show a calling path between the drop_edge_range_index function and _query, only return function(s) names",
45+
]
46+
3847
const RemoveLastPath = (messages: Message[]) => {
3948
const index = messages.findIndex((m) => m.type === MessageTypes.Path)
4049

@@ -63,19 +72,13 @@ export function Chat({ repo, path, setPath, graph, chartRef, selectedPathId, isP
6372

6473
const [tipOpen, setTipOpen] = useState(false);
6574

75+
const [sugOpen, setSugOpen] = useState(false);
76+
6677
// A reference to the chat container to allow scrolling to the bottom
6778
const containerRef: React.RefObject<HTMLDivElement> = useRef(null);
6879

69-
const tipRef: React.RefObject<HTMLDivElement> = useRef(null);
70-
7180
const isSendMessage = messages.some(m => m.type === MessageTypes.Pending) || (messages.some(m => m.text === "Please select a starting point and the end point. Select or press relevant item on the graph") && !messages.some(m => m.type === MessageTypes.Path))
7281

73-
useEffect(() => {
74-
if (tipOpen) {
75-
tipRef.current?.focus()
76-
}
77-
}, [tipOpen])
78-
7982
useEffect(() => {
8083
const p = paths.find((path) => [...path.edges, ...path.nodes].some((e: any) => e.id === selectedPathId))
8184

@@ -202,11 +205,13 @@ export function Chat({ repo, path, setPath, graph, chartRef, selectedPathId, isP
202205
}
203206

204207
// Send the user query to the server
205-
async function sendQuery(event: FormEvent) {
208+
async function sendQuery(event?: FormEvent, sugQuery?: string) {
206209

207-
event.preventDefault();
210+
event?.preventDefault();
208211

209-
const q = query.trim()
212+
if (isSendMessage) return
213+
214+
const q = query?.trim() || sugQuery!
210215

211216
if (!q) {
212217
toast({
@@ -436,7 +441,7 @@ export function Chat({ repo, path, setPath, graph, chartRef, selectedPathId, isP
436441
key={i}
437442
className={cn("flex text-wrap border p-2 gap-2 rounded-md", p.nodes.length === selectedPath?.nodes.length && selectedPath?.nodes.every(node => p?.nodes.some((n) => n.id === node.id)) && "border-[#FF66B3] bg-[#FFF0F7]")}
438443
onClick={() => {
439-
if (selectedPath?.nodes.every(node => p?.nodes.some((n) => n.id === node.id))) return
444+
if (p.nodes.length === selectedPath?.nodes.length && selectedPath?.nodes.every(node => p?.nodes.some((n) => n.id === node.id))) return
440445
handelSetSelectedPath(p)
441446
setIsPath(true)
442447
}}
@@ -486,27 +491,52 @@ export function Chat({ repo, path, setPath, graph, chartRef, selectedPathId, isP
486491
}
487492
{
488493
tipOpen &&
489-
<div ref={tipRef} className="bg-white fixed bottom-[85px] border rounded-md flex flex-col gap-3 p-2 overflow-y-auto" onBlur={() => setTipOpen(false)}>
494+
<div ref={ref => ref?.focus()} className="bg-white absolute bottom-0 border rounded-md flex flex-col gap-3 p-2 overflow-y-auto" tabIndex={-1} onMouseDown={(e) => e.preventDefault()} onBlur={() => setTipOpen(false)}>
490495
{getTip()}
491496
</div>
492497
}
493498
</main>
494-
<footer>
495-
{
496-
repo &&
497-
<div className="flex gap-4 px-4">
498-
<button data-name="lightbulb" disabled={isSendMessage} className="p-4 border rounded-md hover:border-[#FF66B3] hover:bg-[#FFF0F7]" onClick={() => setTipOpen(prev => !prev)}>
499-
<Lightbulb />
500-
</button>
501-
<form className="grow flex items-center border rounded-md pr-2" onSubmit={sendQuery}>
502-
<input disabled={isSendMessage} className="grow p-4 rounded-md focus-visible:outline-none" placeholder="Ask your question" onChange={handleQueryInputChange} value={query} />
503-
<button disabled={isSendMessage} className={`bg-gray-200 p-2 rounded-md ${!isSendMessage && 'hover:bg-gray-300'}`}>
504-
<ArrowRight color="white" />
499+
<DropdownMenu open={sugOpen} onOpenChange={setSugOpen}>
500+
<footer>
501+
{
502+
repo &&
503+
<div className="flex gap-4 px-4">
504+
<button data-name="lightbulb" onClick={() => setTipOpen(prev => !prev)} disabled={isSendMessage} className="p-4 border rounded-md hover:border-[#FF66B3] hover:bg-[#FFF0F7]">
505+
<Lightbulb />
505506
</button>
506-
</form>
507-
</div>
508-
}
509-
</footer>
507+
<form className="grow flex items-center border rounded-md px-2" onSubmit={sendQuery}>
508+
<DropdownMenuTrigger asChild>
509+
<button className="bg-gray-200 p-2 rounded-md hover:bg-gray-300">
510+
<ArrowDown color="white" />
511+
</button>
512+
</DropdownMenuTrigger>
513+
<input className="grow p-4 rounded-md focus-visible:outline-none" placeholder="Ask your question" onChange={handleQueryInputChange} value={query} />
514+
<button disabled={isSendMessage} className={`bg-gray-200 p-2 rounded-md ${!isSendMessage && 'hover:bg-gray-300'}`}>
515+
<ArrowRight color="white" />
516+
</button>
517+
</form>
518+
</div>
519+
}
520+
</footer>
521+
<DropdownMenuContent className="flex flex-col mb-4 w-[20dvw]" side="top">
522+
{
523+
SUGGESTIONS.map((s, i) => (
524+
<button
525+
disabled={isSendMessage}
526+
type="submit"
527+
key={i}
528+
className="p-2 text-left hover:bg-gray-200"
529+
onClick={() => {
530+
sendQuery(undefined, s)
531+
setSugOpen(false)
532+
}}
533+
>
534+
{s}
535+
</button>
536+
))
537+
}
538+
</DropdownMenuContent>
539+
</DropdownMenu>
510540
</div>
511541
);
512542
}

0 commit comments

Comments
 (0)