Files
MikrotikManager/components/statistics/breakdown-dashboard.tsx
T
DenozordecandCursor 5bb9066be8
Docker images / prepare-release (push) Successful in 10s
Docker images / backend-test (push) Successful in 2m23s
Docker images / frontend-image (push) Successful in 3m30s
Docker images / updater-image (push) Successful in 52s
Docker images / backend-image (push) Successful in 3m8s
Docker images / notify-webhook (push) Skipped
Docker images / publish-release (push) Successful in 14s
feat(statistics): добавить BI-разрез и сводную матрицу
Сопоставить клиентов с ifIndex как на карте трафика, чтобы KPI пользователей не обнулялся. На экране — разрез остальных измерений и сводная матрица.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-10 16:07:25 +07:00

58 lines
1.8 KiB
TypeScript

"use client"
import { Frame, FrameHeader, FramePanel, FrameTitle } from "@/components/reui/frame"
import {
StatisticsBreakdownDataGrid,
type StatisticsSliceKind,
} from "@/components/data-grids/statistics-breakdown-data-grid"
import { STATISTICS_DIMS } from "@/lib/statistics-dims"
import type { StatisticsBreakdownRow, StatisticsDto } from "@mmapp/contracts/statistics"
const MINI_ROWS = 12
function rowsForKind(data: StatisticsDto, kind: StatisticsSliceKind): StatisticsBreakdownRow[] {
if (kind === "users") return data.users
if (kind === "servers") return data.servers
if (kind === "interfaces") return data.interfaces
if (kind === "countries") return data.countries
if (kind === "services") return data.services
return data.asns
}
export function BreakdownDashboard({
data,
hidden,
selectedIdFor,
onRowClick,
isLoading,
}: {
data: StatisticsDto
hidden: Set<StatisticsSliceKind>
selectedIdFor: (kind: StatisticsSliceKind) => string | undefined
onRowClick: (kind: StatisticsSliceKind, row: StatisticsBreakdownRow) => void
isLoading?: boolean
}) {
const dims = STATISTICS_DIMS.filter((d) => !hidden.has(d.id))
return (
<div className="grid grid-cols-1 gap-4 p-4 md:grid-cols-2">
{dims.map((d) => (
<Frame key={d.id} dense>
<FrameHeader className="border-b">
<FrameTitle>{d.label}</FrameTitle>
</FrameHeader>
<FramePanel className="max-h-80 overflow-auto p-0">
<StatisticsBreakdownDataGrid
rows={rowsForKind(data, d.id).slice(0, MINI_ROWS)}
kind={d.id}
selectedId={selectedIdFor(d.id)}
onRowClick={(row) => onRowClick(d.id, row)}
isLoading={isLoading}
density="mini"
/>
</FramePanel>
</Frame>
))}
</div>
)
}