Add page to list indexed repositories

This commit is contained in:
bkellam 2024-09-10 21:55:00 -07:00
parent c1227000da
commit 1283f6487f
14 changed files with 781 additions and 27 deletions

View file

@ -18,11 +18,13 @@
"@radix-ui/react-dropdown-menu": "^2.1.1",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-label": "^2.1.0",
"@radix-ui/react-navigation-menu": "^1.2.0",
"@radix-ui/react-scroll-area": "^1.1.0",
"@radix-ui/react-separator": "^1.1.0",
"@radix-ui/react-slot": "^1.1.0",
"@replit/codemirror-vim": "^6.2.1",
"@tanstack/react-query": "^5.53.3",
"@tanstack/react-table": "^8.20.5",
"@uiw/react-codemirror": "^4.23.0",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View file

@ -0,0 +1,8 @@
'use server';
import { listRepositories } from "@/lib/server/searchService";
export const GET = async () => {
const response = await listRepositories();
return Response.json(response);
}

View file

@ -0,0 +1,79 @@
'use client';
import { Button } from "@/components/ui/button";
import { NavigationMenu as NavigationMenuBase, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, navigationMenuTriggerStyle } from "@/components/ui/navigation-menu";
import Link from "next/link";
import { GitHubLogoIcon } from "@radix-ui/react-icons";
import { SettingsDropdown } from "./settingsDropdown";
import { Separator } from "@/components/ui/separator";
import Image from "next/image";
import logoDark from "../../public/sb_logo_dark_small.png";
import logoLight from "../../public/sb_logo_light_small.png";
import { useRouter } from "next/navigation";
const SOURCEBOT_GITHUB_URL = "https://github.com/TaqlaAI/sourcebot";
export const NavigationMenu = () => {
const router = useRouter();
return (
<div className="flex flex-col w-screen h-fit">
<div className="flex flex-row justify-between items-center py-1.5 px-3">
<div className="flex flex-row items-center">
<div
className="mr-3 cursor-pointer"
onClick={() => {
router.push("/");
}}
>
<Image
src={logoDark}
className="h-11 w-auto hidden dark:block"
alt={"Sourcebot logo"}
/>
<Image
src={logoLight}
className="h-11 w-auto block dark:hidden"
alt={"Sourcebot logo"}
/>
</div>
<NavigationMenuBase>
<NavigationMenuList>
<NavigationMenuItem>
<Link href="/" legacyBehavior passHref>
<NavigationMenuLink className={navigationMenuTriggerStyle()}>
Search
</NavigationMenuLink>
</Link>
</NavigationMenuItem>
<NavigationMenuItem>
<Link href="/repos" legacyBehavior passHref>
<NavigationMenuLink className={navigationMenuTriggerStyle()}>
Repositories
</NavigationMenuLink>
</Link>
</NavigationMenuItem>
</NavigationMenuList>
</NavigationMenuBase>
</div>
<div className="flex flex-row items-center gap-2">
<Button
variant="outline"
size="icon"
onClick={() => {
window.open(SOURCEBOT_GITHUB_URL, "_blank");
}}
>
<GitHubLogoIcon className="w-4 h-4" />
</Button>
<SettingsDropdown />
</div>
</div>
<Separator />
</div>
)
}

View file

@ -3,32 +3,15 @@
import Image from "next/image";
import logoDark from "../../public/sb_logo_dark_large.png";
import logoLight from "../../public/sb_logo_light_large.png";
import { NavigationMenu } from "./navigationMenu";
import { SearchBar } from "./searchBar";
import { SettingsDropdown } from "./settingsDropdown";
import { GitHubLogoIcon } from "@radix-ui/react-icons";
import { Button } from "@/components/ui/button";
const SOURCEBOT_GITHUB_URL = "https://github.com/TaqlaAI/sourcebot";
export default function Home() {
return (
<div className="h-screen flex flex-col items-center">
{/* TopBar */}
<div className="absolute top-0 left-0 right-0">
<div className="flex flex-row justify-end items-center py-1.5 px-3 gap-2">
<Button
variant="outline"
size="icon"
onClick={() => {
window.open(SOURCEBOT_GITHUB_URL, "_blank");
}}
>
<GitHubLogoIcon className="w-4 h-4" />
</Button>
<SettingsDropdown />
</div>
</div>
<NavigationMenu />
<div className="flex flex-col justify-center items-center p-4 mt-48">
<div className="max-h-44 w-auto">
<Image

129
src/app/repos/columns.tsx Normal file
View file

@ -0,0 +1,129 @@
'use client';
import { Button } from "@/components/ui/button";
import { Column, ColumnDef } from "@tanstack/react-table"
import { ArrowUpDown } from "lucide-react"
export type RepositoryColumnInfo = {
name: string;
branches: {
name: string,
version: string,
}[];
repoSizeBytes: number;
indexedFiles: number;
indexSizeBytes: number;
shardCount: number;
lastIndexed: string;
latestCommit: string;
commitUrlTemplate: string;
}
export const columns: ColumnDef<RepositoryColumnInfo>[] = [
{
accessorKey: "name",
header: "Name",
},
{
accessorKey: "branches",
header: "Branches",
cell: ({ row }) => {
const branches = row.original.branches;
return (
<div className="flex flex-col gap-2">
{branches.map(({ name, version }, index) => {
const shortVersion = version.substring(0, 8);
return (
<span key={index}>
{name}
@
<span
className="cursor-pointer text-blue-500 hover:underline"
onClick={() => {
const url = row.original.commitUrlTemplate.replace("{{.Version}}", version);
window.open(url, "_blank");
}}
>
{shortVersion}
</span>
</span>
)
})}
</div>
);
},
},
{
accessorKey: "shardCount",
header: ({ column }) => createSortHeader("Shard Count", column),
cell: ({ row }) => (
<div className="text-right">{row.original.shardCount}</div>
)
},
{
accessorKey: "indexedFiles",
header: ({ column }) => createSortHeader("Indexed Files", column),
cell: ({ row }) => (
<div className="text-right">{row.original.indexedFiles}</div>
)
},
{
accessorKey: "indexSizeBytes",
header: ({ column }) => createSortHeader("Index Size", column),
cell: ({ row }) => {
const size = getFormattedSizeString(row.original.indexSizeBytes);
return <div className="text-right">{size}</div>;
}
},
{
accessorKey: "repoSizeBytes",
header: ({ column }) => createSortHeader("Repository Size", column),
cell: ({ row }) => {
const size = getFormattedSizeString(row.original.repoSizeBytes);
return <div className="text-right">{size}</div>;
}
},
{
accessorKey: "lastIndexed",
header: ({ column }) => createSortHeader("Last Indexed", column),
cell: ({ row }) => {
const date = new Date(row.original.lastIndexed);
return date.toISOString();
}
},
{
accessorKey: "latestCommit",
header: ({ column }) => createSortHeader("Latest Commit", column),
cell: ({ row }) => {
const date = new Date(row.original.latestCommit);
return date.toISOString();
}
}
]
const getFormattedSizeString = (bytes: number): string => {
let size = bytes;
const units = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB'];
let unitIndex = 0;
while (size >= 1024 && unitIndex < units.length - 1) {
size /= 1024;
unitIndex++;
}
return `${size.toFixed(2)} ${units[unitIndex]}`;
}
const createSortHeader = (name: string, column: Column<RepositoryColumnInfo, unknown>) => {
return (
<Button
variant="ghost"
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
>
{name}
<ArrowUpDown className="ml-2 h-4 w-4" />
</Button>
)
}

43
src/app/repos/page.tsx Normal file
View file

@ -0,0 +1,43 @@
import { NavigationMenu } from "../navigationMenu";
import { DataTable } from "@/components/ui/data-table";
import { columns, RepositoryColumnInfo } from "./columns";
import { listRepositories } from "@/lib/server/searchService";
import { isServiceError } from "@/lib/utils";
export default async function ReposPage() {
const _repos = await listRepositories();
if (isServiceError(_repos)) {
return <div>Error fetching repositories</div>;
}
const repos = _repos.List.Repos.map((repo): RepositoryColumnInfo => {
return {
name: repo.Repository.Name,
branches: repo.Repository.Branches.map((branch) => {
return {
name: branch.Name,
version: branch.Version,
}
}),
repoSizeBytes: repo.Stats.ContentBytes,
indexSizeBytes: repo.Stats.IndexBytes,
shardCount: repo.Stats.Shards,
lastIndexed: repo.IndexMetadata.IndexTime,
latestCommit: repo.Repository.LatestCommitDate,
indexedFiles: repo.Stats.Documents,
commitUrlTemplate: repo.Repository.CommitURLTemplate,
}
});
return (
<div className="h-screen flex flex-col items-center">
<NavigationMenu />
<DataTable
columns={columns}
data={repos}
searchKey="name"
searchPlaceholder="Search repositories..."
/>
</div>
)
}

View file

@ -0,0 +1,136 @@
"use client"
import {
ColumnDef,
ColumnFiltersState,
SortingState,
flexRender,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
useReactTable,
} from "@tanstack/react-table"
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import * as React from "react"
interface DataTableProps<TData, TValue> {
columns: ColumnDef<TData, TValue>[]
data: TData[]
searchKey: string
searchPlaceholder?: string
}
export function DataTable<TData, TValue>({
columns,
data,
searchKey,
searchPlaceholder,
}: DataTableProps<TData, TValue>) {
const [sorting, setSorting] = React.useState<SortingState>([])
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
[]
)
const table = useReactTable({
data,
columns,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
onSortingChange: setSorting,
getSortedRowModel: getSortedRowModel(),
onColumnFiltersChange: setColumnFilters,
getFilteredRowModel: getFilteredRowModel(),
state: {
sorting,
columnFilters,
},
})
return (
<div>
<div className="flex items-center py-4">
<Input
placeholder={searchPlaceholder}
value={(table.getColumn(searchKey)?.getFilterValue() as string) ?? ""}
onChange={(event) =>
table.getColumn(searchKey)?.setFilterValue(event.target.value)
}
className="max-w-sm"
/>
</div>
<div className="rounded-md border">
<Table>
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id}>
{headerGroup.headers.map((header) => {
return (
<TableHead key={header.id}>
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext()
)}
</TableHead>
)
})}
</TableRow>
))}
</TableHeader>
<TableBody>
{table.getRowModel().rows?.length ? (
table.getRowModel().rows.map((row) => (
<TableRow
key={row.id}
data-state={row.getIsSelected() && "selected"}
>
{row.getVisibleCells().map((cell) => (
<TableCell key={cell.id}>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</TableCell>
))}
</TableRow>
))
) : (
<TableRow>
<TableCell colSpan={columns.length} className="h-24 text-center">
No results.
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</div>
<div className="flex items-center justify-end space-x-2 py-4">
<Button
variant="outline"
size="sm"
onClick={() => table.previousPage()}
disabled={!table.getCanPreviousPage()}
>
Previous
</Button>
<Button
variant="outline"
size="sm"
onClick={() => table.nextPage()}
disabled={!table.getCanNextPage()}
>
Next
</Button>
</div>
</div>
)
}

View file

@ -0,0 +1,128 @@
import * as React from "react"
import * as NavigationMenuPrimitive from "@radix-ui/react-navigation-menu"
import { cva } from "class-variance-authority"
import { ChevronDown } from "lucide-react"
import { cn } from "@/lib/utils"
const NavigationMenu = React.forwardRef<
React.ElementRef<typeof NavigationMenuPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Root>
>(({ className, children, ...props }, ref) => (
<NavigationMenuPrimitive.Root
ref={ref}
className={cn(
"relative z-10 flex max-w-max flex-1 items-center justify-center",
className
)}
{...props}
>
{children}
<NavigationMenuViewport />
</NavigationMenuPrimitive.Root>
))
NavigationMenu.displayName = NavigationMenuPrimitive.Root.displayName
const NavigationMenuList = React.forwardRef<
React.ElementRef<typeof NavigationMenuPrimitive.List>,
React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.List>
>(({ className, ...props }, ref) => (
<NavigationMenuPrimitive.List
ref={ref}
className={cn(
"group flex flex-1 list-none items-center justify-center space-x-1",
className
)}
{...props}
/>
))
NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName
const NavigationMenuItem = NavigationMenuPrimitive.Item
const navigationMenuTriggerStyle = cva(
"group inline-flex h-10 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50"
)
const NavigationMenuTrigger = React.forwardRef<
React.ElementRef<typeof NavigationMenuPrimitive.Trigger>,
React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Trigger>
>(({ className, children, ...props }, ref) => (
<NavigationMenuPrimitive.Trigger
ref={ref}
className={cn(navigationMenuTriggerStyle(), "group", className)}
{...props}
>
{children}{" "}
<ChevronDown
className="relative top-[1px] ml-1 h-3 w-3 transition duration-200 group-data-[state=open]:rotate-180"
aria-hidden="true"
/>
</NavigationMenuPrimitive.Trigger>
))
NavigationMenuTrigger.displayName = NavigationMenuPrimitive.Trigger.displayName
const NavigationMenuContent = React.forwardRef<
React.ElementRef<typeof NavigationMenuPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Content>
>(({ className, ...props }, ref) => (
<NavigationMenuPrimitive.Content
ref={ref}
className={cn(
"left-0 top-0 w-full data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 md:absolute md:w-auto ",
className
)}
{...props}
/>
))
NavigationMenuContent.displayName = NavigationMenuPrimitive.Content.displayName
const NavigationMenuLink = NavigationMenuPrimitive.Link
const NavigationMenuViewport = React.forwardRef<
React.ElementRef<typeof NavigationMenuPrimitive.Viewport>,
React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Viewport>
>(({ className, ...props }, ref) => (
<div className={cn("absolute left-0 top-full flex justify-center")}>
<NavigationMenuPrimitive.Viewport
className={cn(
"origin-top-center relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 md:w-[var(--radix-navigation-menu-viewport-width)]",
className
)}
ref={ref}
{...props}
/>
</div>
))
NavigationMenuViewport.displayName =
NavigationMenuPrimitive.Viewport.displayName
const NavigationMenuIndicator = React.forwardRef<
React.ElementRef<typeof NavigationMenuPrimitive.Indicator>,
React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Indicator>
>(({ className, ...props }, ref) => (
<NavigationMenuPrimitive.Indicator
ref={ref}
className={cn(
"top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in",
className
)}
{...props}
>
<div className="relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm bg-border shadow-md" />
</NavigationMenuPrimitive.Indicator>
))
NavigationMenuIndicator.displayName =
NavigationMenuPrimitive.Indicator.displayName
export {
navigationMenuTriggerStyle,
NavigationMenu,
NavigationMenuList,
NavigationMenuItem,
NavigationMenuContent,
NavigationMenuTrigger,
NavigationMenuLink,
NavigationMenuIndicator,
NavigationMenuViewport,
}

117
src/components/ui/table.tsx Normal file
View file

@ -0,0 +1,117 @@
import * as React from "react"
import { cn } from "@/lib/utils"
const Table = React.forwardRef<
HTMLTableElement,
React.HTMLAttributes<HTMLTableElement>
>(({ className, ...props }, ref) => (
<div className="relative w-full overflow-auto">
<table
ref={ref}
className={cn("w-full caption-bottom text-sm", className)}
{...props}
/>
</div>
))
Table.displayName = "Table"
const TableHeader = React.forwardRef<
HTMLTableSectionElement,
React.HTMLAttributes<HTMLTableSectionElement>
>(({ className, ...props }, ref) => (
<thead ref={ref} className={cn("[&_tr]:border-b", className)} {...props} />
))
TableHeader.displayName = "TableHeader"
const TableBody = React.forwardRef<
HTMLTableSectionElement,
React.HTMLAttributes<HTMLTableSectionElement>
>(({ className, ...props }, ref) => (
<tbody
ref={ref}
className={cn("[&_tr:last-child]:border-0", className)}
{...props}
/>
))
TableBody.displayName = "TableBody"
const TableFooter = React.forwardRef<
HTMLTableSectionElement,
React.HTMLAttributes<HTMLTableSectionElement>
>(({ className, ...props }, ref) => (
<tfoot
ref={ref}
className={cn(
"border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",
className
)}
{...props}
/>
))
TableFooter.displayName = "TableFooter"
const TableRow = React.forwardRef<
HTMLTableRowElement,
React.HTMLAttributes<HTMLTableRowElement>
>(({ className, ...props }, ref) => (
<tr
ref={ref}
className={cn(
"border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",
className
)}
{...props}
/>
))
TableRow.displayName = "TableRow"
const TableHead = React.forwardRef<
HTMLTableCellElement,
React.ThHTMLAttributes<HTMLTableCellElement>
>(({ className, ...props }, ref) => (
<th
ref={ref}
className={cn(
"h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0",
className
)}
{...props}
/>
))
TableHead.displayName = "TableHead"
const TableCell = React.forwardRef<
HTMLTableCellElement,
React.TdHTMLAttributes<HTMLTableCellElement>
>(({ className, ...props }, ref) => (
<td
ref={ref}
className={cn("p-4 align-middle [&:has([role=checkbox])]:pr-0", className)}
{...props}
/>
))
TableCell.displayName = "TableCell"
const TableCaption = React.forwardRef<
HTMLTableCaptionElement,
React.HTMLAttributes<HTMLTableCaptionElement>
>(({ className, ...props }, ref) => (
<caption
ref={ref}
className={cn("mt-4 text-sm text-muted-foreground", className)}
{...props}
/>
))
TableCaption.displayName = "TableCaption"
export {
Table,
TableHeader,
TableBody,
TableFooter,
TableHead,
TableRow,
TableCell,
TableCaption,
}

View file

@ -67,3 +67,62 @@ export type FileSourceResponse = z.infer<typeof fileSourceResponseSchema>;
export const fileSourceResponseSchema = z.object({
source: z.string(),
});
export type ListRepositoriesResponse = z.infer<typeof listRepositoriesResponseSchema>;
// @see : https://github.com/TaqlaAI/zoekt/blob/3780e68cdb537d5a7ed2c84d9b3784f80c7c5d04/api.go#L728
export const statsSchema = z.object({
Repos: z.number(),
Shards: z.number(),
Documents: z.number(),
IndexBytes: z.number(),
ContentBytes: z.number(),
NewLinesCount: z.number(),
DefaultBranchNewLinesCount: z.number(),
OtherBranchesNewLinesCount: z.number(),
});
// @see : https://github.com/TaqlaAI/zoekt/blob/3780e68cdb537d5a7ed2c84d9b3784f80c7c5d04/api.go#L716
export const indexMetadataSchema = z.object({
IndexFormatVersion: z.number(),
IndexFeatureVersion: z.number(),
IndexMinReaderVersion: z.number(),
IndexTime: z.string(),
PlainASCII: z.boolean(),
LanguageMap: z.record(z.string(), z.number()),
ZoektVersion: z.string(),
ID: z.string(),
});
// @see : https://github.com/TaqlaAI/zoekt/blob/3780e68cdb537d5a7ed2c84d9b3784f80c7c5d04/api.go#L555
export const repositorySchema = z.object({
Name: z.string(),
URL: z.string(),
Source: z.string(),
Branches: z.array(z.object({
Name: z.string(),
Version: z.string(),
})),
CommitURLTemplate: z.string(),
FileURLTemplate: z.string(),
LineFragmentTemplate: z.string(),
RawConfig: z.record(z.string(), z.string()),
Rank: z.number(),
IndexOptions: z.string(),
HasSymbols: z.boolean(),
Tombstone: z.boolean(),
LatestCommitDate: z.string(),
FileTombstones: z.string().optional(),
});
export const listRepositoriesResponseSchema = z.object({
List: z.object({
Repos: z.array(z.object({
Repository: repositorySchema,
IndexMetadata: indexMetadataSchema,
Stats: statsSchema,
})),
Stats: statsSchema,
})
});

View file

@ -1,9 +1,9 @@
import escapeStringRegexp from "escape-string-regexp";
import { SHARD_MAX_MATCH_COUNT, TOTAL_MAX_MATCH_COUNT } from "../environment";
import { FileSourceRequest, FileSourceResponse, SearchRequest, SearchResponse, searchResponseSchema } from "../schemas";
import { fileNotFound, invalidZoektResponse, schemaValidationError, ServiceError, unexpectedError } from "../serviceError";
import { FileSourceRequest, FileSourceResponse, ListRepositoriesResponse, listRepositoriesResponseSchema, SearchRequest, SearchResponse, searchResponseSchema } from "../schemas";
import { fileNotFound, invalidZoektResponse, ServiceError, unexpectedError } from "../serviceError";
import { isServiceError } from "../utils";
import { zoektFetch } from "./zoektClient";
import escapeStringRegexp from "escape-string-regexp";
export const search = async ({ query, numResults, whole }: SearchRequest): Promise<SearchResponse | ServiceError> => {
const body = JSON.stringify({
@ -64,3 +64,29 @@ export const getFileSource = async ({ fileName, repository }: FileSourceRequest)
source
}
}
export const listRepositories = async (): Promise<ListRepositoriesResponse | ServiceError> => {
const body = JSON.stringify({
opts: {
Field: 0,
}
});
const listResponse = await zoektFetch({
path: "/api/list",
body,
method: "POST"
});
if (!listResponse.ok) {
return invalidZoektResponse(listResponse);
}
const listBody = await listResponse.json();
const parsedListResponse = listRepositoriesResponseSchema.safeParse(listBody);
if (!parsedListResponse.success) {
console.error(`Failed to parse zoekt response. Error: ${parsedListResponse.error}`);
return unexpectedError(`Something went wrong while parsing the response from zoekt`);
}
return parsedListResponse.data;
}

View file

@ -582,6 +582,26 @@
aria-hidden "^1.1.1"
react-remove-scroll "2.5.7"
"@radix-ui/react-navigation-menu@^1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.2.0.tgz#884c9b9fd141cc5db257bd3f6bf3b84e349c6617"
integrity sha512-OQ8tcwAOR0DhPlSY3e4VMXeHiol7la4PPdJWhhwJiJA+NLX0SaCaonOkRnI3gCDHoZ7Fo7bb/G6q25fRM2Y+3Q==
dependencies:
"@radix-ui/primitive" "1.1.0"
"@radix-ui/react-collection" "1.1.0"
"@radix-ui/react-compose-refs" "1.1.0"
"@radix-ui/react-context" "1.1.0"
"@radix-ui/react-direction" "1.1.0"
"@radix-ui/react-dismissable-layer" "1.1.0"
"@radix-ui/react-id" "1.1.0"
"@radix-ui/react-presence" "1.1.0"
"@radix-ui/react-primitive" "2.0.0"
"@radix-ui/react-use-callback-ref" "1.1.0"
"@radix-ui/react-use-controllable-state" "1.1.0"
"@radix-ui/react-use-layout-effect" "1.1.0"
"@radix-ui/react-use-previous" "1.1.0"
"@radix-ui/react-visually-hidden" "1.1.0"
"@radix-ui/react-popper@1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@radix-ui/react-popper/-/react-popper-1.2.0.tgz#a3e500193d144fe2d8f5d5e60e393d64111f2a7a"
@ -689,6 +709,11 @@
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz#3c2c8ce04827b26a39e442ff4888d9212268bd27"
integrity sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==
"@radix-ui/react-use-previous@1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-previous/-/react-use-previous-1.1.0.tgz#d4dd37b05520f1d996a384eb469320c2ada8377c"
integrity sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==
"@radix-ui/react-use-rect@1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz#13b25b913bd3e3987cc9b073a1a164bb1cf47b88"
@ -703,6 +728,13 @@
dependencies:
"@radix-ui/react-use-layout-effect" "1.1.0"
"@radix-ui/react-visually-hidden@1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.0.tgz#ad47a8572580f7034b3807c8e6740cd41038a5a2"
integrity sha512-N8MDZqtgCgG5S3aV60INAB475osJousYpZ4cTJ2cFbMpdHS5Y6loLTH8LPtkj2QN0x93J30HT/M3qJXM0+lyeQ==
dependencies:
"@radix-ui/react-primitive" "2.0.0"
"@radix-ui/rect@1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@radix-ui/rect/-/rect-1.1.0.tgz#f817d1d3265ac5415dadc67edab30ae196696438"
@ -743,6 +775,18 @@
dependencies:
"@tanstack/query-core" "5.53.3"
"@tanstack/react-table@^8.20.5":
version "8.20.5"
resolved "https://registry.yarnpkg.com/@tanstack/react-table/-/react-table-8.20.5.tgz#19987d101e1ea25ef5406dce4352cab3932449d8"
integrity sha512-WEHopKw3znbUZ61s9i0+i9g8drmDo6asTWbrQh8Us63DAk/M0FkmIqERew6P71HI75ksZ2Pxyuf4vvKh9rAkiA==
dependencies:
"@tanstack/table-core" "8.20.5"
"@tanstack/table-core@8.20.5":
version "8.20.5"
resolved "https://registry.yarnpkg.com/@tanstack/table-core/-/table-core-8.20.5.tgz#3974f0b090bed11243d4107283824167a395cf1d"
integrity sha512-P9dF7XbibHph2PFRz8gfBKEXEY/HJPOhym8CHmjF8y3q5mWpKx9xtZapXQUWCgkqvsK0R46Azuz+VaxD4Xl+Tg==
"@types/json5@^0.0.29":
version "0.0.29"
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"