"use client"; import { useState } from "react"; import { type ColumnDef, type Table as TableType, getCoreRowModel, useReactTable, } from "@tanstack/react-table"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Loader2, CheckCircle2 } from "lucide-react"; import { DataTable } from "@/components/tables/DataTable"; import DropdownSelect from "@/components/ui/dropdown-select"; import { Input } from "@/components/ui/input"; import { cn } from "@/lib/utils"; import type { ForgejoConnection } from "@/lib/api-forgejo"; interface ConnectionsTableProps { connections: ForgejoConnection[]; isLoading: boolean; onEdit?: (connection: ForgejoConnection) => void; onDelete?: (connection: ForgejoConnection) => void; onValidate?: (connection: ForgejoConnection) => void; } export function ForgejoConnectionsTable({ connections, isLoading, onEdit, onDelete, onValidate, }: ConnectionsTableProps) { // onEdit available for future use const _ = onEdit; const table = useReactTable({ data: connections, columns: columns(onValidate), getCoreRowModel: getCoreRowModel(), }); return ( ), title: "No Forgejo connections yet", description: "Connect a Forgejo instance to start tracking issues and pull requests from your Git projects.", actionHref: "/git-projects/connections/new", actionLabel: "Add connection", }} rowActions={{ getEditHref: (row) => `/git-projects/connections/${row.id}/edit`, onDelete: onDelete ?? undefined, }} /> ); } const columns = ( onValidate?: (connection: ForgejoConnection) => void ): ColumnDef[] => [ { accessorKey: "name", header: ({ column }) => { return ( ); }, cell: ({ row }) => (
{row.original.name} {row.original.base_url}
), }, { accessorKey: "status", header: "Status", cell: ({ row }) => { const isActive = row.original.active; return ( {isActive ? "Active" : "Inactive"} ); }, }, { accessorKey: "hasToken", header: "Auth", cell: ({ row }) => { const hasToken = row.original.has_token; const tokenLastEight = row.original.token_last_eight; return (
{hasToken ? "Configured" : "Missing"} {tokenLastEight && hasToken && ( ••••{tokenLastEight} )}
); }, }, { id: "actions", cell: ({ row }) => , }, ]; function ActionsCell({ connection, onValidate, }: { connection: ForgejoConnection; onValidate?: (connection: ForgejoConnection) => void; }) { const [isValidateLoading, setIsValidateLoading] = useState(false); // eslint-disable-next-line @typescript-eslint/no-unused-vars const [validateResult, setValidateResult] = useState<{ ok: boolean; error_message?: string; response_time_ms?: number; } | null>(null); const handleValidate = async () => { if (!onValidate) return; setIsValidateLoading(true); try { await onValidate(connection); } finally { setIsValidateLoading(false); } }; const options = [ { value: "edit", label: "Edit" }, { value: "delete", label: "Delete", icon: (props: { className?: string }) => ( )}, ]; const handleSelect = (value: string) => { if (value === "edit") { // Navigate to edit page } else if (value === "delete") { if (confirm(`Are you sure you want to delete "${connection.name}"?`)) { // Trigger delete via parent } } }; return (
{onValidate && ( )}
); } // Filter component export function ConnectionsTableFilter({ value, onChange, }: { value: string; onChange: (value: string) => void; }) { return ( onChange(e.target.value)} className="h-8 w-[150px] lg:w-[250px]" /> ); } // Column toggle component export function ConnectionsTableToggle({ table, }: { table: TableType; }) { return (
Show:
{table .getAllColumns() .filter((column) => column.getCanHide()) .map((column) => { return ( ); })}
); }