feat: add StroyBot app shell with URL routing

One web part replaces the separate stroy-bot-* web parts. The section and
its parameters live in the page query string (?page=objects&projectId=5),
so links can be copied, opened in a new tab and the browser Back button works.

- shared config: site/Dataverse/API addresses, list and table names
- HTTP layer behind IHttpClient so repositories can be unit-tested
- ui-kit AppLayout + Sidebar, placeholder for sections not ported yet
- migration checklist with every feature of the old web parts
- design tokens mirrored from ui-kit instead of 8 copies

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Тимур Городецкий
2026-10-15 16:42:37 +05:00
parent 5418da3bdc
commit b868e8012d
37 changed files with 1135 additions and 274 deletions
+23
View File
@@ -0,0 +1,23 @@
// Адреса окружения StroyBot. Раньше каждое значение было захардкожено
// в нескольких репозиториях stroy-bot-* — теперь единственное место.
/** Сайт SharePoint со списками StroyBot (Проекты, Объекты, Доступы и т.д.). */
export const SITE_URL = 'https://tnsukz.sharepoint.com/sites/stroy';
/** Окружение Dataverse (таблицы cree9_*). */
export const DATAVERSE_URL = 'https://tansu.crm5.dynamics.com';
/** Корпоративный API (справочник проектов, сметы, Excel-выгрузки). */
export const TNSU_API_BASE_URL = 'https://api.tnsu.kz';
/** AAD-приложение корпоративного API — ресурс для AadHttpClient. */
export const TNSU_API_RESOURCE_ID = '9232d9e2-9807-4753-808f-07250e5474b0';
/** Шрифты дизайн-системы (Inter — текст, Lora — заголовки). Тот же URL, что в report-list и assigner. */
export const FONTS_CSS_URL =
'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Lora:wght@500;600;700&display=swap';
/** Ключи sessionStorage. Значение совпадает со stroy-bot-main — сохранённый выбор не теряется. */
export const SESSION_KEYS = {
selectedProject: 'stroybot_selected_project'
} as const;
+15
View File
@@ -0,0 +1,15 @@
// Таблицы Dataverse StroyBot (Web API, множественное число — как в URL).
export const DATAVERSE_API_PATH = '/api/data/v9.2/';
export const DV_TABLES = {
/** Работы (иерархия, привязка к объекту SharePoint через cree9_objectid). */
works: 'cree9_tables',
/** Отчёты. */
reports: 'cree9_reports',
/** Строки отчётов: работы, персонал, техника. */
reportData: 'cree9_report_datas'
} as const;
/** Логическое имя (единственное число) таблицы работ — для EntityDefinitions. */
export const DV_WORKS_LOGICAL_NAME = 'cree9_table';
+23
View File
@@ -0,0 +1,23 @@
// Названия списков и библиотек SharePoint (getbytitle).
// Внутренние имена полей описываются рядом с репозиторием, который с ними работает.
export const LISTS = {
projects: 'Проекты',
objects: 'Объекты',
access: 'Доступы',
companies: 'Компании',
companiesByProject: 'Компании по проекту',
professions: 'Профессии',
professionsByProject: 'Профессии по проекту',
shifts: 'Смены',
technics: 'Техника',
units: 'Единицы измерения'
} as const;
/** Библиотека с фотографиями отчётов: папка `{projectId}_{reportNumber}`. */
export const REPORT_PHOTO_LIBRARY = 'DocLib';
/** Библиотека с архивом проектов: папка `Архив/{название проекта}`. */
export const ARCHIVE_FOLDER_PATH = 'Shared Documents/Архив';
export type ListTitle = (typeof LISTS)[keyof typeof LISTS];