Files
EvoBGP/apps/web/src/routes/_auth/dashboard.tsx
T
Denozordec dc803bcb34
quality / commitlint (push) Skipped
quality / changes (push) Successful in 9s
quality / docker-check (push) Skipped
quality / openapi (push) Successful in 46s
quality / web (push) Successful in 1m16s
quality / go (push) Successful in 2m42s
quality / bird2 (push) Successful in 16s
CD / quality (push) Successful in 5m19s
CD / publish (push) Successful in 7m19s
refactor(web): remove deprecated dashboard components and enhance KPI grid
- Deleted unused components: `DashboardActivityTimeline`, `DashboardFramePanel`, `DashboardModulesGrid`, `DashboardRecentJobsGrid`, and `DashboardRecentRevisionsGrid` to streamline the dashboard.
- Updated `DashboardKpiGrid` to improve KPI display logic, including progress indicators and enhanced badge functionality.
- Refactored `DashboardNetworkHealth` to provide better status representation based on loading states and network conditions.
- Introduced new properties for KPI cards to support progress tracking and improved visual feedback.

This cleanup aims to enhance performance and maintainability of the dashboard while providing a better user experience.
2026-08-31 10:15:59 +07:00

108 lines
3.8 KiB
TypeScript

import { createFileRoute } from '@tanstack/react-router'
import { useQueries, useQuery } from '@tanstack/react-query'
import { RefreshCw } from 'lucide-react'
import { useState } from 'react'
import { Button } from '@evobgp/ui/components/button'
import { buildDashboardKpiCards } from '@/components/dashboard/dashboard-kpi-grid'
import { DashboardNetworkHealth } from '@/components/dashboard/dashboard-network-health'
import { DashboardOperationsBreakdown } from '@/components/dashboard/dashboard-operations-breakdown'
import { DashboardQuickLinks } from '@/components/dashboard/dashboard-quick-links'
import { OpsDashboard } from '@/components/reui-kit'
import { chartPanelGridClassName } from '@/lib/ui-surface'
import {
overviewJobsQueryOptions,
overviewModulesQueryOptions,
overviewPeersQueryOptions,
overviewSpeakersQueryOptions,
} from '@/queries/overview'
import { settingsQueryOptions } from '@/queries/settings'
export const Route = createFileRoute('/_auth/dashboard')({
component: DashboardComponent,
})
function parseShowQuickActions(value: unknown): boolean {
if (value === false || value === 0 || value === 'false' || value === '0') return false
return true
}
/**
* Dashboard — KPI infographic + Quick Actions + charts (no list duplicates).
* @see https://reui.io/preview/base/dashboard-1
* @see https://reui.io/preview/base/stats-12
* @see https://reui.io/preview/base/stats-4
* @see https://reui.io/preview/base/card-12
* @see https://reui.io/preview/base/chart-27
*/
function DashboardComponent() {
const [lastUpdated, setLastUpdated] = useState<Date | null>(null)
const settingsQ = useQuery(settingsQueryOptions())
const showQuickActions = parseShowQuickActions(settingsQ.data?.ui_show_quick_actions)
const results = useQueries({
queries: [
overviewModulesQueryOptions(),
overviewPeersQueryOptions(),
overviewSpeakersQueryOptions(),
overviewJobsQueryOptions(),
],
})
const [modulesQ, peersQ, speakersQ, jobsQ] = results
const initialLoading =
modulesQ.isLoading || peersQ.isLoading || speakersQ.isLoading || jobsQ.isLoading
const refreshing = results.some((r) => r.isFetching && !r.isLoading)
if (!lastUpdated && !initialLoading && results.every((r) => r.isSuccess || r.isError)) {
setTimeout(() => setLastUpdated(new Date()), 0)
}
function refetchAll() {
setLastUpdated(null)
results.forEach((r) => r.refetch())
}
const modules = modulesQ.data?.items ?? []
const peers = peersQ.data?.items ?? []
const speakers = speakersQ.data?.items ?? []
const jobs = jobsQ.data?.items ?? []
const kpiCards = buildDashboardKpiCards({ modules, peers, speakers, jobs })
return (
<OpsDashboard
title="Обзор"
description={
lastUpdated
? `Состояние панели управления EvoBGP. Обновлено: ${lastUpdated.toLocaleTimeString('ru-RU')}`
: 'Состояние панели управления EvoBGP.'
}
headerActions={
<Button variant="outline" size="sm" onClick={refetchAll} disabled={refreshing}>
<RefreshCw className={refreshing ? 'animate-spin' : ''} />
Обновить
</Button>
}
kpiCards={kpiCards}
isLoading={initialLoading}
afterKpi={showQuickActions ? <DashboardQuickLinks /> : null}
charts={
<div className={chartPanelGridClassName}>
<DashboardNetworkHealth
peers={peers}
speakers={speakers}
jobs={jobs}
loading={refreshing && peers.length === 0 && speakers.length === 0}
/>
<DashboardOperationsBreakdown
jobs={jobs}
modules={modules}
loading={refreshing && jobs.length === 0 && modules.length === 0}
/>
</div>
}
/>
)
}