Sergey Krylov fee179d8e9
All checks were successful
CI / ci (pull_request) Successful in 15m41s
CI / ci (push) Successful in 13m50s
fix(frontend): align broker dashboard HTML parity
2026-06-27 15:23:55 +03:00

140 lines
14 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.

# Редизайн обзора брокерского счёта в инвестиционный дашборд — задачи
Дата: 2026-06-26 (обновлено 2026-06-27)
Статус: в реализации, итерация HTML parity
## Документация и pre-flight
- [x] Выбрать scope: `/broker/:accountId` становится единым дашбордом.
- [x] Выбрать визуальный стиль: структура `temp.html`, текущая светлая DS-тема.
- [x] Исключить график истории стоимости из первой версии.
- [x] Добавить backlog-задачу на историю стоимости брокерского портфеля.
- [x] Создать ветку `codex/broker-dashboard-redesign`.
- [x] Запустить baseline: `rtk npm run test:backend && rtk npm run test:frontend && rtk npm run test:design-system`.
- [x] Написать `spec.md`.
- [x] Написать `plan.md`.
## Реализация
- [x] Добавить pure helpers для фильтрации и суммирования доходных операций dashboard.
- [x] Добавить helpers для фильтров дат, пресетов, валидации и mapping income types → operationTypes.
- [x] Добавить dashboard presentation helpers для fallback, event labels и statuses.
- [x] Добавить локальный `BrokerDashboardCard` pattern или точечно расширить DS, если локального pattern недостаточно.
- [x] Добавить `BrokerDashboardHero` с KPI по portfolio и analytics.
- [x] Добавить `BrokerDashboardEventsCard` на основе `useBrokerEvents`.
- [x] Добавить `BrokerDashboardIncomeCard` на основе `useBrokerOperations`.
- [x] Перенести навигацию счёта из левой колонки в горизонтальные вкладки над контентом.
- [x] Перестроить dashboard на один блок на строке для `События`, `Доходы`, `Аналитика доходности`, `Аллокация`.
- [x] Добавить кликабельные chip-фильтры типов для `События`.
- [x] Добавить `BrokerDashboardDateFilter` — переиспользуемый expandable-компонент фильтра дат (пресеты 7д/30д/90д/1г/Всё, from/to поля, Сбросить/Показать).
- [x] Подключить `BrokerDashboardDateFilter` в `События` с draft/applied состоянием.
- [x] Добавить локальную пагинацию по 10 событий в `События`.
- [x] Добавить кликабельные chip-фильтры типов для `Доходы`.
- [x] Подключить `BrokerDashboardDateFilter` в `Доходы` с draft/applied состоянием.
- [x] Добавить cursor-пагинацию по 10 операций в `Доходы`.
- [x] Добавить `BrokerDashboardAnalyticsCard` на основе `useBrokerAnalytics`.
- [x] Добавить `BrokerDashboardAllocationCard` на основе существующей аллокации.
- [x] Добавить `BrokerDashboardSkeleton`.
- [x] Добавить `BrokerDashboard` как top-level composition widget.
- [x] Заменить текущий вертикальный обзор в `BrokerAccountOverviewPage` на `BrokerDashboard`.
- [x] Добавить unit/component tests для helpers и базовой dashboard composition.
- [x] Выровнять hero KPI: все Metric одной высоты, supportingText не раздвигает "Доходность" выше соседей.
- [x] Заменить donut-диаграмму аллокации на горизонтальные бары в `BrokerDashboardAllocationCard`.
- [x] Убрать слово `Фильтр` из пользовательского текста шапки периода в dashboard-карточках.
- [x] Переименовать действие `Показать` в управлении периодом и визуально улучшить шапку фильтров.
- [x] Заменить native date inputs на одно поле периода с popover и community `DateCalendar` из `@mui/x-date-pickers`.
- [x] Не использовать `@mui/x-date-pickers-pro` и `DateRangePicker`.
- [x] Настроить default range событий на `сегодня - 7 дней` / `сегодня + 7 дней`, доходов — на
`сегодня - 7 дней` / `сегодня`.
- [x] Заменить текстовую загрузку `События` на skeleton таблицы.
- [x] Заменить текстовую загрузку `Доходы` на skeleton таблицы.
- [x] Обновить component tests под новые тексты, единое поле периода, popover-календарь и skeleton loading states.
- [ ] Проверить desktop layout `/broker/2084014113`.
- [ ] Проверить mobile layout `/broker/2084014113`.
## Итерация HTML parity
- [x] Согласовать статический визуальный эталон `docs/research/2026-06-27-broker-account-redesign.html`.
- [x] Обновить `spec.md` под HTML parity: компактные заголовки, единый toolbar, бейджи, цвета, подписи инструментов, `₽`.
- [x] Обновить `plan.md` под перенос HTML parity в React-компоненты.
- [x] Добавить `apps/frontend/src/widgets/broker-dashboard/lib/dashboardVisual.ts` с helpers для money tone, type tone, currency symbol и instrument display.
- [x] Добавить `apps/frontend/src/widgets/broker-dashboard/lib/dashboardVisual.test.ts`.
- [ ] Расширить income helpers так, чтобы строки доходов могли отдавать main/subtitle инструмента без дублирования текста.
- [x] Обновить `BrokerDashboardHero`: semantic colors для доходности, дневного изменения и всего полученных доходов.
- [x] Обновить `BrokerDashboardCard`: компактный card heading вместо крупного page-level heading.
- [x] Обновить `BrokerDashboardDateFilter`: единый toolbar-паттерн и chevron-иконка вместо текстового `v`.
- [x] Обновить `BrokerDashboardEventsCard`: `thead`, двухстрочный инструмент, type badges, semantic amount colors, status badges.
- [x] Обновить `BrokerDashboardIncomeCard`: `thead`, двухстрочный инструмент, type badges, semantic amount colors.
Бейдж `Купон` приведён к `info` (синий) согласно HTML-эталону `.type-badge.coupon` (`incomeTypeTone` в `dashboardVisual.ts`),
`Дивиденд (внешний)` отнесён к `success` (семейство дивидендов).
- [x] Обновить `BrokerDashboardTableSkeleton`: общий skeleton-паттерн для событий и доходов с корректной геометрией колонок.
- [x] Обновить `BrokerDashboardAnalyticsCard`: `₽` для RUB и positive/negative tone карточек.
- [x] Обновить component tests dashboard под HTML parity (analytics tones).
- [x] Проверить, что блок `Доходы` не расширяет backend/API и остаётся в рамках текущих income-типов.
Исправлен пресет «Всё»: `applyDatePreset('all')` теперь отдаёт широкий диапазон `2000-01-01``2099-12-31`
вместо пустых `from`/`to`, которые backend (`BrokerEventsQueryDto @Matches`) отвергал с 400. В DateFilter
кнопка «Применить период» блокируется при инвертированном диапазоне (`to < from`), чтобы избежать
молчаливо пустого ответа (например, будущий `from` при дефолтном `to=сегодня`).
- [x] Исправить default-range `События`, чтобы dashboard по умолчанию и через пресеты мог загружать будущие события.
- [x] Подтянуть card headers, toolbar label `Тип`, count badges и footer summaries ближе к
`docs/research/2026-06-27-broker-account-redesign.html`.
- [ ] Проверить desktop layout `/broker/2084014113` против `docs/research/2026-06-27-broker-account-redesign.html`.
- [ ] Проверить mobile layout `/broker/2084014113` на viewport `390x844` против `docs/research/2026-06-27-broker-account-redesign.html`.
## Definition of Done
- [x] `rtk npm run test:frontend` проходит.
- [x] `rtk npm run test:design-system` проходит.
- [x] `rtk npm run lint -w apps/frontend` проходит.
- [x] `rtk npm run build:frontend` проходит.
- [ ] Dashboard соответствует acceptance criteria из `spec.md`.
- [x] Существующие вкладки `Акции`, `Облигации`, `Операции`, `События`, `Аналитика` остаются доступны.
- [x] `graphify update .` выполнен после code changes.
## Definition of Done для HTML parity
- [x] `rtk npm run test:frontend -- --run src/widgets/broker-dashboard` проходит. (49/49)
- [x] `rtk npm run test:frontend` проходит после HTML parity изменений. (175/175)
- [x] `rtk npm run lint -w apps/frontend` проходит после HTML parity изменений.
- [x] `rtk npm run build:frontend` проходит после HTML parity изменений.
- [ ] На `/broker/2084014113` заголовки карточек, toolbar таблиц, бейджи типов, подписи инструментов,
цвета сумм, analytics colors и skeleton визуально соответствуют `docs/research/2026-06-27-broker-account-redesign.html`.
Проверено только по тестам и code-to-spec mapping внизу файла — live dev server не запускался
в этой итерации (нет backend/auth в среде). Необходима ручная проверка пользователем.
- [ ] Нет общего горизонтального overflow на mobile; горизонтальный scroll допускается только внутри таблиц.
Требует live dev server + ручной проверки на viewport `390x844`.
- [x] `docs/features/broker-dashboard-redesign/tasks.md` обновлён по факту выполнения.
### Code-to-spec mapping для analytics (HTML parity)
`BrokerDashboardAnalyticsCard.tsx` (`apps/frontend/src/widgets/broker-dashboard/ui/`) против
HTML-эталона (`docs/research/2026-06-27-broker-account-redesign.html:1145-1158`):
| HTML reference element | React-компонент / data-testid | Спецификация §6 (spec.md:165-180) |
|------------------------|------------------------------------------------------------|----------------------------------------------------------------------|
| `<section aria-labelledby="analytics-title">` | `BrokerDashboardCard` с `ariaLabel="Аналитика доходности"` | Секция с заголовком, доступная по aria-label |
| `<h2>Аналитика доходности</h2>` | Заголовок карточки | Компактный card heading (§2) |
| `.analytics-item.positive .analytics-value` | `data-testid="dashboard-analytics-totalDeposits"` (tone `positive`) | Пополнения — positive (§6, AC `Блок Аналитика доходности`) |
| `.analytics-item.negative .analytics-value` для Выводы | `data-testid="dashboard-analytics-totalWithdrawn"` (tone `negative`, префикс ``) | Выводы — negative, всегда со знаком `` (§6) |
| `.analytics-item.negative .analytics-value` для Нетто (если нетто<0) | `data-testid="dashboard-analytics-netInvested"` (tone `negative` при `value<0`) | Нетто sign-based 6) |
| `.analytics-item.positive .analytics-value` для Дивиденды/Купоны/Всего получено | `data-testid="dashboard-analytics-totalDividends"`, `…-totalCoupons`, `…-totalReceived` | Positive если `value > 0`, neutral если `value === 0` 6) |
| `113 773,03 ₽` (валюта) | `formatDashboardCurrency` через `shared/lib/formatters` | RUB отображается как `₽` (AC, §2) |
Тесты в `BrokerDashboard.test.tsx`:
- `renders analytics card with the ₽ symbol and no "RUB" code` подтверждает замену `RUB` на `₽`.
- `applies positive, negative and neutral tones to analytics values` подтверждает tone-атрибуты
для каждого поля с разнообразными значениями (`totalDeposits: 1000`, `totalWithdrawn: 250`,
`netInvested: -150`, `totalDividends: 75`, `totalCoupons: 0`, `totalReceived: 90`).
### Что НЕ было проверено в этой итерации
- Реальный визуальный рендеринг `/broker/2084014113` на desktop и `390x844` mobile.
Требуется ручная проверка пользователем с поднятым backend (нужны реальные auth и T-Bank/MOEX
прокси). Dev server не запускался.
- Поведение отсутствующего/ошибочного analytics под live-нагрузкой. Логика в карточке покрыта
тестами, но проверка UX-сообщений и skeleton-states в браузере не делалась.
- Реальный viewport на `390x844` для подтверждения отсутствия общего горизонтального overflow.
Геометрия таблиц уже переключена на внутренний `overflowX: 'auto'` (`BrokerDashboardEventsCard.tsx:176`,
`BrokerDashboardIncomeCard.tsx`), но фактическая вёрстка в браузере не сверялась с эталоном.