fix(ui): подтверждать удаление туннеля GRE
This commit is contained in:
1 parent
f5b64ea154
commit
780d5e9237
5 files changed
+80
-10
No files matched your search
+14
-6
@@ -275,6 +275,8 @@ function GrePageContent({ selectedServerId, selectedTunnelId, allTunnelsHref, on
|
||||
const [tunnelMode, setTunnelMode] = useState<"create" | "edit">("create")
|
||||
const [editingTunnel, setEditingTunnel] = useState<GreTunnel | null>(null)
|
||||
const [pendingDelete, setPendingDelete] = useState<GreTunnel | null>(null)
|
||||
const deleteLock = useRef(false)
|
||||
const [deleteError, setDeleteError] = useState<string | null>(null)
|
||||
const [mutateBusy, setMutateBusy] = useState(false)
|
||||
const [liveStale, setLiveStale] = useState(false)
|
||||
const [historyOpen, setHistoryOpen] = useState(false)
|
||||
@@ -506,19 +508,23 @@ function GrePageContent({ selectedServerId, selectedTunnelId, allTunnelsHref, on
|
||||
|
||||
async function confirmDeleteTunnel() {
|
||||
const t = pendingDelete
|
||||
if (!t || !isLive) return
|
||||
if (!t || !isLive || mutationsLocked || deleteLock.current) return
|
||||
deleteLock.current = true
|
||||
setDeleteError(null)
|
||||
setMutateBusy(true)
|
||||
try {
|
||||
await apiFetch("/api/gre/tunnels", {
|
||||
const result = await apiFetch<{ ok: boolean }>("/api/gre/tunnels", {
|
||||
method: "DELETE",
|
||||
body: JSON.stringify({ serverId: t.serverId, rosId: t.id, name: t.name }),
|
||||
})
|
||||
if (result?.ok !== true) throw new Error("Сервер не подтвердил удаление туннеля")
|
||||
toast.success(`Удалён ${t.name}`)
|
||||
setPendingDelete(null)
|
||||
await loadLive()
|
||||
} catch (err) {
|
||||
toast.error("Не удалось удалить туннель", { description: String(err) })
|
||||
setDeleteError(err instanceof Error ? err.message : "Не удалось удалить туннель")
|
||||
} finally {
|
||||
deleteLock.current = false
|
||||
setMutateBusy(false)
|
||||
}
|
||||
}
|
||||
@@ -1091,7 +1097,7 @@ function GrePageContent({ selectedServerId, selectedTunnelId, allTunnelsHref, on
|
||||
onRestore={restoreRevision}
|
||||
/>
|
||||
|
||||
<AlertDialog open={!!pendingDelete} onOpenChange={(v) => { if (!v) setPendingDelete(null) }}>
|
||||
<AlertDialog open={!!pendingDelete} onOpenChange={(v) => { if (!v && !deleteLock.current) { setPendingDelete(null); setDeleteError(null) } }}>
|
||||
<AlertDialogContent size="default">
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogMedia className="bg-destructive/10 text-destructive">
|
||||
@@ -1103,10 +1109,12 @@ function GrePageContent({ selectedServerId, selectedTunnelId, allTunnelsHref, on
|
||||
? `${pendingDelete.name} на сервере ${serverById[pendingDelete.serverId]?.name ?? pendingDelete.serverId}. Будут удалены интерфейс и связанный /ip/address.`
|
||||
: null}
|
||||
</AlertDialogDescription>
|
||||
{mutateBusy && <p role="status" className="text-sm text-muted-foreground">Ожидание результата удаления…</p>}
|
||||
{deleteError && <p role="alert" className="text-sm text-destructive">{deleteError}</p>}
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel onClick={() => setPendingDelete(null)}>Отмена</AlertDialogCancel>
|
||||
<AlertDialogAction variant="destructive" onClick={() => void confirmDeleteTunnel()}>
|
||||
<AlertDialogCancel disabled={mutateBusy}>Отмена</AlertDialogCancel>
|
||||
<AlertDialogAction variant="destructive" disabled={mutationsLocked} onClick={(e) => { e.preventDefault(); void confirmDeleteTunnel() }}>
|
||||
Удалить
|
||||
</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
|
||||
Reference in new issue
Block a user