fix(alerts): обозначить недоступность событий префиксов
This commit is contained in:
1 parent
f3ec6b31ce
commit
c7e1f75e2e
5 files changed
+29
-5
No files matched your search
@@ -710,12 +710,13 @@ function SeverityBadge({ severity }: { severity: AlertSeverity }) {
|
||||
|
||||
// ─── alert rule row ───────────────────────────────────────────────────────────
|
||||
|
||||
function AlertRuleRow({ rule, onToggle, onDelete, onEdit, interactionsDisabled }: {
|
||||
function AlertRuleRow({ rule, onToggle, onDelete, onEdit, interactionsDisabled,isLive }: {
|
||||
rule: AlertRule
|
||||
onToggle: (id: string, enabled: boolean) => void
|
||||
onDelete: (id: string) => void
|
||||
onEdit?: (id: string) => void
|
||||
interactionsDisabled?: boolean
|
||||
isLive:boolean
|
||||
}) {
|
||||
const { Icon, iconClass, bg } = TYPE_META[rule.type]
|
||||
|
||||
@@ -725,7 +726,7 @@ function AlertRuleRow({ rule, onToggle, onDelete, onEdit, interactionsDisabled }
|
||||
!rule.enabled && "opacity-55",
|
||||
)}>
|
||||
{/* toggle */}
|
||||
<FormToggle ariaLabel={"Включить правило "+rule.name} checked={rule.enabled} onChange={v => onToggle(rule.id, v)} disabled={interactionsDisabled} />
|
||||
<FormToggle ariaLabel={"Включить правило "+rule.name} checked={rule.enabled} onChange={v => onToggle(rule.id, v)} disabled={interactionsDisabled||(isLive&&rule.type==="bgp-prefix"&&!rule.enabled)} />
|
||||
|
||||
{/* severity dot */}
|
||||
<SeverityDot severity={rule.severity} />
|
||||
@@ -737,6 +738,7 @@ function AlertRuleRow({ rule, onToggle, onDelete, onEdit, interactionsDisabled }
|
||||
|
||||
{/* name + target */}
|
||||
<div className="flex-1 min-w-0">
|
||||
{isLive&&rule.type==="bgp-prefix"?<p role="status" className="text-xs text-warning">Отслеживание появления и отзыва префиксов пока недоступно. Это правило не проверяется.</p>:null}
|
||||
<p className="text-sm font-medium truncate">{rule.name}</p>
|
||||
<p className="text-[11px] text-muted-foreground truncate">
|
||||
{TYPE_META[rule.type].label} ·{" "}
|
||||
@@ -1722,6 +1724,8 @@ function AddRuleSheet({
|
||||
{/* ── scrollable body ── */}
|
||||
<fieldset disabled={saving} className="min-h-0 min-w-0 flex-1 overflow-y-auto px-4 sm:px-6 py-5 flex flex-col gap-5 [&>div]:shrink-0">
|
||||
|
||||
{isLive&&form.type==="bgp-prefix"?<p role="status" className="text-xs text-warning">Отслеживание появления и отзыва префиксов пока недоступно. Сохранённое правило не проверяется; можно изменить его тип или отключить в списке.</p>:null}
|
||||
|
||||
{/* name */}
|
||||
<div className="flex flex-col gap-1.5">
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
@@ -1768,6 +1772,7 @@ function AddRuleSheet({
|
||||
key={t}
|
||||
type="button"
|
||||
aria-pressed={active}
|
||||
disabled={isLive&&t==="bgp-prefix"}
|
||||
|
||||
onClick={() => {
|
||||
nameTouchedRef.current = false
|
||||
@@ -1801,7 +1806,7 @@ function AddRuleSheet({
|
||||
{active && <CheckIcon className="size-3.5 shrink-0 text-primary" />}
|
||||
</div>
|
||||
<span className="text-[10px] text-muted-foreground leading-tight pl-0">
|
||||
{TYPE_EVENT_CARD_DESC[t]}
|
||||
{isLive&&t==="bgp-prefix"?"Отслеживание префиксов пока недоступно":TYPE_EVENT_CARD_DESC[t]}
|
||||
</span>
|
||||
</button>
|
||||
)
|
||||
@@ -2739,6 +2744,7 @@ function AlertsContent() {
|
||||
onDelete={id=>setPendingDelete({kind:"rule",id})}
|
||||
onEdit={openRuleSheetEdit}
|
||||
interactionsDisabled={writesDisabled}
|
||||
isLive={isLive}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
|
||||
## Актуальная точка продолжения — 2026-10-03
|
||||
|
||||
Этап 11Б в работе; последний проверенный блок 11Б.4.4.3.9; System DB принят локально с внешними ограничениями. Следующий блок 11Б.4.4.3.10: явно обозначить неподдерживаемый BGP-prefix evaluator в live UI, затем production build накопленных изменений. Далее processing recovery, компактность основной Alerts страницы, Releases/probe scheduling и приёмка 11Б/12.
|
||||
Этап 11Б в работе; последний проверенный блок 11Б.4.4.3.10; System DB принят локально с внешними ограничениями. Следующий блок 11Б.4.4.3.11: компактность основной Alerts страницы и профильная приёмка ПК/320px; processing recovery проектировать отдельно с доказуемой остановкой всех отправителей. Затем Releases/probe scheduling и приёмка 11Б/12. Внешняя PG/Telegram приёмка обязательна перед выпуском.
|
||||
|
||||
Реальные pg_dump/pg_restore, PG rollback и остановка UDP worker требуют внешней приёмки. Датированные продолжения ниже — история; точный следующий шаг также указан в начале [журнала](ux-ui-progress.md).
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
| 9 | VPN, Firewall и Filters | Завершён в границах локальной приёмки 2026-09-30; блоки 9.1–9.64, ограничения в 9.64 |
|
||||
| 10 | Маршрутизация, диагностика, карта и терминал | Завершён в границах локальной приёмки 2026-10-01; блоки 10.1–10.71, внешние ограничения в 10.71 |
|
||||
| 11А | Пользователи, контейнеры, сертификаты и резервные копии | Завершён в границах локальной приёмки 2026-10-01; 11А.1–11А.33, внешние ограничения в 11А.33 |
|
||||
| 11Б | Оповещения, сбор данных, интеграции, релизы и настройки | В работе: 11Б.1–11Б.4.4.3.9; scheduler и GeoIP приняты локально; NetFlow принят локально; Evolution принят локально; далее общие Settings |
|
||||
| 11Б | Оповещения, сбор данных, интеграции, релизы и настройки | В работе: 11Б.1–11Б.4.4.3.10; scheduler и GeoIP приняты локально; NetFlow принят локально; Evolution принят локально; далее общие Settings |
|
||||
| 12 | Итоговая доступность, адаптивность, производительность и регрессия | Не начат |
|
||||
|
||||
|
||||
@@ -36,6 +36,14 @@
|
||||
|
||||
|
||||
|
||||
## Блок 11Б.4.4.3.10 — честная доступность BGP-prefix и сборка (2026-10-03)
|
||||
|
||||
- Backend evaluate-rule для bgp-prefix возвращает null; live UI теперь прямо сообщает, что сохранённое правило не проверяется. Выбор этого типа для нового правила недоступен, выключенное legacy правило нельзя включить через switch. Existing enabled запись можно отключить; редактирование/смена типа/удаление сохраняются. Mock демонстрация и backend policies не менялись.
|
||||
- Это честное ограничение UI, не реализация мониторинга prefix UPDATE и не запрет прямого API. Backend контракт сохраняет legacy тип для совместимости; внешнему клиенту нельзя считать его поддерживаемым по одному enabled:true.
|
||||
- 12 browser picker/prefix/rules, typecheck/lint прошли. Финальная production build frontend/contracts и backend build прошли; Alerts DI/HTTP/реальные JWT gates и sidebar-counts профиль повторно прошли на итоговом состоянии. ReUI Frame checklist применён к адаптации; глобальную ReUI/этап12 приёмку не объявляем.
|
||||
- Полная Alerts приёмка не завершена: основная страница требует компактности, processing recovery не реализован; реальный PG isolation/CAS/rollback, migrations0008/0009 и Telegram не проверены. Все выполненные блоки сохранены локально без push; чужие изменения skill/AGENTS/config/cache не включены.
|
||||
- Следующий точный шаг 11Б.4.4.3.11: компактность основной Alerts страницы и профильная приёмка ПК/320px; processing recovery проектировать отдельно с доказуемой остановкой всех отправителей. Затем Releases/probe scheduling и приёмка 11Б/12. Внешняя PG/Telegram приёмка обязательна перед выпуском.
|
||||
|
||||
## Блок 11Б.4.4.3.9 — доступный выбор и одна прокрутка формы (2026-10-03)
|
||||
|
||||
- Existing object/condition cards теперь native toggle buttons с aria-pressed в labelled group: UI не обещает listbox/option keyboard model без реализации arrow navigation. Type cards тоже сообщают выбранное состояние. Manual object input имеет имя. Список объектов доступен сразу, не требует фокуса на постороннем поле.
|
||||
|
||||
@@ -316,3 +316,7 @@ Backend sidebar optional counts не выдают timeout/partial/error как0,
|
||||
### Продолжение 2026-10-03 — 11Б.4.4.3.9
|
||||
|
||||
Picker keyboard semantics/one parent scroll/initial objects accepted locally; browser21/typecheck/lint/ReUI audit passed, 320px screenshot reviewed. Общий Alerts экран не принят. Следующий блок 11Б.4.4.3.10: явно обозначить неподдерживаемый BGP-prefix evaluator в live UI, затем production build накопленных изменений. Далее processing recovery, компактность основной Alerts страницы, Releases/probe scheduling и приёмка 11Б/12.
|
||||
|
||||
### Продолжение 2026-10-03 — 11Б.4.4.3.10
|
||||
|
||||
Live BGP-prefix честно помечен unsupported, legacy записи не удалены; browser12/typecheck/lint и production frontend/contracts/backend build прошли. Финальный Alerts/backend sidebar профиль прошёл. Основной Alerts экран/processing recovery/внешняя PG и Telegram приёмка остаются. Следующий блок 11Б.4.4.3.11: компактность основной Alerts страницы и профильная приёмка ПК/320px; processing recovery проектировать отдельно с доказуемой остановкой всех отправителей. Затем Releases/probe scheduling и приёмка 11Б/12. Внешняя PG/Telegram приёмка обязательна перед выпуском.
|
||||
@@ -0,0 +1,6 @@
|
||||
import {test,expect} from "@playwright/test"
|
||||
import {emptyAlerts,emptyOutbox,alertsRule} from "./fixtures/alerts"
|
||||
test("Unsupported BGP prefix is visible as unavailable, existing disabled rule cannot be enabled and remains editable",async({page})=>{
|
||||
let writes=0;const rule={...alertsRule,id:"prefix",name:"Legacy prefix",type:"bgp-prefix",groupId:null,enabled:false,target:"любой префикс",targets:["любой префикс"],condition:"был отозван",conditions:["был отозван"]}
|
||||
await page.route("**/health",r=>r.fulfill({json:{status:"ok"}}));await page.route("**/api/**",r=>{const path=new URL(r.request().url()).pathname;if(r.request().method()!=="GET")writes++;return r.fulfill({json:path==="/api/auth/config"?{required:false}:path==="/api/alerts"?{...emptyAlerts,rules:[rule]}:path==="/api/alerts/outbox"?emptyOutbox:path==="/api/filters/gre-tunnels"?{tunnels:[],failures:[]}:[]})});await page.goto("/alerts");await expect(page.getByText("Отслеживание появления и отзыва префиксов пока недоступно. Это правило не проверяется.")).toBeVisible();await expect(page.getByRole("switch",{name:"Включить правило Legacy prefix"})).toBeDisabled();await page.getByRole("button",{name:"Изменить правило Legacy prefix"}).click();const dialog=page.getByRole("dialog");await expect(dialog.getByRole("status")).toContainText("Сохранённое правило не проверяется");await expect(dialog.getByRole("button",{name:/^BGP-префикс/})).toBeDisabled();await dialog.getByRole("button",{name:/^Сервер Доступность/}).click();await expect(dialog.getByRole("status")).toHaveCount(0);expect(writes).toBe(0)
|
||||
})
|
||||
Reference in new issue
Block a user