Skip to content

Commit f06ab41

Browse files
Merge branch 'update-repository-detail-view-ahmm'
2 parents c551985 + 9b7306b commit f06ab41

2 files changed

Lines changed: 56 additions & 187 deletions

File tree

frontend/routes/repositories/$repoId.tsx

Lines changed: 44 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,6 @@ function RepositoryDetailView() {
186186
return (
187187
<div className="flex h-full flex-col">
188188
<div className="flex shrink-0 items-center justify-between border-b border-border bg-background px-4 py-2">
189-
<span className="text-sm font-medium">{repository.displayName}</span>
190-
191189
<div className="flex items-center gap-2">
192190
<Button
193191
variant="ghost"
@@ -231,54 +229,17 @@ function RepositoryDetailView() {
231229
<HugeiconsIcon icon={VisualStudioCodeIcon} size={14} strokeWidth={2} data-slot="icon" />
232230
<span className="max-sm:hidden">Editor</span>
233231
</Button>
234-
235-
<AlertDialog>
236-
<AlertDialogTrigger
237-
render={
238-
<Button
239-
variant="ghost"
240-
size="sm"
241-
className="text-muted-foreground hover:text-destructive"
242-
/>
243-
}
244-
>
245-
<HugeiconsIcon icon={Delete02Icon} size={14} strokeWidth={2} data-slot="icon" />
246-
<span className="max-sm:hidden">Delete</span>
247-
</AlertDialogTrigger>
248-
<AlertDialogContent>
249-
<AlertDialogHeader>
250-
<AlertDialogTitle>Delete Repository</AlertDialogTitle>
251-
<AlertDialogDescription>
252-
This will remove "{repository.displayName}" from Vibora. The actual repository
253-
files will not be affected.
254-
</AlertDialogDescription>
255-
</AlertDialogHeader>
256-
<AlertDialogFooter>
257-
<AlertDialogCancel>Cancel</AlertDialogCancel>
258-
<Button variant="destructive" onClick={handleDelete}>
259-
Delete
260-
</Button>
261-
</AlertDialogFooter>
262-
</AlertDialogContent>
263-
</AlertDialog>
264-
265-
<Button
266-
size="sm"
267-
onClick={handleSave}
268-
disabled={!hasChanges || updateRepository.isPending}
269-
>
270-
<HugeiconsIcon icon={Tick02Icon} size={14} strokeWidth={2} data-slot="icon" />
271-
<span className="max-sm:hidden">{updateRepository.isPending ? 'Saving...' : 'Save'}</span>
272-
</Button>
273232
</div>
233+
234+
<span className="text-sm font-medium">{repository.displayName}</span>
274235
</div>
275236

276237
<Tabs
277238
value={activeTab}
278239
onValueChange={(v) => setActiveTab(v as RepoTab)}
279240
className="flex flex-1 flex-col overflow-hidden"
280241
>
281-
<div className="shrink-0 border-b border-border px-4">
242+
<div className="shrink-0 border-b border-border bg-muted/50 px-4">
282243
<TabsList variant="line">
283244
<TabsTrigger value="settings" className="px-3 py-1.5">Settings</TabsTrigger>
284245
<TabsTrigger value="files" className="px-3 py-1.5">Files</TabsTrigger>
@@ -345,6 +306,47 @@ function RepositoryDetailView() {
345306
</FieldDescription>
346307
</Field>
347308
</FieldGroup>
309+
310+
<div className="flex items-center justify-between pt-4 border-t border-border">
311+
<AlertDialog>
312+
<AlertDialogTrigger
313+
render={
314+
<Button
315+
variant="ghost"
316+
size="sm"
317+
className="text-muted-foreground hover:text-destructive"
318+
/>
319+
}
320+
>
321+
<HugeiconsIcon icon={Delete02Icon} size={14} strokeWidth={2} data-slot="icon" />
322+
Delete
323+
</AlertDialogTrigger>
324+
<AlertDialogContent>
325+
<AlertDialogHeader>
326+
<AlertDialogTitle>Delete Repository</AlertDialogTitle>
327+
<AlertDialogDescription>
328+
This will remove "{repository.displayName}" from Vibora. The actual repository
329+
files will not be affected.
330+
</AlertDialogDescription>
331+
</AlertDialogHeader>
332+
<AlertDialogFooter>
333+
<AlertDialogCancel>Cancel</AlertDialogCancel>
334+
<Button variant="destructive" onClick={handleDelete}>
335+
Delete
336+
</Button>
337+
</AlertDialogFooter>
338+
</AlertDialogContent>
339+
</AlertDialog>
340+
341+
<Button
342+
size="sm"
343+
onClick={handleSave}
344+
disabled={!hasChanges || updateRepository.isPending}
345+
>
346+
<HugeiconsIcon icon={Tick02Icon} size={14} strokeWidth={2} data-slot="icon" />
347+
{updateRepository.isPending ? 'Saving...' : 'Save'}
348+
</Button>
349+
</div>
348350
</div>
349351
</div>
350352
</ScrollArea>

frontend/routes/repositories/index.tsx

Lines changed: 12 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,6 @@ import {
88
} from '@/hooks/use-repositories'
99
import { Button } from '@/components/ui/button'
1010
import { Card, CardContent } from '@/components/ui/card'
11-
import { Input } from '@/components/ui/input'
12-
import { Textarea } from '@/components/ui/textarea'
13-
import { Field, FieldGroup, FieldLabel, FieldDescription } from '@/components/ui/field'
14-
import {
15-
Dialog,
16-
DialogContent,
17-
DialogHeader,
18-
DialogTitle,
19-
DialogDescription,
20-
DialogFooter,
21-
DialogClose,
22-
DialogTrigger,
23-
} from '@/components/ui/dialog'
2411
import {
2512
AlertDialog,
2613
AlertDialogCancel,
@@ -50,7 +37,6 @@ import { buildEditorUrl, getEditorDisplayName, openExternalUrl } from '@/lib/edi
5037
import type { Repository } from '@/types'
5138
import { CreateTaskModal } from '@/components/kanban/create-task-modal'
5239
import { NewProjectDialog } from '@/components/repositories/new-project-dialog'
53-
import { Checkbox } from '@/components/ui/checkbox'
5440

5541
export const Route = createFileRoute('/repositories/')({
5642
component: RepositoriesView,
@@ -206,155 +192,36 @@ function RepositoryCard({
206192
)
207193
}
208194

209-
function CreateRepositoryDialog() {
195+
function AddRepositoryButton() {
210196
const { t } = useTranslation('repositories')
211-
const [open, setOpen] = useState(false)
197+
const navigate = useNavigate()
212198
const [browserOpen, setBrowserOpen] = useState(false)
213-
const [path, setPath] = useState('')
214-
const [displayName, setDisplayName] = useState('')
215-
const [startupScript, setStartupScript] = useState('')
216-
const [copyFiles, setCopyFiles] = useState('')
217-
const [isCopierTemplate, setIsCopierTemplate] = useState(false)
218199

219200
const createRepository = useCreateRepository()
220201
const { data: defaultGitReposDir } = useDefaultGitReposDir()
221202

222203
const handlePathSelect = (selectedPath: string) => {
223-
setPath(selectedPath)
224-
// Auto-fill display name from folder name
225-
if (!displayName) {
226-
setDisplayName(selectedPath.split('/').pop() || '')
227-
}
228-
}
229-
230-
const handleSubmit = (e: React.FormEvent) => {
231-
e.preventDefault()
232-
if (!path.trim()) return
204+
const displayName = selectedPath.split('/').pop() || 'repo'
233205

234206
createRepository.mutate(
235207
{
236-
path: path.trim(),
237-
displayName: displayName.trim() || path.split('/').pop() || 'repo',
238-
startupScript: startupScript.trim() || null,
239-
copyFiles: copyFiles.trim() || null,
240-
isCopierTemplate,
208+
path: selectedPath,
209+
displayName,
241210
},
242211
{
243-
onSuccess: () => {
244-
setOpen(false)
245-
setPath('')
246-
setDisplayName('')
247-
setStartupScript('')
248-
setCopyFiles('')
249-
setIsCopierTemplate(false)
212+
onSuccess: (repo) => {
213+
navigate({ to: '/repositories/$repoId', params: { repoId: repo.id } })
250214
},
251215
}
252216
)
253217
}
254218

255-
const folderName = path ? path.split('/').pop() : ''
256-
257219
return (
258220
<>
259-
<Dialog open={open} onOpenChange={setOpen}>
260-
<DialogTrigger render={<Button size="sm" />}>
261-
<HugeiconsIcon icon={PlusSignIcon} size={16} strokeWidth={2} data-slot="icon" />
262-
<span className="max-sm:hidden">{t('addRepository')}</span>
263-
</DialogTrigger>
264-
<DialogContent className="sm:max-w-md">
265-
<form onSubmit={handleSubmit}>
266-
<DialogHeader>
267-
<DialogTitle>{t('addModal.title')}</DialogTitle>
268-
<DialogDescription>
269-
{t('addModal.description')}
270-
</DialogDescription>
271-
</DialogHeader>
272-
273-
<FieldGroup className="mt-4">
274-
<Field>
275-
<FieldLabel>{t('addModal.fields.path')}</FieldLabel>
276-
<Button
277-
type="button"
278-
variant="outline"
279-
className="w-full justify-start font-normal"
280-
onClick={() => setBrowserOpen(true)}
281-
>
282-
<HugeiconsIcon
283-
icon={Folder01Icon}
284-
size={14}
285-
strokeWidth={2}
286-
className="mr-2"
287-
/>
288-
{folderName ? (
289-
<span className="truncate">{path}</span>
290-
) : (
291-
<span className="text-muted-foreground">{t('addModal.fields.pathPlaceholder')}</span>
292-
)}
293-
</Button>
294-
</Field>
295-
296-
<Field>
297-
<FieldLabel htmlFor="displayName">{t('addModal.fields.displayName')}</FieldLabel>
298-
<Input
299-
id="displayName"
300-
value={displayName}
301-
onChange={(e) => setDisplayName(e.target.value)}
302-
placeholder={folderName || 'My Project'}
303-
/>
304-
</Field>
305-
306-
<Field>
307-
<FieldLabel htmlFor="startupScript">{t('addModal.fields.startupScript')}</FieldLabel>
308-
<Textarea
309-
id="startupScript"
310-
value={startupScript}
311-
onChange={(e) => setStartupScript(e.target.value)}
312-
placeholder={t('addModal.fields.startupScriptPlaceholder')}
313-
rows={2}
314-
/>
315-
<FieldDescription>
316-
{t('addModal.fields.startupScriptDescription')}
317-
</FieldDescription>
318-
</Field>
319-
320-
<Field>
321-
<FieldLabel htmlFor="copyFiles">{t('addModal.fields.copyFiles')}</FieldLabel>
322-
<Input
323-
id="copyFiles"
324-
value={copyFiles}
325-
onChange={(e) => setCopyFiles(e.target.value)}
326-
placeholder={t('addModal.fields.copyFilesPlaceholder')}
327-
/>
328-
<FieldDescription>
329-
{t('addModal.fields.copyFilesDescription')}
330-
</FieldDescription>
331-
</Field>
332-
333-
<Field>
334-
<div className="flex items-center gap-2">
335-
<Checkbox
336-
checked={isCopierTemplate}
337-
onCheckedChange={(checked) => setIsCopierTemplate(checked === true)}
338-
/>
339-
<FieldLabel className="cursor-pointer">
340-
{t('addModal.fields.isCopierTemplate')}
341-
</FieldLabel>
342-
</div>
343-
<FieldDescription>
344-
{t('addModal.fields.isCopierTemplateDescription')}
345-
</FieldDescription>
346-
</Field>
347-
</FieldGroup>
348-
349-
<DialogFooter className="mt-4">
350-
<DialogClose render={<Button variant="outline" type="button" />}>{t('addModal.cancel')}</DialogClose>
351-
<Button type="submit" disabled={createRepository.isPending || !path.trim()}>
352-
{createRepository.isPending ? t('addModal.adding') : t('addRepository')}
353-
</Button>
354-
</DialogFooter>
355-
</form>
356-
</DialogContent>
357-
</Dialog>
221+
<Button size="sm" onClick={() => setBrowserOpen(true)} disabled={createRepository.isPending}>
222+
<HugeiconsIcon icon={PlusSignIcon} size={16} strokeWidth={2} data-slot="icon" />
223+
<span className="max-sm:hidden">{t('addRepository')}</span>
224+
</Button>
358225

359226
<FilesystemBrowser
360227
open={browserOpen}
@@ -386,7 +253,7 @@ function RepositoriesView() {
386253
<div className="flex h-full flex-col">
387254
<div className="flex shrink-0 items-center gap-2 border-b border-border bg-background px-4 py-2">
388255
<NewProjectDialog />
389-
<CreateRepositoryDialog />
256+
<AddRepositoryButton />
390257
</div>
391258

392259
<div className="flex-1 overflow-auto p-4">

0 commit comments

Comments
 (0)