111 lines
2.8 KiB
TypeScript
111 lines
2.8 KiB
TypeScript
import type { ComponentProps } from 'react'
|
|
|
|
import { cn } from '@evofw/ui/lib/utils'
|
|
|
|
import { Badge } from '@/components/reui/badge'
|
|
|
|
type BadgeVariant = NonNullable<ComponentProps<typeof Badge>['variant']>
|
|
|
|
const STATUS_VARIANT: Record<string, BadgeVariant> = {
|
|
active: 'success-light',
|
|
synced: 'success-light',
|
|
ok: 'success-light',
|
|
up: 'success-light',
|
|
enabled: 'success-light',
|
|
approved: 'success-light',
|
|
allow: 'success-light',
|
|
pending_push: 'secondary',
|
|
pending: 'warning-light',
|
|
invited: 'info-light',
|
|
warning: 'warning-light',
|
|
degraded: 'warning-light',
|
|
conflict: 'destructive-light',
|
|
error: 'destructive-light',
|
|
expired: 'destructive-light',
|
|
down: 'destructive-light',
|
|
deny: 'destructive-light',
|
|
revoked: 'secondary',
|
|
disabled: 'secondary',
|
|
static: 'secondary',
|
|
domains: 'secondary',
|
|
manual: 'secondary',
|
|
json_url: 'info-light',
|
|
evobgp_community: 'info-light',
|
|
ip: 'info-light',
|
|
cidr: 'secondary',
|
|
hostname: 'warning-light',
|
|
list: 'info-light',
|
|
unknown: 'outline',
|
|
}
|
|
|
|
const DOT_COLOR: Record<string, string> = {
|
|
'success-light': 'bg-success',
|
|
success: 'bg-success',
|
|
'warning-light': 'bg-warning',
|
|
warning: 'bg-warning',
|
|
'destructive-light': 'bg-destructive',
|
|
destructive: 'bg-destructive',
|
|
'info-light': 'bg-info',
|
|
secondary: 'bg-muted-foreground',
|
|
outline: 'bg-muted-foreground',
|
|
}
|
|
|
|
const STATUS_LABELS: Record<string, string> = {
|
|
active: 'Активен',
|
|
synced: 'Синхронизировано',
|
|
pending_push: 'Ожидает отправки',
|
|
pending: 'Ожидает одобрения',
|
|
invited: 'Приглашён',
|
|
approved: 'Одобрен',
|
|
revoked: 'Отозван',
|
|
enabled: 'Включён',
|
|
disabled: 'Выключен',
|
|
allow: 'Разрешить',
|
|
deny: 'Блокировать',
|
|
conflict: 'Конфликт',
|
|
error: 'Ошибка',
|
|
ok: 'OK',
|
|
up: 'OK',
|
|
warning: 'Предупреждение',
|
|
degraded: 'Замедление',
|
|
down: 'Недоступен',
|
|
expired: 'Истёк',
|
|
static: 'Ручной',
|
|
domains: 'Ручной',
|
|
manual: 'Ручной',
|
|
json_url: 'JSON по URL',
|
|
evobgp_community: 'EvoBGP community',
|
|
ip: 'IP',
|
|
cidr: 'CIDR',
|
|
hostname: 'Домен',
|
|
list: 'Вложенный список',
|
|
unknown: 'Неизвестно',
|
|
}
|
|
|
|
export function StatusBadge({
|
|
status,
|
|
label,
|
|
className,
|
|
}: {
|
|
status: string
|
|
label?: string
|
|
className?: string
|
|
}) {
|
|
const variant = STATUS_VARIANT[status] ?? 'outline'
|
|
const dotColor = DOT_COLOR[variant] ?? 'bg-muted-foreground'
|
|
return (
|
|
<Badge
|
|
variant={variant}
|
|
size="sm"
|
|
radius="full"
|
|
className={cn('gap-1.5', className)}
|
|
>
|
|
<span
|
|
className={cn('size-1.5 shrink-0 rounded-full', dotColor)}
|
|
aria-hidden
|
|
/>
|
|
{label ?? STATUS_LABELS[status] ?? status}
|
|
</Badge>
|
|
)
|
|
}
|