d606f8371c
Ports the weather check added to stroy-bot-main on 2026-10-16: daily station weather, report positions with weather per shift and the AI assessment of working conditions. Opens as ?page=weather&start=&end= instead of the #weathercheck hash, and hub dates survive the way back. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
94 lines
3.0 KiB
TypeScript
94 lines
3.0 KiB
TypeScript
// Маршруты приложения. Раздел и его параметры живут в query-строке страницы
|
|
// SharePoint (?page=objects&projectId=5), поэтому ссылку на любой раздел можно
|
|
// скопировать, открыть в новой вкладке, а «назад» в браузере работает как раньше.
|
|
|
|
export const PAGE_IDS = [
|
|
'hub',
|
|
'objects',
|
|
'works',
|
|
'reports',
|
|
'report',
|
|
'import',
|
|
'resources',
|
|
'binder',
|
|
'weather'
|
|
] 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}` : '';
|
|
}
|