import { useCallback } from 'react'; import { WebPartContext } from '@microsoft/sp-webpart-base'; import { APPROVAL_PHASE } from './models/statuses'; import { IMatrixRow } from './models/IMatrixRow'; import { ApprovalListService } from './approvalList.service'; import { getPlannedMatrix } from './approvalSubmission.service'; import { resolveApproverOrgInfo } from './approverOrgInfo'; import { useMatrixEditor } from './useMatrixEditor'; type MatrixEditor = ReturnType; export interface IPhasedRoute { /** Согласующие — редактируемы заявителем в новой заявке / черновике / доработке. */ approvers: MatrixEditor; /** Исполнители по маршруту (фаза «Исполнение») — только чтение, кроме редактора маршрута. */ executors: MatrixEditor; } interface IRouteSource { context: WebPartContext; approval: ApprovalListService; /** Заявка уже записана — маршрут читаем из её строк, а не планируем заново. */ requestId: number | undefined; /** E-mail сотрудника, по которому резолвится планируемый маршрут. */ employeeEmail: string; requestTypeId: number | undefined; /** Можно ли править согласующих. */ editable: boolean; /** Можно ли править исполнителей (только редактору маршрута, см. canEditExecutors). */ executorsEditable?: boolean; /** Меняется после решения согласующего — перечитать строки. */ reloadSeq?: number; } const byPhase = (execution: boolean): ((rows: IMatrixRow[]) => IMatrixRow[]) => (rows: IMatrixRow[]): IMatrixRow[] => rows.filter((r) => (r.phase === APPROVAL_PHASE.execution) === execution); /** * Маршрут заявки по двум фазам: согласование + исполнение. Без отдельного * запроса фазы 'Execution' getPlannedMatrix исполнителей не резолвит — шаг * исполнения из маршрута «пропадал» бы. Маршрут настраивают в админке * approval-route, форма его только получает. */ export function usePhasedRoute(source: IRouteSource): IPhasedRoute { const { context, approval, requestId, employeeEmail, requestTypeId, editable, executorsEditable = false, reloadSeq = 0 } = source; const canLoad = !!requestId || (!!employeeEmail && !!requestTypeId); const reloadKey = `${employeeEmail}-${requestId ?? 'new'}-${reloadSeq}`; const loadPhase = useCallback( (execution: boolean) => requestId ? approval.getMatrixForRequest(requestId).then(byPhase(execution)) : getPlannedMatrix( context, requestTypeId as number, employeeEmail, approval, execution ? 'Execution' : 'Approval' ), [context, approval, requestId, employeeEmail, requestTypeId] ); const loadApprovers = useCallback(() => loadPhase(false), [loadPhase]); const loadExecutors = useCallback(() => loadPhase(true), [loadPhase]); const jobTitle = (login: string): Promise => approval.getJobTitle(login); const approvers = useMatrixEditor(loadApprovers, reloadKey, editable, canLoad, jobTitle, resolveApproverOrgInfo(context)); const executors = useMatrixEditor(loadExecutors, reloadKey, executorsEditable, canLoad, jobTitle, resolveApproverOrgInfo(context)); return { approvers, executors }; }