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})
+