diff --git a/src/webparts/ctFormsPortal/forms/ct/components/CtCreateForm.tsx b/src/webparts/ctFormsPortal/forms/ct/components/CtCreateForm.tsx index 79b0509..60869e7 100644 --- a/src/webparts/ctFormsPortal/forms/ct/components/CtCreateForm.tsx +++ b/src/webparts/ctFormsPortal/forms/ct/components/CtCreateForm.tsx @@ -14,6 +14,7 @@ import { buildOffersFromSpRecords } from './utils/spOffers'; import { isUserInApprovalChain } from './utils/approvalAccess'; import { CtAccess, getCtAccess, isCtAuthor } from './utils/ctAccess'; import { noOfferRecordsToSuppliers, withNoOfferSuppliers } from './utils/noOfferSuppliers'; +import { reachableStep } from './utils/reachableStep'; import { Alert, Spinner } from '@tnsu/ui-kit'; import styles from './CtCreateForm.module.scss'; import '@tnsu/ui-kit/styles.css'; @@ -191,9 +192,13 @@ const CtCreateForm: React.FC = ({ context, userDisplayName, // Автор, СТ возвращена на доработку — шаг 4: там видно, кто вернул и что исправить. ensureHighestStep(4); goToStep(4); - } else if (approvalMatrix.length > 0) { - // Regular reload — make Step 4 accessible; only mark complete if CT is fully resolved - ensureHighestStep(4); + } else { + // Автор открыл свою СТ — открываем шаги, до которых она уже дошла (позиции → 2, КП → 3, маршрут → 4). + ensureHighestStep(reachableStep({ + hasPositions: positions.length > 0, + hasKp: rawOffers.length > 0 || uploadedKpFiles.length > 0, + hasRoute: approvalMatrix.length > 0, + })); if (ct.status === 'approved' || ct.status === 'rejected') { markStepComplete(4); } diff --git a/src/webparts/ctFormsPortal/forms/ct/components/utils/reachableStep.test.ts b/src/webparts/ctFormsPortal/forms/ct/components/utils/reachableStep.test.ts new file mode 100644 index 0000000..056a00f --- /dev/null +++ b/src/webparts/ctFormsPortal/forms/ct/components/utils/reachableStep.test.ts @@ -0,0 +1,21 @@ +import { reachableStep } from './reachableStep'; + +describe('reachableStep (до какого шага открыт степпер у СТ, загруженной из SP)', () => { + // Черновик в новой вкладке: сессии нет → степпер открывал только шаг 1, хотя позиции и КП уже есть, + // и до шага 3 приходилось идти через «Сохранить и продолжить» на каждом шаге. + it('пустая СТ — только шаг 1', () => { + expect(reachableStep({ hasPositions: false, hasKp: false, hasRoute: false })).toBe(1); + }); + + it('позиции выбраны — открыт шаг 2', () => { + expect(reachableStep({ hasPositions: true, hasKp: false, hasRoute: false })).toBe(2); + }); + + it('есть КП — открыт шаг 3', () => { + expect(reachableStep({ hasPositions: true, hasKp: true, hasRoute: false })).toBe(3); + }); + + it('есть маршрут согласования — открыт шаг 4', () => { + expect(reachableStep({ hasPositions: true, hasKp: true, hasRoute: true })).toBe(4); + }); +}); diff --git a/src/webparts/ctFormsPortal/forms/ct/components/utils/reachableStep.ts b/src/webparts/ctFormsPortal/forms/ct/components/utils/reachableStep.ts new file mode 100644 index 0000000..6fb4ba2 --- /dev/null +++ b/src/webparts/ctFormsPortal/forms/ct/components/utils/reachableStep.ts @@ -0,0 +1,17 @@ +import { FormStep } from '../types/domain'; + +// Что уже есть в СТ, загруженной из SP. +export interface CtProgress { + hasPositions: boolean; + hasKp: boolean; + hasRoute: boolean; +} + +// До какого шага открыт степпер по данным самой СТ, а не по сессии вкладки. Без этого черновик, +// открытый в новой вкладке (из реестра), давал кликнуть только шаг 1, хотя позиции и КП уже есть. +export function reachableStep(progress: CtProgress): FormStep { + if (progress.hasRoute) return 4; + if (progress.hasKp) return 3; + if (progress.hasPositions) return 2; + return 1; +}