Files
stroy-bot-monorepo/src/webparts/stroyBot/app/routing/routes.ts
T
Тимур Городецкий 18c2959820 feat: add works import from Excel (check and plan)
New "Импорт работ из Excel" section checks the planned volumes file
against /Import/StroyBot/Works as soon as it is picked. The builder
turns checked rows into works and decides per work whether to create it
or update the volume and unit of an existing work with the same title
on the object. Saving comes next.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 17:35:21 +05:00

96 lines
3.0 KiB
TypeScript

// Маршруты приложения. Раздел и его параметры живут в query-строке страницы
// SharePoint (?page=objects&projectId=5), поэтому ссылку на любой раздел можно
// скопировать, открыть в новой вкладке, а «назад» в браузере работает как раньше.
export const PAGE_IDS = [
'hub',
'objects',
'works',
'reports',
'report',
'import',
'resources',
'binder',
'weather',
'reportImport',
'worksImport'
] as const;
export type PageId = (typeof PAGE_IDS)[number];
/** Параметры маршрута. Все id — строки как в URL; разбор в числа делают страницы. */
export interface IRoute {
page: PageId;
projectId?: string;
/** Работы: id элемента списка «Объекты». */
objectId?: string;
/** Форма отчёта: открыть существующий отчёт (GUID Dataverse). */
reportId?: string;
/** Форма отчёта: создать на основе существующего (GUID Dataverse). */
copyFromId?: string;
/** Главная и сверка погоды: начало периода (YYYY-MM-DD). */
start?: string;
/** Главная и сверка погоды: конец периода (YYYY-MM-DD). */
end?: string;
}
export const ROUTE_PARAMS = {
page: 'page',
projectId: 'projectId',
objectId: 'objectId',
reportId: 'reportId',
copyFromId: 'copyFromId',
start: 'start',
end: 'end'
} as const;
const ROUTE_VALUE_KEYS: Array<Exclude<keyof IRoute, 'page'>> = [
'projectId',
'objectId',
'reportId',
'copyFromId',
'start',
'end'
];
function isPageId(value: string | undefined): value is PageId {
return value !== undefined && (PAGE_IDS as readonly string[]).indexOf(value) !== -1;
}
export function parseRoute(search: string): IRoute {
const params = new URLSearchParams(search);
const page = params.get(ROUTE_PARAMS.page) ?? undefined;
const route: IRoute = { page: isPageId(page) ? page : 'hub' };
ROUTE_VALUE_KEYS.forEach((key) => {
const value = params.get(ROUTE_PARAMS[key]);
if (value) {
route[key] = value;
}
});
return route;
}
/**
* Собирает query-строку для маршрута. Посторонние параметры страницы SharePoint
* (например, режим редактирования) сохраняются, параметры прошлого маршрута — нет.
*/
export function buildSearch(route: IRoute, currentSearch: string): string {
const params = new URLSearchParams(currentSearch);
params.delete(ROUTE_PARAMS.page);
ROUTE_VALUE_KEYS.forEach((key) => params.delete(ROUTE_PARAMS[key]));
if (route.page !== 'hub') {
params.set(ROUTE_PARAMS.page, route.page);
}
ROUTE_VALUE_KEYS.forEach((key) => {
const value = route[key];
if (value) {
params.set(ROUTE_PARAMS[key], value);
}
});
const query = params.toString();
return query ? `?${query}` : '';
}