"use client" import { useMemo } from "react" import { type ColumnDef, getCoreRowModel, 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, DATA_GRID_CELL_PAD_LAST, } 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 { NetworkIcon } from "lucide-react" export interface OspfNeighborRow { id: string localRouter: string localLabel: string localIface: string remoteRouter: string remoteLabel: string remoteRouterId: string area: string state: "Full" | "2-Way" | "ExStart" | "Down" cost: number uptime: string priority: number } function stateClass(state: OspfNeighborRow["state"]) { if (state === "Full") return "bg-[var(--status-online-bg)] text-[var(--status-online-fg)] border-current/25" if (state === "2-Way") return "bg-[var(--status-degraded-bg)] text-[var(--status-degraded-fg)] border-current/25" return "bg-[var(--status-offline-bg)] text-[var(--status-offline-fg)] border-current/25" } interface OspfNeighborsDataGridProps { neighbors: OspfNeighborRow[] highlightRouterId?: string | null selectedRouterId?: string | null onHighlight?: (routerId: string | null) => void onSelect?: (routerId: string | null) => void } function OspfNeighborsDataGrid({ neighbors, highlightRouterId, selectedRouterId, onHighlight, onSelect, }: OspfNeighborsDataGridProps) { const columns = useMemo[]>( () => [ { id: "localLabel", accessorKey: "localLabel", header: ({ column }) => ( ), cell: ({ row }) => ( {row.original.localLabel} ), meta: { headerTitle: "Роутер", headerClassName: DATA_GRID_CELL_PAD_FIRST, cellClassName: DATA_GRID_CELL_PAD_FIRST, }, }, { id: "localIface", accessorKey: "localIface", header: ({ column }) => , cell: ({ row }) => ( {row.original.localIface} ), meta: { headerTitle: "Интерфейс", headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD, }, }, { id: "remote", header: () => ( Сосед (Router ID) ), enableSorting: false, cell: ({ row }) => { const n = row.original return (
{n.remoteLabel !== n.remoteRouterId ? n.remoteLabel : n.remoteRouterId} {n.remoteLabel !== n.remoteRouterId && ( {n.remoteRouterId} )}
) }, meta: { headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD }, }, { id: "area", accessorKey: "area", header: ({ column }) => , cell: ({ row }) => ( {row.original.area} ), meta: { headerTitle: "Область", headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD, }, }, { id: "state", accessorKey: "state", header: ({ column }) => , cell: ({ row }) => ( {row.original.state} ), meta: { headerTitle: "Состояние", headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD, }, }, { id: "cost", accessorKey: "cost", header: ({ column }) => , cell: ({ row }) => ( {row.original.cost} ), meta: { headerTitle: "Cost", headerClassName: DATA_GRID_CELL_PAD, cellClassName: cn(DATA_GRID_CELL_PAD, "text-center"), }, }, { 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: "priority", accessorKey: "priority", header: ({ column }) => , cell: ({ row }) => ( {row.original.priority} ), meta: { headerTitle: "Prio", headerClassName: DATA_GRID_CELL_PAD_LAST, cellClassName: cn(DATA_GRID_CELL_PAD_LAST, "text-center"), }, }, ], [], ) const rowSelection = useMemo(() => { if (!selectedRouterId) return {} const match = neighbors.find( (n) => n.localRouter === selectedRouterId || n.remoteRouter === selectedRouterId, ) return match ? { [match.id]: true } : {} }, [neighbors, selectedRouterId]) const table = useReactTable({ data: neighbors, columns, getCoreRowModel: getCoreRowModel(), getSortedRowModel: getSortedRowModel(), getRowId: (row) => row.id, enableRowSelection: true, state: { rowSelection }, }) if (neighbors.length === 0) { return ( } title="Нет OSPF-соседей" className="border-0 py-10" /> ) } return ( { onSelect?.(selectedRouterId === row.localRouter ? null : row.localRouter) }} tableClassNames={{ headerRow: "border-b border-border", bodyRow: cn( "group/row cursor-pointer", "data-[state=selected]:bg-primary/5", highlightRouterId && "[&:hover]:bg-muted/30", ), }} tableLayout={{ dense: true }} /> ) } export { OspfNeighborsDataGrid, type OspfNeighborsDataGridProps }