import { useMutation } from "@apollo/client"; import { Form, Modal } from "antd"; import { useEffect } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; import { logImEXEvent } from "../../firebase/firebase.utils"; import { GET_JOB_BY_PK } from "../../graphql/jobs.queries.js"; import { INSERT_NEW_NOTE, UPDATE_NOTE } from "../../graphql/notes.queries"; import { insertAuditTrail } from "../../redux/application/application.actions"; import { toggleModalVisible } from "../../redux/modals/modals.actions"; import { selectNoteUpsert } from "../../redux/modals/modals.selectors"; import { selectCurrentUser } from "../../redux/user/user.selectors"; import AuditTrailMapping from "../../utils/AuditTrailMappings"; import NoteUpsertModalComponent from "./note-upsert-modal.component"; const mapStateToProps = createStructuredSelector({ currentUser: selectCurrentUser, noteUpsertModal: selectNoteUpsert }); const mapDispatchToProps = (dispatch) => ({ toggleModalVisible: () => dispatch(toggleModalVisible("noteUpsert")), insertAuditTrail: ({ jobid, operation, type }) => dispatch( insertAuditTrail({ jobid, operation, type }) ) }); export function NoteUpsertModalContainer({ currentUser, noteUpsertModal, toggleModalVisible, insertAuditTrail }) { const { t } = useTranslation(); const [insertNote] = useMutation(INSERT_NEW_NOTE); const [updateNote] = useMutation(UPDATE_NOTE); const notification = useNotification(); const { open, context, actions } = noteUpsertModal; const { jobId, existingNote, text } = context; const { refetch } = actions; const [form] = Form.useForm(); useEffect(() => { //Required to prevent infinite looping. if (existingNote && open) { form.setFieldsValue(existingNote); } else if (!existingNote && open) { form.resetFields(); if (text) { form.setFieldValue("text", text); } } }, [existingNote, form, open, text]); const handleFinish = async (formValues) => { const { relatedros, ...values } = formValues; if (existingNote) { logImEXEvent("job_note_update"); updateNote({ variables: { noteId: existingNote.id, note: values }, refetchQueries: ["GET_JOB_BY_PK", "QUERY_JOB_CARD_DETAILS", "QUERY_PARTS_QUEUE_CARD_DETAILS"] }).then(() => { notification["success"]({ message: t("notes.successes.updated") }); insertAuditTrail({ jobid: context.jobId, operation: AuditTrailMapping.jobnoteupdated(), type: "jobnoteupdated" }); }); if (refetch) refetch(); toggleModalVisible(); } else { logImEXEvent("job_note_insert"); const AdditionalNoteInserts = relatedros ? Object.keys(relatedros).filter((key) => relatedros[key]) : []; await insertNote({ variables: { noteInput: [{ ...values, jobid: jobId, created_by: currentUser.email }] }, update(cache, { data: { updateNote: updatedNote } }) { try { const existingJob = cache.readQuery({ query: GET_JOB_BY_PK, variables: { id: jobId } }); if (existingJob) { cache.writeQuery({ query: GET_JOB_BY_PK, variables: { id: jobId }, data: { ...existingJob, job: { ...existingJob.job, notes: updatedNote.pinned ? [updatedNote, ...existingJob.job.notes] : existingJob.job.notes.filter((n) => n.id !== updatedNote.id) } } }); } } catch (error) { // Cache miss is okay, query hasn't been executed yet console.log("Cache miss for GET_JOB_BY_PK"); } }, refetchQueries: ["QUERY_NOTES_BY_JOB_PK"] }); if (AdditionalNoteInserts.length > 0) { //Insert the others. AdditionalNoteInserts.forEach(async (newJobId) => { await insertNote({ variables: { noteInput: [{ ...values, jobid: newJobId, created_by: currentUser.email }] } }); insertAuditTrail({ jobid: newJobId, operation: AuditTrailMapping.jobnoteadded(), type: "jobnoteadded" }); }); } if (refetch) refetch(); form.resetFields(); toggleModalVisible(); notification["success"]({ message: t("notes.successes.create") }); insertAuditTrail({ jobid: context.jobId, operation: AuditTrailMapping.jobnoteadded(), type: "jobnoteadded" }); } }; return ( { form.submit(); }} onCancel={() => { toggleModalVisible(); }} destroyOnHidden >
); } export default connect(mapStateToProps, mapDispatchToProps)(NoteUpsertModalContainer);