mirror of
https://github.com/sourcebot-dev/sourcebot.git
synced 2025-12-12 04:15:30 +00:00
more touchups
This commit is contained in:
parent
39bcb09778
commit
cd54eb0b7b
3 changed files with 120 additions and 26 deletions
|
|
@ -1,18 +1,21 @@
|
|||
import { Suspense } from "react"
|
||||
import { notFound } from "next/navigation"
|
||||
import Link from "next/link"
|
||||
import { ChevronLeft, ExternalLink } from "lucide-react"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { sew } from "@/actions"
|
||||
import { Badge } from "@/components/ui/badge"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
|
||||
import { Skeleton } from "@/components/ui/skeleton"
|
||||
import { RepoJobsTable } from "../components/repoJobsTable"
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"
|
||||
import { SINGLE_TENANT_ORG_DOMAIN } from "@/lib/constants"
|
||||
import { sew } from "@/actions"
|
||||
import { withOptionalAuthV2 } from "@/withAuthV2"
|
||||
import { ServiceErrorException } from "@/lib/serviceError"
|
||||
import { cn, getCodeHostInfoForRepo, isServiceError } from "@/lib/utils"
|
||||
import { withOptionalAuthV2 } from "@/withAuthV2"
|
||||
import { ChevronLeft, ExternalLink, Info } from "lucide-react"
|
||||
import Image from "next/image"
|
||||
import Link from "next/link"
|
||||
import { notFound } from "next/navigation"
|
||||
import { Suspense } from "react"
|
||||
import { RepoJobsTable } from "../components/repoJobsTable"
|
||||
import { getConfigSettings } from "@sourcebot/shared"
|
||||
import { env } from "@/env.mjs"
|
||||
|
||||
function formatDate(date: Date | null) {
|
||||
if (!date) return "Never"
|
||||
|
|
@ -39,6 +42,21 @@ export default async function RepoDetailPage({ params }: { params: Promise<{ id:
|
|||
webUrl: repo.webUrl ?? undefined,
|
||||
});
|
||||
|
||||
const configSettings = await getConfigSettings(env.CONFIG_PATH);
|
||||
|
||||
const nextIndexAttempt = (() => {
|
||||
const latestJob = repo.jobs.length > 0 ? repo.jobs[0] : null;
|
||||
if (!latestJob) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (latestJob.completedAt) {
|
||||
return new Date(latestJob.completedAt.getTime() + configSettings.reindexIntervalMs);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
})();
|
||||
|
||||
return (
|
||||
<div className="container mx-auto">
|
||||
<div className="mb-6">
|
||||
|
|
@ -78,16 +96,17 @@ export default async function RepoDetailPage({ params }: { params: Promise<{ id:
|
|||
<div className="grid gap-4 md:grid-cols-3 mb-8">
|
||||
<Card>
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-sm font-medium">Last Indexed</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-semibold">{repo.indexedAt ? formatDate(repo.indexedAt) : "Never"}</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-sm font-medium">Created</CardTitle>
|
||||
<CardTitle className="text-sm font-medium flex items-center gap-1.5">
|
||||
Created
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Info className="h-3.5 w-3.5 text-muted-foreground cursor-help" />
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>When this repository was first added to Sourcebot</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-semibold">{formatDate(repo.createdAt)}</div>
|
||||
|
|
@ -96,10 +115,39 @@ export default async function RepoDetailPage({ params }: { params: Promise<{ id:
|
|||
|
||||
<Card>
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-sm font-medium">Last Updated</CardTitle>
|
||||
<CardTitle className="text-sm font-medium flex items-center gap-1.5">
|
||||
Last indexed
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Info className="h-3.5 w-3.5 text-muted-foreground cursor-help" />
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>The last time this repository was successfully indexed</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-semibold">{formatDate(repo.updatedAt)}</div>
|
||||
<div className="text-2xl font-semibold">{repo.indexedAt ? formatDate(repo.indexedAt) : "Never"}</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-sm font-medium flex items-center gap-1.5">
|
||||
Scheduled
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Info className="h-3.5 w-3.5 text-muted-foreground cursor-help" />
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>When the next indexing job is scheduled to run</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-semibold">{nextIndexAttempt ? formatDate(nextIndexAttempt) : "-"}</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
|
@ -127,8 +175,12 @@ const getRepoWithJobs = async (repoId: number) => sew(() =>
|
|||
id: repoId,
|
||||
},
|
||||
include: {
|
||||
jobs: true,
|
||||
}
|
||||
jobs: {
|
||||
orderBy: {
|
||||
createdAt: 'desc'
|
||||
},
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
if (!repo) {
|
||||
|
|
|
|||
|
|
@ -18,10 +18,13 @@ import {
|
|||
useReactTable,
|
||||
} from "@tanstack/react-table"
|
||||
import { cva } from "class-variance-authority"
|
||||
import { AlertCircle, ArrowUpDown } from "lucide-react"
|
||||
import { AlertCircle, ArrowUpDown, RefreshCwIcon } from "lucide-react"
|
||||
import * as React from "react"
|
||||
import { CopyIconButton } from "../../components/copyIconButton"
|
||||
import { useMemo } from "react"
|
||||
import { LightweightCodeHighlighter } from "../../components/lightweightCodeHighlighter"
|
||||
import { useRouter } from "next/navigation"
|
||||
import { useToast } from "@/components/hooks/use-toast"
|
||||
|
||||
// @see: https://v0.app/chat/repo-indexing-status-uhjdDim8OUS
|
||||
|
||||
|
|
@ -107,8 +110,14 @@ export const columns: ColumnDef<RepoIndexingJob>[] = [
|
|||
<TooltipTrigger>
|
||||
<AlertCircle className="h-4 w-4 text-destructive" />
|
||||
</TooltipTrigger>
|
||||
<TooltipContent className="max-w-sm">
|
||||
<p className="text-sm">{job.errorMessage}</p>
|
||||
<TooltipContent className="max-w-[750px] max-h-96 overflow-scroll">
|
||||
<LightweightCodeHighlighter
|
||||
language="text"
|
||||
lineNumbers={true}
|
||||
renderWhitespace={false}
|
||||
>
|
||||
{job.errorMessage}
|
||||
</LightweightCodeHighlighter>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
|
|
@ -174,6 +183,8 @@ export const RepoJobsTable = ({ data }: { data: RepoIndexingJob[] }) => {
|
|||
const [sorting, setSorting] = React.useState<SortingState>([{ id: "createdAt", desc: true }])
|
||||
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>([])
|
||||
const [columnVisibility, setColumnVisibility] = React.useState<VisibilityState>({})
|
||||
const router = useRouter();
|
||||
const { toast } = useToast();
|
||||
|
||||
const table = useReactTable({
|
||||
data,
|
||||
|
|
@ -238,6 +249,20 @@ export const RepoJobsTable = ({ data }: { data: RepoIndexingJob[] }) => {
|
|||
<SelectItem value="CLEANUP">Cleanup</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
<Button
|
||||
variant="outline"
|
||||
className="ml-auto"
|
||||
onClick={() => {
|
||||
router.refresh();
|
||||
toast({
|
||||
description: "Page refreshed",
|
||||
});
|
||||
}}
|
||||
>
|
||||
<RefreshCwIcon className="w-3 h-3" />
|
||||
Refresh
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="rounded-md border">
|
||||
|
|
|
|||
|
|
@ -28,11 +28,13 @@ import {
|
|||
useReactTable,
|
||||
} from "@tanstack/react-table"
|
||||
import { cva } from "class-variance-authority"
|
||||
import { ArrowUpDown, ExternalLink, MoreHorizontal } from "lucide-react"
|
||||
import { ArrowUpDown, ExternalLink, MoreHorizontal, RefreshCwIcon } from "lucide-react"
|
||||
import Image from "next/image"
|
||||
import Link from "next/link"
|
||||
import { useMemo, useState } from "react"
|
||||
import { getBrowsePath } from "../../browse/hooks/utils"
|
||||
import { useRouter } from "next/navigation"
|
||||
import { useToast } from "@/components/hooks/use-toast";
|
||||
|
||||
// @see: https://v0.app/chat/repo-indexing-status-uhjdDim8OUS
|
||||
|
||||
|
|
@ -193,6 +195,8 @@ export const ReposTable = ({ data }: { data: Repo[] }) => {
|
|||
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([])
|
||||
const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({})
|
||||
const [rowSelection, setRowSelection] = useState({})
|
||||
const router = useRouter();
|
||||
const { toast } = useToast();
|
||||
|
||||
const {
|
||||
numCompleted,
|
||||
|
|
@ -256,6 +260,19 @@ export const ReposTable = ({ data }: { data: Repo[] }) => {
|
|||
<SelectItem value="null">No status ({numNoJobs})</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<Button
|
||||
variant="outline"
|
||||
className="ml-auto"
|
||||
onClick={() => {
|
||||
router.refresh();
|
||||
toast({
|
||||
description: "Page refreshed",
|
||||
});
|
||||
}}
|
||||
>
|
||||
<RefreshCwIcon className="w-3 h-3" />
|
||||
Refresh
|
||||
</Button>
|
||||
</div>
|
||||
<div className="rounded-md border">
|
||||
<Table>
|
||||
|
|
|
|||
Loading…
Reference in a new issue