From cd54eb0b7b6e6bb5e1276968d72b4aa2af349726 Mon Sep 17 00:00:00 2001 From: bkellam Date: Thu, 23 Oct 2025 15:49:58 -0700 Subject: [PATCH] more touchups --- .../web/src/app/[domain]/repos/[id]/page.tsx | 96 ++++++++++++++----- .../repos/components/repoJobsTable.tsx | 31 +++++- .../[domain]/repos/components/reposTable.tsx | 19 +++- 3 files changed, 120 insertions(+), 26 deletions(-) diff --git a/packages/web/src/app/[domain]/repos/[id]/page.tsx b/packages/web/src/app/[domain]/repos/[id]/page.tsx index eeab308c..e6b8dced 100644 --- a/packages/web/src/app/[domain]/repos/[id]/page.tsx +++ b/packages/web/src/app/[domain]/repos/[id]/page.tsx @@ -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 (
@@ -78,16 +96,17 @@ export default async function RepoDetailPage({ params }: { params: Promise<{ id:
- Last Indexed - - -
{repo.indexedAt ? formatDate(repo.indexedAt) : "Never"}
-
-
- - - - Created + + Created + + + + + +

When this repository was first added to Sourcebot

+
+
+
{formatDate(repo.createdAt)}
@@ -96,10 +115,39 @@ export default async function RepoDetailPage({ params }: { params: Promise<{ id: - Last Updated + + Last indexed + + + + + +

The last time this repository was successfully indexed

+
+
+
-
{formatDate(repo.updatedAt)}
+
{repo.indexedAt ? formatDate(repo.indexedAt) : "Never"}
+
+
+ + + + + Scheduled + + + + + +

When the next indexing job is scheduled to run

+
+
+
+
+ +
{nextIndexAttempt ? formatDate(nextIndexAttempt) : "-"}
@@ -127,8 +175,12 @@ const getRepoWithJobs = async (repoId: number) => sew(() => id: repoId, }, include: { - jobs: true, - } + jobs: { + orderBy: { + createdAt: 'desc' + }, + } + }, }); if (!repo) { diff --git a/packages/web/src/app/[domain]/repos/components/repoJobsTable.tsx b/packages/web/src/app/[domain]/repos/components/repoJobsTable.tsx index ef14d6dd..a1bc23d6 100644 --- a/packages/web/src/app/[domain]/repos/components/repoJobsTable.tsx +++ b/packages/web/src/app/[domain]/repos/components/repoJobsTable.tsx @@ -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[] = [ - -

{job.errorMessage}

+ + + {job.errorMessage} + @@ -174,6 +183,8 @@ export const RepoJobsTable = ({ data }: { data: RepoIndexingJob[] }) => { const [sorting, setSorting] = React.useState([{ id: "createdAt", desc: true }]) const [columnFilters, setColumnFilters] = React.useState([]) const [columnVisibility, setColumnVisibility] = React.useState({}) + const router = useRouter(); + const { toast } = useToast(); const table = useReactTable({ data, @@ -238,6 +249,20 @@ export const RepoJobsTable = ({ data }: { data: RepoIndexingJob[] }) => { Cleanup + +
diff --git a/packages/web/src/app/[domain]/repos/components/reposTable.tsx b/packages/web/src/app/[domain]/repos/components/reposTable.tsx index b48bb39c..2731eae2 100644 --- a/packages/web/src/app/[domain]/repos/components/reposTable.tsx +++ b/packages/web/src/app/[domain]/repos/components/reposTable.tsx @@ -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([]) const [columnVisibility, setColumnVisibility] = useState({}) const [rowSelection, setRowSelection] = useState({}) + const router = useRouter(); + const { toast } = useToast(); const { numCompleted, @@ -256,6 +260,19 @@ export const ReposTable = ({ data }: { data: Repo[] }) => { No status ({numNoJobs}) +