Updated the ModuleKpiCards component to improve the display of KPI metrics by introducing a new entries count prop and simplifying the logic for displaying community and DoH information. Added a new mutation hook for updating modules, which includes success and error handling with toast notifications. Enhanced the ModuleDetailComponent to support editing modules with a new dialog and integrated the entries count into the KPI display. Additionally, introduced a new helper function for generating short labels for DoH profiles, improving the overall user experience in module management.
114 lines
3.4 KiB
TypeScript
114 lines
3.4 KiB
TypeScript
import { Clock, Gauge, Globe, Tags } from 'lucide-react'
|
|
|
|
import { KpiStatGrid, type KpiStatItem } from '@/components/kpi-stat-grid'
|
|
import { Badge } from '@/components/reui/badge'
|
|
import { KpiStatGridSkeleton } from '@/components/skeletons'
|
|
import { formatDateTime, moduleIntervalLabel } from '@/lib/modules/display'
|
|
import { communityLabel, moduleDohProfileIds } from '@/lib/modules/helpers'
|
|
import { dohPolicyRu } from '@/lib/ui-labels'
|
|
import type { AsEntry, BgpCommunity, ModuleRow } from '@/types/api'
|
|
|
|
interface ModuleKpiCardsProps {
|
|
mod: ModuleRow | null
|
|
communities: BgpCommunity[]
|
|
asEntries: AsEntry[]
|
|
entriesCount?: number
|
|
loading?: boolean
|
|
}
|
|
|
|
export function ModuleKpiCards({
|
|
mod,
|
|
communities,
|
|
asEntries,
|
|
entriesCount = 0,
|
|
loading = false,
|
|
}: ModuleKpiCardsProps) {
|
|
if (loading || !mod) {
|
|
return <KpiStatGridSkeleton count={4} />
|
|
}
|
|
|
|
const asPrefixTotal = asEntries.reduce((acc, entry) => acc + (entry.prefix_count ?? 0), 0)
|
|
const dohIds = moduleDohProfileIds(mod)
|
|
const isDomains = mod.type === 'DOMAINS'
|
|
const isAsPrefixes = mod.type === 'AS_PREFIXES'
|
|
const community = communityLabel(mod.default_community_id, communities)
|
|
|
|
const entriesFooter = isAsPrefixes ? (
|
|
<Badge variant="success-light" size="sm">
|
|
{asEntries.length} AS · в модуле
|
|
</Badge>
|
|
) : isDomains ? (
|
|
<Badge variant="outline" size="sm">
|
|
{mod.default_community_id ? community : 'без community'}
|
|
</Badge>
|
|
) : (
|
|
<Badge variant="success-light" size="sm">
|
|
{entriesCount} · в модуле
|
|
</Badge>
|
|
)
|
|
|
|
const policyItem: KpiStatItem = isDomains
|
|
? {
|
|
id: 'doh',
|
|
icon: <Globe aria-hidden />,
|
|
iconClassName: 'text-primary',
|
|
value: dohIds.length > 0 ? String(dohIds.length) : '—',
|
|
label: 'DoH',
|
|
footer: (
|
|
<Badge variant={dohIds.length > 0 ? 'info-light' : 'outline'} size="sm">
|
|
{dohIds.length > 0 ? dohPolicyRu(mod.doh_resolver_policy) : 'без DoH'}
|
|
</Badge>
|
|
),
|
|
}
|
|
: {
|
|
id: 'community',
|
|
icon: <Globe aria-hidden />,
|
|
iconClassName: 'text-primary',
|
|
value: community,
|
|
label: 'Community',
|
|
footer: (
|
|
<Badge variant="outline" size="sm">
|
|
по умолчанию
|
|
</Badge>
|
|
),
|
|
}
|
|
|
|
const items: KpiStatItem[] = [
|
|
{
|
|
id: 'priority',
|
|
icon: <Gauge aria-hidden />,
|
|
iconClassName: 'text-info',
|
|
value: String(mod.priority ?? 0),
|
|
label: 'Приоритет',
|
|
footer: (
|
|
<Badge variant={mod.enabled !== false ? 'success-light' : 'outline'} size="sm">
|
|
{mod.enabled !== false ? 'активен' : 'выключен'} · {mod.type}
|
|
</Badge>
|
|
),
|
|
},
|
|
{
|
|
id: 'interval',
|
|
icon: <Clock aria-hidden />,
|
|
iconClassName: 'text-warning',
|
|
value: moduleIntervalLabel(mod),
|
|
label: 'Интервал обновления',
|
|
footer: (
|
|
<Badge variant="primary-light" size="sm">
|
|
{formatDateTime(mod.last_refreshed_at) || 'никогда'}
|
|
</Badge>
|
|
),
|
|
},
|
|
{
|
|
id: 'prefixes',
|
|
icon: <Tags aria-hidden />,
|
|
iconClassName: 'text-success',
|
|
value: isAsPrefixes ? String(asPrefixTotal) : String(entriesCount),
|
|
label: isAsPrefixes ? 'Префиксы AS' : 'Записи модуля',
|
|
footer: entriesFooter,
|
|
},
|
|
policyItem,
|
|
]
|
|
|
|
return <KpiStatGrid items={items} aria-label="KPI модуля" />
|
|
}
|