From b47c5645d599b32eea3683a88a8fae44673c9b5c Mon Sep 17 00:00:00 2001 From: Denozordec Date: Wed, 30 Sep 2026 10:13:11 +0700 Subject: [PATCH] =?UTF-8?q?fix(ui):=20=D0=BF=D0=BE=D0=B4=D1=82=D0=B2=D0=B5?= =?UTF-8?q?=D1=80=D0=B6=D0=B4=D0=B0=D1=82=D1=8C=20=D1=81=D0=BE=D1=85=D1=80?= =?UTF-8?q?=D0=B0=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=84=D0=BE=D1=80=D0=BC?= =?UTF-8?q?=20Firewall?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/(main)/firewall/page.tsx | 99 +++++++++++++++++++++------------ docs/ux-ui-plan.md | 4 +- docs/ux-ui-progress.md | 10 +++- docs/ux-ui-stage-9.md | 4 ++ tests/e2e/firewall-save.spec.ts | 81 +++++++++++++++++++++++++++ 5 files changed, 160 insertions(+), 38 deletions(-) create mode 100644 tests/e2e/firewall-save.spec.ts diff --git a/app/(main)/firewall/page.tsx b/app/(main)/firewall/page.tsx index f7078da1..382c503e 100644 --- a/app/(main)/firewall/page.tsx +++ b/app/(main)/firewall/page.tsx @@ -486,7 +486,7 @@ function generateRsc(rules: FirewallRule[], timestamp?: string): string { // ─── Rule Sheet ─────────────────────────────────────────────────────────────── -function RuleSheet({ open, onClose, initialRule, chainGroup, family, onSave, saving = false }: { +function RuleSheet({ open, onClose, initialRule, chainGroup, family, onSave, saving = false, error }: { open: boolean onClose: () => void initialRule: Partial | null @@ -494,6 +494,7 @@ function RuleSheet({ open, onClose, initialRule, chainGroup, family, onSave, sav family: IpFamily onSave: (payload: RuleWritePayload) => void saving?: boolean + error?: string | null }) { const isNew = !initialRule?.id const [form, setForm] = useState(defaultForm) @@ -530,8 +531,8 @@ function RuleSheet({ open, onClose, initialRule, chainGroup, family, onSave, sav : ["accept", "drop", "reject", "fasttrack-connection", "add-src-to-address-list", "add-dst-to-address-list", "passthrough"] return ( - { if (!v) onClose() }}> - + { if (!v && !saving) onClose() }}> + {isNew ? "Новое правило" : "Редактировать правило"} @@ -539,7 +540,7 @@ function RuleSheet({ open, onClose, initialRule, chainGroup, family, onSave, sav -
+
{/* Chain + Action */}
@@ -616,7 +617,7 @@ function RuleSheet({ open, onClose, initialRule, chainGroup, family, onSave, sav

Log

Записывать совпадения в системный лог

- set("log", v)} /> + set("log", v)} />
{form.log && ( @@ -636,7 +637,7 @@ function RuleSheet({ open, onClose, initialRule, chainGroup, family, onSave, sav

Правило включено

Отключённые правила сохраняются, но не применяются

- set("enabled", v)} /> + set("enabled", v)} /> {/* CLI preview */} @@ -669,10 +670,12 @@ function RuleSheet({ open, onClose, initialRule, chainGroup, family, onSave, sav ].filter(Boolean).join("\n")} - + + {saving &&

Ожидание результата сохранения…

} + {error &&

{error}

} - }>Отмена + }>Отмена