"use client" import { useMemo } from "react" import { type ColumnDef, getCoreRowModel, getExpandedRowModel, getSortedRowModel, useReactTable, } from "@tanstack/react-table" import { cn } from "@/lib/utils" import { DataGridShell } from "@/components/data-grids/shared/data-grid-shell" import { DATA_GRID_CELL_PAD, DATA_GRID_CELL_PAD_FIRST, } from "@/components/data-grids/shared/data-grid-layout" import { DataGridSortHeader } from "@/components/data-grids/shared/data-grid-sort-header" import { EmptyState } from "@/components/empty-state" import { BgpSessionDetail } from "@/components/data-grids/bgp-session-detail" import type { BgpSessionRow, BgpState, BgpType } from "@/lib/bgp/types" import { BGP_AS_NAMES } from "@/lib/bgp/types" import { fmtBgpNum } from "@/lib/bgp/helpers" import { ChevronDownIcon, ChevronRightIcon, NetworkIcon } from "lucide-react" const STATE_STYLE: Record = { Established: { bg: "bg-emerald-500/10", text: "text-emerald-600 dark:text-emerald-400", dot: "bg-emerald-500", label: "Established", }, Active: { bg: "bg-amber-500/10", text: "text-amber-600 dark:text-amber-400", dot: "bg-amber-500", label: "Active", }, Idle: { bg: "bg-slate-500/10", text: "text-slate-500 dark:text-slate-400", dot: "bg-slate-500", label: "Idle", }, Connect: { bg: "bg-blue-500/10", text: "text-blue-600 dark:text-blue-400", dot: "bg-blue-500", label: "Connect", }, OpenSent: { bg: "bg-violet-500/10", text: "text-violet-600 dark:text-violet-400", dot: "bg-violet-500", label: "OpenSent", }, OpenConfirm: { bg: "bg-violet-500/10", text: "text-violet-600 dark:text-violet-400", dot: "bg-violet-500", label: "OpenConfirm", }, } const TYPE_STYLE: Record = { eBGP: { bg: "bg-blue-500/10", text: "text-blue-600 dark:text-blue-400" }, iBGP: { bg: "bg-purple-500/10", text: "text-purple-600 dark:text-purple-400" }, } function StateBadge({ state }: { state: BgpState }) { const s = STATE_STYLE[state] return ( {s.label} ) } function TypeBadge({ type }: { type: BgpType }) { const s = TYPE_STYLE[type] return ( {type} ) } interface BgpSessionsDataGridProps { sessions: BgpSessionRow[] } function BgpSessionsDataGrid({ sessions }: BgpSessionsDataGridProps) { const columns = useMemo[]>( () => [ { id: "serverLabel", accessorKey: "serverLabel", header: ({ column }) => ( ), cell: ({ row }) => { const expanded = row.getIsExpanded() return (
{expanded ? ( ) : ( )} {row.original.serverLabel}
) }, meta: { headerTitle: "Роутер", headerClassName: DATA_GRID_CELL_PAD_FIRST, cellClassName: DATA_GRID_CELL_PAD_FIRST, expandedContent: (row: BgpSessionRow) => , }, }, { id: "peerIp", accessorKey: "peerIp", header: ({ column }) => , cell: ({ row }) => {row.original.peerIp}, meta: { headerTitle: "Peer IP", headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD, }, }, { id: "remoteAs", accessorKey: "remoteAs", header: ({ column }) => , cell: ({ row }) => { const as = row.original.remoteAs return (
AS{as} {BGP_AS_NAMES[as] && ( {BGP_AS_NAMES[as]} )}
) }, meta: { headerTitle: "Remote AS", headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD, }, }, { id: "description", accessorKey: "description", header: ({ column }) => , cell: ({ row }) => ( {row.original.description} ), meta: { headerTitle: "Описание", headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD, }, }, { id: "type", accessorKey: "type", header: ({ column }) => , cell: ({ row }) => , meta: { headerTitle: "Тип", headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD, }, }, { id: "state", accessorKey: "state", header: ({ column }) => , cell: ({ row }) => , meta: { headerTitle: "Состояние", headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD, }, }, { id: "uptime", accessorKey: "uptime", header: ({ column }) => , cell: ({ row }) => ( {row.original.uptime ?? "—"} ), meta: { headerTitle: "Uptime", headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD, }, }, { id: "prefixesRx", accessorKey: "prefixesRx", header: ({ column }) => , cell: ({ row }) => { const n = row.original.prefixesRx return n > 0 ? ( {fmtBgpNum(n)} ) : ( ) }, meta: { headerTitle: "Prefixes ↓", headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD, }, }, { id: "prefixesTx", accessorKey: "prefixesTx", header: ({ column }) => , cell: ({ row }) => { const n = row.original.prefixesTx return n > 0 ? ( {fmtBgpNum(n)} ) : ( ) }, meta: { headerTitle: "Prefixes ↑", headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD, }, }, ], [], ) const table = useReactTable({ data: sessions, columns, getCoreRowModel: getCoreRowModel(), getSortedRowModel: getSortedRowModel(), getExpandedRowModel: getExpandedRowModel(), getRowId: (row) => row.id, getRowCanExpand: () => true, }) if (sessions.length === 0) { return ( } title="Нет BGP-сессий" description="Измените фильтры или проверьте подключение к роутерам" className="border-0 py-10" /> ) } return ( table.getRow(row.id).toggleExpanded()} /> ) } export { BgpSessionsDataGrid, type BgpSessionsDataGridProps }