import { DataTable } from "@/src/components/table/data-table"; import { type LangfuseColumnDef } from "@/src/components/table/types"; import { api } from "@/src/utils/api"; import { safeExtract } from "@/src/utils/map-utils"; import { useQueryParams, withDefault, NumberParam } from "use-query-params"; import { IOTableCell } from "@/src/components/ui/IOTableCell"; import { Avatar, AvatarFallback, AvatarImage, } from "@/src/components/ui/avatar"; import { cn } from "@/src/utils/tailwind"; import { useRowHeightLocalStorage } from "@/src/components/table/data-table-row-height-switch"; import { DataTableToolbar } from "@/src/components/table/data-table-toolbar"; import { type RouterOutputs } from "@/src/utils/api"; import { SettingsTableCard } from "@/src/components/layouts/settings-table-card"; import { BatchExportTableButton } from "@/src/components/BatchExportTableButton"; import { BatchExportTableName } from "@langfuse/shared"; type AuditLogRow = RouterOutputs["auditLogs"]["all"]["data"][number]; export function AuditLogsTable(props: { projectId: string }) { const [paginationState, setPaginationState] = useQueryParams({ pageIndex: withDefault(NumberParam, 0), pageSize: withDefault(NumberParam, 50), }); const auditLogs = api.auditLogs.all.useQuery({ projectId: props.projectId, page: paginationState.pageIndex, limit: paginationState.pageSize, }); const [rowHeight, setRowHeight] = useRowHeightLocalStorage("auditLogs", "s"); const columns: LangfuseColumnDef[] = [ { accessorKey: "createdAt", header: "Time", cell: (row) => { const date = row.getValue() as Date; return date.toLocaleString(); }, }, { accessorKey: "actor", header: "Actor", headerTooltip: { description: "The actor within Langfuse who performed the action.", }, cell: (row) => { const actor = row.getValue() as AuditLogRow["actor"]; if (actor.type === "USER") { const user = actor.body; return (
{user?.image && ( )} {user?.name?.charAt(0) ?? user?.email?.charAt(0) ?? "U"} {user?.name ?? user?.email ?? user.id}
); } if (actor.type === "API_KEY") { const apiKey = actor.body; return (
{apiKey?.publicKey ?? apiKey?.id}
); } return null; }, }, { accessorKey: "resourceType", header: "Resource Type", }, { accessorKey: "resourceId", header: "Resource ID", }, { accessorKey: "action", header: "Action", }, { accessorKey: "before", header: "Before", size: 300, cell: (row) => { const value = row.getValue() as string | null; if (!value) return null; return ; }, }, { accessorKey: "after", header: "After", size: 300, cell: (row) => { const value = row.getValue() as string | null; if (!value) return null; return ; }, }, ]; return ( <> , ]} className="px-0" /> ); }