fix(ui): повысить контраст заполненных таблиц BGP и OSPF

This commit is contained in:
Denozordec committed 2026-10-14 01:05:45 +07:00
1 parent d91cc77cda
commit 8b60ab040a
16 files changed
+1291 -101

No files matched your search

+3 -5
View File
@@ -15,7 +15,7 @@ import { DataPageToolbar } from "@/components/data-page-toolbar"
import { PageHeader } from "@/components/page-header" import { PageHeader } from "@/components/page-header"
import { DataPageCard } from "@/components/data-page-card" import { DataPageCard } from "@/components/data-page-card"
import { OspfNeighborsDataGrid } from "@/components/data-grids/ospf-neighbors-data-grid" import { OspfNeighborsDataGrid } from "@/components/data-grids/ospf-neighbors-data-grid"
import { OspfRoutesDataGrid, routeTypeClass } from "@/components/data-grids/ospf-routes-data-grid" import { OspfRoutesDataGrid, OspfRouteTypeBadge } from "@/components/data-grids/ospf-routes-data-grid"
import { OspfBfdDataGrid } from "@/components/data-grids/ospf-bfd-data-grid" import { OspfBfdDataGrid } from "@/components/data-grids/ospf-bfd-data-grid"
import { Frame, FramePanel } from "@/components/reui/frame" import { Frame, FramePanel } from "@/components/reui/frame"
import { KpiStatGrid } from "@/components/reui-kit/kpi-stat-grid" import { KpiStatGrid } from "@/components/reui-kit/kpi-stat-grid"
@@ -1026,9 +1026,7 @@ function RoutesTab({ routes, hasSearch }: { routes: OspfRoute[]; hasSearch: bool
<div className="flex items-center gap-3 flex-wrap"> <div className="flex items-center gap-3 flex-wrap">
<span className="text-sm font-medium">{routes.some(r => r.dataUnknown) ? "Последний снимок: " : ""}{routes.length} маршрутов</span> <span className="text-sm font-medium">{routes.some(r => r.dataUnknown) ? "Последний снимок: " : ""}{routes.length} маршрутов</span>
{typeCount.map(([type, count]) => ( {typeCount.map(([type, count]) => (
<span key={type} className={cn("inline-flex items-center rounded border px-2 py-0.5 text-[11px] font-medium", routeTypeClass(type as OspfRoute["type"]))}> <OspfRouteTypeBadge key={type} type={type as OspfRoute["type"]} count={count} />
{type === "Unknown" ? "Тип неизвестен" : type}: {count}
</span>
))} ))}
</div> </div>
<DataPageCard> <DataPageCard>
@@ -1043,7 +1041,7 @@ function RoutesTab({ routes, hasSearch }: { routes: OspfRoute[]; hasSearch: bool
{ type: "O E2", desc: "External Type 2" }, { type: "O E2", desc: "External Type 2" },
] as const).map(({ type, desc }) => ( ] as const).map(({ type, desc }) => (
<span key={type} className="flex items-center gap-1.5 text-xs text-muted-foreground"> <span key={type} className="flex items-center gap-1.5 text-xs text-muted-foreground">
<span className={cn("inline-flex items-center rounded border px-1.5 py-0.5 text-[10px] font-medium", routeTypeClass(type))}>{type}</span> <OspfRouteTypeBadge type={type} />
{desc} {desc}
</span> </span>
))} ))}
@@ -8,6 +8,7 @@ import {
useTable, useTable,
} from "@tanstack/react-table" } from "@tanstack/react-table"
import { cn } from "@/lib/utils" import { cn } from "@/lib/utils"
import { Badge } from "@/components/reui/badge"
import { DataGridShell } from "@/components/data-grids/shared/data-grid-shell" import { DataGridShell } from "@/components/data-grids/shared/data-grid-shell"
import { import {
DATA_GRID_CELL_PAD, DATA_GRID_CELL_PAD,
@@ -22,83 +23,20 @@ import { BGP_AS_NAMES } from "@/lib/bgp/types"
import { fmtBgpNum } from "@/lib/bgp/helpers" import { fmtBgpNum } from "@/lib/bgp/helpers"
import { ChevronDownIcon, ChevronRightIcon, NetworkIcon } from "lucide-react" import { ChevronDownIcon, ChevronRightIcon, NetworkIcon } from "lucide-react"
const STATE_STYLE: Record<BgpState, { bg: string; text: string; dot: string; label: string }> = { const STATE_DOT: Record<BgpState, string> = {
Unknown: { bg: "bg-muted", text: "text-muted-foreground", dot: "bg-muted-foreground", label: "Неизвестно" }, Unknown: "bg-muted-foreground", Established: "bg-success", Active: "bg-warning",
Established: { Idle: "bg-muted-foreground", Connect: "bg-info", OpenSent: "bg-info", OpenConfirm: "bg-info",
bg: "bg-emerald-500/10",
text: "text-emerald-600 dark:text-emerald-400",
dot: "bg-emerald-500",
label: "Established",
},
Active: {
bg: "bg-amber-500/10",
text: "text-amber-600 dark:text-amber-400",
dot: "bg-amber-500",
label: "Active",
},
Idle: {
bg: "bg-slate-500/10",
text: "text-slate-500 dark:text-slate-400",
dot: "bg-slate-500",
label: "Idle",
},
Connect: {
bg: "bg-blue-500/10",
text: "text-blue-600 dark:text-blue-400",
dot: "bg-blue-500",
label: "Connect",
},
OpenSent: {
bg: "bg-violet-500/10",
text: "text-violet-600 dark:text-violet-400",
dot: "bg-violet-500",
label: "OpenSent",
},
OpenConfirm: {
bg: "bg-violet-500/10",
text: "text-violet-600 dark:text-violet-400",
dot: "bg-violet-500",
label: "OpenConfirm",
},
}
const TYPE_STYLE: Record<BgpType, { bg: string; text: string }> = {
Unknown: { bg: "bg-muted", text: "text-muted-foreground" },
eBGP: { bg: "bg-blue-500/10", text: "text-blue-600 dark:text-blue-400" },
iBGP: { bg: "bg-purple-500/10", text: "text-purple-600 dark:text-purple-400" },
} }
function StateBadge({ state }: { state: BgpState }) { function StateBadge({ state }: { state: BgpState }) {
const s = STATE_STYLE[state] return <Badge variant="invert-light" size="sm">
return ( <span aria-hidden="true" className={cn("size-1.5 rounded-full shrink-0", STATE_DOT[state])} />
<span {state === "Unknown" ? "Неизвестно" : state}
className={cn( </Badge>
"inline-flex items-center gap-1.5 rounded border px-2 py-0.5 text-[11px] font-semibold",
s.bg,
s.text,
"border-current/20",
)}
>
<span className={cn("size-1.5 rounded-full shrink-0", s.dot)} />
{s.label}
</span>
)
} }
function TypeBadge({ type }: { type: BgpType }) { function TypeBadge({ type }: { type: BgpType }) {
const s = TYPE_STYLE[type] return <Badge variant="invert-light" size="sm">{type === "Unknown" ? "Тип неизвестен" : type}</Badge>
return (
<span
className={cn(
"inline-flex items-center rounded border px-1.5 py-0.5 text-[10px] font-semibold",
s.bg,
s.text,
"border-current/20",
)}
>
{type === "Unknown" ? "Тип неизвестен" : type}
</span>
)
} }
interface BgpSessionsDataGridProps { interface BgpSessionsDataGridProps {
@@ -227,7 +165,7 @@ function BgpSessionsDataGrid({ sessions, emptyTitle, selectedSessionId, onSelect
cell: ({ row }) => { cell: ({ row }) => {
const n = row.original.prefixesRx const n = row.original.prefixesRx
return n !== null ? ( return n !== null ? (
<span className="font-mono tabular-nums text-emerald-600 dark:text-emerald-400 text-right block"> <span className="font-mono tabular-nums text-right block">
{fmtBgpNum(n)} {fmtBgpNum(n)}
</span> </span>
) : ( ) : (
@@ -8,6 +8,7 @@ import {
useTable, useTable,
} from "@tanstack/react-table" } from "@tanstack/react-table"
import { cn } from "@/lib/utils" import { cn } from "@/lib/utils"
import { Badge } from "@/components/reui/badge"
import { DataGridShell } from "@/components/data-grids/shared/data-grid-shell" import { DataGridShell } from "@/components/data-grids/shared/data-grid-shell"
import { import {
DATA_GRID_CELL_PAD, DATA_GRID_CELL_PAD,
@@ -31,12 +32,10 @@ export interface OspfRouteRow {
area: string area: string
} }
function routeTypeClass(type: OspfRouteRow["type"]) { function OspfRouteTypeBadge({ type, count }: { type: OspfRouteRow["type"]; count?: number }) {
if (type === "Unknown") return "bg-muted text-muted-foreground border-border" return <Badge variant="invert-light" size="sm">
if (type === "O") return "bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 border-emerald-500/25" {type === "Unknown" ? "Тип неизвестен" : type}{count === undefined ? "" : ": " + count}
if (type === "O IA") return "bg-blue-500/10 text-blue-600 dark:text-blue-400 border-blue-500/25" </Badge>
if (type === "O E1") return "bg-purple-500/10 text-purple-600 dark:text-purple-400 border-purple-500/25"
return "bg-orange-500/10 text-orange-600 dark:text-orange-400 border-orange-500/25"
} }
interface OspfRoutesDataGridProps { interface OspfRoutesDataGridProps {
@@ -67,14 +66,7 @@ function OspfRoutesDataGrid({ routes, emptyTitle }: OspfRoutesDataGridProps) {
accessorKey: "type", accessorKey: "type",
header: ({ column }) => <DataGridSortHeader column={column} title="Тип" />, header: ({ column }) => <DataGridSortHeader column={column} title="Тип" />,
cell: ({ row }) => ( cell: ({ row }) => (
<span <OspfRouteTypeBadge type={row.original.type} />
className={cn(
"inline-flex items-center rounded border px-1.5 py-0.5 text-[11px] font-medium",
routeTypeClass(row.original.type),
)}
>
{row.original.type === "Unknown" ? "Тип неизвестен" : row.original.type}
</span>
), ),
meta: { headerTitle: "Тип", headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD }, meta: { headerTitle: "Тип", headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD },
}, },
@@ -189,4 +181,4 @@ function OspfRoutesDataGrid({ routes, emptyTitle }: OspfRoutesDataGridProps) {
) )
} }
export { OspfRoutesDataGrid, type OspfRoutesDataGridProps, routeTypeClass } export { OspfRoutesDataGrid, type OspfRoutesDataGridProps, OspfRouteTypeBadge }
+5 -1
View File
@@ -1,6 +1,6 @@
# UX/UI: протокол внешней приёмки 12.5 # UX/UI: протокол внешней приёмки 12.5
Актуальное продолжение 2026-10-14: блок217 завершён. Legacy WAN runtime больше не скрывает ошибки DHCP/addresses/routes и не опрашивает выключенные Home Router/Exit Node. Empty success сохранён. Production15, профиль snapshot/build, live API2/native6/anonymous2/dashboard smoke1440/320 прошли. Backend ux-wan217/compiled1052/source484 matched, frontend ux-gre214; own DB/roles удалены, пароли не менялись. Следующий218 — доступность заполненных таблиц маршрутизации. Этап12.5 открыт. Актуальное продолжение 2026-10-14: блок218 завершён. Заполненные BGP state/type/prefix RX и OSPF route type переведены на читаемые ReUI Badge/основной цвет чисел. Baseline22 violations; fixed104 scoped cells0, E2E22, TypeScript/ESLint/build прошли. Own GRE/OSPF/BGP поднялись, UI8 прошли, own objects удалены и static projection10×2 совпал. Frontend ux-routing218/source527 matched, backend ux-wan217. Следующий219 — скрытые ошибки GRE source snapshots для оповещений. Этап12.5 открыт.
IPsec78: реальный PSK responder established, mode-config198.18.78.10 и online=true подтверждены API; точные собственные объекты удалены. Сертификатный/DN online, late failure и history restore остаются открытыми. [Отчёт](ux-ui/acceptance/ipsec-mode-config-2026-10-09.json), [журнал](ux-ui-progress.md). IPsec78: реальный PSK responder established, mode-config198.18.78.10 и online=true подтверждены API; точные собственные объекты удалены. Сертификатный/DN online, late failure и history restore остаются открытыми. [Отчёт](ux-ui/acceptance/ipsec-mode-config-2026-10-09.json), [журнал](ux-ui-progress.md).
@@ -2595,3 +2595,7 @@ Production compiled SQL/API29 на собственной ограниченно
## 12.5.217 — WAN runtime (2026-10-14) ## 12.5.217 — WAN runtime (2026-10-14)
Read failures/malformed collections дают502, выключенные устройства409 без native poll, empty success сохранён. Production15 и реальная сверка API/native прошли. Подробности и границы — [журнал](ux-ui-progress.md). Backend ux-wan217, frontend ux-gre214; следующий218 — routing table accessibility. Read failures/malformed collections дают502, выключенные устройства409 без native poll, empty success сохранён. Production15 и реальная сверка API/native прошли. Подробности и границы — [журнал](ux-ui-progress.md). Backend ux-wan217, frontend ux-gre214; следующий218 — routing table accessibility.
## 12.5.218 — заполненные routing tables (2026-10-14)
BGP/OSPF contrast: baseline22/fixed104 cells0 violations; E2E22 и real UI8 passed. Own GRE/OSPF/BGP objects удалены; статическая сверка10×2 прошла. Подробности и границы — [журнал](ux-ui-progress.md). Frontend ux-routing218, backend ux-wan217; следующий219 — GRE snapshot source errors.
+1 -1
View File
@@ -1,6 +1,6 @@
# План реализации UX/UI по пятичасовым окнам # План реализации UX/UI по пятичасовым окнам
Актуальное продолжение 2026-10-14: блок217 завершён. Legacy WAN runtime больше не скрывает ошибки DHCP/addresses/routes и не опрашивает выключенные Home Router/Exit Node. Empty success сохранён. Production15, профиль snapshot/build, live API2/native6/anonymous2/dashboard smoke1440/320 прошли. Backend ux-wan217/compiled1052/source484 matched, frontend ux-gre214; own DB/roles удалены, пароли не менялись. Следующий218 — доступность заполненных таблиц маршрутизации. Этап12.5 открыт. Актуальное продолжение 2026-10-14: блок218 завершён. Заполненные BGP state/type/prefix RX и OSPF route type переведены на читаемые ReUI Badge/основной цвет чисел. Baseline22 violations; fixed104 scoped cells0, E2E22, TypeScript/ESLint/build прошли. Own GRE/OSPF/BGP поднялись, UI8 прошли, own objects удалены и static projection10×2 совпал. Frontend ux-routing218/source527 matched, backend ux-wan217. Следующий219 — скрытые ошибки GRE source snapshots для оповещений. Этап12.5 открыт.
Общий план проекта MikrotikManager. Основан на согласованном плане из задачи; точка продолжения обновлена 2026-10-13. Источник фактического прогресса, проверок и ограничений — [журнал реализации](ux-ui-progress.md). Этот документ задаёт объём и критерии завершения, журнал фиксирует результат. Общий план проекта MikrotikManager. Основан на согласованном плане из задачи; точка продолжения обновлена 2026-10-13. Источник фактического прогресса, проверок и ограничений — [журнал реализации](ux-ui-progress.md). Этот документ задаёт объём и критерии завершения, журнал фиксирует результат.
+13 -1
View File
@@ -1,6 +1,6 @@
# UX/UI: журнал реализации # UX/UI: журнал реализации
Актуальное продолжение 2026-10-14: блок217 завершён. Legacy WAN runtime больше не скрывает ошибки DHCP/addresses/routes и не опрашивает выключенные Home Router/Exit Node. Empty success сохранён. Production15, профиль snapshot/build, live API2/native6/anonymous2/dashboard smoke1440/320 прошли. Backend ux-wan217/compiled1052/source484 matched, frontend ux-gre214; own DB/roles удалены, пароли не менялись. Следующий218 — доступность заполненных таблиц маршрутизации. Этап12.5 открыт. Актуальное продолжение 2026-10-14: блок218 завершён. Заполненные BGP state/type/prefix RX и OSPF route type переведены на читаемые ReUI Badge/основной цвет чисел. Baseline22 violations; fixed104 scoped cells0, E2E22, TypeScript/ESLint/build прошли. Own GRE/OSPF/BGP поднялись, UI8 прошли, own objects удалены и static projection10×2 совпал. Frontend ux-routing218/source527 matched, backend ux-wan217. Следующий219 — скрытые ошибки GRE source snapshots для оповещений. Этап12.5 открыт.
Общий план: [UX/UI по этапам и пятичасовым окнам](ux-ui-plan.md). План задаёт объём, этот журнал фиксирует выполненные блоки и ограничения. Записи расположены от новых к старым; подробная история этапа12 также сохранена в [ux-ui-stage-12.md](ux-ui-stage-12.md). Общий план: [UX/UI по этапам и пятичасовым окнам](ux-ui-plan.md). План задаёт объём, этот журнал фиксирует выполненные блоки и ограничения. Записи расположены от новых к старым; подробная история этапа12 также сохранена в [ux-ui-stage-12.md](ux-ui-stage-12.md).
@@ -38,6 +38,18 @@
| 11Б | Оповещения, сбор данных, интеграции, релизы и настройки | Завершён в границах локальной приёмки 2026-10-03; ограничения и evidence в11Б.7 | | 11Б | Оповещения, сбор данных, интеграции, релизы и настройки | Завершён в границах локальной приёмки 2026-10-03; ограничения и evidence в11Б.7 |
| 12 | Итоговая доступность, адаптивность, производительность и регрессия | Локальная приёмка завершена в границах12.3.83; внешняя12.5 в работе, выполненные блоки1–196 и ограничения ниже. Runtime backend/frontend ux-peak196. | | 12 | Итоговая доступность, адаптивность, производительность и регрессия | Локальная приёмка завершена в границах12.3.83; внешняя12.5 в работе, выполненные блоки1–196 и ограничения ниже. Runtime backend/frontend ux-peak196. |
## 12.5.218 — контраст заполненных BGP и OSPF таблиц (2026-10-14)
Baseline104 explicitly scrolled cell checks:22 нарушений в light на1440/320. BGP Established3,31:1, Active2,96:1, Idle4,21:1, prefix RX3,65:1; OSPF O E2 3,23:1. Ручные state/type spans заменены штатным ReUI Badge invert-light; BGP состояния дополнительно различаются семантическим индикатором и прежним текстом. Protocol type — текстовая категория без оценки здоровья. Prefix RX читает основной цвет. OSPF type Badge общий для строк, counts и легенды; vendor components/theme не менялись.
Fixed104 scoped cells0 violations, E2E22 (8 contrast fixtures + BGP data13 + OSPF values1), ESLint0, TypeScript и production build прошли. Первый локальный tsc исчерпал4GB heap: include захватывал игнорируемые tmp source copies. tmp/temp/test-results/playwright-report исключены из TypeScript, исходники и тесты остались включены; повтор прошёл без увеличения heap. Это scoped colour audit, не полная WCAG приёмка.
На Debian свободное место упало до157MB. Удалён неиспользуемый build-cache старше15m и51 старый неиспользуемый тег mmapp-test/frontend:ux-* без force, с защитой image IDs всех контейнеров. ux-gre214 и предыдущий ux-gre213 сохранены; свободно5,5GB перед build. Backend/Portal/Postgres/volumes не удалялись. Frontend ux-routing218/source527 matched, backend ux-wan217 healthy сохранён.
Созданы собственные GRE2, OSPF instances/areas/templates и BGP instances/connections со scoped prefix filters: OSPF Full, BGP Established с received prefixes и два own remote routes active на каждом CHR. Восемь live UI BGP/OSPF ×light/dark ×1440/320 проверили16 scrolled cells без violations/page errors/mutation requests. Все собственные объекты удалены; hash projection перечисленных статических полей10 collections×2 совпал с baseline, dynamic state исключён. Пароли не менялись. Packet-loss SLA/полный протоколный regression этим UI-блоком не принимаются.
Протоколы: [contrast](ux-ui/acceptance/routing218-contrast-2026-10-14.json), [source](ux-ui/acceptance/routing218-source-proof-2026-10-14.json), [deployment](ux-ui/acceptance/routing218-deployment-2026-10-14.json), [storage cleanup](ux-ui/acceptance/routing218-storage-cleanup.json), [native/UI/cleanup](ux-ui/acceptance/routing218-native-live-2026-10-14.json). Следующий219 — GRE источник snapshots: сейчас fetchGreTunnelLiveRows подавляет ошибки устройств и сообщает успешный пустой результат.
## 12.5.217 — достоверный WAN runtime и disabled no-poll (2026-10-14) ## 12.5.217 — достоверный WAN runtime и disabled no-poll (2026-10-14)
/api/servers/:id/wan-runtime подавлял ошибки DHCP, addresses и routes через [] и опрашивал выключенные устройства. Добавлены409 перед native client (с повторной проверкой актуальной DB row) и строгая валидация трёх коллекций тем же readInternetPathRows, что используется Internet path collector. Read failure/malformed row возвращает502 с WAN error; успешный envelope defaultGateway/immediateGateway/defaultInterface/uplinks и корректный empty200 сохранены. Методы/права/алгоритм выбора default route не менялись. Активный dashboard читает сохранённый Internet path, поэтому legacy WAN endpoint не объявляется его единственным источником. /api/servers/:id/wan-runtime подавлял ошибки DHCP, addresses и routes через [] и опрашивал выключенные устройства. Добавлены409 перед native client (с повторной проверкой актуальной DB row) и строгая валидация трёх коллекций тем же readInternetPathRows, что используется Internet path collector. Read failure/malformed row возвращает502 с WAN error; успешный envelope defaultGateway/immediateGateway/defaultInterface/uplinks и корректный empty200 сохранены. Методы/права/алгоритм выбора default route не менялись. Активный dashboard читает сохранённый Internet path, поэтому legacy WAN endpoint не объявляется его единственным источником.
+7 -3
View File
@@ -1,10 +1,10 @@
# Оставшаяся внешняя приёмка — 2026-10-13 # Оставшаяся внешняя приёмка — 2026-10-13
Актуальное продолжение 2026-10-14: блок217 завершён. Legacy WAN runtime больше не скрывает ошибки DHCP/addresses/routes и не опрашивает выключенные Home Router/Exit Node. Empty success сохранён. Production15, профиль snapshot/build, live API2/native6/anonymous2/dashboard smoke1440/320 прошли. Backend ux-wan217/compiled1052/source484 matched, frontend ux-gre214; own DB/roles удалены, пароли не менялись. Следующий218 — доступность заполненных таблиц маршрутизации. Этап12.5 открыт. Актуальное продолжение 2026-10-14: блок218 завершён. Заполненные BGP state/type/prefix RX и OSPF route type переведены на читаемые ReUI Badge/основной цвет чисел. Baseline22 violations; fixed104 scoped cells0, E2E22, TypeScript/ESLint/build прошли. Own GRE/OSPF/BGP поднялись, UI8 прошли, own objects удалены и static projection10×2 совпал. Frontend ux-routing218/source527 matched, backend ux-wan217. Следующий219 — скрытые ошибки GRE source snapshots для оповещений. Этап12.5 открыт.
Это актуальная матрица после 12.5.217. Исторические записи сохраняют версии и ограничения на момент выполнения; поздние проверки ниже уточняют их. Этап 12.5 открыт. Успех в двух CHR и одном backend не означает приёмку всех конфигураций, интеграций или полной регрессии. Это актуальная матрица после 12.5.218. Исторические записи сохраняют версии и ограничения на момент выполнения; поздние проверки ниже уточняют их. Этап 12.5 открыт. Успех в двух CHR и одном backend не означает приёмку всех конфигураций, интеграций или полной регрессии.
Стенд: Debian13/Compose, PostgreSQL18.6, два CHR RouterOS7.24.5. Backend `ux-wan217`, frontend `ux-gre214`; production lab с195 использует AUTH_REQUIRED=true и Portal1.3.1. Подписанные JWT/RBAC проверялись в изолированных процессах. Все собственные объекты112 удалены, исходные13 коллекций×2 (включая logging/certificates/files/routes) проверены; пароли не менялись. Стенд: Debian13/Compose, PostgreSQL18.6, два CHR RouterOS7.24.5. Backend `ux-wan217`, frontend `ux-routing218`; production lab с195 использует AUTH_REQUIRED=true и Portal1.3.1. Подписанные JWT/RBAC проверялись в изолированных процессах. Все собственные объекты112 удалены, исходные13 коллекций×2 (включая logging/certificates/files/routes) проверены; пароли не менялись.
| Раздел | Подтверждено | Осталось / условие завершения | | Раздел | Подтверждено | Осталось / условие завершения |
| --- | --- | --- | | --- | --- | --- |
@@ -1513,3 +1513,7 @@ Production compiled SQL/API29 на собственной ограниченно
## 12.5.217 — WAN runtime (2026-10-14) ## 12.5.217 — WAN runtime (2026-10-14)
Read failures/malformed collections дают502, выключенные устройства409 без native poll, empty success сохранён. Production15 и реальная сверка API/native прошли. Подробности и границы — [журнал](ux-ui-progress.md). Backend ux-wan217, frontend ux-gre214; следующий218 — routing table accessibility. Read failures/malformed collections дают502, выключенные устройства409 без native poll, empty success сохранён. Production15 и реальная сверка API/native прошли. Подробности и границы — [журнал](ux-ui-progress.md). Backend ux-wan217, frontend ux-gre214; следующий218 — routing table accessibility.
## 12.5.218 — заполненные routing tables (2026-10-14)
BGP/OSPF contrast: baseline22/fixed104 cells0 violations; E2E22 и real UI8 passed. Own GRE/OSPF/BGP objects удалены; статическая сверка10×2 прошла. Подробности и границы — [журнал](ux-ui-progress.md). Frontend ux-routing218, backend ux-wan217; следующий219 — GRE snapshot source errors.
+14 -1
View File
@@ -1,6 +1,6 @@
# Этап 12: итоговая приёмка UX/UI # Этап 12: итоговая приёмка UX/UI
Актуальное продолжение 2026-10-14: блок217 завершён. Legacy WAN runtime больше не скрывает ошибки DHCP/addresses/routes и не опрашивает выключенные Home Router/Exit Node. Empty success сохранён. Production15, профиль snapshot/build, live API2/native6/anonymous2/dashboard smoke1440/320 прошли. Backend ux-wan217/compiled1052/source484 matched, frontend ux-gre214; own DB/roles удалены, пароли не менялись. Следующий218 — доступность заполненных таблиц маршрутизации. Этап12.5 открыт. Актуальное продолжение 2026-10-14: блок218 завершён. Заполненные BGP state/type/prefix RX и OSPF route type переведены на читаемые ReUI Badge/основной цвет чисел. Baseline22 violations; fixed104 scoped cells0, E2E22, TypeScript/ESLint/build прошли. Own GRE/OSPF/BGP поднялись, UI8 прошли, own objects удалены и static projection10×2 совпал. Frontend ux-routing218/source527 matched, backend ux-wan217. Следующий219 — скрытые ошибки GRE source snapshots для оповещений. Этап12.5 открыт.
План: [ux-ui-plan.md](ux-ui-plan.md). Фактические результаты: [ux-ui-progress.md](ux-ui-progress.md). Подготовлен после сводных проверок 11Б; завершение каждого блока требует локального коммита без push. План: [ux-ui-plan.md](ux-ui-plan.md). Фактические результаты: [ux-ui-progress.md](ux-ui-progress.md). Подготовлен после сводных проверок 11Б; завершение каждого блока требует локального коммита без push.
@@ -3954,3 +3954,16 @@ Compiled1052/source484 matched; backend healthy, frontend ux-gre214 сохран
Протоколы: [baseline](ux-ui/acceptance/wan217-baseline.json), [fixed](ux-ui/acceptance/wan217-fixed.json), [build](ux-ui/acceptance/wan217-build-proof-2026-10-14.json), [deployment](ux-ui/acceptance/wan217-deployment-2026-10-14.json), [live](ux-ui/acceptance/wan217-live-2026-10-14.json). Следующий218 — accessibility заполненных таблиц маршрутизации: контраст статусов и метрик в light/dark на ПК/телефоне. Протоколы: [baseline](ux-ui/acceptance/wan217-baseline.json), [fixed](ux-ui/acceptance/wan217-fixed.json), [build](ux-ui/acceptance/wan217-build-proof-2026-10-14.json), [deployment](ux-ui/acceptance/wan217-deployment-2026-10-14.json), [live](ux-ui/acceptance/wan217-live-2026-10-14.json). Следующий218 — accessibility заполненных таблиц маршрутизации: контраст статусов и метрик в light/dark на ПК/телефоне.
## 12.5.218 — контраст заполненных BGP и OSPF таблиц (2026-10-14)
Baseline104 explicitly scrolled cell checks:22 нарушений в light на1440/320. BGP Established3,31:1, Active2,96:1, Idle4,21:1, prefix RX3,65:1; OSPF O E2 3,23:1. Ручные state/type spans заменены штатным ReUI Badge invert-light; BGP состояния дополнительно различаются семантическим индикатором и прежним текстом. Protocol type — текстовая категория без оценки здоровья. Prefix RX читает основной цвет. OSPF type Badge общий для строк, counts и легенды; vendor components/theme не менялись.
Fixed104 scoped cells0 violations, E2E22 (8 contrast fixtures + BGP data13 + OSPF values1), ESLint0, TypeScript и production build прошли. Первый локальный tsc исчерпал4GB heap: include захватывал игнорируемые tmp source copies. tmp/temp/test-results/playwright-report исключены из TypeScript, исходники и тесты остались включены; повтор прошёл без увеличения heap. Это scoped colour audit, не полная WCAG приёмка.
На Debian свободное место упало до157MB. Удалён неиспользуемый build-cache старше15m и51 старый неиспользуемый тег mmapp-test/frontend:ux-* без force, с защитой image IDs всех контейнеров. ux-gre214 и предыдущий ux-gre213 сохранены; свободно5,5GB перед build. Backend/Portal/Postgres/volumes не удалялись. Frontend ux-routing218/source527 matched, backend ux-wan217 healthy сохранён.
Созданы собственные GRE2, OSPF instances/areas/templates и BGP instances/connections со scoped prefix filters: OSPF Full, BGP Established с received prefixes и два own remote routes active на каждом CHR. Восемь live UI BGP/OSPF ×light/dark ×1440/320 проверили16 scrolled cells без violations/page errors/mutation requests. Все собственные объекты удалены; hash projection перечисленных статических полей10 collections×2 совпал с baseline, dynamic state исключён. Пароли не менялись. Packet-loss SLA/полный протоколный regression этим UI-блоком не принимаются.
Протоколы: [contrast](ux-ui/acceptance/routing218-contrast-2026-10-14.json), [source](ux-ui/acceptance/routing218-source-proof-2026-10-14.json), [deployment](ux-ui/acceptance/routing218-deployment-2026-10-14.json), [storage cleanup](ux-ui/acceptance/routing218-storage-cleanup.json), [native/UI/cleanup](ux-ui/acceptance/routing218-native-live-2026-10-14.json). Следующий219 — GRE источник snapshots: сейчас fetchGreTunnelLiveRows подавляет ошибки устройств и сообщает успешный пустой результат.
+5 -1
View File
@@ -1,6 +1,6 @@
# Тестовый сервер UX/UI — 2026-10-10 # Тестовый сервер UX/UI — 2026-10-10
Актуальное продолжение 2026-10-14: блок217 завершён. Legacy WAN runtime больше не скрывает ошибки DHCP/addresses/routes и не опрашивает выключенные Home Router/Exit Node. Empty success сохранён. Production15, профиль snapshot/build, live API2/native6/anonymous2/dashboard smoke1440/320 прошли. Backend ux-wan217/compiled1052/source484 matched, frontend ux-gre214; own DB/roles удалены, пароли не менялись. Следующий218 — доступность заполненных таблиц маршрутизации. Этап12.5 открыт. Актуальное продолжение 2026-10-14: блок218 завершён. Заполненные BGP state/type/prefix RX и OSPF route type переведены на читаемые ReUI Badge/основной цвет чисел. Baseline22 violations; fixed104 scoped cells0, E2E22, TypeScript/ESLint/build прошли. Own GRE/OSPF/BGP поднялись, UI8 прошли, own objects удалены и static projection10×2 совпал. Frontend ux-routing218/source527 matched, backend ux-wan217. Следующий219 — скрытые ошибки GRE source snapshots для оповещений. Этап12.5 открыт.
| Параметр | Проверенное состояние | | Параметр | Проверенное состояние |
| --- | --- | | --- | --- |
@@ -2326,3 +2326,7 @@ Production compiled SQL/API29 на собственной ограниченно
## 12.5.217 — WAN runtime (2026-10-14) ## 12.5.217 — WAN runtime (2026-10-14)
Read failures/malformed collections дают502, выключенные устройства409 без native poll, empty success сохранён. Production15 и реальная сверка API/native прошли. Подробности и границы — [журнал](ux-ui-progress.md). Backend ux-wan217, frontend ux-gre214; следующий218 — routing table accessibility. Read failures/malformed collections дают502, выключенные устройства409 без native poll, empty success сохранён. Production15 и реальная сверка API/native прошли. Подробности и границы — [журнал](ux-ui-progress.md). Backend ux-wan217, frontend ux-gre214; следующий218 — routing table accessibility.
## 12.5.218 — заполненные routing tables (2026-10-14)
BGP/OSPF contrast: baseline22/fixed104 cells0 violations; E2E22 и real UI8 passed. Own GRE/OSPF/BGP objects удалены; статическая сверка10×2 прошла. Подробности и границы — [журнал](ux-ui-progress.md). Frontend ux-routing218, backend ux-wan217; следующий219 — GRE snapshot source errors.
@@ -0,0 +1,988 @@
{
"date": "2026-10-14",
"block": "12.5.218",
"baseline": {
"cases": 8,
"cellChecks": 104,
"failedCells": 22,
"casesDetail": [
{
"date": "2026-10-14",
"section": "bgp",
"theme": "light",
"width": 1440,
"scope": "Explicitly scrolled BGP type/state/prefix RX and OSPF route type cells",
"findings": [
{
"row": 0,
"cell": 4,
"text": "eBGP",
"violations": []
},
{
"row": 0,
"cell": 5,
"text": "Established",
"violations": [
{
"id": "color-contrast",
"nodes": [
{
"target": [
".bg-emerald-500\\/10"
],
"summary": "Fix any of the following:\n Element has insufficient color contrast of 3.31 (foreground color: #009966, background color: #e6f8f2, font size: 8.3pt (11px), font weight: normal). Expected contrast ratio of 4.5:1"
}
]
}
]
},
{
"row": 0,
"cell": 7,
"text": "12",
"violations": [
{
"id": "color-contrast",
"nodes": [
{
"target": [
"#own218-audit > .text-emerald-600.dark\\:text-emerald-400.text-right"
],
"summary": "Fix any of the following:\n Element has insufficient color contrast of 3.65 (foreground color: #009966, background color: #ffffff, font size: 10.5pt (14px), font weight: normal). Expected contrast ratio of 4.5:1"
}
]
}
]
},
{
"row": 1,
"cell": 4,
"text": "iBGP",
"violations": []
},
{
"row": 1,
"cell": 5,
"text": "Active",
"violations": [
{
"id": "color-contrast",
"nodes": [
{
"target": [
".text-amber-600"
],
"summary": "Fix any of the following:\n Element has insufficient color contrast of 2.96 (foreground color: #e17100, background color: #fff5e6, font size: 8.3pt (11px), font weight: normal). Expected contrast ratio of 4.5:1"
}
]
}
]
},
{
"row": 1,
"cell": 7,
"text": "12",
"violations": [
{
"id": "color-contrast",
"nodes": [
{
"target": [
"#own218-audit > .text-emerald-600.dark\\:text-emerald-400.text-right"
],
"summary": "Fix any of the following:\n Element has insufficient color contrast of 3.65 (foreground color: #009966, background color: #ffffff, font size: 10.5pt (14px), font weight: normal). Expected contrast ratio of 4.5:1"
}
]
}
]
},
{
"row": 2,
"cell": 4,
"text": "eBGP",
"violations": []
},
{
"row": 2,
"cell": 5,
"text": "Idle",
"violations": [
{
"id": "color-contrast",
"nodes": [
{
"target": [
".bg-slate-500\\/10"
],
"summary": "Fix any of the following:\n Element has insufficient color contrast of 4.21 (foreground color: #62748e, background color: #eff1f4, font size: 8.3pt (11px), font weight: normal). Expected contrast ratio of 4.5:1"
}
]
}
]
},
{
"row": 2,
"cell": 7,
"text": "12",
"violations": [
{
"id": "color-contrast",
"nodes": [
{
"target": [
"#own218-audit > .text-emerald-600.dark\\:text-emerald-400.text-right"
],
"summary": "Fix any of the following:\n Element has insufficient color contrast of 3.65 (foreground color: #009966, background color: #ffffff, font size: 10.5pt (14px), font weight: normal). Expected contrast ratio of 4.5:1"
}
]
}
]
},
{
"row": 3,
"cell": 4,
"text": "eBGP",
"violations": []
},
{
"row": 3,
"cell": 5,
"text": "Connect",
"violations": []
},
{
"row": 3,
"cell": 7,
"text": "12",
"violations": [
{
"id": "color-contrast",
"nodes": [
{
"target": [
"#own218-audit > .text-emerald-600.dark\\:text-emerald-400.text-right"
],
"summary": "Fix any of the following:\n Element has insufficient color contrast of 3.65 (foreground color: #009966, background color: #ffffff, font size: 10.5pt (14px), font weight: normal). Expected contrast ratio of 4.5:1"
}
]
}
]
},
{
"row": 4,
"cell": 4,
"text": "eBGP",
"violations": []
},
{
"row": 4,
"cell": 5,
"text": "OpenSent",
"violations": []
},
{
"row": 4,
"cell": 7,
"text": "12",
"violations": [
{
"id": "color-contrast",
"nodes": [
{
"target": [
"#own218-audit > .text-emerald-600.dark\\:text-emerald-400.text-right"
],
"summary": "Fix any of the following:\n Element has insufficient color contrast of 3.65 (foreground color: #009966, background color: #ffffff, font size: 10.5pt (14px), font weight: normal). Expected contrast ratio of 4.5:1"
}
]
}
]
},
{
"row": 5,
"cell": 4,
"text": "eBGP",
"violations": []
},
{
"row": 5,
"cell": 5,
"text": "OpenConfirm",
"violations": []
},
{
"row": 5,
"cell": 7,
"text": "12",
"violations": [
{
"id": "color-contrast",
"nodes": [
{
"target": [
"#own218-audit > .text-emerald-600.dark\\:text-emerald-400.text-right"
],
"summary": "Fix any of the following:\n Element has insufficient color contrast of 3.65 (foreground color: #009966, background color: #ffffff, font size: 10.5pt (14px), font weight: normal). Expected contrast ratio of 4.5:1"
}
]
}
]
},
{
"row": 6,
"cell": 4,
"text": "Тип неизвестен",
"violations": []
},
{
"row": 6,
"cell": 5,
"text": "Неизвестно",
"violations": []
},
{
"row": 6,
"cell": 7,
"text": "12",
"violations": [
{
"id": "color-contrast",
"nodes": [
{
"target": [
"#own218-audit > .text-emerald-600.dark\\:text-emerald-400.text-right"
],
"summary": "Fix any of the following:\n Element has insufficient color contrast of 3.65 (foreground color: #009966, background color: #ffffff, font size: 10.5pt (14px), font weight: normal). Expected contrast ratio of 4.5:1"
}
]
}
]
}
]
},
{
"date": "2026-10-14",
"section": "bgp",
"theme": "light",
"width": 320,
"scope": "Explicitly scrolled BGP type/state/prefix RX and OSPF route type cells",
"findings": [
{
"row": 0,
"cell": 4,
"text": "eBGP",
"violations": []
},
{
"row": 0,
"cell": 5,
"text": "Established",
"violations": [
{
"id": "color-contrast",
"nodes": [
{
"target": [
".bg-emerald-500\\/10"
],
"summary": "Fix any of the following:\n Element has insufficient color contrast of 3.31 (foreground color: #009966, background color: #e6f8f2, font size: 8.3pt (11px), font weight: normal). Expected contrast ratio of 4.5:1"
}
]
}
]
},
{
"row": 0,
"cell": 7,
"text": "12",
"violations": [
{
"id": "color-contrast",
"nodes": [
{
"target": [
"#own218-audit > .text-emerald-600.dark\\:text-emerald-400.text-right"
],
"summary": "Fix any of the following:\n Element has insufficient color contrast of 3.65 (foreground color: #009966, background color: #ffffff, font size: 10.5pt (14px), font weight: normal). Expected contrast ratio of 4.5:1"
}
]
}
]
},
{
"row": 1,
"cell": 4,
"text": "iBGP",
"violations": []
},
{
"row": 1,
"cell": 5,
"text": "Active",
"violations": [
{
"id": "color-contrast",
"nodes": [
{
"target": [
".text-amber-600"
],
"summary": "Fix any of the following:\n Element has insufficient color contrast of 2.96 (foreground color: #e17100, background color: #fff5e6, font size: 8.3pt (11px), font weight: normal). Expected contrast ratio of 4.5:1"
}
]
}
]
},
{
"row": 1,
"cell": 7,
"text": "12",
"violations": [
{
"id": "color-contrast",
"nodes": [
{
"target": [
"#own218-audit > .text-emerald-600.dark\\:text-emerald-400.text-right"
],
"summary": "Fix any of the following:\n Element has insufficient color contrast of 3.65 (foreground color: #009966, background color: #ffffff, font size: 10.5pt (14px), font weight: normal). Expected contrast ratio of 4.5:1"
}
]
}
]
},
{
"row": 2,
"cell": 4,
"text": "eBGP",
"violations": []
},
{
"row": 2,
"cell": 5,
"text": "Idle",
"violations": [
{
"id": "color-contrast",
"nodes": [
{
"target": [
".bg-slate-500\\/10"
],
"summary": "Fix any of the following:\n Element has insufficient color contrast of 4.21 (foreground color: #62748e, background color: #eff1f4, font size: 8.3pt (11px), font weight: normal). Expected contrast ratio of 4.5:1"
}
]
}
]
},
{
"row": 2,
"cell": 7,
"text": "12",
"violations": [
{
"id": "color-contrast",
"nodes": [
{
"target": [
"#own218-audit > .text-emerald-600.dark\\:text-emerald-400.text-right"
],
"summary": "Fix any of the following:\n Element has insufficient color contrast of 3.65 (foreground color: #009966, background color: #ffffff, font size: 10.5pt (14px), font weight: normal). Expected contrast ratio of 4.5:1"
}
]
}
]
},
{
"row": 3,
"cell": 4,
"text": "eBGP",
"violations": []
},
{
"row": 3,
"cell": 5,
"text": "Connect",
"violations": []
},
{
"row": 3,
"cell": 7,
"text": "12",
"violations": [
{
"id": "color-contrast",
"nodes": [
{
"target": [
"#own218-audit > .text-emerald-600.dark\\:text-emerald-400.text-right"
],
"summary": "Fix any of the following:\n Element has insufficient color contrast of 3.65 (foreground color: #009966, background color: #ffffff, font size: 10.5pt (14px), font weight: normal). Expected contrast ratio of 4.5:1"
}
]
}
]
},
{
"row": 4,
"cell": 4,
"text": "eBGP",
"violations": []
},
{
"row": 4,
"cell": 5,
"text": "OpenSent",
"violations": []
},
{
"row": 4,
"cell": 7,
"text": "12",
"violations": [
{
"id": "color-contrast",
"nodes": [
{
"target": [
"#own218-audit > .text-emerald-600.dark\\:text-emerald-400.text-right"
],
"summary": "Fix any of the following:\n Element has insufficient color contrast of 3.65 (foreground color: #009966, background color: #ffffff, font size: 10.5pt (14px), font weight: normal). Expected contrast ratio of 4.5:1"
}
]
}
]
},
{
"row": 5,
"cell": 4,
"text": "eBGP",
"violations": []
},
{
"row": 5,
"cell": 5,
"text": "OpenConfirm",
"violations": []
},
{
"row": 5,
"cell": 7,
"text": "12",
"violations": [
{
"id": "color-contrast",
"nodes": [
{
"target": [
"#own218-audit > .text-emerald-600.dark\\:text-emerald-400.text-right"
],
"summary": "Fix any of the following:\n Element has insufficient color contrast of 3.65 (foreground color: #009966, background color: #ffffff, font size: 10.5pt (14px), font weight: normal). Expected contrast ratio of 4.5:1"
}
]
}
]
},
{
"row": 6,
"cell": 4,
"text": "Тип неизвестен",
"violations": []
},
{
"row": 6,
"cell": 5,
"text": "Неизвестно",
"violations": []
},
{
"row": 6,
"cell": 7,
"text": "12",
"violations": [
{
"id": "color-contrast",
"nodes": [
{
"target": [
"#own218-audit > .text-emerald-600.dark\\:text-emerald-400.text-right"
],
"summary": "Fix any of the following:\n Element has insufficient color contrast of 3.65 (foreground color: #009966, background color: #ffffff, font size: 10.5pt (14px), font weight: normal). Expected contrast ratio of 4.5:1"
}
]
}
]
}
]
},
{
"date": "2026-10-14",
"section": "bgp",
"theme": "dark",
"width": 1440,
"scope": "Explicitly scrolled BGP type/state/prefix RX and OSPF route type cells",
"findings": [
{
"row": 0,
"cell": 4,
"text": "eBGP",
"violations": []
},
{
"row": 0,
"cell": 5,
"text": "Established",
"violations": []
},
{
"row": 0,
"cell": 7,
"text": "12",
"violations": []
},
{
"row": 1,
"cell": 4,
"text": "iBGP",
"violations": []
},
{
"row": 1,
"cell": 5,
"text": "Active",
"violations": []
},
{
"row": 1,
"cell": 7,
"text": "12",
"violations": []
},
{
"row": 2,
"cell": 4,
"text": "eBGP",
"violations": []
},
{
"row": 2,
"cell": 5,
"text": "Idle",
"violations": []
},
{
"row": 2,
"cell": 7,
"text": "12",
"violations": []
},
{
"row": 3,
"cell": 4,
"text": "eBGP",
"violations": []
},
{
"row": 3,
"cell": 5,
"text": "Connect",
"violations": []
},
{
"row": 3,
"cell": 7,
"text": "12",
"violations": []
},
{
"row": 4,
"cell": 4,
"text": "eBGP",
"violations": []
},
{
"row": 4,
"cell": 5,
"text": "OpenSent",
"violations": []
},
{
"row": 4,
"cell": 7,
"text": "12",
"violations": []
},
{
"row": 5,
"cell": 4,
"text": "eBGP",
"violations": []
},
{
"row": 5,
"cell": 5,
"text": "OpenConfirm",
"violations": []
},
{
"row": 5,
"cell": 7,
"text": "12",
"violations": []
},
{
"row": 6,
"cell": 4,
"text": "Тип неизвестен",
"violations": []
},
{
"row": 6,
"cell": 5,
"text": "Неизвестно",
"violations": []
},
{
"row": 6,
"cell": 7,
"text": "12",
"violations": []
}
]
},
{
"date": "2026-10-14",
"section": "bgp",
"theme": "dark",
"width": 320,
"scope": "Explicitly scrolled BGP type/state/prefix RX and OSPF route type cells",
"findings": [
{
"row": 0,
"cell": 4,
"text": "eBGP",
"violations": []
},
{
"row": 0,
"cell": 5,
"text": "Established",
"violations": []
},
{
"row": 0,
"cell": 7,
"text": "12",
"violations": []
},
{
"row": 1,
"cell": 4,
"text": "iBGP",
"violations": []
},
{
"row": 1,
"cell": 5,
"text": "Active",
"violations": []
},
{
"row": 1,
"cell": 7,
"text": "12",
"violations": []
},
{
"row": 2,
"cell": 4,
"text": "eBGP",
"violations": []
},
{
"row": 2,
"cell": 5,
"text": "Idle",
"violations": []
},
{
"row": 2,
"cell": 7,
"text": "12",
"violations": []
},
{
"row": 3,
"cell": 4,
"text": "eBGP",
"violations": []
},
{
"row": 3,
"cell": 5,
"text": "Connect",
"violations": []
},
{
"row": 3,
"cell": 7,
"text": "12",
"violations": []
},
{
"row": 4,
"cell": 4,
"text": "eBGP",
"violations": []
},
{
"row": 4,
"cell": 5,
"text": "OpenSent",
"violations": []
},
{
"row": 4,
"cell": 7,
"text": "12",
"violations": []
},
{
"row": 5,
"cell": 4,
"text": "eBGP",
"violations": []
},
{
"row": 5,
"cell": 5,
"text": "OpenConfirm",
"violations": []
},
{
"row": 5,
"cell": 7,
"text": "12",
"violations": []
},
{
"row": 6,
"cell": 4,
"text": "Тип неизвестен",
"violations": []
},
{
"row": 6,
"cell": 5,
"text": "Неизвестно",
"violations": []
},
{
"row": 6,
"cell": 7,
"text": "12",
"violations": []
}
]
},
{
"date": "2026-10-14",
"section": "ospf",
"theme": "light",
"width": 1440,
"scope": "Explicitly scrolled BGP type/state/prefix RX and OSPF route type cells",
"findings": [
{
"row": 0,
"cell": 1,
"text": "O",
"violations": []
},
{
"row": 1,
"cell": 1,
"text": "O IA",
"violations": []
},
{
"row": 2,
"cell": 1,
"text": "O E1",
"violations": []
},
{
"row": 3,
"cell": 1,
"text": "O E2",
"violations": [
{
"id": "color-contrast",
"nodes": [
{
"target": [
"#own218-audit > .bg-orange-500\\/10.text-orange-600.dark\\:text-orange-400"
],
"summary": "Fix any of the following:\n Element has insufficient color contrast of 3.23 (foreground color: #f54900, background color: #fff0e6, font size: 8.3pt (11px), font weight: normal). Expected contrast ratio of 4.5:1"
}
]
}
]
},
{
"row": 4,
"cell": 1,
"text": "Тип неизвестен",
"violations": []
}
]
},
{
"date": "2026-10-14",
"section": "ospf",
"theme": "light",
"width": 320,
"scope": "Explicitly scrolled BGP type/state/prefix RX and OSPF route type cells",
"findings": [
{
"row": 0,
"cell": 1,
"text": "O",
"violations": []
},
{
"row": 1,
"cell": 1,
"text": "O IA",
"violations": []
},
{
"row": 2,
"cell": 1,
"text": "O E1",
"violations": []
},
{
"row": 3,
"cell": 1,
"text": "O E2",
"violations": [
{
"id": "color-contrast",
"nodes": [
{
"target": [
"#own218-audit > .bg-orange-500\\/10.text-orange-600.dark\\:text-orange-400"
],
"summary": "Fix any of the following:\n Element has insufficient color contrast of 3.23 (foreground color: #f54900, background color: #fff0e6, font size: 8.3pt (11px), font weight: normal). Expected contrast ratio of 4.5:1"
}
]
}
]
},
{
"row": 4,
"cell": 1,
"text": "Тип неизвестен",
"violations": []
}
]
},
{
"date": "2026-10-14",
"section": "ospf",
"theme": "dark",
"width": 1440,
"scope": "Explicitly scrolled BGP type/state/prefix RX and OSPF route type cells",
"findings": [
{
"row": 0,
"cell": 1,
"text": "O",
"violations": []
},
{
"row": 1,
"cell": 1,
"text": "O IA",
"violations": []
},
{
"row": 2,
"cell": 1,
"text": "O E1",
"violations": []
},
{
"row": 3,
"cell": 1,
"text": "O E2",
"violations": []
},
{
"row": 4,
"cell": 1,
"text": "Тип неизвестен",
"violations": []
}
]
},
{
"date": "2026-10-14",
"section": "ospf",
"theme": "dark",
"width": 320,
"scope": "Explicitly scrolled BGP type/state/prefix RX and OSPF route type cells",
"findings": [
{
"row": 0,
"cell": 1,
"text": "O",
"violations": []
},
{
"row": 1,
"cell": 1,
"text": "O IA",
"violations": []
},
{
"row": 2,
"cell": 1,
"text": "O E1",
"violations": []
},
{
"row": 3,
"cell": 1,
"text": "O E2",
"violations": []
},
{
"row": 4,
"cell": 1,
"text": "Тип неизвестен",
"violations": []
}
]
}
]
},
"fixed": {
"cases": 8,
"cellChecks": 104,
"failedCells": 0
},
"regression": {
"startTime": "2026-10-13T17:51:31.476Z",
"duration": 63706.111,
"expected": 22,
"skipped": 0,
"unexpected": 0,
"flaky": 0
},
"scope": "Scrolled cells only: BGP type/state/prefixRX and OSPF type. No blanket WCAG certification.",
"typeScriptPassed": true,
"eslintErrors": 0,
"typeScriptInitialFailure": "Local default include compiled ignored temporary source copies; exhausted4GB heap. Generated directories now excluded."
}
@@ -0,0 +1,20 @@
{
"date": "2026-10-14",
"block": "12.5.218",
"frontendSourceMatched": 527,
"backendChanged": false,
"services": {
"backend": {
"image": "mmapp-test/backend:ux-wan217",
"imageId": "sha256:f5fac6167453e180e7aacb3b88de14e49860479dfcf46bc7a9ffd34db682e42b",
"running": true,
"health": "healthy"
},
"frontend": {
"image": "mmapp-test/frontend:ux-routing218",
"imageId": "sha256:ec658b9da88c19d60987be5bfc0c15fb339a0310d7a42dc761b40a70a3428c5a",
"running": true,
"health": null
}
}
}
@@ -0,0 +1,127 @@
{
"date": "2026-10-14",
"block": "12.5.218",
"passed": true,
"backend": "ux-wan217",
"frontend": "ux-routing218",
"devices": [
{
"host": "194.226.121.150",
"serverId": 1,
"greOwned": true,
"bgpEstablished": true,
"bgpPrefixesRx": 1,
"ospfFull": true,
"remotePrefixesActive": 2
},
{
"host": "104.165.244.7",
"serverId": 2,
"greOwned": true,
"bgpEstablished": true,
"bgpPrefixesRx": 1,
"ospfFull": true,
"remotePrefixesActive": 2
}
],
"ui": [
{
"section": "bgp",
"theme": "light",
"width": 1440,
"scrolledCellChecks": 3,
"contrastViolations": 0,
"nativeData": true,
"pageErrors": 0,
"mutationRequests": 0
},
{
"section": "bgp",
"theme": "light",
"width": 320,
"scrolledCellChecks": 3,
"contrastViolations": 0,
"nativeData": true,
"pageErrors": 0,
"mutationRequests": 0
},
{
"section": "bgp",
"theme": "dark",
"width": 1440,
"scrolledCellChecks": 3,
"contrastViolations": 0,
"nativeData": true,
"pageErrors": 0,
"mutationRequests": 0
},
{
"section": "bgp",
"theme": "dark",
"width": 320,
"scrolledCellChecks": 3,
"contrastViolations": 0,
"nativeData": true,
"pageErrors": 0,
"mutationRequests": 0
},
{
"section": "ospf",
"theme": "light",
"width": 1440,
"scrolledCellChecks": 1,
"contrastViolations": 0,
"nativeData": true,
"pageErrors": 0,
"mutationRequests": 0
},
{
"section": "ospf",
"theme": "light",
"width": 320,
"scrolledCellChecks": 1,
"contrastViolations": 0,
"nativeData": true,
"pageErrors": 0,
"mutationRequests": 0
},
{
"section": "ospf",
"theme": "dark",
"width": 1440,
"scrolledCellChecks": 1,
"contrastViolations": 0,
"nativeData": true,
"pageErrors": 0,
"mutationRequests": 0
},
{
"section": "ospf",
"theme": "dark",
"width": 320,
"scrolledCellChecks": 1,
"contrastViolations": 0,
"nativeData": true,
"pageErrors": 0,
"mutationRequests": 0
}
],
"cleanup": [
{
"host": "194.226.121.150",
"ownedObjectsRemoved": 15,
"collectionsMatched": 10,
"scope": "Listed static configuration fields; dynamic state excluded"
},
{
"host": "104.165.244.7",
"ownedObjectsRemoved": 15,
"collectionsMatched": 10,
"scope": "Listed static configuration fields; dynamic state excluded"
}
],
"realPortalJWT": true,
"apiMocks": false,
"passwordsUnchanged": true,
"scope": "Owned GRE/BGP/OSPF convergence and filled-table scoped contrast; no packet-loss SLA or complete WCAG claim"
}
@@ -0,0 +1,10 @@
{
"date": "2026-10-14",
"block": "12.5.218",
"kinds": [
{
"kind": "frontend",
"matched": 527
}
]
}
@@ -0,0 +1,63 @@
{
"date": "2026-10-14",
"repository": "mmapp-test/frontend",
"preservedTags": [
"mmapp-test/frontend:ux-gre213",
"mmapp-test/frontend:ux-gre214"
],
"inUseImagesProtected": true,
"force": false,
"removedTags": [
"mmapp-test/frontend:ux-gre212",
"mmapp-test/frontend:ux-gre210",
"mmapp-test/frontend:ux-gre209",
"mmapp-test/frontend:ux-native208",
"mmapp-test/frontend:ux-history207",
"mmapp-test/frontend:ux-accessibility205",
"mmapp-test/frontend:ux-portal199",
"mmapp-test/frontend:ux-peak196",
"mmapp-test/frontend:ux-peak191",
"mmapp-test/frontend:ux-warning183",
"mmapp-test/frontend:ux-status181",
"mmapp-test/frontend:ux-volume180",
"mmapp-test/frontend:ux-live179",
"mmapp-test/frontend:ux-history178",
"mmapp-test/frontend:ux-ping173",
"mmapp-test/frontend:ux-targets171",
"mmapp-test/frontend:ux-bfd158",
"mmapp-test/frontend:ux-ospf153",
"mmapp-test/frontend:ux-wg152",
"mmapp-test/frontend:ux-gre151",
"mmapp-test/frontend:ux-sessions150",
"mmapp-test/frontend:ux-scope148",
"mmapp-test/frontend:ux-http147",
"mmapp-test/frontend:ux-labels146",
"mmapp-test/frontend:ux-traffic141",
"mmapp-test/frontend:ux-log133",
"mmapp-test/frontend:ux-ike124",
"mmapp-test/frontend:ux-bound116",
"mmapp-test/frontend:ux-keepcert115",
"mmapp-test/frontend:ux-alias112-version",
"mmapp-test/frontend:ux-alias112",
"mmapp-test/frontend:ux-a11y101",
"mmapp-test/frontend:ux-ospf91",
"mmapp-test/frontend:ux-optimizer87",
"mmapp-test/frontend:ux-ipsec77",
"mmapp-test/frontend:ux-vxlan76",
"mmapp-test/frontend:ux-479f2ad",
"mmapp-test/frontend:ux-c16fc0c",
"mmapp-test/frontend:ux-c82e8fa",
"mmapp-test/frontend:ux-bf43263",
"mmapp-test/frontend:ux-6a46fb1",
"mmapp-test/frontend:ux-3722fad",
"mmapp-test/frontend:ux-fd521f6",
"mmapp-test/frontend:ux-731803b",
"mmapp-test/frontend:ux-bd3f996",
"mmapp-test/frontend:ux-b55588f",
"mmapp-test/frontend:ux-f194e72",
"mmapp-test/frontend:ux-aa7dbdf",
"mmapp-test/frontend:ux-8782054",
"mmapp-test/frontend:ux-673e5ba",
"mmapp-test/frontend:ux-4d88b97"
]
}
+17
View File
@@ -0,0 +1,17 @@
import {test,expect} from '@playwright/test'
import axe from 'axe-core'
import {writeFileSync} from 'node:fs'
const states=['Established','Active','Idle','Connect','OpenSent','OpenConfirm','Unknown']
const server={id:1,name:'Own218 router',host:'192.0.2.1',enabled:true,country:'RU',status:null}
const host={serverId:1,serverName:server.name,serverSite:'',serverCountry:'RU'}
for(const theme of ['light','dark'])for(const width of [1440,320])for(const section of ['bgp','ospf'])test(`Routing contrast ${section} ${theme} ${width}`,async({page})=>{
test.setTimeout(90000);await page.setViewportSize({width,height:1000});await page.addInitScript(t=>localStorage.setItem('rl-theme',t),theme)
let writes=0;const sessions=states.map((state,index)=>({...host,id:'*'+(index+1),name:'own218-'+state,peerIp:'192.0.2.2',remoteAs:64513,localAs:64512,localId:'192.0.2.1',remoteId:'192.0.2.2',state,type:index===1?'iBGP':index===6?'Unknown':'eBGP',uptime:'1h',holdTime:90,keepalive:30,prefixesRx:12,prefixesTx:2,inputMessages:20,outputMessages:10,capabilities:[],lastError:null}))
const catalog={neighbors:[],interfaces:[],instances:[],bfdSessions:[],routes:['O','O IA','O E1','O E2','Unknown'].map((type,index)=>({...host,id:'r'+index,destination:'192.0.'+(index+2)+'.0/24',type,cost:10,nextHop:'192.0.2.2',via:'ether1',area:'backbone'})),failures:[]}
await page.route('**/health',r=>r.fulfill({json:{ok:true}}));await page.route('**/api/**',r=>{if(r.request().method()!=='GET')writes++;const p=new URL(r.request().url()).pathname;return r.fulfill({json:p==='/api/auth/config'?{required:false}:p==='/api/servers'?[server]:p==='/api/bgp/catalog'?{sessions,failures:[]}:p==='/api/ospf/catalog'?catalog:{}})})
await page.goto('/'+section);if(section==='ospf')await page.getByRole('button',{name:'Маршруты',exact:true}).click()
const rows=page.locator('tr[data-row-id]');await expect(rows).toHaveCount(section==='bgp'?7:5);await page.evaluate(()=>document.fonts.ready);await page.waitForTimeout(900);await page.addScriptTag({content:axe.source});const findings=[]
for(let index=0;index<await rows.count();index++)for(const cellIndex of section==='bgp'?[4,5,7]:[1]){const cell=rows.nth(index).locator('td').nth(cellIndex);await cell.scrollIntoViewIfNeeded();await cell.evaluate(el=>el.id='own218-audit');const result=await page.evaluate(async()=>(window as unknown as {axe:typeof axe}).axe.run({include:['#own218-audit']},{runOnly:{type:'rule',values:['color-contrast']}}));findings.push({row:index,cell:cellIndex,text:(await cell.innerText()).trim(),violations:result.violations.map(v=>({id:v.id,nodes:v.nodes.map(n=>({target:n.target,summary:n.failureSummary}))}))});await cell.evaluate(el=>el.removeAttribute('id'))}
writeFileSync(`tmp/routing218-${section}-${theme}-${width}.json`,JSON.stringify({date:'2026-10-14',section,theme,width,scope:'Explicitly scrolled BGP type/state/prefix RX and OSPF route type cells',findings},null,2))
if(process.env.MMAPP_A11Y_BASELINE!=='true')expect(findings.filter(f=>f.violations.length)).toEqual([]);expect(writes).toBe(0);expect(await page.evaluate(()=>document.documentElement.scrollWidth<=innerWidth+1)).toBe(true)
})
+1 -1
View File
@@ -30,5 +30,5 @@
".next/dev/types/**/*.ts", ".next/dev/types/**/*.ts",
"**/*.mts" "**/*.mts"
], ],
"exclude": ["node_modules", "backend", "packages"] "exclude": ["node_modules", "backend", "packages", "tmp", "temp", "test-results", "playwright-report"]
} }