"use client" import { dataGridFeatures, type DataGridFeatures } from "@/components/reui/data-grid" import { useMemo } from "react" import type {OspfOptimizerObserved} from "@mmapp/contracts" import { type ColumnDef, useTable, } from "@tanstack/react-table" 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" function describeObserved(metric:OspfOptimizerObserved["ping"]|undefined,unit:string){ if(!metric || metric.value===null)return "Измерение: —" const source=metric.source==="speed-probe"?"Проба":"Трафик интерфейса" const date=metric.measuredAt?new Date(metric.measuredAt).toLocaleString("ru-RU"):"дата неизвестна" return source+": "+metric.value+" "+unit+" · "+date } export interface OspfPreviewInterfaceRow { observed?: OspfOptimizerObserved id: string interface: string currentCost: number optimalCost: number score: number pingMs: number dlMbps: number ulMbps: number } interface RouteOptimizerOspfPreviewDataGridProps { rows: OspfPreviewInterfaceRow[] error?: string | null loading?: boolean } function RouteOptimizerOspfPreviewDataGrid({ rows, error, loading, }: RouteOptimizerOspfPreviewDataGridProps) { const columns = useMemo[]>( () => [ { id: "interface", accessorKey: "interface", header: ({ column }) => ( ), cell: ({ row }) => {row.original.interface}, meta: { headerTitle: "Интерфейс", headerClassName: DATA_GRID_CELL_PAD_FIRST, cellClassName: DATA_GRID_CELL_PAD_FIRST, }, }, { id: "cost", accessorKey: "currentCost", header: ({ column }) => , cell: ({ row }) => { const r = row.original return ( {r.currentCost} {" → "} {r.optimalCost} ) }, meta: { headerTitle: "Cost", headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD }, }, { id: "score", accessorKey: "score", header: ({ column }) => , cell: ({ row }) => {row.original.score}, meta: { headerTitle: "Score", headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD }, }, { id: "pingMs", accessorKey: "pingMs", header: ({ column }) => , cell: ({ row }) =>
{row.original.pingMs}ms

{describeObserved(row.original.observed?.ping,"мс")}

, meta: { headerTitle: "Ping модели", headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD }, }, { id: "speed", header: () => Speed (dl/ul) · модель, enableSorting: false, cell: ({ row }) => { const r = row.original return ( ↓{r.dlMbps} / ↑{r.ulMbps}↓ {describeObserved(r.observed?.dl,"Мбит/с")}
↑ {describeObserved(r.observed?.ul,"Мбит/с")}
) }, meta: { headerClassName: DATA_GRID_CELL_PAD_LAST, cellClassName: DATA_GRID_CELL_PAD_LAST }, }, ], [], ) const table = useTable({ features: dataGridFeatures, manualPagination: true, data: rows, columns, getRowId: (row) => row.id, }) if (error && rows.length === 0) { return (

Ошибка preview: {error}

) } if (!loading && rows.length === 0) { return (