diff --git a/frontend/src/webparts/approvalAdmin/components/screens/ManageRequestsApproverModal.tsx b/frontend/src/webparts/approvalAdmin/components/screens/ManageRequestsApproverModal.tsx index 36947ce..6a6c119 100644 --- a/frontend/src/webparts/approvalAdmin/components/screens/ManageRequestsApproverModal.tsx +++ b/frontend/src/webparts/approvalAdmin/components/screens/ManageRequestsApproverModal.tsx @@ -3,30 +3,59 @@ import { Employee } from '../../models'; import { texts } from '../../texts'; import { findEmployeeByEmail, toEmployeeOption } from '../../utils/employee'; import { useAsyncSubmit } from '../../hooks/useAsyncSubmit'; -import { Field, FormGrid, FormModal, SearchableSelect } from '../ui'; +import { + boolToTriState, + isValidSlaHours, + parseSlaHours, + slaHoursToInput, + triStateToBool, + TriState, + TRI_STATE_OPTIONS +} from '../../utils/sla'; +import { Field, FormGrid, FormModal, SearchableSelect, Select, TextInput } from '../ui'; export interface IManageRequestsApproverModalProps { title: string; initialEmail?: string; + /** SLA строки в часах на момент открытия. null — в строке не задано, работает SLA типа заявки. */ + // eslint-disable-next-line @rushstack/no-new-null -- null = «не задано», это не 0 + initialSlaHours: number | null; + /** Опрос причины просрочки по строке. null — берётся от типа заявки. */ + // eslint-disable-next-line @rushstack/no-new-null -- см. initialSlaHours + initialAskOverdueReason: boolean | null; employees: Employee[]; employeesLoading: boolean; /** Email'ы (в любом регистре), уже занятые другими шагами той же фазы — этот человек не может встать в фазу второй раз. */ excludedEmails: string[]; - onSave: (email: string, position: string) => Promise; + onSave: ( + email: string, + position: string, + // eslint-disable-next-line @rushstack/no-new-null -- null = «не задано» + slaHours: number | null, + // eslint-disable-next-line @rushstack/no-new-null -- null = «не задано» + askOverdueReason: boolean | null + ) => Promise; onClose: () => void; } /** - * Переназначение согласующего/исполнителя существующего шага (см. - * ManageRequestsScreen). Должность НЕ вводится — берётся из справочника - * сотрудников (api.tnsu.kz/Employee/All, см. Employee.position в - * models/dictionaries.ts) на момент сохранения, отдельного поля для неё - * в этой форме нет. Добавление НОВОГО шага через модалку не идёт — см. + * Правка существующего шага: кто согласует и какой у шага SLA. + * + * Одна форма на оба вида правки намеренно — раньше SLA жил в отдельной модалке + * со своей кнопкой-флажком в строке, и получалось два похожих диалога и лишняя + * иконка в и без того плотном ряду действий. Правки применяются одним + * сохранением (см. saveModal в ManageRequestsScreen). + * + * Должность НЕ вводится — берётся из справочника сотрудников + * (api.tnsu.kz/Employee/All, см. Employee.position в models/dictionaries.ts) на + * момент сохранения. Добавление НОВОГО шага через модалку не идёт — см. * плашку-пикер под таблицей в ManageRequestsPhaseTable. */ export const ManageRequestsApproverModal: React.FC = ({ title, initialEmail = '', + initialSlaHours, + initialAskOverdueReason, employees, employeesLoading, excludedEmails, @@ -34,6 +63,10 @@ export const ManageRequestsApproverModal: React.FC { const [email, setEmail] = React.useState(initialEmail); + const [slaHours, setSlaHours] = React.useState(() => slaHoursToInput(initialSlaHours)); + const [askOverdueReason, setAskOverdueReason] = React.useState( + () => boolToTriState(initialAskOverdueReason) + ); const submit = useAsyncSubmit(); // Тот, кто уже занят в этой фазе, исключён из списка выбора — дубликат @@ -51,8 +84,14 @@ export const ManageRequestsApproverModal: React.FC onSave(trimmedEmail, position)); + submit.run(() => + onSave(trimmedEmail, position, parseSlaHours(slaHours), triStateToBool(askOverdueReason)) + ); }; return ( @@ -69,6 +108,22 @@ export const ManageRequestsApproverModal: React.FC + + setSlaHours(e.target.value)} + placeholder={texts.manageRequests.slaHoursPlaceholder} + /> + + + setAsk(e.target.value as TriState)} - /> - - - - ); -}; diff --git a/frontend/src/webparts/approvalAdmin/texts.ts b/frontend/src/webparts/approvalAdmin/texts.ts index 5bcc88f..84a89e6 100644 --- a/frontend/src/webparts/approvalAdmin/texts.ts +++ b/frontend/src/webparts/approvalAdmin/texts.ts @@ -342,8 +342,6 @@ export const texts = { reassignTitle: 'Переназначить шаг', columnSla: 'SLA', slaInherited: 'от типа заявки', - editSla: 'Настроить SLA шага', - slaModalTitle: (orderNo: number): string => `SLA шага ${orderNo}`, slaHoursLabel: 'SLA, часов', slaHoursHint: 'Через сколько часов простоя напоминать по этому шагу. Пусто — берётся SLA типа заявки; 0 — напоминать сразу.',