Files
EvoFirewall/docs/ui-design-contract.md
T
Denozordec 9fa6269174
quality / changes (push) Successful in 7s
quality / commitlint (push) Skipped
quality / openapi (push) Successful in 30s
quality / web (push) Successful in 1m3s
quality / api (push) Successful in 1m15s
quality / linux-agent-smoke (push) Failing after 27s
quality / docker-check (push) Failing after 2m28s
CD / quality (push) Failing after 5m52s
CD / publish (push) Skipped
feat: harden firewall policies telemetry and operations
Implement reliable agent apply, telemetry v2, analytics retention, guarded rollouts, enrollment, labels and webhooks. Improve ReUI frontend data safety and bounded list loading, and add Docker smoke, recovery and resource checks. Document local verification and pending native acceptance.
2026-10-26 13:10:58 +07:00

136 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# UI Design Contract (ops apps)
Единый контракт для **CFDM · vps-tracker · EvoBGP · EvoFirewall · auth-portal**.
Surface: **ReUI Frame**. Kit: `apps/web/src/components/reui-kit/`.
Иерархия: **ReUI PRO > shadcn primitives**.
## EvoFirewall: согласованное сохранение текущего интерфейса (2026-10-24)
В текущем roadmap пользователь явно выбрал сохранение существующего внешнего вида. Это приоритетнее прежних рекомендаций этого документа о принудительном выравнивании всей оболочки. Не выполнять массовую замену registry-компонентов, нормализацию классов, типографики, размеров, плотности, KPI/Quick Actions или расположения header/sidebar ради соответствия историческому эталону.
Текущие chrome, локальные адаптации Frame/KPI, кнопка палитры на мобильных экранах, freshness/monitor и формы сохраняются. Поведение, состояния загрузки/ошибки, подписи метрик и доступность исправляются на существующих компонентах. Новые аналитика и диагностика используют Frame, действующие Chart/DataGrid и те же theme tokens без перестройки страницы. Registry `--overwrite` и повторная установка существующих компонентов не разрешены этим этапом.
Высокий контраст — явная пользовательская настройка, меняющая theme-aware токены только при `html[data-contrast='high']`. Стандартная тема сохраняется. Палитра имеет combobox/listbox/active-option связь и прокрутку выбранного результата; таблицы поддерживают Enter/Space, drag handles доступны клавиатурой. Для диагностических статусов и качества измерений используются Badge/Alert варианты, неизвестные данные не заменяются нулём или признаком успешности.
F1 использует те же FormSheet/RHF/Zod/FieldError для Explain и форм Port ACL, а имеющийся Sheet-паттерн overrides сохраняет черновик и добавляет срок/причину. Выбор агентов в аналитике — установленный Base UI Combobox с именами и chips, без требования вводить UUID. Редкие формы загружаются лениво и предзагружаются по фокусу/намерению; существующее расположение основных страниц сохраняется.
F2/F3 добавляют ленивые формы снимков/canary, webhook, ротации credentials и меток, сохраняя Frame/base-nova. Широкие таблицы используют `FormSheet size="lg"|"xl"`: ширина задана точными `data-[side=right]` вариантами, на мобильном — viewport, внутренний grid имеет `minmax(0,1fr)`, таблица прокручивается внутри DataGrid. Исходные registry-компоненты не переписываются. Предпросмотры не запускают изменения; ACK применения и публикация desired policy различаются. Снятие pin требует явного предупреждения о проверке и возобновлении live policy. Ключ подписи install-ссылок и webhook secrets не раскрываются при чтении.
Большие списки используют серверную пагинацию `ResourcePage.serverPagination`: поиск и все фильтры применяются ко всему списку до страницы; локальная сортировка отключена, чтобы не выдавать сортировку страницы за сортировку всего набора. Между запросами сохраняются предыдущая страница и фокус поля, показывается обновление. Неполный CIDR preview помечен сокращённым, количество остаётся полным. Импорт с хотя бы одной ошибочной строкой блокируется целиком; уникальные валидные дубликаты нормализуются.
Локальный ReUI skill обновлён до `68f0e6fa91`. PRO dry-run подтверждён для `settings-2` с `frame`/`base-nova`; файлы блока не установлены. Эти проверки не означают редизайн существующего интерфейса.
Карта: [docs](https://reui.io/docs) · [llms.txt](https://reui.io/llms.txt) · [Get Started](https://reui.io/docs/get-started) · [Styling](https://reui.io/docs/styling) · [Registry](https://reui.io/docs/registry) · [License](https://reui.io/docs/license-setup) · [Blocks](https://reui.io/blocks) · [MCP](https://reui.io/docs/mcp) · [Agent Skills](https://reui.io/docs/agent-skills)
## Surface
Project lock: **`surface: frame`**. Ops / list / dashboard / detail / settings — только **Frame**, не shadcn Card как shell. Не смешивать Card и Frame на одном ops-экране.
```ts
// apps/web/src/lib/ui-surface.ts (где есть)
export const UI_SURFACE = 'frame' as const
```
Settings: секции через Frame + `gap` (без hairline `Separator` под PageHeader); `SettingRow` без `FieldSeparator` по умолчанию (`separated` opt-in). Preview: [settings-3](https://reui.io/preview/base/settings-3) · [settings-16](https://reui.io/preview/base/settings-16).
## Canonical PRO references
| Зона | Block | Preview |
|------|-------|---------|
| Shell | `app-shell-12` (+ cmdk/monitor где нужно) | https://reui.io/preview/base/app-shell-12 · https://reui.io/preview/base/app-shell-7 |
| KPI | horizontal compact hybrid (EvoBGP SoT: icon left + label/Badge + value ± variant) | https://reui.io/preview/base/stats-12 |
| Quick Actions | Frame tiles (sibling KPI) + Badge «Перейти» | https://reui.io/preview/base/stats-12 · https://reui.io/preview/base/card-12 |
| Dashboard | `dashboard-1` | https://reui.io/preview/base/dashboard-1 |
| Lists | `data-grid-filtering-2` | https://reui.io/preview/base/data-grid-filtering-2 |
| Settings | `settings-16` + SettingRow | https://reui.io/preview/base/settings-16 |
| Auth | `auth-13` | https://reui.io/preview/base/auth-13 |
| Empty | `empty-state-14` (prefer) / `empty-state-12` | https://reui.io/preview/base/empty-state-14 · https://reui.io/preview/base/empty-state-12 |
| Forms | `form-7` → Sheet/Drawer | https://reui.io/preview/base/form-7 |
## Kit API (`reui-kit/`)
| Component | Role |
|-----------|------|
| `ResourcePage` | Frame + line tabs + Filters + DataGrid |
| `KpiStatGrid` | EvoBGP hybrid KPI tiles (`items`/`cards`, `variant`, Badge) |
| `QuickActionGrid` | KPI-like quick action tiles (gated by `showQuickActions`) |
| `OpsDashboard` | KPI + optional `afterKpi` + charts + attention queue |
| `SettingsShell` | settings nav + Outlet (**только 2+ секции**; текущий `/settings` — PageShell + Frame) |
| `DetailPanel` | detail Frame sections |
| `filter-utils` | apply/clear ReUI Filters |
`KpiStatGrid` / `QuickActionGrid` markup — SoT **EvoBGP**; в остальных apps diff только `@scope/ui` imports.
## Dashboard layout
| App | Section order |
|-----|---------------|
| EvoBGP / CFDM / EvoFirewall | KPI → **QuickActionGrid** → charts / rest |
| vps-tracker | banner → KPI → charts → attention → **QuickActionGrid** → CSV |
| auth-portal | portal-specific; Quick Actions при наличии dashboard |
Gating: DB `show_quick_actions` / `showQuickActions` / `ui_show_quick_actions` (default `true`).
## Shared App Shell chrome
Эталон разметки: production apps + ReUI [app-shell-12](https://reui.io/preview/base/app-shell-12).
При переключении между apps меняются **только** sidebar nav labels/hrefs и `main` content.
| Токен / зона | Значение |
|--------------|----------|
| `SIDEBAR_WIDTH` / `--sidebar-width` | `240px` |
| Sidebar / hover colors | theme `--sidebar` / `--sidebar-accent` — **без** AppShell `color-mix` override |
| Header | `h-12`, `sticky`, `border-b`, `px-4 md:px-6` |
| Header left | `SidebarTrigger` + `Separator` + Breadcrumb |
| Header right | **AppsMenu** → **SystemMonitorPopover** (тема — в NavUser) |
| Sidebar | AppSwitcher → groups → icons `size-4` → **NavUser** в `SidebarFooter` |
| `main` | `gap-4 md:gap-6`, `px-4 py-4 md:px-6 md:py-5` |
| Search | hotkey ⌘K / Ctrl+K only (не кнопка в header) |
Запрещено в chrome: `SidebarRail`, sync-row footer, Search pill в header, issues Badge в header, `ModeToggle` в header (тема только в NavUser), Provider `color-mix` для `--sidebar*`.
NavUser (footer): avatar + name/email; dropdown — Настройки / Тема (segmented) / Выйти. Preview: [app-shell-1](https://reui.io/preview/base/app-shell-1).
App Switcher: auth-portal `GET /api/v1/app-switcher`. Ids: `cfdm` · `vps` · `bgp` · `fw` · `dns`. Admin: portal `/admin/apps`.
QuickActionGrid / KPI icons: только semantic **text** (`text-info` / `text-primary` / …) на `IconTile` `elevated` — без solid fills.
## System monitor
`SystemMonitorPopover` in header after AppsMenu. Preview: https://reui.io/preview/base/app-shell-12 · https://reui.io/preview/base/app-shell-7
## MCP workflow
1. MCP `user-reui` — `search` / `get_block` / `compose_page` / `get_component` with `surface: "frame"`
2. Cite `previewUrl` + `docsUrl`
3. CLI from `apps/web`: `pnpm dlx shadcn@latest add @reui/...`
4. Adapt into kit — do not hand-roll KPI / Quick Actions / grid / settings rows
5. `validate_usage` / `get_audit_checklist`
Primitives: MCP `plugin-shadcn-shadcn` + project `@scope/ui` (`@cfdm/ui` / `@evobgp/ui` / `@evofw/ui` / `@authportal/ui`).
## License
```env
# apps/web/.env.local (gitignored)
REUI_LICENSE_KEY=
```
`apps/web/components.json` → `@reui` с `Authorization: Bearer ${REUI_LICENSE_KEY}`.
## Spacing
- AppShell main / PageShell: `gap-4 md:gap-6`, `px-4 py-4 md:px-6 md:py-5`
- No `space-y-*` / `space-x-*` — use `flex` + `gap-*`
- Max 1 primary CTA per screen
- Semantic tokens only — no raw `bg-emerald-*`
## Forbidden
- Card as ops list/dashboard shell
- Hand-rolled data tables when ReUI DataGrid / `ResourcePage` exists
- Hand-rolled KPI when `KpiStatGrid` exists
- Hand-rolled Quick Actions when `QuickActionGrid` exists
- SectionCards / DataGridCard as design эталон
- Mixing Card and Frame surfaces on one ops screen