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.
62 lines
1.8 KiB
TypeScript
62 lines
1.8 KiB
TypeScript
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 { jobStatusBreakdown, moduleTypeBreakdown } from '@/lib/metrics'
|
|
import type { JobRow, ModuleRow } from '@/types/api'
|
|
|
|
type FlowMode = 'jobs' | 'modules'
|
|
|
|
/**
|
|
* 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,
|
|
loading,
|
|
}: {
|
|
jobs: JobRow[]
|
|
modules: ModuleRow[]
|
|
loading?: boolean
|
|
}) {
|
|
const [mode, setMode] = useState<FlowMode>('jobs')
|
|
|
|
const slices = useMemo(
|
|
() => (mode === 'jobs' ? jobStatusBreakdown(jobs) : moduleTypeBreakdown(modules)),
|
|
[mode, jobs, modules],
|
|
)
|
|
|
|
const total = slices.reduce((sum, slice) => sum + slice.count, 0)
|
|
const centerLabel = mode === 'jobs' ? 'Задачи' : 'Модули'
|
|
|
|
return (
|
|
<PanelCard
|
|
title="Поток операций"
|
|
description="Доли статусов задач или типов модулей"
|
|
actions={
|
|
<AnalyticsSegmentControl
|
|
value={mode}
|
|
onChange={setMode}
|
|
options={[
|
|
{ value: 'jobs', label: 'Задачи' },
|
|
{ value: 'modules', label: 'Модули' },
|
|
]}
|
|
/>
|
|
}
|
|
className="min-w-0"
|
|
contentClassName="px-5 py-4"
|
|
>
|
|
{loading ? (
|
|
<div className="text-muted-foreground flex h-44 items-center justify-center text-sm">
|
|
Загрузка…
|
|
</div>
|
|
) : (
|
|
<ChartDonutMetric slices={slices} centerLabel={centerLabel} centerValue={total} />
|
|
)}
|
|
</PanelCard>
|
|
)
|
|
}
|