fix(evolution): исключить моковые данные из живого каталога
This commit is contained in:
1 parent
118cd31d65
commit
d272ef57f0
17 files changed
+155
-136
No files matched your search
@@ -12,6 +12,7 @@ import {
|
||||
} from "@/components/ui/sidebar"
|
||||
import { navigationGroups } from "@/lib/navigation"
|
||||
import { useDataSource } from "@/lib/data-source"
|
||||
import { can } from "@/lib/auth"
|
||||
import { useEvoBGP } from "@/lib/evobgp-context"
|
||||
import { requestJson } from "@/shared/api/http-client"
|
||||
import {
|
||||
@@ -78,7 +79,7 @@ export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
|
||||
if (mode !== "live") return mockBadges[url]
|
||||
|
||||
if (url === "/domains" || url === "/ip-ranges" || url === "/asns") {
|
||||
if (!evo.enabled) return undefined
|
||||
if (!evo.settingsLoaded || !evo.enabled || !can("mm:settings:admin")) return undefined
|
||||
if (!evo.snapshot) return undefined
|
||||
if (url === "/domains") return formatSidebarBadgeCount(evo.snapshot.domains.length)
|
||||
if (url === "/ip-ranges") return formatSidebarBadgeCount(evo.snapshot.ipRanges.length)
|
||||
@@ -111,7 +112,7 @@ export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
|
||||
badge: mounted ? badgeFor(it.url) : undefined,
|
||||
})),
|
||||
}))
|
||||
}, [mounted, mode, liveCounts, mockBadges, evo.enabled, evo.snapshot])
|
||||
}, [mounted, mode, liveCounts, mockBadges, evo.settingsLoaded, evo.enabled, evo.snapshot])
|
||||
|
||||
return (
|
||||
<Sidebar collapsible="icon" {...props}>
|
||||
|
||||
@@ -21,10 +21,11 @@ import { FilterIcon, NetworkIcon } from "lucide-react"
|
||||
interface AsnsDataGridProps {
|
||||
asns: Asn[]
|
||||
isLoading?: boolean
|
||||
emptyDescription?: string
|
||||
pagination?: boolean
|
||||
}
|
||||
|
||||
function AsnsDataGrid({ asns, isLoading, pagination = false }: AsnsDataGridProps) {
|
||||
function AsnsDataGrid({ asns, isLoading, pagination = false, emptyDescription }: AsnsDataGridProps) {
|
||||
const columns = useMemo<ColumnDef<DataGridFeatures, Asn>[]>(
|
||||
() => [
|
||||
{
|
||||
@@ -133,7 +134,7 @@ function AsnsDataGrid({ asns, isLoading, pagination = false }: AsnsDataGridProps
|
||||
<EmptyState
|
||||
icon={<NetworkIcon className="size-4" />}
|
||||
title="Нет ASN"
|
||||
description="Добавьте автономные системы или импортируйте каталог"
|
||||
description={emptyDescription ?? "Добавьте автономные системы или импортируйте каталог"}
|
||||
className="border-0 py-12"
|
||||
/>
|
||||
}
|
||||
|
||||
@@ -21,10 +21,11 @@ import { FilterIcon, GlobeIcon } from "lucide-react"
|
||||
interface DomainsDataGridProps {
|
||||
domains: Domain[]
|
||||
isLoading?: boolean
|
||||
emptyDescription?: string
|
||||
pagination?: boolean
|
||||
}
|
||||
|
||||
function DomainsDataGrid({ domains, isLoading, pagination = false }: DomainsDataGridProps) {
|
||||
function DomainsDataGrid({ domains, isLoading, pagination = false, emptyDescription }: DomainsDataGridProps) {
|
||||
const columns = useMemo<ColumnDef<DataGridFeatures, Domain>[]>(
|
||||
() => [
|
||||
{
|
||||
@@ -142,7 +143,7 @@ function DomainsDataGrid({ domains, isLoading, pagination = false }: DomainsData
|
||||
<EmptyState
|
||||
icon={<GlobeIcon className="size-4" />}
|
||||
title="Нет доменов"
|
||||
description="Добавьте домены или импортируйте каталог"
|
||||
description={emptyDescription ?? "Добавьте домены или импортируйте каталог"}
|
||||
className="border-0 py-12"
|
||||
/>
|
||||
}
|
||||
|
||||
@@ -21,10 +21,11 @@ import { FilterIcon, NetworkIcon } from "lucide-react"
|
||||
interface IpRangesDataGridProps {
|
||||
ipRanges: IpRange[]
|
||||
isLoading?: boolean
|
||||
emptyDescription?: string
|
||||
pagination?: boolean
|
||||
}
|
||||
|
||||
function IpRangesDataGrid({ ipRanges, isLoading, pagination = false }: IpRangesDataGridProps) {
|
||||
function IpRangesDataGrid({ ipRanges, isLoading, pagination = false, emptyDescription }: IpRangesDataGridProps) {
|
||||
const columns = useMemo<ColumnDef<DataGridFeatures, IpRange>[]>(
|
||||
() => [
|
||||
{
|
||||
@@ -144,7 +145,7 @@ function IpRangesDataGrid({ ipRanges, isLoading, pagination = false }: IpRangesD
|
||||
<EmptyState
|
||||
icon={<NetworkIcon className="size-4" />}
|
||||
title="Нет IP-диапазонов"
|
||||
description="Добавьте CIDR-блоки или импортируйте каталог"
|
||||
description={emptyDescription ?? "Добавьте CIDR-блоки или импортируйте каталог"}
|
||||
className="border-0 py-12"
|
||||
/>
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
"use client"
|
||||
import Link from "next/link"
|
||||
import {useDataSource} from "@/lib/data-source"
|
||||
import {useEvoBGP} from "@/lib/evobgp-context"
|
||||
import {can} from "@/lib/auth"
|
||||
import {Alert,AlertTitle,AlertDescription} from "@/components/reui/alert"
|
||||
import {Button} from "@/components/ui/button"
|
||||
import {EmptyState} from "@/components/empty-state"
|
||||
import {AlertCircleIcon} from "lucide-react"
|
||||
|
||||
export function useEvoCatalogView(){
|
||||
const {mode,backendStatus}=useDataSource(),evo=useEvoBGP()
|
||||
const allowed=can("mm:settings:admin")
|
||||
const snapshot=mode==="live"&&allowed&&evo.enabled?evo.snapshot:null
|
||||
return {evo,mode,backendStatus,allowed,snapshot,known:mode==="mock"||!!snapshot,loading:mode==="live"&&allowed&&!snapshot&&(evo.settingsLoading||evo.loading)}
|
||||
}
|
||||
export function EvoBgpCatalogStatus(){
|
||||
const {evo,mode,backendStatus,allowed,snapshot}=useEvoCatalogView()
|
||||
if(mode==="mock")return <p role="status" className="text-xs text-muted-foreground">Демонстрационный каталог</p>
|
||||
const reason=!allowed?"Нет доступа к каталогу EvoBGP":!evo.settingsLoaded?evo.settingsLoading?"Загрузка настроек EvoBGP…":"Настройки EvoBGP неизвестны":!evo.enabled?"Интеграция EvoBGP выключена":!snapshot?evo.loading?"Загрузка каталога EvoBGP…":"Каталог EvoBGP не получен":null
|
||||
const error=evo.settingsError||evo.catalogError
|
||||
return <div className="flex min-w-0 flex-col gap-3">
|
||||
{reason?<p role="status" className="text-sm">{reason}</p>:null}
|
||||
{snapshot?<p role="status" className="text-xs text-muted-foreground">Каталог EvoBGP получен: {evo.catalogReceivedAt?new Date(evo.catalogReceivedAt).toLocaleString("ru-RU"):"—"}{evo.loading?" · обновление…":""}</p>:null}
|
||||
{error?<Alert variant="warning"><AlertCircleIcon aria-hidden="true"/><AlertTitle>{snapshot?"Каталог не обновлён; показаны последние данные":"Каталог EvoBGP недоступен"}</AlertTitle><AlertDescription>{[evo.settingsError,evo.catalogError].filter(Boolean).join("; ")}</AlertDescription></Alert>:null}
|
||||
{allowed?<div className="flex flex-wrap gap-2"><Button size="sm" variant="outline" disabled={backendStatus!==true||evo.settingsLoading||evo.loading||evo.operationBusy} onClick={()=>{if(!evo.settingsLoaded||!evo.enabled||evo.settingsError)void evo.loadSettings();else void evo.refresh()}}>Обновить каталог EvoBGP</Button><Link className="text-sm underline underline-offset-4" href="/settings">Настройки → EvoBGP</Link></div>:null}
|
||||
</div>
|
||||
}
|
||||
export function EvoBgpCatalogUnavailable(){return <EmptyState title="Данные каталога не получены" description="Состояние загрузки указано выше. Число записей пока неизвестно." className="py-10"/>}
|
||||
Reference in new issue
Block a user