diff --git a/src/webparts/ctFormsPortal/forms/ct/components/CtCreateForm.tsx b/src/webparts/ctFormsPortal/forms/ct/components/CtCreateForm.tsx index f984e3e..d6a01d3 100644 --- a/src/webparts/ctFormsPortal/forms/ct/components/CtCreateForm.tsx +++ b/src/webparts/ctFormsPortal/forms/ct/components/CtCreateForm.tsx @@ -178,7 +178,12 @@ const CtCreateForm: React.FC = ({ context, userDisplayName, markStepComplete(4); } } - }).catch(() => undefined); + }).catch((err) => { + // Раньше ошибка глоталась молча → при сбое любого запроса форма оставалась + // на устаревшем статусе из session storage (напр. «Сформирована» вместо + // «На согласовании»). Теперь хотя бы видно, какой запрос упал. + console.error("[CtCreateForm] загрузка СТ по ссылке упала:", err); + }); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); diff --git a/src/webparts/ctFormsPortal/forms/ct/services/CtService.ts b/src/webparts/ctFormsPortal/forms/ct/services/CtService.ts index 8ec3a41..007a144 100644 --- a/src/webparts/ctFormsPortal/forms/ct/services/CtService.ts +++ b/src/webparts/ctFormsPortal/forms/ct/services/CtService.ts @@ -614,10 +614,15 @@ export class CtService { async notifyActiveApprover(ctId: string): Promise { const rows = await this.approval.getForRequest(parseInt(ctId, 10)); + if (rows.length === 0) return; + // Есть активный согласующий → уведомляем его («поступила на согласование»). + // Иначе финал (все согласовали / кто-то отклонил): активной строки уже нет, но поток + // сам выбирает получателя (инициатора) по статусу СТ — ему нужен лишь любой RowID этой СТ, + // чтобы выйти на саму СТ и её автора. Берём последнюю строку маршрута. Без этого + // «Согласовано»/«Отклонено» инициатору не уходили (поток вообще не вызывался). const active = rows.filter((r) => r.status === REQUEST_STATUS.onApproval)[0]; - if (active) { - await this.triggerApprovalNotification(active.id); - } + const rowToNotify = active ?? rows[rows.length - 1]; + await this.triggerApprovalNotification(rowToNotify.id); } async triggerApprovalNotification(spItemId: number): Promise { @@ -750,10 +755,11 @@ export class CtService { const filter = positionSpIds .map((id) => `positionId eq ${id}`) .join(" or "); - // offerIdId — SP REST raw-ID suffix for Lookup fields; offerId fallback for plain Number fields + // offerId — обычное числовое поле (SP-Id строки файла КП), НЕ лукап. Раньше в $select + // ошибочно был offerIdId (raw-ID суффикс лукапа) — такого поля нет, и SP валил запрос 400. const url = `${this._li(LISTS.OFFERS)}` + - `?$select=supplierId,offerIdId,offerId` + + `?$select=supplierId,offerId` + `&$filter=${filter}` + `&$top=2000`; const res = await this.http.get(url, SPHttpClient.configurations.v1); @@ -764,7 +770,7 @@ export class CtService { const pairs: Array<{ supplierSpId: number; offerSpId: number }> = []; for (const item of data.value ?? []) { const supplierSpId = Number(item["supplierId"]); - const offerSpId = Number(item["offerIdId"] ?? item["offerId"] ?? 0); + const offerSpId = Number(item["offerId"] ?? 0); if (!offerSpId || !supplierSpId || seen.has(supplierSpId)) continue; seen.add(supplierSpId); pairs.push({ supplierSpId, offerSpId }); diff --git a/src/webparts/ctFormsPortal/shared/approval/ui/DecisionPanel.module.scss b/src/webparts/ctFormsPortal/shared/approval/ui/DecisionPanel.module.scss index 68c2b24..8662104 100644 --- a/src/webparts/ctFormsPortal/shared/approval/ui/DecisionPanel.module.scss +++ b/src/webparts/ctFormsPortal/shared/approval/ui/DecisionPanel.module.scss @@ -6,6 +6,14 @@ background: $white; border: 1px solid $gray-200; border-radius: 6px; + // Не на всю ширину — гармонично с карточкой «Маршрут согласования» (.matrixWrap). + max-width: 720px; +} + +@media (max-width: 900px) { + .panel { + max-width: 100%; + } } .title {