fix: черновик без маршрута планирует маршрут заново при открытии
У части черновиков не оказалось строк маршрута, и форма показывала пустую матрицу: отправить такую заявку было некому. Теперь при открытии черновика без строк маршрут планируется заново (loadRoutePhase), во всех формах; поданные заявки по-прежнему читают записанные строки. Почему строки пропали у первоначального случая — пока не выяснено. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -19,13 +19,14 @@ import {
|
||||
StatusBadge,
|
||||
useMatrixEditor,
|
||||
getPlannedMatrix,
|
||||
loadRoutePhase,
|
||||
isOpenedRouteReady,
|
||||
resolveWriteListId,
|
||||
notifyActiveStep,
|
||||
useRequestTypeId,
|
||||
REQUEST_STATUS,
|
||||
isEditableStatus,
|
||||
IApproverToWrite,
|
||||
APPROVAL_PHASE,
|
||||
unassignedStepMessage
|
||||
} from '../../shared/approval';
|
||||
import { effectiveUserEmail } from '../../shared/impersonation';
|
||||
@@ -149,16 +150,15 @@ const ClearanceForm: React.FC<IRequestFormProps> = ({
|
||||
// передана» (см. TemplateRouteService.ResolveAsync в approval-route).
|
||||
const loadMatrix = useCallback(
|
||||
() =>
|
||||
editId
|
||||
? approval
|
||||
.getMatrixForRequest(editId)
|
||||
.then((rows) => rows.filter((r) => r.phase !== APPROVAL_PHASE.execution))
|
||||
: getPlannedMatrix(context, requestTypeId as number, data.Employee, approval, 'Approval', null, [
|
||||
{ fieldName: 'Position', value: data.Position }
|
||||
]),
|
||||
[context, approval, editId, data.Employee, data.Position, requestTypeId]
|
||||
loadRoutePhase(approval, editId, requestStatus, 'Approval', () =>
|
||||
getPlannedMatrix(context, requestTypeId as number, data.Employee, approval, 'Approval', null, [
|
||||
{ fieldName: 'Position', value: data.Position }
|
||||
])
|
||||
),
|
||||
[context, approval, editId, requestStatus, data.Employee, data.Position, requestTypeId]
|
||||
);
|
||||
const matrixReady = !!editId || (!!data.Employee && !!requestTypeId);
|
||||
const matrixReady =
|
||||
isOpenedRouteReady(editId, requestStatus, requestTypeId) && (!!editId || (!!data.Employee && !!requestTypeId));
|
||||
const matrix = useMatrixEditor(
|
||||
loadMatrix,
|
||||
`${data.Employee}-${editId ?? 'new'}-${data.Position}`,
|
||||
@@ -172,14 +172,12 @@ const ClearanceForm: React.FC<IRequestFormProps> = ({
|
||||
// открытой на редактирование заявки — строки уже записаны, читаем как есть.
|
||||
const loadExecutors = useCallback(
|
||||
() =>
|
||||
editId
|
||||
? approval
|
||||
.getMatrixForRequest(editId)
|
||||
.then((rows) => rows.filter((r) => r.phase === APPROVAL_PHASE.execution))
|
||||
: getPlannedMatrix(context, requestTypeId as number, data.Employee, approval, 'Execution', null, [
|
||||
{ fieldName: 'Position', value: data.Position }
|
||||
]),
|
||||
[context, approval, editId, data.Employee, data.Position, requestTypeId]
|
||||
loadRoutePhase(approval, editId, requestStatus, 'Execution', () =>
|
||||
getPlannedMatrix(context, requestTypeId as number, data.Employee, approval, 'Execution', null, [
|
||||
{ fieldName: 'Position', value: data.Position }
|
||||
])
|
||||
),
|
||||
[context, approval, editId, requestStatus, data.Employee, data.Position, requestTypeId]
|
||||
);
|
||||
const executors = useMatrixEditor(
|
||||
loadExecutors,
|
||||
|
||||
@@ -20,6 +20,8 @@ import {
|
||||
StatusBadge,
|
||||
useMatrixEditor,
|
||||
getPlannedMatrix,
|
||||
loadRoutePhase,
|
||||
isOpenedRouteReady,
|
||||
resolveWriteListId,
|
||||
notifyActiveStep,
|
||||
useRequestTypeId,
|
||||
@@ -28,7 +30,6 @@ import {
|
||||
IApproverToWrite,
|
||||
unassignedStepMessage,
|
||||
useFormExecutors,
|
||||
approvalPhaseRows,
|
||||
executorsToWrite,
|
||||
initialSubmitStatus
|
||||
} from '../../shared/approval';
|
||||
@@ -172,13 +173,15 @@ const ConcreteRequestForm: React.FC<IRequestFormProps> = ({
|
||||
// проект не выбран (см. matrixReady). У заявки на редактировании маршрут
|
||||
// читается из уже записанных строк, поэтому проект там уже не нужен.
|
||||
const projectId = data.ProjectId || null;
|
||||
const matrixReady = !!editId || (!!data.SiteChiefEmail && !!projectId && !!requestTypeId);
|
||||
const matrixReady =
|
||||
isOpenedRouteReady(editId, requestStatus, requestTypeId) &&
|
||||
(!!editId || (!!data.SiteChiefEmail && !!projectId && !!requestTypeId));
|
||||
const loadMatrix = useCallback(
|
||||
() =>
|
||||
editId
|
||||
? approval.getMatrixForRequest(editId).then(approvalPhaseRows)
|
||||
: getPlannedMatrix(context, requestTypeId as number, data.SiteChiefEmail, approval, 'Approval', null, undefined, projectId),
|
||||
[context, approval, editId, data.SiteChiefEmail, requestTypeId, projectId]
|
||||
loadRoutePhase(approval, editId, requestStatus, 'Approval', () =>
|
||||
getPlannedMatrix(context, requestTypeId as number, data.SiteChiefEmail, approval, 'Approval', null, undefined, projectId)
|
||||
),
|
||||
[context, approval, editId, requestStatus, data.SiteChiefEmail, requestTypeId, projectId]
|
||||
);
|
||||
const matrix = useMatrixEditor(
|
||||
loadMatrix,
|
||||
@@ -197,6 +200,7 @@ const ConcreteRequestForm: React.FC<IRequestFormProps> = ({
|
||||
requestTypeId,
|
||||
userEmail: data.SiteChiefEmail,
|
||||
editId,
|
||||
requestStatus,
|
||||
projectId
|
||||
});
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ import {
|
||||
StatusBadge,
|
||||
useMatrixEditor,
|
||||
getPlannedMatrix,
|
||||
loadRoutePhase,
|
||||
isOpenedRouteReady,
|
||||
notifyActiveStep,
|
||||
useRequestTypeId,
|
||||
REQUEST_STATUS,
|
||||
@@ -27,7 +29,6 @@ import {
|
||||
IApproverToWrite,
|
||||
unassignedStepMessage,
|
||||
resolveWriteListId,
|
||||
approvalPhaseRows,
|
||||
executorsToWrite,
|
||||
initialSubmitStatus,
|
||||
useFormExecutors
|
||||
@@ -163,18 +164,18 @@ const DismissalForm: React.FC<IRequestFormProps> = ({
|
||||
// затереть правки инициатора.
|
||||
const loadMatrix = useCallback(
|
||||
() =>
|
||||
editId
|
||||
? approval.getMatrixForRequest(editId).then(approvalPhaseRows)
|
||||
: getPlannedMatrix(context, requestTypeId as number, data.Employee, approval, 'Approval', null, [
|
||||
{ fieldName: 'Position', value: primaryPosition(data.Organization) }
|
||||
]),
|
||||
[context, approval, editId, data.Employee, data.Organization, requestTypeId]
|
||||
loadRoutePhase(approval, editId, requestStatus, 'Approval', () =>
|
||||
getPlannedMatrix(context, requestTypeId as number, data.Employee, approval, 'Approval', null, [
|
||||
{ fieldName: 'Position', value: primaryPosition(data.Organization) }
|
||||
])
|
||||
),
|
||||
[context, approval, editId, requestStatus, data.Employee, data.Organization, requestTypeId]
|
||||
);
|
||||
const matrix = useMatrixEditor(
|
||||
loadMatrix,
|
||||
`${data.Employee}-${editId ?? 'new'}-${primaryPosition(data.Organization)}`,
|
||||
!readOnly,
|
||||
!!editId || (!!data.Employee && !!requestTypeId),
|
||||
isOpenedRouteReady(editId, requestStatus, requestTypeId) && (!!editId || (!!data.Employee && !!requestTypeId)),
|
||||
(login) => approval.getJobTitle(login)
|
||||
);
|
||||
|
||||
@@ -187,6 +188,7 @@ const DismissalForm: React.FC<IRequestFormProps> = ({
|
||||
requestTypeId,
|
||||
userEmail: data.Employee,
|
||||
editId,
|
||||
requestStatus,
|
||||
fieldValues: [{ fieldName: 'Position', value: primaryPosition(data.Organization) }]
|
||||
});
|
||||
|
||||
|
||||
@@ -20,10 +20,11 @@ import {
|
||||
useMatrixEditor,
|
||||
useFormExecutors,
|
||||
ExecutorsMatrix,
|
||||
approvalPhaseRows,
|
||||
executorsToWrite,
|
||||
initialSubmitStatus,
|
||||
getPlannedMatrix,
|
||||
loadRoutePhase,
|
||||
isOpenedRouteReady,
|
||||
resolveWriteListId,
|
||||
notifyActiveStep,
|
||||
useRequestTypeId,
|
||||
@@ -159,16 +160,16 @@ const EmployeeTransferForm: React.FC<IRequestFormProps> = ({
|
||||
// маршрут читается из уже записанных строк, чтобы не затереть правки инициатора.
|
||||
const loadMatrix = useCallback(
|
||||
() =>
|
||||
editId
|
||||
? approval.getMatrixForRequest(editId).then(approvalPhaseRows)
|
||||
: getPlannedMatrix(context, requestTypeId as number, data.Employee, approval, 'Approval'),
|
||||
[context, approval, editId, data.Employee, requestTypeId]
|
||||
loadRoutePhase(approval, editId, requestStatus, 'Approval', () =>
|
||||
getPlannedMatrix(context, requestTypeId as number, data.Employee, approval, 'Approval')
|
||||
),
|
||||
[context, approval, editId, requestStatus, data.Employee, requestTypeId]
|
||||
);
|
||||
const matrix = useMatrixEditor(
|
||||
loadMatrix,
|
||||
`${data.Employee}-${editId ?? 'new'}`,
|
||||
!readOnly,
|
||||
!!editId || (!!data.Employee && !!requestTypeId),
|
||||
isOpenedRouteReady(editId, requestStatus, requestTypeId) && (!!editId || (!!data.Employee && !!requestTypeId)),
|
||||
(login) => approval.getJobTitle(login)
|
||||
);
|
||||
|
||||
@@ -180,7 +181,8 @@ const EmployeeTransferForm: React.FC<IRequestFormProps> = ({
|
||||
approval,
|
||||
requestTypeId,
|
||||
userEmail: data.Employee,
|
||||
editId
|
||||
editId,
|
||||
requestStatus
|
||||
});
|
||||
|
||||
const isValid = !!(
|
||||
|
||||
@@ -28,13 +28,14 @@ import {
|
||||
useMatrixEditor,
|
||||
canEditExecutors,
|
||||
getPlannedMatrix,
|
||||
loadRoutePhase,
|
||||
isOpenedRouteReady,
|
||||
resolveWriteListId,
|
||||
notifyActiveStep,
|
||||
useRequestTypeId,
|
||||
REQUEST_STATUS,
|
||||
isEditableStatus,
|
||||
IApproverToWrite,
|
||||
APPROVAL_PHASE,
|
||||
unassignedStepMessage,
|
||||
resolveApproverOrgInfo,
|
||||
canEditRoute
|
||||
@@ -161,7 +162,7 @@ const RecruitingHireForm: React.FC<IRequestFormProps> = ({
|
||||
// (поле — мультивыбор) и ждём его выбора, как раньше.
|
||||
// Пустой Id — проект старой заявки, введённый вручную (см. projectsFromItem).
|
||||
const projectId = (data.Projects.length > 0 && data.Projects[0].Id) || null;
|
||||
const matrixReady = !!editId || (!!projectId && !!requestTypeId);
|
||||
const matrixReady = isOpenedRouteReady(editId, requestStatus, requestTypeId) &&(!!editId || (!!projectId && !!requestTypeId));
|
||||
// Несколько шагов маршрута условны по компании (см. панель «Маршруты»:
|
||||
// «CompaniesJson = TOO QAZGEOMAX», «CompaniesJson = TOO CT Global», шаг с
|
||||
// сразу ДВУМЯ условиями одновременно). Companies — мультивыбор → ОДНА запись
|
||||
@@ -180,12 +181,10 @@ const RecruitingHireForm: React.FC<IRequestFormProps> = ({
|
||||
}, [companiesFieldValue, projectsFieldValue]);
|
||||
const loadMatrix = useCallback(
|
||||
() =>
|
||||
editId
|
||||
? approval
|
||||
.getMatrixForRequest(editId)
|
||||
.then((rows) => rows.filter((r) => r.phase !== APPROVAL_PHASE.execution))
|
||||
: getPlannedMatrix(context, requestTypeId as number, userEmail, approval, 'Approval', null, fieldValues, projectId),
|
||||
[context, userEmail, approval, editId, requestTypeId, fieldValues, projectId]
|
||||
loadRoutePhase(approval, editId, requestStatus, 'Approval', () =>
|
||||
getPlannedMatrix(context, requestTypeId as number, userEmail, approval, 'Approval', null, fieldValues, projectId)
|
||||
),
|
||||
[context, userEmail, approval, editId, requestStatus, requestTypeId, fieldValues, projectId]
|
||||
);
|
||||
const matrix = useMatrixEditor(
|
||||
loadMatrix,
|
||||
@@ -200,12 +199,10 @@ const RecruitingHireForm: React.FC<IRequestFormProps> = ({
|
||||
// Фаза исполнения: исполнители из маршрута (status='Execution'), только для чтения.
|
||||
const loadExecutors = useCallback(
|
||||
() =>
|
||||
editId
|
||||
? approval
|
||||
.getMatrixForRequest(editId)
|
||||
.then((rows) => rows.filter((r) => r.phase === APPROVAL_PHASE.execution))
|
||||
: getPlannedMatrix(context, requestTypeId as number, userEmail, approval, 'Execution', null, fieldValues, projectId),
|
||||
[context, userEmail, approval, editId, requestTypeId, fieldValues, projectId]
|
||||
loadRoutePhase(approval, editId, requestStatus, 'Execution', () =>
|
||||
getPlannedMatrix(context, requestTypeId as number, userEmail, approval, 'Execution', null, fieldValues, projectId)
|
||||
),
|
||||
[context, userEmail, approval, editId, requestStatus, requestTypeId, fieldValues, projectId]
|
||||
);
|
||||
const executors = useMatrixEditor(
|
||||
loadExecutors,
|
||||
|
||||
@@ -28,6 +28,8 @@ import {
|
||||
useMatrixEditor,
|
||||
canEditExecutors,
|
||||
getPlannedMatrix,
|
||||
loadRoutePhase,
|
||||
isOpenedRouteReady,
|
||||
resolveWriteListId,
|
||||
notifyActiveStep,
|
||||
useRequestTypeId,
|
||||
@@ -36,8 +38,7 @@ import {
|
||||
IApproverToWrite,
|
||||
unassignedStepMessage,
|
||||
resolveApproverOrgInfo,
|
||||
canEditRoute,
|
||||
APPROVAL_PHASE
|
||||
canEditRoute
|
||||
} from '../../shared/approval';
|
||||
import {
|
||||
uploadAttachments,
|
||||
@@ -192,7 +193,7 @@ const RecruitingSelectionForm: React.FC<IRequestFormProps> = ({
|
||||
const projectId = data.ObjectProjectId || null;
|
||||
// Новая заявка: матрицу резолвим только когда есть и тип, и проект — иначе
|
||||
// 404 «маршрут не найден». При редактировании читаем уже записанные строки.
|
||||
const matrixReady = !!editId || (!!projectId && !!requestTypeId);
|
||||
const matrixReady = isOpenedRouteReady(editId, requestStatus, requestTypeId) &&(!!editId || (!!projectId && !!requestTypeId));
|
||||
// Условные шаги маршрута (см. [[request-portal-fieldvalues-routing]] — тот же
|
||||
// разбор на RecruitingHire): fieldName = internalName колонки. Companies —
|
||||
// мультивыбор → ОДНА запись fieldValues, value — имена выбранных компаний
|
||||
@@ -207,12 +208,10 @@ const RecruitingSelectionForm: React.FC<IRequestFormProps> = ({
|
||||
}, [companiesFieldValue, data.ObjectProject]);
|
||||
const loadMatrix = useCallback(
|
||||
() =>
|
||||
editId
|
||||
? approval
|
||||
.getMatrixForRequest(editId)
|
||||
.then((rows) => rows.filter((r) => r.phase !== APPROVAL_PHASE.execution))
|
||||
: getPlannedMatrix(context, requestTypeId as number, userEmail, approval, 'Approval', null, fieldValues, projectId),
|
||||
[context, userEmail, approval, editId, requestTypeId, fieldValues, projectId]
|
||||
loadRoutePhase(approval, editId, requestStatus, 'Approval', () =>
|
||||
getPlannedMatrix(context, requestTypeId as number, userEmail, approval, 'Approval', null, fieldValues, projectId)
|
||||
),
|
||||
[context, userEmail, approval, editId, requestStatus, requestTypeId, fieldValues, projectId]
|
||||
);
|
||||
const matrix = useMatrixEditor(
|
||||
loadMatrix,
|
||||
@@ -227,12 +226,10 @@ const RecruitingSelectionForm: React.FC<IRequestFormProps> = ({
|
||||
// Фаза исполнения: исполнители из маршрута (status='Execution'), только для чтения.
|
||||
const loadExecutors = useCallback(
|
||||
() =>
|
||||
editId
|
||||
? approval
|
||||
.getMatrixForRequest(editId)
|
||||
.then((rows) => rows.filter((r) => r.phase === APPROVAL_PHASE.execution))
|
||||
: getPlannedMatrix(context, requestTypeId as number, userEmail, approval, 'Execution', null, fieldValues, projectId),
|
||||
[context, userEmail, approval, editId, requestTypeId, fieldValues, projectId]
|
||||
loadRoutePhase(approval, editId, requestStatus, 'Execution', () =>
|
||||
getPlannedMatrix(context, requestTypeId as number, userEmail, approval, 'Execution', null, fieldValues, projectId)
|
||||
),
|
||||
[context, userEmail, approval, editId, requestStatus, requestTypeId, fieldValues, projectId]
|
||||
);
|
||||
const executors = useMatrixEditor(
|
||||
loadExecutors,
|
||||
|
||||
@@ -23,6 +23,8 @@ import {
|
||||
useMatrixEditor,
|
||||
canEditExecutors,
|
||||
getPlannedMatrix,
|
||||
loadRoutePhase,
|
||||
isOpenedRouteReady,
|
||||
notifyActiveStep,
|
||||
useRequestTypeId,
|
||||
REQUEST_STATUS,
|
||||
@@ -30,7 +32,6 @@ import {
|
||||
IApproverToWrite,
|
||||
unassignedStepMessage,
|
||||
resolveWriteListId,
|
||||
APPROVAL_PHASE,
|
||||
initialSubmitStatus,
|
||||
resolveApproverOrgInfo,
|
||||
canEditRoute
|
||||
@@ -210,18 +211,18 @@ const ReferralForm: React.FC<IRequestFormProps> = ({
|
||||
// правки инициатора.
|
||||
const loadMatrix = useCallback(
|
||||
() =>
|
||||
editId
|
||||
? approval
|
||||
.getMatrixForRequest(editId)
|
||||
.then((rows) => rows.filter((r) => r.phase !== APPROVAL_PHASE.execution))
|
||||
: getPlannedMatrix(context, requestTypeId as number, data.Referrer, approval, 'Approval'),
|
||||
[context, approval, editId, data.Referrer, requestTypeId]
|
||||
loadRoutePhase(approval, editId, requestStatus, 'Approval', () =>
|
||||
getPlannedMatrix(context, requestTypeId as number, data.Referrer, approval, 'Approval')
|
||||
),
|
||||
[context, approval, editId, requestStatus, data.Referrer, requestTypeId]
|
||||
);
|
||||
const matrixReady =
|
||||
isOpenedRouteReady(editId, requestStatus, requestTypeId) && (!!editId || (!!data.Referrer && !!requestTypeId));
|
||||
const matrix = useMatrixEditor(
|
||||
loadMatrix,
|
||||
`${data.Referrer}-${editId ?? 'new'}`,
|
||||
!readOnly,
|
||||
!!editId || (!!data.Referrer && !!requestTypeId),
|
||||
matrixReady,
|
||||
(login) => approval.getJobTitle(login),
|
||||
resolveApproverOrgInfo(context)
|
||||
);
|
||||
@@ -232,18 +233,16 @@ const ReferralForm: React.FC<IRequestFormProps> = ({
|
||||
// 'Execution' getPlannedMatrix её просто не резолвит.
|
||||
const loadExecutors = useCallback(
|
||||
() =>
|
||||
editId
|
||||
? approval
|
||||
.getMatrixForRequest(editId)
|
||||
.then((rows) => rows.filter((r) => r.phase === APPROVAL_PHASE.execution))
|
||||
: getPlannedMatrix(context, requestTypeId as number, data.Referrer, approval, 'Execution'),
|
||||
[context, approval, editId, data.Referrer, requestTypeId]
|
||||
loadRoutePhase(approval, editId, requestStatus, 'Execution', () =>
|
||||
getPlannedMatrix(context, requestTypeId as number, data.Referrer, approval, 'Execution')
|
||||
),
|
||||
[context, approval, editId, requestStatus, data.Referrer, requestTypeId]
|
||||
);
|
||||
const executors = useMatrixEditor(
|
||||
loadExecutors,
|
||||
`${data.Referrer}-${editId ?? 'new'}`,
|
||||
canEditExecutors(context, readOnly),
|
||||
!!editId || (!!data.Referrer && !!requestTypeId),
|
||||
matrixReady,
|
||||
(login) => approval.getJobTitle(login),
|
||||
resolveApproverOrgInfo(context)
|
||||
);
|
||||
|
||||
@@ -19,6 +19,8 @@ import {
|
||||
StatusBadge,
|
||||
useMatrixEditor,
|
||||
getPlannedMatrix,
|
||||
loadRoutePhase,
|
||||
isOpenedRouteReady,
|
||||
notifyActiveStep,
|
||||
useRequestTypeId,
|
||||
REQUEST_STATUS,
|
||||
@@ -28,7 +30,6 @@ import {
|
||||
resolveWriteListId,
|
||||
useFormExecutors,
|
||||
ExecutorsMatrix,
|
||||
approvalPhaseRows,
|
||||
executorsToWrite,
|
||||
initialSubmitStatus
|
||||
} from '../../shared/approval';
|
||||
@@ -183,13 +184,14 @@ const ServiceRequestForm: React.FC<IRequestFormProps> = ({
|
||||
// Маршрут зависит от проекта (см. approval-route: согласующие — руководитель
|
||||
// проекта, ПТО объекта) — пока проект не выбран, resolve вернёт 404.
|
||||
const projectId = data.ProjectId || null;
|
||||
const matrixReady = !!editId || (!!userEmail && !!projectId && !!requestTypeId);
|
||||
const matrixReady =
|
||||
isOpenedRouteReady(editId, requestStatus, requestTypeId) && (!!editId || (!!userEmail && !!projectId && !!requestTypeId));
|
||||
const loadMatrix = useCallback(
|
||||
() =>
|
||||
editId
|
||||
? approval.getMatrixForRequest(editId).then(approvalPhaseRows)
|
||||
: getPlannedMatrix(context, requestTypeId as number, userEmail, approval, 'Approval', null, undefined, projectId),
|
||||
[context, userEmail, approval, editId, projectId, requestTypeId]
|
||||
loadRoutePhase(approval, editId, requestStatus, 'Approval', () =>
|
||||
getPlannedMatrix(context, requestTypeId as number, userEmail, approval, 'Approval', null, undefined, projectId)
|
||||
),
|
||||
[context, userEmail, approval, editId, requestStatus, projectId, requestTypeId]
|
||||
);
|
||||
const matrix = useMatrixEditor(loadMatrix, `${userEmail}-${editId ?? 'new'}-${projectId}`, !readOnly, matrixReady, (login) =>
|
||||
approval.getJobTitle(login)
|
||||
@@ -203,6 +205,7 @@ const ServiceRequestForm: React.FC<IRequestFormProps> = ({
|
||||
requestTypeId,
|
||||
userEmail: matrixReady ? userEmail : '',
|
||||
editId,
|
||||
requestStatus,
|
||||
projectId
|
||||
});
|
||||
|
||||
|
||||
@@ -133,6 +133,8 @@ const SkudExplanationForm: React.FC<IRequestFormProps> = ({
|
||||
context,
|
||||
approval,
|
||||
requestId: editId,
|
||||
replanEmptyDraft: true,
|
||||
requestStatus,
|
||||
employeeEmail: data.Employee,
|
||||
requestTypeId,
|
||||
editable: !readOnly,
|
||||
|
||||
@@ -22,6 +22,8 @@ import {
|
||||
StatusBadge,
|
||||
useMatrixEditor,
|
||||
getPlannedMatrix,
|
||||
loadRoutePhase,
|
||||
isOpenedRouteReady,
|
||||
resolveWriteListId,
|
||||
notifyActiveStep,
|
||||
useRequestTypeId,
|
||||
@@ -29,7 +31,6 @@ import {
|
||||
isEditableStatus,
|
||||
IApproverToWrite,
|
||||
unassignedStepMessage,
|
||||
APPROVAL_PHASE,
|
||||
executorsToWrite
|
||||
} from '../../shared/approval';
|
||||
import {
|
||||
@@ -181,15 +182,14 @@ const Ticket1CForm: React.FC<IRequestFormProps> = ({
|
||||
[data.WorkType, data.Department]
|
||||
);
|
||||
const matrixKey = `${userEmail}-${editId ?? 'new'}-${data.WorkType}-${data.Department}`;
|
||||
const matrixReady = !!editId || (!!data.WorkType && !!requestTypeId);
|
||||
const matrixReady =
|
||||
isOpenedRouteReady(editId, requestStatus, requestTypeId) && (!!editId || (!!data.WorkType && !!requestTypeId));
|
||||
const loadMatrix = useCallback(
|
||||
() =>
|
||||
editId
|
||||
? approval
|
||||
.getMatrixForRequest(editId)
|
||||
.then((rows) => rows.filter((r) => r.phase !== APPROVAL_PHASE.execution))
|
||||
: getPlannedMatrix(context, requestTypeId as number, userEmail, approval, 'Approval', null, fieldValues),
|
||||
[context, userEmail, approval, editId, fieldValues, requestTypeId]
|
||||
loadRoutePhase(approval, editId, requestStatus, 'Approval', () =>
|
||||
getPlannedMatrix(context, requestTypeId as number, userEmail, approval, 'Approval', null, fieldValues)
|
||||
),
|
||||
[context, userEmail, approval, editId, requestStatus, fieldValues, requestTypeId]
|
||||
);
|
||||
const matrix = useMatrixEditor(loadMatrix, matrixKey, false, matrixReady, (login) => approval.getJobTitle(login));
|
||||
|
||||
@@ -197,12 +197,10 @@ const Ticket1CForm: React.FC<IRequestFormProps> = ({
|
||||
// в карточке Planner, в портале отмечает «Выполнено» (см. plannerHandoff.ts).
|
||||
const loadExecutors = useCallback(
|
||||
() =>
|
||||
editId
|
||||
? approval
|
||||
.getMatrixForRequest(editId)
|
||||
.then((rows) => rows.filter((r) => r.phase === APPROVAL_PHASE.execution))
|
||||
: getPlannedMatrix(context, requestTypeId as number, userEmail, approval, 'Execution', null, fieldValues),
|
||||
[context, userEmail, approval, editId, fieldValues, requestTypeId]
|
||||
loadRoutePhase(approval, editId, requestStatus, 'Execution', () =>
|
||||
getPlannedMatrix(context, requestTypeId as number, userEmail, approval, 'Execution', null, fieldValues)
|
||||
),
|
||||
[context, userEmail, approval, editId, requestStatus, fieldValues, requestTypeId]
|
||||
);
|
||||
const executors = useMatrixEditor(loadExecutors, matrixKey, false, matrixReady, (login) => approval.getJobTitle(login));
|
||||
// Должность нового «Руководителя» — approval-route её не знает (резолвил шаг
|
||||
|
||||
@@ -24,12 +24,13 @@ import {
|
||||
useMatrixEditor,
|
||||
canEditExecutors,
|
||||
getPlannedMatrix,
|
||||
loadRoutePhase,
|
||||
isOpenedRouteReady,
|
||||
notifyActiveStep,
|
||||
useRequestTypeId,
|
||||
REQUEST_STATUS,
|
||||
isEditableStatus,
|
||||
IApproverToWrite,
|
||||
APPROVAL_PHASE,
|
||||
unassignedStepMessage,
|
||||
resolveWriteListId
|
||||
} from '../../shared/approval';
|
||||
@@ -301,18 +302,18 @@ const TmcTransferForm: React.FC<IRequestFormProps> = ({
|
||||
// Маршрут согласования зависит от заявителя и проекта-источника («Откуда»):
|
||||
// пока не выбраны, resolve вернёт 404 — не грузим, показываем заглушку. У
|
||||
// открытой на редактирование заявки маршрут уже записан, ни то ни другое не нужно.
|
||||
const matrixReady = !!editId || (!!userEmail && !!projectId && !!requestTypeId);
|
||||
const openedReady = isOpenedRouteReady(editId, requestStatus, requestTypeId);
|
||||
const matrixReady = openedReady && (!!editId || (!!userEmail && !!projectId && !!requestTypeId));
|
||||
// Исполнитель определяется проектом-получателем («Куда»): показываем блок с
|
||||
// заглушкой, пока «Куда» не выбрано. Источник и заявитель тоже нужны, иначе resolve 404.
|
||||
const executorsReady = !!editId || (!!userEmail && !!projectId && !!targetProjectId && !!requestTypeId);
|
||||
const executorsReady =
|
||||
openedReady && (!!editId || (!!userEmail && !!projectId && !!targetProjectId && !!requestTypeId));
|
||||
const loadMatrix = useCallback(
|
||||
() =>
|
||||
editId
|
||||
? approval
|
||||
.getMatrixForRequest(editId)
|
||||
.then((rows) => rows.filter((r) => r.phase !== APPROVAL_PHASE.execution))
|
||||
: getPlannedMatrix(context, requestTypeId as number, userEmail, approval, 'Approval', null, undefined, projectId),
|
||||
[context, userEmail, approval, editId, projectId, requestTypeId]
|
||||
loadRoutePhase(approval, editId, requestStatus, 'Approval', () =>
|
||||
getPlannedMatrix(context, requestTypeId as number, userEmail, approval, 'Approval', null, undefined, projectId)
|
||||
),
|
||||
[context, userEmail, approval, editId, requestStatus, projectId, requestTypeId]
|
||||
);
|
||||
const matrix = useMatrixEditor(loadMatrix, `${userEmail}-${editId ?? 'new'}-${projectId}`, !readOnly, matrixReady, (login) =>
|
||||
approval.getJobTitle(login)
|
||||
@@ -321,12 +322,10 @@ const TmcTransferForm: React.FC<IRequestFormProps> = ({
|
||||
// Фаза исполнения: исполнители из маршрута (status='Execution'), только для чтения.
|
||||
const loadExecutors = useCallback(
|
||||
() =>
|
||||
editId
|
||||
? approval
|
||||
.getMatrixForRequest(editId)
|
||||
.then((rows) => rows.filter((r) => r.phase === APPROVAL_PHASE.execution))
|
||||
: getPlannedMatrix(context, requestTypeId as number, userEmail, approval, 'Execution', null, undefined, projectId),
|
||||
[context, userEmail, approval, editId, projectId, requestTypeId]
|
||||
loadRoutePhase(approval, editId, requestStatus, 'Execution', () =>
|
||||
getPlannedMatrix(context, requestTypeId as number, userEmail, approval, 'Execution', null, undefined, projectId)
|
||||
),
|
||||
[context, userEmail, approval, editId, requestStatus, projectId, requestTypeId]
|
||||
);
|
||||
const executors = useMatrixEditor(
|
||||
loadExecutors,
|
||||
|
||||
@@ -22,10 +22,11 @@ import {
|
||||
StatusBadge,
|
||||
useMatrixEditor,
|
||||
useFormExecutors,
|
||||
approvalPhaseRows,
|
||||
executorsToWrite,
|
||||
initialSubmitStatus,
|
||||
getPlannedMatrix,
|
||||
loadRoutePhase,
|
||||
isOpenedRouteReady,
|
||||
notifyActiveStep,
|
||||
useRequestTypeId,
|
||||
REQUEST_STATUS,
|
||||
@@ -162,16 +163,16 @@ const UnpaidLeaveForm: React.FC<IRequestFormProps> = ({
|
||||
// маршрут читается из уже записанных строк, чтобы не затереть правки инициатора.
|
||||
const loadMatrix = useCallback(
|
||||
() =>
|
||||
editId
|
||||
? approval.getMatrixForRequest(editId).then(approvalPhaseRows)
|
||||
: getPlannedMatrix(context, requestTypeId as number, data.Employee, approval, 'Approval'),
|
||||
[context, approval, editId, data.Employee, requestTypeId]
|
||||
loadRoutePhase(approval, editId, requestStatus, 'Approval', () =>
|
||||
getPlannedMatrix(context, requestTypeId as number, data.Employee, approval, 'Approval')
|
||||
),
|
||||
[context, approval, editId, requestStatus, data.Employee, requestTypeId]
|
||||
);
|
||||
const matrix = useMatrixEditor(
|
||||
loadMatrix,
|
||||
`${data.Employee}-${editId ?? 'new'}`,
|
||||
!readOnly,
|
||||
!!editId || (!!data.Employee && !!requestTypeId),
|
||||
isOpenedRouteReady(editId, requestStatus, requestTypeId) && (!!editId || (!!data.Employee && !!requestTypeId)),
|
||||
(login) => approval.getJobTitle(login)
|
||||
);
|
||||
|
||||
@@ -182,7 +183,8 @@ const UnpaidLeaveForm: React.FC<IRequestFormProps> = ({
|
||||
approval,
|
||||
requestTypeId,
|
||||
userEmail: data.Employee,
|
||||
editId
|
||||
editId,
|
||||
requestStatus
|
||||
});
|
||||
|
||||
// Проблемы полей (см. validation.ts) подсвечиваются под полями через FieldIssuesProvider.
|
||||
|
||||
@@ -20,10 +20,11 @@ import {
|
||||
useMatrixEditor,
|
||||
useFormExecutors,
|
||||
ExecutorsMatrix,
|
||||
approvalPhaseRows,
|
||||
executorsToWrite,
|
||||
initialSubmitStatus,
|
||||
getPlannedMatrix,
|
||||
loadRoutePhase,
|
||||
isOpenedRouteReady,
|
||||
resolveWriteListId,
|
||||
notifyActiveStep,
|
||||
useRequestTypeId,
|
||||
@@ -170,16 +171,16 @@ const VacationForm: React.FC<IRequestFormProps> = ({
|
||||
// маршрут читается из уже записанных строк, чтобы не затереть правки инициатора.
|
||||
const loadMatrix = useCallback(
|
||||
() =>
|
||||
editId
|
||||
? approval.getMatrixForRequest(editId).then(approvalPhaseRows)
|
||||
: getPlannedMatrix(context, requestTypeId as number, data.Employee, approval, 'Approval'),
|
||||
[context, approval, editId, data.Employee, requestTypeId]
|
||||
loadRoutePhase(approval, editId, requestStatus, 'Approval', () =>
|
||||
getPlannedMatrix(context, requestTypeId as number, data.Employee, approval, 'Approval')
|
||||
),
|
||||
[context, approval, editId, requestStatus, data.Employee, requestTypeId]
|
||||
);
|
||||
const matrix = useMatrixEditor(
|
||||
loadMatrix,
|
||||
`${data.Employee}-${editId ?? 'new'}`,
|
||||
!readOnly,
|
||||
!!editId || (!!data.Employee && !!requestTypeId),
|
||||
isOpenedRouteReady(editId, requestStatus, requestTypeId) && (!!editId || (!!data.Employee && !!requestTypeId)),
|
||||
(login) => approval.getJobTitle(login)
|
||||
);
|
||||
|
||||
@@ -191,7 +192,8 @@ const VacationForm: React.FC<IRequestFormProps> = ({
|
||||
approval,
|
||||
requestTypeId,
|
||||
userEmail: data.Employee,
|
||||
editId
|
||||
editId,
|
||||
requestStatus
|
||||
});
|
||||
|
||||
const daysNum = Number(data.DaysCount);
|
||||
|
||||
@@ -27,13 +27,14 @@ import {
|
||||
useMatrixEditor,
|
||||
canEditExecutors,
|
||||
getPlannedMatrix,
|
||||
loadRoutePhase,
|
||||
isOpenedRouteReady,
|
||||
resolveWriteListId,
|
||||
notifyActiveStep,
|
||||
useRequestTypeId,
|
||||
REQUEST_STATUS,
|
||||
isEditableStatus,
|
||||
IApproverToWrite,
|
||||
APPROVAL_PHASE,
|
||||
IResolveFieldValue,
|
||||
unassignedStepMessage
|
||||
} from '../../shared/approval';
|
||||
@@ -182,36 +183,33 @@ const WorkplaceSetupForm: React.FC<IRequestFormProps> = ({
|
||||
// вручную при первом сохранении, и планирование затёрло бы эти правки.
|
||||
const loadMatrix = useCallback(
|
||||
() =>
|
||||
editId
|
||||
? approval
|
||||
.getMatrixForRequest(editId)
|
||||
.then((rows) => rows.filter((r) => r.phase !== APPROVAL_PHASE.execution))
|
||||
: getPlannedMatrix(context, requestTypeId as number, userEmail, approval, 'Approval', data.DepartmentId, fieldValues),
|
||||
[context, userEmail, approval, editId, data.DepartmentId, requestTypeId, fieldValues]
|
||||
loadRoutePhase(approval, editId, requestStatus, 'Approval', () =>
|
||||
getPlannedMatrix(context, requestTypeId as number, userEmail, approval, 'Approval', data.DepartmentId, fieldValues)
|
||||
),
|
||||
[context, userEmail, approval, editId, requestStatus, data.DepartmentId, requestTypeId, fieldValues]
|
||||
);
|
||||
const matrixReady = isOpenedRouteReady(editId, requestStatus, requestTypeId) && (!!editId || !!requestTypeId);
|
||||
const matrix = useMatrixEditor(
|
||||
loadMatrix,
|
||||
matrixKey,
|
||||
!readOnly,
|
||||
!!editId || !!requestTypeId,
|
||||
matrixReady,
|
||||
(login) => approval.getJobTitle(login)
|
||||
);
|
||||
|
||||
// Фаза исполнения: исполнители из маршрута (status='Execution'), только для чтения.
|
||||
const loadExecutors = useCallback(
|
||||
() =>
|
||||
editId
|
||||
? approval
|
||||
.getMatrixForRequest(editId)
|
||||
.then((rows) => rows.filter((r) => r.phase === APPROVAL_PHASE.execution))
|
||||
: getPlannedMatrix(context, requestTypeId as number, userEmail, approval, 'Execution', data.DepartmentId, fieldValues),
|
||||
[context, userEmail, approval, editId, data.DepartmentId, requestTypeId, fieldValues]
|
||||
loadRoutePhase(approval, editId, requestStatus, 'Execution', () =>
|
||||
getPlannedMatrix(context, requestTypeId as number, userEmail, approval, 'Execution', data.DepartmentId, fieldValues)
|
||||
),
|
||||
[context, userEmail, approval, editId, requestStatus, data.DepartmentId, requestTypeId, fieldValues]
|
||||
);
|
||||
const executors = useMatrixEditor(
|
||||
loadExecutors,
|
||||
matrixKey,
|
||||
canEditExecutors(context, readOnly),
|
||||
!!editId || !!requestTypeId,
|
||||
matrixReady,
|
||||
(login) => approval.getJobTitle(login)
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user