Feature/request type access all requests (#22)
Tests / frontend-test (push) Successful in 1m24s

Co-authored-by: gorbenko.pavel <gorbenko.pavel@tansu.kz>
Reviewed-on: http://git.tnsu.kz/timur.gorodetskiy/request-portal/pulls/22
This commit was merged in pull request #22.
This commit is contained in:
2026-09-25 11:48:09 +00:00
parent ebc74dc46d
commit 98be3980cb
15 changed files with 590 additions and 56 deletions
@@ -10,6 +10,7 @@ import { IRequestType } from '../../models/types';
import { emitRequestsChanged } from '../../shared/requestEvents';
import { confirmDiscardFormChanges, markFormClean } from '../../shared/unsavedChanges';
import { useIsTester } from '../../shared/useIsTester';
import { useAccessibleAllRequestsFormKeys } from '../../shared/approval';
export interface ISubmitFeatureProps {
context: WebPartContext;
@@ -25,6 +26,12 @@ export interface ISubmitFeatureProps {
/** Пользователь выбрал плитку — сообщаем наверх, чтобы адрес страницы стал
* ссылкой на эту пустую форму (см. newRequestLinkUrl в shared/routing). */
onFormSelected?: (formKey: string) => void;
/**
* Кнопка «Все заявки этого типа» на форме — только когда в админке
* approval-route текущему пользователю выдан доступ к этому типу (см.
* hasRequestTypeAccess ниже). Ведёт в раздел «Все заявки» (nav='allRequests').
*/
onOpenAllRequests?: (requestTypeId: number) => void;
}
// Фича «Подать заявку»: плитки → беспоук-форма (категории/вкладки — в RequestPortal).
@@ -35,6 +42,7 @@ const SubmitFeature: React.FC<ISubmitFeatureProps> = ({
initialForm,
editForm,
onFormSelected,
onOpenAllRequests,
}) => {
// «Создать на основе» и «редактировать» оба сразу открывают нужную форму, минуя плитки.
const preOpen = initialForm ?? editForm;
@@ -60,6 +68,13 @@ const SubmitFeature: React.FC<ISubmitFeatureProps> = ({
const requests = getRequestsByCategory(activeCategoryId);
const isTester = useIsTester();
// Кнопка «Все заявки этого типа» — и на плитке, и на открытой форме, только
// если текущему пользователю в админке approval-route выдан доступ к этому
// типу (см. shared/approval/requestTypeAccess.ts). Один общий поход по всем
// типам разом (formKey формы совпадает с pageUrl approval-route по
// соглашению, см. useRequestTypeId) — не по одному запросу на каждую плитку.
const accessibleAllRequestsIds = useAccessibleAllRequestsFormKeys(context);
// Возврат к плиткам закрывает форму и теряет введённое (раздел остаётся
// смонтированным, но состояние формы живёт в самом FormComponent). Спрашиваем,
// если правки есть и они не сохранены; после согласия флаг снимаем — терять
@@ -102,21 +117,37 @@ const SubmitFeature: React.FC<ISubmitFeatureProps> = ({
// которой они пришли (formKey совпал).
const external = initialForm && request.id === initialForm.formKey ? initialForm : undefined;
const allRequestsTypeId = accessibleAllRequestsIds?.get(request.id);
// Ленивый рендер формы: её код подтягивается только сейчас, при открытии.
return (
<React.Suspense fallback={<div className={styles.loading}>Загрузка формы…</div>}>
<FormComponent
requestType={request}
context={context}
onCancel={handleBack}
onSaved={emitRequestsChanged}
sourceId={sourceId}
editId={editId}
positionId={external?.positionId}
nomenclatureId={external?.nomenclatureId}
storeName={external?.storeName}
/>
</React.Suspense>
<>
{allRequestsTypeId !== undefined && onOpenAllRequests && (
<div className={styles.formToolbar}>
<button
type="button"
className={styles.allRequestsButton}
onClick={() => onOpenAllRequests(allRequestsTypeId)}
>
<Icon name="people" size="sm" />
<span>Все заявки этого типа</span>
</button>
</div>
)}
<React.Suspense fallback={<div className={styles.loading}>Загрузка формы…</div>}>
<FormComponent
requestType={request}
context={context}
onCancel={handleBack}
onSaved={emitRequestsChanged}
sourceId={sourceId}
editId={editId}
positionId={external?.positionId}
nomenclatureId={external?.nomenclatureId}
storeName={external?.storeName}
/>
</React.Suspense>
</>
);
};
@@ -135,7 +166,12 @@ const SubmitFeature: React.FC<ISubmitFeatureProps> = ({
{selectedRequest ? (
renderSelected(selectedRequest)
) : (
<RequestGrid requests={requests} onSelect={handleSelect} />
<RequestGrid
requests={requests}
onSelect={handleSelect}
accessibleAllRequestsIds={accessibleAllRequestsIds}
onOpenAllRequests={onOpenAllRequests}
/>
)}
</div>
);