diff --git a/frontend/src/components/ContactModal/index.js b/frontend/src/components/ContactModal/index.js index 5b4264b..93aff6e 100644 --- a/frontend/src/components/ContactModal/index.js +++ b/frontend/src/components/ContactModal/index.js @@ -63,7 +63,7 @@ const ContactSchema = Yup.object().shape({ email: Yup.string().email("Invalid email"), }); -const ContactModal = ({ open, onClose, contactId }) => { +const ContactModal = ({ open, onClose, contactId, initialValues, onSave }) => { const classes = useStyles(); const isMounted = useRef(true); @@ -83,7 +83,14 @@ const ContactModal = ({ open, onClose, contactId }) => { useEffect(() => { const fetchContact = async () => { + if (initialValues) { + setContact(prevState => { + return { ...prevState, ...initialValues }; + }); + } + if (!contactId) return; + try { const { data } = await api.get(`/contacts/${contactId}`); if (isMounted.current) { @@ -104,10 +111,14 @@ const ContactModal = ({ open, onClose, contactId }) => { }; fetchContact(); - }, [contactId, open]); + }, [contactId, open, initialValues]); - const handleClose = () => { - onClose(); + const handleClose = contactId => { + if (contactId) { + onClose(contactId); + } else { + onClose(); + } setContact(initialState); }; @@ -115,8 +126,13 @@ const ContactModal = ({ open, onClose, contactId }) => { try { if (contactId) { await api.put(`/contacts/${contactId}`, values); + handleClose(); } else { - await api.post("/contacts", values); + const { data } = await api.post("/contacts", values); + if (onSave) { + onSave(data); + } + handleClose(); } toast.success(i18n.t("contactModal.success")); } catch (err) { @@ -131,7 +147,6 @@ const ContactModal = ({ open, onClose, contactId }) => { toast.error("Unknown error"); } } - handleClose(); }; return ( diff --git a/frontend/src/components/NewTicketModal/index.js b/frontend/src/components/NewTicketModal/index.js index bfab47c..4b77639 100644 --- a/frontend/src/components/NewTicketModal/index.js +++ b/frontend/src/components/NewTicketModal/index.js @@ -19,6 +19,7 @@ import { makeStyles } from "@material-ui/core/styles"; import { i18n } from "../../translate/i18n"; import api from "../../services/api"; import ButtonWithSpinner from "../ButtonWithSpinner"; +import ContactModal from "../ContactModal"; const useStyles = makeStyles(theme => ({ root: { @@ -27,7 +28,7 @@ const useStyles = makeStyles(theme => ({ }, })); -const filterOptions = createFilterOptions({ +const filter = createFilterOptions({ trim: true, }); @@ -40,9 +41,14 @@ const NewTicketModal = ({ modalOpen, onClose }) => { const [loading, setLoading] = useState(false); const [searchParam, setSearchParam] = useState(""); const [selectedContact, setSelectedContact] = useState(null); + const [newContact, setNewContact] = useState({}); + const [contactModalOpen, setContactModalOpen] = useState(false); useEffect(() => { - if (!modalOpen || searchParam.length < 3) return; + if (!modalOpen || searchParam.length < 3) { + setLoading(false); + return; + } setLoading(true); const delayDebounceFn = setTimeout(() => { const fetchContacts = async () => { @@ -53,6 +59,7 @@ const NewTicketModal = ({ modalOpen, onClose }) => { setOptions(data.contacts); setLoading(false); } catch (err) { + setLoading(false); const errorMsg = err.response?.data?.error; if (errorMsg) { if (i18n.exists(`backendErrors.${errorMsg}`)) { @@ -77,13 +84,12 @@ const NewTicketModal = ({ modalOpen, onClose }) => { setSelectedContact(null); }; - const handleSaveTicket = async e => { - e.preventDefault(); - if (!selectedContact) return; + const handleSaveTicket = async contactId => { + if (!contactId) return; setLoading(true); try { const { data: ticket } = await api.post("/tickets", { - contactId: selectedContact.id, + contactId: contactId, userId: userId, status: "open", }); @@ -104,73 +110,123 @@ const NewTicketModal = ({ modalOpen, onClose }) => { handleClose(); }; + const handleSelectOption = (e, newValue) => { + if (newValue?.number) { + setSelectedContact(newValue); + } else if (newValue?.name) { + setNewContact({ name: newValue.name }); + setContactModalOpen(true); + } + }; + + const handleCloseContactModal = () => { + setContactModalOpen(false); + }; + + const handleAddNewContactTicket = contact => { + handleSaveTicket(contact.id); + }; + + const createAddContactOption = (options, params) => { + const filtered = filter(options, params); + + if (params.inputValue !== "" && !loading && searchParam.length >= 3) { + filtered.push({ + name: `${params.inputValue}`, + }); + } + + return filtered; + }; + + const renderOption = option => { + if (option.number) { + return `${option.name} - ${option.number}`; + } else { + return `${i18n.t("newTicketModal.add")} ${option.name}`; + } + }; + + const renderOptionLabel = option => { + if (option.number) { + return `${option.name} - ${option.number}`; + } else { + return `${option.name}`; + } + }; + return (