fix(ui): читать актуальную цель копирования Filters
This commit is contained in:
1 parent
365ab2173c
commit
860e88ed3e
5 files changed
+99
-10
No files matched your search
@@ -1527,7 +1527,7 @@ function FiltersPage() {
|
||||
|
||||
const applyRules = useCallback(async (
|
||||
serverId: string,
|
||||
nextRules: FilterRule[],
|
||||
nextRules: FilterRule[] | (() => Promise<FilterRule[]>),
|
||||
source: "apply" | "copy" = "apply",
|
||||
) => {
|
||||
if (!mounted.current) return { ok: false, error: "Источник данных изменён" }
|
||||
@@ -1538,7 +1538,8 @@ function FiltersPage() {
|
||||
return { ok: false, error }
|
||||
}
|
||||
if (!isLive) {
|
||||
setRulesets(p => p.map(rs => rs.serverId === serverId ? { ...rs, rules: nextRules } : rs))
|
||||
const rules = typeof nextRules === "function" ? await nextRules() : nextRules
|
||||
setRulesets(p => p.map(rs => rs.serverId === serverId ? { ...rs, rules } : rs))
|
||||
return { ok: true }
|
||||
}
|
||||
applyLock.current = true
|
||||
@@ -1546,15 +1547,17 @@ function FiltersPage() {
|
||||
setRulesReading(false)
|
||||
setApplyBusy(true)
|
||||
try {
|
||||
const rules = typeof nextRules === "function" ? await nextRules() : nextRules
|
||||
if (!mounted.current) return { ok: false, error: "Источник данных изменён" }
|
||||
const payload = await apiFetch<unknown>("/api/filters/rules", {
|
||||
method: "PUT",
|
||||
body: JSON.stringify({ serverId, rules: nextRules, source }),
|
||||
body: JSON.stringify({ serverId, rules, source }),
|
||||
})
|
||||
if (!mounted.current) return { ok: false, error: "Источник данных изменён" }
|
||||
const parsed = filtersMutationSchema.safeParse(payload)
|
||||
if (!parsed.success) throw new Error("Сервер не подтвердил применение правил")
|
||||
const res = parsed.data
|
||||
setRulesets(p => p.map(rs => rs.serverId === serverId ? { ...rs, rules: res.rules ?? nextRules } : rs))
|
||||
setRulesets(p => p.map(rs => rs.serverId === serverId ? { ...rs, rules: res.rules ?? rules } : rs))
|
||||
toast.success("Правила применены на роутер")
|
||||
return { ok: true }
|
||||
} catch (err) {
|
||||
@@ -1718,11 +1721,20 @@ function FiltersPage() {
|
||||
}
|
||||
|
||||
const handleCopyRules = useCallback(async (targetServerId: string, rules: FilterRule[], mode: CopyMode) => {
|
||||
const existing = rulesets.find((rs) => rs.serverId === targetServerId)?.rules ?? []
|
||||
const next = mode === "replace" ? rules : [...existing, ...rules]
|
||||
const result = await applyRules(targetServerId, next, "copy")
|
||||
const prepare = async () => {
|
||||
const payload = await apiFetch<unknown>(`/api/filters/rules?serverId=${encodeURIComponent(targetServerId)}`)
|
||||
if (!mounted.current) throw new Error("Источник данных изменён")
|
||||
const parsed = filtersResponseSchema.safeParse(payload)
|
||||
const target = parsed.success ? parsed.data.rulesets.find(rs => rs.serverId === targetServerId) : undefined
|
||||
if (!parsed.success || !target || parsed.data.stale || parsed.data.live !== true) throw new Error("Не удалось получить актуальные правила целевого устройства")
|
||||
setRulesets(prev => prev.map(rs => rs.serverId === targetServerId ? { ...rs, rules: target.rules } : rs))
|
||||
return mode === "replace" ? rules : [...target.rules, ...rules]
|
||||
}
|
||||
const existing = rulesets.find(rs => rs.serverId === targetServerId)?.rules ?? []
|
||||
const localRules = mode === "replace" ? rules : [...existing, ...rules]
|
||||
const result = await applyRules(targetServerId, isLive ? prepare : localRules, "copy")
|
||||
return result.ok ? null : result.error ?? "Не удалось скопировать правила"
|
||||
}, [rulesets, applyRules])
|
||||
}, [rulesets, applyRules, apiFetch, isLive])
|
||||
const handleMove = async (id: string, direction: -1 | 1) => {
|
||||
if (mutationsLocked || applyLock.current || moveLock.current) return
|
||||
const index = currentRules.findIndex(r => r.id === id)
|
||||
|
||||
Reference in new issue
Block a user