fix(ui): заменить таблицы на карточки данных и улучшить функциональность поиска
Docker images / prepare-release (push) Successful in 6s
Docker images / backend-image (push) Successful in 1m37s
Docker images / frontend-image (push) Successful in 1m50s
Docker images / updater-image (push) Successful in 44s
Docker images / notify-webhook (push) Has been skipped
Docker images / publish-release (push) Successful in 7s
Docker images / prepare-release (push) Successful in 6s
Docker images / backend-image (push) Successful in 1m37s
Docker images / frontend-image (push) Successful in 1m50s
Docker images / updater-image (push) Successful in 44s
Docker images / notify-webhook (push) Has been skipped
Docker images / publish-release (push) Successful in 7s
This commit is contained in:
@@ -2,11 +2,13 @@
|
||||
|
||||
import { useMemo, useState } from "react"
|
||||
import { PageHeader } from "@/components/page-header"
|
||||
import { DataTable } from "@/components/data-table"
|
||||
import { DataPageCard } from "@/components/data-page-card"
|
||||
import { DataPageToolbar } from "@/components/data-page-toolbar"
|
||||
import { IpRangesDataGrid } from "@/components/data-grids/ip-ranges-data-grid"
|
||||
import { FileImportDialog } from "@/components/file-import-dialog"
|
||||
import { ipRanges as mockIpRanges } from "@/lib/data"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { UploadIcon, DownloadIcon, PlusIcon, FilterIcon, LoaderCircleIcon } from "lucide-react"
|
||||
import { UploadIcon, DownloadIcon, PlusIcon, LoaderCircleIcon } from "lucide-react"
|
||||
import { useDataSource } from "@/lib/data-source"
|
||||
import { useEvoBGP } from "@/lib/evobgp-context"
|
||||
import { cn } from "@/lib/utils"
|
||||
@@ -16,6 +18,7 @@ export default function IpRangesPage() {
|
||||
const { mode } = useDataSource()
|
||||
const { enabled, snapshot, loading, error } = useEvoBGP()
|
||||
const [importOpen, setImportOpen] = useState(false)
|
||||
const [search, setSearch] = useState("")
|
||||
|
||||
const useEvoCatalog = mode === "live" && enabled
|
||||
|
||||
@@ -25,6 +28,18 @@ export default function IpRangesPage() {
|
||||
return snapshot?.ipRanges ?? []
|
||||
}, [useEvoCatalog, loading, snapshot])
|
||||
|
||||
const filtered = useMemo(() => {
|
||||
if (!search) return rows
|
||||
const q = search.toLowerCase()
|
||||
return rows.filter(
|
||||
(r) =>
|
||||
r.cidr.toLowerCase().includes(q) ||
|
||||
r.asn.toLowerCase().includes(q) ||
|
||||
r.country.toLowerCase().includes(q) ||
|
||||
r.filter.toLowerCase().includes(q),
|
||||
)
|
||||
}, [rows, search])
|
||||
|
||||
return (
|
||||
<div className="flex flex-col h-full">
|
||||
<PageHeader
|
||||
@@ -60,57 +75,19 @@ export default function IpRangesPage() {
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<DataTable
|
||||
data={rows}
|
||||
isLoading={useEvoCatalog && loading && !snapshot}
|
||||
searchPlaceholder="Поиск по CIDR, ASN…"
|
||||
searchKeys={["cidr", "asn", "country", "filter"]}
|
||||
columns={[
|
||||
{
|
||||
key: "cidr",
|
||||
label: "CIDR",
|
||||
render: (d) => <span className="font-mono font-medium">{d.cidr}</span>,
|
||||
},
|
||||
{
|
||||
key: "asn",
|
||||
label: "ASN",
|
||||
render: (d) => <span className="font-mono text-xs text-muted-foreground">{d.asn}</span>,
|
||||
},
|
||||
{
|
||||
key: "country",
|
||||
label: "Страна",
|
||||
render: (d) => <span className="text-xs border border-border rounded px-2 py-0.5">{d.country}</span>,
|
||||
},
|
||||
{
|
||||
key: "purpose",
|
||||
label: "Назначение",
|
||||
render: (d) => <span className="text-xs border border-border rounded px-2 py-0.5">{d.purpose}</span>,
|
||||
},
|
||||
{
|
||||
key: "filter",
|
||||
label: "Фильтр",
|
||||
render: (d) => (
|
||||
<span className="inline-flex items-center gap-1 text-xs bg-muted rounded px-2 py-0.5">
|
||||
<FilterIcon className="size-3 text-muted-foreground" />{d.filter}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "updated",
|
||||
label: "Обновлён",
|
||||
render: (d) => <span className="text-xs text-muted-foreground">{d.updated}</span>,
|
||||
},
|
||||
{
|
||||
key: "enabled",
|
||||
label: "Статус",
|
||||
render: (d) => (
|
||||
<span className={`text-xs font-medium ${d.enabled ? "text-emerald-600" : "text-muted-foreground"}`}>
|
||||
{d.enabled ? "Активен" : "Отключён"}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<DataPageCard>
|
||||
<DataPageToolbar
|
||||
search={search}
|
||||
onSearchChange={setSearch}
|
||||
searchPlaceholder="Поиск по CIDR, ASN…"
|
||||
countLabel={`${filtered.length} диапазонов`}
|
||||
/>
|
||||
<IpRangesDataGrid
|
||||
ipRanges={filtered}
|
||||
isLoading={useEvoCatalog && loading && !snapshot}
|
||||
pagination={useEvoCatalog}
|
||||
/>
|
||||
</DataPageCard>
|
||||
</div>
|
||||
</div>
|
||||
<FileImportDialog
|
||||
|
||||
Reference in New Issue
Block a user