fix(ui): подтверждать удаление правил Filters

This commit is contained in:
Denozordec committed 2026-09-30 11:29:54 +07:00
1 parent 8412ba9bbe
commit c4011cfaff
6 files changed
+154 -19

No files matched your search

+57 -2
View File
@@ -32,6 +32,7 @@ import {
import {
Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription, SheetFooter,
} from "@/components/ui/sheet"
import { AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, AlertDialogAction } from "@/components/ui/alert-dialog"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"
import { toast } from "sonner"
@@ -1356,6 +1357,10 @@ export default function FiltersPage() {
const [copyOpen, setCopyOpen] = useState(false)
const [applyBusy, setApplyBusy] = useState(false)
const applyLock = useRef(false)
const [pendingDelete, setPendingDelete] = useState<{ serverId: string; serverName: string; rule: FilterRule } | null>(null)
const [deletePending, setDeletePending] = useState(false)
const [deleteError, setDeleteError] = useState<string | null>(null)
const deleteLock = useRef(false)
const [liveStale, setLiveStale] = useState(false)
const [historyOpen, setHistoryOpen] = useState(false)
const [historyLoading, setHistoryLoading] = useState(false)
@@ -1472,6 +1477,8 @@ export default function FiltersPage() {
const handleSelectServer = useCallback((id: string) => {
if (applyLock.current) return
setSheetOpen(false)
setPendingDelete(null)
setDeleteError(null)
setSelectedServerId(id)
setSearch("")
}, [])
@@ -1632,8 +1639,36 @@ export default function FiltersPage() {
}
const handleDelete = (id: string) => {
if (mutationsLocked) return
updateRules(selectedServerId, rules => rules.filter(r => r.id !== id))
if (mutationsLocked || applyLock.current) return
const rule = currentRules.find(r => r.id === id)
if (!rule || !selectedServer) return
setDeleteError(null)
setPendingDelete({ serverId: selectedServerId, serverName: selectedServer.name, rule })
}
const confirmDelete = async () => {
if (!pendingDelete || deleteLock.current) return
if (mutationsLocked || applyLock.current) {
setDeleteError("Дождитесь завершения операции или обновите данные")
return
}
const current = rulesets.find(rs => rs.serverId === pendingDelete.serverId)?.rules
if (!current?.some(r => r.id === pendingDelete.rule.id)) {
setDeleteError("Правило отсутствует в текущем списке — обновите данные")
return
}
deleteLock.current = true
setDeletePending(true)
setDeleteError(null)
try {
const result = await applyRules(pendingDelete.serverId, current.filter(r => r.id !== pendingDelete.rule.id))
if (!result.ok) setDeleteError(result.error ?? "Не удалось удалить правило")
else setPendingDelete(null)
} catch (error) {
setDeleteError(error instanceof Error ? error.message : "Не удалось удалить правило")
} finally {
deleteLock.current = false
setDeletePending(false)
}
}
const handleCopyRules = useCallback(async (targetServerId: string, rules: FilterRule[], mode: CopyMode) => {
@@ -1884,6 +1919,26 @@ export default function FiltersPage() {
</div>
</ServerRailLayout>
<AlertDialog open={!!pendingDelete} onOpenChange={open => {
if (!open && !deleteLock.current) { setPendingDelete(null); setDeleteError(null) }
}}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Удалить правило Filters?</AlertDialogTitle>
<AlertDialogDescription>
Community {pendingDelete?.rule.community} · {pendingDelete?.serverName}.
Правило будет удалено из набора фильтров устройства.
</AlertDialogDescription>
{deletePending && <p role="status" className="text-sm text-muted-foreground">Ожидание подтверждения удаления…</p>}
{deleteError && <p role="alert" className="text-sm text-destructive">{deleteError}</p>}
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel disabled={deletePending}>Отмена</AlertDialogCancel>
<AlertDialogAction variant="destructive" disabled={deletePending || mutationsLocked} onClick={e => { e.preventDefault(); void confirmDelete() }}>Удалить</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
<RuleSheet
key={`${sheetOpen}-${sheetMode}-${editingId ?? "new"}-${selectedServerId}`}
open={sheetOpen}