Files
MikrotikManager/components/data-grids/probes-speed-probes-data-grid.tsx
T

174 lines
5.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client"
import { dataGridFeatures, type DataGridFeatures } from "@/components/reui/data-grid"
import { useMemo, useEffect } from "react"
import {
type ColumnDef,
useTable,
} 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 { ClockIcon } from "lucide-react"
import type {SpeedProbeApiRow} from "@/lib/probe-schedule-response"
export type {SpeedProbeApiRow} from "@/lib/probe-schedule-response"
interface ProbesSpeedProbesDataGridProps {
rows: SpeedProbeApiRow[]
serverName: (id: string) => string
}
function ProbesSpeedProbesDataGrid({ rows, serverName }: ProbesSpeedProbesDataGridProps) {
const columns = useMemo<ColumnDef<DataGridFeatures, SpeedProbeApiRow>[]>(
() => [
{
id: "src",
header: ({ column }) => <DataGridSortHeader column={column} title="Источник" className="ml-1" />,
accessorFn: (row) => row.srcServerId,
cell: ({ row }) => {
const r = row.original
return (
<span className="truncate font-mono text-xs block">
{serverName(r.srcServerId)}
{r.srcInterface ? ` · ${r.srcInterface}` : ""}
</span>
)
},
meta: {
headerTitle: "Источник",
headerClassName: DATA_GRID_CELL_PAD_FIRST,
cellClassName: DATA_GRID_CELL_PAD_FIRST,
},
},
{
id: "dst",
accessorFn: (row) => row.dstServerId,
header: ({ column }) => <DataGridSortHeader column={column} title="Назначение" />,
cell: ({ row }) => {
const r = row.original
return (
<span className="truncate font-mono text-xs block">
{serverName(r.dstServerId)}
{r.dstInterface ? ` · ${r.dstInterface}` : ""}
</span>
)
},
meta: {
headerTitle: "Назначение",
headerClassName: DATA_GRID_CELL_PAD,
cellClassName: DATA_GRID_CELL_PAD,
},
},
{
id: "protocol",
accessorKey: "protocol",
header: ({ column }) => <DataGridSortHeader column={column} title="Протокол" />,
cell: ({ row }) => <span className="text-xs">{row.original.protocol.toUpperCase()}</span>,
meta: {
headerTitle: "Протокол",
headerClassName: DATA_GRID_CELL_PAD,
cellClassName: DATA_GRID_CELL_PAD,
},
},
{
id: "durationSec",
accessorKey: "durationSec",
header: ({ column }) => <DataGridSortHeader column={column} title="Сек" />,
cell: ({ row }) => <span className="font-mono text-xs">{row.original.durationSec}s</span>,
meta: {
headerTitle: "Сек",
headerClassName: DATA_GRID_CELL_PAD,
cellClassName: DATA_GRID_CELL_PAD,
},
},
{
id: "enabled",
accessorKey: "enabled",
header: ({ column }) => <DataGridSortHeader column={column} title="Вкл" />,
cell: ({ row }) => <span className="text-xs">{row.original.enabled ? "да" : "нет"}</span>,
meta: {
headerTitle: "Вкл",
headerClassName: DATA_GRID_CELL_PAD,
cellClassName: DATA_GRID_CELL_PAD,
},
},
{
id: "lastRunAt",
accessorKey: "lastRunAt",
header: ({ column }) => <DataGridSortHeader column={column} title="Последний запуск" />,
cell: ({ row }) => {
const r = row.original
return (
<span className="text-xs text-muted-foreground truncate block">
{r.lastRunAt ?? "—"}
{r.lastStatus === "done" && (
<span className="text-emerald-600 dark:text-emerald-400 ml-1">
TX: {r.lastTxAvgMbps==null?"неизвестно":r.lastTxAvgMbps.toFixed(1)+" Мбит/с"} · RX: {r.lastRxAvgMbps==null?"неизвестно":r.lastRxAvgMbps.toFixed(1)+" Мбит/с"}
</span>
)}
{r.lastStatus === "error" && r.lastError && (
<span className="text-destructive ml-1 truncate">{r.lastError}</span>
)}
</span>
)
},
meta: {
headerTitle: "Последний запуск",
headerClassName: DATA_GRID_CELL_PAD_LAST,
cellClassName: DATA_GRID_CELL_PAD_LAST,
},
},
],
[serverName],
)
const table = useTable({
features: dataGridFeatures,
manualPagination: false,
autoResetPageIndex: false,
initialState: { pagination: { pageIndex: 0, pageSize: 50 } },
data: rows,
columns,
getRowId: (row) => row.id,
})
const { pageIndex, pageSize } = table.state.pagination
useEffect(() => {
const lastPage = Math.max(0, Math.ceil(rows.length / pageSize) - 1)
if (pageIndex > lastPage) table.setPageIndex(lastPage)
}, [rows.length, pageSize, pageIndex, table])
if (rows.length === 0) {
return (
<EmptyState
icon={<ClockIcon className="size-4" />}
title="Нет записей speed-test"
description="Добавьте пробы в разделе мониторинга."
className="border-0 py-10"
/>
)
}
return (
<DataGridShell
table={table}
recordCount={rows.length}
pagination={rows.length > 50 || table.state.pagination.pageSize !== 50}
tableClassNames={{
headerRow: "border-b border-border",
bodyRow: cn("group/row", "[&[data-disabled=true]]:opacity-50"),
}}
/>
)
}
export { ProbesSpeedProbesDataGrid, type ProbesSpeedProbesDataGridProps }