CLEANUP Refactored note upsert to use redux modals.
This commit is contained in:
@@ -30,8 +30,6 @@ export function InvoiceEnterModalContainer({
|
|||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [updateContract] = useMutation(RETURN_CONTRACT);
|
const [updateContract] = useMutation(RETURN_CONTRACT);
|
||||||
const handleFinish = values => {
|
const handleFinish = values => {
|
||||||
console.log("Finish", values);
|
|
||||||
|
|
||||||
updateContract({
|
updateContract({
|
||||||
variables: {
|
variables: {
|
||||||
contractId: context.contractId,
|
contractId: context.contractId,
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import AlertComponent from "../alert/alert.component";
|
|||||||
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
|
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
|
||||||
import NoteUpsertModal from "../note-upsert-modal/note-upsert-modal.container";
|
import NoteUpsertModal from "../note-upsert-modal/note-upsert-modal.container";
|
||||||
import ScheduleJobModalContainer from "../schedule-job-modal/schedule-job-modal.container";
|
import ScheduleJobModalContainer from "../schedule-job-modal/schedule-job-modal.container";
|
||||||
//import JobDetailCardsHeaderComponent from "./job-detail-cards.header.component";
|
|
||||||
import JobDetailCardsCustomerComponent from "./job-detail-cards.customer.component";
|
import JobDetailCardsCustomerComponent from "./job-detail-cards.customer.component";
|
||||||
import JobDetailCardsDamageComponent from "./job-detail-cards.damage.component";
|
import JobDetailCardsDamageComponent from "./job-detail-cards.damage.component";
|
||||||
import JobDetailCardsDatesComponent from "./job-detail-cards.dates.component";
|
import JobDetailCardsDatesComponent from "./job-detail-cards.dates.component";
|
||||||
@@ -29,16 +28,21 @@ import JobDetailCardsTotalsComponent from "./job-detail-cards.totals.component";
|
|||||||
|
|
||||||
const mapDispatchToProps = dispatch => ({
|
const mapDispatchToProps = dispatch => ({
|
||||||
setInvoiceEnterContext: context =>
|
setInvoiceEnterContext: context =>
|
||||||
dispatch(setModalContext({ context: context, modal: "invoiceEnter" }))
|
dispatch(setModalContext({ context: context, modal: "invoiceEnter" })),
|
||||||
|
setNoteUpsertContext: context =>
|
||||||
|
dispatch(setModalContext({ context: context, modal: "noteUpsert" }))
|
||||||
});
|
});
|
||||||
|
|
||||||
function JobDetailCards({ selectedJob, setInvoiceEnterContext }) {
|
export function JobDetailCards({
|
||||||
|
selectedJob,
|
||||||
|
setInvoiceEnterContext,
|
||||||
|
setNoteUpsertContext
|
||||||
|
}) {
|
||||||
const { loading, error, data, refetch } = useQuery(QUERY_JOB_CARD_DETAILS, {
|
const { loading, error, data, refetch } = useQuery(QUERY_JOB_CARD_DETAILS, {
|
||||||
fetchPolicy: "network-only",
|
fetchPolicy: "network-only",
|
||||||
variables: { id: selectedJob },
|
variables: { id: selectedJob },
|
||||||
skip: !selectedJob
|
skip: !selectedJob
|
||||||
});
|
});
|
||||||
const [noteModalVisible, setNoteModalVisible] = useState(false);
|
|
||||||
const scheduleModalState = useState(false);
|
const scheduleModalState = useState(false);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
@@ -50,12 +54,7 @@ function JobDetailCards({ selectedJob, setInvoiceEnterContext }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="job-cards-container">
|
<div className="job-cards-container">
|
||||||
<NoteUpsertModal
|
<NoteUpsertModal />
|
||||||
jobId={data.jobs_by_pk.id}
|
|
||||||
visible={noteModalVisible}
|
|
||||||
changeVisibility={setNoteModalVisible}
|
|
||||||
refetch={refetch}
|
|
||||||
/>
|
|
||||||
<ScheduleJobModalContainer
|
<ScheduleJobModalContainer
|
||||||
scheduleModalState={scheduleModalState}
|
scheduleModalState={scheduleModalState}
|
||||||
jobId={data.jobs_by_pk.id}
|
jobId={data.jobs_by_pk.id}
|
||||||
@@ -110,7 +109,12 @@ function JobDetailCards({ selectedJob, setInvoiceEnterContext }) {
|
|||||||
key="notes"
|
key="notes"
|
||||||
actiontype="addNote"
|
actiontype="addNote"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setNoteModalVisible(!noteModalVisible);
|
setNoteUpsertContext({
|
||||||
|
actions: { refetch: refetch },
|
||||||
|
context: {
|
||||||
|
jobId: data.jobs_by_pk.id
|
||||||
|
}
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<EditFilled />
|
<EditFilled />
|
||||||
@@ -120,7 +124,7 @@ function JobDetailCards({ selectedJob, setInvoiceEnterContext }) {
|
|||||||
key="postinvoices"
|
key="postinvoices"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setInvoiceEnterContext({
|
setInvoiceEnterContext({
|
||||||
actions: { refetch: null },
|
actions: { refetch: refetch },
|
||||||
context: {
|
context: {
|
||||||
job: data.jobs_by_pk
|
job: data.jobs_by_pk
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +1,32 @@
|
|||||||
import React, { useState } from "react";
|
|
||||||
import { Table, Button, notification } from "antd";
|
|
||||||
import {
|
import {
|
||||||
WarningFilled,
|
|
||||||
EyeInvisibleFilled,
|
|
||||||
DeleteFilled,
|
DeleteFilled,
|
||||||
EditFilled
|
EditFilled,
|
||||||
|
EyeInvisibleFilled,
|
||||||
|
WarningFilled
|
||||||
} from "@ant-design/icons";
|
} from "@ant-design/icons";
|
||||||
|
import { Button, notification, Table } from "antd";
|
||||||
|
import React from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import Moment from "react-moment";
|
import Moment from "react-moment";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import { setModalContext } from "../../redux/modals/modals.actions";
|
||||||
import NoteUpsertModal from "../note-upsert-modal/note-upsert-modal.container";
|
import NoteUpsertModal from "../note-upsert-modal/note-upsert-modal.container";
|
||||||
|
|
||||||
export default function JobNotesComponent({
|
const mapDispatchToProps = dispatch => ({
|
||||||
|
setNoteUpsertContext: context =>
|
||||||
|
dispatch(setModalContext({ context: context, modal: "noteUpsert" }))
|
||||||
|
});
|
||||||
|
|
||||||
|
export function JobNotesComponent({
|
||||||
loading,
|
loading,
|
||||||
data,
|
data,
|
||||||
refetch,
|
refetch,
|
||||||
deleteNote,
|
deleteNote,
|
||||||
jobId
|
jobId,
|
||||||
|
setNoteUpsertContext
|
||||||
}) {
|
}) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [noteModalVisible, setNoteModalVisible] = useState(false);
|
|
||||||
const [existingNote, setExistingNote] = useState(null);
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
title: "",
|
title: "",
|
||||||
@@ -28,7 +35,6 @@ export default function JobNotesComponent({
|
|||||||
width: 80,
|
width: 80,
|
||||||
render: (text, record) => (
|
render: (text, record) => (
|
||||||
<span>
|
<span>
|
||||||
{" "}
|
|
||||||
{record.critical ? (
|
{record.critical ? (
|
||||||
<WarningFilled style={{ margin: 4, color: "red" }} />
|
<WarningFilled style={{ margin: 4, color: "red" }} />
|
||||||
) : null}
|
) : null}
|
||||||
@@ -87,8 +93,13 @@ export default function JobNotesComponent({
|
|||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setExistingNote(record);
|
setNoteUpsertContext({
|
||||||
setNoteModalVisible(true);
|
actions: { refetch: refetch },
|
||||||
|
context: {
|
||||||
|
jobId: jobId,
|
||||||
|
existingNote: record
|
||||||
|
}
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<EditFilled />
|
<EditFilled />
|
||||||
@@ -100,17 +111,15 @@ export default function JobNotesComponent({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<NoteUpsertModal
|
<NoteUpsertModal />
|
||||||
jobId={jobId}
|
|
||||||
visible={noteModalVisible}
|
|
||||||
changeVisibility={setNoteModalVisible}
|
|
||||||
refetch={refetch}
|
|
||||||
existingNote={existingNote}
|
|
||||||
/>
|
|
||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setExistingNote(null);
|
setNoteUpsertContext({
|
||||||
setNoteModalVisible(true);
|
actions: { refetch: refetch },
|
||||||
|
context: {
|
||||||
|
jobId: jobId
|
||||||
|
}
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{t("notes.actions.new")}
|
{t("notes.actions.new")}
|
||||||
@@ -125,3 +134,4 @@ export default function JobNotesComponent({
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
export default connect(null, mapDispatchToProps)(JobNotesComponent);
|
||||||
|
|||||||
@@ -1,58 +1,41 @@
|
|||||||
import { Input, Modal, Switch } from "antd";
|
import { Form, Input, Switch } from "antd";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
export default function NoteUpsertModalComponent({
|
export default function NoteUpsertModalComponent() {
|
||||||
visible,
|
|
||||||
changeVisibility,
|
|
||||||
noteState,
|
|
||||||
setNoteState,
|
|
||||||
updateExistingNote,
|
|
||||||
insertNewNote
|
|
||||||
}) {
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<div>
|
||||||
title={noteState.id ? t("notes.actions.edit") : t("notes.actions.new")}
|
<Form.Item
|
||||||
visible={visible}
|
label={t("notes.fields.critical")}
|
||||||
okText={t("general.actions.save")}
|
name="critical"
|
||||||
onOk={() => {
|
valuePropName="checked"
|
||||||
noteState.id ? updateExistingNote() : insertNewNote();
|
>
|
||||||
}}
|
<Switch />
|
||||||
onCancel={() => {
|
</Form.Item>
|
||||||
changeVisibility(false);
|
<Form.Item
|
||||||
}}
|
label={t("notes.fields.private")}
|
||||||
>
|
name="private"
|
||||||
<div>
|
valuePropName="checked"
|
||||||
{t("notes.fields.critical")}
|
>
|
||||||
<Switch
|
<Switch />
|
||||||
title={t("notes.fields.critical")}
|
</Form.Item>
|
||||||
checked={noteState.critical}
|
<Form.Item
|
||||||
onChange={checked => {
|
label={t("notes.fields.text")}
|
||||||
setNoteState({ ...noteState, critical: checked });
|
name="text"
|
||||||
}}
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: t("general.validation.required")
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Input.TextArea
|
||||||
|
rows={8}
|
||||||
|
placeholder={t("notes.labels.newnoteplaceholder")}
|
||||||
/>
|
/>
|
||||||
</div>
|
</Form.Item>
|
||||||
<div>
|
</div>
|
||||||
{t("notes.fields.private")}
|
|
||||||
<Switch
|
|
||||||
title={t("notes.fields.private")}
|
|
||||||
checked={noteState.private}
|
|
||||||
onChange={checked => {
|
|
||||||
setNoteState({ ...noteState, private: checked });
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Input.TextArea
|
|
||||||
rows={8}
|
|
||||||
value={noteState.text}
|
|
||||||
placeholder={t("notes.labels.newnoteplaceholder")}
|
|
||||||
onChange={e => {
|
|
||||||
setNoteState({ ...noteState, text: e.target.value });
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Modal>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,84 +1,97 @@
|
|||||||
import { notification } from "antd";
|
|
||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { useMutation } from "@apollo/react-hooks";
|
import { useMutation } from "@apollo/react-hooks";
|
||||||
|
import { Form, Modal, notification } from "antd";
|
||||||
|
import React, { useEffect } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { INSERT_NEW_NOTE, UPDATE_NOTE } from "../../graphql/notes.queries";
|
|
||||||
import NoteUpsertModalComponent from "./note-upsert-modal.component";
|
|
||||||
|
|
||||||
|
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
|
import { INSERT_NEW_NOTE, UPDATE_NOTE } from "../../graphql/notes.queries";
|
||||||
|
import { toggleModalVisible } from "../../redux/modals/modals.actions";
|
||||||
|
import { selectNoteUpsert } from "../../redux/modals/modals.selectors";
|
||||||
import { selectCurrentUser } from "../../redux/user/user.selectors";
|
import { selectCurrentUser } from "../../redux/user/user.selectors";
|
||||||
|
import NoteUpsertModalComponent from "./note-upsert-modal.component";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
currentUser: selectCurrentUser
|
currentUser: selectCurrentUser,
|
||||||
|
noteUpsertModal: selectNoteUpsert
|
||||||
|
});
|
||||||
|
const mapDispatchToProps = dispatch => ({
|
||||||
|
toggleModalVisible: () => dispatch(toggleModalVisible("noteUpsert"))
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect (mapStateToProps,null)( function NoteUpsertModalContainer({
|
export function NoteUpsertModalContainer({
|
||||||
jobId,
|
currentUser,
|
||||||
visible,
|
noteUpsertModal,
|
||||||
changeVisibility,
|
toggleModalVisible
|
||||||
refetch,
|
|
||||||
existingNote,currentUser
|
|
||||||
}) {
|
}) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [insertNote] = useMutation(INSERT_NEW_NOTE);
|
const [insertNote] = useMutation(INSERT_NEW_NOTE);
|
||||||
const [updateNote] = useMutation(UPDATE_NOTE);
|
const [updateNote] = useMutation(UPDATE_NOTE);
|
||||||
|
|
||||||
const [noteState, setNoteState] = useState({
|
const { visible, context, actions } = noteUpsertModal;
|
||||||
private: false,
|
const { jobId, existingNote } = context;
|
||||||
critical: false,
|
const { refetch } = actions;
|
||||||
text: ""
|
|
||||||
});
|
const [form] = Form.useForm();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
//Required to prevent infinite looping.
|
//Required to prevent infinite looping.
|
||||||
if (existingNote) {
|
if (existingNote) {
|
||||||
setNoteState(existingNote);
|
form.resetFields();
|
||||||
}
|
}
|
||||||
}, [existingNote]);
|
}, [existingNote, form]);
|
||||||
|
|
||||||
const insertNewNote = () => {
|
const handleFinish = values => {
|
||||||
insertNote({
|
if (existingNote) {
|
||||||
variables: {
|
updateNote({
|
||||||
noteInput: [
|
variables: {
|
||||||
{ ...noteState, jobid: jobId, created_by: currentUser.email }
|
noteId: existingNote.id,
|
||||||
]
|
note: values
|
||||||
}
|
}
|
||||||
}).then(r => {
|
}).then(r => {
|
||||||
refetch();
|
notification["success"]({
|
||||||
changeVisibility(!visible);
|
message: t("notes.successes.updated")
|
||||||
notification["success"]({
|
});
|
||||||
message: t("notes.successes.create")
|
|
||||||
});
|
});
|
||||||
});
|
if (refetch) refetch();
|
||||||
};
|
toggleModalVisible();
|
||||||
|
} else {
|
||||||
const updateExistingNote = () => {
|
insertNote({
|
||||||
//Required, otherwise unable to spread in new note prop.
|
variables: {
|
||||||
delete noteState.__typename;
|
noteInput: [
|
||||||
updateNote({
|
{ ...values, jobid: jobId, created_by: currentUser.email }
|
||||||
variables: {
|
]
|
||||||
noteId: noteState.id,
|
}
|
||||||
note: noteState
|
}).then(r => {
|
||||||
}
|
if (refetch) refetch();
|
||||||
}).then(r => {
|
toggleModalVisible();
|
||||||
notification["success"]({
|
notification["success"]({
|
||||||
message: t("notes.successes.updated")
|
message: t("notes.successes.create")
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
refetch();
|
|
||||||
changeVisibility(!visible);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NoteUpsertModalComponent
|
<Modal
|
||||||
|
title={existingNote ? t("notes.actions.edit") : t("notes.actions.new")}
|
||||||
visible={visible}
|
visible={visible}
|
||||||
changeVisibility={changeVisibility}
|
okText={t("general.actions.save")}
|
||||||
updateExistingNote={updateExistingNote}
|
onOk={() => {
|
||||||
insertNewNote={insertNewNote}
|
form.submit();
|
||||||
noteState={noteState}
|
}}
|
||||||
setNoteState={setNoteState}
|
onCancel={() => {
|
||||||
/>
|
toggleModalVisible();
|
||||||
|
}}
|
||||||
|
destroyOnClose
|
||||||
|
>
|
||||||
|
<Form form={form} onFinish={handleFinish} initialValues={existingNote}>
|
||||||
|
<NoteUpsertModalComponent />
|
||||||
|
</Form>
|
||||||
|
</Modal>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(NoteUpsertModalContainer);
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ const baseModal = {
|
|||||||
const INITIAL_STATE = {
|
const INITIAL_STATE = {
|
||||||
jobLineEdit: { ...baseModal },
|
jobLineEdit: { ...baseModal },
|
||||||
invoiceEnter: { ...baseModal },
|
invoiceEnter: { ...baseModal },
|
||||||
courtesyCarReturn: { ...baseModal }
|
courtesyCarReturn: { ...baseModal },
|
||||||
|
noteUpsert: { ...baseModal }
|
||||||
};
|
};
|
||||||
|
|
||||||
const modalsReducer = (state = INITIAL_STATE, action) => {
|
const modalsReducer = (state = INITIAL_STATE, action) => {
|
||||||
|
|||||||
@@ -17,3 +17,7 @@ export const selectCourtesyCarReturn = createSelector(
|
|||||||
modals => modals.courtesyCarReturn
|
modals => modals.courtesyCarReturn
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const selectNoteUpsert = createSelector(
|
||||||
|
[selectModals],
|
||||||
|
modals => modals.noteUpsert
|
||||||
|
);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
const ModalActionTypes = {
|
const ModalActionTypes = {
|
||||||
TOGGLE_MODAL_VISIBLE: "TOGGLE_MODAL_VISIBLE",
|
TOGGLE_MODAL_VISIBLE: "TOGGLE_MODAL_VISIBLE",
|
||||||
SET_MODAL_CONTEXT: "SET_JOBLINEEDIT_CONTEXT"
|
SET_MODAL_CONTEXT: "SET_MODAL_CONTEXT"
|
||||||
};
|
};
|
||||||
export default ModalActionTypes;
|
export default ModalActionTypes;
|
||||||
|
|||||||
Reference in New Issue
Block a user