Skip to content

Commit ef30258

Browse files
authored
Merge pull request #268 from DevanshuNEU/feat/directory-picker
feat: directory picker UI -- select packages before indexing monorepos (OPE-110)
2 parents 6379d8f + de87311 commit ef30258

9 files changed

Lines changed: 508 additions & 13 deletions

File tree

frontend/bun.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"dependencies": {
1717
"@radix-ui/react-accordion": "^1.2.12",
1818
"@radix-ui/react-avatar": "^1.1.11",
19+
"@radix-ui/react-checkbox": "^1.3.3",
1920
"@radix-ui/react-collapsible": "^1.1.12",
2021
"@radix-ui/react-dialog": "^1.1.15",
2122
"@radix-ui/react-dropdown-menu": "^2.1.16",

frontend/src/components/AddRepoForm.tsx

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import { useState } from 'react'
22
import { motion, AnimatePresence } from 'framer-motion'
3-
import { Package, Plus, X, Loader2 } from 'lucide-react'
3+
import { Package, Plus, X, Loader2, Search } from 'lucide-react'
44
import { Button } from '@/components/ui/button'
55
import { Input } from '@/components/ui/input'
66
import { Label } from '@/components/ui/label'
7+
import { API_URL } from '@/config/api'
8+
import type { AnalyzeResult } from '@/types'
79

810
// Discriminated union: if isOpen is provided, onOpenChange is required
911
type UncontrolledProps = {
@@ -18,21 +20,50 @@ type ControlledProps = {
1820

1921
type AddRepoFormProps = {
2022
onAdd: (gitUrl: string, branch: string) => Promise<void>
23+
onAnalyzed?: (result: AnalyzeResult, gitUrl: string, branch: string) => void
2124
loading: boolean
2225
} & (UncontrolledProps | ControlledProps)
2326

24-
export function AddRepoForm({ onAdd, loading, isOpen, onOpenChange }: AddRepoFormProps) {
27+
export function AddRepoForm({ onAdd, onAnalyzed, loading, isOpen, onOpenChange }: AddRepoFormProps) {
2528
const [gitUrl, setGitUrl] = useState('')
2629
const [branch, setBranch] = useState('main')
30+
const [analyzing, setAnalyzing] = useState(false)
2731
const [internalOpen, setInternalOpen] = useState(false)
2832

2933
const isControlled = isOpen !== undefined
3034
const showForm = isControlled ? isOpen : internalOpen
3135
const setShowForm = isControlled ? onOpenChange : setInternalOpen
36+
const isBusy = loading || analyzing
3237

3338
const handleSubmit = async (e: React.FormEvent) => {
3439
e.preventDefault()
3540
if (!gitUrl) return
41+
42+
// If onAnalyzed provided and URL is GitHub, analyze first
43+
if (onAnalyzed && gitUrl.includes('github.com')) {
44+
try {
45+
setAnalyzing(true)
46+
const resp = await fetch(`${API_URL}/repos/analyze`, {
47+
method: 'POST',
48+
headers: { 'Content-Type': 'application/json' },
49+
body: JSON.stringify({ github_url: gitUrl }),
50+
})
51+
if (resp.ok) {
52+
const result: AnalyzeResult = await resp.json()
53+
if (result.suggestion === 'large_repo') {
54+
onAnalyzed(result, gitUrl, branch)
55+
setShowForm(false)
56+
return
57+
}
58+
}
59+
// Small repo or non-GitHub: proceed directly
60+
} catch {
61+
// Analyze failed -- fall through to direct add
62+
} finally {
63+
setAnalyzing(false)
64+
}
65+
}
66+
3667
await onAdd(gitUrl, branch)
3768
setGitUrl('')
3869
setBranch('main')
@@ -60,7 +91,7 @@ export function AddRepoForm({ onAdd, loading, isOpen, onOpenChange }: AddRepoFor
6091
animate={{ opacity: 1 }}
6192
exit={{ opacity: 0 }}
6293
className="fixed inset-0 bg-background/80 backdrop-blur-md flex items-center justify-center z-50"
63-
onClick={() => !loading && setShowForm(false)}
94+
onClick={() => !isBusy && setShowForm(false)}
6495
>
6596
<motion.div
6697
initial={{ opacity: 0, scale: 0.95, y: 20 }}
@@ -82,8 +113,9 @@ export function AddRepoForm({ onAdd, loading, isOpen, onOpenChange }: AddRepoFor
82113
</div>
83114
<button
84115
onClick={() => setShowForm(false)}
116+
aria-label="Close"
85117
className="w-8 h-8 flex items-center justify-center rounded-lg text-muted-foreground hover:text-foreground hover:bg-muted transition-colors"
86-
disabled={loading}
118+
disabled={isBusy}
87119
>
88120
<X className="w-4 h-4" />
89121
</button>
@@ -100,7 +132,7 @@ export function AddRepoForm({ onAdd, loading, isOpen, onOpenChange }: AddRepoFor
100132
onChange={(e) => setGitUrl(e.target.value)}
101133
placeholder="https://github.com/username/repo"
102134
required
103-
disabled={loading}
135+
disabled={isBusy}
104136
autoFocus
105137
/>
106138
</div>
@@ -114,7 +146,7 @@ export function AddRepoForm({ onAdd, loading, isOpen, onOpenChange }: AddRepoFor
114146
onChange={(e) => setBranch(e.target.value)}
115147
placeholder="main"
116148
required
117-
disabled={loading}
149+
disabled={isBusy}
118150
/>
119151
<p className="text-xs text-muted-foreground">Repository will be cloned and automatically indexed</p>
120152
</div>
@@ -125,17 +157,22 @@ export function AddRepoForm({ onAdd, loading, isOpen, onOpenChange }: AddRepoFor
125157
type="button"
126158
variant="outline"
127159
onClick={() => { setShowForm(false); setGitUrl(''); setBranch('main') }}
128-
disabled={loading}
160+
disabled={isBusy}
129161
className="flex-1"
130162
>
131163
Cancel
132164
</Button>
133165
<Button
134166
type="submit"
135-
disabled={loading}
167+
disabled={isBusy}
136168
className="flex-1 bg-primary hover:bg-primary/90 text-primary-foreground"
137169
>
138-
{loading ? (
170+
{analyzing ? (
171+
<>
172+
<Search className="w-4 h-4 animate-pulse" />
173+
Analyzing...
174+
</>
175+
) : loading ? (
139176
<>
140177
<Loader2 className="w-4 h-4 animate-spin" />
141178
Adding...

0 commit comments

Comments
 (0)