"use client" import { DataGridContainer, DataGridScrollArea, DataGridTable, dataGridFeatures, type DataGridFeatures } from "@/components/reui/data-grid" import { useEffect, useMemo } from "react" import { type ColumnDef, useTable, } from "@tanstack/react-table" import { cn } from "@/lib/utils" import { Badge } from "@/components/reui/badge" 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 { RouteIcon } from "lucide-react" export interface OspfRouteRow { id: string dataUnknown?: boolean destination: string type: "O" | "O IA" | "O E1" | "O E2" | "Unknown" cost: number | null nextHop: string via: string serverId: string serverLabel: string area: string } function OspfRouteTypeBadge({ type, count }: { type: OspfRouteRow["type"]; count?: number }) { return {type === "Unknown" ? "Тип неизвестен" : type}{count === undefined ? "" : ": " + count} } interface OspfRoutesDataGridProps { emptyTitle?: string routes: OspfRouteRow[] } function OspfRoutesDataGrid({ routes, emptyTitle }: OspfRoutesDataGridProps) { const columns = useMemo[]>( () => [ { id: "destination", size: 180, accessorKey: "destination", header: ({ column }) => ( ), cell: ({ row }) => {row.original.destination}, meta: { headerTitle: "Назначение", headerClassName: DATA_GRID_CELL_PAD_FIRST, cellClassName: DATA_GRID_CELL_PAD_FIRST, }, }, { id: "type", size: 116, accessorKey: "type", header: ({ column }) => , cell: ({ row }) => ( ), meta: { headerTitle: "Тип", headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD }, }, { id: "cost", size: 80, 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: "nextHop", accessorKey: "nextHop", header: ({ column }) => , cell: ({ row }) => ( {row.original.nextHop} ), meta: { headerTitle: "Следующий хоп", headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD, }, }, { id: "via", size: 120, accessorKey: "via", header: ({ column }) => , cell: ({ row }) => ( {row.original.via} ), meta: { headerTitle: "Интерфейс", headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD, }, }, { id: "serverLabel", accessorKey: "serverLabel", header: ({ column }) => , cell: ({ row }) => {row.original.serverLabel}{row.original.dataUnknown ? " · Неизвестно" : ""}, meta: { headerTitle: "Роутер", headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD, }, }, { id: "area", size: 120, accessorKey: "area", header: ({ column }) => , cell: ({ row }) => ( {row.original.area} ), meta: { headerTitle: "Область", headerClassName: cn(DATA_GRID_CELL_PAD_LAST, "text-right"), cellClassName: cn(DATA_GRID_CELL_PAD_LAST, "text-right"), }, }, ], [], ) const table = useTable({ features: dataGridFeatures, manualPagination: false, autoResetPageIndex: false, initialState: { pagination: { pageIndex: 0, pageSize: 50 }, columnPinning: { start: ["destination"], end: [] } }, data: routes, columns, getRowId: (row) => row.id, }) const { pageIndex, pageSize } = table.state.pagination useEffect(() => { const lastPage = Math.max(0, Math.ceil(routes.length / pageSize) - 1) if (pageIndex > lastPage) table.setPageIndex(lastPage) }, [routes.length, pageIndex, pageSize, table]) if (routes.length === 0) { return ( } title={emptyTitle ?? "Нет OSPF-маршрутов"} className="border-0 py-10" /> ) } return ( 50 || pageSize !== 50} tableClassNames={{ headerRow: "border-b border-border", bodyRow: "group/row hover:bg-muted/30" }} tableLayout={{ dense: true, columnsPinnable: true }} > ) } export { OspfRoutesDataGrid, type OspfRoutesDataGridProps, OspfRouteTypeBadge }