import { Alert, AlertIcon, Flex, Button, Tooltip, HStack, Spinner, ModalBody, ModalCloseButton, ModalContent, Modal, VStack, useToast, ModalOverlay, IconButton, } from '@chakra-ui/react'; import { zodResolver } from '@hookform/resolvers/zod'; import { FC, useEffect, useState } from 'react'; import { FormProvider, useForm } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; import { AddIcon, DialogModalHeader, DialogModalFooter, DeleteIcon, EditIcon } from 'components/dialog'; import { getDefaultValues } from './default-values'; import { schema, FormType } from './form-schema'; import { InboundsField } from './inbounds-field'; import { NameField } from './name-field'; import { InboundType, Service, ServiceCreate } from 'types'; import { fetchInbounds, useInbounds, useServices } from 'stores'; import { useQuery } from 'react-query'; import { queryIds } from 'constants/query-ids'; const formatService = (service: Service): FormType => { const inbounds: number[] = service.inbounds.map((inbound: number | InboundType): number => { return (typeof inbound !== 'number') ? inbound.id : inbound; }); return { ...service, inbounds, }; }; export type ServiceDialogProps = {}; export const ServiceDialog: FC = () => { const { editingService, isCreatingNewService, onCreateService, editService, onEditingService, createService, onDeletingService, } = useServices(); const { refetchInbounds } = useInbounds(); const { data: inbounds, } = useQuery(queryIds.inbounds, () => fetchInbounds()); const isEditing = !!editingService; const isOpen = isCreatingNewService || isEditing; const [loading, setLoading] = useState(false); const [error, setError] = useState(''); const toast = useToast(); const { t } = useTranslation(); const form = useForm({ defaultValues: getDefaultValues(), resolver: zodResolver(schema), }); useEffect(() => { if (isOpen) { refetchInbounds(); form.reset(); } }, [isOpen]); useEffect(() => { if (editingService) { form.reset(formatService(editingService)); } }, [editingService]); const submit = async (values: FormType) => { setLoading(true); const methods = { edited: editService, created: createService }; const method = isEditing ? 'edited' : 'created'; setError(null); const { inbounds, name } = values; let body: ServiceCreate = { name, inbounds, id: editingService?.id }; await methods[method](body) .then(() => { toast({ title: t( isEditing ? 'serviceDialog.serviceEdited' : 'serviceDialog.serviceCreated', { name: values.name } ), status: 'success', isClosable: true, position: 'top', duration: 3000, }); onClose(); }) .catch((err) => { if (err?.response?.status === 409 || err?.response?.status === 400) setError(err?.response?._data?.detail); if (err?.response?.status === 422) { Object.keys(err.response._data.detail).forEach((key) => { setError(err?.response._data.detail[key] as string); form.setError(key as 'name' | 'inbounds', { type: 'custom', message: err.response._data.detail[key], }); }); } }) .finally(() => { setLoading(false); }); }; const onClose = () => { form.reset(getDefaultValues()); onCreateService(false); onEditingService(null); setError(null); }; const disabled = loading; return (
{error && ( {error} )} {error && ( {error} )} {isEditing && editingService !== null && ( <> { onDeletingService(editingService); onClose(); }} > )}
); };