Загрузка данных
import { ContractorAutocomplete } from '@/entities/Location/components/ContractorAutocomplete';
import { AppConsts } from '@/shared';
import {
NUMBER_FIELD_SYMBOLS_LIMIT,
TICKET_DESCRIPTION_SYMBOLS_LIMIT,
} from '@/shared/consts/constants';
import { useFieldValidation } from '@/shared/hooks/useFieldValidation';
import { useGetLocationUUID } from '@/shared/hooks/useGetLocationUUID';
import { isMultilineValue } from '@/utils';
import { ticketDrawerSchema } from '@/widgets/TicketDrawer/schema/ticketSchema';
import { yupResolver } from '@hookform/resolvers/yup';
import { useCreateLocationTicketMutation } from '@shared/api/location/client';
import {
Button,
DateTimeField,
Drawer,
DrawerActions,
TextField,
} from '@shared/components';
import { useCloseDrawer } from '@shared/hooks/drawer/useCloseDrawer';
import {
EventActionTypes,
useSendClickStreamEvent,
} from '@shared/hooks/useSendClickStreamEvent';
import { DrawerTypes } from '@shared/model/drawer/drawer.types';
import dayjs from 'dayjs';
import { useEffect } from 'react';
import {
Controller,
FormProvider,
SubmitHandler,
useForm,
} from 'react-hook-form';
import { useTranslation } from 'react-i18next';
type Value = {
field: 'number' | 'description';
limitedSymbols?: number;
};
const INPUT_VALUES: Value[] = [
{ field: 'number', limitedSymbols: NUMBER_FIELD_SYMBOLS_LIMIT },
{ field: 'description', limitedSymbols: TICKET_DESCRIPTION_SYMBOLS_LIMIT },
];
export const TicketCreateDrawer = () => {
const { id } = useGetLocationUUID();
const { t } = useTranslation('common');
const { sendEvent } = useSendClickStreamEvent(
EventActionTypes.createLocationTicket,
);
const closeDrawer = useCloseDrawer();
const methods = useForm({
mode: 'onBlur',
defaultValues: {
number: '',
deadline: undefined,
registeredAt: new Date(),
description: '',
contractorId: null,
},
resolver: yupResolver(ticketDrawerSchema),
});
const {
control,
handleSubmit,
reset,
getValues,
formState: { isDirty, isValid },
} = methods;
const { isRequiredField } = useFieldValidation(ticketDrawerSchema);
const [createTicket, { isLoading, isSuccess, reset: resetCreateTicket }] =
useCreateLocationTicketMutation();
const handleSave: SubmitHandler<{
number: string;
deadline: Date;
registeredAt: Date;
description?: string;
contractorId?: string | null;
}> = (data) => {
createTicket({
locationTicketCreateRequest: {
registeredAt: dayjs(data.registeredAt).format(
AppConsts.Date.format.Rfc3339,
),
number: data.number.trim(),
deadline: dayjs(data.deadline).format(AppConsts.Date.format.Rfc3339),
locationId: id,
description: data?.description || '',
contractorId: data?.contractorId || undefined,
},
});
};
useEffect(() => {
if (isSuccess) {
closeDrawer(DrawerTypes.ticketCreate);
resetCreateTicket();
reset();
sendEvent();
}
}, [isSuccess]);
const isSaveButtonDisabled = !isDirty || !isValid;
const actions: DrawerActions = {
actionPrimary: (
<Button
onClick={handleSubmit(handleSave)}
loading={isLoading}
disabled={isSaveButtonDisabled}
>
{t('buttons.save')}
</Button>
),
};
const handleClose = () => {
reset();
};
return (
<FormProvider {...methods}>
<Drawer
type={DrawerTypes.ticketCreate}
title={t('drawerTitle.createTicket')}
actions={actions}
onClose={handleClose}
>
{INPUT_VALUES.map((value) => (
<Controller
key={value.field}
name={value.field}
control={control}
render={({ field, fieldState: { error } }) => (
<TextField
fullWidth
label={t(value.field)}
error={!!error?.message}
limitedSymbols={value.limitedSymbols}
helperText={t(error?.message as string)}
multiline={isMultilineValue(value.field)}
required={isRequiredField(value.field)}
{...field}
/>
)}
/>
))}
<Controller
control={control}
name='registeredAt'
render={({ field: { value, onChange } }) => (
<DateTimeField
label={t('createdAt')}
value={value}
onChange={onChange}
required={isRequiredField('registredAt')}
maxDate={getValues('deadline')}
margin='none'
/>
)}
/>
<Controller
control={control}
name='deadline'
render={({ field: { value, onChange } }) => (
<DateTimeField
label={t('ticket:deadline')}
value={value}
onChange={onChange}
required={isRequiredField('deadline')}
minDate={getValues('registeredAt')}
margin='none'
/>
)}
/>
<ContractorAutocomplete />
</Drawer>
</FormProvider>
);
};