fix: в заголовке заявковк на чтение теперь показывает правильный номер
This commit is contained in:
@@ -70,6 +70,16 @@ const RequestPortal: React.FC<IRequestPortalProps> = ({ hasTeamsContext, context
|
||||
const [mobileNavOpen, setMobileNavOpen] = React.useState<boolean>(false);
|
||||
const [navCounts, setNavCounts] = React.useState<INavCounts | undefined>(undefined);
|
||||
|
||||
// Уникальный код заявки для заголовка Drawer (approve/edit) — сама форма
|
||||
// узнаёт его только после загрузки (см. onCodeLoaded в ApproveFeature/
|
||||
// EditFeature), поэтому не берём route.itemId (это RowID в SharePoint, а не
|
||||
// видимый пользователю код). Сбрасываем при переходе на другую заявку —
|
||||
// иначе при быстрой смене итемов в заголовке на миг мелькнёт код ПРЕДЫДУЩЕЙ.
|
||||
const [drawerCode, setDrawerCode] = React.useState<string>('');
|
||||
React.useEffect(() => {
|
||||
setDrawerCode('');
|
||||
}, [route.itemId, route.mode]);
|
||||
|
||||
const [activeCategoryId, setActiveCategoryId] = React.useState<string>(() => {
|
||||
if (route.mode === 'create' && route.formKey) {
|
||||
const found = REQUEST_TYPES.filter((r) => r.id === route.formKey)[0];
|
||||
@@ -386,15 +396,21 @@ const RequestPortal: React.FC<IRequestPortalProps> = ({ hasTeamsContext, context
|
||||
</div>
|
||||
|
||||
{route.mode === 'approve' && route.formKey && route.itemId && (
|
||||
<Drawer title={`Заявка №${route.itemId}`} onClose={closeDrawer}>
|
||||
<ApproveFeature context={context} formKey={route.formKey} itemId={route.itemId} listId={route.listId} />
|
||||
<Drawer title={drawerCode ? `Заявка №${drawerCode}` : 'Заявка'} onClose={closeDrawer}>
|
||||
<ApproveFeature
|
||||
context={context}
|
||||
formKey={route.formKey}
|
||||
itemId={route.itemId}
|
||||
listId={route.listId}
|
||||
onCodeLoaded={setDrawerCode}
|
||||
/>
|
||||
</Drawer>
|
||||
)}
|
||||
|
||||
{/* Своя незавершённая заявка — та же панель, но с формой. Ввод здесь тоже
|
||||
помечает состояние изменённым, поэтому обёртка ловит input/change. */}
|
||||
{route.mode === 'edit' && route.formKey && route.itemId && (
|
||||
<Drawer title={`Заявка №${route.itemId}`} onClose={closeEditDrawer}>
|
||||
<Drawer title={drawerCode ? `Заявка №${drawerCode}` : 'Заявка'} onClose={closeEditDrawer}>
|
||||
<div onInput={markFormDirty} onChange={markFormDirty}>
|
||||
<EditFeature
|
||||
context={context}
|
||||
@@ -402,6 +418,7 @@ const RequestPortal: React.FC<IRequestPortalProps> = ({ hasTeamsContext, context
|
||||
itemId={route.itemId}
|
||||
listId={route.listId}
|
||||
onClose={closeDrawer}
|
||||
onCodeLoaded={setDrawerCode}
|
||||
/>
|
||||
</div>
|
||||
</Drawer>
|
||||
|
||||
@@ -13,6 +13,8 @@ export interface IApproveFeatureProps {
|
||||
itemId: number;
|
||||
/** Партиция, где лежит заявка (см. IRoute.listId) — не задана у ссылок старого формата. */
|
||||
listId?: string;
|
||||
/** Уведомление о загруженном уникальном коде заявки — транзитом в ViewComponent (см. заголовок Drawer в RequestPortal). */
|
||||
onCodeLoaded?: (code: string) => void;
|
||||
}
|
||||
|
||||
// Фича «Согласование»: открывается по ссылке из потока (mode=approve&type=&id=)
|
||||
@@ -23,7 +25,7 @@ export interface IApproveFeatureProps {
|
||||
// знает о полях конкретной формы, а эта фича — единственный вход в просмотр
|
||||
// заявки, общий для всех типов. Стоит вне .rp-print-root формы, поэтому в
|
||||
// печатную версию заявки переписка не попадает.
|
||||
const ApproveFeature: React.FC<IApproveFeatureProps> = ({ context, formKey, itemId, listId }) => {
|
||||
const ApproveFeature: React.FC<IApproveFeatureProps> = ({ context, formKey, itemId, listId, onCodeLoaded }) => {
|
||||
const ViewComponent = getViewComponent(formKey);
|
||||
|
||||
// Партиция указана и реестр ТОЧНО знает, что её там нет — см. тот же
|
||||
@@ -40,7 +42,13 @@ const ApproveFeature: React.FC<IApproveFeatureProps> = ({ context, formKey, item
|
||||
) : ViewComponent ? (
|
||||
<>
|
||||
<React.Suspense fallback={<div className={styles.state}>Загрузка…</div>}>
|
||||
<ViewComponent context={context} itemId={itemId} formKey={formKey} listId={listId} />
|
||||
<ViewComponent
|
||||
context={context}
|
||||
itemId={itemId}
|
||||
formKey={formKey}
|
||||
listId={listId}
|
||||
onCodeLoaded={onCodeLoaded}
|
||||
/>
|
||||
</React.Suspense>
|
||||
{/* Доступно всем, кто может открыть заявку: автору, всем согласующим
|
||||
(и уже решившим, и ещё ждущим своей очереди) и исполнителям —
|
||||
|
||||
@@ -17,6 +17,8 @@ export interface IEditFeatureProps {
|
||||
listId?: string;
|
||||
/** Закрыть панель (после сохранения). */
|
||||
onClose: () => void;
|
||||
/** Уведомление о загруженном уникальном коде заявки — транзитом в FormComponent (см. заголовок Drawer в RequestPortal). */
|
||||
onCodeLoaded?: (code: string) => void;
|
||||
}
|
||||
|
||||
// Фича «Редактирование»: открывает СВОЮ незавершённую заявку (черновик,
|
||||
@@ -26,7 +28,7 @@ export interface IEditFeatureProps {
|
||||
//
|
||||
// Отдельно от features/submit намеренно: там форма живёт в потоке «плитки →
|
||||
// новая заявка», а тут — точечное открытие конкретной записи по ссылке.
|
||||
const EditFeature: React.FC<IEditFeatureProps> = ({ context, formKey, itemId, listId, onClose }) => {
|
||||
const EditFeature: React.FC<IEditFeatureProps> = ({ context, formKey, itemId, listId, onClose, onCodeLoaded }) => {
|
||||
const FormComponent = getFormComponent(formKey);
|
||||
const requestType = REQUEST_TYPES.filter((r) => r.id === formKey)[0];
|
||||
|
||||
@@ -65,6 +67,7 @@ const EditFeature: React.FC<IEditFeatureProps> = ({ context, formKey, itemId, li
|
||||
emitRequestsChanged();
|
||||
onClose();
|
||||
}}
|
||||
onCodeLoaded={onCodeLoaded}
|
||||
/>
|
||||
</React.Suspense>
|
||||
{/* Обсуждение — то же самое, что видят согласующие (комментарии к строке
|
||||
|
||||
@@ -45,7 +45,8 @@ const ClearanceForm: React.FC<IRequestFormProps> = ({
|
||||
onCancel,
|
||||
onSaved,
|
||||
editId,
|
||||
editListId
|
||||
editListId,
|
||||
onCodeLoaded
|
||||
}) => {
|
||||
const [data, setData] = useState<IFormData>(EMPTY_DATA);
|
||||
const [requestId, setRequestId] = useState<number | undefined>(editId);
|
||||
@@ -77,6 +78,7 @@ const ClearanceForm: React.FC<IRequestFormProps> = ({
|
||||
setData(loaded.data);
|
||||
setRequestStatus(loaded.status);
|
||||
setRequestCode(loaded.code || undefined);
|
||||
if (loaded.code) onCodeLoaded?.(loaded.code);
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
|
||||
@@ -39,6 +39,8 @@ interface IClearanceViewProps {
|
||||
formKey: string;
|
||||
/** Партиция, где лежит ЭТА заявка — см. IApprovalViewProps.listId. */
|
||||
listId?: string;
|
||||
/** Уведомление о загруженном уникальном коде заявки — см. IApprovalViewProps.onCodeLoaded. */
|
||||
onCodeLoaded?: (code: string) => void;
|
||||
}
|
||||
|
||||
type SaveState = 'idle' | 'saving' | 'saved' | 'error';
|
||||
@@ -46,7 +48,7 @@ type SaveState = 'idle' | 'saving' | 'saved' | 'error';
|
||||
// Обходной лист в режиме согласующего. Форма read-only, КРОМЕ отметок, которые
|
||||
// заполняет профильный отдел на своём шаге: КДП — карта СКУД и сумма обучения,
|
||||
// отдел подбора — парковочная карта (см. approverRights.ts).
|
||||
const ClearanceView: React.FC<IClearanceViewProps> = ({ context, itemId, formKey, listId }) => {
|
||||
const ClearanceView: React.FC<IClearanceViewProps> = ({ context, itemId, formKey, listId, onCodeLoaded }) => {
|
||||
const [data, setData] = useState<IFormData>(EMPTY_DATA);
|
||||
const [status, setStatus] = useState<string>('');
|
||||
const [code, setCode] = useState<string>('');
|
||||
@@ -113,6 +115,7 @@ const ClearanceView: React.FC<IClearanceViewProps> = ({ context, itemId, formKey
|
||||
setData(loaded.data);
|
||||
setStatus(loaded.status);
|
||||
setCode(loaded.code);
|
||||
onCodeLoaded?.(loaded.code);
|
||||
setError(null);
|
||||
setLoading(false);
|
||||
setLockedWriteOffs(
|
||||
|
||||
@@ -45,7 +45,8 @@ const DismissalForm: React.FC<IRequestFormProps> = ({
|
||||
onCancel,
|
||||
onSaved,
|
||||
editId,
|
||||
editListId
|
||||
editListId,
|
||||
onCodeLoaded
|
||||
}) => {
|
||||
const [data, setData] = useState<IFormData>(EMPTY_DATA);
|
||||
const [requestId, setRequestId] = useState<number | undefined>(editId);
|
||||
@@ -81,6 +82,7 @@ const DismissalForm: React.FC<IRequestFormProps> = ({
|
||||
setData(loaded.data);
|
||||
setRequestStatus(loaded.status);
|
||||
setRequestCode(loaded.code || undefined);
|
||||
if (loaded.code) onCodeLoaded?.(loaded.code);
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
|
||||
@@ -48,12 +48,14 @@ interface IDismissalViewProps {
|
||||
formKey: string;
|
||||
/** Партиция, где лежит ЭТА заявка — см. IApprovalViewProps.listId. */
|
||||
listId?: string;
|
||||
/** Уведомление о загруженном уникальном коде заявки — см. IApprovalViewProps.onCodeLoaded. */
|
||||
onCodeLoaded?: (code: string) => void;
|
||||
}
|
||||
|
||||
// Заявление на увольнение только для просмотра (режим согласующего).
|
||||
// Переиспользует ту же секцию, что и форма подачи; редактирование выключено через
|
||||
// <FormModeProvider readOnly> — поля сами становятся неизменяемыми.
|
||||
const DismissalView: React.FC<IDismissalViewProps> = ({ context, itemId, formKey, listId }) => {
|
||||
const DismissalView: React.FC<IDismissalViewProps> = ({ context, itemId, formKey, listId, onCodeLoaded }) => {
|
||||
const [data, setData] = useState<IFormData>(EMPTY_DATA);
|
||||
const [status, setStatus] = useState<string>('');
|
||||
const [code, setCode] = useState<string>('');
|
||||
@@ -92,6 +94,7 @@ const DismissalView: React.FC<IDismissalViewProps> = ({ context, itemId, formKey
|
||||
setData(loaded.data);
|
||||
setStatus(loaded.status);
|
||||
setCode(loaded.code);
|
||||
onCodeLoaded?.(loaded.code);
|
||||
setError(null);
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
@@ -67,7 +67,8 @@ const RecruitingHireForm: React.FC<IRequestFormProps> = ({
|
||||
onCancel,
|
||||
onSaved,
|
||||
editId,
|
||||
editListId
|
||||
editListId,
|
||||
onCodeLoaded
|
||||
}) => {
|
||||
const [data, setData] = useState<IFormData>(EMPTY_DATA);
|
||||
// Вложения — три зоны: удостоверение, резюме и прочие (см. attachmentCategories.ts).
|
||||
@@ -100,6 +101,7 @@ const RecruitingHireForm: React.FC<IRequestFormProps> = ({
|
||||
setData(loaded.data);
|
||||
setRequestStatus(loaded.status);
|
||||
setRequestCode(loaded.code || undefined);
|
||||
if (loaded.code) onCodeLoaded?.(loaded.code);
|
||||
setExistingAttachments(atts);
|
||||
}
|
||||
})
|
||||
|
||||
@@ -41,6 +41,8 @@ interface IRecruitingHireViewProps {
|
||||
formKey: string;
|
||||
/** Партиция, где лежит ЭТА заявка — см. IApprovalViewProps.listId. */
|
||||
listId?: string;
|
||||
/** Уведомление о загруженном уникальном коде заявки — см. IApprovalViewProps.onCodeLoaded. */
|
||||
onCodeLoaded?: (code: string) => void;
|
||||
}
|
||||
|
||||
// Ключ формы «Организация рабочего места» в реестре (data/requests) — цель
|
||||
@@ -53,7 +55,7 @@ const NOOP_SET: SetField = () => undefined;
|
||||
// Заявка «на прием» только для просмотра (режим согласующего).
|
||||
// Переиспользует те же секции, что и форма подачи; редактирование выключено
|
||||
// через <FormModeProvider readOnly> — поля сами становятся неизменяемыми.
|
||||
const RecruitingHireView: React.FC<IRecruitingHireViewProps> = ({ context, itemId, formKey, listId }) => {
|
||||
const RecruitingHireView: React.FC<IRecruitingHireViewProps> = ({ context, itemId, formKey, listId, onCodeLoaded }) => {
|
||||
const [data, setData] = useState<IFormData>(EMPTY_DATA);
|
||||
const [status, setStatus] = useState<string>('');
|
||||
const [code, setCode] = useState<string>('');
|
||||
@@ -114,6 +116,7 @@ const RecruitingHireView: React.FC<IRecruitingHireViewProps> = ({ context, itemI
|
||||
setData(loaded.data);
|
||||
setStatus(loaded.status);
|
||||
setCode(loaded.code);
|
||||
onCodeLoaded?.(loaded.code);
|
||||
setAttachments(files);
|
||||
setError(null);
|
||||
setLoading(false);
|
||||
|
||||
@@ -113,7 +113,6 @@ export const HIRE_TYPE_OPTIONS: ISelectOption[] = [
|
||||
|
||||
/** Варианты «Испытательный срок» — самые частые сроки (совпадают с choices колонки ProbationPeriod). */
|
||||
export const PROBATION_PERIOD_OPTIONS: ISelectOption[] = [
|
||||
{ value: 'Без испытательного срока', label: 'Без испытательного срока' },
|
||||
{ value: '1 месяц', label: '1 месяц' },
|
||||
{ value: '2 месяца', label: '2 месяца' },
|
||||
{ value: '3 месяца', label: '3 месяца' },
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
{ "internalName": "PpeClothingSize", "title": "СИЗ: размер одежды", "type": "Text" },
|
||||
{ "internalName": "PpeShoeSize", "title": "СИЗ: размер обуви", "type": "Number" },
|
||||
|
||||
{ "internalName": "ProbationPeriod", "title": "Испытательный срок", "type": "Choice", "choices": ["Без испытательного срока", "1 месяц", "2 месяца", "3 месяца", "6 месяцев"] },
|
||||
{ "internalName": "ProbationPeriod", "title": "Испытательный срок", "type": "Choice", "choices": ["1 месяц", "2 месяца", "3 месяца", "6 месяцев"] },
|
||||
{ "internalName": "SalaryProbation", "title": "Оклад при испытательном сроке", "type": "Number", "decimals": 2 },
|
||||
{ "internalName": "SalaryAfterProbation", "title": "Оклад по завершении ИС", "type": "Number", "decimals": 2 },
|
||||
{ "internalName": "WorkSchedule", "title": "График работы", "type": "Text" },
|
||||
|
||||
@@ -59,7 +59,8 @@ const RecruitingSelectionForm: React.FC<IRequestFormProps> = ({
|
||||
onCancel,
|
||||
onSaved,
|
||||
editId,
|
||||
editListId
|
||||
editListId,
|
||||
onCodeLoaded
|
||||
}) => {
|
||||
const [data, setData] = useState<IFormData>(EMPTY_DATA);
|
||||
const [files, setFiles] = useState<File[]>([]);
|
||||
@@ -85,6 +86,7 @@ const RecruitingSelectionForm: React.FC<IRequestFormProps> = ({
|
||||
setData(loaded.data);
|
||||
setRequestStatus(loaded.status);
|
||||
setRequestCode(loaded.code || undefined);
|
||||
if (loaded.code) onCodeLoaded?.(loaded.code);
|
||||
setExistingAttachments(atts);
|
||||
}
|
||||
})
|
||||
|
||||
@@ -37,6 +37,8 @@ interface IRecruitingSelectionViewProps {
|
||||
formKey: string;
|
||||
/** Партиция, где лежит ЭТА заявка — см. IApprovalViewProps.listId. */
|
||||
listId?: string;
|
||||
/** Уведомление о загруженном уникальном коде заявки — см. IApprovalViewProps.onCodeLoaded. */
|
||||
onCodeLoaded?: (code: string) => void;
|
||||
}
|
||||
|
||||
// В режиме чтения поля не редактируются, поэтому обновление — пустышка.
|
||||
@@ -44,7 +46,7 @@ const NOOP_SET: SetField = () => undefined;
|
||||
|
||||
// Заявка «на подбор» только для просмотра (режим согласующего). Переиспользует те же
|
||||
// секции, что и форма подачи; редактирование выключено через <FormModeProvider readOnly>.
|
||||
const RecruitingSelectionView: React.FC<IRecruitingSelectionViewProps> = ({ context, itemId, formKey, listId }) => {
|
||||
const RecruitingSelectionView: React.FC<IRecruitingSelectionViewProps> = ({ context, itemId, formKey, listId, onCodeLoaded }) => {
|
||||
const [data, setData] = useState<IFormData>(EMPTY_DATA);
|
||||
const [status, setStatus] = useState<string>('');
|
||||
const [code, setCode] = useState<string>('');
|
||||
@@ -78,6 +80,7 @@ const RecruitingSelectionView: React.FC<IRecruitingSelectionViewProps> = ({ cont
|
||||
setData(loaded.data);
|
||||
setStatus(loaded.status);
|
||||
setCode(loaded.code);
|
||||
onCodeLoaded?.(loaded.code);
|
||||
setAttachments(files);
|
||||
setError(null);
|
||||
setLoading(false);
|
||||
|
||||
@@ -50,7 +50,8 @@ const ReferralForm: React.FC<IRequestFormProps> = ({
|
||||
onCancel,
|
||||
onSaved,
|
||||
editId,
|
||||
editListId
|
||||
editListId,
|
||||
onCodeLoaded
|
||||
}) => {
|
||||
const [data, setData] = useState<IFormData>(EMPTY_DATA);
|
||||
const [requestId, setRequestId] = useState<number | undefined>(editId);
|
||||
@@ -82,6 +83,7 @@ const ReferralForm: React.FC<IRequestFormProps> = ({
|
||||
setData(loaded.data);
|
||||
setRequestStatus(loaded.status);
|
||||
setRequestCode(loaded.code || undefined);
|
||||
if (loaded.code) onCodeLoaded?.(loaded.code);
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
|
||||
@@ -37,6 +37,8 @@ interface IReferralViewProps {
|
||||
formKey: string;
|
||||
/** Партиция, где лежит ЭТА заявка — см. IApprovalViewProps.listId. */
|
||||
listId?: string;
|
||||
/** Уведомление о загруженном уникальном коде заявки — см. IApprovalViewProps.onCodeLoaded. */
|
||||
onCodeLoaded?: (code: string) => void;
|
||||
}
|
||||
|
||||
// В режиме чтения поля не редактируются, поэтому обновление — пустышка.
|
||||
@@ -45,7 +47,7 @@ const NOOP_SET: SetField = () => undefined;
|
||||
// Реферальная рекомендация только для просмотра (режим согласующего). Переиспользует
|
||||
// те же секции, что и форма подачи; редактирование выключено через
|
||||
// <FormModeProvider readOnly> — поля сами становятся неизменяемыми.
|
||||
const ReferralView: React.FC<IReferralViewProps> = ({ context, itemId, formKey, listId }) => {
|
||||
const ReferralView: React.FC<IReferralViewProps> = ({ context, itemId, formKey, listId, onCodeLoaded }) => {
|
||||
const [data, setData] = useState<IFormData>(EMPTY_DATA);
|
||||
const [status, setStatus] = useState<string>('');
|
||||
const [code, setCode] = useState<string>('');
|
||||
@@ -99,6 +101,7 @@ const ReferralView: React.FC<IReferralViewProps> = ({ context, itemId, formKey,
|
||||
setData(loaded.data);
|
||||
setStatus(loaded.status);
|
||||
setCode(loaded.code);
|
||||
onCodeLoaded?.(loaded.code);
|
||||
setError(null);
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
@@ -76,7 +76,8 @@ const Ticket1CForm: React.FC<IRequestFormProps> = ({
|
||||
onCancel,
|
||||
onSaved,
|
||||
editId,
|
||||
editListId
|
||||
editListId,
|
||||
onCodeLoaded
|
||||
}) => {
|
||||
const [data, setData] = useState<IFormData>(EMPTY_DATA);
|
||||
const [files, setFiles] = useState<File[]>([]);
|
||||
@@ -101,6 +102,7 @@ const Ticket1CForm: React.FC<IRequestFormProps> = ({
|
||||
setData(loaded.data);
|
||||
setRequestStatus(loaded.status);
|
||||
setRequestCode(loaded.code || undefined);
|
||||
if (loaded.code) onCodeLoaded?.(loaded.code);
|
||||
setExistingAttachments(atts);
|
||||
}
|
||||
})
|
||||
|
||||
@@ -49,6 +49,8 @@ interface ITicket1CViewProps {
|
||||
formKey: string;
|
||||
/** Партиция, где лежит ЭТА заявка — см. IApprovalViewProps.listId. */
|
||||
listId?: string;
|
||||
/** Уведомление о загруженном уникальном коде заявки — см. IApprovalViewProps.onCodeLoaded. */
|
||||
onCodeLoaded?: (code: string) => void;
|
||||
}
|
||||
|
||||
/** Текст карточки Planner из данных заявки; rejection — автор и причина отклонения, если есть. */
|
||||
@@ -80,7 +82,7 @@ function buildPlannerNotes(
|
||||
}
|
||||
|
||||
// Заявка в отдел 1С только для просмотра (режим согласующего).
|
||||
const Ticket1CView: React.FC<ITicket1CViewProps> = ({ context, itemId, formKey, listId }) => {
|
||||
const Ticket1CView: React.FC<ITicket1CViewProps> = ({ context, itemId, formKey, listId, onCodeLoaded }) => {
|
||||
const [data, setData] = useState<IFormData>(EMPTY_DATA);
|
||||
const [status, setStatus] = useState<string>('');
|
||||
const [code, setCode] = useState<string>('');
|
||||
@@ -116,6 +118,7 @@ const Ticket1CView: React.FC<ITicket1CViewProps> = ({ context, itemId, formKey,
|
||||
setData(loaded.data);
|
||||
setStatus(loaded.status);
|
||||
setCode(loaded.code);
|
||||
onCodeLoaded?.(loaded.code);
|
||||
setAttachments(files);
|
||||
setError(null);
|
||||
setLoading(false);
|
||||
|
||||
@@ -57,7 +57,8 @@ const TmcTransferForm: React.FC<IRequestFormProps> = ({
|
||||
onCancel,
|
||||
onSaved,
|
||||
editId,
|
||||
editListId
|
||||
editListId,
|
||||
onCodeLoaded
|
||||
}) => {
|
||||
const [data, setData] = useState<IFormData>(EMPTY_DATA);
|
||||
const [files, setFiles] = useState<File[]>([]);
|
||||
@@ -134,6 +135,7 @@ const TmcTransferForm: React.FC<IRequestFormProps> = ({
|
||||
setData(loaded.data);
|
||||
setRequestStatus(loaded.status);
|
||||
setRequestCode(loaded.code || undefined);
|
||||
if (loaded.code) onCodeLoaded?.(loaded.code);
|
||||
setExistingAttachments(atts);
|
||||
}
|
||||
})
|
||||
|
||||
@@ -49,10 +49,12 @@ interface ITmcTransferViewProps {
|
||||
formKey: string;
|
||||
/** Партиция, где лежит ЭТА заявка — см. IApprovalViewProps.listId. */
|
||||
listId?: string;
|
||||
/** Уведомление о загруженном уникальном коде заявки — см. IApprovalViewProps.onCodeLoaded. */
|
||||
onCodeLoaded?: (code: string) => void;
|
||||
}
|
||||
|
||||
// Заявка «СЗ на перемещение ТМЦ» только для просмотра (режим согласующего).
|
||||
const TmcTransferView: React.FC<ITmcTransferViewProps> = ({ context, itemId, formKey, listId }) => {
|
||||
const TmcTransferView: React.FC<ITmcTransferViewProps> = ({ context, itemId, formKey, listId, onCodeLoaded }) => {
|
||||
const [data, setData] = useState<IFormData>(EMPTY_DATA);
|
||||
const [status, setStatus] = useState<string>('');
|
||||
const [code, setCode] = useState<string>('');
|
||||
@@ -106,6 +108,7 @@ const TmcTransferView: React.FC<ITmcTransferViewProps> = ({ context, itemId, for
|
||||
setData(loaded.data);
|
||||
setStatus(loaded.status);
|
||||
setCode(loaded.code);
|
||||
onCodeLoaded?.(loaded.code);
|
||||
setAttachments(files);
|
||||
setError(null);
|
||||
setLoading(false);
|
||||
|
||||
@@ -45,7 +45,8 @@ const UnpaidLeaveForm: React.FC<IRequestFormProps> = ({
|
||||
onCancel,
|
||||
onSaved,
|
||||
editId,
|
||||
editListId
|
||||
editListId,
|
||||
onCodeLoaded
|
||||
}) => {
|
||||
const [data, setData] = useState<IFormData>(EMPTY_DATA);
|
||||
const [requestId, setRequestId] = useState<number | undefined>(editId);
|
||||
@@ -77,6 +78,7 @@ const UnpaidLeaveForm: React.FC<IRequestFormProps> = ({
|
||||
setData(loaded.data);
|
||||
setRequestStatus(loaded.status);
|
||||
setRequestCode(loaded.code || undefined);
|
||||
if (loaded.code) onCodeLoaded?.(loaded.code);
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
|
||||
@@ -31,6 +31,8 @@ interface IUnpaidLeaveViewProps {
|
||||
formKey: string;
|
||||
/** Партиция, где лежит ЭТА заявка — см. IApprovalViewProps.listId. */
|
||||
listId?: string;
|
||||
/** Уведомление о загруженном уникальном коде заявки — см. IApprovalViewProps.onCodeLoaded. */
|
||||
onCodeLoaded?: (code: string) => void;
|
||||
}
|
||||
|
||||
// В режиме чтения поля не редактируются, поэтому обновление — пустышка.
|
||||
@@ -39,7 +41,7 @@ const NOOP_SET: SetField = () => undefined;
|
||||
// Заявка без содержания только для просмотра (режим согласующего). Переиспользует
|
||||
// ту же секцию, что и форма подачи; редактирование выключено через
|
||||
// <FormModeProvider readOnly> — поля сами становятся неизменяемыми.
|
||||
const UnpaidLeaveView: React.FC<IUnpaidLeaveViewProps> = ({ context, itemId, formKey, listId }) => {
|
||||
const UnpaidLeaveView: React.FC<IUnpaidLeaveViewProps> = ({ context, itemId, formKey, listId, onCodeLoaded }) => {
|
||||
const [data, setData] = useState<IFormData>(EMPTY_DATA);
|
||||
const [status, setStatus] = useState<string>('');
|
||||
const [code, setCode] = useState<string>('');
|
||||
@@ -75,6 +77,7 @@ const UnpaidLeaveView: React.FC<IUnpaidLeaveViewProps> = ({ context, itemId, for
|
||||
setData(loaded.data);
|
||||
setStatus(loaded.status);
|
||||
setCode(loaded.code);
|
||||
onCodeLoaded?.(loaded.code);
|
||||
setError(null);
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
@@ -45,7 +45,8 @@ const VacationForm: React.FC<IRequestFormProps> = ({
|
||||
onCancel,
|
||||
onSaved,
|
||||
editId,
|
||||
editListId
|
||||
editListId,
|
||||
onCodeLoaded
|
||||
}) => {
|
||||
const [data, setData] = useState<IFormData>(EMPTY_DATA);
|
||||
const [requestId, setRequestId] = useState<number | undefined>(editId);
|
||||
@@ -77,6 +78,7 @@ const VacationForm: React.FC<IRequestFormProps> = ({
|
||||
setData(loaded.data);
|
||||
setRequestStatus(loaded.status);
|
||||
setRequestCode(loaded.code || undefined);
|
||||
if (loaded.code) onCodeLoaded?.(loaded.code);
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
|
||||
@@ -31,6 +31,8 @@ interface IVacationViewProps {
|
||||
formKey: string;
|
||||
/** Партиция, где лежит ЭТА заявка — см. IApprovalViewProps.listId. */
|
||||
listId?: string;
|
||||
/** Уведомление о загруженном уникальном коде заявки — см. IApprovalViewProps.onCodeLoaded. */
|
||||
onCodeLoaded?: (code: string) => void;
|
||||
}
|
||||
|
||||
// В режиме чтения поля не редактируются, поэтому обновление — пустышка.
|
||||
@@ -39,7 +41,7 @@ const NOOP_SET: SetField = () => undefined;
|
||||
// Заявка на отпуск только для просмотра (режим согласующего). Переиспользует ту
|
||||
// же секцию, что и форма подачи; редактирование выключено через
|
||||
// <FormModeProvider readOnly> — поля сами становятся неизменяемыми.
|
||||
const VacationView: React.FC<IVacationViewProps> = ({ context, itemId, formKey, listId }) => {
|
||||
const VacationView: React.FC<IVacationViewProps> = ({ context, itemId, formKey, listId, onCodeLoaded }) => {
|
||||
const [data, setData] = useState<IFormData>(EMPTY_DATA);
|
||||
const [status, setStatus] = useState<string>('');
|
||||
const [code, setCode] = useState<string>('');
|
||||
@@ -75,6 +77,7 @@ const VacationView: React.FC<IVacationViewProps> = ({ context, itemId, formKey,
|
||||
setData(loaded.data);
|
||||
setStatus(loaded.status);
|
||||
setCode(loaded.code);
|
||||
onCodeLoaded?.(loaded.code);
|
||||
setError(null);
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
@@ -59,7 +59,8 @@ const WorkplaceSetupForm: React.FC<IRequestFormProps> = ({
|
||||
onSaved,
|
||||
sourceId,
|
||||
editId,
|
||||
editListId
|
||||
editListId,
|
||||
onCodeLoaded
|
||||
}) => {
|
||||
const [data, setData] = useState<IFormData>(EMPTY_DATA);
|
||||
const [files, setFiles] = useState<File[]>([]);
|
||||
@@ -90,6 +91,7 @@ const WorkplaceSetupForm: React.FC<IRequestFormProps> = ({
|
||||
setData(loaded.data);
|
||||
setRequestStatus(loaded.status);
|
||||
setRequestCode(loaded.code || undefined);
|
||||
if (loaded.code) onCodeLoaded?.(loaded.code);
|
||||
setExistingAttachments(atts);
|
||||
}
|
||||
})
|
||||
|
||||
@@ -49,6 +49,8 @@ interface IWorkplaceSetupViewProps {
|
||||
formKey: string;
|
||||
/** Партиция, где лежит ЭТА заявка — см. IApprovalViewProps.listId. */
|
||||
listId?: string;
|
||||
/** Уведомление о загруженном уникальном коде заявки — см. IApprovalViewProps.onCodeLoaded. */
|
||||
onCodeLoaded?: (code: string) => void;
|
||||
}
|
||||
|
||||
type SaveState = 'idle' | 'saving' | 'saved' | 'error';
|
||||
@@ -56,7 +58,7 @@ type SaveState = 'idle' | 'saving' | 'saved' | 'error';
|
||||
// Заявка «орг. рабочего места» только для просмотра (режим согласующего).
|
||||
// Исключение: первый согласующий шаг (по маршруту — непосредственный руководитель)
|
||||
// на своём этапе может заполнить «Необходимое ПО» и «Доступы» (инициатор их не знает).
|
||||
const WorkplaceSetupView: React.FC<IWorkplaceSetupViewProps> = ({ context, itemId, formKey, listId }) => {
|
||||
const WorkplaceSetupView: React.FC<IWorkplaceSetupViewProps> = ({ context, itemId, formKey, listId, onCodeLoaded }) => {
|
||||
const [data, setData] = useState<IFormData>(EMPTY_DATA);
|
||||
const [status, setStatus] = useState<string>('');
|
||||
const [code, setCode] = useState<string>('');
|
||||
@@ -121,6 +123,7 @@ const WorkplaceSetupView: React.FC<IWorkplaceSetupViewProps> = ({ context, itemI
|
||||
setData(loaded.data);
|
||||
setStatus(loaded.status);
|
||||
setCode(loaded.code);
|
||||
onCodeLoaded?.(loaded.code);
|
||||
setAttachments(files);
|
||||
setError(null);
|
||||
setLoading(false);
|
||||
|
||||
@@ -17,6 +17,12 @@ export interface IApprovalViewProps {
|
||||
* текущую партицию типа заявки (старые ссылки без параметра).
|
||||
*/
|
||||
listId?: string;
|
||||
/**
|
||||
* Уведомление о загруженном уникальном коде заявки — нужен родителю
|
||||
* (RequestPortal) для заголовка Drawer, который рендерится ДО того, как
|
||||
* View успевает загрузить саму заявку и узнать её код.
|
||||
*/
|
||||
onCodeLoaded?: (code: string) => void;
|
||||
}
|
||||
|
||||
type ViewComponent = React.ComponentType<IApprovalViewProps>;
|
||||
|
||||
@@ -53,4 +53,11 @@ export interface IRequestFormProps {
|
||||
* форма откатывается на текущую партицию.
|
||||
*/
|
||||
editListId?: string;
|
||||
/**
|
||||
* Уведомление о загруженном уникальном коде заявки (только режим editId —
|
||||
* при загрузке существующей записи на редактирование). Нужен родителю
|
||||
* (RequestPortal) для заголовка Drawer — там до загрузки формы неизвестен
|
||||
* даже сам факт существования кода, только RowID из URL.
|
||||
*/
|
||||
onCodeLoaded?: (code: string) => void;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user