Build, Test, and Push CFDM Docker Image / test (push) Failing after 51s
Build, Test, and Push CFDM Docker Image / build-and-push (push) Has been skipped
Build, Test, and Push CFDM Docker Image / update-wiki (push) Has been skipped
Build, Test, and Push CFDM Docker Image / create-release (push) Has been skipped
143 lines
4.8 KiB
TypeScript
143 lines
4.8 KiB
TypeScript
import { useState } from 'react'
|
|
import { Link } from '@tanstack/react-router'
|
|
import { MoreHorizontalIcon } from 'lucide-react'
|
|
import { ConfirmDialog } from '@/components/confirm-dialog'
|
|
import type { SubdomainTableRow } from '@/hooks/use-domain-page'
|
|
import { formatSubdomainServiceLinks } from '@/hooks/use-domain-page'
|
|
import { formatDate } from '@/lib/format'
|
|
import { Badge } from '@cfdm/ui/components/badge'
|
|
import { Button } from '@cfdm/ui/components/button'
|
|
import {
|
|
DropdownMenu,
|
|
DropdownMenuContent,
|
|
DropdownMenuItem,
|
|
DropdownMenuSeparator,
|
|
DropdownMenuTrigger,
|
|
} from '@cfdm/ui/components/dropdown-menu'
|
|
import {
|
|
Table,
|
|
TableBody,
|
|
TableCell,
|
|
TableHead,
|
|
TableHeader,
|
|
TableRow,
|
|
} from '@cfdm/ui/components/table'
|
|
|
|
interface SubdomainsTableProps {
|
|
domainId: string
|
|
rows: SubdomainTableRow[]
|
|
isDeleting?: boolean
|
|
isToggling?: boolean
|
|
onEdit: (row: SubdomainTableRow) => void
|
|
onDelete: (row: SubdomainTableRow) => void
|
|
onToggleEnabled: (row: SubdomainTableRow) => void
|
|
}
|
|
|
|
export function SubdomainsTable({
|
|
domainId,
|
|
rows,
|
|
isDeleting = false,
|
|
isToggling = false,
|
|
onEdit,
|
|
onDelete,
|
|
onToggleEnabled,
|
|
}: SubdomainsTableProps) {
|
|
const [deleteTarget, setDeleteTarget] = useState<SubdomainTableRow | null>(null)
|
|
|
|
return (
|
|
<>
|
|
<div className="overflow-hidden rounded-lg border">
|
|
<Table>
|
|
<TableHeader>
|
|
<TableRow>
|
|
<TableHead>Поддомен</TableHead>
|
|
<TableHead>Статус</TableHead>
|
|
<TableHead>Группа / Сервис</TableHead>
|
|
<TableHead>Создан</TableHead>
|
|
<TableHead className="w-12">
|
|
<span className="sr-only">Действия</span>
|
|
</TableHead>
|
|
</TableRow>
|
|
</TableHeader>
|
|
<TableBody>
|
|
{rows.map((row) => (
|
|
<TableRow key={row.subdomain.id}>
|
|
<TableCell className="font-mono">{row.subdomain.fqdn}</TableCell>
|
|
<TableCell>
|
|
<Badge variant={row.subdomain.enabled ? 'default' : 'outline'}>
|
|
{row.subdomain.enabled ? 'Активен' : 'Неактивен'}
|
|
</Badge>
|
|
</TableCell>
|
|
<TableCell>{formatSubdomainServiceLinks(row.serviceLinks)}</TableCell>
|
|
<TableCell>{formatDate(row.subdomain.created_at)}</TableCell>
|
|
<TableCell className="text-right">
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger
|
|
render={
|
|
<Button variant="outline" size="icon" className="size-8" />
|
|
}
|
|
>
|
|
<MoreHorizontalIcon />
|
|
<span className="sr-only">Действия</span>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent align="end">
|
|
<DropdownMenuItem onClick={() => onEdit(row)}>
|
|
Редактировать
|
|
</DropdownMenuItem>
|
|
<DropdownMenuItem
|
|
disabled={isToggling}
|
|
onClick={() => onToggleEnabled(row)}
|
|
>
|
|
{row.subdomain.enabled ? 'Деактивировать' : 'Активировать'}
|
|
</DropdownMenuItem>
|
|
<DropdownMenuItem
|
|
render={
|
|
<Link
|
|
to="/domains/$domainId/dns"
|
|
params={{ domainId }}
|
|
search={{ host: row.subdomain.fqdn }}
|
|
/>
|
|
}
|
|
>
|
|
DNS-записи
|
|
</DropdownMenuItem>
|
|
<DropdownMenuSeparator />
|
|
<DropdownMenuItem
|
|
variant="destructive"
|
|
onClick={() => setDeleteTarget(row)}
|
|
>
|
|
Удалить
|
|
</DropdownMenuItem>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
</TableCell>
|
|
</TableRow>
|
|
))}
|
|
</TableBody>
|
|
</Table>
|
|
</div>
|
|
|
|
<ConfirmDialog
|
|
open={deleteTarget !== null}
|
|
onOpenChange={(open) => {
|
|
if (!open) setDeleteTarget(null)
|
|
}}
|
|
title="Удалить поддомен?"
|
|
description={
|
|
deleteTarget
|
|
? `Поддомен ${deleteTarget.subdomain.fqdn} будет удалён из менеджера.`
|
|
: ''
|
|
}
|
|
confirmLabel="Удалить"
|
|
onConfirm={() => {
|
|
if (deleteTarget) {
|
|
onDelete(deleteTarget)
|
|
setDeleteTarget(null)
|
|
}
|
|
}}
|
|
disabled={isDeleting}
|
|
/>
|
|
</>
|
|
)
|
|
}
|