Refactored multiple components, including PanelCard, SettingsCard, and DataGridShell, to replace Card with Frame for better organization and presentation. Enhanced the DataGridToolbar to support optional ReUI filters and improved the overall structure of the KPI stat grid. Updated .gitignore to include .env.local for local environment configurations, ensuring better management of environment variables.
87 lines
2.4 KiB
TypeScript
87 lines
2.4 KiB
TypeScript
import type { ReactNode } from 'react'
|
|
import {
|
|
Frame,
|
|
FrameDescription,
|
|
FrameHeader,
|
|
FramePanel,
|
|
FrameTitle,
|
|
} from '@/components/reui/frame'
|
|
import { Skeleton } from '@evobgp/ui/components/skeleton'
|
|
import { PageHeader } from '@/components/page-header'
|
|
import { KpiStatGrid, type KpiStatCardData } from './kpi-stat-grid'
|
|
|
|
export type OpsKpiCard = KpiStatCardData
|
|
|
|
interface OpsDashboardProps {
|
|
title?: string
|
|
description?: string
|
|
kpiCards: OpsKpiCard[]
|
|
charts: ReactNode
|
|
queue: ReactNode
|
|
queueTitle?: string
|
|
queueDescription?: string
|
|
isLoading?: boolean
|
|
}
|
|
|
|
const rootClassName =
|
|
'text-foreground @container flex w-full flex-col gap-2 md:gap-3'
|
|
|
|
function OpsDashboardSkeleton() {
|
|
return (
|
|
<div className={rootClassName}>
|
|
<header className="px-1">
|
|
<Skeleton className="h-7 w-56" />
|
|
<Skeleton className="mt-2 h-4 w-80 max-w-full" />
|
|
</header>
|
|
<KpiStatGrid cards={[]} isLoading skeletonCount={4} />
|
|
<div className="grid gap-2 @3xl:grid-cols-2">
|
|
<Skeleton className="h-64 w-full rounded-xl" />
|
|
<Skeleton className="h-64 w-full rounded-xl" />
|
|
</div>
|
|
<Skeleton className="h-48 w-full rounded-xl" />
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export function OpsDashboard({
|
|
title = 'Панель управления',
|
|
description = 'Обзор модулей, сети, задач и состояния плоскости управления',
|
|
kpiCards,
|
|
charts,
|
|
queue,
|
|
queueTitle = 'Требуют внимания',
|
|
queueDescription = 'Проблемы BGP, сбои задач и офлайн-спикеры',
|
|
isLoading = false,
|
|
}: OpsDashboardProps) {
|
|
if (isLoading) {
|
|
return <OpsDashboardSkeleton />
|
|
}
|
|
|
|
return (
|
|
<div className={rootClassName}>
|
|
<PageHeader title={title} description={description} />
|
|
|
|
<section aria-label="Ключевые метрики">
|
|
<KpiStatGrid cards={kpiCards} skeletonCount={4} />
|
|
</section>
|
|
|
|
<section
|
|
aria-label="Аналитика"
|
|
className="grid min-w-0 items-start gap-2 @3xl:grid-cols-2"
|
|
>
|
|
{charts}
|
|
</section>
|
|
|
|
<section aria-label={queueTitle}>
|
|
<Frame dense spacing="sm" className="w-full">
|
|
<FrameHeader>
|
|
<FrameTitle>{queueTitle}</FrameTitle>
|
|
<FrameDescription>{queueDescription}</FrameDescription>
|
|
</FrameHeader>
|
|
<FramePanel>{queue}</FramePanel>
|
|
</Frame>
|
|
</section>
|
|
</div>
|
|
)
|
|
}
|