This commit is contained in:
@@ -12,6 +12,12 @@ import * as React from 'react';
|
||||
// списке данных. Заявка показывается в выезжающей панели ПОВЕРХ текущего
|
||||
// раздела, поэтому rpnav сохраняется вместе с rpmode.
|
||||
//
|
||||
// Ссылка на ПУСТУЮ новую форму конкретного типа (без предзаполнения, минуя
|
||||
// плитки) — см. newRequestLinkUrl():
|
||||
// …/СтраницаПортала.aspx?rpmode=create&rptype=<форма>
|
||||
// Отличается от «создать на основе» (тот же rpmode=create, но с rpsource) —
|
||||
// без rpsource форма просто открывается пустой.
|
||||
//
|
||||
// Префикс rp (request-portal): имена id/mode/type зарезервированы SharePoint
|
||||
// (напр. ?id= он трактует как навигацию к элементу → «Элемент не существует»),
|
||||
// поэтому используем собственные, неконфликтные имена параметров.
|
||||
@@ -63,6 +69,23 @@ export interface IRoute {
|
||||
listId?: string;
|
||||
/** Id исходной заявки для предзаполнения — для 'create' (напр. орг. места на основе прием). */
|
||||
sourceId?: number;
|
||||
/**
|
||||
* Id строки-источника во внешней системе (Dataverse «Строка заявки», GUID
|
||||
* первичного ключа). Приходит по ссылке из внешней системы вместе с rptype —
|
||||
* форма «СЗ на перемещение ТМЦ» по нему после отправки на согласование
|
||||
* записывает обратно ссылку на заявку (см. shared/dataverse/demandLine.service).
|
||||
*/
|
||||
positionId?: string;
|
||||
/**
|
||||
* Id номенклатуры для GET /Dictionary/Nomenclature/{id} — форма предзаполняет
|
||||
* табличную часть остатками по складам. Приходит по той же внешней ссылке.
|
||||
*/
|
||||
nomenclatureId?: string;
|
||||
/**
|
||||
* Склад-фильтр для GET /Dictionary/Nomenclature — вернуть остатки только по
|
||||
* этому складу. Приходит по той же внешней ссылке; пусто — все склады.
|
||||
*/
|
||||
storeName?: string;
|
||||
/** Подвкладка «Моих заявок»; задана только при nav='own'. */
|
||||
ownTab?: OwnTab;
|
||||
/** Фильтр по статусу заявки; задан только при nav='own' и ownTab='created'. */
|
||||
@@ -310,6 +333,12 @@ export function parseRoute(search: string = window.location.search): IRoute {
|
||||
const listId = params.get('rplist') ?? undefined;
|
||||
const sourceRaw = params.get('rpsource');
|
||||
const sourceId = sourceRaw ? Number(sourceRaw) : undefined;
|
||||
// Параметры внешней ссылки (без rp-префикса — так их формирует внешняя
|
||||
// система, менять её мы не можем). Актуальны только для сценария «создать» по
|
||||
// rptype: заполнить форму ТМЦ из справочника и запомнить строку-источник.
|
||||
const positionId = params.get('positionId') ?? undefined;
|
||||
const nomenclatureId = params.get('nomenclatureId') ?? undefined;
|
||||
const storeName = params.get('storeName') ?? undefined;
|
||||
|
||||
// Подвкладка и фильтр — состояние раздела «Мои заявки», поэтому вне его не
|
||||
// читаются вовсе (иначе чужой rptab из ссылки «протёк» бы в другой раздел).
|
||||
@@ -343,6 +372,17 @@ export function parseRoute(search: string = window.location.search): IRoute {
|
||||
if (formKey && sourceId && !isNaN(sourceId)) {
|
||||
return { mode: 'create', nav: 'new', formKey, sourceId };
|
||||
}
|
||||
// Ссылка на пустую новую форму конкретного типа — без предзаполнения
|
||||
// (клик по плитке внутри портала, либо явная ссылка ?rptype=<форма> без
|
||||
// rpsource — см. newRequestLinkUrl). Как и ветка с rpsource выше, НЕ требует
|
||||
// rpmode=create: buildQuery() его для этого случая не пишет (значения по
|
||||
// умолчанию в адрес не пишем), поэтому единственный сигнал — сам rptype.
|
||||
// Но approve/edit явно исключаем: битая/неполная ссылка на них (напр.
|
||||
// rpmode=approve без валидного rpid) должна откатываться на обычную подачу,
|
||||
// а не тихо превращаться в открытие пустой формы другого режима.
|
||||
if (formKey && mode !== 'approve' && mode !== 'edit') {
|
||||
return { mode: 'create', nav: 'new', formKey, positionId, nomenclatureId, storeName };
|
||||
}
|
||||
return { mode: 'submit', nav, ownTab, ownStatus, page, query };
|
||||
}
|
||||
|
||||
@@ -380,9 +420,9 @@ function buildQuery(route: IRoute): string {
|
||||
// Партиция неизвестна (архивная ссылка старого формата, до этого поля) —
|
||||
// ссылка всё равно валидна, форма/просмотр просто откатятся на текущую.
|
||||
if (route.listId) params.set('rplist', route.listId);
|
||||
} else if (route.mode === 'create' && route.formKey && route.sourceId) {
|
||||
} else if (route.mode === 'create' && route.formKey) {
|
||||
params.set('rptype', route.formKey);
|
||||
params.set('rpsource', String(route.sourceId));
|
||||
if (route.sourceId) params.set('rpsource', String(route.sourceId));
|
||||
}
|
||||
|
||||
const query = params.toString();
|
||||
@@ -438,6 +478,18 @@ export function requestLinkUrl(formKey: string, itemId: number, listId?: string)
|
||||
return `${window.location.origin}${window.location.pathname}?${params.toString()}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* АБСОЛЮТНАЯ ссылка на ПУСТУЮ новую форму конкретного типа — без предзаполнения,
|
||||
* в отличие от requestLinkUrl (просмотр существующей). Для той же цели: письмо,
|
||||
* сообщение в чат, кнопка «поделиться ссылкой на форму».
|
||||
*/
|
||||
export function newRequestLinkUrl(formKey: string): string {
|
||||
const params = new URLSearchParams();
|
||||
params.set('rpmode', 'create');
|
||||
params.set('rptype', formKey);
|
||||
return `${window.location.origin}${window.location.pathname}?${params.toString()}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Открыть заявку по её АБСОЛЮТНОЙ ссылке (см. requestLinkUrl) БЕЗ перезагрузки
|
||||
* страницы — если ссылка ведёт на эту же страницу портала.
|
||||
|
||||
Reference in New Issue
Block a user