"use client" // ReUI PRO solution-dev-ops-2: Frame-led grid, toolbar and display settings. // https://reui.io/preview/base/solution-dev-ops-2 import { useEffect, useMemo, useState, type ReactNode } from "react" import { useTable, type ColumnDef } from "@tanstack/react-table" import { elementScroll, observeElementRect, observeElementOffset } from "@tanstack/react-virtual" import type { LogEntry } from "@mmapp/contracts" import { CopyIcon, Columns3Icon, WrapTextIcon } from "lucide-react" import { toast } from "sonner" import { DataGrid, DataGridContainer, DataGridTableVirtual, DataGridColumnVisibility, dataGridFeatures, type DataGridFeatures } from "@/components/reui/data-grid" import { Frame, FrameHeader, FrameTitle, FrameDescription, FramePanel } from "@/components/reui/frame" import { Button } from "@/components/ui/button" import { DATA_GRID_LABELS_RU } from "@/lib/data-grid-labels-ru" import { HighlightMessage, LevelBadge, formatLogTime } from "./log-presentation" export function LogsGrid({ entries, loading, total, search, toolbar, onSelect, onPause, hasMore, fetchingMore, loadMore, reset }: { entries: LogEntry[]; loading: boolean; total: number | null; search: string; toolbar: ReactNode; onSelect: (entry: LogEntry) => void; onPause: () => void; hasMore: boolean; fetchingMore: boolean; loadMore: () => void; reset: () => void }) { const [wrap, setWrap] = useState(false) const [narrow, setNarrow] = useState(false) useEffect(() => { const mq = window.matchMedia("(max-width: 767px)") const update = () => setNarrow(mq.matches) queueMicrotask(update); mq.addEventListener("change", update) return () => mq.removeEventListener("change", update) }, []) const columns = useMemo[]>(() => [ { accessorKey: "effectiveAt", header: "Время", size: 165, cell: ({ row }) => {formatLogTime(row.original.effectiveAt)}{row.original.timeKind === "receipt" && *} }, { accessorKey: "serverName", header: "Устройство", size: 150, cell: ({ row }) => {row.original.serverName} }, { accessorKey: "level", header: "Уровень", size: 165, cell: ({ row }) => }, { accessorKey: "topics", header: "Topics", size: 180, cell: ({ row }) => {row.original.topics.join(", ")} }, { accessorKey: "message", header: narrow ? "Событие" : "Сообщение", size: narrow ? 300 : 600, enableHiding: false, cell: ({ row }) => }, { id: "copy", header: "", size: 46, enableHiding: false, cell: ({ row }) => }, ], [wrap, narrow, search, onSelect]) const table = useTable({ features: dataGridFeatures, data: entries, columns, getRowId: row => row.id, manualPagination: true, rowCount: entries.length }) useEffect(() => { table.setColumnVisibility({ effectiveAt: !narrow, serverName: !narrow, level: !narrow, topics: !narrow, copy: !narrow }) }, [narrow, table]) return

Событий за выбранный период нет

} tableClassNames={{ edgeCell: "first:ps-(--frame-panel-header-px) last:pe-(--frame-panel-header-px)" }}>
Журнал событийЗагружено {entries.length.toLocaleString("ru-RU")}{total !== null ? ` · Найдено ${total.toLocaleString("ru-RU")}` : ""}
Колонки} />
{toolbar}
{ if ((event.target as HTMLElement).scrollTop > 16) onPause() }}> element.getBoundingClientRect().height }} />
* Использовано время получения. Часовой пояс отображения: браузер.{hasMore && }
}