Files
MikrotikManager/docs/ux-ui-stage-7.md
T

12 KiB
Raw Blame History

Этап 7: серверы и мониторинг

Подготовка 2026-09-20 по текущему коду после этапа 6. Блоки 7.1 и 7.2 реализованы 2026-09-21; далее права действий, блок 7.3. Основа: ReUI PRO, base-nova, Frame; переиспользовать установленные Filters/DataGrid, ServerFilters, PageHeader и Sheet. Не менять vendored-компоненты и правила сетевых операций.

Инвентаризация

Область Подтверждено в коде Следующая доработка
Серверы app/(main)/servers/page.tsx: URL читает только server; search/typeFilter/advancedFilters — локальный useState Восстановление фильтров из URL без сброса выбранного сервера
Filters server-filter-fields.ts: country/status/type; apply-filter-query.ts сохраняет AND/OR, вложенность, negated и черновики Ограниченный валидируемый codec дерева, без уплощения
Формы сервера Уже есть сохранение формы при ошибке, блокировка повторов, загрузка деталей, разделение результатов опроса и обновления списка Проверить UX шагов и доступность, сохранить существующие гарантии
Мониторинг /uptime?probe=... выбирает проверку; отдельные вкладки и фильтры пока не имеют полного URL-контракта Отдельный блок URL после серверов; не распространять probe на несвязанные ресурсы/speed
Телефон Ping-пробы: фиксированная сетка из 11 колонок, FramePanel с overflow-hidden Доступные имя/цель/состояние и действия на 320/390 px без обрезки
Права lib/auth.ts: can/hasPermission; страницы servers/uptime не используют их для разрешений действий UI-доступность по фактической политике backend, с повторной обработкой 403

Референсы и схема

Блок Референс Схема доработки
Список серверов Data Grid Filtering 2 Контекст → поиск/тип/Filters → результат → детали
Детали и формы Sheet 8 Объект → доступное действие → форма → подтверждённый API-результат
Проверки на телефоне List 9 Имя и цель → состояние → измерение → действия
ПК:      [Контекст сервера / проверки · снять выбор]
         [Поиск] [Тип] [Filters] [Доступные действия]
         [Таблица → детали → форма → результат]
         URL ↔ фильтры; Back/reload возвращают контекст

Телефон: [Имя проверки                 Состояние]
         [Источник → цель]
         [RTT / потери] [Действия]
         [Раскрыть дополнительные сведения]

Это схема иерархии, а не разрешение переписать таблицы или блоки вручную. Конкретную композицию мобильного списка выбрать из установленных компонентов после проверки текущих действий строки.

Блок 7.1 — URL серверов

Реализованный контракт:

Параметр Значение Правило
server Точный ID из этапа 6 Сохранять при изменении фильтров; отсутствие объекта не подменять другим
q Строка поиска Пустое значение удалять; ввод обновлять сразу через native replaceState, без новых записей истории и повторных запросов API
type jump-host / exit-node / home-router «Все» — отсутствие параметра; дискретный выбор добавляет запись истории
filters JSON {v:1, query: FilterQuery} URLSearchParams кодирует значение; сохранить AND/OR и структуру групп

Сначала реализовать чистый codec в lib/data-filters/server-url-state.ts и профильные unit-тесты. Валидировать до передачи в Filters/evaluator: версию, тип узла, уникальные ID, поля из SERVER_FILTER_FIELDS, допустимые для select операторы/значения. Ограничить размер JSON 8 KiB, количество узлов 50, глубину 4. Эти числа — рабочие пределы нового контракта, не существующие ограничения ReUI. Окончательный список операторов сверить с установленной конфигурацией select.

Черновик незавершённого условия оставить локальным; не публиковать частично собранное дерево и не превращать OR в AND. При восстановлении неверного filters/type показать понятное сообщение и действие сброса; до сброса не расширять результат до всех серверов молча. Не помещать в URL пароли, ключи и поля форм.

URL — источник сохранённого состояния. Back/Forward/reload восстанавливают контролы и строки без циклов синхронизации, автозаписи и повторного открытия форм. При быстрых изменениях разных контролов читать актуальные параметры, чтобы поздняя запись поиска не затёрла type/filters/server. Сброс фильтров удаляет q/type/filters, сохраняя server и чужие параметры; «Все серверы» снимает только server.

Приёмка: прямой URL; reload; Back/Forward; смена type после ввода поиска; AND/OR; черновик; повреждённый/слишком большой JSON; неизвестное поле/оператор; сброс с сохранением server; пустой результат; отсутствие POST/PATCH/DELETE от навигации. Прогнать codec unit-тесты, servers.spec.ts, профильные URL E2E, lint/TypeScript и production build. Затем журнал и локальный коммит без push.

Блоки после 7.1

  1. 7.2 — мобильные проверки (выполнено). Устранить обрезку Ping-проб, сохранив выбор строк, раскрытие, запуск и меню. Проверить 320/390/1440 px, клавиатуру/Escape, отсутствие скрытых обязательных действий и горизонтального скролла всей страницы.
  2. 7.3 — права действий. Источник политики — backend/src/lib/permissions.ts, применение — backend/src/plugins/auth.ts. GET /api/servers* требует mm:servers:read, запись — mm:servers:write; GET /api/uptime* — mm:uptime:read, запись — mm:uptime:write. Учитывать наследование write/admin через существующий hasPermission и режим auth disabled. Проверить конкретные маршруты опроса/теста соединения, не считать их чтением только по названию. UI не заменяет backend-проверку: серверный 403 сохраняет форму и сообщает отказ. Не выдавать доступ только по is_admin без подтверждения текущей политики.
  3. 7.4 — формы, детали и полный контекст мониторинга. Восстановление вкладки/фильтров из URL, понятные единицы и подписи, возврат к списку после действия. Не дублировать сохранённые исправления этапа 1; проверить загрузку, отмену, 400/403/500, timeout и повторное нажатие.
  4. 7.5 — приёмка этапа. Сценарий «проблема → сервер/проверка → действие → возврат» с сохранением контекста; профильные E2E, права в HTTP-моках, TypeScript, lint и build. Реальные JWT/RouterOS отдельно в тестовом окружении.

Локальная приёмка этапа 7 завершена 2026-09-23: 94 профильных E2E и 2 проверки смены backend. Полные границы и внешние ограничения — в docs/ux-ui-progress.md. Следующий этап — 8, трафик и статистика.

Решение по синхронизации URL (7.1)

Поиск использует native replaceState без debounce: установленный Next App Router синхронизирует useSearchParams, не запрашивая серверные данные. Браузерный тест подтвердил быстрый посимвольный ввод и неизменное количество GET /api/servers. Это устраняет отложенную запись, способную затереть последующий выбор type/filters. Дискретные изменения используют pushState, читая актуальный window.location.search. Черновик Filters привязан к сохранённому filters и сбрасывается при popstate. Неверные type/filters блокируют выдачу до исправления/сброса; server и чужие параметры сохраняются.

Реализация адаптивных строк (7.2)

Один DOM и прежние обработчики Ping-проб сохранены. Frame задаёт контейнер ширины; локальный CSS module перестраивает существующую строку в две колонки с подписями при ширине контейнера менее 1100 px. При достаточной ширине возвращается сетка 11 колонок. Имена, цель, интерфейс и фильтр переносятся; состояние подписано на узком экране. Переключатель получил доступное имя через label, кнопки — aria-label, серверный заголовок — aria-expanded. Используются прежние FormToggle/Button/Collapsible/Sparkline; ReUI и общая тема не изменены.

11 профильных E2E прошли, в том числе длинные подписи на 320/390/1440 px, видимость действий, Enter для раскрытия графика, редактирование/Escape, запрос звезды и включение пробы. Скриншоты 320/1440 просмотрены, обрезка строки устранена. Проверка не означает адаптивность всех вкладок uptime: Resources/Speed и их формы остаются отдельными частями плана.