import React, { useState } from "react"; import { Table, TableBody, TableCell, TableHead, TableHeaderCell, TableRow, Icon, Button, } from "@tremor/react"; import { TrashIcon, SwitchVerticalIcon, ChevronUpIcon, ChevronDownIcon, } from "@heroicons/react/outline"; import { Tooltip } from "antd"; import { ColumnDef, flexRender, getCoreRowModel, getSortedRowModel, SortingState, useReactTable, } from "@tanstack/react-table"; import { getGuardrailLogoAndName, guardrail_provider_map } from "./guardrail_info_helpers"; import EditGuardrailForm from "./edit_guardrail_form"; import GuardrailInfoView from "./guardrail_info"; interface GuardrailItem { guardrail_id?: string; guardrail_name: string | null; litellm_params: { guardrail: string; mode: string; default_on: boolean; pii_entities_config?: {[key: string]: string}; [key: string]: any; }; guardrail_info: Record | null; created_at?: string; updated_at?: string; } interface GuardrailTableProps { guardrailsList: GuardrailItem[]; isLoading: boolean; onDeleteClick: (guardrailId: string, guardrailName: string) => void; accessToken: string | null; onGuardrailUpdated: () => void; isAdmin?: boolean; onShowGuardrailInfo?: (isVisible: boolean) => void; } const GuardrailTable: React.FC = ({ guardrailsList, isLoading, onDeleteClick, accessToken, onGuardrailUpdated, isAdmin = false, onShowGuardrailInfo, }) => { const [sorting, setSorting] = useState([ { id: "created_at", desc: true } ]); const [editModalVisible, setEditModalVisible] = useState(false); const [selectedGuardrail, setSelectedGuardrail] = useState(null); const [showGuardrailInfo, setShowGuardrailInfo] = useState(false); const [selectedGuardrailId, setSelectedGuardrailId] = useState(null); // Format date helper function const formatDate = (dateString?: string) => { if (!dateString) return "-"; const date = new Date(dateString); return date.toLocaleString(); }; const handleEditClick = (guardrail: GuardrailItem) => { setSelectedGuardrail(guardrail); setEditModalVisible(true); }; const handleEditSuccess = () => { setEditModalVisible(false); setSelectedGuardrail(null); onGuardrailUpdated(); }; const handleGuardrailIdClick = (guardrailId: string) => { setSelectedGuardrailId(guardrailId); setShowGuardrailInfo(true); onShowGuardrailInfo?.(true); }; const handleGuardrailInfoClose = () => { setShowGuardrailInfo(false); setSelectedGuardrailId(null); onShowGuardrailInfo?.(false); }; const handleGuardrailDeleted = () => { setShowGuardrailInfo(false); setSelectedGuardrailId(null); onShowGuardrailInfo?.(false); onGuardrailUpdated(); }; const columns: ColumnDef[] = [ { header: "Guardrail ID", accessorKey: "guardrail_id", cell: (info: any) => ( ), }, { header: "Name", accessorKey: "guardrail_name", cell: ({ row }) => { const guardrail = row.original; return ( {guardrail.guardrail_name || "-"} ); }, }, { header: "Provider", accessorKey: "litellm_params.guardrail", cell: ({ row }) => { const guardrail = row.original; const { logo, displayName } = getGuardrailLogoAndName(guardrail.litellm_params.guardrail); return (
{logo && ( {`${displayName} { // Hide broken image (e.target as HTMLImageElement).style.display = 'none'; }} /> )} {displayName}
); }, }, { header: "Mode", accessorKey: "litellm_params.mode", cell: ({ row }) => { const guardrail = row.original; return ( {guardrail.litellm_params.mode} ); }, }, { header: "Created At", accessorKey: "created_at", cell: ({ row }) => { const guardrail = row.original; return ( {formatDate(guardrail.created_at)} ); }, }, { header: "Updated At", accessorKey: "updated_at", cell: ({ row }) => { const guardrail = row.original; return ( {formatDate(guardrail.updated_at)} ); }, }, { id: "actions", header: "", cell: ({ row }) => { const guardrail = row.original; return (
guardrail.guardrail_id && onDeleteClick(guardrail.guardrail_id, guardrail.guardrail_name || 'Unnamed Guardrail')} className="cursor-pointer hover:text-red-500" tooltip="Delete guardrail" />
); }, }, ]; const table = useReactTable({ data: guardrailsList, columns, state: { sorting, }, onSortingChange: setSorting, getCoreRowModel: getCoreRowModel(), getSortedRowModel: getSortedRowModel(), enableSorting: true, }); // If showing guardrail info, render the GuardrailInfoView if (showGuardrailInfo && selectedGuardrailId) { return ( ); } return (
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => (
{header.isPlaceholder ? null : ( flexRender( header.column.columnDef.header, header.getContext() ) )}
{header.id !== 'actions' && (
{header.column.getIsSorted() ? ( { asc: , desc: }[header.column.getIsSorted() as string] ) : ( )}
)}
))}
))}
{isLoading ? (

Loading...

) : guardrailsList.length > 0 ? ( table.getRowModel().rows.map((row) => ( {row.getVisibleCells().map((cell) => ( {flexRender(cell.column.columnDef.cell, cell.getContext())} ))} )) ) : (

No guardrails found

)}
{/* Edit Modal */} {selectedGuardrail && ( setEditModalVisible(false)} accessToken={accessToken} onSuccess={handleEditSuccess} guardrailId={selectedGuardrail.guardrail_id || ''} initialValues={{ guardrail_name: selectedGuardrail.guardrail_name || '', provider: Object.keys(guardrail_provider_map).find( key => guardrail_provider_map[key] === selectedGuardrail?.litellm_params.guardrail ) || '', mode: selectedGuardrail.litellm_params.mode, default_on: selectedGuardrail.litellm_params.default_on, pii_entities_config: selectedGuardrail.litellm_params.pii_entities_config, ...selectedGuardrail.guardrail_info }} /> )}
); }; export default GuardrailTable;