теперь можно пройти по заявку в мои заявки
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import * as React from 'react';
|
||||
|
||||
// Маршрутизация портала по параметрам URL.
|
||||
//
|
||||
// Обычный режим (нет параметров) — подача заявок (features/submit).
|
||||
@@ -8,6 +10,11 @@
|
||||
// Префикс rp (request-portal): имена id/mode/type зарезервированы SharePoint
|
||||
// (напр. ?id= он трактует как навигацию к элементу → «Элемент не существует»),
|
||||
// поэтому используем собственные, неконфликтные имена параметров.
|
||||
//
|
||||
// Навигация внутри портала (напр. клик по заявке в «Мои заявки») идёт через
|
||||
// navigate() — это history.pushState без перезагрузки страницы. useRoute()
|
||||
// подписан и на popstate (кнопка «назад»), и на её собственное событие,
|
||||
// поэтому реагирует на оба способа смены URL.
|
||||
|
||||
export type PortalMode = 'submit' | 'approve' | 'create';
|
||||
|
||||
@@ -21,6 +28,8 @@ export interface IRoute {
|
||||
sourceId?: number;
|
||||
}
|
||||
|
||||
const ROUTE_CHANGE_EVENT = 'rp-route-change';
|
||||
|
||||
/** Разобрать строку запроса (по умолчанию — из адреса страницы) в маршрут. */
|
||||
export function parseRoute(search: string = window.location.search): IRoute {
|
||||
const params = new URLSearchParams(search);
|
||||
@@ -41,3 +50,68 @@ export function parseRoute(search: string = window.location.search): IRoute {
|
||||
}
|
||||
return { mode: 'submit' };
|
||||
}
|
||||
|
||||
/**
|
||||
* Перейти на другой маршрут без перезагрузки страницы (SPA): обновляет
|
||||
* query-параметры адресной строки через history.pushState и оповещает
|
||||
* useRoute() своим событием (popstate на pushState сам не срабатывает).
|
||||
*/
|
||||
export function navigate(route: IRoute): void {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
params.delete('rpmode');
|
||||
params.delete('rptype');
|
||||
params.delete('rpid');
|
||||
params.delete('rpsource');
|
||||
|
||||
if (route.mode === 'approve' && route.formKey && route.itemId) {
|
||||
params.set('rpmode', 'approve');
|
||||
params.set('rptype', route.formKey);
|
||||
params.set('rpid', String(route.itemId));
|
||||
} else if (route.mode === 'create' && route.formKey && route.sourceId) {
|
||||
params.set('rptype', route.formKey);
|
||||
params.set('rpsource', String(route.sourceId));
|
||||
}
|
||||
|
||||
const query = params.toString();
|
||||
const url = `${window.location.pathname}${query ? `?${query}` : ''}${window.location.hash}`;
|
||||
window.history.pushState({}, '', url);
|
||||
window.dispatchEvent(new Event(ROUTE_CHANGE_EVENT));
|
||||
}
|
||||
|
||||
/** Ссылка на маршрут (для href — открытие в новой вкладке, копирование и т.п.). */
|
||||
export function routeUrl(route: IRoute): string {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
params.delete('rpmode');
|
||||
params.delete('rptype');
|
||||
params.delete('rpid');
|
||||
params.delete('rpsource');
|
||||
|
||||
if (route.mode === 'approve' && route.formKey && route.itemId) {
|
||||
params.set('rpmode', 'approve');
|
||||
params.set('rptype', route.formKey);
|
||||
params.set('rpid', String(route.itemId));
|
||||
} else if (route.mode === 'create' && route.formKey && route.sourceId) {
|
||||
params.set('rptype', route.formKey);
|
||||
params.set('rpsource', String(route.sourceId));
|
||||
}
|
||||
|
||||
const query = params.toString();
|
||||
return `${window.location.pathname}${query ? `?${query}` : ''}${window.location.hash}`;
|
||||
}
|
||||
|
||||
/** Текущий маршрут, реактивно обновляется по navigate() и кнопке «назад». */
|
||||
export function useRoute(): IRoute {
|
||||
const [route, setRoute] = React.useState<IRoute>(() => parseRoute());
|
||||
|
||||
React.useEffect(() => {
|
||||
const onChange = (): void => setRoute(parseRoute());
|
||||
window.addEventListener('popstate', onChange);
|
||||
window.addEventListener(ROUTE_CHANGE_EVENT, onChange);
|
||||
return () => {
|
||||
window.removeEventListener('popstate', onChange);
|
||||
window.removeEventListener(ROUTE_CHANGE_EVENT, onChange);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return route;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user