'use client'; import Link from 'next/link'; import {useMemo, useState} from 'react'; import {useMutation} from '@tanstack/react-query'; import {Eye, Pencil, 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, domains, certificates, routes, routesLoading = false, onChanged, }: { zoneId: number; domains: ZoneDomainItem[]; certificates: TlsCertificateItem[]; routes: ProxyRouteItem[]; routesLoading?: boolean; onChanged(): Promise | void; }) { const [editing, setEditing] = useState(undefined); 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} ))}
)}
{domain.remark || '—'} event.stopPropagation()} >
{domain.proxy_route_id ? ( 查看路由详情 ) : null} 编辑域名 删除域名
); })}
)} { if (!open) { setEditing(undefined); } }} zoneId={zoneId} domain={editing ?? null} onSaved={onChanged} /> { if (!open) { setDeleting(null); } }} > 确认删除域名 确认删除 {deleting?.domain} 吗?此操作不可撤销。 取消 { event.preventDefault(); if (deleting) { remove.mutate(deleting.id); } }} > {remove.isPending ? '删除中…' : '确认删除'} ); }