9.2 KiB
Raw Blame History

Дизайн-системный рефакторинг брокерских страниц — 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 — отметить все выполненные пункты.