fix(web): parse string readiness checks on monitoring System tab
Исправляет ложные «Ошибки проверок»: GET /v1/ready отдаёт строки ok/memory, а не boolean. Уплотнён ReUI Frame/donut layout на вкладке Система. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -7,12 +7,20 @@ import { DataGridSection } from '@/components/data-grid-shell'
|
||||
import { StatusBadge } from '@/components/status-badge'
|
||||
import { DataGridColumnHeader } from '@/components/reui/data-grid/data-grid-column-header'
|
||||
import { useClientDataGrid } from '@/hooks/use-client-data-grid'
|
||||
import { jobStatusRu, readyCheckRu } from '@/lib/ui-labels'
|
||||
import {
|
||||
isReadyCheckOk,
|
||||
isSystemReady,
|
||||
readyCheckStatusLabel,
|
||||
} from '@/lib/metrics'
|
||||
import { readyCheckRu } from '@/lib/ui-labels'
|
||||
import type { ReadyStatus } from '@/queries/monitoring'
|
||||
import { Item, ItemMedia } from '@evobgp/ui/components/item'
|
||||
import { cn } from '@evobgp/ui/lib/utils'
|
||||
|
||||
const READY_CHECK_ICONS: Record<string, typeof Database> = {
|
||||
postgres: Database,
|
||||
store: HardDrive,
|
||||
store_backend: HardDrive,
|
||||
jobs: ListTodo,
|
||||
}
|
||||
|
||||
@@ -21,6 +29,7 @@ interface ReadyCheckRow {
|
||||
label: string
|
||||
subtitle?: string
|
||||
icon: typeof Database
|
||||
iconClassName?: string
|
||||
status: string
|
||||
statusLabel: string
|
||||
}
|
||||
@@ -34,12 +43,14 @@ export function MonitoringReadyGrid({
|
||||
}) {
|
||||
const data = useMemo<ReadyCheckRow[]>(() => {
|
||||
const checks = ready.checks ?? {}
|
||||
const systemReady = isSystemReady(ready.status)
|
||||
const rows: ReadyCheckRow[] = [
|
||||
{
|
||||
id: 'liveness',
|
||||
label: 'Живучесть',
|
||||
subtitle: '/v1/health',
|
||||
icon: HeartPulse,
|
||||
iconClassName: health?.ok ? 'text-success' : 'text-destructive',
|
||||
status: health?.ok ? 'ok' : 'error',
|
||||
statusLabel: health?.ok ? 'В норме' : 'Ошибка',
|
||||
},
|
||||
@@ -48,19 +59,21 @@ export function MonitoringReadyGrid({
|
||||
label: 'Готовность',
|
||||
subtitle: '/v1/ready',
|
||||
icon: ShieldCheck,
|
||||
status: ready.status === 'ok' ? 'ok' : 'warning',
|
||||
statusLabel: ready.status === 'ok' ? 'Готов' : jobStatusRu(ready.status ?? 'pending'),
|
||||
iconClassName: systemReady ? 'text-success' : 'text-warning',
|
||||
status: systemReady ? 'ok' : 'warning',
|
||||
statusLabel: systemReady ? 'Готов' : 'Не готов',
|
||||
},
|
||||
]
|
||||
for (const key of Object.keys(checks)) {
|
||||
const value = checks[key]
|
||||
const ok = typeof value === 'boolean' ? value : value?.ok !== false
|
||||
const ok = isReadyCheckOk(value)
|
||||
rows.push({
|
||||
id: key,
|
||||
label: readyCheckRu(key),
|
||||
icon: READY_CHECK_ICONS[key] ?? ListTodo,
|
||||
iconClassName: ok ? 'text-success' : 'text-destructive',
|
||||
status: ok ? 'ok' : 'error',
|
||||
statusLabel: ok ? 'В норме' : 'Ошибка',
|
||||
statusLabel: readyCheckStatusLabel(value, ok),
|
||||
})
|
||||
}
|
||||
return rows
|
||||
@@ -74,8 +87,17 @@ export function MonitoringReadyGrid({
|
||||
cell: ({ row }) => {
|
||||
const Icon = row.original.icon
|
||||
return (
|
||||
<div className="flex items-center gap-2">
|
||||
<Icon className="size-4 shrink-0 text-muted-foreground" />
|
||||
<div className="flex min-w-0 items-center gap-2.5 py-0.5">
|
||||
<Item
|
||||
className={cn(
|
||||
'border-background bg-muted flex size-8 shrink-0 items-center justify-center border-2 p-0 shadow-[0_1px_3px_0_rgba(0,0,0,0.14)] dark:border [&_svg]:size-3.5',
|
||||
row.original.iconClassName,
|
||||
)}
|
||||
>
|
||||
<ItemMedia variant="icon" className="size-auto">
|
||||
<Icon />
|
||||
</ItemMedia>
|
||||
</Item>
|
||||
<DataGridPrimaryCell
|
||||
title={row.original.label}
|
||||
subtitle={row.original.subtitle}
|
||||
@@ -90,7 +112,9 @@ export function MonitoringReadyGrid({
|
||||
enableSorting: false,
|
||||
header: 'Статус',
|
||||
cell: ({ row }) => (
|
||||
<StatusBadge status={row.original.status} label={row.original.statusLabel} />
|
||||
<div className="flex justify-start">
|
||||
<StatusBadge status={row.original.status} label={row.original.statusLabel} />
|
||||
</div>
|
||||
),
|
||||
meta: { headerTitle: 'Статус' },
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user