Skip to content

Commit cd54eb0

Browse files
more touchups
1 parent 39bcb09 commit cd54eb0

File tree

3 files changed

+114
-20
lines changed

3 files changed

+114
-20
lines changed

packages/web/src/app/[domain]/repos/[id]/page.tsx

Lines changed: 68 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
1-
import { Suspense } from "react"
2-
import { notFound } from "next/navigation"
3-
import Link from "next/link"
4-
import { ChevronLeft, ExternalLink } from "lucide-react"
5-
import { Button } from "@/components/ui/button"
1+
import { sew } from "@/actions"
62
import { Badge } from "@/components/ui/badge"
3+
import { Button } from "@/components/ui/button"
74
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
85
import { Skeleton } from "@/components/ui/skeleton"
9-
import { RepoJobsTable } from "../components/repoJobsTable"
6+
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"
107
import { SINGLE_TENANT_ORG_DOMAIN } from "@/lib/constants"
11-
import { sew } from "@/actions"
12-
import { withOptionalAuthV2 } from "@/withAuthV2"
138
import { ServiceErrorException } from "@/lib/serviceError"
149
import { cn, getCodeHostInfoForRepo, isServiceError } from "@/lib/utils"
10+
import { withOptionalAuthV2 } from "@/withAuthV2"
11+
import { ChevronLeft, ExternalLink, Info } from "lucide-react"
1512
import Image from "next/image"
13+
import Link from "next/link"
14+
import { notFound } from "next/navigation"
15+
import { Suspense } from "react"
16+
import { RepoJobsTable } from "../components/repoJobsTable"
17+
import { getConfigSettings } from "@sourcebot/shared"
18+
import { env } from "@/env.mjs"
1619

1720
function formatDate(date: Date | null) {
1821
if (!date) return "Never"
@@ -39,6 +42,21 @@ export default async function RepoDetailPage({ params }: { params: Promise<{ id:
3942
webUrl: repo.webUrl ?? undefined,
4043
});
4144

45+
const configSettings = await getConfigSettings(env.CONFIG_PATH);
46+
47+
const nextIndexAttempt = (() => {
48+
const latestJob = repo.jobs.length > 0 ? repo.jobs[0] : null;
49+
if (!latestJob) {
50+
return undefined;
51+
}
52+
53+
if (latestJob.completedAt) {
54+
return new Date(latestJob.completedAt.getTime() + configSettings.reindexIntervalMs);
55+
}
56+
57+
return undefined;
58+
})();
59+
4260
return (
4361
<div className="container mx-auto">
4462
<div className="mb-6">
@@ -78,28 +96,58 @@ export default async function RepoDetailPage({ params }: { params: Promise<{ id:
7896
<div className="grid gap-4 md:grid-cols-3 mb-8">
7997
<Card>
8098
<CardHeader className="pb-3">
81-
<CardTitle className="text-sm font-medium">Last Indexed</CardTitle>
99+
<CardTitle className="text-sm font-medium flex items-center gap-1.5">
100+
Created
101+
<Tooltip>
102+
<TooltipTrigger asChild>
103+
<Info className="h-3.5 w-3.5 text-muted-foreground cursor-help" />
104+
</TooltipTrigger>
105+
<TooltipContent>
106+
<p>When this repository was first added to Sourcebot</p>
107+
</TooltipContent>
108+
</Tooltip>
109+
</CardTitle>
82110
</CardHeader>
83111
<CardContent>
84-
<div className="text-2xl font-semibold">{repo.indexedAt ? formatDate(repo.indexedAt) : "Never"}</div>
112+
<div className="text-2xl font-semibold">{formatDate(repo.createdAt)}</div>
85113
</CardContent>
86114
</Card>
87115

88116
<Card>
89117
<CardHeader className="pb-3">
90-
<CardTitle className="text-sm font-medium">Created</CardTitle>
118+
<CardTitle className="text-sm font-medium flex items-center gap-1.5">
119+
Last indexed
120+
<Tooltip>
121+
<TooltipTrigger asChild>
122+
<Info className="h-3.5 w-3.5 text-muted-foreground cursor-help" />
123+
</TooltipTrigger>
124+
<TooltipContent>
125+
<p>The last time this repository was successfully indexed</p>
126+
</TooltipContent>
127+
</Tooltip>
128+
</CardTitle>
91129
</CardHeader>
92130
<CardContent>
93-
<div className="text-2xl font-semibold">{formatDate(repo.createdAt)}</div>
131+
<div className="text-2xl font-semibold">{repo.indexedAt ? formatDate(repo.indexedAt) : "Never"}</div>
94132
</CardContent>
95133
</Card>
96134

97135
<Card>
98136
<CardHeader className="pb-3">
99-
<CardTitle className="text-sm font-medium">Last Updated</CardTitle>
137+
<CardTitle className="text-sm font-medium flex items-center gap-1.5">
138+
Scheduled
139+
<Tooltip>
140+
<TooltipTrigger asChild>
141+
<Info className="h-3.5 w-3.5 text-muted-foreground cursor-help" />
142+
</TooltipTrigger>
143+
<TooltipContent>
144+
<p>When the next indexing job is scheduled to run</p>
145+
</TooltipContent>
146+
</Tooltip>
147+
</CardTitle>
100148
</CardHeader>
101149
<CardContent>
102-
<div className="text-2xl font-semibold">{formatDate(repo.updatedAt)}</div>
150+
<div className="text-2xl font-semibold">{nextIndexAttempt ? formatDate(nextIndexAttempt) : "-"}</div>
103151
</CardContent>
104152
</Card>
105153
</div>
@@ -127,8 +175,12 @@ const getRepoWithJobs = async (repoId: number) => sew(() =>
127175
id: repoId,
128176
},
129177
include: {
130-
jobs: true,
131-
}
178+
jobs: {
179+
orderBy: {
180+
createdAt: 'desc'
181+
},
182+
}
183+
},
132184
});
133185

134186
if (!repo) {

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

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,13 @@ import {
1818
useReactTable,
1919
} from "@tanstack/react-table"
2020
import { cva } from "class-variance-authority"
21-
import { AlertCircle, ArrowUpDown } from "lucide-react"
21+
import { AlertCircle, ArrowUpDown, RefreshCwIcon } from "lucide-react"
2222
import * as React from "react"
2323
import { CopyIconButton } from "../../components/copyIconButton"
2424
import { useMemo } from "react"
25+
import { LightweightCodeHighlighter } from "../../components/lightweightCodeHighlighter"
26+
import { useRouter } from "next/navigation"
27+
import { useToast } from "@/components/hooks/use-toast"
2528

2629
// @see: https://v0.app/chat/repo-indexing-status-uhjdDim8OUS
2730

@@ -107,8 +110,14 @@ export const columns: ColumnDef<RepoIndexingJob>[] = [
107110
<TooltipTrigger>
108111
<AlertCircle className="h-4 w-4 text-destructive" />
109112
</TooltipTrigger>
110-
<TooltipContent className="max-w-sm">
111-
<p className="text-sm">{job.errorMessage}</p>
113+
<TooltipContent className="max-w-[750px] max-h-96 overflow-scroll">
114+
<LightweightCodeHighlighter
115+
language="text"
116+
lineNumbers={true}
117+
renderWhitespace={false}
118+
>
119+
{job.errorMessage}
120+
</LightweightCodeHighlighter>
112121
</TooltipContent>
113122
</Tooltip>
114123
</TooltipProvider>
@@ -174,6 +183,8 @@ export const RepoJobsTable = ({ data }: { data: RepoIndexingJob[] }) => {
174183
const [sorting, setSorting] = React.useState<SortingState>([{ id: "createdAt", desc: true }])
175184
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>([])
176185
const [columnVisibility, setColumnVisibility] = React.useState<VisibilityState>({})
186+
const router = useRouter();
187+
const { toast } = useToast();
177188

178189
const table = useReactTable({
179190
data,
@@ -238,6 +249,20 @@ export const RepoJobsTable = ({ data }: { data: RepoIndexingJob[] }) => {
238249
<SelectItem value="CLEANUP">Cleanup</SelectItem>
239250
</SelectContent>
240251
</Select>
252+
253+
<Button
254+
variant="outline"
255+
className="ml-auto"
256+
onClick={() => {
257+
router.refresh();
258+
toast({
259+
description: "Page refreshed",
260+
});
261+
}}
262+
>
263+
<RefreshCwIcon className="w-3 h-3" />
264+
Refresh
265+
</Button>
241266
</div>
242267

243268
<div className="rounded-md border">

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

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,13 @@ import {
2828
useReactTable,
2929
} from "@tanstack/react-table"
3030
import { cva } from "class-variance-authority"
31-
import { ArrowUpDown, ExternalLink, MoreHorizontal } from "lucide-react"
31+
import { ArrowUpDown, ExternalLink, MoreHorizontal, RefreshCwIcon } from "lucide-react"
3232
import Image from "next/image"
3333
import Link from "next/link"
3434
import { useMemo, useState } from "react"
3535
import { getBrowsePath } from "../../browse/hooks/utils"
36+
import { useRouter } from "next/navigation"
37+
import { useToast } from "@/components/hooks/use-toast";
3638

3739
// @see: https://v0.app/chat/repo-indexing-status-uhjdDim8OUS
3840

@@ -193,6 +195,8 @@ export const ReposTable = ({ data }: { data: Repo[] }) => {
193195
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([])
194196
const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({})
195197
const [rowSelection, setRowSelection] = useState({})
198+
const router = useRouter();
199+
const { toast } = useToast();
196200

197201
const {
198202
numCompleted,
@@ -256,6 +260,19 @@ export const ReposTable = ({ data }: { data: Repo[] }) => {
256260
<SelectItem value="null">No status ({numNoJobs})</SelectItem>
257261
</SelectContent>
258262
</Select>
263+
<Button
264+
variant="outline"
265+
className="ml-auto"
266+
onClick={() => {
267+
router.refresh();
268+
toast({
269+
description: "Page refreshed",
270+
});
271+
}}
272+
>
273+
<RefreshCwIcon className="w-3 h-3" />
274+
Refresh
275+
</Button>
259276
</div>
260277
<div className="rounded-md border">
261278
<Table>

0 commit comments

Comments
 (0)