feat: refactor components to utilize DataGridCard for improved UI consistency
CI / changes (push) Successful in 11s
CI / commitlint (push) Has been skipped
CI / openapi (push) Has been skipped
CI / web (push) Successful in 57s
CI / go (push) Has been skipped
CI / bird2 (push) Has been skipped
CI / release (push) Successful in 4m27s
CI / changes (push) Successful in 11s
CI / commitlint (push) Has been skipped
CI / openapi (push) Has been skipped
CI / web (push) Successful in 57s
CI / go (push) Has been skipped
CI / bird2 (push) Has been skipped
CI / release (push) Successful in 4m27s
Updated various components including AccessApiKeysCard, FirewallClientsGrid, FirewallRulesGrid, ModuleEntriesSection, and DirectoriesComponent to replace traditional card and table structures with the new DataGridCard component. This change enhances the user interface by providing a more consistent layout and improved loading states. Additionally, integrated QueryState for better handling of loading and error scenarios across these components, streamlining the overall user experience.
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
import { ColumnDef, useReactTable } from '@tanstack/react-table'
|
||||
import { Database, HardDrive, HeartPulse, ListTodo, ShieldCheck } from 'lucide-react'
|
||||
import { useMemo } from 'react'
|
||||
|
||||
import { Badge } from '@evobgp/ui/components/badge'
|
||||
|
||||
import { DataGridShell } from '@/components/data-grid-shell'
|
||||
import { DataGridColumnHeader } from '@/components/reui/data-grid/data-grid-column-header'
|
||||
import { createClientDataGridOptions } from '@/lib/data-grid-defaults'
|
||||
import type { ReadyStatus } from '@/queries/monitoring'
|
||||
|
||||
const READY_CHECK_ICONS: Record<string, typeof Database> = {
|
||||
postgres: Database,
|
||||
store: HardDrive,
|
||||
jobs: ListTodo,
|
||||
}
|
||||
|
||||
interface ReadyCheckRow {
|
||||
id: string
|
||||
label: string
|
||||
subtitle?: string
|
||||
icon: typeof Database
|
||||
ok: boolean
|
||||
statusLabel: string
|
||||
variant: 'default' | 'destructive' | 'secondary'
|
||||
}
|
||||
|
||||
export function MonitoringReadyGrid({
|
||||
health,
|
||||
ready,
|
||||
}: {
|
||||
health?: { ok?: boolean; status?: string; error?: string } | null
|
||||
ready: ReadyStatus
|
||||
}) {
|
||||
const data = useMemo<ReadyCheckRow[]>(() => {
|
||||
const checks = ready.checks ?? {}
|
||||
const rows: ReadyCheckRow[] = [
|
||||
{
|
||||
id: 'liveness',
|
||||
label: 'Liveness',
|
||||
subtitle: '/v1/health',
|
||||
icon: HeartPulse,
|
||||
ok: health?.ok === true,
|
||||
statusLabel: health?.ok ? 'OK' : 'Ошибка',
|
||||
variant: health?.ok ? 'default' : 'destructive',
|
||||
},
|
||||
{
|
||||
id: 'readiness',
|
||||
label: 'Readiness',
|
||||
subtitle: '/v1/ready',
|
||||
icon: ShieldCheck,
|
||||
ok: ready.status === 'ok',
|
||||
statusLabel: ready.status ?? '—',
|
||||
variant: ready.status === 'ok' ? 'default' : 'secondary',
|
||||
},
|
||||
]
|
||||
for (const key of Object.keys(checks)) {
|
||||
const value = checks[key]
|
||||
const ok = typeof value === 'boolean' ? value : value?.ok !== false
|
||||
rows.push({
|
||||
id: key,
|
||||
label: key,
|
||||
icon: READY_CHECK_ICONS[key] ?? ListTodo,
|
||||
ok,
|
||||
statusLabel: ok ? 'OK' : 'Ошибка',
|
||||
variant: ok ? 'default' : 'destructive',
|
||||
})
|
||||
}
|
||||
return rows
|
||||
}, [health?.ok, ready.checks, ready.status])
|
||||
|
||||
const columns = useMemo<ColumnDef<ReadyCheckRow>[]>(
|
||||
() => [
|
||||
{
|
||||
accessorKey: 'label',
|
||||
header: ({ column }) => <DataGridColumnHeader column={column} title="Проверка" />,
|
||||
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>
|
||||
<p className="text-sm font-medium">{row.original.label}</p>
|
||||
{row.original.subtitle ? (
|
||||
<p className="text-xs text-muted-foreground">{row.original.subtitle}</p>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
meta: { headerTitle: 'Проверка' },
|
||||
},
|
||||
{
|
||||
id: 'status',
|
||||
enableSorting: false,
|
||||
header: 'Статус',
|
||||
cell: ({ row }) => (
|
||||
<Badge variant={row.original.variant}>{row.original.statusLabel}</Badge>
|
||||
),
|
||||
meta: { headerTitle: 'Статус' },
|
||||
},
|
||||
],
|
||||
[],
|
||||
)
|
||||
|
||||
const table = useReactTable({
|
||||
data,
|
||||
columns,
|
||||
...createClientDataGridOptions<ReadyCheckRow>({
|
||||
initialState: { pagination: { pageSize: 20 } },
|
||||
}),
|
||||
getRowId: (row) => row.id,
|
||||
})
|
||||
|
||||
return (
|
||||
<DataGridShell
|
||||
table={table}
|
||||
recordCount={data.length}
|
||||
showPagination={false}
|
||||
emptyMessage="Нет проверок"
|
||||
/>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user