feat(автосогласование): флаг «Автосогласование» в форме шага маршрута
Админка получает управление флагом AutoApprove на шаге маршрута (добавлен в предыдущем коммите на бэкенде): чекбокс в RouteStepFormModal, перенос значения при копировании маршрута (RouteCopyModal), проверка «включён без действующего SLA — ошибка» (считать нечего, задача такой шаг пропустит молча). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -47,7 +47,8 @@ function toStepInput(step: TemplateRouteStep): CreateTemplateRouteStepInput {
|
||||
conditions: step.conditions,
|
||||
conditionsLogic: step.conditionsLogic,
|
||||
slaHours: step.slaHours,
|
||||
askOverdueReason: step.askOverdueReason
|
||||
askOverdueReason: step.askOverdueReason,
|
||||
autoApprove: step.autoApprove
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -77,6 +77,7 @@ interface IFormState {
|
||||
/** Пусто — наследовать SLA от типа заявки; «0» — напоминать сразу. Это разные вещи. */
|
||||
slaHours: string;
|
||||
askOverdueReason: TriState;
|
||||
autoApprove: boolean;
|
||||
}
|
||||
|
||||
const EMPTY_CONDITION: RouteStepCondition = { fieldName: '', operation: ComparisonOperator.GreaterThan, value: '' };
|
||||
@@ -133,7 +134,8 @@ function toFormState(editing: TemplateRouteStep | undefined, nextOrderNo: number
|
||||
conditions: [EMPTY_CONDITION],
|
||||
conditionsLogic: ConditionsLogic.And,
|
||||
slaHours: '',
|
||||
askOverdueReason: ''
|
||||
askOverdueReason: '',
|
||||
autoApprove: false
|
||||
};
|
||||
}
|
||||
return {
|
||||
@@ -149,7 +151,8 @@ function toFormState(editing: TemplateRouteStep | undefined, nextOrderNo: number
|
||||
conditions: editing.conditions.length > 0 ? editing.conditions : [EMPTY_CONDITION],
|
||||
conditionsLogic: editing.conditionsLogic,
|
||||
slaHours: slaHoursToInput(editing.slaHours),
|
||||
askOverdueReason: boolToTriState(editing.askOverdueReason)
|
||||
askOverdueReason: boolToTriState(editing.askOverdueReason),
|
||||
autoApprove: editing.autoApprove
|
||||
};
|
||||
}
|
||||
|
||||
@@ -365,6 +368,14 @@ export const RouteStepFormModal: React.FC<IRouteStepFormModalProps> = ({
|
||||
submit.fail(texts.routeSteps.validationSlaHours);
|
||||
return;
|
||||
}
|
||||
// Автосогласование отсчитывается от SLA — без него фоновая задача шаг просто
|
||||
// пропустит (см. AutoApproveService.DeadlineOf), и настройка тихо не сработала
|
||||
// бы. Пустое поле здесь не значит «нет SLA»: оно значит «взять у типа заявки»,
|
||||
// поэтому ошибка только когда SLA нет и там.
|
||||
if (form.autoApprove && parseSlaHours(form.slaHours) === null && requestType?.slaHours === null) {
|
||||
submit.fail(texts.routeSteps.validationAutoApproveWithoutSla);
|
||||
return;
|
||||
}
|
||||
|
||||
const payload = {
|
||||
orderNo,
|
||||
@@ -379,7 +390,8 @@ export const RouteStepFormModal: React.FC<IRouteStepFormModalProps> = ({
|
||||
: null,
|
||||
conditionsLogic: form.conditionsLogic,
|
||||
slaHours: parseSlaHours(form.slaHours),
|
||||
askOverdueReason: triStateToBool(form.askOverdueReason)
|
||||
askOverdueReason: triStateToBool(form.askOverdueReason),
|
||||
autoApprove: form.autoApprove
|
||||
};
|
||||
|
||||
const request = editing
|
||||
@@ -505,6 +517,14 @@ export const RouteStepFormModal: React.FC<IRouteStepFormModalProps> = ({
|
||||
/>
|
||||
</Field>
|
||||
|
||||
<Field label={texts.routeSteps.autoApproveLabel} full hint={texts.routeSteps.autoApproveHint}>
|
||||
<Checkbox
|
||||
label={texts.routeSteps.autoApproveCheckbox}
|
||||
checked={form.autoApprove}
|
||||
onChange={v => setForm({ ...form, autoApprove: v })}
|
||||
/>
|
||||
</Field>
|
||||
|
||||
<Field label={texts.routeSteps.conditionLabel} full hint={!hasListId ? texts.routeSteps.conditionDisabledHint : undefined}>
|
||||
<Checkbox
|
||||
label={texts.routeSteps.conditionCheckbox}
|
||||
|
||||
@@ -34,6 +34,15 @@ export interface TemplateRouteStep {
|
||||
slaHours: number | null;
|
||||
/** Спрашивать ли причину просрочки на этом шаге. null — наследовать от типа. */
|
||||
askOverdueReason: boolean | null;
|
||||
/**
|
||||
* Согласовывать шаг автоматически, когда истечёт его SLA (фоновая задача бэкенда,
|
||||
* см. AutoApproveService). Обычный boolean, а не «три состояния», как у полей выше:
|
||||
* наследовать его неоткуда — у типа заявки такой настройки нет.
|
||||
*
|
||||
* Работает только вместе с SLA: без действующего SLA (ни здесь, ни у типа заявки)
|
||||
* отсчитывать нечего, и задача такой шаг пропускает.
|
||||
*/
|
||||
autoApprove: boolean;
|
||||
/** Предупреждение бэкенда о сохранённом шаге (например, должность не найдена). */
|
||||
warning?: string | null;
|
||||
}
|
||||
@@ -50,6 +59,7 @@ export interface CreateTemplateRouteStepInput {
|
||||
conditionsLogic: ConditionsLogic;
|
||||
slaHours: number | null;
|
||||
askOverdueReason: boolean | null;
|
||||
autoApprove: boolean;
|
||||
}
|
||||
|
||||
export type UpdateTemplateRouteStepInput = CreateTemplateRouteStepInput;
|
||||
@@ -66,6 +76,7 @@ export interface PatchTemplateRouteStepInput {
|
||||
conditionsLogic?: ConditionsLogic;
|
||||
slaHours?: number | null;
|
||||
askOverdueReason?: boolean | null;
|
||||
autoApprove?: boolean;
|
||||
}
|
||||
|
||||
// Способ задать исполнителя шага: ровно одно из полей выше должно быть заполнено
|
||||
|
||||
@@ -329,6 +329,12 @@ export const texts = {
|
||||
slaHoursPlaceholder: 'Как у типа заявки',
|
||||
askOverdueReasonLabel: 'Спрашивать причину просрочки',
|
||||
askOverdueReasonHint: '«Не задано» — берётся значение типа заявки.',
|
||||
autoApproveLabel: 'Автосогласование',
|
||||
autoApproveCheckbox: 'Согласовать шаг автоматически, когда истечёт SLA',
|
||||
autoApproveHint:
|
||||
'Если согласующий не примет решение в срок, шаг будет согласован без него и заявка пойдёт дальше. Проверка идёт раз в час, поэтому согласование произойдёт в течение часа после истечения срока.',
|
||||
validationAutoApproveWithoutSla:
|
||||
'Автосогласование считается от SLA — задайте SLA шага или SLA типа заявки.',
|
||||
conditionLabel: 'Условие видимости шага',
|
||||
conditionCheckbox: 'Показывать шаг только при выполнении условия',
|
||||
conditionDisabledHint:
|
||||
|
||||
@@ -16,6 +16,7 @@ function step(overrides: Partial<TemplateRouteStep>): TemplateRouteStep {
|
||||
conditionsLogic: ConditionsLogic.And,
|
||||
slaHours: null,
|
||||
askOverdueReason: null,
|
||||
autoApprove: false,
|
||||
...overrides
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user