'use client'; import Link from 'next/link'; import { useMemo, useState } from 'react'; import { useMutation } from '@tanstack/react-query'; import { Eye, Plus, Trash2 } from 'lucide-react'; import { toast } from 'sonner'; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from '@/components/ui/alert-dialog'; import { Button } from '@/components/ui/button'; import { EmptyStateWithBorder } from '@/components/layout/empty'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '@/components/ui/table'; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from '@/components/ui/tooltip'; import { ZoneDomainService, type ProxyRouteItem, type TlsCertificateItem, type ZoneDomainItem, } from '@/lib/services/openflare'; import { getUpstreamLabels } from '../../../proxy-routes/components/helpers'; import { ZoneDomainDialog } from './zone-domain-dialog'; export function ZoneDomainsTable({ zoneId, zoneRoot, domains, certificates, routes, routesLoading = false, onChanged, }: { zoneId: number; zoneRoot: string; domains: ZoneDomainItem[]; certificates: TlsCertificateItem[]; routes: ProxyRouteItem[]; routesLoading?: boolean; onChanged(): Promise | void; }) { const [createOpen, setCreateOpen] = useState(false); const [deleting, setDeleting] = useState(null); const remove = useMutation({ mutationFn: (id: number) => ZoneDomainService.deleteById(zoneId, id), onSuccess: async () => { toast.success('域名已删除'); setDeleting(null); await onChanged(); }, onError: (error) => toast.error(error instanceof Error ? error.message : '删除失败'), }); const certificateMap = useMemo( () => new Map(certificates.map((certificate) => [certificate.id, certificate])), [certificates], ); const routeMap = useMemo( () => new Map(routes.map((route) => [route.id, route])), [routes], ); return ( <>
{domains.length === 0 ? ( ) : (
FQDN 证书 上游 操作 {domains.map((domain) => { const route = domain.proxy_route_id != null ? routeMap.get(domain.proxy_route_id) : undefined; const upstreams = route ? getUpstreamLabels(route) : []; const certLabel = domain.cert_id ? (certificateMap.get(domain.cert_id)?.name ?? `证书 #${domain.cert_id}`) : '未绑定'; return ( {domain.domain} {certLabel} {!domain.proxy_route_id ? ( 未关联路由 ) : routesLoading && !route ? ( 加载中… ) : upstreams.length === 0 ? ( 未配置上游 ) : (
{upstreams.map((upstream) => ( {upstream} ))}
)}
event.stopPropagation()} >
{domain.proxy_route_id ? ( 查看路由详情 ) : null} 删除域名
); })}
)} { if (!open) { setDeleting(null); } }} > 确认删除域名 确认删除 {deleting?.domain} 吗?此操作不可撤销。 取消 { event.preventDefault(); if (deleting) { remove.mutate(deleting.id); } }} > {remove.isPending ? '删除中…' : '确认删除'} ); }