diff --git a/src/webparts/requestPortal/forms/Clearance/ClearanceForm.tsx b/src/webparts/requestPortal/forms/Clearance/ClearanceForm.tsx index 1f61330..db25869 100644 --- a/src/webparts/requestPortal/forms/Clearance/ClearanceForm.tsx +++ b/src/webparts/requestPortal/forms/Clearance/ClearanceForm.tsx @@ -201,7 +201,8 @@ const ClearanceForm: React.FC = ({ // Транзитом из маршрута в строку списка: наследование бэкенд применил // при resolve, форма только переносит значения (см. IMatrixRow.slaHours). slaHours: r.slaHours, - askOverdueReason: r.askOverdueReason + askOverdueReason: r.askOverdueReason, + autoApprove: r.autoApprove })); const save = (status: string): (() => Promise) => async (): Promise => { diff --git a/src/webparts/requestPortal/forms/Clearance/approval/provisioning.json b/src/webparts/requestPortal/forms/Clearance/approval/provisioning.json index 5395c52..606125e 100644 --- a/src/webparts/requestPortal/forms/Clearance/approval/provisioning.json +++ b/src/webparts/requestPortal/forms/Clearance/approval/provisioning.json @@ -11,6 +11,7 @@ { "internalName": "Phase", "title": "Фаза", "type": "Choice", "choices": ["Согласование", "Исполнение"] }, { "internalName": "SLAhours", "title": "SLA, часов", "type": "Number" }, { "internalName": "AskOverdueReason", "title": "Опрос причины просрочки", "type": "Boolean" }, + { "internalName": "AutoApprove", "title": "Автосогласование", "type": "Boolean" }, { "internalName": "DelegatedBy", "title": "Кем переназначено", "type": "User", "userSelectionMode": "PeopleOnly" } ] } diff --git a/src/webparts/requestPortal/forms/ConcreteRequest/ConcreteRequestForm.tsx b/src/webparts/requestPortal/forms/ConcreteRequest/ConcreteRequestForm.tsx index 2536cc4..3cf1c92 100644 --- a/src/webparts/requestPortal/forms/ConcreteRequest/ConcreteRequestForm.tsx +++ b/src/webparts/requestPortal/forms/ConcreteRequest/ConcreteRequestForm.tsx @@ -199,7 +199,8 @@ const ConcreteRequestForm: React.FC = ({ // Транзитом из маршрута в строку списка: наследование бэкенд применил // при resolve, форма только переносит значения (см. IMatrixRow.slaHours). slaHours: r.slaHours, - askOverdueReason: r.askOverdueReason + askOverdueReason: r.askOverdueReason, + autoApprove: r.autoApprove })); const save = (status: string): (() => Promise) => async (): Promise => { diff --git a/src/webparts/requestPortal/forms/ConcreteRequest/approval/provisioning.json b/src/webparts/requestPortal/forms/ConcreteRequest/approval/provisioning.json index aa70b8d..750ca20 100644 --- a/src/webparts/requestPortal/forms/ConcreteRequest/approval/provisioning.json +++ b/src/webparts/requestPortal/forms/ConcreteRequest/approval/provisioning.json @@ -11,6 +11,7 @@ { "internalName": "Phase", "title": "Фаза", "type": "Choice", "choices": ["Согласование", "Исполнение"] }, { "internalName": "SLAhours", "title": "SLA, часов", "type": "Number" }, { "internalName": "AskOverdueReason", "title": "Опрос причины просрочки", "type": "Boolean" }, + { "internalName": "AutoApprove", "title": "Автосогласование", "type": "Boolean" }, { "internalName": "DelegatedBy", "title": "Кем переназначено", "type": "User", "userSelectionMode": "PeopleOnly" } ] } diff --git a/src/webparts/requestPortal/forms/Dismissal/DismissalForm.tsx b/src/webparts/requestPortal/forms/Dismissal/DismissalForm.tsx index 2be4313..4663c71 100644 --- a/src/webparts/requestPortal/forms/Dismissal/DismissalForm.tsx +++ b/src/webparts/requestPortal/forms/Dismissal/DismissalForm.tsx @@ -222,7 +222,8 @@ const DismissalForm: React.FC = ({ // Транзитом из маршрута в строку списка: наследование бэкенд применил // при resolve, форма только переносит значения (см. IMatrixRow.slaHours). slaHours: r.slaHours, - askOverdueReason: r.askOverdueReason + askOverdueReason: r.askOverdueReason, + autoApprove: r.autoApprove })); const save = (status: string): (() => Promise) => async (): Promise => { diff --git a/src/webparts/requestPortal/forms/Dismissal/approval/provisioning.json b/src/webparts/requestPortal/forms/Dismissal/approval/provisioning.json index 5244649..9041e91 100644 --- a/src/webparts/requestPortal/forms/Dismissal/approval/provisioning.json +++ b/src/webparts/requestPortal/forms/Dismissal/approval/provisioning.json @@ -11,6 +11,7 @@ { "internalName": "Phase", "title": "Фаза", "type": "Choice", "choices": ["Согласование", "Исполнение"] }, { "internalName": "SLAhours", "title": "SLA, часов", "type": "Number" }, { "internalName": "AskOverdueReason", "title": "Опрос причины просрочки", "type": "Boolean" }, + { "internalName": "AutoApprove", "title": "Автосогласование", "type": "Boolean" }, { "internalName": "DelegatedBy", "title": "Кем переназначено", "type": "User", "userSelectionMode": "PeopleOnly" } ] } diff --git a/src/webparts/requestPortal/forms/Dismissal/createClearance.ts b/src/webparts/requestPortal/forms/Dismissal/createClearance.ts index c51dea6..421655a 100644 --- a/src/webparts/requestPortal/forms/Dismissal/createClearance.ts +++ b/src/webparts/requestPortal/forms/Dismissal/createClearance.ts @@ -46,7 +46,8 @@ function toApprovers(rows: IMatrixRow[]): IApproverToWrite[] { allowReassign: r.allowReassign, order: r.order, slaHours: r.slaHours, - askOverdueReason: r.askOverdueReason + askOverdueReason: r.askOverdueReason, + autoApprove: r.autoApprove })); } diff --git a/src/webparts/requestPortal/forms/EmployeeTransfer/EmployeeTransferForm.tsx b/src/webparts/requestPortal/forms/EmployeeTransfer/EmployeeTransferForm.tsx index fe53d62..4edb360 100644 --- a/src/webparts/requestPortal/forms/EmployeeTransfer/EmployeeTransferForm.tsx +++ b/src/webparts/requestPortal/forms/EmployeeTransfer/EmployeeTransferForm.tsx @@ -188,7 +188,8 @@ const EmployeeTransferForm: React.FC = ({ // Транзитом из маршрута в строку списка: наследование бэкенд применил // при resolve, форма только переносит значения (см. IMatrixRow.slaHours). slaHours: r.slaHours, - askOverdueReason: r.askOverdueReason + askOverdueReason: r.askOverdueReason, + autoApprove: r.autoApprove })); const save = (status: string): (() => Promise) => async (): Promise => { diff --git a/src/webparts/requestPortal/forms/EmployeeTransfer/approval/provisioning.json b/src/webparts/requestPortal/forms/EmployeeTransfer/approval/provisioning.json index 04202a6..89c5b4c 100644 --- a/src/webparts/requestPortal/forms/EmployeeTransfer/approval/provisioning.json +++ b/src/webparts/requestPortal/forms/EmployeeTransfer/approval/provisioning.json @@ -11,6 +11,7 @@ { "internalName": "Phase", "title": "Фаза", "type": "Choice", "choices": ["Согласование", "Исполнение"] }, { "internalName": "SLAhours", "title": "SLA, часов", "type": "Number" }, { "internalName": "AskOverdueReason", "title": "Опрос причины просрочки", "type": "Boolean" }, + { "internalName": "AutoApprove", "title": "Автосогласование", "type": "Boolean" }, { "internalName": "DelegatedBy", "title": "Кем переназначено", "type": "User", "userSelectionMode": "PeopleOnly" } ] } diff --git a/src/webparts/requestPortal/forms/RecruitingHire/RecruitingHireForm.tsx b/src/webparts/requestPortal/forms/RecruitingHire/RecruitingHireForm.tsx index 94287db..b4651b2 100644 --- a/src/webparts/requestPortal/forms/RecruitingHire/RecruitingHireForm.tsx +++ b/src/webparts/requestPortal/forms/RecruitingHire/RecruitingHireForm.tsx @@ -214,6 +214,7 @@ const RecruitingHireForm: React.FC = ({ // при resolve, форма только переносит значения (см. IMatrixRow.slaHours). slaHours: r.slaHours, askOverdueReason: r.askOverdueReason, + autoApprove: r.autoApprove })); // Удаление уже прикреплённого файла (в правке) — сразу из заявки. diff --git a/src/webparts/requestPortal/forms/RecruitingHire/approval/provisioning.json b/src/webparts/requestPortal/forms/RecruitingHire/approval/provisioning.json index 26dd879..557401f 100644 --- a/src/webparts/requestPortal/forms/RecruitingHire/approval/provisioning.json +++ b/src/webparts/requestPortal/forms/RecruitingHire/approval/provisioning.json @@ -11,6 +11,7 @@ { "internalName": "Phase", "title": "Фаза", "type": "Choice", "choices": ["Согласование", "Исполнение"] }, { "internalName": "SLAhours", "title": "SLA, часов", "type": "Number" }, { "internalName": "AskOverdueReason", "title": "Опрос причины просрочки", "type": "Boolean" }, + { "internalName": "AutoApprove", "title": "Автосогласование", "type": "Boolean" }, { "internalName": "DelegatedBy", "title": "Кем переназначено", "type": "User", "userSelectionMode": "PeopleOnly" } ] } diff --git a/src/webparts/requestPortal/forms/RecruitingSelection/RecruitingSelectionForm.tsx b/src/webparts/requestPortal/forms/RecruitingSelection/RecruitingSelectionForm.tsx index c7565ff..cc358be 100644 --- a/src/webparts/requestPortal/forms/RecruitingSelection/RecruitingSelectionForm.tsx +++ b/src/webparts/requestPortal/forms/RecruitingSelection/RecruitingSelectionForm.tsx @@ -224,7 +224,8 @@ const RecruitingSelectionForm: React.FC = ({ // Транзитом из маршрута в строку списка: наследование бэкенд применил // при resolve, форма только переносит значения (см. IMatrixRow.slaHours). slaHours: r.slaHours, - askOverdueReason: r.askOverdueReason + askOverdueReason: r.askOverdueReason, + autoApprove: r.autoApprove })); const handleRemoveAttachment = (fileName: string): void => { diff --git a/src/webparts/requestPortal/forms/RecruitingSelection/approval/provisioning.json b/src/webparts/requestPortal/forms/RecruitingSelection/approval/provisioning.json index 9707088..6ed944a 100644 --- a/src/webparts/requestPortal/forms/RecruitingSelection/approval/provisioning.json +++ b/src/webparts/requestPortal/forms/RecruitingSelection/approval/provisioning.json @@ -11,6 +11,7 @@ { "internalName": "Phase", "title": "Фаза", "type": "Choice", "choices": ["Согласование", "Исполнение"] }, { "internalName": "SLAhours", "title": "SLA, часов", "type": "Number" }, { "internalName": "AskOverdueReason", "title": "Опрос причины просрочки", "type": "Boolean" }, + { "internalName": "AutoApprove", "title": "Автосогласование", "type": "Boolean" }, { "internalName": "DelegatedBy", "title": "Кем переназначено", "type": "User", "userSelectionMode": "PeopleOnly" } ] } diff --git a/src/webparts/requestPortal/forms/Referral/ReferralForm.tsx b/src/webparts/requestPortal/forms/Referral/ReferralForm.tsx index c5f31ed..30b09c6 100644 --- a/src/webparts/requestPortal/forms/Referral/ReferralForm.tsx +++ b/src/webparts/requestPortal/forms/Referral/ReferralForm.tsx @@ -268,7 +268,8 @@ const ReferralForm: React.FC = ({ // Транзитом из маршрута в строку списка: наследование бэкенд применил // при resolve, форма только переносит значения (см. IMatrixRow.slaHours). slaHours: r.slaHours, - askOverdueReason: r.askOverdueReason + askOverdueReason: r.askOverdueReason, + autoApprove: r.autoApprove })); const save = (status: string): (() => Promise) => async (): Promise => { diff --git a/src/webparts/requestPortal/forms/Referral/approval/provisioning.json b/src/webparts/requestPortal/forms/Referral/approval/provisioning.json index 4e58915..6937bcf 100644 --- a/src/webparts/requestPortal/forms/Referral/approval/provisioning.json +++ b/src/webparts/requestPortal/forms/Referral/approval/provisioning.json @@ -11,6 +11,7 @@ { "internalName": "Phase", "title": "Фаза", "type": "Choice", "choices": ["Согласование", "Исполнение"] }, { "internalName": "SLAhours", "title": "SLA, часов", "type": "Number" }, { "internalName": "AskOverdueReason", "title": "Опрос причины просрочки", "type": "Boolean" }, + { "internalName": "AutoApprove", "title": "Автосогласование", "type": "Boolean" }, { "internalName": "DelegatedBy", "title": "Кем переназначено", "type": "User", "userSelectionMode": "PeopleOnly" } ] } diff --git a/src/webparts/requestPortal/forms/ServiceRequest/approval/provisioning.json b/src/webparts/requestPortal/forms/ServiceRequest/approval/provisioning.json index eafb929..1f7e447 100644 --- a/src/webparts/requestPortal/forms/ServiceRequest/approval/provisioning.json +++ b/src/webparts/requestPortal/forms/ServiceRequest/approval/provisioning.json @@ -11,6 +11,7 @@ { "internalName": "Phase", "title": "Фаза", "type": "Choice", "choices": ["Согласование", "Исполнение"] }, { "internalName": "SLAhours", "title": "SLA, часов", "type": "Number" }, { "internalName": "AskOverdueReason", "title": "Опрос причины просрочки", "type": "Boolean" }, + { "internalName": "AutoApprove", "title": "Автосогласование", "type": "Boolean" }, { "internalName": "DelegatedBy", "title": "Кем переназначено", "type": "User", "userSelectionMode": "PeopleOnly" } ] } diff --git a/src/webparts/requestPortal/forms/Ticket1C/Ticket1CForm.tsx b/src/webparts/requestPortal/forms/Ticket1C/Ticket1CForm.tsx index 3084a37..78920d2 100644 --- a/src/webparts/requestPortal/forms/Ticket1C/Ticket1CForm.tsx +++ b/src/webparts/requestPortal/forms/Ticket1C/Ticket1CForm.tsx @@ -208,7 +208,8 @@ const Ticket1CForm: React.FC = ({ // Транзитом из маршрута в строку списка: наследование бэкенд применил // при resolve, форма только переносит значения (см. IMatrixRow.slaHours). slaHours: r.slaHours, - askOverdueReason: r.askOverdueReason + askOverdueReason: r.askOverdueReason, + autoApprove: r.autoApprove })); const handleRemoveAttachment = (fileName: string): void => { diff --git a/src/webparts/requestPortal/forms/Ticket1C/approval/provisioning.json b/src/webparts/requestPortal/forms/Ticket1C/approval/provisioning.json index d144c07..a8561d0 100644 --- a/src/webparts/requestPortal/forms/Ticket1C/approval/provisioning.json +++ b/src/webparts/requestPortal/forms/Ticket1C/approval/provisioning.json @@ -11,6 +11,7 @@ { "internalName": "Phase", "title": "Фаза", "type": "Choice", "choices": ["Согласование", "Исполнение"] }, { "internalName": "SLAhours", "title": "SLA, часов", "type": "Number" }, { "internalName": "AskOverdueReason", "title": "Опрос причины просрочки", "type": "Boolean" }, + { "internalName": "AutoApprove", "title": "Автосогласование", "type": "Boolean" }, { "internalName": "DelegatedBy", "title": "Кем переназначено", "type": "User", "userSelectionMode": "PeopleOnly" } ] } diff --git a/src/webparts/requestPortal/forms/TmcTransfer/approval/provisioning.json b/src/webparts/requestPortal/forms/TmcTransfer/approval/provisioning.json index 3ebe166..356ee53 100644 --- a/src/webparts/requestPortal/forms/TmcTransfer/approval/provisioning.json +++ b/src/webparts/requestPortal/forms/TmcTransfer/approval/provisioning.json @@ -11,6 +11,7 @@ { "internalName": "Phase", "title": "Фаза", "type": "Choice", "choices": ["Согласование", "Исполнение"] }, { "internalName": "SLAhours", "title": "SLA, часов", "type": "Number" }, { "internalName": "AskOverdueReason", "title": "Опрос причины просрочки", "type": "Boolean" }, + { "internalName": "AutoApprove", "title": "Автосогласование", "type": "Boolean" }, { "internalName": "DelegatedBy", "title": "Кем переназначено", "type": "User", "userSelectionMode": "PeopleOnly" } ] } diff --git a/src/webparts/requestPortal/forms/UnpaidLeave/UnpaidLeaveForm.tsx b/src/webparts/requestPortal/forms/UnpaidLeave/UnpaidLeaveForm.tsx index 3dcd50e..d474441 100644 --- a/src/webparts/requestPortal/forms/UnpaidLeave/UnpaidLeaveForm.tsx +++ b/src/webparts/requestPortal/forms/UnpaidLeave/UnpaidLeaveForm.tsx @@ -200,7 +200,8 @@ const UnpaidLeaveForm: React.FC = ({ // Транзитом из маршрута в строку списка: наследование бэкенд применил // при resolve, форма только переносит значения (см. IMatrixRow.slaHours). slaHours: r.slaHours, - askOverdueReason: r.askOverdueReason + askOverdueReason: r.askOverdueReason, + autoApprove: r.autoApprove })); const save = (status: string): (() => Promise) => async (): Promise => { diff --git a/src/webparts/requestPortal/forms/UnpaidLeave/approval/provisioning.json b/src/webparts/requestPortal/forms/UnpaidLeave/approval/provisioning.json index cac6582..a7bafb1 100644 --- a/src/webparts/requestPortal/forms/UnpaidLeave/approval/provisioning.json +++ b/src/webparts/requestPortal/forms/UnpaidLeave/approval/provisioning.json @@ -11,6 +11,7 @@ { "internalName": "Phase", "title": "Фаза", "type": "Choice", "choices": ["Согласование", "Исполнение"] }, { "internalName": "SLAhours", "title": "SLA, часов", "type": "Number" }, { "internalName": "AskOverdueReason", "title": "Опрос причины просрочки", "type": "Boolean" }, + { "internalName": "AutoApprove", "title": "Автосогласование", "type": "Boolean" }, { "internalName": "DelegatedBy", "title": "Кем переназначено", "type": "User", "userSelectionMode": "PeopleOnly" } ] } diff --git a/src/webparts/requestPortal/forms/Vacation/VacationForm.tsx b/src/webparts/requestPortal/forms/Vacation/VacationForm.tsx index 909697a..a689433 100644 --- a/src/webparts/requestPortal/forms/Vacation/VacationForm.tsx +++ b/src/webparts/requestPortal/forms/Vacation/VacationForm.tsx @@ -198,7 +198,8 @@ const VacationForm: React.FC = ({ // Транзитом из маршрута в строку списка: наследование бэкенд применил // при resolve, форма только переносит значения (см. IMatrixRow.slaHours). slaHours: r.slaHours, - askOverdueReason: r.askOverdueReason + askOverdueReason: r.askOverdueReason, + autoApprove: r.autoApprove })); const save = (status: string): (() => Promise) => async (): Promise => { diff --git a/src/webparts/requestPortal/forms/Vacation/approval/provisioning.json b/src/webparts/requestPortal/forms/Vacation/approval/provisioning.json index 6558228..ba36be0 100644 --- a/src/webparts/requestPortal/forms/Vacation/approval/provisioning.json +++ b/src/webparts/requestPortal/forms/Vacation/approval/provisioning.json @@ -11,6 +11,7 @@ { "internalName": "Phase", "title": "Фаза", "type": "Choice", "choices": ["Согласование", "Исполнение"] }, { "internalName": "SLAhours", "title": "SLA, часов", "type": "Number" }, { "internalName": "AskOverdueReason", "title": "Опрос причины просрочки", "type": "Boolean" }, + { "internalName": "AutoApprove", "title": "Автосогласование", "type": "Boolean" }, { "internalName": "DelegatedBy", "title": "Кем переназначено", "type": "User", "userSelectionMode": "PeopleOnly" } ] } diff --git a/src/webparts/requestPortal/forms/WorkplaceSetup/WorkplaceSetupForm.tsx b/src/webparts/requestPortal/forms/WorkplaceSetup/WorkplaceSetupForm.tsx index 3b8192f..776994d 100644 --- a/src/webparts/requestPortal/forms/WorkplaceSetup/WorkplaceSetupForm.tsx +++ b/src/webparts/requestPortal/forms/WorkplaceSetup/WorkplaceSetupForm.tsx @@ -232,6 +232,7 @@ const WorkplaceSetupForm: React.FC = ({ // при resolve, форма только переносит значения (см. IMatrixRow.slaHours). slaHours: r.slaHours, askOverdueReason: r.askOverdueReason, + autoApprove: r.autoApprove })); // Удаление уже прикреплённого файла (в правке) — сразу из заявки. diff --git a/src/webparts/requestPortal/forms/WorkplaceSetup/approval/provisioning.json b/src/webparts/requestPortal/forms/WorkplaceSetup/approval/provisioning.json index f6b867d..ec88893 100644 --- a/src/webparts/requestPortal/forms/WorkplaceSetup/approval/provisioning.json +++ b/src/webparts/requestPortal/forms/WorkplaceSetup/approval/provisioning.json @@ -11,6 +11,7 @@ { "internalName": "Phase", "title": "Фаза", "type": "Choice", "choices": ["Согласование", "Исполнение"] }, { "internalName": "SLAhours", "title": "SLA, часов", "type": "Number" }, { "internalName": "AskOverdueReason", "title": "Опрос причины просрочки", "type": "Boolean" }, + { "internalName": "AutoApprove", "title": "Автосогласование", "type": "Boolean" }, { "internalName": "DelegatedBy", "title": "Кем переназначено", "type": "User", "userSelectionMode": "PeopleOnly" } ] } diff --git a/src/webparts/requestPortal/shared/approval/approvalList.service.ts b/src/webparts/requestPortal/shared/approval/approvalList.service.ts index bb26955..a320cf7 100644 --- a/src/webparts/requestPortal/shared/approval/approvalList.service.ts +++ b/src/webparts/requestPortal/shared/approval/approvalList.service.ts @@ -36,6 +36,7 @@ const FIELDS = { delegatedBy: 'DelegatedBy', // «Кем переназначено» (User) → DelegatedById slaHours: 'SLAhours', // «SLA, часов» (Number) — пусто значит «взять у типа заявки» askOverdueReason: 'AskOverdueReason', // «Опрос причины просрочки» (Да/Нет) + autoApprove: 'AutoApprove', // «Автосогласование» (Да/Нет) — см. IApproverToWrite.autoApprove }; // Согласующий для записи в список. @@ -61,6 +62,14 @@ export interface IApproverToWrite { slaHours?: number | null; // eslint-disable-next-line @rushstack/no-new-null -- см. slaHours askOverdueReason?: boolean | null; + /** + * Согласовать шаг автоматически по истечении SLA — так же, как SLA-поля выше, + * приходит из resolve с уже применённым решением (наследовать здесь нечего, + * см. ResolvedRouteStepDto.AutoApprove на бэкенде), портал только переносит + * значение в строку. undefined — «не задано» (старые строки без этого поля); + * фактическое решение принимает не портал, а фоновая задача бэкенда. + */ + autoApprove?: boolean; } // Все запросы к списку «<форма> — согласование». listTitle задаётся формой. @@ -141,6 +150,7 @@ export class ApprovalListService { // ?? null, а не || null: ноль часов — значимое значение. [FIELDS.slaHours]: a.slaHours ?? null, [FIELDS.askOverdueReason]: a.askOverdueReason ?? null, + [FIELDS.autoApprove]: a.autoApprove ?? false, }); }); await execute(); @@ -278,6 +288,7 @@ export class ApprovalListService { FIELDS.phase, FIELDS.slaHours, FIELDS.askOverdueReason, + FIELDS.autoApprove, `${FIELDS.approver}/Title`, `${FIELDS.approver}/EMail`, `${FIELDS.delegatedBy}/Title` @@ -306,6 +317,7 @@ export class ApprovalListService { // проставленный при первой отправке, обнулился бы у черновика. slaHours: (r[FIELDS.slaHours] as number | null) ?? null, askOverdueReason: (r[FIELDS.askOverdueReason] as boolean | null) ?? null, + autoApprove: (r[FIELDS.autoApprove] as boolean | null) ?? false, }; }); } diff --git a/src/webparts/requestPortal/shared/approval/approvalSubmission.service.ts b/src/webparts/requestPortal/shared/approval/approvalSubmission.service.ts index f09b1ab..2205ece 100644 --- a/src/webparts/requestPortal/shared/approval/approvalSubmission.service.ts +++ b/src/webparts/requestPortal/shared/approval/approvalSubmission.service.ts @@ -38,6 +38,7 @@ export async function getPlannedMatrix( phase, slaHours: s.slaHours, askOverdueReason: s.askOverdueReason, + autoApprove: s.autoApprove, warning: s.warning, })) ); diff --git a/src/webparts/requestPortal/shared/approval/models/IApprovalRouteApi.ts b/src/webparts/requestPortal/shared/approval/models/IApprovalRouteApi.ts index ce7eb33..9ec18bb 100644 --- a/src/webparts/requestPortal/shared/approval/models/IApprovalRouteApi.ts +++ b/src/webparts/requestPortal/shared/approval/models/IApprovalRouteApi.ts @@ -108,4 +108,13 @@ export interface IResolvedRouteStep { slaHours: number | null; // eslint-disable-next-line @rushstack/no-new-null -- см. slaHours askOverdueReason: boolean | null; + /** + * Согласовать шаг автоматически, когда истечёт его SLA — настраивается ТОЛЬКО в + * админке маршрутов (approval-route), портал это значение только читает из + * resolve и переносит в строку списка согласования, ничего не решая сам: + * фактическое автосогласование выполняет фоновая задача бэкенда (Hangfire). + * Обычный boolean, а не nullable, как SLA-поля выше, — наследовать здесь + * нечего, см. соответствующее поле на бэкенде (TemplateRouteStep.AutoApprove). + */ + autoApprove: boolean; } diff --git a/src/webparts/requestPortal/shared/approval/models/IMatrixRow.ts b/src/webparts/requestPortal/shared/approval/models/IMatrixRow.ts index 29b5810..49cfc57 100644 --- a/src/webparts/requestPortal/shared/approval/models/IMatrixRow.ts +++ b/src/webparts/requestPortal/shared/approval/models/IMatrixRow.ts @@ -31,6 +31,13 @@ export interface IMatrixRow { slaHours?: number | null; // eslint-disable-next-line @rushstack/no-new-null -- см. slaHours askOverdueReason?: boolean | null; + /** + * Согласовать шаг автоматически по истечении SLA — то же транзитное поле, что и + * slaHours/askOverdueReason выше: настраивается в админке, портал только + * переносит значение в строку списка, ничего не решая сам (см. + * IResolvedRouteStep.autoApprove). + */ + autoApprove?: boolean; /** * Предупреждение approval-route по ЭТОМУ шагу (см. IResolvedRouteStep.warning) — * например, роль не разрешилась в конкретного человека, и почему именно. diff --git a/src/webparts/requestPortal/shared/approval/ui/ApprovalMatrix.tsx b/src/webparts/requestPortal/shared/approval/ui/ApprovalMatrix.tsx index e6daf7e..1106cf5 100644 --- a/src/webparts/requestPortal/shared/approval/ui/ApprovalMatrix.tsx +++ b/src/webparts/requestPortal/shared/approval/ui/ApprovalMatrix.tsx @@ -193,7 +193,12 @@ export const ApprovalMatrix: React.FC = ({ )} {hasDates && {r.date}} {hasSla && ( - {r.slaHours || r.slaHours === 0 ? `${r.slaHours} ч` : '—'} + + {r.slaHours || r.slaHours === 0 ? `${r.slaHours} ч` : '—'} + {/* Настраивается только в админке — здесь чисто информативно, + чтобы участник видел: решение по шагу примут не только вручную. */} + {r.autoApprove && (авто)} + )} {/* Перемещение действует на ШАГ целиком (параллельные строки переезжают вместе): одна пара стрелок на весь шаг. */} diff --git a/src/webparts/requestPortal/shared/approval/ui/approval.module.scss b/src/webparts/requestPortal/shared/approval/ui/approval.module.scss index 507a2dc..ff0d849 100644 --- a/src/webparts/requestPortal/shared/approval/ui/approval.module.scss +++ b/src/webparts/requestPortal/shared/approval/ui/approval.module.scss @@ -187,6 +187,14 @@ font-weight: 500; } +// Пометка «(авто)» рядом со значением SLA — шаг настроен на автосогласование +// (см. ApprovalMatrix.tsx/r.autoApprove). Нейтральным серым, не золотым и не +// красным: это не проблема и не решение человека, а просто информация о +// правиле, действующем на шаг. +.autoApproveBadge { + color: $gray-500; +} + // Причина, по которой approval-route не назначил человека на шаг (см. // ApprovalMatrix.tsx/r.warning) — красным, как настоящая проблема маршрута // (в отличие от нейтрального addedByInline/commentInline): пустая строка