Skip to content

Commit 41bc076

Browse files
committed
feat(web): moved trigger sync dropdown menu item outside of repo.webUrl block
- Moved the whole repo actions dropdown to its own component (repoActionsDropdown.tsx)
1 parent 51f0b3e commit 41bc076

File tree

2 files changed

+88
-51
lines changed

2 files changed

+88
-51
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
"use client"
2+
3+
import { Button } from "@/components/ui/button"
4+
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger,
5+
} from "@/components/ui/dropdown-menu"
6+
import { SINGLE_TENANT_ORG_DOMAIN } from "@/lib/constants"
7+
import { getCodeHostInfoForRepo, isServiceError } from "@/lib/utils"
8+
import { ExternalLink, MoreHorizontal } from "lucide-react"
9+
import Link from "next/link"
10+
import { useState } from "react"
11+
import { indexRepo } from "@/features/workerApi/actions"
12+
import { useRouter } from "next/navigation"
13+
import { useToast } from "@/components/hooks/use-toast"
14+
import type { Repo } from "./reposTable"
15+
16+
interface RepoActionsDropdownProps {
17+
repo: Repo
18+
}
19+
20+
export const RepoActionsDropdown = ({ repo }: RepoActionsDropdownProps) => {
21+
const [isSyncing, setIsSyncing] = useState(false)
22+
const router = useRouter()
23+
const { toast } = useToast()
24+
25+
const codeHostInfo = getCodeHostInfoForRepo({
26+
codeHostType: repo.codeHostType,
27+
name: repo.name,
28+
displayName: repo.displayName ?? undefined,
29+
webUrl: repo.webUrl ?? undefined,
30+
})
31+
32+
const handleTriggerSync = async () => {
33+
setIsSyncing(true)
34+
const response = await indexRepo(repo.id)
35+
36+
if (!isServiceError(response)) {
37+
const { jobId } = response
38+
toast({
39+
description: `✅ Repository sync triggered successfully. Job ID: ${jobId}`,
40+
})
41+
router.refresh()
42+
} else {
43+
toast({
44+
description: `❌ Failed to sync repository. ${response.message}`,
45+
})
46+
}
47+
48+
setIsSyncing(false)
49+
}
50+
51+
return (
52+
<DropdownMenu>
53+
<DropdownMenuTrigger asChild>
54+
<Button variant="ghost" className="h-8 w-8 p-0">
55+
<span className="sr-only">Open menu</span>
56+
<MoreHorizontal className="h-4 w-4" />
57+
</Button>
58+
</DropdownMenuTrigger>
59+
<DropdownMenuContent align="end">
60+
<DropdownMenuLabel>Actions</DropdownMenuLabel>
61+
<DropdownMenuItem asChild>
62+
<Link href={`/${SINGLE_TENANT_ORG_DOMAIN}/repos/${repo.id}`}>View details</Link>
63+
</DropdownMenuItem>
64+
<DropdownMenuItem
65+
onClick={handleTriggerSync}
66+
disabled={isSyncing}
67+
>
68+
Trigger sync
69+
</DropdownMenuItem>
70+
{repo.webUrl && (
71+
<>
72+
<DropdownMenuSeparator />
73+
<DropdownMenuItem asChild>
74+
<a href={repo.webUrl} target="_blank" rel="noopener noreferrer" className="flex items-center">
75+
Open in {codeHostInfo.codeHostName}
76+
<ExternalLink className="ml-2 h-3 w-3" />
77+
</a>
78+
</DropdownMenuItem>
79+
</>
80+
)}
81+
</DropdownMenuContent>
82+
</DropdownMenu>
83+
)
84+
}

packages/web/src/app/[domain]/repos/components/reposTable.tsx

Lines changed: 4 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,11 @@
22

33
import { Badge } from "@/components/ui/badge"
44
import { Button } from "@/components/ui/button"
5-
import {
6-
DropdownMenu,
7-
DropdownMenuContent,
8-
DropdownMenuItem,
9-
DropdownMenuLabel,
10-
DropdownMenuSeparator,
11-
DropdownMenuTrigger,
12-
} from "@/components/ui/dropdown-menu"
135
import { InputGroup, InputGroupAddon, InputGroupInput } from "@/components/ui/input-group"
146
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
157
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
168
import { SINGLE_TENANT_ORG_DOMAIN } from "@/lib/constants"
17-
import { cn, getCodeHostCommitUrl, getCodeHostIcon, getCodeHostInfoForRepo, getRepoImageSrc, isServiceError } from "@/lib/utils"
9+
import { cn, getCodeHostCommitUrl, getCodeHostIcon, getRepoImageSrc, isServiceError } from "@/lib/utils"
1810
import {
1911
type ColumnDef,
2012
type VisibilityState,
@@ -23,7 +15,7 @@ import {
2315
useReactTable,
2416
} from "@tanstack/react-table"
2517
import { cva } from "class-variance-authority"
26-
import { ArrowDown, ArrowUp, ArrowUpDown, ExternalLink, Loader2, MoreHorizontal, RefreshCwIcon } from "lucide-react"
18+
import { ArrowDown, ArrowUp, ArrowUpDown, Loader2, RefreshCwIcon } from "lucide-react"
2719
import Image from "next/image"
2820
import Link from "next/link"
2921
import { useEffect, useRef, useState } from "react"
@@ -36,6 +28,7 @@ import { NotificationDot } from "../../components/notificationDot"
3628
import { CodeHostType } from "@sourcebot/db"
3729
import { useHotkeys } from "react-hotkeys-hook"
3830
import { indexRepo } from "@/features/workerApi/actions"
31+
import { RepoActionsDropdown } from "./repoActionsDropdown"
3932

4033
// @see: https://v0.app/chat/repo-indexing-status-uhjdDim8OUS
4134

@@ -256,47 +249,7 @@ export const getColumns = (context: ColumnsContext): ColumnDef<Repo>[] => [
256249
enableHiding: false,
257250
cell: ({ row }) => {
258251
const repo = row.original
259-
const codeHostInfo = getCodeHostInfoForRepo({
260-
codeHostType: repo.codeHostType,
261-
name: repo.name,
262-
displayName: repo.displayName ?? undefined,
263-
webUrl: repo.webUrl ?? undefined,
264-
});
265-
const isSyncing = context.syncingRepoId === repo.id;
266-
267-
return (
268-
<DropdownMenu>
269-
<DropdownMenuTrigger asChild>
270-
<Button variant="ghost" className="h-8 w-8 p-0">
271-
<span className="sr-only">Open menu</span>
272-
<MoreHorizontal className="h-4 w-4" />
273-
</Button>
274-
</DropdownMenuTrigger>
275-
<DropdownMenuContent align="end">
276-
<DropdownMenuLabel>Actions</DropdownMenuLabel>
277-
<DropdownMenuItem asChild>
278-
<Link href={`/${SINGLE_TENANT_ORG_DOMAIN}/repos/${repo.id}`}>View details</Link>
279-
</DropdownMenuItem>
280-
{repo.webUrl && (
281-
<>
282-
<DropdownMenuSeparator />
283-
<DropdownMenuItem
284-
onClick={() => context.onTriggerSync(repo.id)}
285-
disabled={isSyncing}
286-
>
287-
Trigger Sync
288-
</DropdownMenuItem>
289-
<DropdownMenuItem asChild>
290-
<a href={repo.webUrl} target="_blank" rel="noopener noreferrer" className="flex items-center">
291-
Open in {codeHostInfo.codeHostName}
292-
<ExternalLink className="ml-2 h-3 w-3" />
293-
</a>
294-
</DropdownMenuItem>
295-
</>
296-
)}
297-
</DropdownMenuContent>
298-
</DropdownMenu>
299-
)
252+
return <RepoActionsDropdown repo={repo} />
300253
},
301254
},
302255
]

0 commit comments

Comments
 (0)