"use client"; import { type ColumnDef, type ColumnFiltersState, type PaginationState, type SortingState, type VisibilityState, getCoreRowModel, getFacetedRowModel, getFacetedUniqueValues, getFilteredRowModel, getPaginationRowModel, getSortedRowModel, useReactTable, } from "@tanstack/react-table"; import { useCallback, useEffect, useMemo, useState } from "react"; import Link from "next/link"; import { useRouter } from "next/navigation"; import { toast } from "sonner"; import { useCurrentUser } from "@/hooks/use-current-user"; import { toastError } from "@/lib/format"; import { deleteLexicon, deleteNetworkLexicon, getLexicons, } from "@/lib/api"; import type { LexiconSummary } from "@/types/lexicons"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, } from "@/components/ui/alert-dialog"; import { DataTable } from "@/components/data-table/data-table"; import { DataTableColumnHeader } from "@/components/data-table/data-table-column-header"; import { DataTableToolbar } from "@/components/data-table/data-table-toolbar"; import { SiteHeader } from "@/components/site-header"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Eye, Rows3, Trash2 } from "lucide-react"; export default function LexiconsPage() { const { hasPermission } = useCurrentUser(); const router = useRouter(); const [lexicons, setLexicons] = useState([]); const load = useCallback(() => { getLexicons() .then(setLexicons) .catch((e) => toastError("Failed to load lexicons", e)); }, []); useEffect(() => { load(); }, [load]); async function handleDelete(lex: LexiconSummary) { try { if (lex.source === "network") { await deleteNetworkLexicon(lex.id); } else { await deleteLexicon(lex.id); } toast.success("Lexicon deleted"); load(); } catch (e: unknown) { toastError("Failed to delete lexicon", e); } } const columns = useMemo[]>( () => [ { id: "id", accessorKey: "id", header: ({ column }) => ( ), cell: ({ row }) => ( {row.original.id} ), filterFn: "includesString", enableColumnFilter: true, enableSorting: true, enableHiding: false, meta: { label: "ID", placeholder: "Filter by ID...", variant: "text", }, }, { id: "lexicon_type", accessorKey: "lexicon_type", header: ({ column }) => ( ), cell: ({ row }) => ( {row.original.lexicon_type} ), filterFn: (row, columnId, filterValue) => { if (!Array.isArray(filterValue) || filterValue.length === 0) return true; return filterValue.includes(row.getValue(columnId)); }, enableColumnFilter: true, enableSorting: true, meta: { label: "Type", variant: "multiSelect", options: [ { label: "Record", value: "record" }, { label: "Query", value: "query" }, { label: "Procedure", value: "procedure" }, ], }, }, { id: "source", accessorKey: "source", header: ({ column }) => ( ), cell: ({ row }) => ( {row.original.source} ), filterFn: (row, columnId, filterValue) => { if (!Array.isArray(filterValue) || filterValue.length === 0) return true; return filterValue.includes(row.getValue(columnId)); }, enableColumnFilter: true, enableSorting: true, meta: { label: "Source", variant: "select", options: [ { label: "Manual", value: "manual" }, { label: "Network", value: "network" }, ], }, }, { id: "action", accessorKey: "action", header: ({ column }) => ( ), cell: ({ row }) => row.original.action ?? "--", enableSorting: true, }, { id: "backfill", accessorKey: "backfill", header: ({ column }) => ( ), cell: ({ row }) => (row.original.backfill ? "Yes" : "No"), enableSorting: true, }, { id: "revision", accessorKey: "revision", header: ({ column }) => ( ), cell: ({ row }) => ( {row.original.revision} ), enableSorting: true, }, { id: "actions", header: "", cell: ({ row }) => (
{row.original.lexicon_type === "record" && ( )} {hasPermission("lexicons:delete") && ( e.stopPropagation()}> Delete lexicon? This will permanently remove the lexicon and its associated routes. This action cannot be undone. Cancel handleDelete(row.original)}>Delete )}
), enableSorting: false, enableHiding: false, }, ], // eslint-disable-next-line react-hooks/exhaustive-deps [hasPermission], ); const [sorting, setSorting] = useState([ { id: "id", desc: false }, ]); const [columnFilters, setColumnFilters] = useState([]); const [columnVisibility, setColumnVisibility] = useState({}); const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 20, }); const table = useReactTable({ data: lexicons, columns, state: { sorting, columnFilters, columnVisibility, pagination, columnPinning: { right: ["actions"] }, }, defaultColumn: { enableColumnFilter: false, }, onSortingChange: setSorting, onColumnFiltersChange: setColumnFilters, onColumnVisibilityChange: setColumnVisibility, onPaginationChange: setPagination, getCoreRowModel: getCoreRowModel(), getFilteredRowModel: getFilteredRowModel(), getSortedRowModel: getSortedRowModel(), getPaginationRowModel: getPaginationRowModel(), getFacetedRowModel: getFacetedRowModel(), getFacetedUniqueValues: getFacetedUniqueValues(), getRowId: (row) => row.id, }); return ( <>
router.push(`/dashboard/lexicons/${encodeURIComponent(lex.id)}`) } > {hasPermission("lexicons:create") && ( )}
); }