Co-authored-by: gorbenko.pavel <gorbenko.pavel@tansu.kz> Reviewed-on: http://git.tnsu.kz/timur.gorodetskiy/request-portal/pulls/15
This commit was merged in pull request #15.
This commit is contained in:
@@ -412,6 +412,69 @@ export function routeUrl(route: IRoute): string {
|
||||
return buildQuery(route);
|
||||
}
|
||||
|
||||
/**
|
||||
* АБСОЛЮТНАЯ ссылка на просмотр заявки — для того, что переживёт текущую сессию:
|
||||
* колонка-гиперссылка в списке SharePoint, письмо, сообщение в чат.
|
||||
*
|
||||
* Отличается от routeUrl() двумя вещами, и обе важны именно для «хранимой» ссылки:
|
||||
* она с origin (в списке относительный путь бесполезен — его открывают из
|
||||
* представления SharePoint, а не со страницы портала) и без посторонних
|
||||
* query-параметров текущей страницы (routeUrl их намеренно сохраняет, потому что
|
||||
* это навигация ВНУТРИ открытой страницы).
|
||||
*
|
||||
* Страница портала берётся из адреса текущей — портал живёт на одной странице,
|
||||
* другого способа узнать её путь у клиентского кода нет.
|
||||
*/
|
||||
export function requestLinkUrl(formKey: string, itemId: number, listId?: string): string {
|
||||
const params = new URLSearchParams();
|
||||
params.set('rpmode', 'approve');
|
||||
params.set('rptype', formKey);
|
||||
params.set('rpid', String(itemId));
|
||||
if (listId) {
|
||||
params.set('rplist', listId);
|
||||
}
|
||||
return `${window.location.origin}${window.location.pathname}?${params.toString()}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Открыть заявку по её АБСОЛЮТНОЙ ссылке (см. requestLinkUrl) БЕЗ перезагрузки
|
||||
* страницы — если ссылка ведёт на эту же страницу портала.
|
||||
*
|
||||
* Зачем: страница SharePoint со SPFx грузится секунды, а ссылка между парными
|
||||
* заявками (заявление на увольнение ↔ обходной лист) — это по сути та же страница
|
||||
* с другими rp-параметрами, то есть ровно то, что умеет navigate(). Полная
|
||||
* перезагрузка здесь ничего не даёт.
|
||||
*
|
||||
* Возвращает false, если ссылка ведёт куда-то ещё (другой сайт, другая страница,
|
||||
* не на просмотр заявки) — тогда вызывающий НЕ должен подавлять клик и обязан
|
||||
* дать браузеру перейти по ней обычным образом.
|
||||
*/
|
||||
export function navigateToRequestLink(url: string): boolean {
|
||||
let target: URL;
|
||||
try {
|
||||
target = new URL(url, window.location.href);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
// Путь в SharePoint регистронезависим, а ссылка могла быть записана в список
|
||||
// когда-то с другим регистром — сравниваем в нижнем.
|
||||
if (
|
||||
target.origin !== window.location.origin ||
|
||||
target.pathname.toLowerCase() !== window.location.pathname.toLowerCase()
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const route = parseRoute(target.search);
|
||||
if (route.mode !== 'approve' || !route.formKey || !route.itemId) {
|
||||
return false;
|
||||
}
|
||||
// Раздел бокового меню берём ТЕКУЩИЙ, а не из ссылки: заявка показывается в
|
||||
// панели поверх раздела, и уход по ссылке не должен переключать раздел под ней.
|
||||
navigate({ ...route, nav: parseRoute().nav });
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Текущий маршрут, реактивно обновляется по navigate() и кнопке «назад». */
|
||||
export function useRoute(): IRoute {
|
||||
const [route, setRoute] = React.useState<IRoute>(() => parseRoute());
|
||||
|
||||
Reference in New Issue
Block a user