85 lines
3.1 KiB
TypeScript
85 lines
3.1 KiB
TypeScript
import * as React from 'react';
|
|
import { texts } from '../../texts';
|
|
import { useAsyncSubmit } from '../../hooks/useAsyncSubmit';
|
|
import {
|
|
boolToTriState,
|
|
isValidSlaHours,
|
|
parseSlaHours,
|
|
slaHoursToInput,
|
|
triStateToBool,
|
|
TriState,
|
|
TRI_STATE_OPTIONS
|
|
} from '../../utils/sla';
|
|
import { Field, FormGrid, FormModal, Select, TextInput } from '../ui';
|
|
|
|
export interface IManageRequestsSlaModalProps {
|
|
/** Номер шага — только для заголовка, чтобы было видно, что правим. */
|
|
orderNo: number;
|
|
// eslint-disable-next-line @rushstack/no-new-null -- null = «в строке не задано», это не 0
|
|
slaHours: number | null;
|
|
// eslint-disable-next-line @rushstack/no-new-null -- null = «в строке не задано»
|
|
askOverdueReason: boolean | null;
|
|
// eslint-disable-next-line @rushstack/no-new-null -- см. выше
|
|
onSave: (slaHours: number | null, askOverdueReason: boolean | null) => Promise<void>;
|
|
onClose: () => void;
|
|
}
|
|
|
|
/**
|
|
* SLA конкретной строки маршрута конкретной заявки.
|
|
*
|
|
* Правится отдельно от маршрута-шаблона: шаблон задаёт значение на момент
|
|
* создания заявки, а здесь его можно поменять для одной уже идущей заявки, не
|
|
* трогая остальные.
|
|
*
|
|
* Пустое поле сохраняется как «не задано» — тогда работает SLA типа заявки.
|
|
* Ноль пустотой не считается: это «напоминать сразу».
|
|
*/
|
|
export const ManageRequestsSlaModal: React.FC<IManageRequestsSlaModalProps> = ({
|
|
orderNo,
|
|
slaHours,
|
|
askOverdueReason,
|
|
onSave,
|
|
onClose
|
|
}) => {
|
|
const [hours, setHours] = React.useState(() => slaHoursToInput(slaHours));
|
|
const [ask, setAsk] = React.useState<TriState>(() => boolToTriState(askOverdueReason));
|
|
const submit = useAsyncSubmit();
|
|
|
|
const handleSubmit = (): void => {
|
|
if (!isValidSlaHours(hours)) {
|
|
submit.fail(texts.manageRequests.validationSlaHours);
|
|
return;
|
|
}
|
|
submit.run(() => onSave(parseSlaHours(hours), triStateToBool(ask)));
|
|
};
|
|
|
|
return (
|
|
<FormModal
|
|
title={texts.manageRequests.slaModalTitle(orderNo)}
|
|
error={submit.error}
|
|
isSaving={submit.isBusy}
|
|
onSubmit={handleSubmit}
|
|
onClose={onClose}
|
|
>
|
|
<FormGrid>
|
|
<Field label={texts.manageRequests.slaHoursLabel} full hint={texts.manageRequests.slaHoursHint}>
|
|
<TextInput
|
|
type="number"
|
|
min={0}
|
|
value={hours}
|
|
onChange={e => setHours(e.target.value)}
|
|
placeholder={texts.manageRequests.slaHoursPlaceholder}
|
|
/>
|
|
</Field>
|
|
<Field label={texts.manageRequests.askOverdueReasonLabel} full hint={texts.manageRequests.askOverdueReasonHint}>
|
|
<Select
|
|
options={TRI_STATE_OPTIONS}
|
|
value={ask}
|
|
onChange={e => setAsk(e.target.value as TriState)}
|
|
/>
|
|
</Field>
|
|
</FormGrid>
|
|
</FormModal>
|
|
);
|
|
};
|