Files
harbor-net/docs/audits/windows-client-ux-2026-07-08/AUDIT.md

17 KiB
Raw Blame History

UX/UI-аудит Windows-клиента

Дата: 2026-07-08

Область аудита

Проверен текущий React UI apps/windows-client для Vite/Tauri как компактная Windows-утилита управления proxy-маршрутизацией приложений. Аудит выполнялся в browser-preview на http://127.0.0.1:5174/, поэтому нативные Tauri-команды были недоступны, а интерфейс показывал preview/runtime-ошибки. Все выводы ниже привязаны к скриншотам, снятым в этом прогоне.

Цель пользователя

Главная задача пользователя - быстро управлять службами и понять:

  • какие компоненты установлены;
  • какие службы запущены, остановлены или отсутствуют;
  • какое действие доступно прямо сейчас: установить, удалить, запустить, остановить, обновить, добавить или применить;
  • что сейчас маршрутизируется;
  • через какую цепочку компонентов идет трафик;
  • готовы ли ProxiFyre и опциональный Local sing-box;
  • можно ли безопасно применить изменения;
  • что делать дальше, если что-то сломано.

Цель по доступности: интерфейс должен быть управляемым с клавиатуры, с понятными статусами, читаемым восстановлением после ошибок, предсказуемыми focus states и устойчивой адаптацией к узким размерам Windows-окна.

Доказательства

  1. 01-summary-desktop.png - панель "Сводка", desktop-ширина. Состояние: смешанное. Главный статус виден, но примененное состояние еще "загружается", а рядом уже показан бейдж "Совпадает".
  2. 02-proxifyre-desktop.png - панель ProxiFyre, desktop-ширина. Состояние: в целом рабочее. Состав компонента и список приложений компактны, но главное действие apply доступно даже при отсутствующих prerequisites.
  3. 03-proxy-desktop.png - панель "VPN / Прокси", desktop-ширина. Состояние: рабочее. Настройка маршрута понятна, но route path выглядит как вторичный текст, а apply-action выглядит валидным до того, как маршрут может успешно примениться.
  4. 04-proxy-validation-desktop.png - невалидный proxy input. Состояние: хорошая база. Inline-валидация находится рядом с полем и отключает действие проверки.
  5. 05-summary-narrow.png - панель "Сводка", узкая ширина. Состояние: напряженное. Контент перестраивается, но нижний log dock и длинные сообщения обрезают важную информацию.
  6. 06-proxifyre-narrow.png - панель ProxiFyre, узкая ширина. Состояние: напряженное. Контролы складываются неплохо, но setup chips переполняются по горизонтали, а нижний dock конкурирует с основной задачей.

Доменное направление

Ключевые понятия домена: цепочка маршрута, здоровье компонентов, локальный runtime, внешний endpoint, выбранные приложения, сгенерированный конфиг, граница apply/restart, диагностика.

Цветовой мир: темная Windows-оболочка, терминальный черный, зеленый для driver/service ready, amber для предупреждений, красный для блокеров/firewall, синий для links/actions, slate для config-файлов.

Сигнатурный элемент, который стоит усилить: Service Control Row - повторяемая строка компонента, где слева состояние службы, в центре человекочитаемый статус, справа одно главное действие и меню дополнительных действий. Route-chain readout тоже нужен, но как объяснение эффекта этих служб: Apps -> ProxiFyre -> target -> VPN/server.

Дефолты, которые стоит отбрасывать:

  • generic dashboard cards -> service-control utility;
  • большая зеленая apply-кнопка всегда видна -> apply gated by readiness + inline blockers;
  • raw logs как главный error surface -> сначала человеческое recovery-сообщение, raw details вторым уровнем.
  • разрозненные кнопки и анимации -> shared component base с едиными variants/states/motion tokens.

Сильные стороны

  • Приложение уже ощущается как компактная desktop-утилита, а не как сайт. Фиксированный header, tabs, плотные панели и темная системная палитра подходят задаче.
  • Продуктовая модель сильная: ProxiFyre и Local sing-box разделены, sing-box не сделан обязательным.
  • Inline-валидация SOCKS5-поля расположена рядом с полем и отключает "Проверить", когда формат неверный.
  • Зона добавления приложения использует иконки с доступными labels и tooltip, поэтому плотный workflow остается сканируемым.
  • Для основных анимаций есть prefers-reduced-motion.
  • UI использует настоящие button и tab roles, а не click-only divs. Это хорошая база для доступности.

UX-риски

  1. Apply выглядит доступным, когда маршрут еще не actionable.

    • Доказательства: 02-proxifyre-desktop.png, 03-proxy-desktop.png.
    • ProxiFyre отсутствует и список приложений пуст, но "Обновить конфиг" / "Обновить маршрут" ярко-зеленые. Это провоцирует failed action вместо направленного setup.
  2. Главная цепочка маршрута не является визуальным фокусом.

    • Доказательства: 01-summary-desktop.png, 03-proxy-desktop.png.
    • Самая важная mental model - путь трафика, но сейчас он показан plain text в таблице или вторичном блоке. Пользователь вынужден читать фрагменты статуса вместо того, чтобы сразу увидеть цепочку.
  3. В "Сводке" есть противоречивое состояние.

    • Доказательство: 01-summary-desktop.png.
    • "Состояние загружается" показано рядом с "Совпадает", а система одновременно говорит "Не настроено". Это может создать ощущение, что действий не требуется.
  4. Preview/native command failures слишком сырые.

    • Доказательства: все скриншоты.
    • Dock показывает Cannot read properties of undefined (reading 'invoke'). Для разработчика это полезно, но как первичный пользовательский error surface это шум.
  5. Bottom log dock конфликтует с узкой компоновкой.

    • Доказательства: 05-summary-narrow.png, 06-proxifyre-narrow.png.
    • Важные сообщения обрезаются до "Компонен..." и "Cannot read prop..."; dock постоянно занимает вертикальное место в и так коротком окне.
  6. ProxiFyre setup chips плохо перестраиваются.

    • Доказательство: 06-proxifyre-narrow.png.
    • Горизонтальная chip-лента скрывает третий dependency и ухудшает диагностическую ясность.
  7. Терминология немного смешана.

    • Доказательства: 01-summary-desktop.png, 03-proxy-desktop.png.
    • config, TCP check, VPN сервер, Local sing-box, ProxiFyre - все эти термины допустимы, но нужен единый принцип: сначала пользовательский русский, технический идентификатор вторым уровнем.
  8. Компонентная база пока не выражена как система.

    • Доказательства: 02-proxifyre-desktop.png, 03-proxy-desktop.png, 06-proxifyre-narrow.png.
    • Кнопки "Обновить", "Установить", "Открыть", "Проверить", add-icon buttons и service actions выглядят близко, но пока не читаются как строгая система variants. Из-за этого сложно гарантировать одинаковые hover/loading/disabled/focus states и одинаковую motion-модель.

Риски доступности

  • Tablist использует role="tab", но не видно поддержки ожидаемого arrow-key behavior и roving tab index. Пользователю с клавиатурой, вероятно, придется проходить все tabs через Tab вместо Left/Right.
  • Focus visibility есть через browser defaults, но визуально она тяжелая и не согласована со стилем приложения. Нужен отдельный :focus-visible token для buttons, tabs, inputs и icon controls.
  • Status dots сильно полагаются на цвет. Стоит дублировать состояние видимым текстом или aria-label/screen-reader text там, где текст рядом не объясняет статус.
  • Footer использует aria-live, но повторяющиеся raw runtime errors могут быть шумными для assistive tech. Сначала стоит объявлять короткий статус, а подробный error text держать за "Посмотреть".
  • На узкой ширине truncation может скрывать actionable-часть сообщений и button labels.
  • Скриншоты не доказывают полный keyboard order, screen-reader output или contrast ratios. Для этого нужен интерактивный accessibility pass.

План улучшений

P0 - Сделать service-control flow заслуживающим доверия

  1. Ввести shared component base:

    • Button с variants: primary, neutral, add, danger, icon;
    • Tabs с единым keyboard behavior и animation contract;
    • ServiceControlRow для ProxiFyre, Local sing-box и будущих служб;
    • StatusPill, Field, ActionMenu, LogDock;
    • единые states: default, hover, active, focus-visible, disabled, loading.
  2. Нормализовать motion tokens:

    • button press: 100-140ms;
    • tab switch: 180-240ms, только opacity + transform;
    • popover/menu: 150-180ms;
    • service operation: видимый loading state, чтобы интерфейс не ощущался зависшим;
    • не использовать transition: all.
  3. Заменить raw preview/native invocation failures на дружелюбное состояние:

    • "Desktop-команды недоступны в browser preview. Запусти через Tauri для управления службами."
    • Raw error оставить только в деталях лога.
  4. Заблокировать primary apply actions до готовности:

    • disabled + explanation, когда список приложений пуст;
    • disabled + explanation, когда ProxiFyre отсутствует;
    • disabled + explanation, когда выбран local route без установленного/запущенного sing-box или выбранного сервера;
    • "Открыть конфиг" оставить вторичным действием, не равным apply по весу.
  5. Исправить язык summary-state:

    • использовать взаимоисключающие состояния: "Проверяю", "Не готово", "Готово к применению", "Применено", "Есть черновик";
    • не показывать "Совпадает", пока saved/applied state реально не загружен.

P1 - Пересобрать главную mental model

  1. Вынести route-chain component как объясняющий элемент:

    • узел Apps с количеством;
    • узел ProxiFyre со статусом installed/running;
    • узел Target: external SOCKS5 или Local sing-box;
    • узел Server, когда активен local sing-box;
    • каждый сломанный узел показывает одно следующее действие.
  2. Переработать "Сводку" в command center:

    • сверху: route-chain и readiness системы;
    • посередине: applied vs draft diff, только если есть отличие;
    • снизу: максимум два next actions;
    • длинные config paths и подробный состав компонентов убрать из первого взгляда.
  3. Разделить "настроить маршрут" и "применить маршрут":

    • Proxy panel отвечает за endpoint choice и connection check;
    • ProxiFyre panel отвечает за app selection и service readiness;
    • Summary подтверждает объединенный маршрут и применяет только при готовности.

P2 - Усилить responsive и component craft

  1. Превратить setup chips в wrapping checklist на узких ширинах.

  2. Сделать log dock адаптивным:

    • desktop: persistent compact dock подходит;
    • narrow: collapsed toast/details sheet вместо постоянного full-width footer.
  3. Определить design tokens:

    • surfaces: canvas, panel, inset, elevated;
    • text: primary, secondary, muted, disabled;
    • status: ready, warning, blocked, checking;
    • focus ring и border intensities.
  4. Стандартизировать copy:

  • последовательно использовать "конфиг" или "конфигурация";
  • заменить "TCP check" на "TCP-проверка";
  • Local sing-box оставить техническим именем компонента, но в user-facing headings связывать с "локальный прокси".

P3 - Verification pass

  1. Добавить focused interaction QA:
  • keyboard tab order;
  • arrow-key tab navigation;
  • focus return из menus/popovers;
  • disabled-action explanations;
  • empty, loading, error, missing-component, ready и unapplied-change states.
  1. Добавить responsive visual snapshots:
  • 1280x720 desktop;
  • 800x600 compact desktop;
  • 420x720 narrow window;
  • длинные proxy/server names и длинные Windows paths.

Рекомендуемый первый redesign slice

Сначала стоит сделать shared UI foundation: Button, Tabs, ServiceControlRow, StatusPill, Field, ActionMenu, LogDock и motion tokens. После этого собрать ProxiFyre и Local sing-box через один ServiceControlRow, а route-chain использовать как объясняющий компонент в "Сводке" и "VPN / Прокси". Такой порядок сначала стабилизирует поведение кнопок/табы/анимации, затем улучшит ориентацию и recovery без переписывания всего UI.