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 <[email protected]>
11 KiB
План перевода консоли на 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:
- Каркас: AppShell (сайдбар 240/60 px, шапка 48 px, ⌘K, меню профиля с Change Theme / My Profile / Change Password / 2FA / API token), пункты из
SECTIONS. - Login (+ OTP, Forgot password, LoginCover).
- Dashboard: KpiStrip, график (Chart.js), heatmap, Top-таблицы, BlockingMenu, сравнение периодов, custom range.
- Zones: дерево/список зон, записи, панели Add/Edit Record, Add / Clone / Convert / Import / Sign / Unsign Zone, DNSSEC, Zone Options, Permissions, Edit Zone File.
- Cache: дерево кэша и записи.
- Blocking: Overview, Rules, Lists, Domain check, Recent blocked.
- Apps: каталог, установленные, Install / Update / Config.
- DNS Client.
- Settings: 9 вкладок (General, Web Service, Optional Protocols, TSIG, Recursion, Cache, Blocking, Proxy & Forwarders, Logging).
- DHCP: Leases, Scopes, ScopeForm.
- Administration: Sessions, Users, Groups, Permissions, SSO, LDAP, Cluster, UserDetails.
- Logs: View Logs, Query Logs.
- About и состояния: пусто, ошибка, нет доступа, загрузка.
- Вариации: светлая тема, высокий контраст, телефон 390 px, свёрнутое меню.
Результат этапа: холст, проверенный по чек-листу системы (Frame, одна primary-кнопка, DataGrid вместо ручных таблиц, статус = слово + глиф + токен).
Этап 2. Основа во фронтенде
- Подключить Tailwind v4 и shadcn (
base-nova), создатьcomponents.json(уже есть), алиас@/,src/theme/globals.cssна токенах системы. - Мост токенов: сопоставить
src/theme/tokens.css(893 строки) токенам ReUI, не ломая ThemeProvider (System / Light / Dark). - Установить компоненты 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.