From dfc33dcb99d678be97e61e1158c64311d8c31721 Mon Sep 17 00:00:00 2001 From: Denozordec Date: Tue, 18 Aug 2026 16:03:52 +0700 Subject: [PATCH] refactor(web): streamline dashboard and tab components for improved layout Refactored various dashboard components and tab structures to enhance layout and responsiveness. Adjusted class names to include 'min-w-0' for better overflow handling and improved alignment. Updated the ChartDonutMetric to include a tooltip for better data representation. Simplified the DashboardRecentJobsGrid and DashboardRecentRevisionsGrid by replacing DataGridSection with DataGridShell for consistency. Enhanced the OpsDashboard layout for better clarity and usability. --- .../analytics/chart-donut-metric.tsx | 3 + apps/web/src/components/badge-tabs.tsx | 2 +- .../dashboard-operations-breakdown.tsx | 56 +++++-------------- .../dashboard/dashboard-recent-jobs-grid.tsx | 9 +-- .../dashboard-recent-revisions-grid.tsx | 9 +-- .../src/components/reui-kit/ops-dashboard.tsx | 32 ++++------- apps/web/src/routes/_auth/dashboard.tsx | 17 +++--- packages/ui/src/components/tabs.tsx | 17 +++--- 8 files changed, 54 insertions(+), 91 deletions(-) diff --git a/apps/web/src/components/analytics/chart-donut-metric.tsx b/apps/web/src/components/analytics/chart-donut-metric.tsx index f6e283a..126cd3c 100644 --- a/apps/web/src/components/analytics/chart-donut-metric.tsx +++ b/apps/web/src/components/analytics/chart-donut-metric.tsx @@ -2,6 +2,8 @@ import { Cell, Label, Pie, PieChart } from 'recharts' import { ChartContainer, + ChartTooltip, + ChartTooltipContent, type ChartConfig, } from '@evobgp/ui/components/chart' import { cn } from '@evobgp/ui/lib/utils' @@ -43,6 +45,7 @@ export function ChartDonutMetric({
+ } /> diff --git a/apps/web/src/components/dashboard/dashboard-operations-breakdown.tsx b/apps/web/src/components/dashboard/dashboard-operations-breakdown.tsx index 620389b..8965ca7 100644 --- a/apps/web/src/components/dashboard/dashboard-operations-breakdown.tsx +++ b/apps/web/src/components/dashboard/dashboard-operations-breakdown.tsx @@ -3,13 +3,16 @@ import { useMemo, useState } from 'react' import { ChartDonutMetric } from '@/components/analytics/chart-donut-metric' import { AnalyticsSegmentControl } from '@/components/analytics/analytics-segment-control' import { PanelCard } from '@/components/panel-card' -import { Separator } from '@evobgp/ui/components/separator' import { jobStatusBreakdown, moduleTypeBreakdown } from '@/lib/metrics' import type { JobRow, ModuleRow } from '@/types/api' type FlowMode = 'jobs' | 'modules' -/** chart-13 inspired donut breakdown (Card surface). */ +/** + * Donut distribution — chart-27 DNA: Frame + one legend (inside ChartDonutMetric). + * @see https://reui.io/preview/base/chart-27 + * @see https://reui.io/docs/components/base/frame + */ export function DashboardOperationsBreakdown({ jobs, modules, @@ -32,7 +35,7 @@ export function DashboardOperationsBreakdown({ return ( } - className="h-full" + className="min-w-0" + contentClassName="px-5 py-4" > -
- {loading ? ( -
- Загрузка… -
- ) : ( - <> - - {slices.length > 0 ? ( -
    - {slices.map((slice, index) => { - const pct = total > 0 ? ((slice.count / total) * 100).toFixed(1) : '0' - return ( -
  • -
    -
    - - {slice.label} -
    - {slice.count} - - {pct}% - -
    - {index < slices.length - 1 ? : null} -
  • - ) - })} -
- ) : null} - - )} -
+ {loading ? ( +
+ Загрузка… +
+ ) : ( + + )}
) } diff --git a/apps/web/src/components/dashboard/dashboard-recent-jobs-grid.tsx b/apps/web/src/components/dashboard/dashboard-recent-jobs-grid.tsx index fd25a31..71b160c 100644 --- a/apps/web/src/components/dashboard/dashboard-recent-jobs-grid.tsx +++ b/apps/web/src/components/dashboard/dashboard-recent-jobs-grid.tsx @@ -2,7 +2,7 @@ import { ColumnDef } from '@tanstack/react-table' import { useMemo } from 'react' import { DataGridPrimaryCell } from '@/components/data-grid-cell' -import { DataGridSection } from '@/components/data-grid-shell' +import { DataGridShell } from '@/components/data-grid-shell' import { StatusBadge } from '@/components/status-badge' import { DataGridColumnHeader } from '@/components/reui/data-grid/data-grid-column-header' import { DATA_GRID_DENSE_LAYOUT } from '@/lib/data-grid-defaults' @@ -49,7 +49,7 @@ export function DashboardRecentJobsGrid({ [nameById], ) - const { table, globalFilter, setGlobalFilter, filteredCount } = useClientDataGrid({ + const { table, filteredCount } = useClientDataGrid({ data, columns, getSearchText: (row) => { @@ -63,16 +63,13 @@ export function DashboardRecentJobsGrid({ }) return ( - ) } diff --git a/apps/web/src/components/dashboard/dashboard-recent-revisions-grid.tsx b/apps/web/src/components/dashboard/dashboard-recent-revisions-grid.tsx index b63718e..3eeb9f6 100644 --- a/apps/web/src/components/dashboard/dashboard-recent-revisions-grid.tsx +++ b/apps/web/src/components/dashboard/dashboard-recent-revisions-grid.tsx @@ -2,7 +2,7 @@ import { ColumnDef } from '@tanstack/react-table' import { useMemo } from 'react' import { DataGridMutedCell, DataGridPrimaryCell } from '@/components/data-grid-cell' -import { DataGridSection } from '@/components/data-grid-shell' +import { DataGridShell } from '@/components/data-grid-shell' import { DataGridColumnHeader } from '@/components/reui/data-grid/data-grid-column-header' import { DATA_GRID_DENSE_LAYOUT } from '@/lib/data-grid-defaults' import { useClientDataGrid } from '@/hooks/use-client-data-grid' @@ -42,7 +42,7 @@ export function DashboardRecentRevisionsGrid({ [], ) - const { table, globalFilter, setGlobalFilter, filteredCount } = useClientDataGrid({ + const { table, filteredCount } = useClientDataGrid({ data, columns, getSearchText: (row) => row.id, @@ -51,16 +51,13 @@ export function DashboardRecentRevisionsGrid({ }) return ( - ) } diff --git a/apps/web/src/components/reui-kit/ops-dashboard.tsx b/apps/web/src/components/reui-kit/ops-dashboard.tsx index 441519a..c972635 100644 --- a/apps/web/src/components/reui-kit/ops-dashboard.tsx +++ b/apps/web/src/components/reui-kit/ops-dashboard.tsx @@ -1,11 +1,4 @@ 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' @@ -47,9 +40,11 @@ function OpsDashboardSkeleton() { } /** - * Ops dashboard: KPI → optional Quick Actions → charts → attention queue. + * Ops dashboard: KPI → optional Quick Actions → charts → queue. + * Queue is a sibling Frame grid — never wrap FrameDataGrid inside another Frame. * @see https://reui.io/preview/base/dashboard-1 * @see https://reui.io/preview/base/stats-12 + * @see https://reui.io/docs/components/base/frame */ export function OpsDashboard({ title = 'Панель управления', @@ -77,21 +72,18 @@ export function OpsDashboard({ {afterKpi ?
{afterKpi}
: null} -
+
{charts}
-
- - - {queueTitle} - {queueDescription} - - {queue} - +
+
+

{queueTitle}

+ {queueDescription ? ( +

{queueDescription}

+ ) : null} +
+ {queue}
) diff --git a/apps/web/src/routes/_auth/dashboard.tsx b/apps/web/src/routes/_auth/dashboard.tsx index 75b26d2..f540342 100644 --- a/apps/web/src/routes/_auth/dashboard.tsx +++ b/apps/web/src/routes/_auth/dashboard.tsx @@ -7,7 +7,6 @@ import { Button } from '@evobgp/ui/components/button' import { Skeleton } from '@evobgp/ui/components/skeleton' import { DashboardActivityTimeline } from '@/components/dashboard/dashboard-activity-timeline' -import { DashboardFramePanel } from '@/components/dashboard/dashboard-frame-panel' import { buildDashboardKpiCards } from '@/components/dashboard/dashboard-kpi-grid' import { DashboardModulesGrid } from '@/components/dashboard/dashboard-modules-grid' import { DashboardNetworkHealth } from '@/components/dashboard/dashboard-network-health' @@ -15,7 +14,7 @@ import { DashboardOperationsBreakdown } from '@/components/dashboard/dashboard-o import { DashboardQuickLinks } from '@/components/dashboard/dashboard-quick-links' import { DashboardRecentJobsGrid } from '@/components/dashboard/dashboard-recent-jobs-grid' import { DashboardRecentRevisionsGrid } from '@/components/dashboard/dashboard-recent-revisions-grid' -import { OpsDashboard } from '@/components/reui-kit' +import { FrameDataGrid, OpsDashboard } from '@/components/reui-kit' import { chartPanelGridClassName, dashboardMainSidebarClassName } from '@/lib/ui-surface' import { moduleNameById, @@ -111,7 +110,7 @@ function DashboardComponent() { peers={peers} speakers={speakers} /> -
+
@@ -122,28 +121,26 @@ function DashboardComponent() { queueDescription="Последние фоновые операции и история конфигураций" queue={
- {activityLoading ? ( ) : ( - + )} - - + {activityLoading ? ( ) : ( )} - +
} /> diff --git a/packages/ui/src/components/tabs.tsx b/packages/ui/src/components/tabs.tsx index 3b0ded1..137c901 100644 --- a/packages/ui/src/components/tabs.tsx +++ b/packages/ui/src/components/tabs.tsx @@ -24,12 +24,13 @@ function Tabs({ } const tabsListVariants = cva( - "group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground group-data-[orientation=horizontal]/tabs:h-9 group-data-[orientation=vertical]/tabs:h-fit group-data-[orientation=vertical]/tabs:flex-col data-[variant=line]:rounded-none", + "group/tabs-list inline-flex w-fit items-center justify-center rounded-lg text-muted-foreground group-data-[orientation=vertical]/tabs:h-fit group-data-[orientation=vertical]/tabs:flex-col data-[variant=line]:rounded-none", { variants: { variant: { - default: "bg-muted", - line: "gap-1 border-b border-border bg-transparent", + default: + "bg-muted p-[3px] group-data-[orientation=horizontal]/tabs:h-9", + line: "h-auto gap-1 overflow-visible border-b border-border bg-transparent p-0", }, }, defaultVariants: { @@ -58,10 +59,12 @@ function TabsTrigger({ className, ...props }: TabsPrimitive.Tab.Props) {