mirror of
https://github.com/sourcebot-dev/sourcebot.git
synced 2025-12-13 21:05:22 +00:00
more cleanup
This commit is contained in:
parent
49578b1074
commit
e5bb570650
6 changed files with 102 additions and 31 deletions
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import { KeyboardShortcutHint } from "@/app/components/keyboardShortcutHint";
|
import { KeyboardShortcutHint } from "@/app/components/keyboardShortcutHint";
|
||||||
import { useDomain } from "@/hooks/useDomain";
|
import { useDomain } from "@/hooks/useDomain";
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
import { Select, SelectContent, SelectItemNoItemText, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||||
import { Separator } from "@/components/ui/separator";
|
import { Separator } from "@/components/ui/separator";
|
||||||
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
|
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
|
|
@ -87,7 +87,7 @@ export const SearchModeSelector = ({
|
||||||
onMouseEnter={() => setFocusedSearchMode("precise")}
|
onMouseEnter={() => setFocusedSearchMode("precise")}
|
||||||
onFocus={() => setFocusedSearchMode("precise")}
|
onFocus={() => setFocusedSearchMode("precise")}
|
||||||
>
|
>
|
||||||
<SelectItem
|
<SelectItemNoItemText
|
||||||
value="precise"
|
value="precise"
|
||||||
className="cursor-pointer"
|
className="cursor-pointer"
|
||||||
>
|
>
|
||||||
|
|
@ -99,7 +99,7 @@ export const SearchModeSelector = ({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</SelectItem>
|
</SelectItemNoItemText>
|
||||||
<TooltipContent
|
<TooltipContent
|
||||||
side="right"
|
side="right"
|
||||||
className="w-64 z-50"
|
className="w-64 z-50"
|
||||||
|
|
@ -126,7 +126,7 @@ export const SearchModeSelector = ({
|
||||||
onMouseEnter={() => setFocusedSearchMode("agentic")}
|
onMouseEnter={() => setFocusedSearchMode("agentic")}
|
||||||
onFocus={() => setFocusedSearchMode("agentic")}
|
onFocus={() => setFocusedSearchMode("agentic")}
|
||||||
>
|
>
|
||||||
<SelectItem
|
<SelectItemNoItemText
|
||||||
value="agentic"
|
value="agentic"
|
||||||
className="cursor-pointer"
|
className="cursor-pointer"
|
||||||
>
|
>
|
||||||
|
|
@ -138,7 +138,7 @@ export const SearchModeSelector = ({
|
||||||
<KeyboardShortcutHint shortcut="⌘ I" />
|
<KeyboardShortcutHint shortcut="⌘ I" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</SelectItem>
|
</SelectItemNoItemText>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
|
|
@ -167,5 +167,3 @@ export const SearchModeSelector = ({
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import { Button } from "@/components/ui/button"
|
||||||
import { Badge } from "@/components/ui/badge"
|
import { Badge } from "@/components/ui/badge"
|
||||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
|
||||||
import { Skeleton } from "@/components/ui/skeleton"
|
import { Skeleton } from "@/components/ui/skeleton"
|
||||||
import { RepoJobsTable } from "../components/repo-jobs-table"
|
import { RepoJobsTable } from "../components/repoJobsTable"
|
||||||
import { SINGLE_TENANT_ORG_DOMAIN } from "@/lib/constants"
|
import { SINGLE_TENANT_ORG_DOMAIN } from "@/lib/constants"
|
||||||
import { sew } from "@/actions"
|
import { sew } from "@/actions"
|
||||||
import { withOptionalAuthV2 } from "@/withAuthV2"
|
import { withOptionalAuthV2 } from "@/withAuthV2"
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,9 @@ import { cva } from "class-variance-authority"
|
||||||
import { AlertCircle, ArrowUpDown } from "lucide-react"
|
import { AlertCircle, ArrowUpDown } from "lucide-react"
|
||||||
import * as React from "react"
|
import * as React from "react"
|
||||||
import { CopyIconButton } from "../../components/copyIconButton"
|
import { CopyIconButton } from "../../components/copyIconButton"
|
||||||
|
import { useMemo } from "react"
|
||||||
|
|
||||||
|
// @see: https://v0.app/chat/repo-indexing-status-uhjdDim8OUS
|
||||||
|
|
||||||
export type RepoIndexingJob = {
|
export type RepoIndexingJob = {
|
||||||
id: string
|
id: string
|
||||||
|
|
@ -189,6 +192,20 @@ export const RepoJobsTable = ({ data }: { data: RepoIndexingJob[] }) => {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const {
|
||||||
|
numCompleted,
|
||||||
|
numInProgress,
|
||||||
|
numPending,
|
||||||
|
numFailed,
|
||||||
|
} = useMemo(() => {
|
||||||
|
return {
|
||||||
|
numCompleted: data.filter((job) => job.status === "COMPLETED").length,
|
||||||
|
numInProgress: data.filter((job) => job.status === "IN_PROGRESS").length,
|
||||||
|
numPending: data.filter((job) => job.status === "PENDING").length,
|
||||||
|
numFailed: data.filter((job) => job.status === "FAILED").length,
|
||||||
|
};
|
||||||
|
}, [data]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<div className="flex items-center gap-4 py-4">
|
<div className="flex items-center gap-4 py-4">
|
||||||
|
|
@ -200,11 +217,11 @@ export const RepoJobsTable = ({ data }: { data: RepoIndexingJob[] }) => {
|
||||||
<SelectValue placeholder="Filter by status" />
|
<SelectValue placeholder="Filter by status" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectItem value="all">All statuses</SelectItem>
|
<SelectItem value="all">Filter by status</SelectItem>
|
||||||
<SelectItem value="PENDING">Pending</SelectItem>
|
<SelectItem value="COMPLETED">Completed ({numCompleted})</SelectItem>
|
||||||
<SelectItem value="IN_PROGRESS">In Progress</SelectItem>
|
<SelectItem value="IN_PROGRESS">In progress ({numInProgress})</SelectItem>
|
||||||
<SelectItem value="COMPLETED">Completed</SelectItem>
|
<SelectItem value="PENDING">Pending ({numPending})</SelectItem>
|
||||||
<SelectItem value="FAILED">Failed</SelectItem>
|
<SelectItem value="FAILED">Failed ({numFailed})</SelectItem>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
|
|
||||||
|
|
@ -14,7 +14,7 @@ import { Input } from "@/components/ui/input"
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
|
||||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
|
||||||
import { SINGLE_TENANT_ORG_DOMAIN } from "@/lib/constants"
|
import { SINGLE_TENANT_ORG_DOMAIN } from "@/lib/constants"
|
||||||
import { getRepoImageSrc } from "@/lib/utils"
|
import { getCodeHostInfoForRepo, getRepoImageSrc } from "@/lib/utils"
|
||||||
import {
|
import {
|
||||||
type ColumnDef,
|
type ColumnDef,
|
||||||
type ColumnFiltersState,
|
type ColumnFiltersState,
|
||||||
|
|
@ -31,7 +31,10 @@ import { cva } from "class-variance-authority"
|
||||||
import { ArrowUpDown, ExternalLink, MoreHorizontal } from "lucide-react"
|
import { ArrowUpDown, ExternalLink, MoreHorizontal } from "lucide-react"
|
||||||
import Image from "next/image"
|
import Image from "next/image"
|
||||||
import Link from "next/link"
|
import Link from "next/link"
|
||||||
import * as React from "react"
|
import { useMemo, useState } from "react"
|
||||||
|
import { getBrowsePath } from "../../browse/hooks/utils"
|
||||||
|
|
||||||
|
// @see: https://v0.app/chat/repo-indexing-status-uhjdDim8OUS
|
||||||
|
|
||||||
export type Repo = {
|
export type Repo = {
|
||||||
id: number
|
id: number
|
||||||
|
|
@ -42,6 +45,7 @@ export type Repo = {
|
||||||
indexedAt: Date | null
|
indexedAt: Date | null
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
webUrl: string | null
|
webUrl: string | null
|
||||||
|
codeHostType: string
|
||||||
imageUrl: string | null
|
imageUrl: string | null
|
||||||
latestJobStatus: "PENDING" | "IN_PROGRESS" | "COMPLETED" | "FAILED" | null
|
latestJobStatus: "PENDING" | "IN_PROGRESS" | "COMPLETED" | "FAILED" | null
|
||||||
}
|
}
|
||||||
|
|
@ -112,7 +116,12 @@ export const columns: ColumnDef<Repo>[] = [
|
||||||
{repo.displayName?.charAt(0) ?? repo.name.charAt(0)}
|
{repo.displayName?.charAt(0) ?? repo.name.charAt(0)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<Link href={`/repos/${repo.id}`} className="font-medium hover:underline">
|
<Link href={getBrowsePath({
|
||||||
|
repoName: repo.name,
|
||||||
|
path: '/',
|
||||||
|
pathType: 'tree',
|
||||||
|
domain: SINGLE_TENANT_ORG_DOMAIN,
|
||||||
|
})} className="font-medium hover:underline">
|
||||||
{repo.displayName || repo.name}
|
{repo.displayName || repo.name}
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -141,6 +150,12 @@ export const columns: ColumnDef<Repo>[] = [
|
||||||
enableHiding: false,
|
enableHiding: false,
|
||||||
cell: ({ row }) => {
|
cell: ({ row }) => {
|
||||||
const repo = row.original
|
const repo = row.original
|
||||||
|
const codeHostInfo = getCodeHostInfoForRepo({
|
||||||
|
codeHostType: repo.codeHostType,
|
||||||
|
name: repo.name,
|
||||||
|
displayName: repo.displayName ?? undefined,
|
||||||
|
webUrl: repo.webUrl ?? undefined,
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
|
|
@ -155,12 +170,12 @@ export const columns: ColumnDef<Repo>[] = [
|
||||||
<DropdownMenuItem asChild>
|
<DropdownMenuItem asChild>
|
||||||
<Link href={`/${SINGLE_TENANT_ORG_DOMAIN}/repos/${repo.id}`}>View details</Link>
|
<Link href={`/${SINGLE_TENANT_ORG_DOMAIN}/repos/${repo.id}`}>View details</Link>
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
{repo.webUrl && (
|
{(repo.webUrl && codeHostInfo) && (
|
||||||
<>
|
<>
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<DropdownMenuItem asChild>
|
<DropdownMenuItem asChild>
|
||||||
<a href={repo.webUrl} target="_blank" rel="noopener noreferrer" className="flex items-center">
|
<a href={repo.webUrl} target="_blank" rel="noopener noreferrer" className="flex items-center">
|
||||||
Open in GitHub
|
Open in {codeHostInfo.codeHostName}
|
||||||
<ExternalLink className="ml-2 h-3 w-3" />
|
<ExternalLink className="ml-2 h-3 w-3" />
|
||||||
</a>
|
</a>
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
|
|
@ -174,10 +189,26 @@ export const columns: ColumnDef<Repo>[] = [
|
||||||
]
|
]
|
||||||
|
|
||||||
export const ReposTable = ({ data }: { data: Repo[] }) => {
|
export const ReposTable = ({ data }: { data: Repo[] }) => {
|
||||||
const [sorting, setSorting] = React.useState<SortingState>([])
|
const [sorting, setSorting] = useState<SortingState>([])
|
||||||
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>([])
|
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([])
|
||||||
const [columnVisibility, setColumnVisibility] = React.useState<VisibilityState>({})
|
const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({})
|
||||||
const [rowSelection, setRowSelection] = React.useState({})
|
const [rowSelection, setRowSelection] = useState({})
|
||||||
|
|
||||||
|
const {
|
||||||
|
numCompleted,
|
||||||
|
numInProgress,
|
||||||
|
numPending,
|
||||||
|
numFailed,
|
||||||
|
numNoJobs,
|
||||||
|
} = useMemo(() => {
|
||||||
|
return {
|
||||||
|
numCompleted: data.filter((repo) => repo.latestJobStatus === "COMPLETED").length,
|
||||||
|
numInProgress: data.filter((repo) => repo.latestJobStatus === "IN_PROGRESS").length,
|
||||||
|
numPending: data.filter((repo) => repo.latestJobStatus === "PENDING").length,
|
||||||
|
numFailed: data.filter((repo) => repo.latestJobStatus === "FAILED").length,
|
||||||
|
numNoJobs: data.filter((repo) => repo.latestJobStatus === null).length,
|
||||||
|
}
|
||||||
|
}, [data]);
|
||||||
|
|
||||||
const table = useReactTable({
|
const table = useReactTable({
|
||||||
data,
|
data,
|
||||||
|
|
@ -217,12 +248,12 @@ export const ReposTable = ({ data }: { data: Repo[] }) => {
|
||||||
<SelectValue placeholder="Filter by status" />
|
<SelectValue placeholder="Filter by status" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectItem value="all">All Statuses</SelectItem>
|
<SelectItem value="all">Filter by status</SelectItem>
|
||||||
<SelectItem value="COMPLETED">Completed</SelectItem>
|
<SelectItem value="COMPLETED">Completed ({numCompleted})</SelectItem>
|
||||||
<SelectItem value="IN_PROGRESS">In Progress</SelectItem>
|
<SelectItem value="IN_PROGRESS">In progress ({numInProgress})</SelectItem>
|
||||||
<SelectItem value="PENDING">Pending</SelectItem>
|
<SelectItem value="PENDING">Pending ({numPending})</SelectItem>
|
||||||
<SelectItem value="FAILED">Failed</SelectItem>
|
<SelectItem value="FAILED">Failed ({numFailed})</SelectItem>
|
||||||
<SelectItem value="null">No Jobs</SelectItem>
|
<SelectItem value="null">No status ({numNoJobs})</SelectItem>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -2,7 +2,7 @@ import { sew } from "@/actions";
|
||||||
import { ServiceErrorException } from "@/lib/serviceError";
|
import { ServiceErrorException } from "@/lib/serviceError";
|
||||||
import { isServiceError } from "@/lib/utils";
|
import { isServiceError } from "@/lib/utils";
|
||||||
import { withOptionalAuthV2 } from "@/withAuthV2";
|
import { withOptionalAuthV2 } from "@/withAuthV2";
|
||||||
import { ReposTable } from "./components/repos-table";
|
import { ReposTable } from "./components/reposTable";
|
||||||
|
|
||||||
export default async function ReposPage() {
|
export default async function ReposPage() {
|
||||||
|
|
||||||
|
|
@ -27,7 +27,8 @@ export default async function ReposPage() {
|
||||||
createdAt: repo.createdAt,
|
createdAt: repo.createdAt,
|
||||||
webUrl: repo.webUrl,
|
webUrl: repo.webUrl,
|
||||||
imageUrl: repo.imageUrl,
|
imageUrl: repo.imageUrl,
|
||||||
latestJobStatus: repo.jobs.length > 0 ? repo.jobs[0].status : null
|
latestJobStatus: repo.jobs.length > 0 ? repo.jobs[0].status : null,
|
||||||
|
codeHostType: repo.external_codeHostType,
|
||||||
}))} />
|
}))} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -129,11 +129,34 @@ const SelectItem = React.forwardRef<
|
||||||
</SelectPrimitive.ItemIndicator>
|
</SelectPrimitive.ItemIndicator>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
{children}
|
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
|
||||||
</SelectPrimitive.Item>
|
</SelectPrimitive.Item>
|
||||||
))
|
))
|
||||||
SelectItem.displayName = SelectPrimitive.Item.displayName
|
SelectItem.displayName = SelectPrimitive.Item.displayName
|
||||||
|
|
||||||
|
const SelectItemNoItemText = React.forwardRef<
|
||||||
|
React.ElementRef<typeof SelectPrimitive.Item>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
|
||||||
|
>(({ className, children, ...props }, ref) => (
|
||||||
|
<SelectPrimitive.Item
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
||||||
|
<SelectPrimitive.ItemIndicator>
|
||||||
|
<Check className="h-4 w-4" />
|
||||||
|
</SelectPrimitive.ItemIndicator>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
{children}
|
||||||
|
</SelectPrimitive.Item>
|
||||||
|
))
|
||||||
|
SelectItemNoItemText.displayName = SelectPrimitive.Item.displayName
|
||||||
|
|
||||||
const SelectSeparator = React.forwardRef<
|
const SelectSeparator = React.forwardRef<
|
||||||
React.ElementRef<typeof SelectPrimitive.Separator>,
|
React.ElementRef<typeof SelectPrimitive.Separator>,
|
||||||
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
|
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
|
||||||
|
|
@ -154,6 +177,7 @@ export {
|
||||||
SelectContent,
|
SelectContent,
|
||||||
SelectLabel,
|
SelectLabel,
|
||||||
SelectItem,
|
SelectItem,
|
||||||
|
SelectItemNoItemText,
|
||||||
SelectSeparator,
|
SelectSeparator,
|
||||||
SelectScrollUpButton,
|
SelectScrollUpButton,
|
||||||
SelectScrollDownButton,
|
SelectScrollDownButton,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue