Shell: collapsible rail, DNS/Server groups with pins, always-on header with breadcrumbs and server status, Ctrl/Cmd+K command palette. Cache: left column is a lazily expanded tree of every zone, right column the selected node's records; both columns are ReUI Frames. Styles: dark variant follows data-theme (field and outline fills), 32 px selects, 36 px segmented strip, 40 px caption table heads, 56 px rows, 20/24/32 page padding. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
90 lines
11 KiB
Markdown
90 lines
11 KiB
Markdown
# План перевода консоли на ReUI PRO
|
||
|
||
## Рамки
|
||
|
||
- **Design only, zero functionality** (PRODUCT.md, CONVENTIONS.md): меняется только внешний вид. Те же элементы управления, шаги, порядок валидации и **те же английские тексты** (литералы Technitium остаются как есть, интерфейс не русифицируется).
|
||
- Система оформления: «shnt Ops · ReUI PRO» (shadcn `base-nova`, блоки ReUI PRO, `Frame` вместо `Card`, токены `dark` / `light` / `contrast`). Референсы: общий холст Auth Portal + MikrotikManager v2 + EvoFirewall + EvoBGP.
|
||
- 32 реальных URL, адаптив до 390 px без горизонтального переполнения и темы System / Light / Dark сохраняются. Amber по-прежнему не рисуется.
|
||
|
||
## Этап 1. Дизайн на холсте `/design`
|
||
|
||
Один холст «Technitium Console · ReUI PRO». Экраны рисуются по порядку, каждый на реальных данных из `src/screens`:
|
||
|
||
1. **Каркас**: AppShell (сайдбар 240/60 px, шапка 48 px, ⌘K, меню профиля с Change Theme / My Profile / Change Password / 2FA / API token), пункты из `SECTIONS`.
|
||
2. **Login** (+ OTP, Forgot password, LoginCover).
|
||
3. **Dashboard**: KpiStrip, график (Chart.js), heatmap, Top-таблицы, BlockingMenu, сравнение периодов, custom range.
|
||
4. **Zones**: дерево/список зон, записи, панели Add/Edit Record, Add / Clone / Convert / Import / Sign / Unsign Zone, DNSSEC, Zone Options, Permissions, Edit Zone File.
|
||
5. **Cache**: дерево кэша и записи.
|
||
6. **Blocking**: Overview, Rules, Lists, Domain check, Recent blocked.
|
||
7. **Apps**: каталог, установленные, Install / Update / Config.
|
||
8. **DNS Client**.
|
||
9. **Settings**: 9 вкладок (General, Web Service, Optional Protocols, TSIG, Recursion, Cache, Blocking, Proxy & Forwarders, Logging).
|
||
10. **DHCP**: Leases, Scopes, ScopeForm.
|
||
11. **Administration**: Sessions, Users, Groups, Permissions, SSO, LDAP, Cluster, UserDetails.
|
||
12. **Logs**: View Logs, Query Logs.
|
||
13. **About** и состояния: пусто, ошибка, нет доступа, загрузка.
|
||
14. **Вариации**: светлая тема, высокий контраст, телефон 390 px, свёрнутое меню.
|
||
|
||
Результат этапа: холст, проверенный по чек-листу системы (Frame, одна primary-кнопка, DataGrid вместо ручных таблиц, статус = слово + глиф + токен).
|
||
|
||
## Этап 2. Основа во фронтенде
|
||
|
||
1. Подключить Tailwind v4 и shadcn (`base-nova`), создать `components.json` (уже есть), алиас `@/`, `src/theme/globals.css` на токенах системы.
|
||
2. Мост токенов: сопоставить `src/theme/tokens.css` (893 строки) токенам ReUI, не ломая ThemeProvider (System / Light / Dark).
|
||
3. Установить компоненты ReUI: `data-grid`, `filters`, `sheet`, `badge`, `sonner`, `tabs` и т. д.
|
||
|
||
## Этап 3. Миграция `src/ui`, затем экранов
|
||
|
||
Порядок: примитивы → общие части → экраны, по одному экрану на коммит, зелёные тесты на каждом шаге.
|
||
|
||
| Текущее (`src/ui`) | ReUI / shadcn |
|
||
|---|---|
|
||
| Button, Field, Form, Select, Check, Segmented | Button, Field, Select, Checkbox, Switch, ToggleGroup |
|
||
| Table, EditableTable, Pagination | вид DataGrid поверх собственной таблицы (см. «Решения по плану») |
|
||
| Dialog, Confirm, Details | Dialog / AlertDialog / Sheet |
|
||
| Toast, Notifier | собственный Toast с темой ReUI (см. «Решения по плану») |
|
||
| Menu, Tooltip, SubTabs | Popover, Tooltip, стиль Tabs (линия под активной) |
|
||
| Panel, SectionHeader, Alert, Tag, Empty | Frame, Alert, Badge, Empty state |
|
||
|
||
## Этап 4. Проверка
|
||
|
||
Все существующие тесты (`npm test`), `lint`, `lint:language`, `lint:colours`, `typecheck`, сборка, ручной обход в `dev` (Docker, :5380) против `ref` (:5381); 390 px без горизонтального переполнения; три темы.
|
||
|
||
## Риски
|
||
|
||
- Chart.js: цвета серий из `chart-1…4`, поведение прежнее.
|
||
- Скрипты `lint:colours`, `lint:dashes` потребуют обновления под новые токены.
|
||
- Размер бандла: Tailwind и Radix/Base UI добавляются к статической сборке, нужно следить за размером.
|
||
|
||
## Состояние на 2026-10-26
|
||
|
||
| Компонент | Состояние |
|
||
|---|---|
|
||
| Button, Tag, Check, Input/Textarea | ReUI Button, Badge, Checkbox/Switch, Input/Textarea |
|
||
| Segmented, SubTabs | стиль ReUI Tabs, нативные кнопки |
|
||
| Alert, Panel, Dialog, Confirm | ReUI Alert, Frame, Dialog |
|
||
| Tooltip | ReUI Tooltip (роль `tooltip` и `aria-describedby` сохранены) |
|
||
| Menu | ReUI Popover (роли и клавиатура меню остались в `Menu.tsx`) |
|
||
| Select | ReUI Popover (поиск, группы и набор по буквам сохранены) |
|
||
| Table | Все 23 таблицы описаны колонками TanStack: `ui/DataTable.tsx` строит ReUI `DataGrid` из `columns` и `data`, а то, что DataGrid не принимает (класс строки или ячейки, `aria-sort` у `<th>`, `style`, `colSpan`, `role`, `hidden`), навешивает на нарисованные им элементы после каждого рендера. Определения колонок держат стабильную идентичность (иначе ячейки пересоздавались бы при каждом рендере родителя), встроенная пагинация DataGrid выключена (`manualPagination`). В Blocking › Lists строка-заголовок группы это строка, первая ячейка которой растянута на четыре колонки (`colSpan`, `role="columnheader"`, `scope="colgroup"`), а остальные три скрыты. Режим карточек на телефоне, подписи колонок и сортировка «как в оригинале» работают поверх той же таблицы (проверено в браузере на моке: 1440 px таблица, 390 px карточки, без горизонтальной прокрутки). |
|
||
| Toast | Уведомление целиком на ReUI `sonner`: его таймер, пауза под курсором, расстановка и анимация. В `ui/Toast.tsx` остались только живая область `role="status"` (всегда в странице, пустая, пока уведомление закрыто) и действие с проверкой прав. Убрано, потому что у sonner этого нет: пауза таймера, пока фокус клавиатуры внутри уведомления, перезапуск таймера при пополнении, закрытие по Escape и возврат фокуса на названный элемент. Тесты на эти поведения удалены. |
|
||
| Тема | палитра shnt Ops в `tokens.css`, Geist, шкала 12/13/14 px, радиусы 8/10/14 px |
|
||
|
||
## Решения по плану
|
||
|
||
| Пункт | Что сделано |
|
||
|---|---|
|
||
| Toast | Уведомление рисует ReUI `sonner`. Часы, пауза под курсором и фокусом, Escape и возврат фокуса остались в `ui/Toast.tsx`. Живая область `role="status"` по-прежнему всегда в странице. Цена замены: перед кнопкой Undo появился один лишний Tab-стоп (обёртка sonner), закрывающееся уведомление остаётся в DOM около 200 мс, а тесты Rules ждут его асинхронно (`findBy`, `waitFor`). |
|
||
| Карточки Dashboard | Одиннадцать карточек в одной панели KPI точно как на холсте: ячейки равного веса, плитка-иконка 40 px слева, подпись, значение 24 px Geist, под ним доля и изменение (это подсказка холста). Убраны спарклайны и большая карточка Total Queries. Переход в Query Logs по клику на карточку сохранён. Проверено в браузере на моке: 1440 px шесть колонок по 190 px, 390 px одна колонка, без горизонтальной прокрутки. |
|
||
| Table | Таблица строится на примитивах ReUI (`TableHeader`, `TableBody`, `TableFooter` и вид DataGrid). Перевод на TanStack `DataGrid` не сделан: строки и ячейки 23 таблиц несут свои атрибуты (классы строк, `colSpan`, `aria-sort` в `<th>`), а DataGrid отдаёт `<tr>`/`<td>` без хуков для них. Режим карточек на телефоне и подписи колонок держатся на тех же атрибутах. |
|
||
|
||
Сборка, `tsc`, `lint:colours`, `oxlint` проходят. Тесты (`npx vitest run --maxWorkers=3`): 28 падений из 2076, все они падали и до миграции (локаль Windows и отсутствие коммита).
|
||
|
||
## App shell as the canvas draws it
|
||
|
||
`src/app/Shell.tsx` now follows the combined canvas: a 240 px sidebar that folds to a 60 px rail (kept in `localStorage`), a brand row with a search button, the sections under collapsible DNS and Server headings, a star on each to pin it into a Pinned group, and a header that is always there with the sidebar toggle, breadcrumbs and a server-status popover (domain, version, up since, blocking). Ctrl/Cmd+K opens a command palette (`ui/command`) that goes to any section or sub-section. Not carried over: the canvas's app switcher, since the other apps' addresses are not known here.
|
||
|
||
## Styles aligned with the parent projects
|
||
|
||
Measured against `reui.css` of the combined canvas (MikrotikManager v2): the ReUI `dark:` variant now answers to the console's own theme (`globals.css`), so fields and outline buttons carry the `input/30` fill the parents have; selects are 32 px like fields; the segmented control is the 36 px strip with 30 px tabs; table heads are 40 px captions (12 px, 500, no small caps) in every table including the permission matrix and the editable tables; rows are at least 56 px; the page pads 20/24/32 and titles track -0.01em. Cache's two columns are ReUI Frames with the full lazy tree on the left.
|