feat: письмо инициатору при отклонении и возврате заявки

Поток RequestsNotification умеет ветки «Отклонено» и «Возврат на доработку»,
но портал их не вызывал: notifyActiveStep ищет только активные строки, а после
такого решения их нет — инициатор узнавал о решении, только открыв заявку.

notifyInitiatorOfReturn шлёт в тот же поток RowID строки, по которой решил
текущий пользователь; подключён в onDecided всех форм, кроме «Изменения
условий ТД» (доработаем позже).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Тимур Городецкий
2026-10-28 16:50:31 +05:00
parent 72e330e659
commit 9cacb6b271
17 changed files with 198 additions and 76 deletions
@@ -23,6 +23,7 @@ import {
ApprovalHistory,
useMatrixEditor,
notifyActiveStep,
notifyInitiatorOfReturn,
useRequestTypeId,
isEditableStatus,
APPROVAL_PHASE
@@ -102,20 +103,25 @@ const Ticket1CView: React.FC<ITicket1CViewProps> = ({ context, itemId, formKey,
approval.getJobTitle(l)
);
// rowId — оповестить конкретную активную строку (см. notifyActiveStep).
const notify = (rowId?: number): void => {
if (!requestTypeId) return;
notifyActiveStep(
context,
approval,
itemId,
{
// Куда смотрит поток оповещения; undefined — тип заявки ещё не резолвился.
const notifyTarget = requestTypeId
? {
requestTypeId,
dataListName: listId ? dataListTitleForListId(FORM_ID, listId) : dataListTitle(FORM_ID),
approvalListName: listId ? approvalListTitleForListId(FORM_ID, listId) : approvalListTitle(FORM_ID)
},
rowId
).catch(() => undefined);
}
: undefined;
// rowId — оповестить конкретную активную строку (см. notifyActiveStep).
const notify = (rowId?: number): void => {
if (!notifyTarget) return;
notifyActiveStep(context, approval, itemId, notifyTarget, rowId).catch(() => undefined);
};
// Отклонили или вернули на доработку — письмо инициатору (при других статусах ничего не делает).
const notifyInitiator = (newStatus: string): void => {
if (!notifyTarget) return;
notifyInitiatorOfReturn(context, approval, itemId, notifyTarget, newStatus).catch(() => undefined);
};
const executorEditing = useExecutorEditing({
@@ -246,6 +252,7 @@ const Ticket1CView: React.FC<ITicket1CViewProps> = ({ context, itemId, formKey,
setDecisionSeq((n) => n + 1);
// Очередь сдвинулась — уведомляем следующий активный шаг.
notify();
notifyInitiator(newStatus);
// Дошла до исполнения / завершилась / отклонена — карточка в Planner
// (повторно не создаётся, см. plannerHandoff.ts).