AURORA-1836: фиксированная высота строк вместо measureElement #222

Open
aep wants to merge 2 commits from feat/211-aurora-1836-row-measure into test
Owner

Closes #211

Jira: AURORA-1836

Что сделано

  • Новый хелпер createFixedRowVirtualizerOptions({ rowHeight, overscan, extra }) (RealtimeTable/utils/virtualizerOptions.js): estimateSize и measureElement возвращают константу, элемент не читается (нет offsetHeight/getBoundingClientRect, нет синхронного layout).
  • Лист (RealtimeTable.jsx), свод 1 (SummaryTable.jsx), свод 2 (Svod2Page.jsx) переведены на хелпер.
  • Высота строки задана явно: строке (muiTableBodyRowProps.style.height) и ячейке (height + overflow: hidden, box-sizing: border-box), чтобы раскладка и виртуализатор не расходились.
  • Мёртвая BASE_TABLE_CONFIG.muiTableRowProps (80 px / 5rem, MRT v3 её не читает) удалена; TABLE_ROW_HEIGHT теперь '3rem'.
  • Overscan строк свода 2: 8 -> 3. Overscan строк листа не менялся (AURORA-1837).
  • Фактическая высота сохранена, не 80 px.

Тесты

  • node --test web/src/components/RealtimeTable/utils/*.test.js: 13 passed, 0 failed (включая virtualizerOptions.test.js с Proxy, бросающим на любое чтение свойства элемента).
  • npm run build проходит. biome check по изменённым файлам: новых замечаний нет (в RealtimeTable.jsx, SummaryTable.jsx, Svod2Page.jsx остались прежние format/organizeImports/lint, репозиторий biome-ом не отформатирован).
  • Бэк не менялся, pytest не запускался.

Проверить руками

  • Лист FORM_2/AHR: нет наездов строк и щелей в начале, середине и конце прокрутки.
  • Последняя строка видна целиком.
  • Сворачивание и разворачивание групп.
  • Масштаб sizeMult 0.8 / 1 / 1.5.
  • Поиск: переход к совпадению (scrollToIndex) попадает в нужную строку.
  • Окна шириной около 1366, 1600, 1920 и более 1920 px: высота зависит от rem (см. R-1), строки не должны наезжать.
  • Свод 1 (с раскрытием строк) и свод 2 (с фильтрами, плашки «Вид сметы»/«ССП»): без наездов и щелей, последняя строка видна.

Замер до/после

Будет добавлен после ночного прогона на стенде perf/.
Сценарии: PERF_RUN_ID=<id> PERF_TARGETS='FORM_2/AHR/*' PERF_ROLES=rf PERF_AXES=y PERF_REPEATS=3 PERF_TRACE=0 npx playwright test scenarios/scroll.spec.ts; своды: PERF_TARGETS='svod/svod1_MAIN,svod/svod2_GO,svod/projects_summaries' PERF_ROLES=dfip PERF_MAX_STEPS=200. Ожидание: в CPU-профиле нет offsetHeight; FORM_2/AHR не хуже -10 % от 89 мс.

Rulings I made

  • R-1: высота строки в rem, а не в px. Фактическая высота листа равна 3rem (minHeight/maxHeight ячейки), а html { font-size: .83vw } при ширине <= 1920 делает rem зависимым от окна: «~40 px» из отчёта perf соответствует окну около 1600 px (3 x 13,3 = 39,8), а на 1920 строка 47,8 px. Постоянный px привёл бы к наездам. Поэтому строка/ячейка заданы в rem, а виртуализатор получает функцию getRootFontSizePx() * 3 (по window.innerWidth, без чтения layout). Цена ошибки: расхождение фо��мулы с App.css даёт наезды/щели; при смене ширины окна ResizeObserver строк снова вызывает measureElement, значение пересчитывается.
  • R-2: высота свода 1 = 2.25rem, свода 2 = 2.75rem. Выведены из стилей (py 0.5rem x 2 + line-height 1.43 x 0.8125rem + 1 px граница ~ 2.2rem; у свода 2 добавлена плашка 0.25rem x 2 + 1.35 x 0.8125rem + рамка ~ 2.7rem), вживую не замерены. Прежние 37 px были лишь оценкой. Цена ошибки: небольшое изменение плотности строк; значение правится константой ROW_HEIGHT_REM.
  • R-3: хелпер принимает rowHeight числом или функцией и extra для прочих опций (scrollPaddingStart/End листа). Цена ошибки: нет.
  • R-4: height/overflow: hidden добавлены только в тело (getTableBodyCellProps), а не в общий getTableHeadCellStyles, чтобы не обрезать элементы заголовка.

🤖 Generated with Claude Code

Closes #211 Jira: AURORA-1836 ## Что сделано - Новый хелпер `createFixedRowVirtualizerOptions({ rowHeight, overscan, extra })` (`RealtimeTable/utils/virtualizerOptions.js`): `estimateSize` и `measureElement` возвращают константу, элемент не читается (нет `offsetHeight`/`getBoundingClientRect`, нет синхронного layout). - Лист (`RealtimeTable.jsx`), свод 1 (`SummaryTable.jsx`), свод 2 (`Svod2Page.jsx`) переведены на хелпер. - Высота строки задана явно: строке (`muiTableBodyRowProps.style.height`) и ячейке (`height` + `overflow: hidden`, `box-sizing: border-box`), чтобы раскладка и виртуализатор не расходились. - Мёртвая `BASE_TABLE_CONFIG.muiTableRowProps` (80 px / 5rem, MRT v3 её не читает) удалена; `TABLE_ROW_HEIGHT` теперь `'3rem'`. - Overscan строк свода 2: 8 -> 3. Overscan строк листа не менялся (AURORA-1837). - Фактическая высота сохранена, не 80 px. ## Тесты - `node --test web/src/components/RealtimeTable/utils/*.test.js`: 13 passed, 0 failed (включая `virtualizerOptions.test.js` с Proxy, бросающим на любое чтение свойства элемента). - `npm run build` проходит. `biome check` по изменённым файлам: новых замечаний нет (в `RealtimeTable.jsx`, `SummaryTable.jsx`, `Svod2Page.jsx` остались прежние format/organizeImports/lint, репозиторий biome-ом не отформатирован). - Бэк не менялся, pytest не запускался. ## Проверить руками - Лист FORM_2/AHR: нет наездов строк и щелей в начале, середине и конце прокрутки. - Последняя строка видна целиком. - Сворачивание и разворачивание групп. - Масштаб sizeMult 0.8 / 1 / 1.5. - Поиск: переход к совпадению (scrollToIndex) попадает в нужную строку. - Окна шириной около 1366, 1600, 1920 и более 1920 px: высота зависит от rem (см. R-1), строки не должны наезжать. - Свод 1 (с раскрытием строк) и свод 2 (с фильтрами, плашки «Вид сметы»/«ССП»): без наездов и щелей, последняя строка видна. ## Замер до/после Будет добавлен после ночного прогона на стенде perf/. Сценарии: `PERF_RUN_ID=<id> PERF_TARGETS='FORM_2/AHR/*' PERF_ROLES=rf PERF_AXES=y PERF_REPEATS=3 PERF_TRACE=0 npx playwright test scenarios/scroll.spec.ts`; своды: `PERF_TARGETS='svod/svod1_MAIN,svod/svod2_GO,svod/projects_summaries' PERF_ROLES=dfip PERF_MAX_STEPS=200`. Ожидание: в CPU-профиле нет `offsetHeight`; FORM_2/AHR не хуже -10 % от 89 мс. ## Rulings I made - R-1: высота строки в rem, а не в px. Фактическая высота листа равна 3rem (minHeight/maxHeight ячейки), а `html { font-size: .83vw }` при ширине <= 1920 делает rem зависимым от окна: «~40 px» из отчёта perf соответствует окну около 1600 px (3 x 13,3 = 39,8), а на 1920 строка 47,8 px. Постоянный px привёл бы к наездам. Поэтому строка/ячейка заданы в rem, а виртуализатор получает функцию `getRootFontSizePx() * 3` (по `window.innerWidth`, без чтения layout). Цена ошибки: расхождение фо��мулы с App.css даёт наезды/щели; при смене ширины окна ResizeObserver строк снова вызывает `measureElement`, значение пересчитывается. - R-2: высота свода 1 = 2.25rem, свода 2 = 2.75rem. Выведены из стилей (py 0.5rem x 2 + line-height 1.43 x 0.8125rem + 1 px граница ~ 2.2rem; у свода 2 добавлена плашка 0.25rem x 2 + 1.35 x 0.8125rem + рамка ~ 2.7rem), вживую не замерены. Прежние 37 px были лишь оценкой. Цена ошибки: небольшое изменение плотности строк; значение правится константой `ROW_HEIGHT_REM`. - R-3: хелпер принимает `rowHeight` числом или функцией и `extra` для прочих опций (`scrollPaddingStart/End` листа). Цена ошибки: нет. - R-4: `height`/`overflow: hidden` добавлены только в тело (`getTableBodyCellProps`), а не в общий `getTableHeadCellStyles`, чтобы не обрезать элементы заголовка. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
aep added 2 commits 2026-10-28 17:10:54 +03:00
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Высота строки и ячейки задана явно в rem, виртуализатор не читает offsetHeight.
Мёртвая muiTableRowProps удалена. Overscan строк свода 2: 8 -> 3.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This pull request can be merged automatically.
You are not authorized to merge this pull request.

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin feat/211-aurora-1836-row-measure:feat/211-aurora-1836-row-measure
git checkout feat/211-aurora-1836-row-measure
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: RSHB/DFiP_Budget_planing#222
No description provided.