Files
tnsu-ui-kit/PROJECT.md
T
2026-08-13 14:53:11 +05:00

143 lines
12 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.
# @tnsu/ui-kit — память проекта
Единый пакет UI-компонентов для SPFx web part'ов ТНСУ + Storybook как витрина.
Этот файл — источник правды по решениям, плану и прогрессу. Обновлять по ходу работы.
## Зачем проект
У команды много SPFx web part'ов в **разных репозиториях** (request-portal, бывший
1c-ticket-form, pto-tracker и др.). В каждом дизайн разъезжается, компоненты копируются
и пишутся заново. Цель — вынести компоненты в один npm-пакет, подключать его в любую
web part через `npm i`, и держать единый вид через дизайн-токены.
Источник компонентов: `request-portal/src/webparts/requestPortal/shared/ui/` — там уже
~30 чистых компонентов на SCSS-модулях с barrel-экспортом (`ui/index.ts`). Это база.
## Ключевые архитектурные решения
- **Гибридный подход**: отдельный репозиторий `tnsu-ui-kit` (пакет + Storybook),
публикуется в GitLab Package Registry. Существующие web part'ы остаются в своих репах
и просто ставят пакет. НЕ монорепо (не хотим переселять существующие проекты).
- **Сборка — Vite (library mode)**, не tsup. Причина: компоненты на `.module.scss`,
Vite понимает SCSS-модули из коробки и он же движок Storybook → один инструмент.
- **React/Fluent/tslib — только `peerDependencies`** (React 17, @fluentui/react 8, tslib).
Защита от двух React в бандле («Invalid hook call»). Локально те же версии стоят как
devDependencies для сборки и Storybook.
- **Дизайн-токены** (`tokens.scss`: цвета, отступы, радиусы) — единый рычаг общего вида.
Компоненты тянут значения оттуда, а не хардкодят.
- **Скоуп имени `@tnsu`** — сверить с именем группы в GitLab на шаге публикации.
Пока имя ни на что не влияет, переименование = find-replace.
- **Что переносим**: только чистые UI-примитивы (Button, TextInput, FormCard, Select,
ItemsTable, PeopleField...). НЕ переносим бизнес-логику: `approval/`, `pnp/`,
`dictionary/`, сервисы SharePoint — они привязаны к спискам. Возможно позже отдельный
пакет `@tnsu/sp-core`.
- **Расширение через пропсы**, не форки. Если в старом проекте компонент выглядел иначе —
добавляем `variant`/`size` в ui-kit, а не плодим копии.
- **Версии инструментов синхронны с SPFx**: TypeScript пинить на `~5.8.0` (как в
request-portal). Без пина `npm i typescript` ставит TS 7 (нативный компилятор без
JS Compiler API) — vite-plugin-dts падает. То же правило для React/Fluent.
## План (маршрут)
1. [x] Скелет репо — папка, git, package.json, зависимости
2. [x] Сборка (Vite) — vite.config.ts, пакет собирается в dist/
3. [x] Первый компонент — Button перенесён, сборка чистая
4. [x] Дизайн-токены — src/tokens/_tokens.scss перенесён из request-portal
5. [x] Storybook — витрина работает (SB 10.4 + Vite), Button виден со всеми вариантами
6. [x] Публикация — @tnsu/ui-kit@0.0.1 опубликован в Gitea (это Gitea 1.26.4, НЕ GitLab!)
7. [~] Потребление проверено ПОЛНОСТЬЮ: request-portal собрался (heft webpack ок) +
кнопки из пакета отрисовались в SharePoint workbench со стилями (accent-золото,
secondary-рамки). CSS из пакета применяется в рантайме. Осталась публикация в registry.
ВАЖНО про потребление (проверено 2026-08-13):
- Тест через локальный тарбол (`npm pack` → `npm i ../tnsu-ui-kit/*.tgz`), НЕ npm link
(link тащит второй React → Invalid hook call).
- CSS подключается в SPFx через `import '@tnsu/ui-kit/styles.css'` в корневом компоненте
веб-парта (RequestPortal.tsx). SPFx-webpack (5.95) обрабатывает .css из node_modules — ОК.
- Заменён Button в SubmitActions.tsx (`../Button/Button` → `@tnsu/ui-kit`). Правки НЕ
коммитить, пока пакет не опубликован в registry (сейчас ссылается на file:-тарбол).
Известный tech-debt: Sass `@import` устарел (Dart Sass 3.0). Мигрировать токены и
модули на `@use`/`@forward` — отдельной задачей, сейчас работает с варнингом.
## Прогресс / журнал
- **Шаг 1 готов**: создан репо `C:\Users\gorodetskiy.timur\Documents\Projects\tnsu-ui-kit`,
`git init`, болванка package.json.
- **Шаг 2 в работе**: переписан package.json (@tnsu/ui-kit, exports, peerDeps, Vite-скрипты),
ставятся devDependencies, добавлен .gitignore.
## План переноса компонентов (инвентаризация + решения, 2026-08-13)
Источник — request-portal `shared/ui/`, `shared/approval/ui/`, `shared/dictionary/ui/`,
и (фаза 2) `components/`.
### Группа 1 — чистая презентация, переносим КАК ЕСТЬ
Alert, FormCard, FormGrid, FormField, TextInput, TextArea, PhoneInput, MoneyInput,
Select, Toggle, CollapseSection, FormActions, Icon (+ IconSprite/iconNames),
RequestNumber, StatusBadge, ErrorOverlay, FormMode (FormModeProvider + useFormReadOnly).
### Группа 2 — презентация с нюансами (решения приняты)
- ConfirmDialog (+ confirmModal), FileDropzone, useFlipRows → переносим КАК ЕСТЬ (проверено: чисты).
- AttachmentList → переносим, но РАЗВЯЗАТЬ тип: вместо `import { IAttachmentInfo }`
из attachments.service объявить локальный `{ url: string; fileName: string }`.
- PrintButton → переносим КАК ЕСТЬ; сохраняем соглашение классов `.rp-print-root` /
`.rp-no-print` — задокументировать в README, чтобы потребители их соблюдали.
- ItemsTable → ОБОБЩАЕМ в generic `DataTable` (колонки через проп: {key,title,width?,
align?,editable?,render?}, value/onChange/readOnly). Excel-вставка — ОПЦИОНАЛЬНАЯ/
подключаемая (не хардкодить parseExcelRows под ТМЦ; проект даёт свой маппинг/парсер).
ТМЦ-таблица = конфиг колонок поверх DataTable. Это ОТДЕЛЬНАЯ design-задача (не copy-paste),
делать позже, сверяя абстракцию со 2-м реальным примером таблицы.
### Группа 3 — бизнес-логика / SharePoint, НЕ в ui-kit (как есть)
PeopleField/PeopleFieldMulti, UserPicker, InitiatorLine, SubmitActions, useRequestSubmit,
DecisionPanel, ApprovalMatrix, DepartmentPicker, ProjectPicker.
- SubmitActions — на обсуждении: можно «очистить» от useRequestSubmit → презентационный → в ui-kit.
- Пикеры — возможно позже РАЗДЕЛИТЬ: презентационный UI (ui-kit) + data-обёртка (проект).
- Логику согласования — возможно в отдельный пакет @tnsu/approval (или @tnsu/sp-core). На будущее.
### Группа 4 — навигация / app shell (ФАЗА 2)
Tabs (из CategoryTabs), Breadcrumbs (новый), Sidebar (из SideNav), AppLayout (из RequestPortal),
Drawer(?). Сначала «расцепить» от роутинга портала → сделать controlled
(items + activeId + onSelect), потом переносить. Даёт новым приложениям готовую оболочку.
### Порядок работ
1. [СДЕЛАНО в 0.1.0] Быстрая пачка (20 компонентов): вся Группа 1 (кроме ErrorOverlay/
StatusBadge — оказались связаны с diagnostics/statuses, отложены) + ConfirmDialog/
FileDropzone/useFlipRows + AttachmentList (тип развязан на локальный {url,fileName}) +
PrintButton. Сборка чистая, типы ок.
2. DataTable — отдельной design-задачей.
3. Группа 3/4 — по мере надобности.
## Как мигрировать старый проект (памятка на будущее)
1. `npm i @tnsu/ui-kit` — ничего не ломается, пакет просто лежит рядом.
2. Заменяем импорты по одному компоненту/форме: `../shared/ui` → `@tnsu/ui-kit`.
Пропсы те же, JSX не меняется. Старый и новый компонент могут сосуществовать.
3. Проверили форму → удалили старый компонент из `shared/ui`.
4. Повторяем, пока `shared/ui` не опустеет.
5. Перед миграцией проекта проверить: его версии React/Fluent совместимы с peerDeps ui-kit.
## Публикация (Gitea, НЕ GitLab!)
- Хостинг git — **Gitea 1.26.4** на http://git.tnsu.kz (не GitLab). Registry npm привязан
к ВЛАДЕЛЬЦУ, не к проекту. Никакого "project ID" не нужно.
- Адрес registry: `http://git.tnsu.kz/api/packages/timur.gorodetskiy/npm/`
- `.npmrc` в проекте (можно коммитить, НЕ секрет):
`@tnsu:registry=http://git.tnsu.kz/api/packages/timur.gorodetskiy/npm/`
- Токен (СЕКРЕТ) — в `~/.npmrc` (C:\Users\gorodetskiy.timur\.npmrc), в git НЕ попадает:
`//git.tnsu.kz/api/packages/timur.gorodetskiy/npm/:_authToken=<TOKEN>`
- Токен создаётся в Gitea: аватар → Настройки → Приложения → права `package` = Чтение и запись.
- Публикация: `npm run build && npm publish`. Бамп версии в package.json перед каждой
публикацией (npm не даёт перезаписать уже опубликованную версию).
- Потребителю (request-portal и др.) нужен такой же `@tnsu:registry` в его `.npmrc` +
свой токен на чтение пакетов.
- ПРОВЕРЕНО: коллега (другой пользователь Gitea) успешно установил @tnsu/ui-kit со своим
read-токеном — кросс-доступ к личным пакетам работает, переносить в организацию пока НЕ нужно.
## Окружение
- Node: v22.x (как в SPFx: >=22.14 <23)
- React 17.0.1, @fluentui/react ^8.106.4, tslib 2.3.1
- GitLab: http://git.tnsu.kz/timur.gorodetskiy/tnsu-ui-kit.git