diff --git a/src/webparts/ctFormsPortal/forms/ct/components/CtCreateForm.module.scss b/src/webparts/ctFormsPortal/forms/ct/components/CtCreateForm.module.scss index b12f7a9..e052702 100644 --- a/src/webparts/ctFormsPortal/forms/ct/components/CtCreateForm.module.scss +++ b/src/webparts/ctFormsPortal/forms/ct/components/CtCreateForm.module.scss @@ -26,6 +26,13 @@ } } +.loader { + display: flex; + align-items: center; + justify-content: center; + padding: 64px 0; +} + .content { flex: 1; background: $surface; diff --git a/src/webparts/ctFormsPortal/forms/ct/components/CtCreateForm.tsx b/src/webparts/ctFormsPortal/forms/ct/components/CtCreateForm.tsx index 89e90c4..79b0509 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 { Alert, Spinner } from '@tnsu/ui-kit'; import styles from './CtCreateForm.module.scss'; import '@tnsu/ui-kit/styles.css'; @@ -35,6 +36,11 @@ const CtCreateForm: React.FC = ({ context, userDisplayName, ensureHighestStep, } = useCtForm(); + // Открыта существующая СТ — шаги не показываем, пока она не загрузится из SP. Иначе шаг 1 успевал + // появиться с пустой сессией и запоминал пустой выбор: «Выберите позиции», хотя позиции в СТ есть. + const [isCtLoading, setIsCtLoading] = useState(!!initialCtId); + const [ctLoadError, setCtLoadError] = useState(undefined); + // Режим формы — по тому, кто открыл и в каком статусе СТ (getCtAccess), а не по ctid/ctId в ссылке. // Считается на каждом рендере из данных СТ — ничего не «прилипает» в сессии: после «Перезапустить // согласование» или возврата на доработку режим меняется сам. astel-k — цены не видит никогда. @@ -192,11 +198,14 @@ const CtCreateForm: React.FC = ({ context, userDisplayName, markStepComplete(4); } } + setIsCtLoading(false); }).catch((err) => { // Раньше ошибка глоталась молча → при сбое любого запроса форма оставалась // на устаревшем статусе из session storage (напр. «Сформирована» вместо - // «На согласовании»). Теперь хотя бы видно, какой запрос упал. + // «На согласовании»). Показываем ошибку, а шаги — по данным сессии, если они есть. console.error("[CtCreateForm] загрузка СТ по ссылке упала:", err); + setCtLoadError(`Не удалось загрузить СТ: ${(err as Error).message ?? 'неизвестная ошибка'}`); + setIsCtLoading(false); }); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); @@ -256,8 +265,19 @@ const CtCreateForm: React.FC = ({ context, userDisplayName, } }; + if (isCtLoading) { + return ( +
+
+ +
+
+ ); + } + return (
+ {ctLoadError && {ctLoadError}}