From 1ad6b4a6b6b66ceee006053c44265d5eb7b49ecb Mon Sep 17 00:00:00 2001 From: Denozordec Date: Sun, 4 Oct 2026 21:58:57 +0700 Subject: [PATCH] =?UTF-8?q?fix(ui):=20=D0=BE=D0=B3=D1=80=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D1=87=D0=B8=D1=82=D1=8C=20=D0=BE=D1=82=D0=BE=D0=B1=D1=80=D0=B0?= =?UTF-8?q?=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BC=D0=B0=D1=82=D1=80=D0=B8?= =?UTF-8?q?=D1=86=D1=8B=20WAN=20=D0=B8=20Jump=20Host?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../route-optimizer-wan-matrix-data-grid.tsx | 80 +++++++++++++++--- docs/ux-ui-performance.md | 9 ++ docs/ux-ui-plan.md | 2 +- docs/ux-ui-progress.md | 2 +- docs/ux-ui-stage-12.md | 9 ++ .../screens/optimizer-wan-matrix-1000-320.png | Bin 0 -> 42632 bytes .../optimizer-wan-matrix-100jh-320.png | Bin 0 -> 39974 bytes tests/e2e/large-optimizer-wan-matrix.spec.ts | 44 +++++++++- 8 files changed, 132 insertions(+), 14 deletions(-) create mode 100644 docs/ux-ui/screens/optimizer-wan-matrix-1000-320.png create mode 100644 docs/ux-ui/screens/optimizer-wan-matrix-100jh-320.png diff --git a/components/data-grids/route-optimizer-wan-matrix-data-grid.tsx b/components/data-grids/route-optimizer-wan-matrix-data-grid.tsx index de653568..59d9af67 100644 --- a/components/data-grids/route-optimizer-wan-matrix-data-grid.tsx +++ b/components/data-grids/route-optimizer-wan-matrix-data-grid.tsx @@ -2,7 +2,10 @@ import { dataGridFeatures, type DataGridFeatures } from "@/components/reui/data-grid" -import { useMemo } from "react" +import { useEffect, useMemo, useState } from "react" +import { Input } from "@/components/ui/input" +import { Button } from "@/components/ui/button" +import { DataGridContainer, DataGridScrollArea, DataGridTable } from "@/components/reui/data-grid" import { type ColumnDef, useTable, @@ -38,12 +41,35 @@ function RouteOptimizerWanMatrixDataGrid({ legs, jumpHosts, }: RouteOptimizerWanMatrixDataGridProps) { - const bestScore = legs.length ? Math.max(...legs.map((l) => l.score)) : 0 + const [wanQuery, setWanQuery] = useState("") + const [jhQuery, setJhQuery] = useState("") + const [jhPage, setJhPage] = useState(0) + const filteredWans = useMemo(() => home.wans.filter(wan => + [wan.name, wan.iface, wan.isp, wan.ip, wan.id].join(" ").toLocaleLowerCase().includes(wanQuery.trim().toLocaleLowerCase())), [home.wans, wanQuery]) + const filteredHosts = useMemo(() => jumpHosts.filter(jh => + [jh.label, jh.site, jh.ip, jh.country, jh.id].join(" ").toLocaleLowerCase().includes(jhQuery.trim().toLocaleLowerCase())), [jumpHosts, jhQuery]) + const lastHostPage = Math.max(0, Math.ceil(filteredHosts.length / 5) - 1) + const hostPage = Math.min(jhPage, lastHostPage) + if (jhPage !== hostPage) setJhPage(hostPage) + const visibleHosts = useMemo(() => filteredHosts.slice(hostPage * 5, hostPage * 5 + 5), [filteredHosts, hostPage]) + const { bestScore, legMap } = useMemo(() => { + let bestScore = legs.length ? -Infinity : 0 + const legMap = new Map>() + for (const leg of legs) { + bestScore = Math.max(bestScore, leg.score) + let byHost = legMap.get(leg.wanId) + if (!byHost) { byHost = new Map(); legMap.set(leg.wanId, byHost) } + // Preserve the first matching leg, as the former Array.find did. + if (!byHost.has(leg.jhId)) byHost.set(leg.jhId, leg) + } + return { bestScore, legMap } + }, [legs]) const columns = useMemo[]>(() => { const base: ColumnDef[] = [ { id: "wan", + size: 180, accessorKey: "name", header: () => WAN-аплинк, cell: ({ row }) => { @@ -62,6 +88,7 @@ function RouteOptimizerWanMatrixDataGrid({ }, { id: "isp", + size: 160, header: () => ISP / IP, cell: ({ row }) => { const wan = row.original @@ -76,6 +103,7 @@ function RouteOptimizerWanMatrixDataGrid({ }, { id: "bandwidth", + size: 112, header: () => ( Лимит модели @@ -97,8 +125,9 @@ function RouteOptimizerWanMatrixDataGrid({ }, ] - const jhCols: ColumnDef[] = jumpHosts.map((jh) => ({ + const jhCols: ColumnDef[] = visibleHosts.map((jh) => ({ id: `jh-${jh.id}`, + size: 200, header: () => (
{jh.label}
@@ -110,7 +139,7 @@ function RouteOptimizerWanMatrixDataGrid({ ), cell: ({ row }) => { const wan = row.original - const leg = legs.find((l) => l.wanId === wan.id && l.jhId === jh.id) + const leg = legMap.get(wan.id)?.get(jh.id) if (!leg) return — const isBest = leg.score === bestScore return ( @@ -165,24 +194,55 @@ function RouteOptimizerWanMatrixDataGrid({ } return [...base, ...jhCols] - }, [bestScore, jumpHosts, legs]) + }, [bestScore, visibleHosts, legMap]) const table = useTable({ features: dataGridFeatures, - manualPagination: true, + manualPagination: false, + autoResetPageIndex: false, + initialState: { pagination: { pageIndex: 0, pageSize: 50 }, columnPinning: { start: ["wan"], end: [] } }, manualSorting: true, - data: home.wans, + data: filteredWans, columns, getRowId: (row) => row.id, }) + const { pageIndex, pageSize } = table.state.pagination + useEffect(() => { + const lastPage = Math.max(0, Math.ceil(filteredWans.length / pageSize) - 1) + if (pageIndex > lastPage) table.setPageIndex(lastPage) + }, [filteredWans.length, pageIndex, pageSize, table]) + return ( +
+
+ + +
+
+ WAN: {filteredWans.length} из {home.wans.length}. Jump Host: {filteredHosts.length} из {jumpHosts.length}. + {filteredHosts.length > 5 && <> + Столбцы {hostPage * 5 + 1}–{Math.min((hostPage + 1) * 5, filteredHosts.length)} из {filteredHosts.length} + + + } +
50 || pageSize !== 50} tableClassNames={{ headerRow: "border-b bg-muted/20", bodyRow: "group/row hover:bg-muted/30" }} - tableLayout={{ dense: true }} - /> + tableLayout={{ dense: true, width: "fixed", columnsPinnable: true }} + > + + + + +
) } diff --git a/docs/ux-ui-performance.md b/docs/ux-ui-performance.md index 2ca3f6de..02d46899 100644 --- a/docs/ux-ui-performance.md +++ b/docs/ux-ui-performance.md @@ -124,3 +124,12 @@ commRecs строятся через filter(sourceServerId).slice(0,24), а Home 2026-10-04. Live API подменён строгими DTO, без Exit и API mutations. Два браузерных профиля прошли: WAN1000×JH1 — 1000 строк,4 столбца,28019 DOM таблицы,28712 DOM страницы,4977мс dev-ready,108917байт; WAN10×JH100 — 10 строк,103 столбца,9803 DOM таблицы,10595 DOM страницы,2258мс dev-ready,16593байт. Время dev измеряет также загрузку/компиляцию и не является production benchmark. Чистый расчёт7WAN×20 wildcard probes воспроизводится scripts/performance/optimizer-probes-profile.mjs, в отдельном child process с жёстким timeout10000мс. Расчёт не завершился за timeout; тяжёлый DFS нельзя воспроизводить в UI. Нет DB/API/сетевых операций. Следующий12.3.60 — страницы50WAN и ограниченное окно JH, поиск по полному каталогу, проверка обновления/сжатия и320px. Семантику назначения probes этим блоком не меняем. + + +## 12.3.60 — ограниченное отображение WAN matrix + +2026-10-04. ReUI DataGrid/TanStack v9: клиентские страницы50WAN, окно5JH, поиск по полному WAN/JH каталогу, точные filtered/total counts. Fixed widths/горизонтальный DataGridScrollArea/закреплённый WAN; страницы сохраняются при refresh и нормализуются при сжатии каталога. Best score берётся из всех legs циклом без spread; Map WAN→JH сохраняет первый matching leg, как прежний find. Raw unknown/zero/даты и модель остаются раздельными. API writes отсутствуют. + +WAN1000×JH1:1000→50rows,28019→1419tableDOM,28712→2149pageDOM,2264ms dev-ready. WAN10×JH100:103→8columns,9803→683tableDOM,10595→1492pageDOM,1785ms dev-ready. Полные исходные массивы остаются в памяти. + +Проверены12browser + повтор2 после lint-правки, TypeScript без incremental, targeted ESLint, production build, ReUI validate_usage/checklist. Мобильные снимки docs/ux-ui/screens/optimizer-wan-matrix-{1000,100jh}-320.png просмотрены. Поиск последних объектов, последний диапазон, cache/refresh/clamp,320px/pinnedWAN и WCAG axe приняты. Общая регрессия после delta ещё требуется.6 manualPagination:true остаются; CPU DFS и срез24 commRecs не исправлены этим блоком. diff --git a/docs/ux-ui-plan.md b/docs/ux-ui-plan.md index c63f7d09..0121c708 100644 --- a/docs/ux-ui-plan.md +++ b/docs/ux-ui-plan.md @@ -1,6 +1,6 @@ # План реализации UX/UI по пятичасовым окнам -Актуальное продолжение 2026-10-04: 12.3.59 завершён: отдельные профили WAN1000×JH1, WAN10×JH100 и CPU7WAN×20 probes. Следующий12.3.60: ограничить отображение WAN/JH без среза исходных данных; тяжёлый DFS пока остаётся отдельным риском. Общая регрессия после delta и внешняя12.5 остаются. +Актуальное продолжение 2026-10-04: 12.3.60 завершён: WAN matrix50 rows/5JH, полный поиск и best, обновление/clamp/320px/axe. Следующий12.3.61: ускорить DFS назначения проб с доказательством сохранения выбора и tie-порядка; CPU7WAN×20 пока timeout10с. Общая регрессия после delta и внешняя12.5 остаются. Общий план проекта MikrotikManager. Основан на согласованном плане из задачи; точка продолжения обновлена 2026-10-04. Источник фактического прогресса, проверок и ограничений — [журнал реализации](ux-ui-progress.md). Этот документ задаёт объём и критерии завершения, журнал фиксирует результат. diff --git a/docs/ux-ui-progress.md b/docs/ux-ui-progress.md index 95dc60c2..331683f6 100644 --- a/docs/ux-ui-progress.md +++ b/docs/ux-ui-progress.md @@ -1,6 +1,6 @@ # UX/UI: журнал реализации -Актуальное продолжение 2026-10-04: 12.3.59 завершён: отдельные профили WAN1000×JH1, WAN10×JH100 и CPU7WAN×20 probes. Следующий12.3.60: ограничить отображение WAN/JH без среза исходных данных; тяжёлый DFS пока остаётся отдельным риском. Общая регрессия после delta и внешняя12.5 остаются. +Актуальное продолжение 2026-10-04: 12.3.60 завершён: WAN matrix50 rows/5JH, полный поиск и best, обновление/clamp/320px/axe. Следующий12.3.61: ускорить DFS назначения проб с доказательством сохранения выбора и tie-порядка; CPU7WAN×20 пока timeout10с. Общая регрессия после delta и внешняя12.5 остаются. Общий план: [UX/UI по этапам и пятичасовым окнам](ux-ui-plan.md). План задаёт объём, этот журнал фиксирует выполненные блоки и ограничения. diff --git a/docs/ux-ui-stage-12.md b/docs/ux-ui-stage-12.md index ccf578c0..5467a847 100644 --- a/docs/ux-ui-stage-12.md +++ b/docs/ux-ui-stage-12.md @@ -676,3 +676,12 @@ commRecs строятся через filter(sourceServerId).slice(0,24), а Home 2026-10-04. Live API подменён строгими DTO, без Exit и API mutations. Два браузерных профиля прошли: WAN1000×JH1 — 1000 строк,4 столбца,28019 DOM таблицы,28712 DOM страницы,4977мс dev-ready,108917байт; WAN10×JH100 — 10 строк,103 столбца,9803 DOM таблицы,10595 DOM страницы,2258мс dev-ready,16593байт. Время dev измеряет также загрузку/компиляцию и не является production benchmark. Чистый расчёт7WAN×20 wildcard probes воспроизводится scripts/performance/optimizer-probes-profile.mjs, в отдельном child process с жёстким timeout10000мс. Расчёт не завершился за timeout; тяжёлый DFS нельзя воспроизводить в UI. Нет DB/API/сетевых операций. Следующий12.3.60 — страницы50WAN и ограниченное окно JH, поиск по полному каталогу, проверка обновления/сжатия и320px. Семантику назначения probes этим блоком не меняем. + + +## 12.3.60 — ограниченное отображение WAN matrix + +2026-10-04. ReUI DataGrid/TanStack v9: клиентские страницы50WAN, окно5JH, поиск по полному WAN/JH каталогу, точные filtered/total counts. Fixed widths/горизонтальный DataGridScrollArea/закреплённый WAN; страницы сохраняются при refresh и нормализуются при сжатии каталога. Best score берётся из всех legs циклом без spread; Map WAN→JH сохраняет первый matching leg, как прежний find. Raw unknown/zero/даты и модель остаются раздельными. API writes отсутствуют. + +WAN1000×JH1:1000→50rows,28019→1419tableDOM,28712→2149pageDOM,2264ms dev-ready. WAN10×JH100:103→8columns,9803→683tableDOM,10595→1492pageDOM,1785ms dev-ready. Полные исходные массивы остаются в памяти. + +Проверены12browser + повтор2 после lint-правки, TypeScript без incremental, targeted ESLint, production build, ReUI validate_usage/checklist. Мобильные снимки docs/ux-ui/screens/optimizer-wan-matrix-{1000,100jh}-320.png просмотрены. Поиск последних объектов, последний диапазон, cache/refresh/clamp,320px/pinnedWAN и WCAG axe приняты. Общая регрессия после delta ещё требуется.6 manualPagination:true остаются; CPU DFS и срез24 commRecs не исправлены этим блоком. diff --git a/docs/ux-ui/screens/optimizer-wan-matrix-1000-320.png b/docs/ux-ui/screens/optimizer-wan-matrix-1000-320.png new file mode 100644 index 0000000000000000000000000000000000000000..4da86281203450e16d163032b8a62c45b1dd3089 GIT binary patch literal 42632 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 literal 0 HcmV?d00001 diff --git a/docs/ux-ui/screens/optimizer-wan-matrix-100jh-320.png b/docs/ux-ui/screens/optimizer-wan-matrix-100jh-320.png new file mode 100644 index 0000000000000000000000000000000000000000..2b45733e51dc1ecb23c855612a52225c03bd7faf GIT binary patch literal 39974 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 { test.setTimeout(90000) const common = { host: "192.0.2.1", enabled: true, status: "online", latency: 10, country: "RU", site: "TEST", model: "CHR" } - const servers = optimizerServersSchema.parse([ + let servers = optimizerServersSchema.parse([ { ...common, id: 1, name: "Домашний роутер", type: "home-router", wanUplinks: Array.from({ length: wanCount }, (_, i) => ({ id: `wan${i+1}`, name: `WAN${i+1}`, isp: "ISP", iface: `ether${i+1}`, ip: `198.51.100.${i+1}`, maxDl: 100, maxUl: 100 })) }, ...Array.from({ length: jhCount }, (_, i) => ({ ...common, id: i+2, name: `Jump ${i+1}`, type: "jump-host" })), ]) + let reads = 0 const writes: string[] = [] await page.route("**/health", r => r.fulfill({ json: { ok: true } })) await page.route("**/api/**", r => { const path = new URL(r.request().url()).pathname + if (path === "/api/servers") reads++ if (r.request().method() !== "GET" && !path.endsWith("/preview")) writes.push(path) return r.fulfill({ json: path === "/api/auth/config" ? { required: false } : path === "/api/servers" ? servers : path === "/api/filters/rules" ? { rulesets: [] } : path === "/api/uptime/speed-probes" ? { probes: [] } : path === "/api/ospf/catalog" ? { interfaces: [], instances: [], neighbors: [], bfdSessions: [], routes: [], failures: [] } : path.endsWith("/ospf/optimize/preview") ? { serverId: 1, serverName: "Домашний роутер", pingWeight: 60, interfacesTotal: 0, changedCount: 0, unchangedCount: 0, interfaces: [], changes: [] } : {} }) @@ -22,9 +25,46 @@ for (const [wanCount,jhCount] of [[1000,1],[10,100]]) { const started=Date.now(); await page.goto("/route-optimizer?server=1&keep=1") const table=page.getByRole("table").filter({hasText:"WAN-аплинк"}) - await expect(table.locator("tr[data-row-id]")).toHaveCount(wanCount) + await expect(table.locator("tr[data-row-id]")).toHaveCount(Math.min(50,wanCount)) const profile={wanCount,jhCount,bytes:Buffer.byteLength(JSON.stringify(servers)),rows:await table.locator("tr[data-row-id]").count(),columns:await table.getByRole("columnheader").count(),tableNodes:await table.locator("*").count(),pageNodes:await page.locator("*").count(),readyMs:Date.now()-started} console.log("WAN matrix",JSON.stringify(profile)); writeFileSync(info.outputPath("matrix-profile.json"),JSON.stringify(profile,null,2)) + const root=page.getByRole("region",{name:"Матрица WAN и Jump Host"}) + await expect(table.getByRole("columnheader")).toHaveCount(3+Math.min(5,jhCount)) + if(wanCount>50){ + const next=root.getByRole("button",{name:"Следующая страница",exact:true}) + await next.click(); await expect(table.locator("tr[data-row-id]").first()).toHaveAttribute("data-row-id","wan51") + const before=reads; await page.getByRole("button",{name:"Обновить",exact:true}).click(); await expect.poll(()=>reads).toBeGreaterThan(before) + await expect(table.locator("tr[data-row-id]").first()).toHaveAttribute("data-row-id","wan51") + await root.getByRole("textbox",{name:"Поиск WAN",exact:true}).fill("WAN1000") + await expect(table.locator("tr[data-row-id]")).toHaveCount(1); await expect(table.locator("tr[data-row-id]").first()).toHaveAttribute("data-row-id","wan1000") + await root.getByRole("textbox",{name:"Поиск WAN",exact:true}).fill("") + for(let i=0;i<19;i++)await next.click() + await expect(next).toBeDisabled();await expect(table.locator("tr[data-row-id]").last()).toHaveAttribute("data-row-id","wan1000") + } else { + const next=root.getByRole("button",{name:"Следующие Jump Host",exact:true}) + await next.click();await expect(table.getByRole("columnheader",{name:/Jump 6/})).toBeVisible() + const before=reads;await page.getByRole("button",{name:"Обновить",exact:true}).click();await expect.poll(()=>reads).toBeGreaterThan(before) + await expect(table.getByRole("columnheader",{name:/Jump 6/})).toBeVisible() + await root.getByRole("textbox",{name:"Поиск Jump Host",exact:true}).fill("Jump 100") + await expect(table.getByRole("columnheader")).toHaveCount(4);await expect(table.getByRole("columnheader",{name:/Jump 100/})).toBeVisible() + await root.getByRole("textbox",{name:"Поиск Jump Host",exact:true}).fill("no-such-host") + await expect(root).toContainText("Jump Host: 0 из 100");await expect(table.getByRole("columnheader")).toHaveCount(3) + await root.getByRole("textbox",{name:"Поиск Jump Host",exact:true}).fill("") + for(let i=0;i<19;i++)await next.click() + await expect(next).toBeDisabled();await expect(table.getByRole("columnheader",{name:/Jump 100/})).toBeVisible() + } + await page.setViewportSize({width:320,height:1000}) + const scroll=root.locator('[data-slot="scroll-area-viewport"]') + await scroll.evaluate(el=>{el.scrollLeft=el.scrollWidth}) + expect(await table.locator('tr[data-row-id]').first().getByRole('cell').first().evaluate(el=>{const a=el.getBoundingClientRect(),v=el.closest('[data-slot="scroll-area-viewport"]')!.getBoundingClientRect();return a.left>=v.left-1&&a.right<=v.right+1})).toBe(true) + expect(await page.evaluate(()=>document.documentElement.scrollWidth)).toBeLessThanOrEqual(320) + await scroll.evaluate(el=>{el.scrollLeft=0});await root.evaluate(el=>el.scrollIntoView({block:"start"})) + await page.addStyleTag({content:"nextjs-portal{display:none!important}"});await page.screenshot({path:info.outputPath("matrix-320.png"),animations:"disabled"}) + await page.addScriptTag({content:axe.source}) + expect((await page.evaluate(async()=> (window as unknown as {axe:typeof axe}).axe.run(document.querySelector('[aria-label="Матрица WAN и Jump Host"]')!,{runOnly:{type:"tag",values:["wcag2a","wcag2aa","wcag21a","wcag21aa"]}}))).violations.map(v=>({id:v.id,nodes:v.nodes.map(n=>n.target)}))).toEqual([]) + servers=servers.slice(0,2).map(server=>server.id===1?{...server,wanUplinks:server.wanUplinks!.slice(0,1)}:server) + await page.getByRole("button",{name:"Обновить",exact:true}).click() + await expect(table.locator('tr[data-row-id]')).toHaveCount(1);await expect(table.locator('tr[data-row-id]').first()).toHaveAttribute('data-row-id','wan1');await expect(table.getByRole('columnheader')).toHaveCount(4) expect(writes).toEqual([]) }) }