mirror of
https://github.com/sourcebot-dev/sourcebot.git
synced 2025-12-11 20:05:25 +00:00
chore(web): Change carousel and repository list links to link to file tree (#528)
This commit is contained in:
parent
5073c7db22
commit
e1b6239e2c
4 changed files with 41 additions and 40 deletions
|
|
@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
### Changed
|
### Changed
|
||||||
- Improved repository query performance by adding db indices. [#526](https://github.com/sourcebot-dev/sourcebot/pull/526)
|
- Improved repository query performance by adding db indices. [#526](https://github.com/sourcebot-dev/sourcebot/pull/526)
|
||||||
- Improved repository query performance by removing JOIN on `Connection` table. [#527](https://github.com/sourcebot-dev/sourcebot/pull/527)
|
- Improved repository query performance by removing JOIN on `Connection` table. [#527](https://github.com/sourcebot-dev/sourcebot/pull/527)
|
||||||
|
- Changed repo carousel and repo list links to redirect to the file browser. [#528](https://github.com/sourcebot-dev/sourcebot/pull/528)
|
||||||
|
|
||||||
## [4.7.1] - 2025-09-19
|
## [4.7.1] - 2025-09-19
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,9 @@ import Image from "next/image";
|
||||||
import { FileIcon } from "@radix-ui/react-icons";
|
import { FileIcon } from "@radix-ui/react-icons";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import { RepositoryQuery } from "@/lib/types";
|
import { RepositoryQuery } from "@/lib/types";
|
||||||
|
import { getBrowsePath } from "../../browse/hooks/useBrowseNavigation";
|
||||||
|
import Link from "next/link";
|
||||||
|
import { useDomain } from "@/hooks/useDomain";
|
||||||
|
|
||||||
interface RepositoryCarouselProps {
|
interface RepositoryCarouselProps {
|
||||||
repos: RepositoryQuery[];
|
repos: RepositoryQuery[];
|
||||||
|
|
@ -56,7 +59,8 @@ interface RepositoryBadgeProps {
|
||||||
const RepositoryBadge = ({
|
const RepositoryBadge = ({
|
||||||
repo
|
repo
|
||||||
}: RepositoryBadgeProps) => {
|
}: RepositoryBadgeProps) => {
|
||||||
const { repoIcon, displayName, repoLink } = (() => {
|
const domain = useDomain();
|
||||||
|
const { repoIcon, displayName } = (() => {
|
||||||
const info = getCodeHostInfoForRepo({
|
const info = getCodeHostInfoForRepo({
|
||||||
codeHostType: repo.codeHostType,
|
codeHostType: repo.codeHostType,
|
||||||
name: repo.repoName,
|
name: repo.repoName,
|
||||||
|
|
@ -72,32 +76,30 @@ const RepositoryBadge = ({
|
||||||
className={`w-4 h-4 ${info.iconClassName}`}
|
className={`w-4 h-4 ${info.iconClassName}`}
|
||||||
/>,
|
/>,
|
||||||
displayName: info.displayName,
|
displayName: info.displayName,
|
||||||
repoLink: info.repoLink,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
repoIcon: <FileIcon className="w-4 h-4" />,
|
repoIcon: <FileIcon className="w-4 h-4" />,
|
||||||
displayName: repo.repoName,
|
displayName: repo.repoName,
|
||||||
repoLink: undefined,
|
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<Link
|
||||||
onClick={() => {
|
href={getBrowsePath({
|
||||||
if (repoLink !== undefined) {
|
repoName: repo.repoName,
|
||||||
window.open(repoLink, "_blank");
|
path: '/',
|
||||||
}
|
pathType: 'tree',
|
||||||
}}
|
domain
|
||||||
className={clsx("flex flex-row items-center gap-2 border rounded-md p-2 text-clip", {
|
|
||||||
"cursor-pointer": repoLink !== undefined,
|
|
||||||
})}
|
})}
|
||||||
|
|
||||||
|
className={clsx("flex flex-row items-center gap-2 border rounded-md p-2 text-clip")}
|
||||||
>
|
>
|
||||||
{repoIcon}
|
{repoIcon}
|
||||||
<span className="text-sm font-mono">
|
<span className="text-sm font-mono">
|
||||||
{displayName}
|
{displayName}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</Link>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,20 +2,22 @@
|
||||||
|
|
||||||
import { Button } from "@/components/ui/button"
|
import { Button } from "@/components/ui/button"
|
||||||
import type { ColumnDef } from "@tanstack/react-table"
|
import type { ColumnDef } from "@tanstack/react-table"
|
||||||
import { ArrowUpDown, ExternalLink, Clock, Loader2, CheckCircle2, XCircle, Trash2, Check, ListFilter } from "lucide-react"
|
import { ArrowUpDown, Clock, Loader2, CheckCircle2, XCircle, Trash2, Check, ListFilter } from "lucide-react"
|
||||||
import Image from "next/image"
|
import Image from "next/image"
|
||||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"
|
||||||
import { cn, getRepoImageSrc } from "@/lib/utils"
|
import { cn, getRepoImageSrc } from "@/lib/utils"
|
||||||
import { RepoIndexingStatus } from "@sourcebot/db";
|
import { RepoIndexingStatus } from "@sourcebot/db";
|
||||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"
|
||||||
|
import Link from "next/link"
|
||||||
|
import { getBrowsePath } from "../browse/hooks/useBrowseNavigation"
|
||||||
|
|
||||||
export type RepositoryColumnInfo = {
|
export type RepositoryColumnInfo = {
|
||||||
repoId: number
|
repoId: number
|
||||||
name: string
|
repoName: string;
|
||||||
|
repoDisplayName: string
|
||||||
imageUrl?: string
|
imageUrl?: string
|
||||||
repoIndexingStatus: RepoIndexingStatus
|
repoIndexingStatus: RepoIndexingStatus
|
||||||
lastIndexed: string
|
lastIndexed: string
|
||||||
url: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const statusLabels = {
|
const statusLabels = {
|
||||||
|
|
@ -90,42 +92,38 @@ const StatusIndicator = ({ status }: { status: RepoIndexingStatus }) => {
|
||||||
|
|
||||||
export const columns = (domain: string): ColumnDef<RepositoryColumnInfo>[] => [
|
export const columns = (domain: string): ColumnDef<RepositoryColumnInfo>[] => [
|
||||||
{
|
{
|
||||||
accessorKey: "name",
|
accessorKey: "repoDisplayName",
|
||||||
header: 'Repository',
|
header: 'Repository',
|
||||||
cell: ({ row }) => {
|
cell: ({ row: { original: { repoId, repoName, repoDisplayName, imageUrl } } }) => {
|
||||||
const repo = row.original
|
|
||||||
const url = repo.url
|
|
||||||
const isRemoteRepo = url.length > 0
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-row items-center gap-3 py-2">
|
<div className="flex flex-row items-center gap-3 py-2">
|
||||||
<div className="relative h-8 w-8 overflow-hidden rounded-md border bg-muted">
|
<div className="relative h-8 w-8 overflow-hidden rounded-md border bg-muted">
|
||||||
{repo.imageUrl ? (
|
{imageUrl ? (
|
||||||
<Image
|
<Image
|
||||||
src={getRepoImageSrc(repo.imageUrl, repo.repoId, domain) || "/placeholder.svg"}
|
src={getRepoImageSrc(imageUrl, repoId, domain) || "/placeholder.svg"}
|
||||||
alt={`${repo.name} logo`}
|
alt={`${repoDisplayName} logo`}
|
||||||
width={32}
|
width={32}
|
||||||
height={32}
|
height={32}
|
||||||
className="object-cover"
|
className="object-cover"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex h-full w-full items-center justify-center bg-muted text-xs font-medium uppercase text-muted-foreground">
|
<div className="flex h-full w-full items-center justify-center bg-muted text-xs font-medium uppercase text-muted-foreground">
|
||||||
{repo.name.charAt(0)}
|
{repoDisplayName.charAt(0)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<span
|
<Link
|
||||||
className={isRemoteRepo ? "font-medium text-primary hover:underline cursor-pointer" : "font-medium"}
|
className={"font-medium text-primary hover:underline cursor-pointer"}
|
||||||
onClick={() => {
|
href={getBrowsePath({
|
||||||
if (isRemoteRepo) {
|
repoName: repoName,
|
||||||
window.open(url, "_blank")
|
path: '/',
|
||||||
}
|
pathType: 'tree',
|
||||||
}}
|
domain
|
||||||
|
})}
|
||||||
>
|
>
|
||||||
{repo.name.length > 40 ? `${repo.name.slice(0, 40)}...` : repo.name}
|
{repoDisplayName.length > 40 ? `${repoDisplayName.slice(0, 40)}...` : repoDisplayName}
|
||||||
</span>
|
</Link>
|
||||||
{isRemoteRepo && <ExternalLink className="h-3.5 w-3.5 text-muted-foreground" />}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -37,21 +37,21 @@ export const RepositoryTable = ({
|
||||||
const tableRepos = useMemo(() => {
|
const tableRepos = useMemo(() => {
|
||||||
if (reposLoading) return Array(4).fill(null).map(() => ({
|
if (reposLoading) return Array(4).fill(null).map(() => ({
|
||||||
repoId: 0,
|
repoId: 0,
|
||||||
name: "",
|
repoName: "",
|
||||||
|
repoDisplayName: "",
|
||||||
repoIndexingStatus: RepoIndexingStatus.NEW,
|
repoIndexingStatus: RepoIndexingStatus.NEW,
|
||||||
lastIndexed: "",
|
lastIndexed: "",
|
||||||
url: "",
|
|
||||||
imageUrl: "",
|
imageUrl: "",
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (!repos) return [];
|
if (!repos) return [];
|
||||||
return repos.map((repo): RepositoryColumnInfo => ({
|
return repos.map((repo): RepositoryColumnInfo => ({
|
||||||
repoId: repo.repoId,
|
repoId: repo.repoId,
|
||||||
name: repo.repoDisplayName ?? repo.repoName,
|
repoName: repo.repoName,
|
||||||
|
repoDisplayName: repo.repoDisplayName ?? repo.repoName,
|
||||||
imageUrl: repo.imageUrl,
|
imageUrl: repo.imageUrl,
|
||||||
repoIndexingStatus: repo.repoIndexingStatus as RepoIndexingStatus,
|
repoIndexingStatus: repo.repoIndexingStatus as RepoIndexingStatus,
|
||||||
lastIndexed: repo.indexedAt?.toISOString() ?? "",
|
lastIndexed: repo.indexedAt?.toISOString() ?? "",
|
||||||
url: repo.webUrl ?? repo.repoCloneUrl,
|
|
||||||
})).sort((a, b) => {
|
})).sort((a, b) => {
|
||||||
const getPriorityFromStatus = (status: RepoIndexingStatus) => {
|
const getPriorityFromStatus = (status: RepoIndexingStatus) => {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
|
|
@ -119,7 +119,7 @@ export const RepositoryTable = ({
|
||||||
<DataTable
|
<DataTable
|
||||||
columns={tableColumns}
|
columns={tableColumns}
|
||||||
data={tableRepos}
|
data={tableRepos}
|
||||||
searchKey="name"
|
searchKey="repoDisplayName"
|
||||||
searchPlaceholder="Search repositories..."
|
searchPlaceholder="Search repositories..."
|
||||||
headerActions={isAddReposButtonVisible && (
|
headerActions={isAddReposButtonVisible && (
|
||||||
<Button
|
<Button
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue