"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 { ActionBadge, ChainBadge } from "@/components/data-grids/firewall-rules-data-grid" import { DataGridShell } from "@/components/data-grids/shared/data-grid-shell" import { DATA_GRID_CONTAINER_CLASS, DATA_GRID_CELL_PAD, DATA_GRID_CELL_PAD_FIRST, DATA_GRID_CELL_PAD_LAST, } from "@/components/data-grids/shared/data-grid-layout" import { cn } from "@/lib/utils" import { PowerIcon, Trash2Icon } from "lucide-react" function ScenarioCell({ enabled, children }: { enabled: boolean; children: React.ReactNode }) { return
{children}
} export interface ScenarioRuleRow { id: string chain: string action: string proto: string src: string dst: string port: string iface: string comment: string enabled: boolean } interface FirewallScenarioRulesDataGridProps { rules: ScenarioRuleRow[] onToggleEnabled: (id: string) => void onMoveUp: (id: string) => void onMoveDown: (id: string) => void onRemove: (id: string) => void } function FirewallScenarioRulesDataGrid({ rules, onToggleEnabled, onMoveUp, onMoveDown, onRemove, }: FirewallScenarioRulesDataGridProps) { const indexedRules = useMemo( () => rules.map((rule, index) => ({ ...rule, _index: index + 1 })), [rules], ) const columns = useMemo[]>( () => [ { id: "index", accessorKey: "_index", header: () => #, enableSorting: false, cell: ({ row }) => ( {row.original._index} ), size: 40, meta: { headerClassName: DATA_GRID_CELL_PAD_FIRST, cellClassName: DATA_GRID_CELL_PAD_FIRST, }, }, { id: "chain", size: 112, accessorKey: "chain", header: () => Цепочка, enableSorting: false, cell: ({ row }) => ( ), meta: { headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD }, }, { id: "action", size: 176, accessorKey: "action", header: () => Действие, enableSorting: false, cell: ({ row }) => , meta: { headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD }, }, { id: "src", size: 176, accessorKey: "src", header: () => Src, enableSorting: false, cell: ({ row }) => ( {row.original.src || "any"} ), meta: { headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD }, }, { id: "dst", size: 176, accessorKey: "dst", header: () => Dst, enableSorting: false, cell: ({ row }) => ( {row.original.dst || "any"} ), meta: { headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD }, }, { id: "port", size: 112, accessorKey: "port", header: () => Порт, enableSorting: false, cell: ({ row }) => ( {row.original.port || "—"} ), meta: { headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD }, }, { id: "iface", size: 160, accessorKey: "iface", header: () => Iface, enableSorting: false, cell: ({ row }) => ( {row.original.iface || "—"} ), meta: { headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD }, }, { id: "comment", size: 192, accessorKey: "comment", header: () => Комментарий, enableSorting: false, cell: ({ row }) => ( {row.original.comment || "—"} ), meta: { headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD }, }, { id: "actions", size: 208, header: () => null, enableSorting: false, cell: ({ row }) => { const index = row.original._index - 1 return (
) }, meta: { headerClassName: DATA_GRID_CELL_PAD_LAST, cellClassName: DATA_GRID_CELL_PAD_LAST }, }, ], [onMoveDown, onMoveUp, onRemove, onToggleEnabled, rules.length], ) const table = useTable({ features: dataGridFeatures, manualPagination: false, autoResetPageIndex: false, initialState: { pagination: { pageIndex: 0, pageSize: 50 }, columnPinning: { start: ["index", "chain"], end: [] } }, manualSorting: true, data: indexedRules, columns, getRowId: (row) => row.id, }) const { pageIndex, pageSize } = table.state.pagination useEffect(() => { const lastPage = Math.max(0, Math.ceil(rules.length / pageSize) - 1) if (pageIndex > lastPage) table.setPageIndex(lastPage) }, [rules.length, pageIndex, pageSize, table]) return ( 50 || pageSize !== 50} tableLayout={{ dense: true, columnsPinnable: true }} tableClassNames={{ bodyRow: cn("group/row text-xs", "hover:bg-muted/20 transition-colors"), }} > ) } export { FirewallScenarioRulesDataGrid, type FirewallScenarioRulesDataGridProps }