"use client" import { useMemo, useState } from "react" import { type ColumnDef, getCoreRowModel, getSortedRowModel, useReactTable, } from "@tanstack/react-table" import type { FullRoute } from "@/lib/route-optimizer-data" import { Flag } from "@/components/flag" import { cn } from "@/lib/utils" import { Button } from "@/components/ui/button" 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 { ArrowRightIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react" function Chip({ children, color }: { children: React.ReactNode; color?: string }) { return ( {children} ) } function ProbChip({ prob, best }: { prob: number; best?: boolean }) { return ( {prob}% ) } function ConfChip({ conf }: { conf: string }) { const map: Record = { HIGH: "bg-sky-500/10 text-sky-600 dark:text-sky-400 border-sky-500/20", MEDIUM: "bg-amber-500/10 text-amber-600 dark:text-amber-400 border-amber-500/20", LOW: "bg-red-500/10 text-red-600 dark:text-red-400 border-red-500/20", } return {conf} } interface RouteOptimizerFullRoutesDataGridProps { routes: FullRoute[] bestId?: string } function RouteOptimizerFullRoutesDataGrid({ routes, bestId, }: RouteOptimizerFullRoutesDataGridProps) { const [expanded, setExpanded] = useState(false) const visibleRoutes = expanded ? routes : routes.slice(0, 5) const indexed = useMemo( () => visibleRoutes.map((r, index) => ({ ...r, _index: index })), [visibleRoutes], ) const columns = useMemo[]>( () => [ { id: "index", header: () => # Маршрут, enableSorting: false, cell: ({ row }) => { const isBest = row.original.id === bestId || row.original._index === 0 return (
{row.original._index + 1} {isBest && ( Лучший )}
) }, meta: { headerClassName: DATA_GRID_CELL_PAD_FIRST, cellClassName: DATA_GRID_CELL_PAD_FIRST }, }, { id: "wanJh", header: () => WAN → JH, enableSorting: false, cell: ({ row }) => { const r = row.original return (
{r.wan.name}
{r.jh.label}
{r.hw.pingMs} мс · ↓{r.hw.dlMbps} ↑{r.hw.ulMbps}
) }, meta: { headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD }, }, { id: "jhExit", header: () => JH → Exit, enableSorting: false, cell: ({ row }) => { const r = row.original return (
{r.exit.label} ({r.exit.site})
{r.je.pingMs} мс · ↓{r.je.dlMbps} ↑{r.je.ulMbps}
) }, meta: { headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD }, }, { id: "totalPing", accessorFn: (row) => row.hw.pingMs + row.je.pingMs, header: ({ column }) => ( ), cell: ({ row }) => { const totalPing = row.original.hw.pingMs + row.original.je.pingMs return ( {totalPing} мс ) }, meta: { headerTitle: "Ping (итого)", headerClassName: cn(DATA_GRID_CELL_PAD, "text-center"), cellClassName: cn(DATA_GRID_CELL_PAD, "text-center"), }, }, { id: "bw", header: () => ( BW (мин) ), enableSorting: false, cell: ({ row }) => { const r = row.original const minDl = Math.min(r.hw.dlMbps, r.je.dlMbps) const minUl = Math.min(r.hw.ulMbps, r.je.ulMbps) return (
↓{minDl}
↑{minUl}
) }, meta: { headerClassName: cn(DATA_GRID_CELL_PAD, "text-center"), cellClassName: cn(DATA_GRID_CELL_PAD, "text-center"), }, }, { id: "score", accessorKey: "score", header: ({ column }) => ( ), cell: ({ row }) => ( {row.original.score} ), meta: { headerTitle: "Score", headerClassName: cn(DATA_GRID_CELL_PAD, "text-center"), cellClassName: cn(DATA_GRID_CELL_PAD, "text-center"), }, }, { id: "prob", accessorKey: "probabilityOptimal", header: ({ column }) => ( ), cell: ({ row }) => { const isBest = row.original.id === bestId || row.original._index === 0 return (
) }, meta: { headerTitle: "P(opt)", headerClassName: cn(DATA_GRID_CELL_PAD, "text-center"), cellClassName: cn(DATA_GRID_CELL_PAD, "text-center"), }, }, { id: "confidence", accessorKey: "confidence", header: ({ column }) => ( ), cell: ({ row }) => (
), meta: { headerTitle: "Conf.", headerClassName: DATA_GRID_CELL_PAD_LAST, cellClassName: cn(DATA_GRID_CELL_PAD_LAST, "text-center"), }, }, ], [bestId], ) const table = useReactTable({ data: indexed, columns, getCoreRowModel: getCoreRowModel(), getSortedRowModel: getSortedRowModel(), getRowId: (row) => row.id, }) return (
{routes.length > 5 && ( )}
) } export { RouteOptimizerFullRoutesDataGrid, type RouteOptimizerFullRoutesDataGridProps }