145 lines
9.2 KiB
Markdown
145 lines
9.2 KiB
Markdown
# Дизайн-системный рефакторинг брокерских страниц — Plan
|
||
|
||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development
|
||
> (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use
|
||
> checkbox (`- [ ]`) syntax for tracking.
|
||
|
||
**Goal:** Удалить legacy-стили из страниц и компонентов брокерского раздела: CSS-классы,
|
||
`inline styles`, `SkeletonBlock`, `TableSkeleton` → перевести на `@moex-vibe/design-system`.
|
||
|
||
**Architecture:** Бизнес-логика, контракты и маршрутизация меняться не будут.
|
||
Градиенты героических секций, которые не имеют DS-эквивалента, сохраняются как `sx`-инлайн-стили.
|
||
SVG-диаграмма (`BrokerAllocationChart`) сохраняется как есть, меняются только обёртки.
|
||
|
||
**Tech Stack:** React 18, MUI 6.5, `@moex-vibe/design-system` 0.1.0, CSS custom properties.
|
||
|
||
**Связанные документы:**
|
||
|
||
- Epic: `docs/epics/BrokerPortfolio.md`
|
||
- Функциональная базовая фича: `docs/features/broker-account-sections/spec.md`
|
||
- Research: `docs/research/2026-06-18-broker-account-sections.md`
|
||
|
||
---
|
||
|
||
## Task 1: BrokerAccountLayout
|
||
|
||
Заменить layout shell на DS.
|
||
|
||
- `div.broker-account` → `<Box component="div">`
|
||
- `header.broker-account__header` → `<Box>` flex
|
||
- `h1` → `<Heading level={1}>`
|
||
- `nav.broker-account__navigation` → `<Box component="nav">`
|
||
- `NavLink` классы → при оставлении `className` callback (уникальный prefix для active state), но в первую очередь сменить на `Box` + `<Button>` или DS Tabs если доступен (DS Tabs/doc check)
|
||
- `div.broker-account__workspace` → `<Box>` grid (desktop sidebar + mobile row)
|
||
- `div.broker-account__content` → `<Box>` c overflow-auto
|
||
- Удалить CSS для `.broker-account__header`, `.broker-account__workspace`, `.broker-account__navigation`, `.broker-account__link`, `.broker-account__content` в `styles.css`
|
||
|
||
## Task 2: BrokerAccountOverviewPage, BrokerSummary, BrokerAssetCards
|
||
|
||
Перевести три связанных компонента overview на DS.
|
||
|
||
- `div.broker-overview` → `<Box component="div">`
|
||
- `section.broker-overview__summary` → `<Box>` grid
|
||
- `div.broker-overview__card` + inline-спаны → `<Box>` (card container) + `<Text>`
|
||
- `<span className="broker-overview__label">` → `<Text variant="label" tone="secondary">`
|
||
- `<strong>` значения → `<Text sx={{ fontWeight: 700 }}>`
|
||
- `ul.broker-overview__cash` → `<Box component="ul">` + `<Box component="li">`
|
||
- `section.broker-overview__assets` → `<Box>` grid
|
||
- `Link.broker-overview__asset-link` → `<Link>` + `<Box>` для layout карточки
|
||
- `<strong className="broker-overview__asset-title">` → `<Text sx={{ fontWeight: 700 }}>`
|
||
- Спаны значений/процентов → `<Box component="span">` + `<Text>`
|
||
- Оставить hero-gradient (`broker-overview__hero`-style) на caretaker'е (см. Out of scope)
|
||
|
||
## Task 3: BrokerOverviewSkeleton
|
||
|
||
Заменить старые skeleton на DS-component.
|
||
|
||
- Импорт `SkeletonBlock` → DS `Skeleton`
|
||
- `div.broker-overview__card` → `<Box>` для контейнера skeleton-элементов
|
||
- `SkeletonBlock height={...} width={...}` → `<Skeleton height={...} width={...} shape="text">`
|
||
- `SkeletonBlock borderRadius={80}` → `<Skeleton height={160} width={160} shape="circular">`
|
||
|
||
## Task 4: BrokerAllocationChart (wrap only)
|
||
|
||
Оставить SVG без изменений, мигрировать только обёртки.
|
||
|
||
- `figure.broker-allocation` → `<Box component="figure">`
|
||
- `figcaption` → `<Box component="figcaption">`
|
||
- `<p>` в пустом состоянии → `<Text tone="muted">`
|
||
- `<ul>` / `<li>` легенды → `<Box component="ul">` + `<Box component="li">`
|
||
- `span.broker-allocation__swatch` → `<Box}` с inline-цветом в `sx`
|
||
- Спаны текста легенды → `<Text>` или `<Box component="span">` с кастомным `fontSize`
|
||
- `ul.broker-allocation__negative` → `<Box component="ul">`
|
||
- Удалить CSS для `.broker-allocation*` в `styles.css` (кроме SVG-правил, которые оставить нетронутыми или перенести в inline)
|
||
|
||
## Task 5: BrokerPositionTable, PositionTicker
|
||
|
||
Миграция таблицы позиций.
|
||
|
||
- Вспомогательные типы для `headerStyle`, `cellStyle`, `pagButtonStyle` → MUI `sx` через `<Box>`, `<Button>`
|
||
- Импорт `SkeletonBlock` в компоненте → удалить, использовать `Skeleton` через `<TableSkeleton>` (см. Task 6)
|
||
- `h2` inline-стили → `<Heading level={2}>` с кастомной `sx` для размера/масштаба
|
||
- Ошибки/пустые `<p>` → `<Text>` через Box с inline-цветом
|
||
- `PositionTicker`: `<Link style={{ fontWeight: 700 }}>` → `<Link>` с `<Text sx={{ fontWeight: 700 }}>` внутри
|
||
- `table` → `<table component="table">` или оставить нативным table, но стилизовать через `sx`
|
||
- Сохранить `loading-spinner` класс в `styles.css` (глобальный):
|
||
- `TableSkeleton` → `<Skeleton>` after DS migration
|
||
- Keep `table-container` as minimal CSS or remove; convert `loading-overlay` to Box.
|
||
|
||
## Task 6: TableSkeleton
|
||
|
||
Заменить импорт `SkeletonBlock` на DS `Skeleton`.
|
||
|
||
- Убрать импорт `SkeletonBlock`, заменить на `Skeleton` из `@moex-vibe/design-system`.
|
||
- `SkeletonBlock height={12} width={col.width}` → `<Skeleton height={12} width={col.width} shape="text"/>`.
|
||
|
||
## Task 7: BrokerOperationsTable
|
||
|
||
Миграция таблицы операций.
|
||
|
||
- Вспомогательные стили (`tableStyle`, `thStyle`, `tdStyle`, `pagButtonStyle`) → inline-`sx` или `<Box>`
|
||
- Оставить `<select>` нативный, но обёрнуть в `<Box component="label">`
|
||
- `h2 inline` → `<Heading level={2}>` с `sx={{ fontSize: 20 }}`
|
||
- `<span role="status">` с `loading-spinner` → `<Skeleton shape="circular" width={14} height={14} />` (если DS поддерживает) или оставить `<span className="loading-spinner">` временно; DS `Skeleton` не имеет circular-only без width/height — оставить на этой итерации, можно оставить loading-spinner, так как это глобальный анимационный класс, а не DS.
|
||
- Пустые состояния / alert-тексты → `<Text tone="muted">` / `<Text tone="negative">`
|
||
- Пагинация `<button>` → `<Button variant="secondary">`
|
||
- `aria-label` — сохранить.
|
||
|
||
## Task 8: BrokerPositionsPage, BrokerOperationsPage
|
||
|
||
Миграция "обёрточных" страниц-секций.
|
||
|
||
- `section` → `<Box component="section">`
|
||
- `h2 inline` → `<Heading level={2}>` с `sx={{ fontSize: 20 }}`
|
||
- `p role="alert"` → `<Text tone="negative" component="p">` (или `<Box component="p">`)
|
||
- `p.empty` → `<Text tone="muted">`
|
||
- `div.broker-operations__toolbar` → `<Box>` с flex
|
||
- `label > span + select` → `<Box component="label">` + `<Text>` + `<select>`
|
||
|
||
## Task 9: SkeletonBlock удаление
|
||
|
||
После замены всех потребителей:
|
||
|
||
1. Удалить `apps/frontend/src/shared/ui/SkeletonBlock.tsx`.
|
||
2. Удалить экспорт из `apps/frontend/src/shared/ui/index.ts`.
|
||
3. Убедиться, что `import { SkeletonBlock }` не осталось нигде.
|
||
|
||
## Task 10: Очистка `styles.css`
|
||
|
||
- Удалить все selector'ы из блока `broker-account__*`, `broker-overview__*`, `broker-allocation__*` (SVG стили оставить), `broker-operations__toolbar*`.
|
||
- Оставить косметические классы, которые ещё не мигрированы (если таковые возникнут).
|
||
- Оставить `.loading-spinner` (глобальный анимационный класс, применяется через `className` где-то еще).
|
||
- Оставить `:root` CSS variables — они DS взаиморасчётные токены.
|
||
|
||
## Task 11: Тестирование и сборка
|
||
|
||
- [ ] `npm run test:frontend` — все тесты PASS.
|
||
- [ ] `npm run lint -w apps/frontend` — без ошибок.
|
||
- [ ] `npm run build:frontend` — без TypeScript/Vite ошибок.
|
||
- [ ] Проверить, что нет остатков `SkeletonBlock` импортов в кодовой базе: `grep -r "SkeletonBlock" apps/frontend/src`.
|
||
- [ ] Проверить, что нет остатков `broker-account__*`, `broker-overview__*`, `broker-allocation__*`, `broker-operations__toolbar` в TSX: `grep -rE "broker-(account|overview|allocation|operations)" apps/frontend/src --include='*.{ts,tsx}'`.
|
||
|
||
## Task 12: Вердикт и записка
|
||
|
||
- [ ] Обновить `docs/features/broker-account-sections-ds-migration/tasks.md` — отметить все выполненные пункты.
|