// Домен вкладки «Редактирование заявок»: живёт целиком в SharePoint-списках // «<форма> — данные» / «<форма> — согласование», которыми управляет // request-portal (см. request_type.list_id/site_url — ссылки именно на список // данных; список согласования вычисляется по конвенции имени, см. approvalListTitle // в requestManageService.ts). Это НЕ сущности Tnsu.ApprovalRoute.Api — совпадений // с models/templateRoutes.ts нет, здесь другое хранилище. // // Значения статусов — Choice-колонки SharePoint, 1:1 с // request-portal/src/webparts/requestPortal/shared/approval/models/statuses.ts // (тот же самый список, то же самое хранилище — просто другой клиент). export const REQUEST_STATUS = { draft: 'Черновик', onApproval: 'На согласовании', queued: 'Ждёт очереди', onExecution: 'На исполнении', executed: 'Выполнено', approved: 'Согласовано', rejected: 'Отклонено', returned: 'Возвращена на доработку', execution: 'Выполнение', closed: 'Закрыта' } as const; export const APPROVAL_PHASE = { approval: 'Согласование', execution: 'Исполнение' } as const; // Строка маршрута в одном из этих статусов ЕЩЁ НЕ решена согласующим/исполнителем // ОКОНЧАТЕЛЬНО — её можно менять (переназначить человека, удалить, переставить, // добавить новую рядом). «Возвращена на доработку» сюда включена нарочно: это не // финальное решение (заявка вернётся на новый круг после доработки), поэтому // согласующего на этом шаге всё ещё можно переназначить. approved/executed/ // rejected — финальные решения, трогать нельзя ни при каких условиях. const EDITABLE_ROW_STATUSES: string[] = [ REQUEST_STATUS.draft, REQUEST_STATUS.queued, REQUEST_STATUS.onApproval, REQUEST_STATUS.onExecution, REQUEST_STATUS.returned ]; export function isEditableRowStatus(status: string): boolean { return EDITABLE_ROW_STATUSES.indexOf(status) !== -1; } // Заявка в этом статусе прошла полностью (все фазы завершены) — маршрут можно // только посмотреть, редактирование выключается целиком независимо от статусов // отдельных строк. export function isFullyClosedRequestStatus(status: string): boolean { return status === REQUEST_STATUS.closed; } export interface ManagedRequestSummary { id: number; title: string; status: string; created: string; // ISO authorName: string; } export interface ManagedRequestPage { items: ManagedRequestSummary[]; hasMore: boolean; } // Строка списка «… — согласование». approverId/approverEmail нужны и для // отображения, и как исходное значение при открытии формы переназначения. export interface ManagedApprovalRow { id: number; ticketId: number; // eslint-disable-next-line @rushstack/no-new-null -- lookup-поле SharePoint, у ghost-строки (см. handleAddApprover) значения ещё нет approverId: number | null; approverName: string; approverEmail: string; position: string; status: string; date: string; comment: string; order: number; allowReassign: boolean; phase: string; } export interface ManagedRequestMatrix { request: ManagedRequestSummary; /** Абсолютный URL сайта, где лежат списки данных/согласования этого типа заявки. */ siteUrl: string; /** Title списка «… — согласование» (вычислен из Title списка данных). */ approvalListTitle: string; /** Обе фазы вместе, упорядочены по StepOrder. */ rows: ManagedApprovalRow[]; }