diff --git a/web/package-lock.json b/web/package-lock.json
index a675b937c..d3312cb4a 100644
Binary files a/web/package-lock.json and b/web/package-lock.json differ
diff --git a/web/package.json b/web/package.json
index 5d41bb77a..47f33f978 100644
--- a/web/package.json
+++ b/web/package.json
@@ -12,6 +12,7 @@
"@azure/monitor-opentelemetry": "^1.11.1",
"@radix-ui/react-dropdown-menu": "^2.1.15",
"@radix-ui/react-slot": "^1.2.3",
+ "@tanstack/react-table": "^8.21.3",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"lucide-react": "^0.514.0",
diff --git a/web/src/components/ui/table.tsx b/web/src/components/ui/table.tsx
new file mode 100644
index 000000000..4b3c98ea4
--- /dev/null
+++ b/web/src/components/ui/table.tsx
@@ -0,0 +1,116 @@
+"use client";
+
+import * as React from "react";
+
+import { cn } from "@/lib/utils";
+
+function Table({ className, ...props }: React.ComponentProps<"table">) {
+ return (
+
+ );
+}
+
+function TableHeader({ className, ...props }: React.ComponentProps<"thead">) {
+ return (
+
+ );
+}
+
+function TableBody({ className, ...props }: React.ComponentProps<"tbody">) {
+ return (
+
+ );
+}
+
+function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">) {
+ return (
+ tr]:last:border-b-0",
+ className,
+ )}
+ {...props}
+ />
+ );
+}
+
+function TableRow({ className, ...props }: React.ComponentProps<"tr">) {
+ return (
+
+ );
+}
+
+function TableHead({ className, ...props }: React.ComponentProps<"th">) {
+ return (
+ [role=checkbox]]:translate-y-[2px]",
+ className,
+ )}
+ {...props}
+ />
+ );
+}
+
+function TableCell({ className, ...props }: React.ComponentProps<"td">) {
+ return (
+ | [role=checkbox]]:translate-y-[2px]",
+ className,
+ )}
+ {...props}
+ />
+ );
+}
+
+function TableCaption({
+ className,
+ ...props
+}: React.ComponentProps<"caption">) {
+ return (
+
+ );
+}
+
+export {
+ Table,
+ TableHeader,
+ TableBody,
+ TableFooter,
+ TableHead,
+ TableRow,
+ TableCell,
+ TableCaption,
+};
|