diff --git a/client/package-lock.json b/client/package-lock.json index 795453627..502852653 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -66,7 +66,6 @@ "react-resizable": "^3.0.5", "react-router-dom": "^6.26.2", "react-sticky": "^6.0.3", - "react-virtualized": "^9.22.5", "react-virtuoso": "^4.10.4", "recharts": "^2.12.7", "redux": "^5.0.1", @@ -6422,6 +6421,7 @@ "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==", + "license": "MIT", "dependencies": { "core-js": "^2.4.0", "regenerator-runtime": "^0.11.0" @@ -6430,7 +6430,8 @@ "node_modules/babel-runtime/node_modules/regenerator-runtime": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "license": "MIT" }, "node_modules/backo2": { "version": "1.0.2", @@ -7363,7 +7364,8 @@ "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", - "hasInstallScript": true + "hasInstallScript": true, + "license": "MIT" }, "node_modules/core-js-compat": { "version": "3.37.1", @@ -14276,6 +14278,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/react-drag-listview/-/react-drag-listview-2.0.0.tgz", "integrity": "sha512-7Apx/1Xt4qu+JHHP0rH6aLgZgS7c2MX8ocHVGCi03KfeIWEu0t14MhT3boQKM33l5eJrE/IWfExFTvoYq22fsg==", + "license": "MIT", "dependencies": { "babel-runtime": "^6.26.0", "prop-types": "^15.5.8" @@ -14596,23 +14599,6 @@ "react-dom": ">=16.6.0" } }, - "node_modules/react-virtualized": { - "version": "9.22.5", - "resolved": "https://registry.npmjs.org/react-virtualized/-/react-virtualized-9.22.5.tgz", - "integrity": "sha512-YqQMRzlVANBv1L/7r63OHa2b0ZsAaDp1UhVNEdUaXI8A5u6hTpA5NYtUueLH2rFuY/27mTGIBl7ZhqFKzw18YQ==", - "dependencies": { - "@babel/runtime": "^7.7.2", - "clsx": "^1.0.4", - "dom-helpers": "^5.1.3", - "loose-envify": "^1.4.0", - "prop-types": "^15.7.2", - "react-lifecycles-compat": "^3.0.4" - }, - "peerDependencies": { - "react": "^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0", - "react-dom": "^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0" - } - }, "node_modules/react-virtuoso": { "version": "4.10.4", "resolved": "https://registry.npmjs.org/react-virtuoso/-/react-virtuoso-4.10.4.tgz", diff --git a/client/package.json b/client/package.json index ae8724b9a..f5889dad5 100644 --- a/client/package.json +++ b/client/package.json @@ -65,7 +65,6 @@ "react-resizable": "^3.0.5", "react-router-dom": "^6.26.2", "react-sticky": "^6.0.3", - "react-virtualized": "^9.22.5", "react-virtuoso": "^4.10.4", "recharts": "^2.12.7", "redux": "^5.0.1", diff --git a/client/src/App/App.jsx b/client/src/App/App.jsx index 8099b09bb..26f44fc8d 100644 --- a/client/src/App/App.jsx +++ b/client/src/App/App.jsx @@ -22,6 +22,7 @@ import Eula from "../components/eula/eula.component"; import InstanceRenderMgr from "../utils/instanceRenderMgr"; import ProductFruitsWrapper from "./ProductFruitsWrapper.jsx"; import { SocketProvider } from "../contexts/SocketIO/socketContext.jsx"; +import { NotificationProvider } from "../contexts/Notifications/notificationContext.jsx"; const ResetPassword = lazy(() => import("../pages/reset-password/reset-password.component")); const ManagePage = lazy(() => import("../pages/manage/manage.page.container")); @@ -145,84 +146,85 @@ export function App({ bodyshop, checkUserSession, currentUser, online, setOnline rome: "9BkbEseqNqxw8jUH" })} /> - - - - - - } - /> - - - - } - /> - - - - } - /> - - - - } - /> - - - - } - /> - - - - } - /> - - - - - - } - > - } /> - - - - - - - } - > - } /> - - }> - } /> - - + + + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + + + } + > + } /> + + + + + + + } + > + } /> + + }> + } /> + + + ); } diff --git a/client/src/components/allocations-assignment/allocations-assignment.container.jsx b/client/src/components/allocations-assignment/allocations-assignment.container.jsx index 43d4b306c..60a0f68dc 100644 --- a/client/src/components/allocations-assignment/allocations-assignment.container.jsx +++ b/client/src/components/allocations-assignment/allocations-assignment.container.jsx @@ -3,7 +3,7 @@ import AllocationsAssignmentComponent from "./allocations-assignment.component"; import { useMutation } from "@apollo/client"; import { INSERT_ALLOCATION } from "../../graphql/allocations.queries"; import { useTranslation } from "react-i18next"; -import { notification } from "antd"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; export default function AllocationsAssignmentContainer({ jobLineId, hours, refetch }) { const visibilityState = useState(false); @@ -14,6 +14,7 @@ export default function AllocationsAssignmentContainer({ jobLineId, hours, refet employeeid: null }); const [insertAllocation] = useMutation(INSERT_ALLOCATION); + const notification = useNotification(); const handleAssignment = () => { insertAllocation({ variables: { alloc: { ...assignment } } }) diff --git a/client/src/components/allocations-bulk-assignment/allocations-bulk-assignment.container.jsx b/client/src/components/allocations-bulk-assignment/allocations-bulk-assignment.container.jsx index ea68dd129..fa298b7e8 100644 --- a/client/src/components/allocations-bulk-assignment/allocations-bulk-assignment.container.jsx +++ b/client/src/components/allocations-bulk-assignment/allocations-bulk-assignment.container.jsx @@ -3,7 +3,7 @@ import AllocationsBulkAssignment from "./allocations-bulk-assignment.component"; import { useMutation } from "@apollo/client"; import { INSERT_ALLOCATION } from "../../graphql/allocations.queries"; import { useTranslation } from "react-i18next"; -import { notification } from "antd"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; export default function AllocationsBulkAssignmentContainer({ jobLines, refetch }) { const visibilityState = useState(false); @@ -12,6 +12,7 @@ export default function AllocationsBulkAssignmentContainer({ jobLines, refetch } employeeid: null }); const [insertAllocation] = useMutation(INSERT_ALLOCATION); + const notification = useNotification(); const handleAssignment = () => { const allocs = jobLines.reduce((acc, value) => { diff --git a/client/src/components/allocations-employee-label/allocations-employee-label.container.jsx b/client/src/components/allocations-employee-label/allocations-employee-label.container.jsx index 44fe5d43e..af93f1798 100644 --- a/client/src/components/allocations-employee-label/allocations-employee-label.container.jsx +++ b/client/src/components/allocations-employee-label/allocations-employee-label.container.jsx @@ -2,12 +2,13 @@ import React from "react"; import { useMutation } from "@apollo/client"; import { DELETE_ALLOCATION } from "../../graphql/allocations.queries"; import AllocationsLabelComponent from "./allocations-employee-label.component"; -import { notification } from "antd"; import { useTranslation } from "react-i18next"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; export default function AllocationsLabelContainer({ allocation, refetch }) { const [deleteAllocation] = useMutation(DELETE_ALLOCATION); const { t } = useTranslation(); + const notification = useNotification(); const handleClick = (e) => { e.preventDefault(); diff --git a/client/src/components/bill-delete-button/bill-delete-button.component.jsx b/client/src/components/bill-delete-button/bill-delete-button.component.jsx index 55c9a9072..5ab24d60f 100644 --- a/client/src/components/bill-delete-button/bill-delete-button.component.jsx +++ b/client/src/components/bill-delete-button/bill-delete-button.component.jsx @@ -1,6 +1,6 @@ import { DeleteFilled } from "@ant-design/icons"; import { useMutation } from "@apollo/client"; -import { Button, notification, Popconfirm } from "antd"; +import { Button, Popconfirm } from "antd"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { DELETE_BILL } from "../../graphql/bills.queries"; @@ -9,6 +9,7 @@ import { insertAuditTrail } from "../../redux/application/application.actions"; import AuditTrailMapping from "../../utils/AuditTrailMappings"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({}); const mapDispatchToProps = (dispatch) => ({ @@ -21,6 +22,7 @@ export function BillDeleteButton({ bill, jobid, callback, insertAuditTrail }) { const [loading, setLoading] = useState(false); const { t } = useTranslation(); const [deleteBill] = useMutation(DELETE_BILL); + const notification = useNotification(); const handleDelete = async () => { setLoading(true); diff --git a/client/src/components/bill-enter-modal/bill-enter-modal.container.jsx b/client/src/components/bill-enter-modal/bill-enter-modal.container.jsx index 18d6db174..a86a1fbea 100644 --- a/client/src/components/bill-enter-modal/bill-enter-modal.container.jsx +++ b/client/src/components/bill-enter-modal/bill-enter-modal.container.jsx @@ -1,6 +1,6 @@ import { useApolloClient, useMutation } from "@apollo/client"; import { useSplitTreatments } from "@splitsoftware/splitio-react"; -import { Button, Checkbox, Form, Modal, notification, Space } from "antd"; +import { Button, Checkbox, Form, Modal, Space } from "antd"; import _ from "lodash"; import React, { useEffect, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -24,6 +24,7 @@ import BillFormContainer from "../bill-form/bill-form.container"; import { CalculateBillTotal } from "../bill-form/bill-form.totals.utility"; import { handleUpload as handleLocalUpload } from "../documents-local-upload/documents-local-upload.utility"; import { handleUpload } from "../documents-upload/documents-upload.utility"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ billEnterModal: selectBillEnterModal, @@ -49,6 +50,7 @@ function BillEnterModalContainer({ billEnterModal, toggleModalVisible, bodyshop, const [loading, setLoading] = useState(false); const client = useApolloClient(); const [generateLabel, setGenerateLabel] = useLocalStorage("enter_bill_generate_label", false); + const notification = useNotification(); const { treatments: { Enhanced_Payroll } @@ -291,7 +293,8 @@ function BillEnterModalContainer({ billEnterModal, toggleModalVisible, bodyshop, jobid: values.jobid, invoice_number: remainingValues.invoice_number, vendorid: remainingValues.vendorid - } + }, + notification }); }); } else { @@ -305,7 +308,8 @@ function BillEnterModalContainer({ billEnterModal, toggleModalVisible, bodyshop, billId: billId, tagsArray: null, callback: null - } + }, + notification ); }); } @@ -325,7 +329,9 @@ function BillEnterModalContainer({ billEnterModal, toggleModalVisible, bodyshop, } }, {}, - "p" + "p", + null, + notification ); } diff --git a/client/src/components/bill-form/bill-form.lines.component.jsx b/client/src/components/bill-form/bill-form.lines.component.jsx index ae0840cc1..896c529eb 100644 --- a/client/src/components/bill-form/bill-form.lines.component.jsx +++ b/client/src/components/bill-form/bill-form.lines.component.jsx @@ -473,7 +473,7 @@ export function BillEnterModalLinesComponent({ valuePropName: "checked", initialValue: InstanceRenderManager({ imex: true, - rome: false, + rome: false }), name: [field.name, "applicable_taxes", "federal"] }; @@ -625,11 +625,15 @@ const EditableCell = ({ wrapper, ...restProps }) => { + const propsFinal = formItemProps && formItemProps(record); + if (propsFinal && "key" in propsFinal) { + delete propsFinal.key; + } if (additional) return (
- + {(formInput && formInput(record, record.name)) || children} {additional && additional(record, record.name)} @@ -640,7 +644,7 @@ const EditableCell = ({ return ( - + {(formInput && formInput(record, record.name)) || children} @@ -648,7 +652,7 @@ const EditableCell = ({ ); return ( - + {(formInput && formInput(record, record.name)) || children} diff --git a/client/src/components/bill-mark-exported-button/bill-mark-exported-button.component.jsx b/client/src/components/bill-mark-exported-button/bill-mark-exported-button.component.jsx index 5a5720135..a3954a626 100644 --- a/client/src/components/bill-mark-exported-button/bill-mark-exported-button.component.jsx +++ b/client/src/components/bill-mark-exported-button/bill-mark-exported-button.component.jsx @@ -1,5 +1,5 @@ import { gql, useMutation } from "@apollo/client"; -import { Button, notification } from "antd"; +import { Button } from "antd"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; @@ -8,6 +8,7 @@ import { createStructuredSelector } from "reselect"; import { selectAuthLevel, selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors"; import { HasRbacAccess } from "../rbac-wrapper/rbac-wrapper.component"; import { INSERT_EXPORT_LOG } from "../../graphql/accounting.queries"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -24,6 +25,7 @@ export function BillMarkExportedButton({ currentUser, bodyshop, authLevel, bill const { t } = useTranslation(); const [loading, setLoading] = useState(false); const [insertExportLog] = useMutation(INSERT_EXPORT_LOG); + const notification = useNotification(); const [updateBill] = useMutation(gql` mutation UPDATE_BILL($billId: uuid!) { diff --git a/client/src/components/bill-print-button/bill-print-button.component.jsx b/client/src/components/bill-print-button/bill-print-button.component.jsx index f63b9a13f..70449db3e 100644 --- a/client/src/components/bill-print-button/bill-print-button.component.jsx +++ b/client/src/components/bill-print-button/bill-print-button.component.jsx @@ -3,11 +3,13 @@ import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { GenerateDocument } from "../../utils/RenderTemplate"; import { TemplateList } from "../../utils/TemplateConstants"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; export default function BillPrintButton({ billid }) { const { t } = useTranslation(); const [loading, setLoading] = useState(false); const Templates = TemplateList("job_special"); + const notification = useNotification(); const submitHandler = async () => { setLoading(true); @@ -20,7 +22,9 @@ export default function BillPrintButton({ billid }) { } }, {}, - "p" + "p", + null, + notification ); } catch (e) { console.warn("Warning: Error generating a document."); diff --git a/client/src/components/bill-reexport-button/bill-reexport-button.component.jsx b/client/src/components/bill-reexport-button/bill-reexport-button.component.jsx index 81da224d7..03c5e47e7 100644 --- a/client/src/components/bill-reexport-button/bill-reexport-button.component.jsx +++ b/client/src/components/bill-reexport-button/bill-reexport-button.component.jsx @@ -1,5 +1,5 @@ import { gql, useMutation } from "@apollo/client"; -import { Button, notification } from "antd"; +import { Button } from "antd"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; @@ -7,6 +7,7 @@ import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import { selectAuthLevel, selectBodyshop } from "../../redux/user/user.selectors"; import { HasRbacAccess } from "../rbac-wrapper/rbac-wrapper.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -21,6 +22,7 @@ export default connect(mapStateToProps, mapDispatchToProps)(BillMarkForReexportB export function BillMarkForReexportButton({ bodyshop, authLevel, bill }) { const { t } = useTranslation(); const [loading, setLoading] = useState(false); + const notification = useNotification(); const [updateBill] = useMutation(gql` mutation UPDATE_BILL($billId: uuid!) { diff --git a/client/src/components/billline-add-inventory/billline-add-inventory.component.jsx b/client/src/components/billline-add-inventory/billline-add-inventory.component.jsx index 63d322b79..81321bcbc 100644 --- a/client/src/components/billline-add-inventory/billline-add-inventory.component.jsx +++ b/client/src/components/billline-add-inventory/billline-add-inventory.component.jsx @@ -1,6 +1,6 @@ import { FileAddFilled } from "@ant-design/icons"; import { useMutation } from "@apollo/client"; -import { Button, notification, Tooltip } from "antd"; +import { Button, Tooltip } from "antd"; import { t } from "i18next"; import dayjs from "./../../utils/day"; import React, { useState } from "react"; @@ -11,6 +11,7 @@ import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selecto import { CalculateBillTotal } from "../bill-form/bill-form.totals.utility"; import queryString from "query-string"; import { useLocation } from "react-router-dom"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -25,6 +26,7 @@ export function BilllineAddInventory({ currentUser, bodyshop, billline, disabled const [loading, setLoading] = useState(false); const { billid } = queryString.parse(useLocation().search); const [insertInventoryLine] = useMutation(INSERT_INVENTORY_AND_CREDIT); + const notification = useNotification(); const addToInventory = async () => { setLoading(true); diff --git a/client/src/components/ca-bc-etf-table-modal/ca-bc-etf-table-modal.container.jsx b/client/src/components/ca-bc-etf-table-modal/ca-bc-etf-table-modal.container.jsx index 04c49e2db..4d69f43cd 100644 --- a/client/src/components/ca-bc-etf-table-modal/ca-bc-etf-table-modal.container.jsx +++ b/client/src/components/ca-bc-etf-table-modal/ca-bc-etf-table-modal.container.jsx @@ -9,6 +9,7 @@ import { selectCaBcEtfTableConvert } from "../../redux/modals/modals.selectors"; import { GenerateDocument } from "../../utils/RenderTemplate"; import { TemplateList } from "../../utils/TemplateConstants"; import CaBcEtfTableModalComponent from "./ca-bc-etf-table.modal.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ caBcEtfTableModal: selectCaBcEtfTableConvert @@ -25,6 +26,7 @@ export function ContractsFindModalContainer({ caBcEtfTableModal, toggleModalVisi const [loading, setLoading] = useState(false); const [form] = Form.useForm(); const EtfTemplate = TemplateList("special").ca_bc_etf_table; + const notification = useNotification(); const handleFinish = async (values) => { logImEXEvent("ca_bc_etf_table_parse"); @@ -53,7 +55,9 @@ export function ContractsFindModalContainer({ caBcEtfTableModal, toggleModalVisi } }, {}, - values.sendby === "email" ? "e" : "p" + values.sendby === "email" ? "e" : "p", + null, + notification ); setLoading(false); }; diff --git a/client/src/components/card-payment-modal/card-payment-modal.component.jsx b/client/src/components/card-payment-modal/card-payment-modal.component.jsx index ae90d2d9e..7e82168a0 100644 --- a/client/src/components/card-payment-modal/card-payment-modal.component.jsx +++ b/client/src/components/card-payment-modal/card-payment-modal.component.jsx @@ -1,6 +1,6 @@ import { CopyFilled, DeleteFilled } from "@ant-design/icons"; import { useLazyQuery, useMutation } from "@apollo/client"; -import { Button, Card, Col, Form, Input, message, notification, Row, Space, Spin, Statistic } from "antd"; +import { Button, Card, Col, Form, Input, message, Row, Space, Spin, Statistic } from "antd"; import axios from "axios"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; @@ -15,6 +15,7 @@ import AuditTrailMapping from "../../utils/AuditTrailMappings"; import CurrencyFormItemComponent from "../form-items-formatted/currency-form-item.component"; import JobSearchSelectComponent from "../job-search-select/job-search-select.component"; import { getCurrentUser } from "../../firebase/firebase.utils"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ cardPaymentModal: selectCardPayment, @@ -48,6 +49,7 @@ const CardPaymentModalComponent = ({ const [loading, setLoading] = useState(false); const [insertPaymentResponse] = useMutation(INSERT_PAYMENT_RESPONSE); const { t } = useTranslation(); + const notification = useNotification(); const [, { data, refetch, queryLoading }] = useLazyQuery(QUERY_RO_AND_OWNER_BY_JOB_PKS, { variables: { jobids: [context.jobid] }, diff --git a/client/src/components/chat-label/chat-label.component.jsx b/client/src/components/chat-label/chat-label.component.jsx index 0764869ee..ddd367798 100644 --- a/client/src/components/chat-label/chat-label.component.jsx +++ b/client/src/components/chat-label/chat-label.component.jsx @@ -1,6 +1,6 @@ import { PlusOutlined } from "@ant-design/icons"; import { useMutation } from "@apollo/client"; -import { Input, notification, Spin, Tag, Tooltip } from "antd"; +import { Input, Spin, Tag, Tooltip } from "antd"; import React, { useContext, useState } from "react"; import { useTranslation } from "react-i18next"; import { UPDATE_CONVERSATION_LABEL } from "../../graphql/conversations.queries"; @@ -8,6 +8,7 @@ import SocketContext from "../../contexts/SocketIO/socketContext.jsx"; import { createStructuredSelector } from "reselect"; import { selectBodyshop } from "../../redux/user/user.selectors.js"; import { connect } from "react-redux"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop @@ -20,6 +21,7 @@ export function ChatLabel({ conversation, bodyshop }) { const [editing, setEditing] = useState(false); const [value, setValue] = useState(conversation.label); const { socket } = useContext(SocketContext); + const notification = useNotification(); const { t } = useTranslation(); const [updateLabel] = useMutation(UPDATE_CONVERSATION_LABEL); diff --git a/client/src/components/chat-open-button/chat-open-button.component.jsx b/client/src/components/chat-open-button/chat-open-button.component.jsx index dcd41c041..42cd5dc82 100644 --- a/client/src/components/chat-open-button/chat-open-button.component.jsx +++ b/client/src/components/chat-open-button/chat-open-button.component.jsx @@ -1,4 +1,3 @@ -import { notification } from "antd"; import parsePhoneNumber from "libphonenumber-js"; import React, { useContext } from "react"; import { useTranslation } from "react-i18next"; @@ -10,6 +9,7 @@ import { createStructuredSelector } from "reselect"; import { selectBodyshop } from "../../redux/user/user.selectors"; import { searchingForConversation } from "../../redux/messaging/messaging.selectors"; import SocketContext from "../../contexts/SocketIO/socketContext.jsx"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -23,6 +23,7 @@ const mapDispatchToProps = (dispatch) => ({ export function ChatOpenButton({ bodyshop, searchingForConversation, phone, jobid, openChatByPhone }) { const { t } = useTranslation(); const { socket } = useContext(SocketContext); + const notification = useNotification(); if (!phone) return <>; diff --git a/client/src/components/chat-print-button/chat-print-button.component.jsx b/client/src/components/chat-print-button/chat-print-button.component.jsx index 0b175b769..eb6491b33 100644 --- a/client/src/components/chat-print-button/chat-print-button.component.jsx +++ b/client/src/components/chat-print-button/chat-print-button.component.jsx @@ -6,6 +6,7 @@ import { createStructuredSelector } from "reselect"; import { setEmailOptions } from "../../redux/email/email.actions"; import { GenerateDocument } from "../../utils/RenderTemplate"; import { TemplateList } from "../../utils/TemplateConstants"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({}); @@ -15,6 +16,7 @@ const mapDispatchToProps = (dispatch) => ({ export function ChatPrintButton({ conversation }) { const [loading, setLoading] = useState(false); + const notification = useNotification(); const generateDocument = (type) => { setLoading(true); @@ -27,7 +29,8 @@ export function ChatPrintButton({ conversation }) { subject: TemplateList("messaging").conversation_list.subject }, type, - conversation.id + conversation.id, + notification ).catch((e) => { console.warn("Something went wrong generating a document."); }); diff --git a/client/src/components/contract-convert-to-ro/contract-convert-to-ro.component.jsx b/client/src/components/contract-convert-to-ro/contract-convert-to-ro.component.jsx index ee8d01ed6..e4655c23b 100644 --- a/client/src/components/contract-convert-to-ro/contract-convert-to-ro.component.jsx +++ b/client/src/components/contract-convert-to-ro/contract-convert-to-ro.component.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { Button, Form, InputNumber, notification, Popover, Radio, Select, Space } from "antd"; +import { Button, Form, InputNumber, Popover, Radio, Select, Space } from "antd"; import axios from "axios"; import dayjs from "../../utils/day"; import React, { useState } from "react"; @@ -9,6 +9,7 @@ import { useNavigate } from "react-router-dom"; import { createStructuredSelector } from "reselect"; import { INSERT_NEW_JOB } from "../../graphql/jobs.queries"; import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ //currentUser: selectCurrentUser @@ -25,6 +26,7 @@ export function ContractConvertToRo({ bodyshop, currentUser, contract, disabled const [loading, setLoading] = useState(false); const [insertJob] = useMutation(INSERT_NEW_JOB); const history = useNavigate(); + const notification = useNotification(); const handleFinish = async (values) => { setLoading(true); diff --git a/client/src/components/contract-form/contract-form-job-prefill.component.jsx b/client/src/components/contract-form/contract-form-job-prefill.component.jsx index 76f32023f..6d63f5b8a 100644 --- a/client/src/components/contract-form/contract-form-job-prefill.component.jsx +++ b/client/src/components/contract-form/contract-form-job-prefill.component.jsx @@ -1,12 +1,14 @@ import { useLazyQuery } from "@apollo/client"; -import { Button, notification } from "antd"; +import { Button } from "antd"; import React, { useEffect } from "react"; import { useTranslation } from "react-i18next"; import { GET_JOB_FOR_CC_CONTRACT } from "../../graphql/jobs.queries"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; export default function ContractCreateJobPrefillComponent({ jobId, form }) { const [call, { loading, error, data }] = useLazyQuery(GET_JOB_FOR_CC_CONTRACT); const { t } = useTranslation(); + const notification = useNotification(); const handleClick = () => { call({ variables: { id: jobId } }); diff --git a/client/src/components/courtesy-car-return-modal/courtesy-car-return-modal.container.jsx b/client/src/components/courtesy-car-return-modal/courtesy-car-return-modal.container.jsx index acbfc6ff0..210f7887a 100644 --- a/client/src/components/courtesy-car-return-modal/courtesy-car-return-modal.container.jsx +++ b/client/src/components/courtesy-car-return-modal/courtesy-car-return-modal.container.jsx @@ -1,4 +1,4 @@ -import { Form, Modal, notification } from "antd"; +import { Form, Modal } from "antd"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; @@ -10,6 +10,7 @@ import CourtesyCarReturnModalComponent from "./courtesy-car-return-modal.compone import dayjs from "../../utils/day"; import { RETURN_CONTRACT } from "../../graphql/cccontracts.queries"; import { useMutation } from "@apollo/client"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ courtesyCarReturnModal: selectCourtesyCarReturn, @@ -26,6 +27,8 @@ export function CCReturnModalContainer({ courtesyCarReturnModal, toggleModalVisi const { t } = useTranslation(); const [form] = Form.useForm(); const [updateContract] = useMutation(RETURN_CONTRACT); + const notification = useNotification(); + const handleFinish = (values) => { setLoading(true); updateContract({ diff --git a/client/src/components/courtesy-cars-list/courtesy-cars-list.component.jsx b/client/src/components/courtesy-cars-list/courtesy-cars-list.component.jsx index 2f96c7491..eaf0efb45 100644 --- a/client/src/components/courtesy-cars-list/courtesy-cars-list.component.jsx +++ b/client/src/components/courtesy-cars-list/courtesy-cars-list.component.jsx @@ -10,6 +10,7 @@ import { TemplateList } from "../../utils/TemplateConstants"; import { alphaSort } from "../../utils/sorters"; import useLocalStorage from "../../utils/useLocalStorage"; import { OwnerNameDisplayFunction } from "../owner-name-display/owner-name-display.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; export default function CourtesyCarsList({ loading, courtesycars, refetch }) { const [state, setState] = useState({ @@ -18,6 +19,7 @@ export default function CourtesyCarsList({ loading, courtesycars, refetch }) { const [searchText, setSearchText] = useState(""); const [filter, setFilter] = useLocalStorage("filter_courtesy_cars_list", null); const { t } = useTranslation(); + const notification = useNotification(); const columns = [ { @@ -64,8 +66,8 @@ export default function CourtesyCarsList({ loading, courtesycars, refetch }) { }, { text: t("courtesycars.status.unavailable"), - value: "courtesycars.status.unavailable", - }, + value: "courtesycars.status.unavailable" + } ], onFilter: (value, record) => record.status === value, sortOrder: state.sortedInfo.columnKey === "status" && state.sortedInfo.order, @@ -239,7 +241,9 @@ export default function CourtesyCarsList({ loading, courtesycars, refetch }) { } }, {}, - "p" + "p", + null, + notification ) } ]; diff --git a/client/src/components/dashboard-grid/dashboard-grid.component.jsx b/client/src/components/dashboard-grid/dashboard-grid.component.jsx index 614dbb90f..6c3412a3d 100644 --- a/client/src/components/dashboard-grid/dashboard-grid.component.jsx +++ b/client/src/components/dashboard-grid/dashboard-grid.component.jsx @@ -1,6 +1,6 @@ import Icon, { SyncOutlined } from "@ant-design/icons"; import { gql, useMutation, useQuery } from "@apollo/client"; -import { Button, Dropdown, notification, Space } from "antd"; +import { Button, Dropdown, Space } from "antd"; import { PageHeader } from "@ant-design/pro-layout"; import i18next from "i18next"; import _ from "lodash"; @@ -46,6 +46,7 @@ import JobLifecycleDashboardComponent, { } from "../dashboard-components/job-lifecycle/job-lifecycle-dashboard.component"; import "./dashboard-grid.styles.scss"; import { GenerateDashboardData } from "./dashboard-grid.utils"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const ResponsiveReactGridLayout = WidthProvider(Responsive); @@ -64,6 +65,7 @@ export function DashboardGridComponent({ currentUser, bodyshop }) { ? bodyshop.associations[0].user.dashboardlayout : { items: [], layout: {}, layouts: [] }) }); + const notification = useNotification(); const { loading, error, data, refetch } = useQuery(createDashboardQuery(state), { fetchPolicy: "network-only", diff --git a/client/src/components/document-editor/document-editor.component.jsx b/client/src/components/document-editor/document-editor.component.jsx index 70c7293f3..4d2eddc52 100644 --- a/client/src/components/document-editor/document-editor.component.jsx +++ b/client/src/components/document-editor/document-editor.component.jsx @@ -9,6 +9,7 @@ import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selecto import { handleUpload } from "../documents-upload/documents-upload.utility"; import { GenerateSrcUrl } from "../jobs-documents-gallery/job-documents.utility"; import LoadingSpinner from "../loading-spinner/loading-spinner.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ currentUser: selectCurrentUser, @@ -24,6 +25,7 @@ export function DocumentEditorComponent({ currentUser, bodyshop, document }) { const [uploaded, setuploaded] = useState(false); const markerArea = useRef(null); const { t } = useTranslation(); + const notification = useNotification(); const triggerUpload = useCallback( async (dataUrl) => { @@ -45,10 +47,11 @@ export function DocumentEditorComponent({ currentUser, bodyshop, document }) { //billId: billId, tagsArray: ["edited"] //callback: callbackAfterUpload, - } + }, + notification ); }, - [bodyshop, currentUser, document] + [bodyshop, currentUser, document, notification] ); useEffect(() => { diff --git a/client/src/components/documents-local-upload/documents-local-upload.component.jsx b/client/src/components/documents-local-upload/documents-local-upload.component.jsx index cd756b8f2..bd59c9cf4 100644 --- a/client/src/components/documents-local-upload/documents-local-upload.component.jsx +++ b/client/src/components/documents-local-upload/documents-local-upload.component.jsx @@ -9,6 +9,7 @@ import { handleUpload } from "./documents-local-upload.utility"; import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component"; import LockWrapperComponent from "../lock-wrapper/lock-wrapper.component"; import { useTranslation } from "react-i18next"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ currentUser: selectCurrentUser, @@ -27,6 +28,8 @@ export function DocumentsLocalUploadComponent({ }) { const [fileList, setFileList] = useState([]); const { t } = useTranslation(); + const notification = useNotification(); + const handleDone = (uid) => { setTimeout(() => { setFileList((fileList) => fileList.filter((x) => x.uid !== uid)); @@ -53,7 +56,8 @@ export function DocumentsLocalUploadComponent({ vendorid, invoice_number, callback: callbackAfterUpload - } + }, + notification }) } {...(!allowAllTypes && { diff --git a/client/src/components/documents-local-upload/documents-local-upload.utility.js b/client/src/components/documents-local-upload/documents-local-upload.utility.js index 833ceedcf..69b5f41ea 100644 --- a/client/src/components/documents-local-upload/documents-local-upload.utility.js +++ b/client/src/components/documents-local-upload/documents-local-upload.utility.js @@ -2,10 +2,9 @@ import cleanAxios from "../../utils/CleanAxios"; import { store } from "../../redux/store"; import { addMediaForJob } from "../../redux/media/media.actions"; import normalizeUrl from "normalize-url"; -import { notification } from "antd"; import i18n from "i18next"; -export const handleUpload = async ({ ev, context }) => { +export const handleUpload = async ({ ev, context, notification }) => { const { onError, onSuccess, onProgress, file } = ev; const { jobid, invoice_number, vendorid, callbackAfterUpload } = context; @@ -43,11 +42,15 @@ export const handleUpload = async ({ ev, context }) => { } } else { onSuccess && onSuccess(file); - notification.open({ - type: "success", - key: "docuploadsuccess", - message: i18n.t("documents.successes.insert") - }); + if (notification) { + notification.open({ + type: "success", + key: "docuploadsuccess", + message: i18n.t("documents.successes.insert") + }); + } else { + console.error("No notification context found in document local upload utility."); + } store.dispatch( addMediaForJob({ jobid, diff --git a/client/src/components/documents-upload/documents-upload.component.jsx b/client/src/components/documents-upload/documents-upload.component.jsx index 0020d690a..bcadffc18 100644 --- a/client/src/components/documents-upload/documents-upload.component.jsx +++ b/client/src/components/documents-upload/documents-upload.component.jsx @@ -1,5 +1,5 @@ import { UploadOutlined } from "@ant-design/icons"; -import { notification, Progress, Result, Space, Upload } from "antd"; +import { Progress, Result, Space, Upload } from "antd"; import React, { useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; @@ -9,6 +9,7 @@ import formatBytes from "../../utils/formatbytes"; import { handleUpload } from "./documents-upload.utility"; import LockWrapperComponent from "../lock-wrapper/lock-wrapper.component"; import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ currentUser: selectCurrentUser, @@ -28,6 +29,7 @@ export function DocumentsUploadComponent({ }) { const { t } = useTranslation(); const [fileList, setFileList] = useState([]); + const notification = useNotification(); const pct = useMemo(() => { return parseInt((totalSize / ((bodyshop && bodyshop.jobsizelimit) || 1)) * 100); @@ -76,14 +78,18 @@ export function DocumentsUploadComponent({ return true; }} customRequest={(ev) => - handleUpload(ev, { - bodyshop: bodyshop, - uploaded_by: currentUser.email, - jobId: jobId, - billId: billId, - tagsArray: tagsArray, - callback: callbackAfterUpload - }) + handleUpload( + ev, + { + bodyshop: bodyshop, + uploaded_by: currentUser.email, + jobId: jobId, + billId: billId, + tagsArray: tagsArray, + callback: callbackAfterUpload + }, + notification + ) } accept="audio/*, video/*, image/*, .pdf, .doc, .docx, .xls, .xlsx" // showUploadList={false} diff --git a/client/src/components/documents-upload/documents-upload.utility.js b/client/src/components/documents-upload/documents-upload.utility.js index 6e2e12c24..ed8cb404f 100644 --- a/client/src/components/documents-upload/documents-upload.utility.js +++ b/client/src/components/documents-upload/documents-upload.utility.js @@ -1,4 +1,3 @@ -import { notification } from "antd"; import axios from "axios"; import i18n from "i18next"; import { logImEXEvent } from "../../firebase/firebase.utils"; @@ -14,7 +13,7 @@ import { store } from "../../redux/store"; var cleanAxios = axios.create(); cleanAxios.interceptors.request.eject(axiosAuthInterceptorId); -export const handleUpload = (ev, context) => { +export const handleUpload = (ev, context, notification) => { logImEXEvent("document_upload", { filetype: ev.file.type }); const { onError, onSuccess, onProgress } = ev; @@ -24,10 +23,20 @@ export const handleUpload = (ev, context) => { let key = `${bodyshop.id}/${jobId}/${replaceAccents(fileName).replace(/[^A-Z0-9]+/gi, "_")}-${new Date().getTime()}`; let extension = fileName.split(".").pop(); - uploadToCloudinary(key, extension, ev.file.type, ev.file, onError, onSuccess, onProgress, context); + uploadToCloudinary(key, extension, ev.file.type, ev.file, onError, onSuccess, onProgress, context, notification); }; -export const uploadToCloudinary = async (key, extension, fileType, file, onError, onSuccess, onProgress, context) => { +export const uploadToCloudinary = async ( + key, + extension, + fileType, + file, + onError, + onSuccess, + onProgress, + context, + notification +) => { const { bodyshop, jobId, billId, uploaded_by, callback, tagsArray } = context; //Set variables for getting the signed URL. diff --git a/client/src/components/email-overlay/email-overlay.container.jsx b/client/src/components/email-overlay/email-overlay.container.jsx index 73d1d52c4..bab312df0 100644 --- a/client/src/components/email-overlay/email-overlay.container.jsx +++ b/client/src/components/email-overlay/email-overlay.container.jsx @@ -1,4 +1,4 @@ -import { Button, Divider, Form, Modal, notification, Space } from "antd"; +import { Button, Divider, Form, Modal, Space } from "antd"; import axios from "axios"; import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -13,6 +13,7 @@ import { EmailSettings } from "../../utils/TemplateConstants"; import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component"; import LoadingSpinner from "../loading-spinner/loading-spinner.component"; import EmailOverlayComponent from "./email-overlay.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ modalVisible: selectEmailVisible, @@ -36,6 +37,7 @@ export function EmailOverlayContainer({ emailConfig, modalVisible, toggleEmailOv pdf: null }); const [selectedMedia, setSelectedMedia] = useState([]); + const notification = useNotification(); const defaultEmailFrom = { from: { @@ -109,7 +111,14 @@ export function EmailOverlayContainer({ emailConfig, modalVisible, toggleEmailOv const render = async () => { logImEXEvent("email_render_template", { template: emailConfig.template }); setLoading(true); - let { html, pdf, filename } = await RenderTemplate(emailConfig.template, bodyshop, true); + let { html, pdf, filename } = await RenderTemplate( + emailConfig.template, + bodyshop, + true, + false, + false, + notification + ); const response = await axios.post("/render/inlinecss", { html: html, diff --git a/client/src/components/email-test/email-test-component.jsx b/client/src/components/email-test/email-test-component.jsx index 787ba3a76..b033b8570 100644 --- a/client/src/components/email-test/email-test-component.jsx +++ b/client/src/components/email-test/email-test-component.jsx @@ -8,6 +8,7 @@ import { GenerateDocument } from "../../utils/RenderTemplate"; import DateTimePicker from "../form-date-time-picker/form-date-time-picker.component"; import LayoutFormRow from "../layout-form-row/layout-form-row.component"; import dayjs from "../../utils/day"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ currentUser: selectCurrentUser @@ -19,6 +20,7 @@ const mapDispatchToProps = (dispatch) => ({ export function EmailTestComponent({ currentUser, setEmailOptions }) { const [form] = Form.useForm(); + const notification = useNotification(); const handleFinish = (values) => { GenerateDocument( @@ -40,7 +42,9 @@ export function EmailTestComponent({ currentUser, setEmailOptions }) { { to: values.to }, - values.email ? "e" : "p" + values.email ? "e" : "p", + null, + notification ); }; diff --git a/client/src/components/eula/eula.component.jsx b/client/src/components/eula/eula.component.jsx index 399a52b40..389911961 100644 --- a/client/src/components/eula/eula.component.jsx +++ b/client/src/components/eula/eula.component.jsx @@ -1,5 +1,5 @@ import React, { useCallback, useEffect, useRef, useState } from "react"; -import { Button, Card, Checkbox, Col, Form, Input, Modal, notification, Row } from "antd"; +import { Button, Card, Checkbox, Col, Form, Input, Modal, Row } from "antd"; import Markdown from "react-markdown"; import { createStructuredSelector } from "reselect"; import { selectCurrentEula, selectCurrentUser } from "../../redux/user/user.selectors"; @@ -12,6 +12,7 @@ import dayjs from "../../utils/day"; import "./eula.styles.scss"; import DateTimePicker from "../form-date-time-picker/form-date-time-picker.component.jsx"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const Eula = ({ currentEula, currentUser, acceptEula }) => { const [formReady, setFormReady] = useState(false); @@ -20,7 +21,7 @@ const Eula = ({ currentEula, currentUser, acceptEula }) => { const [form] = Form.useForm(); const markdownCardRef = useRef(null); const { t } = useTranslation(); - const [api, contextHolder] = notification.useNotification(); + const notification = useNotification(); const handleScroll = useCallback( (e) => { @@ -75,7 +76,7 @@ const Eula = ({ currentEula, currentUser, acceptEula }) => { }); acceptEula(); } catch (err) { - api.error({ + notification.error({ message: t("eula.errors.acceptance.message"), description: t("eula.errors.acceptance.description"), placement: "bottomRight", @@ -91,7 +92,6 @@ const Eula = ({ currentEula, currentUser, acceptEula }) => { return ( <> - {contextHolder} {t("menus.header.newjob")} }, { - type: "divider" + type: "divider", + id: "header-jobs-divider" }, { key: "alljobs", @@ -409,7 +410,8 @@ function Header({ label: {t("menus.header.alljobs")} }, { - type: "divider" + type: "divider", + id: "header-jobs-divider2" }, { key: "productionlist", @@ -432,7 +434,8 @@ function Header({ }, { - type: "divider" + type: "divider", + id: "header-jobs-divider3" }, { key: "scoreboard", @@ -556,6 +559,7 @@ function Header({ children: [ { key: "createTask", + id: "header-create-task", icon: , label: t("menus.header.create_task"), onClick: () => { @@ -567,11 +571,13 @@ function Header({ }, { key: "mytasks", + id: "header-my-tasks", icon: , label: {t("menus.header.my_tasks")} }, { key: "all_tasks", + id: "header-all-tasks", icon: , label: {t("menus.header.all_tasks")} } @@ -667,6 +673,7 @@ function Header({ ? [ { key: "rescue", + id: "header-rescue", icon: , label: t("menus.header.rescueme"), onClick: () => { @@ -730,6 +737,7 @@ function Header({ id: "header-recent", children: recentItems.map((i, idx) => ({ key: idx, + id: `header-recent-${idx}`, label: {i.label} })) } diff --git a/client/src/components/inventory-line-delete/inventory-line-delete.component.jsx b/client/src/components/inventory-line-delete/inventory-line-delete.component.jsx index 5175bac47..0c488ba41 100644 --- a/client/src/components/inventory-line-delete/inventory-line-delete.component.jsx +++ b/client/src/components/inventory-line-delete/inventory-line-delete.component.jsx @@ -1,15 +1,17 @@ import { DeleteFilled } from "@ant-design/icons"; import { useMutation } from "@apollo/client"; -import { Button, notification, Popconfirm } from "antd"; +import { Button, Popconfirm } from "antd"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { DELETE_INVENTORY_LINE } from "../../graphql/inventory.queries"; import RbacWrapper from "../rbac-wrapper/rbac-wrapper.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; export default function InventoryLineDelete({ inventoryline, disabled, refetch }) { const [loading, setLoading] = useState(false); const { t } = useTranslation(); const [deleteInventoryLine] = useMutation(DELETE_INVENTORY_LINE); + const notification = useNotification(); const handleDelete = async () => { setLoading(true); diff --git a/client/src/components/inventory-upsert-modal/inventory-upsert-modal.container.jsx b/client/src/components/inventory-upsert-modal/inventory-upsert-modal.container.jsx index a7fa56646..410261706 100644 --- a/client/src/components/inventory-upsert-modal/inventory-upsert-modal.container.jsx +++ b/client/src/components/inventory-upsert-modal/inventory-upsert-modal.container.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { Form, Modal, notification } from "antd"; +import { Form, Modal } from "antd"; import React, { useEffect } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; @@ -10,6 +10,7 @@ import { toggleModalVisible } from "../../redux/modals/modals.actions"; import { selectInventoryUpsert } from "../../redux/modals/modals.selectors"; import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors"; import InventoryUpsertModal from "./inventory-upsert-modal.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -24,6 +25,7 @@ export function InventoryUpsertModalContainer({ currentUser, bodyshop, inventory const { t } = useTranslation(); const [insertInventory] = useMutation(INSERT_INVENTORY_LINE); const [updateInventoryLine] = useMutation(UPDATE_INVENTORY_LINE); + const notification = useNotification(); const { open, context, actions } = inventoryUpsertModal; const { existingInventory } = context; diff --git a/client/src/components/job-3rd-party-modal/job-3rd-party-modal.component.jsx b/client/src/components/job-3rd-party-modal/job-3rd-party-modal.component.jsx index b0f5cac79..12b6ebc71 100644 --- a/client/src/components/job-3rd-party-modal/job-3rd-party-modal.component.jsx +++ b/client/src/components/job-3rd-party-modal/job-3rd-party-modal.component.jsx @@ -11,6 +11,7 @@ import { GenerateDocument } from "../../utils/RenderTemplate"; import { TemplateList } from "../../utils/TemplateConstants"; import LayoutFormRow from "../layout-form-row/layout-form-row.component"; import VendorSearchSelect from "../vendor-search-select/vendor-search-select.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -30,6 +31,7 @@ export function Jobd3RdPartyModal({ bodyshop, jobId, job, technician }) { fetchPolicy: "network-only", nextFetchPolicy: "network-only" }); + const notification = useNotification(); const showModal = () => { form.setFieldsValue({ @@ -59,7 +61,9 @@ export function Jobd3RdPartyModal({ bodyshop, jobId, job, technician }) { context: restVals }, { subject: TemplateList("job_special").special_thirdpartypayer.subject }, - sendtype + sendtype, + null, + notification ); }; diff --git a/client/src/components/job-at-change/job-at-change.component.jsx b/client/src/components/job-at-change/job-at-change.component.jsx index 07a652a15..cf02100bb 100644 --- a/client/src/components/job-at-change/job-at-change.component.jsx +++ b/client/src/components/job-at-change/job-at-change.component.jsx @@ -4,9 +4,10 @@ import { UPDATE_JOB } from "../../graphql/jobs.queries"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; -import { Dropdown, notification } from "antd"; +import { Dropdown } from "antd"; import { DownOutlined } from "@ant-design/icons"; import { selectBodyshop } from "../../redux/user/user.selectors"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop @@ -18,6 +19,7 @@ const mapDispatchToProps = (dispatch) => ({ export function JobAltTransportChange({ bodyshop, job }) { const [updateJob] = useMutation(UPDATE_JOB); const { t } = useTranslation(); + const notification = useNotification(); const onClick = async ({ key }) => { const result = await updateJob({ diff --git a/client/src/components/job-at-change/schedule-event.color.component.jsx b/client/src/components/job-at-change/schedule-event.color.component.jsx index e66a8b6d9..6ad866b2e 100644 --- a/client/src/components/job-at-change/schedule-event.color.component.jsx +++ b/client/src/components/job-at-change/schedule-event.color.component.jsx @@ -4,9 +4,10 @@ import { UPDATE_APPOINTMENT } from "../../graphql/appointments.queries"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; -import { Dropdown, notification } from "antd"; +import { Dropdown } from "antd"; import { DownOutlined } from "@ant-design/icons"; import { selectBodyshop } from "../../redux/user/user.selectors"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop @@ -18,6 +19,7 @@ const mapDispatchToProps = (dispatch) => ({ export function ScheduleEventColor({ bodyshop, event }) { const [updateAppointment] = useMutation(UPDATE_APPOINTMENT); const { t } = useTranslation(); + const notification = useNotification(); const onClick = async ({ key }) => { const result = await updateAppointment({ diff --git a/client/src/components/job-at-change/schedule-event.component.jsx b/client/src/components/job-at-change/schedule-event.component.jsx index 8b1bc769f..97eded476 100644 --- a/client/src/components/job-at-change/schedule-event.component.jsx +++ b/client/src/components/job-at-change/schedule-event.component.jsx @@ -1,6 +1,6 @@ import { AlertFilled } from "@ant-design/icons"; import { useMutation } from "@apollo/client"; -import { Button, Divider, Dropdown, Form, Input, notification, Popover, Select, Space } from "antd"; +import { Button, Divider, Dropdown, Form, Input, Popover, Select, Space } from "antd"; import parsePhoneNumber from "libphonenumber-js"; import queryString from "query-string"; import React, { useContext, useState } from "react"; @@ -25,6 +25,7 @@ import ScheduleManualEvent from "../schedule-manual-event/schedule-manual-event. import ScheduleAtChange from "./job-at-change.component"; import ScheduleEventColor from "./schedule-event.color.component"; import ScheduleEventNote from "./schedule-event.note.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop @@ -51,6 +52,7 @@ export function ScheduleEventComponent({ const [updateAppointment] = useMutation(UPDATE_APPOINTMENT); const [title, setTitle] = useState(event.title); const { socket } = useContext(SocketContext); + const notification = useNotification(); const blockContent = ( @@ -127,7 +129,9 @@ export function ScheduleEventComponent({ - {(event.job && event.job.loss_of_use) || ""} + + {(event.job && event.job.loss_of_use) || ""} + {(event.job && event.job.alt_transport) || ""} @@ -181,7 +185,8 @@ export function ScheduleEventComponent({ subject: Template.subject }, "e", - event.job && event.job.id + event.job && event.job.id, + notification ); } }, diff --git a/client/src/components/job-at-change/schedule-event.container.jsx b/client/src/components/job-at-change/schedule-event.container.jsx index f576d4073..37e5bed79 100644 --- a/client/src/components/job-at-change/schedule-event.container.jsx +++ b/client/src/components/job-at-change/schedule-event.container.jsx @@ -1,5 +1,4 @@ import { useMutation } from "@apollo/client"; -import { notification } from "antd"; import React from "react"; import { useTranslation } from "react-i18next"; import { useDispatch } from "react-redux"; @@ -9,12 +8,15 @@ import { UPDATE_JOB } from "../../graphql/jobs.queries"; import { insertAuditTrail } from "../../redux/application/application.actions"; import AuditTrailMapping from "../../utils/AuditTrailMappings"; import ScheduleEventComponent from "./schedule-event.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; export default function ScheduleEventContainer({ bodyshop, event, refetch }) { const dispatch = useDispatch(); const { t } = useTranslation(); const [cancelAppointment] = useMutation(CANCEL_APPOINTMENT_BY_ID); const [updateJob] = useMutation(UPDATE_JOB); + const notification = useNotification(); + const handleCancel = async ({ id, lost_sale_reason }) => { logImEXEvent("schedule_cancel_appt"); diff --git a/client/src/components/job-at-change/schedule-event.note.component.jsx b/client/src/components/job-at-change/schedule-event.note.component.jsx index a2eb60302..4b6952102 100644 --- a/client/src/components/job-at-change/schedule-event.note.component.jsx +++ b/client/src/components/job-at-change/schedule-event.note.component.jsx @@ -1,6 +1,6 @@ import { EditFilled, SaveFilled } from "@ant-design/icons"; import { useMutation } from "@apollo/client"; -import { Button, Input, notification, Space } from "antd"; +import { Button, Input, Space } from "antd"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; @@ -8,6 +8,7 @@ import { createStructuredSelector } from "reselect"; import { UPDATE_APPOINTMENT } from "../../graphql/appointments.queries"; import { selectBodyshop } from "../../redux/user/user.selectors"; import DataLabel from "../data-label/data-label.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop @@ -22,6 +23,7 @@ export function ScheduleEventNote({ event }) { const [loading, setLoading] = useState(false); const [updateAppointment] = useMutation(UPDATE_APPOINTMENT); const { t } = useTranslation(); + const notification = useNotification(); const toggleEdit = async () => { if (editing) { diff --git a/client/src/components/job-calculate-totals/job-calculate-totals.component.jsx b/client/src/components/job-calculate-totals/job-calculate-totals.component.jsx index 706cf16a0..6addb5605 100644 --- a/client/src/components/job-calculate-totals/job-calculate-totals.component.jsx +++ b/client/src/components/job-calculate-totals/job-calculate-totals.component.jsx @@ -1,11 +1,13 @@ -import { Button, notification } from "antd"; +import { Button } from "antd"; import Axios from "axios"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; export default function JobCalculateTotals({ job, disabled, refetch }) { const { t } = useTranslation(); const [loading, setLoading] = useState(false); + const notification = useNotification(); const handleCalculate = async () => { try { diff --git a/client/src/components/job-checklist/components/job-checklist-form/job-checklist-form.component.jsx b/client/src/components/job-checklist/components/job-checklist-form/job-checklist-form.component.jsx index a276fcb07..18f5d025e 100644 --- a/client/src/components/job-checklist/components/job-checklist-form/job-checklist-form.component.jsx +++ b/client/src/components/job-checklist/components/job-checklist-form/job-checklist-form.component.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { Button, Card, Form, Input, notification, Switch } from "antd"; +import { Button, Card, Form, Input, Switch } from "antd"; import queryString from "query-string"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; @@ -16,6 +16,7 @@ import AuditTrailMapping from "../../../../utils/AuditTrailMappings"; import dayjs from "../../../../utils/day"; import ConfigFormComponents from "../../../config-form-components/config-form-components.component"; import DateTimePicker from "../../../form-date-time-picker/form-date-time-picker.component"; +import { useNotification } from "../../../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -32,6 +33,7 @@ export function JobChecklistForm({ insertAuditTrail, formItems, bodyshop, curren const [markAptArrived] = useMutation(MARK_APPOINTMENT_ARRIVED); const [markLatestAptArrived] = useMutation(MARK_LATEST_APPOINTMENT_ARRIVED); const [updateOwner] = useMutation(UPDATE_OWNER); + const notification = useNotification(); const { jobId } = useParams(); const history = useNavigate(); diff --git a/client/src/components/job-checklist/components/job-checklist-template-list/job-checklist-template-list.component.jsx b/client/src/components/job-checklist/components/job-checklist-template-list/job-checklist-template-list.component.jsx index 05fa55c77..bf0216a0e 100644 --- a/client/src/components/job-checklist/components/job-checklist-template-list/job-checklist-template-list.component.jsx +++ b/client/src/components/job-checklist/components/job-checklist-template-list/job-checklist-template-list.component.jsx @@ -6,12 +6,14 @@ import { useParams } from "react-router-dom"; import { logImEXEvent } from "../../../../firebase/firebase.utils"; import { GenerateDocument, GenerateDocuments } from "../../../../utils/RenderTemplate"; import { TemplateList } from "../../../../utils/TemplateConstants"; +import { useNotification } from "../../../../contexts/Notifications/notificationContext.jsx"; const TemplateListGenerated = TemplateList(); export default function JobIntakeTemplateList({ templates }) { const { jobId } = useParams(); const { t } = useTranslation(); const [loading, setLoading] = useState(false); + const notification = useNotification(); const renderTemplate = async (templateKey) => { setLoading(true); @@ -23,7 +25,9 @@ export default function JobIntakeTemplateList({ templates }) { variables: { id: jobId } }, {}, - "p" + "p", + null, + notification ); setLoading(false); }; @@ -35,7 +39,8 @@ export default function JobIntakeTemplateList({ templates }) { await GenerateDocuments( templates.map((key) => { return { name: key, variables: { id: jobId } }; - }) + }), + notification ); setLoading(false); }; diff --git a/client/src/components/job-create-iou/job-create-iou.component.jsx b/client/src/components/job-create-iou/job-create-iou.component.jsx index 0aed7b2ea..cd2fbdc1d 100644 --- a/client/src/components/job-create-iou/job-create-iou.component.jsx +++ b/client/src/components/job-create-iou/job-create-iou.component.jsx @@ -1,6 +1,6 @@ import { useApolloClient } from "@apollo/client"; import { useSplitTreatments } from "@splitsoftware/splitio-react"; -import { Button, notification, Popconfirm } from "antd"; +import { Button, Popconfirm } from "antd"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; @@ -10,6 +10,7 @@ import { UPDATE_JOB_LINES_IOU } from "../../graphql/jobs-lines.queries"; import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors"; import { CreateIouForJob } from "../jobs-detail-header-actions/jobs-detail-header-actions.duplicate.util"; import { selectTechnician } from "../../redux/tech/tech.selectors"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -27,6 +28,7 @@ export function JobCreateIOU({ bodyshop, currentUser, job, selectedJobLines, tec const [loading, setLoading] = useState(false); const client = useApolloClient(); const history = useNavigate(); + const notification = useNotification(); const { treatments: { IOU_Tracking } diff --git a/client/src/components/job-detail-lines/job-lines-part-price-change.component.jsx b/client/src/components/job-detail-lines/job-lines-part-price-change.component.jsx index 34b82ade8..62c8523b8 100644 --- a/client/src/components/job-detail-lines/job-lines-part-price-change.component.jsx +++ b/client/src/components/job-detail-lines/job-lines-part-price-change.component.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { Button, Form, notification, Popover, Tooltip } from "antd"; +import { Button, Form, Popover, Tooltip } from "antd"; import axios from "axios"; import { t } from "i18next"; import React, { useState } from "react"; @@ -11,6 +11,7 @@ import CurrencyFormatter from "../../utils/CurrencyFormatter"; import InstanceRenderManager from "../../utils/instanceRenderMgr"; import CurrencyFormItemComponent from "../form-items-formatted/currency-form-item.component"; import JobLineConvertToLabor from "../job-line-convert-to-labor/job-line-convert-to-labor.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ technician: selectTechnician @@ -20,6 +21,7 @@ const mapDispatchToProps = (dispatch) => ({}); export function JobLinesPartPriceChange({ job, line, refetch, technician }) { const [loading, setLoading] = useState(false); const [updatePartPrice] = useMutation(UPDATE_LINE_PPC); + const notification = useNotification(); const handleFinish = async (values) => { try { diff --git a/client/src/components/job-employee-assignments/job-employee-assignments.container.jsx b/client/src/components/job-employee-assignments/job-employee-assignments.container.jsx index f5cc9921e..5284d9e0c 100644 --- a/client/src/components/job-employee-assignments/job-employee-assignments.container.jsx +++ b/client/src/components/job-employee-assignments/job-employee-assignments.container.jsx @@ -1,5 +1,4 @@ import { useMutation } from "@apollo/client"; -import { notification } from "antd"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { logImEXEvent } from "../../firebase/firebase.utils"; @@ -10,6 +9,7 @@ import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import { insertAuditTrail } from "../../redux/application/application.actions"; import AuditTrailMapping from "../../utils/AuditTrailMappings"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ //currentUser: selectCurrentUser @@ -23,6 +23,7 @@ export function JobEmployeeAssignmentsContainer({ job, refetch, insertAuditTrail const { t } = useTranslation(); const [updateJob] = useMutation(UPDATE_JOB_ASSIGNMENTS); const [loading, setLoading] = useState(false); + const notification = useNotification(); const handleAdd = async (assignment) => { setLoading(true); diff --git a/client/src/components/job-line-bulk-assign/job-line-bulk-assign.component.jsx b/client/src/components/job-line-bulk-assign/job-line-bulk-assign.component.jsx index a64a77b7f..4904a7a31 100644 --- a/client/src/components/job-line-bulk-assign/job-line-bulk-assign.component.jsx +++ b/client/src/components/job-line-bulk-assign/job-line-bulk-assign.component.jsx @@ -1,7 +1,7 @@ import React, { useState } from "react"; import { useMutation } from "@apollo/client"; -import { Button, Form, notification, Popover, Select, Space } from "antd"; +import { Button, Form, Popover, Select, Space } from "antd"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; @@ -10,6 +10,7 @@ import { selectJobReadOnly } from "../../redux/application/application.selectors import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors"; import { insertAuditTrail } from "../../redux/application/application.actions"; import AuditTrailMapping from "../../utils/AuditTrailMappings"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -36,6 +37,7 @@ export function JoblineBulkAssign({ const { t } = useTranslation(); const [assignLines] = useMutation(UPDATE_LINE_BULK_ASSIGN); + const notification = useNotification(); const handleConvert = async (values) => { try { diff --git a/client/src/components/job-line-convert-to-labor/job-line-convert-to-labor.component.jsx b/client/src/components/job-line-convert-to-labor/job-line-convert-to-labor.component.jsx index 8ac34647e..a42e6734e 100644 --- a/client/src/components/job-line-convert-to-labor/job-line-convert-to-labor.component.jsx +++ b/client/src/components/job-line-convert-to-labor/job-line-convert-to-labor.component.jsx @@ -1,6 +1,6 @@ import { ClockCircleOutlined } from "@ant-design/icons"; import { useApolloClient } from "@apollo/client"; -import { Button, Card, Form, notification, Popover, Select, Space, Tooltip } from "antd"; +import { Button, Card, Form, Popover, Select, Space, Tooltip } from "antd"; import { useState } from "react"; import { useTranslation } from "react-i18next"; import { logImEXEvent } from "../../firebase/firebase.utils"; @@ -13,6 +13,7 @@ import { UPDATE_JOB_LINE } from "../../graphql/jobs-lines.queries"; import { insertAuditTrail } from "../../redux/application/application.actions"; import { selectTechnician } from "../../redux/tech/tech.selectors"; import AuditTrailMapping from "../../utils/AuditTrailMappings"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ technician: selectTechnician @@ -29,6 +30,7 @@ export function JobLineConvertToLabor({ children, jobline, job, insertAuditTrail const [form] = Form.useForm(); const [visibility, setVisibility] = useState(false); const client = useApolloClient(); + const notification = useNotification(); const handleFinish = async (values) => { const { mod_lbr_ty } = values; diff --git a/client/src/components/job-line-dispatch-button/job-line-dispatch-button.component.jsx b/client/src/components/job-line-dispatch-button/job-line-dispatch-button.component.jsx index ce0b6e4fe..24f507bd1 100644 --- a/client/src/components/job-line-dispatch-button/job-line-dispatch-button.component.jsx +++ b/client/src/components/job-line-dispatch-button/job-line-dispatch-button.component.jsx @@ -1,7 +1,7 @@ import React, { useState } from "react"; import { useMutation } from "@apollo/client"; -import { Button, Form, notification, Popover, Select, Space } from "antd"; +import { Button, Form, Popover, Select, Space } from "antd"; import dayjs from "../../utils/day"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; @@ -11,6 +11,7 @@ import { selectJobReadOnly } from "../../redux/application/application.selectors import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors"; import { GenerateDocument } from "../../utils/RenderTemplate"; import { TemplateList } from "../../utils/TemplateConstants"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -25,7 +26,6 @@ export default connect(mapStateToProps, mapDispatchToProps)(JobLineDispatchButto export function JobLineDispatchButton({ setSelectedLines, selectedLines, - bodyshop, jobRO, job, @@ -40,6 +40,7 @@ export function JobLineDispatchButton({ }); const { t } = useTranslation(); const [dispatchLines] = useMutation(INSERT_PARTS_DISPATCH); + const notification = useNotification(); const handleConvert = async (values) => { try { @@ -80,7 +81,9 @@ export function JobLineDispatchButton({ } }, {}, - "p" + "p", + null, + notification ); } setVisible(false); diff --git a/client/src/components/job-line-location-popup/job-line-location-popup.component.jsx b/client/src/components/job-line-location-popup/job-line-location-popup.component.jsx index 7171f6d11..6aed4399e 100644 --- a/client/src/components/job-line-location-popup/job-line-location-popup.component.jsx +++ b/client/src/components/job-line-location-popup/job-line-location-popup.component.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { notification, Select, Space } from "antd"; +import { Select, Space } from "antd"; import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; @@ -7,6 +7,7 @@ import { createStructuredSelector } from "reselect"; import { UPDATE_JOB_LINE } from "../../graphql/jobs-lines.queries"; import { selectBodyshop } from "../../redux/user/user.selectors"; import LoadingSpinner from "../loading-spinner/loading-spinner.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ //currentUser: selectCurrentUser @@ -22,6 +23,7 @@ export function JobLineLocationPopup({ bodyshop, jobline, disabled }) { const [location, setLocation] = useState(jobline.location); const [updateJob] = useMutation(UPDATE_JOB_LINE); const { t } = useTranslation(); + const notification = useNotification(); useEffect(() => { if (editing) setLocation(jobline.location); diff --git a/client/src/components/job-line-note-popup/job-line-note-popup.component.jsx b/client/src/components/job-line-note-popup/job-line-note-popup.component.jsx index 2adb3bf72..304a7779c 100644 --- a/client/src/components/job-line-note-popup/job-line-note-popup.component.jsx +++ b/client/src/components/job-line-note-popup/job-line-note-popup.component.jsx @@ -1,10 +1,11 @@ import { FieldTimeOutlined } from "@ant-design/icons"; import { useMutation } from "@apollo/client"; -import { Input, notification } from "antd"; +import { Input } from "antd"; import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { UPDATE_JOB_LINE } from "../../graphql/jobs-lines.queries"; import LoadingSpinner from "../loading-spinner/loading-spinner.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; export default function JobLineNotePopup({ jobline, disabled }) { const [editing, setEditing] = useState(false); @@ -12,6 +13,7 @@ export default function JobLineNotePopup({ jobline, disabled }) { const [note, setNote] = useState(jobline.note); const [updateJob] = useMutation(UPDATE_JOB_LINE); const { t } = useTranslation(); + const notification = useNotification(); useEffect(() => { if (editing) setNote(jobline.notes); diff --git a/client/src/components/job-line-status-popup/job-line-status-popup.component.jsx b/client/src/components/job-line-status-popup/job-line-status-popup.component.jsx index ecc468010..7a5813a09 100644 --- a/client/src/components/job-line-status-popup/job-line-status-popup.component.jsx +++ b/client/src/components/job-line-status-popup/job-line-status-popup.component.jsx @@ -1,4 +1,4 @@ -import { notification, Select } from "antd"; +import { Select } from "antd"; import React, { useEffect, useState } from "react"; import { useMutation } from "@apollo/client"; import { useTranslation } from "react-i18next"; @@ -7,6 +7,7 @@ import { createStructuredSelector } from "reselect"; import { UPDATE_JOB_LINE } from "../../graphql/jobs-lines.queries"; import { selectBodyshop } from "../../redux/user/user.selectors"; import LoadingSpinner from "../loading-spinner/loading-spinner.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ //currentUser: selectCurrentUser @@ -22,6 +23,7 @@ export function JobLineStatusPopup({ bodyshop, jobline, disabled }) { const [status, setStatus] = useState(jobline.status); const [updateJob] = useMutation(UPDATE_JOB_LINE); const { t } = useTranslation(); + const notification = useNotification(); useEffect(() => { if (editing) setStatus(jobline.status); diff --git a/client/src/components/job-line-team-assignment/job-line-team-assignmnent.component.jsx b/client/src/components/job-line-team-assignment/job-line-team-assignmnent.component.jsx index d80b281fd..0115e1ad8 100644 --- a/client/src/components/job-line-team-assignment/job-line-team-assignmnent.component.jsx +++ b/client/src/components/job-line-team-assignment/job-line-team-assignmnent.component.jsx @@ -1,4 +1,4 @@ -import { notification, Select } from "antd"; +import { Select } from "antd"; import React, { useEffect, useState } from "react"; import { useMutation } from "@apollo/client"; import { useTranslation } from "react-i18next"; @@ -9,6 +9,7 @@ import { selectBodyshop } from "../../redux/user/user.selectors"; import LoadingSpinner from "../loading-spinner/loading-spinner.component"; import { insertAuditTrail } from "../../redux/application/application.actions"; import AuditTrailMapping from "../../utils/AuditTrailMappings"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ //currentUser: selectCurrentUser @@ -24,6 +25,7 @@ export function JoblineTeamAssignment({ bodyshop, jobline, disabled, jobId, inse const [assignedTeam, setAssignedTeam] = useState(jobline.assigned_team); const [updateJob] = useMutation(UPDATE_JOB_LINE); const { t } = useTranslation(); + const notification = useNotification(); useEffect(() => { if (editing) setAssignedTeam(jobline.assigned_team); diff --git a/client/src/components/job-lines-upsert-modal/job-lines-upsert-modal.container.jsx b/client/src/components/job-lines-upsert-modal/job-lines-upsert-modal.container.jsx index 76f8b52bb..be9a19c79 100644 --- a/client/src/components/job-lines-upsert-modal/job-lines-upsert-modal.container.jsx +++ b/client/src/components/job-lines-upsert-modal/job-lines-upsert-modal.container.jsx @@ -1,6 +1,5 @@ import { useMutation } from "@apollo/client"; import { useSplitTreatments } from "@splitsoftware/splitio-react"; -import { notification } from "antd"; import Axios from "axios"; import Dinero from "dinero.js"; import React, { useState } from "react"; @@ -14,6 +13,7 @@ import { selectBodyshop } from "../../redux/user/user.selectors"; import CriticalPartsScan from "../../utils/criticalPartsScan"; import UndefinedToNull from "../../utils/undefinedtonull"; import JobLinesUpdsertModal from "./job-lines-upsert-modal.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ jobLineEditModal: selectJobLineEditModal, @@ -31,6 +31,7 @@ function JobLinesUpsertModalContainer({ jobLineEditModal, toggleModalVisible, bo names: ["CriticalPartsScanning"], splitKey: bodyshop.imexshopid }); + const notification = useNotification(); const { t } = useTranslation(); const [insertJobLine] = useMutation(INSERT_NEW_JOB_LINE); @@ -115,7 +116,7 @@ function JobLinesUpsertModalContainer({ jobLineEditModal, toggleModalVisible, bo toggleModalVisible(); } if (CriticalPartsScanning.treatment === "on") { - CriticalPartsScan(jobLineEditModal.context.jobid); + CriticalPartsScan(jobLineEditModal.context.jobid, notification); } setLoading(false); }; diff --git a/client/src/components/job-remove-from-parst-queue/job-remove-from-parts-queue.component.jsx b/client/src/components/job-remove-from-parst-queue/job-remove-from-parts-queue.component.jsx index 92682aa83..f11731554 100644 --- a/client/src/components/job-remove-from-parst-queue/job-remove-from-parts-queue.component.jsx +++ b/client/src/components/job-remove-from-parst-queue/job-remove-from-parts-queue.component.jsx @@ -1,14 +1,15 @@ import { useMutation } from "@apollo/client"; -import { Checkbox, notification, Space, Spin } from "antd"; +import { Checkbox, Space, Spin } from "antd"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { UPDATE_JOB } from "../../graphql/jobs.queries"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; export default function JobRemoveFromPartsQueue({ checked, jobId }) { const [updateJob] = useMutation(UPDATE_JOB); const { t } = useTranslation(); - const [loading, setLoading] = useState(false); + const notification = useNotification(); const handleChange = async (e) => { setLoading(true); diff --git a/client/src/components/job-scoreboard-add-button/job-scoreboard-add-button.component.jsx b/client/src/components/job-scoreboard-add-button/job-scoreboard-add-button.component.jsx index 8b5c9c1c2..88ad6e819 100644 --- a/client/src/components/job-scoreboard-add-button/job-scoreboard-add-button.component.jsx +++ b/client/src/components/job-scoreboard-add-button/job-scoreboard-add-button.component.jsx @@ -1,6 +1,6 @@ import { CheckCircleOutlined } from "@ant-design/icons"; import { useLazyQuery, useMutation } from "@apollo/client"; -import { Button, Card, Form, InputNumber, notification, Popover, Space } from "antd"; +import { Button, Card, Form, InputNumber, Popover, Space } from "antd"; import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; @@ -17,6 +17,7 @@ import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component.j import DateTimePicker from "../form-date-time-picker/form-date-time-picker.component.jsx"; import LoadingSpinner from "../loading-spinner/loading-spinner.component"; import LockWrapperComponent from "../lock-wrapper/lock-wrapper.component.jsx"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop @@ -33,6 +34,7 @@ export function ScoreboardAddButton({ bodyshop, job, disabled, ...otherBtnProps const [form] = Form.useForm(); const [visibility, setVisibility] = useState(false); const [callQuery, { loading: entryLoading, data: entryData }] = useLazyQuery(QUERY_SCOREBOARD_ENTRY); + const notification = useNotification(); useEffect(() => { if (visibility) { diff --git a/client/src/components/job-send-parts-price-change/job-send-parts-price-change.component.jsx b/client/src/components/job-send-parts-price-change/job-send-parts-price-change.component.jsx index 040213089..fcfb5076c 100644 --- a/client/src/components/job-send-parts-price-change/job-send-parts-price-change.component.jsx +++ b/client/src/components/job-send-parts-price-change/job-send-parts-price-change.component.jsx @@ -1,11 +1,14 @@ -import { Button, notification } from "antd"; +import { Button } from "antd"; import axios from "axios"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; export default function JobSendPartPriceChangeComponent({ job, disabled }) { const { t } = useTranslation(); const [loading, setLoading] = useState(false); + const notification = useNotification(); + const handleClick = async () => { setLoading(true); try { diff --git a/client/src/components/job-totals-table/jobs-totals.cash-discount-display.component.jsx b/client/src/components/job-totals-table/jobs-totals.cash-discount-display.component.jsx index ab7a253e5..53e973006 100644 --- a/client/src/components/job-totals-table/jobs-totals.cash-discount-display.component.jsx +++ b/client/src/components/job-totals-table/jobs-totals.cash-discount-display.component.jsx @@ -1,4 +1,4 @@ -import { notification, Spin } from "antd"; +import { Spin } from "antd"; import axios from "axios"; import Dinero from "dinero.js"; import React, { useCallback, useEffect, useState } from "react"; @@ -6,6 +6,8 @@ import React, { useCallback, useEffect, useState } from "react"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import { selectBodyshop } from "../../redux/user/user.selectors"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; + const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop }); @@ -15,6 +17,7 @@ export default connect(mapStateToProps, mapDispatchToProps)(JobTotalsCashDiscoun export function JobTotalsCashDiscount({ bodyshop, amountDinero }) { const [loading, setLoading] = useState(true); const [fee, setFee] = useState(0); + const notification = useNotification(); const fetchData = useCallback(async () => { if (amountDinero && bodyshop) { @@ -47,7 +50,7 @@ export function JobTotalsCashDiscount({ bodyshop, amountDinero }) { setLoading(false); } } - }, [amountDinero, bodyshop]); + }, [amountDinero, bodyshop, notification]); useEffect(() => { fetchData(); diff --git a/client/src/components/jobs-admin-change-status/jobs-admin-change.status.component.jsx b/client/src/components/jobs-admin-change-status/jobs-admin-change.status.component.jsx index 1cc4942e1..6a469e75f 100644 --- a/client/src/components/jobs-admin-change-status/jobs-admin-change.status.component.jsx +++ b/client/src/components/jobs-admin-change-status/jobs-admin-change.status.component.jsx @@ -1,6 +1,6 @@ import { DownCircleFilled } from "@ant-design/icons"; import { useMutation } from "@apollo/client"; -import { Button, Dropdown, notification } from "antd"; +import { Button, Dropdown } from "antd"; import React from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; @@ -9,6 +9,7 @@ import { UPDATE_JOB_STATUS } from "../../graphql/jobs.queries"; import { insertAuditTrail } from "../../redux/application/application.actions"; import { selectBodyshop } from "../../redux/user/user.selectors"; import AuditTrailMapping from "../../utils/AuditTrailMappings"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop @@ -20,6 +21,7 @@ export default connect(mapStateToProps, mapDispatchToProps)(JobsAdminStatus); export function JobsAdminStatus({ insertAuditTrail, bodyshop, job }) { const { t } = useTranslation(); + const notification = useNotification(); const [mutationUpdateJobstatus] = useMutation(UPDATE_JOB_STATUS); const updateJobStatus = (status) => { diff --git a/client/src/components/jobs-admin-class/jobs-admin-class.component.jsx b/client/src/components/jobs-admin-class/jobs-admin-class.component.jsx index 35c326675..6ed008d81 100644 --- a/client/src/components/jobs-admin-class/jobs-admin-class.component.jsx +++ b/client/src/components/jobs-admin-class/jobs-admin-class.component.jsx @@ -1,11 +1,12 @@ import { useMutation } from "@apollo/client"; -import { Button, Form, notification, Popconfirm, Select } from "antd"; +import { Button, Form, Popconfirm, Select } from "antd"; import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import { UPDATE_JOB } from "../../graphql/jobs.queries"; import { selectBodyshop } from "../../redux/user/user.selectors"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop @@ -20,6 +21,7 @@ export function JobsAdminClass({ bodyshop, job }) { const [loading, setLoading] = useState(false); const [form] = Form.useForm(); const [updateJob] = useMutation(UPDATE_JOB); + const notification = useNotification(); const handleFinish = async (values) => { setLoading(true); diff --git a/client/src/components/jobs-admin-dates/jobs-admin-dates.component.jsx b/client/src/components/jobs-admin-dates/jobs-admin-dates.component.jsx index 709257d77..767c62553 100644 --- a/client/src/components/jobs-admin-dates/jobs-admin-dates.component.jsx +++ b/client/src/components/jobs-admin-dates/jobs-admin-dates.component.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { Button, Form, notification } from "antd"; +import { Button, Form } from "antd"; import dayjs from "../../utils/day"; import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -13,6 +13,7 @@ import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import { insertAuditTrail } from "../../redux/application/application.actions"; import { DateTimeFormat } from "./../../utils/DateFormatter"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ //currentUser: selectCurrentUser @@ -36,6 +37,7 @@ export function JobsAdminDatesChange({ insertAuditTrail, job }) { const [loading, setLoading] = useState(false); const [form] = Form.useForm(); const [updateJob] = useMutation(UPDATE_JOB); + const notification = useNotification(); const handleFinish = async (values) => { setLoading(true); diff --git a/client/src/components/jobs-admin-delete-intake/jobs-admin-delete-intake.component.jsx b/client/src/components/jobs-admin-delete-intake/jobs-admin-delete-intake.component.jsx index 3277375a8..826c84737 100644 --- a/client/src/components/jobs-admin-delete-intake/jobs-admin-delete-intake.component.jsx +++ b/client/src/components/jobs-admin-delete-intake/jobs-admin-delete-intake.component.jsx @@ -1,13 +1,15 @@ import { useMutation } from "@apollo/client"; -import { Button, Space, notification } from "antd"; +import { Button, Space } from "antd"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { DELETE_DELIVERY_CHECKLIST, DELETE_INTAKE_CHECKLIST } from "../../graphql/jobs.queries"; import InstanceRenderManager from "../../utils/instanceRenderMgr"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; export default function JobAdminDeleteIntake({ job }) { const { t } = useTranslation(); const [loading, setLoading] = useState(false); + const notification = useNotification(); const [deleteIntake] = useMutation(DELETE_INTAKE_CHECKLIST); const [deleteDelivery] = useMutation(DELETE_DELIVERY_CHECKLIST); @@ -50,7 +52,7 @@ export default function JobAdminDeleteIntake({ job }) { const InstanceRender = InstanceRenderManager({ imex: true, - rome: "USE_IMEX", + rome: "USE_IMEX" }); return InstanceRender ? ( diff --git a/client/src/components/jobs-admin-mark-reexport/jobs-admin-mark-reexport.component.jsx b/client/src/components/jobs-admin-mark-reexport/jobs-admin-mark-reexport.component.jsx index 8be01cb02..13c4541d8 100644 --- a/client/src/components/jobs-admin-mark-reexport/jobs-admin-mark-reexport.component.jsx +++ b/client/src/components/jobs-admin-mark-reexport/jobs-admin-mark-reexport.component.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { Button, Space, notification } from "antd"; +import { Button, Space } from "antd"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import dayjs from "../../utils/day"; @@ -10,6 +10,7 @@ import { MARK_JOB_AS_EXPORTED, MARK_JOB_AS_UNINVOICED, MARK_JOB_FOR_REEXPORT } f import { insertAuditTrail } from "../../redux/application/application.actions"; import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors"; import AuditTrailMapping from "../../utils/AuditTrailMappings"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -24,6 +25,7 @@ export function JobAdminMarkReexport({ insertAuditTrail, bodyshop, currentUser, const { t } = useTranslation(); const [loading, setLoading] = useState(false); const [insertExportLog] = useMutation(INSERT_EXPORT_LOG); + const notification = useNotification(); const [markJobForReexport] = useMutation(MARK_JOB_FOR_REEXPORT); const [markJobExported] = useMutation(MARK_JOB_AS_EXPORTED); diff --git a/client/src/components/jobs-admin-owner-reassociate/jobs-admin-owner-reassociate.component.jsx b/client/src/components/jobs-admin-owner-reassociate/jobs-admin-owner-reassociate.component.jsx index 68e1cbacd..b4869075d 100644 --- a/client/src/components/jobs-admin-owner-reassociate/jobs-admin-owner-reassociate.component.jsx +++ b/client/src/components/jobs-admin-owner-reassociate/jobs-admin-owner-reassociate.component.jsx @@ -1,15 +1,18 @@ import { useMutation } from "@apollo/client"; -import { Button, Form, notification } from "antd"; +import { Button, Form } from "antd"; import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { UPDATE_JOB } from "../../graphql/jobs.queries"; import OwnerSearchSelect from "../owner-search-select/owner-search-select.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; export default function JobAdminOwnerReassociate({ job }) { const { t } = useTranslation(); const [loading, setLoading] = useState(false); const [form] = Form.useForm(); const [updateJob] = useMutation(UPDATE_JOB); + const notification = useNotification(); + const handleFinish = async (values) => { setLoading(true); const result = await updateJob({ diff --git a/client/src/components/jobs-admin-remove-ar/jobs-admin-remove-ar.component.jsx b/client/src/components/jobs-admin-remove-ar/jobs-admin-remove-ar.component.jsx index 61d9cbaf6..bdbae8a80 100644 --- a/client/src/components/jobs-admin-remove-ar/jobs-admin-remove-ar.component.jsx +++ b/client/src/components/jobs-admin-remove-ar/jobs-admin-remove-ar.component.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { notification, Switch } from "antd"; +import { Switch } from "antd"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; @@ -7,6 +7,7 @@ import { createStructuredSelector } from "reselect"; import { UPDATE_REMOVE_FROM_AR } from "../../graphql/jobs.queries"; import { insertAuditTrail } from "../../redux/application/application.actions"; import AuditTrailMapping from "../../utils/AuditTrailMappings"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({}); const mapDispatchToProps = (dispatch) => ({ @@ -19,6 +20,7 @@ export function JobsAdminRemoveAR({ insertAuditTrail, job }) { const { t } = useTranslation(); const [loading, setLoading] = useState(false); const [switchValue, setSwitchValue] = useState(job.remove_from_ar); + const notification = useNotification(); const [mutationUpdateRemoveFromAR] = useMutation(UPDATE_REMOVE_FROM_AR); diff --git a/client/src/components/jobs-admin-unvoid/jobs-admin-unvoid.component.jsx b/client/src/components/jobs-admin-unvoid/jobs-admin-unvoid.component.jsx index ea6e8f8ab..47f0c5a5f 100644 --- a/client/src/components/jobs-admin-unvoid/jobs-admin-unvoid.component.jsx +++ b/client/src/components/jobs-admin-unvoid/jobs-admin-unvoid.component.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { Button, notification } from "antd"; +import { Button } from "antd"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; @@ -8,6 +8,7 @@ import { UNVOID_JOB } from "../../graphql/jobs.queries"; import { insertAuditTrail } from "../../redux/application/application.actions"; import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors"; import AuditTrailMapping from "../../utils/AuditTrailMappings"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -22,6 +23,7 @@ export function JobsAdminUnvoid({ insertAuditTrail, bodyshop, job, currentUser } const { t } = useTranslation(); const [loading, setLoading] = useState(false); const [mutationUnvoidJob] = useMutation(UNVOID_JOB); + const notification = useNotification(); const handleUpdate = async (values) => { setLoading(true); diff --git a/client/src/components/jobs-admin-vehicle-reassociate/jobs-admin-vehicle-reassociate.component.jsx b/client/src/components/jobs-admin-vehicle-reassociate/jobs-admin-vehicle-reassociate.component.jsx index ce2d317e4..600578dbc 100644 --- a/client/src/components/jobs-admin-vehicle-reassociate/jobs-admin-vehicle-reassociate.component.jsx +++ b/client/src/components/jobs-admin-vehicle-reassociate/jobs-admin-vehicle-reassociate.component.jsx @@ -1,15 +1,18 @@ import { useMutation } from "@apollo/client"; -import { Button, Form, notification } from "antd"; +import { Button, Form } from "antd"; import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { UPDATE_JOB } from "../../graphql/jobs.queries"; import VehicleSearchSelect from "../vehicle-search-select/vehicle-search-select.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; export default function JobAdminOwnerReassociate({ job }) { const { t } = useTranslation(); const [loading, setLoading] = useState(false); const [form] = Form.useForm(); const [updateJob] = useMutation(UPDATE_JOB); + const notification = useNotification(); + const handleFinish = async (values) => { setLoading(true); const result = await updateJob({ diff --git a/client/src/components/jobs-available-scan/jobs-available-scan.component.jsx b/client/src/components/jobs-available-scan/jobs-available-scan.component.jsx index 111714fad..96d1ab13b 100644 --- a/client/src/components/jobs-available-scan/jobs-available-scan.component.jsx +++ b/client/src/components/jobs-available-scan/jobs-available-scan.component.jsx @@ -1,5 +1,5 @@ import { DownloadOutlined, SyncOutlined } from "@ant-design/icons"; -import { Button, Card, Input, notification, Space, Table } from "antd"; +import { Button, Card, Input, Space, Table } from "antd"; import axios from "axios"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; @@ -7,6 +7,7 @@ import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import { selectPartnerVersion } from "../../redux/application/application.selectors"; import { alphaSort } from "../../utils/sorters"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ //currentUser: selectCurrentUser @@ -26,6 +27,7 @@ export function JobsAvailableScan({ partnerVersion, refetch }) { filteredInfo: { text: "" } }); const { t } = useTranslation(); + const notification = useNotification(); const handleTableChange = (pagination, filters, sorter) => { setState({ ...state, filteredInfo: filters, sortedInfo: sorter }); diff --git a/client/src/components/jobs-available-table/jobs-available-table.component.jsx b/client/src/components/jobs-available-table/jobs-available-table.component.jsx index 3d397597e..6aeb1cd63 100644 --- a/client/src/components/jobs-available-table/jobs-available-table.component.jsx +++ b/client/src/components/jobs-available-table/jobs-available-table.component.jsx @@ -1,6 +1,6 @@ import { DeleteFilled, DownloadOutlined, PlusCircleFilled, SyncOutlined } from "@ant-design/icons"; import { useMutation } from "@apollo/client"; -import { Alert, Button, Card, Input, notification, Space, Table } from "antd"; +import { Alert, Button, Card, Input, Space, Table } from "antd"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; @@ -11,6 +11,7 @@ import { selectBodyshop } from "../../redux/user/user.selectors"; import CurrencyFormatter from "../../utils/CurrencyFormatter"; import { TimeAgoFormatter } from "../../utils/DateFormatter"; import { alphaSort } from "../../utils/sorters"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop @@ -29,6 +30,7 @@ export function JobsAvailableComponent({ bodyshop, loading, data, refetch, addJo sortedInfo: {}, filteredInfo: { text: "" } }); + const notification = useNotification(); const handleTableChange = (pagination, filters, sorter) => { setState({ ...state, filteredInfo: filters, sortedInfo: sorter }); diff --git a/client/src/components/jobs-available-table/jobs-available-table.container.jsx b/client/src/components/jobs-available-table/jobs-available-table.container.jsx index 2cadc3c8c..043a5b30e 100644 --- a/client/src/components/jobs-available-table/jobs-available-table.container.jsx +++ b/client/src/components/jobs-available-table/jobs-available-table.container.jsx @@ -1,6 +1,6 @@ import { gql, useApolloClient, useLazyQuery, useMutation, useQuery } from "@apollo/client"; import { useSplitTreatments } from "@splitsoftware/splitio-react"; -import { Col, Row, notification } from "antd"; //import { Button, Col, Row, notification } from "antd"; +import { Col, Row } from "antd"; import Axios from "axios"; import _ from "lodash"; import queryString from "query-string"; @@ -33,6 +33,7 @@ import OwnerFindModalContainer from "../owner-find-modal/owner-find-modal.contai import { GetSupplementDelta } from "./jobs-available-supplement.estlines.util"; import HeaderFields from "./jobs-available-supplement.headerfields"; import JobsAvailableTableComponent from "./jobs-available-table.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -50,6 +51,7 @@ export function JobsAvailableContainer({ bodyshop, currentUser, insertAuditTrail names: ["CriticalPartsScanning"], splitKey: bodyshop.imexshopid }); + const notification = useNotification(); const { loading, error, data, refetch } = useQuery(QUERY_AVAILABLE_JOBS, { fetchPolicy: "network-only", @@ -175,7 +177,7 @@ export function JobsAvailableContainer({ bodyshop, currentUser, insertAuditTrail }); if (CriticalPartsScanning.treatment === "on") { - CriticalPartsScan(r.data.insert_jobs.returning[0].id); + CriticalPartsScan(r.data.insert_jobs.returning[0].id, notification); } notification["success"]({ message: t("jobs.successes.created"), @@ -277,7 +279,7 @@ export function JobsAvailableContainer({ bodyshop, currentUser, insertAuditTrail setPartsQueueToggle(bodyshop.md_functionality_toggles.parts_queue_toggle); if (CriticalPartsScanning.treatment === "on") { - CriticalPartsScan(updateResult.data.update_jobs.returning[0].id); + CriticalPartsScan(updateResult.data.update_jobs.returning[0].id, notification); } if (updateResult.errors) { //error while inserting diff --git a/client/src/components/jobs-change-status/jobs-change-status.component.jsx b/client/src/components/jobs-change-status/jobs-change-status.component.jsx index 12545faac..bdfcfca94 100644 --- a/client/src/components/jobs-change-status/jobs-change-status.component.jsx +++ b/client/src/components/jobs-change-status/jobs-change-status.component.jsx @@ -1,6 +1,6 @@ import { DownCircleFilled } from "@ant-design/icons"; import { useMutation } from "@apollo/client"; -import { Button, Dropdown, notification } from "antd"; +import { Button, Dropdown } from "antd"; import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; @@ -10,6 +10,7 @@ import { insertAuditTrail } from "../../redux/application/application.actions"; import { selectJobReadOnly } from "../../redux/application/application.selectors"; import { selectBodyshop } from "../../redux/user/user.selectors"; import AuditTrailMapping from "../../utils/AuditTrailMappings"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -25,6 +26,8 @@ export function JobsChangeStatus({ job, bodyshop, jobRO, insertAuditTrail }) { const [availableStatuses, setAvailableStatuses] = useState([]); const [otherStages, setOtherStages] = useState([]); const [mutationUpdateJobstatus] = useMutation(UPDATE_JOB_STATUS); + const notification = useNotification(); + const updateJobStatus = (status) => { mutationUpdateJobstatus({ variables: { jobId: job.id, status: status } diff --git a/client/src/components/jobs-close-export-button/jobs-close-export-button.component.jsx b/client/src/components/jobs-close-export-button/jobs-close-export-button.component.jsx index f22da1eab..410753123 100644 --- a/client/src/components/jobs-close-export-button/jobs-close-export-button.component.jsx +++ b/client/src/components/jobs-close-export-button/jobs-close-export-button.component.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { Button, notification } from "antd"; +import { Button } from "antd"; import axios from "axios"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; @@ -13,6 +13,7 @@ import { insertAuditTrail } from "../../redux/application/application.actions"; import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors"; import AuditTrailMapping from "../../utils/AuditTrailMappings"; import client from "../../utils/GraphQLClient"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -48,6 +49,7 @@ export function JobsCloseExportButton({ const [updateJob] = useMutation(UPDATE_JOB); const [insertExportLog] = useMutation(INSERT_EXPORT_LOG); const [loading, setLoading] = useState(false); + const notification = useNotification(); const handleQbxml = async () => { //Check if it's a CDK setup. diff --git a/client/src/components/jobs-convert-button/jobs-convert-button.component.jsx b/client/src/components/jobs-convert-button/jobs-convert-button.component.jsx index 941de644b..29160eff3 100644 --- a/client/src/components/jobs-convert-button/jobs-convert-button.component.jsx +++ b/client/src/components/jobs-convert-button/jobs-convert-button.component.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { Button, Form, Input, notification, Popover, Select, Space, Switch } from "antd"; +import { Button, Form, Input, Popover, Select, Space, Switch } from "antd"; import axios from "axios"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; @@ -11,6 +11,7 @@ import { selectJobReadOnly } from "../../redux/application/application.selectors import { selectBodyshop } from "../../redux/user/user.selectors"; import AuditTrailMapping from "../../utils/AuditTrailMappings"; import InstanceRenderManager from "../../utils/instanceRenderMgr"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ //currentUser: selectCurrentUser @@ -27,6 +28,7 @@ export function JobsConvertButton({ bodyshop, job, refetch, jobRO, insertAuditTr const [mutationConvertJob] = useMutation(CONVERT_JOB_TO_RO); const { t } = useTranslation(); const [form] = Form.useForm(); + const notification = useNotification(); const handleConvert = async ({ employee_csr, category, ...values }) => { if (parentFormIsFieldsTouched()) { diff --git a/client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.addtoproduction.util.jsx b/client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.addtoproduction.util.jsx index e40c0162a..6a540bb69 100644 --- a/client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.addtoproduction.util.jsx +++ b/client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.addtoproduction.util.jsx @@ -1,4 +1,3 @@ -import { notification } from "antd"; import i18n from "i18next"; import { logImEXEvent } from "../../firebase/firebase.utils"; import { UPDATE_JOB } from "../../graphql/jobs.queries"; @@ -6,7 +5,7 @@ import { insertAuditTrail } from "../../redux/application/application.actions"; import { store } from "../../redux/store"; import AuditTrailMapping from "../../utils/AuditTrailMappings"; -export default function AddToProduction(apolloClient, jobId, completionCallback, remove = false) { +export default function AddToProduction(apolloClient, jobId, completionCallback, remove = false, notification) { logImEXEvent("job_add_to_production"); //get a list of all fields on the job diff --git a/client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.component.jsx b/client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.component.jsx index 89e0efa43..cdcda334d 100644 --- a/client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.component.jsx +++ b/client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.component.jsx @@ -1,7 +1,7 @@ import { DownCircleFilled } from "@ant-design/icons"; import { useApolloClient, useMutation } from "@apollo/client"; import { useSplitTreatments } from "@splitsoftware/splitio-react"; -import { Button, Card, Dropdown, Form, Input, Modal, notification, Popconfirm, Popover, Select, Space } from "antd"; +import { Button, Card, Dropdown, Form, Input, Modal, Popconfirm, Popover, Select, Space } from "antd"; import axios from "axios"; import parsePhoneNumber from "libphonenumber-js"; import React, { useContext, useMemo, useState } from "react"; @@ -31,6 +31,7 @@ import AddToProduction from "./jobs-detail-header-actions.addtoproduction.util"; import DuplicateJob from "./jobs-detail-header-actions.duplicate.util"; import JobsDetailHeaderActionsToggleProduction from "./jobs-detail-header-actions.toggle-production"; import SocketContext from "../../contexts/SocketIO/socketContext.jsx"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -128,6 +129,7 @@ export function JobsDetailHeaderActions({ const [voidJob] = useMutation(VOID_JOB); const [cancelAllAppointments] = useMutation(CANCEL_APPOINTMENTS_BY_JOB_ID); const { socket } = useContext(SocketContext); + const notification = useNotification(); const { treatments: { ImEXPay } @@ -822,14 +824,14 @@ export function JobsDetailHeaderActions({ id: "job-actions-removefromproduction", disabled: !job.converted, label: t("jobs.actions.removefromproduction"), - onClick: () => AddToProduction(client, job.id, refetch, true) + onClick: () => AddToProduction(client, job.id, refetch, true, notification) } : { key: "addtoproduction", id: "job-actions-addtoproduction", disabled: !job.converted, label: t("jobs.actions.addtoproduction"), - onClick: () => AddToProduction(client, job.id, refetch) + onClick: () => AddToProduction(client, job.id, refetch, notification) } ); diff --git a/client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.toggle-production.jsx b/client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.toggle-production.jsx index 358b19900..75c7d7299 100644 --- a/client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.toggle-production.jsx +++ b/client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.toggle-production.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { Button, Form, notification, Popover, Space } from "antd"; +import { Button, Form, Popover, Space } from "antd"; import dayjs from "dayjs"; import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -12,6 +12,7 @@ import { selectBodyshop } from "../../redux/user/user.selectors"; import AuditTrailMapping from "../../utils/AuditTrailMappings"; import { DateTimeFormatterFunction } from "../../utils/DateFormatter"; import FormDateTimePickerComponent from "../form-date-time-picker/form-date-time-picker.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ //currentUser: selectCurrentUser, @@ -28,6 +29,7 @@ export function JobsDetailHeaderActionsToggleProduction({ bodyshop, job, jobRO, const [mutationUpdateJob] = useMutation(JOB_PRODUCTION_TOGGLE); const { t } = useTranslation(); const [form] = Form.useForm(); + const notification = useNotification(); useEffect(() => { //Figure out what scenario were in, populate accodingly diff --git a/client/src/components/jobs-documents-gallery/jobs-document-gallery.reassign.component.jsx b/client/src/components/jobs-documents-gallery/jobs-document-gallery.reassign.component.jsx index 82011bb05..8964aaab4 100644 --- a/client/src/components/jobs-documents-gallery/jobs-document-gallery.reassign.component.jsx +++ b/client/src/components/jobs-documents-gallery/jobs-document-gallery.reassign.component.jsx @@ -1,5 +1,5 @@ import { useApolloClient } from "@apollo/client"; -import { Button, Form, notification, Popover, Space } from "antd"; +import { Button, Form, Popover, Space } from "antd"; import axios from "axios"; import React, { useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -8,6 +8,7 @@ import { createStructuredSelector } from "reselect"; import { GET_DOC_SIZE_BY_JOB } from "../../graphql/documents.queries"; import { selectBodyshop } from "../../redux/user/user.selectors"; import JobSearchSelect from "../job-search-select/job-search-select.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop @@ -20,6 +21,7 @@ export default connect(mapStateToProps, mapDispatchToProps)(JobsDocumentsGallery export function JobsDocumentsGalleryReassign({ bodyshop, galleryImages, callback }) { const { t } = useTranslation(); const [form] = Form.useForm(); + const notification = useNotification(); const selectedImages = useMemo(() => { return [ diff --git a/client/src/components/jobs-documents-gallery/jobs-documents-gallery.delete.component.jsx b/client/src/components/jobs-documents-gallery/jobs-documents-gallery.delete.component.jsx index cfc1fb98a..5cd1fcb06 100644 --- a/client/src/components/jobs-documents-gallery/jobs-documents-gallery.delete.component.jsx +++ b/client/src/components/jobs-documents-gallery/jobs-documents-gallery.delete.component.jsx @@ -1,13 +1,15 @@ import { QuestionCircleOutlined } from "@ant-design/icons"; -import { Button, notification, Popconfirm } from "antd"; +import { Button, Popconfirm } from "antd"; import axios from "axios"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { logImEXEvent } from "../../firebase/firebase.utils"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; //Context: currentUserEmail, bodyshop, jobid, invoiceid export default function JobsDocumentsDeleteButton({ galleryImages, deletionCallback }) { const { t } = useTranslation(); + const notification = useNotification(); const imagesToDelete = [ ...galleryImages.images.filter((image) => image.isSelected), diff --git a/client/src/components/jobs-documents-local-gallery/jobs-documents-local-gallery.delete.component.jsx b/client/src/components/jobs-documents-local-gallery/jobs-documents-local-gallery.delete.component.jsx index e2af7861e..05624557c 100644 --- a/client/src/components/jobs-documents-local-gallery/jobs-documents-local-gallery.delete.component.jsx +++ b/client/src/components/jobs-documents-local-gallery/jobs-documents-local-gallery.delete.component.jsx @@ -1,5 +1,5 @@ import { QuestionCircleOutlined } from "@ant-design/icons"; -import { Button, notification, Popconfirm } from "antd"; +import { Button, Popconfirm } from "antd"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { logImEXEvent } from "../../firebase/firebase.utils"; @@ -10,6 +10,7 @@ import { createStructuredSelector } from "reselect"; import { getJobMedia } from "../../redux/media/media.actions"; import { selectAllMedia } from "../../redux/media/media.selectors"; import { selectBodyshop } from "../../redux/user/user.selectors"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ allMedia: selectAllMedia, @@ -23,6 +24,7 @@ export default connect(mapStateToProps, mapDispatchToProps)(JobsDocumentsLocalDe export function JobsDocumentsLocalDeleteButton({ bodyshop, getJobMedia, allMedia, jobid }) { const { t } = useTranslation(); + const notification = useNotification(); const [loading, setLoading] = useState(false); diff --git a/client/src/components/jobs-export-all-button/jobs-export-all-button.component.jsx b/client/src/components/jobs-export-all-button/jobs-export-all-button.component.jsx index f9670dc77..4103f4eb1 100644 --- a/client/src/components/jobs-export-all-button/jobs-export-all-button.component.jsx +++ b/client/src/components/jobs-export-all-button/jobs-export-all-button.component.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { Button, notification } from "antd"; +import { Button } from "antd"; import axios from "axios"; import _ from "lodash"; import React, { useState } from "react"; @@ -13,6 +13,7 @@ import { insertAuditTrail } from "../../redux/application/application.actions"; import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors"; import AuditTrailMapping from "../../utils/AuditTrailMappings"; import client from "../../utils/GraphQLClient"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -47,6 +48,7 @@ export function JobsExportAllButton({ const { t } = useTranslation(); const [updateJob] = useMutation(UPDATE_JOBS); const [insertExportLog] = useMutation(INSERT_EXPORT_LOG); + const notification = useNotification(); const [loading, setLoading] = useState(false); const handleQbxml = async () => { diff --git a/client/src/components/jobs-mark-selected-exported/jobs-mark-selected-exported.jsx b/client/src/components/jobs-mark-selected-exported/jobs-mark-selected-exported.jsx index acedd194f..0dcf63019 100644 --- a/client/src/components/jobs-mark-selected-exported/jobs-mark-selected-exported.jsx +++ b/client/src/components/jobs-mark-selected-exported/jobs-mark-selected-exported.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { Button, notification, Popconfirm } from "antd"; +import { Button, Popconfirm } from "antd"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; @@ -9,6 +9,7 @@ import { UPDATE_JOBS } from "../../graphql/jobs.queries"; import { insertAuditTrail } from "../../redux/application/application.actions"; import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors"; import AuditTrailMapping from "../../utils/AuditTrailMappings"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -35,6 +36,7 @@ export function JobMarkSelectedExported({ const [loading, setLoading] = useState(false); const [open, setOpen] = useState(false); const [insertExportLog] = useMutation(INSERT_EXPORT_LOG); + const notification = useNotification(); const [updateJob] = useMutation(UPDATE_JOBS); const handleUpdate = async () => { diff --git a/client/src/components/jobs-notes/jobs-notes.container.jsx b/client/src/components/jobs-notes/jobs-notes.container.jsx index 96252f891..fb3a50b5d 100644 --- a/client/src/components/jobs-notes/jobs-notes.container.jsx +++ b/client/src/components/jobs-notes/jobs-notes.container.jsx @@ -1,5 +1,4 @@ import { useMutation, useQuery } from "@apollo/client"; -import { notification } from "antd"; import React, { useState } from "react"; //import SpinComponent from "../../components/loading-spinner/loading-spinner.component"; import { useTranslation } from "react-i18next"; @@ -11,6 +10,7 @@ import { DELETE_NOTE, QUERY_NOTES_BY_JOB_PK } from "../../graphql/notes.queries" import { insertAuditTrail } from "../../redux/application/application.actions"; import AuditTrailMapping from "../../utils/AuditTrailMappings"; import JobNotesComponent from "./jobs.notes.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ //currentUser: selectCurrentUser @@ -30,6 +30,8 @@ export function JobNotesContainer({ jobId, insertAuditTrail }) { const [deleteNote] = useMutation(DELETE_NOTE); const { t } = useTranslation(); const [deleteLoading, setDeleteLoading] = useState(false); + const notification = useNotification(); + const handleNoteDelete = (id) => { logImEXEvent("job_note_delete"); setDeleteLoading(true); diff --git a/client/src/components/labor-allocations-adjustment-edit/labor-allocations-adjustment-edit.component.jsx b/client/src/components/labor-allocations-adjustment-edit/labor-allocations-adjustment-edit.component.jsx index 88e5cd654..a76baeb73 100644 --- a/client/src/components/labor-allocations-adjustment-edit/labor-allocations-adjustment-edit.component.jsx +++ b/client/src/components/labor-allocations-adjustment-edit/labor-allocations-adjustment-edit.component.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { Button, Card, Form, InputNumber, notification, Popover, Select } from "antd"; +import { Button, Card, Form, InputNumber, Popover, Select } from "antd"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { UPDATE_JOB } from "../../graphql/jobs.queries"; @@ -8,6 +8,7 @@ import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import { insertAuditTrail } from "../../redux/application/application.actions"; import AuditTrailMapping from "../../utils/AuditTrailMappings"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ //currentUser: selectCurrentUser @@ -29,6 +30,7 @@ export function LaborAllocationsAdjustmentEdit({ const [open, setOpen] = useState(false); const [updateAdjustments] = useMutation(UPDATE_JOB); const [form] = Form.useForm(); + const notification = useNotification(); const { t } = useTranslation(); diff --git a/client/src/components/labor-allocations-table/labor-allocations-table.payroll.component.jsx b/client/src/components/labor-allocations-table/labor-allocations-table.payroll.component.jsx index 82ccbbc7e..5604c59d6 100644 --- a/client/src/components/labor-allocations-table/labor-allocations-table.payroll.component.jsx +++ b/client/src/components/labor-allocations-table/labor-allocations-table.payroll.component.jsx @@ -1,4 +1,4 @@ -import { Alert, Button, Card, Col, notification, Row, Space, Table, Typography } from "antd"; +import { Alert, Button, Card, Col, Row, Space, Table, Typography } from "antd"; import { SyncOutlined } from "@ant-design/icons"; import axios from "axios"; import _ from "lodash"; @@ -13,6 +13,7 @@ import "./labor-allocations-table.styles.scss"; import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component"; import UpsellComponent, { upsellEnum } from "../upsell/upsell.component"; import LockWrapperComponent from "../lock-wrapper/lock-wrapper.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -40,6 +41,7 @@ export function PayrollLaborAllocationsTable({ }, filteredInfo: {} }); + const notification = useNotification(); useEffect(() => { async function CalculateTotals() { diff --git a/client/src/components/note-upsert-modal/note-upsert-modal.container.jsx b/client/src/components/note-upsert-modal/note-upsert-modal.container.jsx index f6b149fc4..6d844e5fa 100644 --- a/client/src/components/note-upsert-modal/note-upsert-modal.container.jsx +++ b/client/src/components/note-upsert-modal/note-upsert-modal.container.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { Form, Modal, notification } from "antd"; +import { Form, Modal } from "antd"; import React, { useEffect } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; @@ -12,6 +12,7 @@ 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"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ currentUser: selectCurrentUser, @@ -26,6 +27,7 @@ export function NoteUpsertModalContainer({ currentUser, noteUpsertModal, toggleM 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; diff --git a/client/src/components/owner-detail-form/owner-detail-form.container.jsx b/client/src/components/owner-detail-form/owner-detail-form.container.jsx index 3958560d4..fdf2df339 100644 --- a/client/src/components/owner-detail-form/owner-detail-form.container.jsx +++ b/client/src/components/owner-detail-form/owner-detail-form.container.jsx @@ -1,4 +1,4 @@ -import { Button, Form, notification, Popconfirm } from "antd"; +import { Button, Form, Popconfirm } from "antd"; import { PageHeader } from "@ant-design/pro-layout"; import React, { useState } from "react"; @@ -7,6 +7,7 @@ import { useMutation } from "@apollo/client"; import { useTranslation } from "react-i18next"; import { DELETE_OWNER, UPDATE_OWNER } from "../../graphql/owners.queries"; import OwnerDetailFormComponent from "./owner-detail-form.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; function OwnerDetailFormContainer({ owner, refetch }) { const { t } = useTranslation(); @@ -15,6 +16,7 @@ function OwnerDetailFormContainer({ owner, refetch }) { const [loading, setLoading] = useState(false); const [updateOwner] = useMutation(UPDATE_OWNER); const [deleteOwner] = useMutation(DELETE_OWNER); + const notification = useNotification(); const handleDelete = async () => { setLoading(true); diff --git a/client/src/components/owner-detail-update-jobs/owner-detail-update-jobs.component.jsx b/client/src/components/owner-detail-update-jobs/owner-detail-update-jobs.component.jsx index 5db3a72a2..6aad4613c 100644 --- a/client/src/components/owner-detail-update-jobs/owner-detail-update-jobs.component.jsx +++ b/client/src/components/owner-detail-update-jobs/owner-detail-update-jobs.component.jsx @@ -1,13 +1,16 @@ import React from "react"; -import { Button, notification } from "antd"; +import { Button } from "antd"; import { useTranslation } from "react-i18next"; import { useMutation } from "@apollo/client"; import { UPDATE_JOBS } from "../../graphql/jobs.queries"; import { logImEXEvent } from "../../firebase/firebase.utils"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; export default function OwnerDetailUpdateJobsComponent({ owner, selectedJobs, disabled }) { const { t } = useTranslation(); const [updateJobs] = useMutation(UPDATE_JOBS); + const notification = useNotification(); + const handlecClick = (e) => { logImEXEvent("owner_update_jobs", { count: selectedJobs.length }); diff --git a/client/src/components/parts-dispatch-expander/parts-dispatch-expander.component.jsx b/client/src/components/parts-dispatch-expander/parts-dispatch-expander.component.jsx index 2a84527cc..90adb8284 100644 --- a/client/src/components/parts-dispatch-expander/parts-dispatch-expander.component.jsx +++ b/client/src/components/parts-dispatch-expander/parts-dispatch-expander.component.jsx @@ -1,14 +1,16 @@ import { useMutation } from "@apollo/client"; -import { Button, Card, Col, notification, Row, Table } from "antd"; +import { Button, Card, Col, Row, Table } from "antd"; import dayjs from "../../utils/day"; import React from "react"; import { useTranslation } from "react-i18next"; import { UPDATE_PARTS_DISPATCH_LINE } from "../../graphql/parts-dispatch.queries"; import { DateTimeFormatter } from "../../utils/DateFormatter"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; export default function PartsDispatchExpander({ dispatch, job }) { const { t } = useTranslation(); const [updateDispatchLine] = useMutation(UPDATE_PARTS_DISPATCH_LINE); + const notification = useNotification(); const handleAccept = async ({ partsDispatchLineId }) => { const accepted_at = dayjs(); diff --git a/client/src/components/parts-order-backorder-eta/parts-order-backorder-eta.component.jsx b/client/src/components/parts-order-backorder-eta/parts-order-backorder-eta.component.jsx index db0d49f70..d8895803b 100644 --- a/client/src/components/parts-order-backorder-eta/parts-order-backorder-eta.component.jsx +++ b/client/src/components/parts-order-backorder-eta/parts-order-backorder-eta.component.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { Button, Form, notification, Popover, Spin } from "antd"; +import { Button, Form, Popover, Spin } from "antd"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; @@ -10,6 +10,7 @@ import { selectBodyshop } from "../../redux/user/user.selectors"; import { DateFormatter } from "../../utils/DateFormatter"; import { CalendarFilled } from "@ant-design/icons"; import DateTimePicker from "../form-date-time-picker/form-date-time-picker.component.jsx"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop @@ -28,6 +29,7 @@ export function PartsOrderBackorderEta({ const [updateBoDate] = useMutation(MUTATION_UPDATE_BO_ETA); const { t } = useTranslation(); const [form] = Form.useForm(); + const notification = useNotification(); const isAlreadyBackordered = bodyshop.md_order_statuses.default_bo === partsOrderStatus; diff --git a/client/src/components/parts-order-cm-received/parts-order-cm-received.component.jsx b/client/src/components/parts-order-cm-received/parts-order-cm-received.component.jsx index d29efc1d0..af7d52142 100644 --- a/client/src/components/parts-order-cm-received/parts-order-cm-received.component.jsx +++ b/client/src/components/parts-order-cm-received/parts-order-cm-received.component.jsx @@ -1,14 +1,16 @@ import { useMutation } from "@apollo/client"; -import { Checkbox, notification, Space, Spin } from "antd"; +import { Checkbox, Space, Spin } from "antd"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { MUTATION_UPDATE_PO_CM_REECEIVED } from "../../graphql/parts-orders.queries"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; export default function PartsOrderCmReceived({ checked, orderLineId, partsOrderId }) { const [updateLine] = useMutation(MUTATION_UPDATE_PO_CM_REECEIVED); const { t } = useTranslation(); const [loading, setLoading] = useState(false); + const notification = useNotification(); const handleChange = async (e) => { setLoading(true); diff --git a/client/src/components/parts-order-line-backorder-button/parts-order-line-backorder-button.component.jsx b/client/src/components/parts-order-line-backorder-button/parts-order-line-backorder-button.component.jsx index 061e77918..26910643c 100644 --- a/client/src/components/parts-order-line-backorder-button/parts-order-line-backorder-button.component.jsx +++ b/client/src/components/parts-order-line-backorder-button/parts-order-line-backorder-button.component.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { Button, Form, notification, Popover } from "antd"; +import { Button, Form, Popover } from "antd"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; @@ -8,6 +8,7 @@ import { logImEXEvent } from "../../firebase/firebase.utils"; import { MUTATION_BACKORDER_PART_LINE } from "../../graphql/parts-orders.queries"; import { selectBodyshop } from "../../redux/user/user.selectors"; import DateTimePicker from "../form-date-time-picker/form-date-time-picker.component.jsx"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop @@ -19,6 +20,7 @@ export function PartsOrderLineBackorderButton({ partsOrderStatus, partsLineId, j const [backorderLine] = useMutation(MUTATION_BACKORDER_PART_LINE); const { t } = useTranslation(); const [form] = Form.useForm(); + const notification = useNotification(); const isAlreadyBackordered = bodyshop.md_order_statuses.default_bo === partsOrderStatus; diff --git a/client/src/components/parts-order-modal/parts-order-modal.container.jsx b/client/src/components/parts-order-modal/parts-order-modal.container.jsx index 76113a7e0..280597163 100644 --- a/client/src/components/parts-order-modal/parts-order-modal.container.jsx +++ b/client/src/components/parts-order-modal/parts-order-modal.container.jsx @@ -1,5 +1,5 @@ import { useMutation, useQuery, useApolloClient } from "@apollo/client"; -import { Form, Modal, notification } from "antd"; +import { Form, Modal } from "antd"; import dayjs from "../../utils/day"; import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -24,6 +24,7 @@ import axios from "axios"; import { useSplitTreatments } from "@splitsoftware/splitio-react"; import _ from "lodash"; import { UPDATE_JOB } from "../../graphql/jobs.queries"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ currentUser: selectCurrentUser, @@ -49,6 +50,7 @@ export function PartsOrderModalContainer({ }) { const { t } = useTranslation(); const client = useApolloClient(); + const notification = useNotification(); const { treatments: { OEConnection_PriceChange } @@ -158,7 +160,7 @@ export function PartsOrderModalContainer({ vendorid: bodyshop.inhousevendorid, invoice_number: "ih", isinhouse: true, - date: dayjs(), + date: dayjs(), total: 0, billlines: values.parts_order_lines.data.map((p) => { return { @@ -213,7 +215,8 @@ export function PartsOrderModalContainer({ : Templates.sublet_order.subject }, "e", - jobId + jobId, + notification ); } else if (sendType === "p") { GenerateDocument( @@ -228,7 +231,9 @@ export function PartsOrderModalContainer({ } }, {}, - "p" + "p", + null, + notification ); } else if (sendType === "oec") { //Send to Partner OEC. diff --git a/client/src/components/parts-receive-modal/parts-receive-modal.container.jsx b/client/src/components/parts-receive-modal/parts-receive-modal.container.jsx index 50ef34625..4c52ce195 100644 --- a/client/src/components/parts-receive-modal/parts-receive-modal.container.jsx +++ b/client/src/components/parts-receive-modal/parts-receive-modal.container.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { Form, Modal, notification } from "antd"; +import { Form, Modal } from "antd"; import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; @@ -10,6 +10,7 @@ import { toggleModalVisible } from "../../redux/modals/modals.actions"; import { selectPartsReceive } from "../../redux/modals/modals.selectors"; import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors"; import PartsReceiveModalComponent from "./parts-receive-modal.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ currentUser: selectCurrentUser, @@ -24,6 +25,8 @@ const mapDispatchToProps = (dispatch) => ({ export function PartsReceiveModalContainer({ partsReceiveModal, toggleModalVisible, currentUser, bodyshop }) { const { t } = useTranslation(); const [loading, setLoading] = useState(false); + const notification = useNotification(); + const { open, context, actions } = partsReceiveModal; const { partsorderlines } = context; diff --git a/client/src/components/payable-export-all-button/payable-export-all-button.component.jsx b/client/src/components/payable-export-all-button/payable-export-all-button.component.jsx index 6e2d2b5ed..a49d0e159 100644 --- a/client/src/components/payable-export-all-button/payable-export-all-button.component.jsx +++ b/client/src/components/payable-export-all-button/payable-export-all-button.component.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { Button, notification } from "antd"; +import { Button } from "antd"; import axios from "axios"; import _ from "lodash"; import React, { useState } from "react"; @@ -12,6 +12,7 @@ import { INSERT_EXPORT_LOG } from "../../graphql/accounting.queries"; import { UPDATE_BILLS } from "../../graphql/bills.queries"; import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors"; import client from "../../utils/GraphQLClient"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -42,6 +43,7 @@ export function PayableExportAll({ const [updateBill] = useMutation(UPDATE_BILLS); const [loading, setLoading] = useState(false); const [insertExportLog] = useMutation(INSERT_EXPORT_LOG); + const notification = useNotification(); const handleQbxml = async () => { logImEXEvent("accounting_payables_export_all"); diff --git a/client/src/components/payable-export-button/payable-export-button.component.jsx b/client/src/components/payable-export-button/payable-export-button.component.jsx index f369b031c..0eea05838 100644 --- a/client/src/components/payable-export-button/payable-export-button.component.jsx +++ b/client/src/components/payable-export-button/payable-export-button.component.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { Button, notification } from "antd"; +import { Button } from "antd"; import axios from "axios"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; @@ -11,6 +11,7 @@ import { INSERT_EXPORT_LOG } from "../../graphql/accounting.queries"; import { UPDATE_BILLS } from "../../graphql/bills.queries"; import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors"; import client from "../../utils/GraphQLClient"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -41,6 +42,7 @@ export function PayableExportButton({ const [updateBill] = useMutation(UPDATE_BILLS); const [loading, setLoading] = useState(false); const [insertExportLog] = useMutation(INSERT_EXPORT_LOG); + const notification = useNotification(); const handleQbxml = async () => { logImEXEvent("accounting_export_payable"); diff --git a/client/src/components/payable-mark-selected-exported/payable-mark-selected-exported.component.jsx b/client/src/components/payable-mark-selected-exported/payable-mark-selected-exported.component.jsx index ccd480547..10adb9f54 100644 --- a/client/src/components/payable-mark-selected-exported/payable-mark-selected-exported.component.jsx +++ b/client/src/components/payable-mark-selected-exported/payable-mark-selected-exported.component.jsx @@ -1,11 +1,12 @@ import { gql, useMutation } from "@apollo/client"; -import { Button, notification, Popconfirm } from "antd"; +import { Button, Popconfirm } from "antd"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import { INSERT_EXPORT_LOG } from "../../graphql/accounting.queries"; import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -41,6 +42,7 @@ export function BillMarkSelectedExported({ } } `); + const notification = useNotification(); const handleUpdate = async () => { setLoading(true); diff --git a/client/src/components/payment-expanded-row/payment-expanded-row.component.jsx b/client/src/components/payment-expanded-row/payment-expanded-row.component.jsx index abd9b1fa3..d0d3f53e4 100644 --- a/client/src/components/payment-expanded-row/payment-expanded-row.component.jsx +++ b/client/src/components/payment-expanded-row/payment-expanded-row.component.jsx @@ -1,5 +1,5 @@ import { useMutation, useQuery } from "@apollo/client"; -import { Button, Descriptions, InputNumber, Modal, notification, Space } from "antd"; +import { Button, Descriptions, InputNumber, Modal, Space } from "antd"; import axios from "axios"; import dayjs from "../../utils/day"; import React, { useState } from "react"; @@ -12,10 +12,11 @@ import { import { INSERT_NEW_PAYMENT } from "../../graphql/payments.queries"; import CurrencyFormatter from "../../utils/CurrencyFormatter"; import { DateTimeFormatter } from "../../utils/DateFormatter"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const { confirm } = Modal; -const openNotificationWithIcon = (type, t) => { +const openNotificationWithIcon = (type, t, notification) => { notification[type]({ message: t("job_payments.notifications.error.title"), description: t("job_payments.notifications.error.description") @@ -27,6 +28,7 @@ const PaymentExpandedRowComponent = ({ record, bodyshop }) => { const [insertPayment] = useMutation(INSERT_NEW_PAYMENT); const [insertPaymentResponse] = useMutation(INSERT_PAYMENT_RESPONSE); const { t } = useTranslation(); + const notification = useNotification(); const { loading, error, data } = useQuery(QUERY_PAYMENT_RESPONSE_BY_PAYMENT_ID, { variables: { @@ -97,7 +99,7 @@ const PaymentExpandedRowComponent = ({ record, bodyshop }) => { }); if (refundResponse.data.status < 0) { - openNotificationWithIcon("error", t); + openNotificationWithIcon("error", t, notification); return; } @@ -119,11 +121,7 @@ const PaymentExpandedRowComponent = ({ record, bodyshop }) => { return (
- + {payment_response?.response?.methodhint} diff --git a/client/src/components/payment-export-button/payment-export-button.component.jsx b/client/src/components/payment-export-button/payment-export-button.component.jsx index 35937da58..432d380b7 100644 --- a/client/src/components/payment-export-button/payment-export-button.component.jsx +++ b/client/src/components/payment-export-button/payment-export-button.component.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { Button, notification } from "antd"; +import { Button } from "antd"; import axios from "axios"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; @@ -11,6 +11,7 @@ import { UPDATE_PAYMENTS } from "../../graphql/payments.queries"; import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors"; import client from "../../utils/GraphQLClient"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -41,6 +42,7 @@ export function PaymentExportButton({ const [updatePayment] = useMutation(UPDATE_PAYMENTS); const [loading, setLoading] = useState(false); const [insertExportLog] = useMutation(INSERT_EXPORT_LOG); + const notification = useNotification(); const handleQbxml = async () => { logImEXEvent("accounting_payment_export"); diff --git a/client/src/components/payment-mark-export-button/payment-mark-export-button-component.jsx b/client/src/components/payment-mark-export-button/payment-mark-export-button-component.jsx index f82832ddc..3f2fa4ce3 100644 --- a/client/src/components/payment-mark-export-button/payment-mark-export-button-component.jsx +++ b/client/src/components/payment-mark-export-button/payment-mark-export-button-component.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { Button, notification } from "antd"; +import { Button } from "antd"; import React from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; @@ -9,6 +9,7 @@ import { UPDATE_PAYMENT } from "../../graphql/payments.queries"; import { setModalContext } from "../../redux/modals/modals.actions"; import { selectPayment } from "../../redux/modals/modals.selectors"; import { selectCurrentUser } from "../../redux/user/user.selectors"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ currentUser: selectCurrentUser, @@ -23,6 +24,7 @@ const PaymentMarkForExportButton = ({ bodyshop, payment, refetch, setPaymentCont const { t } = useTranslation(); const [insertExportLog, { loading: exportLogLoading }] = useMutation(INSERT_EXPORT_LOG); const [updatePayment, { loading: updatePaymentLoading }] = useMutation(UPDATE_PAYMENT); + const notification = useNotification(); const handleClick = async () => { const today = new Date(); diff --git a/client/src/components/payment-mark-selected-exported/payment-mark-selected-exported.component.jsx b/client/src/components/payment-mark-selected-exported/payment-mark-selected-exported.component.jsx index 8dbd2ae45..d65b89207 100644 --- a/client/src/components/payment-mark-selected-exported/payment-mark-selected-exported.component.jsx +++ b/client/src/components/payment-mark-selected-exported/payment-mark-selected-exported.component.jsx @@ -1,11 +1,12 @@ import { gql, useMutation } from "@apollo/client"; -import { Button, notification, Popconfirm } from "antd"; +import { Button, Popconfirm } from "antd"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import { INSERT_EXPORT_LOG } from "../../graphql/accounting.queries"; import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -29,6 +30,7 @@ export function PaymentMarkSelectedExported({ const { t } = useTranslation(); const [loading, setLoading] = useState(false); const [open, setOpen] = useState(false); + const notification = useNotification(); const [insertExportLog] = useMutation(INSERT_EXPORT_LOG); const [updatePayments] = useMutation(gql` diff --git a/client/src/components/payment-modal/payment-modal.container.jsx b/client/src/components/payment-modal/payment-modal.container.jsx index 6535005d2..471269193 100644 --- a/client/src/components/payment-modal/payment-modal.container.jsx +++ b/client/src/components/payment-modal/payment-modal.container.jsx @@ -1,34 +1,35 @@ -import {useMutation} from "@apollo/client"; -import {Button, Form, Modal, notification, Space} from "antd"; -import React, {useEffect, useState} from "react"; -import {useTranslation} from "react-i18next"; -import {connect} from "react-redux"; -import {createStructuredSelector} from "reselect"; -import {INSERT_NEW_PAYMENT, UPDATE_PAYMENT} from "../../graphql/payments.queries"; -import {toggleModalVisible} from "../../redux/modals/modals.actions"; -import {selectPayment} from "../../redux/modals/modals.selectors"; -import {selectBodyshop} from "../../redux/user/user.selectors"; -import {GenerateDocument} from "../../utils/RenderTemplate"; -import {TemplateList} from "../../utils/TemplateConstants"; +import { useMutation } from "@apollo/client"; +import { Button, Form, Modal, Space } from "antd"; +import React, { useEffect, useState } from "react"; +import { useTranslation } from "react-i18next"; +import { connect } from "react-redux"; +import { createStructuredSelector } from "reselect"; +import { INSERT_NEW_PAYMENT, UPDATE_PAYMENT } from "../../graphql/payments.queries"; +import { toggleModalVisible } from "../../redux/modals/modals.actions"; +import { selectPayment } from "../../redux/modals/modals.selectors"; +import { selectBodyshop } from "../../redux/user/user.selectors"; +import { GenerateDocument } from "../../utils/RenderTemplate"; +import { TemplateList } from "../../utils/TemplateConstants"; import PaymentForm from "../payment-form/payment-form.component"; -import PaymentMarkForExportButton - from "../payment-mark-export-button/payment-mark-export-button-component"; +import PaymentMarkForExportButton from "../payment-mark-export-button/payment-mark-export-button-component"; import PaymentReexportButton from "../payment-reexport-button/payment-reexport-button.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ paymentModal: selectPayment, - bodyshop: selectBodyshop, + bodyshop: selectBodyshop }); const mapDispatchToProps = (dispatch) => ({ toggleModalVisible: () => dispatch(toggleModalVisible("payment")) }); -function PaymentModalContainer({paymentModal, toggleModalVisible, bodyshop }) { +function PaymentModalContainer({ paymentModal, toggleModalVisible, bodyshop }) { const [form] = Form.useForm(); const [enterAgain, setEnterAgain] = useState(false); const [insertPayment] = useMutation(INSERT_NEW_PAYMENT); const [updatePayment] = useMutation(UPDATE_PAYMENT); + const notification = useNotification(); const { t } = useTranslation(); const { context, actions, open } = paymentModal; @@ -69,7 +70,8 @@ function PaymentModalContainer({paymentModal, toggleModalVisible, bodyshop }) { subject: Templates.payment_receipt.subject }, sendby === "email" ? "e" : "p", - paymentObj.jobid + paymentObj.jobid, + notification ); } } else { diff --git a/client/src/components/payment-reexport-button/payment-reexport-button.component.jsx b/client/src/components/payment-reexport-button/payment-reexport-button.component.jsx index 3abd5bfd5..f9175e8b5 100644 --- a/client/src/components/payment-reexport-button/payment-reexport-button.component.jsx +++ b/client/src/components/payment-reexport-button/payment-reexport-button.component.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { Button, notification } from "antd"; +import { Button } from "antd"; import React from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; @@ -7,6 +7,7 @@ import { createStructuredSelector } from "reselect"; import { UPDATE_PAYMENT } from "../../graphql/payments.queries"; import { setModalContext } from "../../redux/modals/modals.actions"; import { selectPayment } from "../../redux/modals/modals.selectors"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ paymentModal: selectPayment @@ -19,6 +20,7 @@ const mapDispatchToProps = (dispatch) => ({ const PaymentReexportButton = ({ paymentModal, payment, refetch, setPaymentContext }) => { const { t } = useTranslation(); const [updatePayment, { loading }] = useMutation(UPDATE_PAYMENT); + const notification = useNotification(); const handleClick = async () => { const paymentUpdateResponse = await updatePayment({ diff --git a/client/src/components/payments-export-all-button/payments-export-all-button.component.jsx b/client/src/components/payments-export-all-button/payments-export-all-button.component.jsx index 46131daae..b7168073b 100644 --- a/client/src/components/payments-export-all-button/payments-export-all-button.component.jsx +++ b/client/src/components/payments-export-all-button/payments-export-all-button.component.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { Button, notification } from "antd"; +import { Button } from "antd"; import axios from "axios"; import _ from "lodash"; import React, { useState } from "react"; @@ -11,6 +11,7 @@ import { UPDATE_PAYMENTS } from "../../graphql/payments.queries"; import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors"; import client from "../../utils/GraphQLClient"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -41,6 +42,7 @@ export function PaymentsExportAllButton({ const [updatePayments] = useMutation(UPDATE_PAYMENTS); const [loading, setLoading] = useState(false); const [insertExportLog] = useMutation(INSERT_EXPORT_LOG); + const notification = useNotification(); const handleQbxml = async () => { setLoading(true); diff --git a/client/src/components/phonebook-form/phonebook-form.container.jsx b/client/src/components/phonebook-form/phonebook-form.container.jsx index 78db9920e..6f01ec4bf 100644 --- a/client/src/components/phonebook-form/phonebook-form.container.jsx +++ b/client/src/components/phonebook-form/phonebook-form.container.jsx @@ -1,5 +1,5 @@ import { useMutation, useQuery } from "@apollo/client"; -import { Form, notification } from "antd"; +import { Form } from "antd"; import queryString from "query-string"; import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -16,6 +16,7 @@ import { selectBodyshop } from "../../redux/user/user.selectors"; import AlertComponent from "../alert/alert.component"; import LoadingSpinner from "../loading-spinner/loading-spinner.component"; import PhonebookFormComponent from "./phonebook-form.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop @@ -39,6 +40,8 @@ function PhonebookFormContainer({ refetch, bodyshop }) { const [insertPhonebook] = useMutation(INSERT_NEW_PHONEBOOK); const [deletePhonebook] = useMutation(DELETE_PHONEBOOK); + const notification = useNotification(); + const handleDelete = async () => { setFormLoading(true); const result = await deletePhonebook({ diff --git a/client/src/components/print-center-item/print-center-item.component.jsx b/client/src/components/print-center-item/print-center-item.component.jsx index 42e8a6d95..edd023e83 100644 --- a/client/src/components/print-center-item/print-center-item.component.jsx +++ b/client/src/components/print-center-item/print-center-item.component.jsx @@ -9,7 +9,8 @@ import { selectTechnician } from "../../redux/tech/tech.selectors"; import { selectBodyshop } from "../../redux/user/user.selectors"; import { GenerateDocument } from "../../utils/RenderTemplate"; import LockWrapperComponent from "../lock-wrapper/lock-wrapper.component"; -import { HasFeatureAccess } from './../feature-wrapper/feature-wrapper.component'; +import { HasFeatureAccess } from "./../feature-wrapper/feature-wrapper.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ printCenterModal: selectPrintCenter, @@ -31,6 +32,8 @@ export function PrintCenterItemComponent({ }) { const [loading, setLoading] = useState(false); const { context } = printCenterModal; + const notification = useNotification(); + const renderToNewWindow = async () => { setLoading(true); await GenerateDocument( @@ -39,12 +42,17 @@ export function PrintCenterItemComponent({ variables: { id: id } }, {}, - "p" + "p", + null, + notification ); setLoading(false); }; - if (disabled || (item.featureNameRestricted && !HasFeatureAccess({"featureName": item.featureNameRestricted, bodyshop}))) + if ( + disabled || + (item.featureNameRestricted && !HasFeatureAccess({ featureName: item.featureNameRestricted, bodyshop })) + ) return (
  • @@ -70,7 +78,8 @@ export function PrintCenterItemComponent({ subject: item.subject }, "e", - id + id, + notification ); }} /> diff --git a/client/src/components/print-center-jobs-labels/print-center-jobs-labels.component.jsx b/client/src/components/print-center-jobs-labels/print-center-jobs-labels.component.jsx index 6639f14f3..b33ae39f5 100644 --- a/client/src/components/print-center-jobs-labels/print-center-jobs-labels.component.jsx +++ b/client/src/components/print-center-jobs-labels/print-center-jobs-labels.component.jsx @@ -1,13 +1,4 @@ -import { - Button, - Card, - Form, - InputNumber, - notification, - Popover, - Radio, - Space, -} from "antd"; +import { Button, Card, Form, InputNumber, Popover, Radio, Space } from "antd"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; @@ -15,6 +6,7 @@ import { createStructuredSelector } from "reselect"; import { selectBodyshop } from "../../redux/user/user.selectors"; import { GenerateDocument } from "../../utils/RenderTemplate"; import { TemplateList } from "../../utils/TemplateConstants"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop @@ -29,6 +21,7 @@ export function PrintCenterJobsLabels({ bodyshop, jobId }) { const [loading, setLoading] = useState(false); const { t } = useTranslation(); const [form] = Form.useForm(); + const notification = useNotification(); const handleOk = (e) => { e.stopPropagation(); @@ -51,7 +44,8 @@ export function PrintCenterJobsLabels({ bodyshop, jobId }) { }, {}, "p", - jobId + jobId, + notification ); setIsModalVisible(false); } catch (error) { @@ -109,9 +103,7 @@ export function PrintCenterJobsLabels({ bodyshop, jobId }) { - +
  • diff --git a/client/src/components/print-center-speed-print/print-center-speed-print.component.jsx b/client/src/components/print-center-speed-print/print-center-speed-print.component.jsx index ffbe2d161..b287377d4 100644 --- a/client/src/components/print-center-speed-print/print-center-speed-print.component.jsx +++ b/client/src/components/print-center-speed-print/print-center-speed-print.component.jsx @@ -9,6 +9,7 @@ import { logImEXEvent } from "../../firebase/firebase.utils"; import { selectBodyshop } from "../../redux/user/user.selectors"; import { GenerateDocuments } from "../../utils/RenderTemplate"; import { TemplateList } from "../../utils/TemplateConstants"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop //currentUser: selectCurrentUser @@ -21,6 +22,7 @@ export function PrintCenterSpeedPrint({ bodyshop, jobId }) { const [loading, setLoading] = useState(false); const { speedprint } = bodyshop; const { t } = useTranslation(); + const notification = useNotification(); const renderAllTemplates = async (templateKeys) => { logImEXEvent("speed_print_render_all_templates"); @@ -28,7 +30,8 @@ export function PrintCenterSpeedPrint({ bodyshop, jobId }) { await GenerateDocuments( templateKeys.map((key) => { return { name: key, variables: { id: jobId } }; - }) + }), + notification ); setLoading(false); }; diff --git a/client/src/components/print-wrapper/print-wrapper.component.jsx b/client/src/components/print-wrapper/print-wrapper.component.jsx index cbb7e515e..2a00d1d00 100644 --- a/client/src/components/print-wrapper/print-wrapper.component.jsx +++ b/client/src/components/print-wrapper/print-wrapper.component.jsx @@ -2,6 +2,7 @@ import { MailFilled, PrinterFilled } from "@ant-design/icons"; import { Space, Spin } from "antd"; import React, { useState } from "react"; import { GenerateDocument } from "../../utils/RenderTemplate"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; export default function PrintWrapperComponent({ templateObject, @@ -12,10 +13,12 @@ export default function PrintWrapperComponent({ disabled }) { const [loading, setLoading] = useState(false); + const notification = useNotification(); + const handlePrint = async (type) => { if (disabled) return; setLoading(true); - await GenerateDocument(templateObject, messageObject, type, id); + await GenerateDocument(templateObject, messageObject, type, id, notification); setLoading(false); }; diff --git a/client/src/components/production-board-kanban/production-board-kanban.component.jsx b/client/src/components/production-board-kanban/production-board-kanban.component.jsx index 00333198c..574ee1c5a 100644 --- a/client/src/components/production-board-kanban/production-board-kanban.component.jsx +++ b/client/src/components/production-board-kanban/production-board-kanban.component.jsx @@ -1,7 +1,7 @@ import { SyncOutlined } from "@ant-design/icons"; import { PageHeader } from "@ant-design/pro-layout"; import { useApolloClient } from "@apollo/client"; -import { Button, notification, Skeleton, Space } from "antd"; +import { Button, Skeleton, Space } from "antd"; import cloneDeep from "lodash/cloneDeep"; import isEqual from "lodash/isEqual"; import React, { useCallback, useEffect, useMemo, useState } from "react"; @@ -24,6 +24,7 @@ import { createBoardData } from "./production-board-kanban.utils.js"; import { defaultFilters, mergeWithDefaults } from "./settings/defaultKanbanSettings.js"; import ProductionBoardKanbanSettings from "./settings/production-board-kanban.settings.component.jsx"; import Board from "./trello-board/index"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop @@ -46,6 +47,7 @@ function ProductionBoardKanbanComponent({ data, bodyshop, refetch, insertAuditTr const [loading, setLoading] = useState(true); const [isMoving, setIsMoving] = useState(false); const [orientation, setOrientation] = useState("vertical"); + const notification = useNotification(); const { t } = useTranslation(); const client = useApolloClient(); @@ -180,7 +182,7 @@ function ProductionBoardKanbanComponent({ data, bodyshop, refetch, insertAuditTr setIsMoving(false); } }, - [boardLanes, client, getCardByID, isMoving, t, insertAuditTrail] + [boardLanes, client, getCardByID, isMoving, t, insertAuditTrail, notification] ); const cardSettings = useMemo(() => { diff --git a/client/src/components/production-board-kanban/settings/production-board-kanban.settings.component.jsx b/client/src/components/production-board-kanban/settings/production-board-kanban.settings.component.jsx index 0d78416f8..ea0ae5865 100644 --- a/client/src/components/production-board-kanban/settings/production-board-kanban.settings.component.jsx +++ b/client/src/components/production-board-kanban/settings/production-board-kanban.settings.component.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { Button, Card, Col, Form, notification, Popover, Row, Tabs } from "antd"; +import { Button, Card, Col, Form, Popover, Row, Tabs } from "antd"; import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { UPDATE_KANBAN_SETTINGS } from "../../../graphql/user.queries.js"; @@ -10,6 +10,7 @@ import StatisticsSettings from "./StatisticsSettings.jsx"; import FilterSettings from "./FilterSettings.jsx"; import PropTypes from "prop-types"; import { isFunction } from "lodash"; +import { useNotification } from "../../../contexts/Notifications/notificationContext.jsx"; function ProductionBoardKanbanSettings({ associationSettings, parentLoading, bodyshop, data, onSettingsChange }) { const [form] = Form.useForm(); @@ -22,6 +23,7 @@ function ProductionBoardKanbanSettings({ associationSettings, parentLoading, bod const [updateKbSettings] = useMutation(UPDATE_KANBAN_SETTINGS); const { t } = useTranslation(); + const notification = useNotification(); useEffect(() => { if (associationSettings?.kanban_settings) { diff --git a/client/src/components/production-list-columns/production-list-columns.empassignment.component.jsx b/client/src/components/production-list-columns/production-list-columns.empassignment.component.jsx index 141ed42bb..3e7cdbdcd 100644 --- a/client/src/components/production-list-columns/production-list-columns.empassignment.component.jsx +++ b/client/src/components/production-list-columns/production-list-columns.empassignment.component.jsx @@ -1,6 +1,6 @@ import { DeleteFilled, PlusCircleFilled } from "@ant-design/icons"; import { useMutation } from "@apollo/client"; -import { Button, Col, notification, Popover, Row, Select, Space, Spin } from "antd"; +import { Button, Col, Popover, Row, Select, Space, Spin } from "antd"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; @@ -10,6 +10,7 @@ import { UPDATE_JOB } from "../../graphql/jobs.queries"; import { insertAuditTrail } from "../../redux/application/application.actions"; import { selectBodyshop } from "../../redux/user/user.selectors"; import AuditTrailMapping from "../../utils/AuditTrailMappings"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const iconStyle = { marginLeft: ".3rem" }; const mapStateToProps = createStructuredSelector({ @@ -23,6 +24,7 @@ export function ProductionListEmpAssignment({ insertAuditTrail, bodyshop, record const { t } = useTranslation(); const [updateJob] = useMutation(UPDATE_JOB); const [loading, setLoading] = useState(false); + const notification = useNotification(); const handleAdd = async (assignment) => { setLoading(true); diff --git a/client/src/components/production-list-columns/production-list-columns.lastcontacted.component.jsx b/client/src/components/production-list-columns/production-list-columns.lastcontacted.component.jsx index 4b4b03a72..26adb6d10 100644 --- a/client/src/components/production-list-columns/production-list-columns.lastcontacted.component.jsx +++ b/client/src/components/production-list-columns/production-list-columns.lastcontacted.component.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { Button, Card, Dropdown, Form, Input, notification, Space } from "antd"; +import { Button, Card, Dropdown, Form, Input, Space } from "antd"; import dayjs from "../../utils/day"; import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -11,6 +11,7 @@ import { INSERT_NEW_NOTE } from "../../graphql/notes.queries"; import { selectCurrentUser } from "../../redux/user/user.selectors"; import { DateFormatter } from "../../utils/DateFormatter"; import FormDateTimePickerComponent from "../form-date-time-picker/form-date-time-picker.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ currentUser: selectCurrentUser @@ -26,6 +27,8 @@ export function ProductionLastContacted({ currentUser, record }) { const [open, setOpen] = useState(false); const { t } = useTranslation(); const [form] = Form.useForm(); + const notification = useNotification(); + const handleFinish = async ({ date_last_contacted, date_next_contact, note }) => { logImEXEvent("production_last_contacted"); diff --git a/client/src/components/production-list-table/production-list-config-manager.component.jsx b/client/src/components/production-list-table/production-list-config-manager.component.jsx index ef8b07af7..e23685ad6 100644 --- a/client/src/components/production-list-table/production-list-config-manager.component.jsx +++ b/client/src/components/production-list-table/production-list-config-manager.component.jsx @@ -1,6 +1,6 @@ import { DeleteOutlined, ExclamationCircleOutlined, PlusOutlined } from "@ant-design/icons"; import { useMutation } from "@apollo/client"; -import { Button, Form, Input, Modal, notification, Popconfirm, Popover, Select, Space } from "antd"; +import { Button, Form, Input, Modal, Popconfirm, Popover, Select, Space } from "antd"; import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { UPDATE_ACTIVE_PROD_LIST_VIEW } from "../../graphql/associations.queries"; @@ -9,6 +9,7 @@ import ProductionListColumns from "../production-list-columns/production-list-co import { useSplitTreatments } from "@splitsoftware/splitio-react"; import { logImEXEvent } from "../../firebase/firebase.utils"; import { isFunction } from "lodash"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const { confirm } = Modal; @@ -33,6 +34,7 @@ export function ProductionListConfigManager({ const [open, setOpen] = useState(false); const [isAddingNewProfile, setIsAddingNewProfile] = useState(false); const [form] = Form.useForm(); + const notification = useNotification(); const [activeView, setActiveView] = useState(() => { const assoc = bodyshop.associations.find((a) => a.useremail === currentUser.email); diff --git a/client/src/components/production-list-table/production-list-print.component.jsx b/client/src/components/production-list-table/production-list-print.component.jsx index 08c7f206d..4edd7350e 100644 --- a/client/src/components/production-list-table/production-list-print.component.jsx +++ b/client/src/components/production-list-table/production-list-print.component.jsx @@ -6,6 +6,7 @@ import { GenerateDocument } from "../../utils/RenderTemplate"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import { selectBodyshop } from "../../redux/user/user.selectors"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const ProdTemplates = TemplateList("production"); const { production_by_technician_one, production_by_category_one, production_by_repair_status_one } = @@ -22,6 +23,7 @@ export default connect(mapStateToProps, mapDispatchToProps)(ProductionListPrint) export function ProductionListPrint({ bodyshop }) { const { t } = useTranslation(); const [loading, setLoading] = useState(false); + const notification = useNotification(); const menu = { items: [ @@ -37,7 +39,9 @@ export function ProductionListPrint({ bodyshop }) { // variables: { id: contract.id }, }, {}, - "p" + "p", + null, + notification ); setLoading(false); } @@ -59,7 +63,9 @@ export function ProductionListPrint({ bodyshop }) { variables: { id: e.id } }, {}, - "p" + "p", + null, + notification ); setLoading(false); } @@ -80,7 +86,9 @@ export function ProductionListPrint({ bodyshop }) { variables: { category: e } }, {}, - "p" + "p", + null, + notification ); setLoading(false); } @@ -101,7 +109,9 @@ export function ProductionListPrint({ bodyshop }) { variables: { status: e } }, {}, - "p" + "p", + null, + notification ); setLoading(false); } diff --git a/client/src/components/production-remove-button/production-remove-button.component.jsx b/client/src/components/production-remove-button/production-remove-button.component.jsx index c440485b6..9e13689f9 100644 --- a/client/src/components/production-remove-button/production-remove-button.component.jsx +++ b/client/src/components/production-remove-button/production-remove-button.component.jsx @@ -1,11 +1,12 @@ import { useMutation } from "@apollo/client"; -import { Button, notification } from "antd"; +import { Button } from "antd"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { logImEXEvent } from "../../firebase/firebase.utils"; import { UPDATE_JOB } from "../../graphql/jobs.queries"; import queryString from "query-string"; import { useLocation, useNavigate } from "react-router-dom"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; export default function ProductionRemoveButton({ jobId }) { const [removeJobFromProduction] = useMutation(UPDATE_JOB); @@ -13,6 +14,7 @@ export default function ProductionRemoveButton({ jobId }) { const [loading, setLoading] = useState(false); const search = queryString.parse(useLocation().search); const history = useNavigate(); + const notification = useNotification(); const handleRemoveFromProd = async () => { logImEXEvent("production_remove_job"); diff --git a/client/src/components/production-sublets-manage/production-sublets-manage.component.jsx b/client/src/components/production-sublets-manage/production-sublets-manage.component.jsx index d52772afc..4bfefb2de 100644 --- a/client/src/components/production-sublets-manage/production-sublets-manage.component.jsx +++ b/client/src/components/production-sublets-manage/production-sublets-manage.component.jsx @@ -1,14 +1,16 @@ import { CheckCircleFilled, EyeInvisibleFilled } from "@ant-design/icons"; -import { Button, List, notification, Popover } from "antd"; +import { Button, List, Popover } from "antd"; import React, { useMemo, useState, useCallback } from "react"; import { useMutation } from "@apollo/client"; import { useTranslation } from "react-i18next"; import { UPDATE_JOB_LINE_SUBLET } from "../../graphql/jobs-lines.queries"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; export default function ProductionSubletsManageComponent({ subletJobLines }) { const { t } = useTranslation(); const [updateJobLine] = useMutation(UPDATE_JOB_LINE_SUBLET); const [loading, setLoading] = useState(false); + const notification = useNotification(); const subletCount = useMemo( () => ({ @@ -47,7 +49,7 @@ export default function ProductionSubletsManageComponent({ subletJobLines }) { } setLoading(false); }, - [updateJobLine, t] + [updateJobLine, t, notification] ); const popContent = useMemo( diff --git a/client/src/components/profile-my/profile-my.component.jsx b/client/src/components/profile-my/profile-my.component.jsx index 16af7809a..f53646bee 100644 --- a/client/src/components/profile-my/profile-my.component.jsx +++ b/client/src/components/profile-my/profile-my.component.jsx @@ -1,4 +1,4 @@ -import { Button, Card, Col, Form, Input, notification } from "antd"; +import { Button, Card, Col, Form, Input } from "antd"; import { LockOutlined } from "@ant-design/icons"; import React from "react"; import { useTranslation } from "react-i18next"; @@ -8,6 +8,7 @@ import { updateUserDetails } from "../../redux/user/user.actions"; import { selectCurrentUser } from "../../redux/user/user.selectors"; import { logImEXEvent, updateCurrentPassword } from "../../firebase/firebase.utils"; import LayoutFormRow from "../layout-form-row/layout-form-row.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ currentUser: selectCurrentUser @@ -20,6 +21,7 @@ export default connect( mapDispatchToProps )(function ProfileMyComponent({ currentUser, updateUserDetails }) { const { t } = useTranslation(); + const notification = useNotification(); const handleFinish = (values) => { logImEXEvent("profile_update"); diff --git a/client/src/components/report-center-modal/report-center-modal.component.jsx b/client/src/components/report-center-modal/report-center-modal.component.jsx index 8d4b31def..ddea0aab2 100644 --- a/client/src/components/report-center-modal/report-center-modal.component.jsx +++ b/client/src/components/report-center-modal/report-center-modal.component.jsx @@ -22,6 +22,7 @@ import VendorSearchSelect from "../vendor-search-select/vendor-search-select.com import ReportCenterModalFiltersSortersComponent from "./report-center-modal-filters-sorters-component"; import "./report-center-modal.styles.scss"; import LockWrapperComponent from "../lock-wrapper/lock-wrapper.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ reportCenterModal: selectReportCenter, @@ -42,6 +43,7 @@ export function ReportCenterModalComponent({ reportCenterModal, bodyshop }) { names: ["Enhanced_Payroll", "ADPPayroll"], splitKey: bodyshop.imexshopid }); + const notification = useNotification(); const [loading, setLoading] = useState(false); const { t } = useTranslation(); @@ -119,7 +121,8 @@ export function ReportCenterModalComponent({ reportCenterModal, bodyshop }) { : values.sendby === "email" ? "e" : "p", - id + id, + notification ); setLoading(false); }; diff --git a/client/src/components/schedule-block-day/schedule-block-day.component.jsx b/client/src/components/schedule-block-day/schedule-block-day.component.jsx index e579697db..58be2878d 100644 --- a/client/src/components/schedule-block-day/schedule-block-day.component.jsx +++ b/client/src/components/schedule-block-day/schedule-block-day.component.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { Dropdown, notification } from "antd"; +import { Dropdown } from "antd"; import dayjs from "../../utils/day"; import React from "react"; import { useTranslation } from "react-i18next"; @@ -8,6 +8,7 @@ import { createStructuredSelector } from "reselect"; import { INSERT_APPOINTMENT_BLOCK } from "../../graphql/appointments.queries"; import { selectBodyshop } from "../../redux/user/user.selectors"; import { logImEXEvent } from "../../firebase/firebase.utils"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop @@ -18,6 +19,7 @@ const mapDispatchToProps = (dispatch) => ({}); export function ScheduleBlockDay({ date, children, refetch, bodyshop, alreadyBlocked }) { const { t } = useTranslation(); const [insertBlock] = useMutation(INSERT_APPOINTMENT_BLOCK); + const notification = useNotification(); const handleMenu = async (e) => { e.domEvent.stopPropagation(); diff --git a/client/src/components/schedule-job-modal/schedule-job-modal.container.jsx b/client/src/components/schedule-job-modal/schedule-job-modal.container.jsx index eac29d274..9508de845 100644 --- a/client/src/components/schedule-job-modal/schedule-job-modal.container.jsx +++ b/client/src/components/schedule-job-modal/schedule-job-modal.container.jsx @@ -1,5 +1,5 @@ import { useMutation, useQuery } from "@apollo/client"; -import { Form, Modal, notification } from "antd"; +import { Form, Modal } from "antd"; import dayjs from "../../utils/day"; import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -21,6 +21,7 @@ import AuditTrailMapping from "../../utils/AuditTrailMappings"; import { DateTimeFormat } from "../../utils/DateFormatter"; import { TemplateList } from "../../utils/TemplateConstants"; import ScheduleJobModalComponent from "./schedule-job-modal.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -41,6 +42,8 @@ export function ScheduleJobModalContainer({ currentUser, insertAuditTrail }) { + const notification = useNotification(); + const { open, context, actions } = scheduleModal; const { jobId, job, previousEvent } = context; diff --git a/client/src/components/scoreboard-entry-edit/scoreboard-entry-edit.component.jsx b/client/src/components/scoreboard-entry-edit/scoreboard-entry-edit.component.jsx index 9d09dedcd..d3fc83c6f 100644 --- a/client/src/components/scoreboard-entry-edit/scoreboard-entry-edit.component.jsx +++ b/client/src/components/scoreboard-entry-edit/scoreboard-entry-edit.component.jsx @@ -1,16 +1,18 @@ import { useMutation } from "@apollo/client"; -import { Button, Card, Dropdown, Form, InputNumber, notification, Space } from "antd"; +import { Button, Card, Dropdown, Form, InputNumber, Space } from "antd"; import dayjs from "../../utils/day"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { UPDATE_SCOREBOARD_ENTRY } from "../../graphql/scoreboard.queries"; import DateTimePicker from "../form-date-time-picker/form-date-time-picker.component.jsx"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; export default function ScoreboardEntryEdit({ entry }) { const [open, setOpen] = useState(false); const [loading, setLoading] = useState(false); const { t } = useTranslation(); const [updateScoreboardentry] = useMutation(UPDATE_SCOREBOARD_ENTRY); + const notification = useNotification(); const handleFinish = async (values) => { setLoading(true); diff --git a/client/src/components/scoreboard-remove-button/scorebard-remove-button.component.jsx b/client/src/components/scoreboard-remove-button/scorebard-remove-button.component.jsx index 5aef10d17..3864ad57d 100644 --- a/client/src/components/scoreboard-remove-button/scorebard-remove-button.component.jsx +++ b/client/src/components/scoreboard-remove-button/scorebard-remove-button.component.jsx @@ -1,15 +1,18 @@ import React, { useState } from "react"; import { useTranslation } from "react-i18next"; -import { Button, notification } from "antd"; +import { Button } from "antd"; import { DeleteFilled } from "@ant-design/icons"; import { useMutation } from "@apollo/client"; import { DELETE_SCOREBOARD_ENTRY } from "../../graphql/scoreboard.queries"; import { logImEXEvent } from "../../firebase/firebase.utils"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; export default function ScoreboardRemoveButton({ scoreboardId }) { const { t } = useTranslation(); const [deleteScoreboardEntry] = useMutation(DELETE_SCOREBOARD_ENTRY); const [loading, setLoading] = useState(false); + const notification = useNotification(); + const handleDelete = async (e) => { logImEXEvent("scoreboard_remove_job"); diff --git a/client/src/components/shop-employees/shop-employees-add-vacation.component.jsx b/client/src/components/shop-employees/shop-employees-add-vacation.component.jsx index a60a91d21..87005fc5d 100644 --- a/client/src/components/shop-employees/shop-employees-add-vacation.component.jsx +++ b/client/src/components/shop-employees/shop-employees-add-vacation.component.jsx @@ -1,11 +1,12 @@ import { useMutation } from "@apollo/client"; -import { Button, Card, Form, notification, Popover, Space } from "antd"; +import { Button, Card, Form, Popover, Space } from "antd"; import dayjs from "../../utils/day"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { logImEXEvent } from "../../firebase/firebase.utils"; import { INSERT_VACATION } from "../../graphql/employees.queries"; import DateTimePicker from "../form-date-time-picker/form-date-time-picker.component.jsx"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; export default function ShopEmployeeAddVacation({ employee }) { const { t } = useTranslation(); @@ -14,6 +15,7 @@ export default function ShopEmployeeAddVacation({ employee }) { const [loading, setLoading] = useState(false); const [form] = Form.useForm(); const [visibility, setVisibility] = useState(false); + const notification = useNotification(); const handleFinish = async (values) => { logImEXEvent("employee_add_vacation"); diff --git a/client/src/components/shop-employees/shop-employees-form.component.jsx b/client/src/components/shop-employees/shop-employees-form.component.jsx index f57658350..563ad835b 100644 --- a/client/src/components/shop-employees/shop-employees-form.component.jsx +++ b/client/src/components/shop-employees/shop-employees-form.component.jsx @@ -1,6 +1,6 @@ import { DeleteFilled } from "@ant-design/icons"; import { useApolloClient, useMutation, useQuery } from "@apollo/client"; -import { Button, Card, Form, Input, InputNumber, notification, Select, Switch, Table } from "antd"; +import { Button, Card, Form, Input, InputNumber, Select, Switch, Table } from "antd"; import { useForm } from "antd/es/form/Form"; import dayjs from "../../utils/day"; import React, { useEffect } from "react"; @@ -27,6 +27,7 @@ import ShopEmployeeAddVacation from "./shop-employees-add-vacation.component"; import queryString from "query-string"; import { useSplitTreatments } from "@splitsoftware/splitio-react"; import DateTimePicker from "../form-date-time-picker/form-date-time-picker.component.jsx"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop @@ -47,6 +48,7 @@ export function ShopEmployeesFormComponent({ bodyshop }) { fetchPolicy: "network-only", nextFetchPolicy: "network-only" }); + const notification = useNotification(); const { treatments: { Enhanced_Payroll } diff --git a/client/src/components/shop-info/shop-info.container.jsx b/client/src/components/shop-info/shop-info.container.jsx index 1b3e94eab..915325ea9 100644 --- a/client/src/components/shop-info/shop-info.container.jsx +++ b/client/src/components/shop-info/shop-info.container.jsx @@ -1,5 +1,5 @@ import { useMutation, useQuery } from "@apollo/client"; -import { Form, notification } from "antd"; +import { Form } from "antd"; import dayjs from "../../utils/day"; import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -9,6 +9,7 @@ import AlertComponent from "../alert/alert.component"; import FormsFieldChanged from "../form-fields-changed-alert/form-fields-changed-alert.component"; import LoadingSpinner from "../loading-spinner/loading-spinner.component"; import ShopInfoComponent from "./shop-info.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; export default function ShopInfoContainer() { const [form] = Form.useForm(); @@ -19,6 +20,7 @@ export default function ShopInfoContainer() { fetchPolicy: "network-only", nextFetchPolicy: "network-only" }); + const notification = useNotification(); const handleFinish = (values) => { setSaveLoading(true); diff --git a/client/src/components/shop-teams/shop-employee-teams.form.component.jsx b/client/src/components/shop-teams/shop-employee-teams.form.component.jsx index dec40e45a..8194767bd 100644 --- a/client/src/components/shop-teams/shop-employee-teams.form.component.jsx +++ b/client/src/components/shop-teams/shop-employee-teams.form.component.jsx @@ -1,6 +1,6 @@ import { DeleteFilled } from "@ant-design/icons"; import { useMutation, useQuery } from "@apollo/client"; -import { Button, Card, Form, Input, InputNumber, notification, Space, Switch } from "antd"; +import { Button, Card, Form, Input, InputNumber, Space, Switch } from "antd"; import querystring from "query-string"; import React, { useEffect } from "react"; @@ -21,6 +21,7 @@ import { UPDATE_EMPLOYEE_TEAM } from "../../graphql/employee_teams.queries"; import EmployeeSearchSelectComponent from "../employee-search-select/employee-search-select.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop @@ -34,6 +35,7 @@ export function ShopEmployeeTeamsFormComponent({ bodyshop }) { const [form] = Form.useForm(); const history = useNavigate(); const search = querystring.parse(useLocation().search); + const notification = useNotification(); const { error, data } = useQuery(QUERY_EMPLOYEE_TEAM_BY_ID, { variables: { id: search.employeeTeamId }, diff --git a/client/src/components/shop-template-delete/shop-template-delete.component.jsx b/client/src/components/shop-template-delete/shop-template-delete.component.jsx index 68932d275..b40715c25 100644 --- a/client/src/components/shop-template-delete/shop-template-delete.component.jsx +++ b/client/src/components/shop-template-delete/shop-template-delete.component.jsx @@ -1,17 +1,19 @@ import { useMutation } from "@apollo/client"; -import { Button, notification, Popconfirm } from "antd"; +import { Button, Popconfirm } from "antd"; import queryString from "query-string"; import React from "react"; import { useTranslation } from "react-i18next"; import { useLocation, useNavigate } from "react-router-dom"; import { DELETE_TEMPLATE } from "../../graphql/templates.queries"; import { logImEXEvent } from "../../firebase/firebase.utils"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; export default function ShopTemplateDeleteComponent({ templateId, refetch }) { const { t } = useTranslation(); const search = queryString.parse(useLocation().search); const history = useNavigate(); const [deleteTemplate] = useMutation(DELETE_TEMPLATE); + const notification = useNotification(); const handleDelete = async () => { logImEXEvent("shop_template_delete"); diff --git a/client/src/components/shop-template-editor-save-button/shop-template-editor-save-button.component.jsx b/client/src/components/shop-template-editor-save-button/shop-template-editor-save-button.component.jsx index 5037eed5c..cea0965e6 100644 --- a/client/src/components/shop-template-editor-save-button/shop-template-editor-save-button.component.jsx +++ b/client/src/components/shop-template-editor-save-button/shop-template-editor-save-button.component.jsx @@ -1,15 +1,17 @@ import React, { useState } from "react"; -import { Button, notification } from "antd"; +import { Button } from "antd"; import { useMutation } from "@apollo/client"; import { useTranslation } from "react-i18next"; import { UPDATE_TEMPLATE } from "../../graphql/templates.queries"; import { logImEXEvent } from "../../firebase/firebase.utils"; import axios from "axios"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; export default function ShopTemplateSaveButton({ templateId, gql, emailEditorRef }) { const { t } = useTranslation(); const [loading, setLoading] = useState(false); const [updateTemplate] = useMutation(UPDATE_TEMPLATE); + const notification = useNotification(); const handleSave = async () => { logImEXEvent("shop_template_update"); diff --git a/client/src/components/shop-users-auth-edit/shop-users-auth-edit.component.jsx b/client/src/components/shop-users-auth-edit/shop-users-auth-edit.component.jsx index 065555fb8..3fe7adda5 100644 --- a/client/src/components/shop-users-auth-edit/shop-users-auth-edit.component.jsx +++ b/client/src/components/shop-users-auth-edit/shop-users-auth-edit.component.jsx @@ -1,14 +1,16 @@ -import { InputNumber, notification } from "antd"; +import { InputNumber } from "antd"; import React, { useState } from "react"; import { useMutation } from "@apollo/client"; import { useTranslation } from "react-i18next"; import { UPDATE_ASSOCIATION } from "../../graphql/user.queries"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; export default function ShopUsersAuthEdit({ association }) { const { t } = useTranslation(); const [updateAssociation] = useMutation(UPDATE_ASSOCIATION); const [open, setOpen] = useState(false); const [value, setValue] = useState(association.authlevel); + const notification = useNotification(); const handleSave = async () => { setOpen(false); diff --git a/client/src/components/task-list/task-list.container.jsx b/client/src/components/task-list/task-list.container.jsx index 1c01d381d..bcf81b9ce 100644 --- a/client/src/components/task-list/task-list.container.jsx +++ b/client/src/components/task-list/task-list.container.jsx @@ -6,7 +6,6 @@ import { pageLimit } from "../../utils/config.js"; import AlertComponent from "../alert/alert.component.jsx"; import React from "react"; import TaskListComponent from "./task-list.component.jsx"; -import { notification } from "antd"; import { useTranslation } from "react-i18next"; import { connect, useDispatch } from "react-redux"; import { insertAuditTrail } from "../../redux/application/application.actions.js"; @@ -14,6 +13,7 @@ import AuditTrailMapping from "../../utils/AuditTrailMappings.js"; import { createStructuredSelector } from "reselect"; import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors.js"; import dayjs from "../../utils/day"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -37,6 +37,7 @@ export function TaskListContainer({ disableJobRefetch = false }) { const { t } = useTranslation(); + const notification = useNotification(); const searchParams = queryString.parse(useLocation().search); const { page, diff --git a/client/src/components/task-upsert-modal/task-upsert-modal.container.jsx b/client/src/components/task-upsert-modal/task-upsert-modal.container.jsx index b2d139ec1..6fa023352 100644 --- a/client/src/components/task-upsert-modal/task-upsert-modal.container.jsx +++ b/client/src/components/task-upsert-modal/task-upsert-modal.container.jsx @@ -1,5 +1,5 @@ import { useMutation, useQuery } from "@apollo/client"; -import { Form, Modal, notification } from "antd"; +import { Form, Modal } from "antd"; import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; @@ -16,6 +16,7 @@ import { insertAuditTrail } from "../../redux/application/application.actions.js import AuditTrailMapping from "../../utils/AuditTrailMappings.js"; import { isEqual } from "lodash"; import refetchRouteMappings from "./task-upsert-modal.route.mappings"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ currentUser: selectCurrentUser, @@ -41,6 +42,7 @@ export function TaskUpsertModalContainer({ bodyshop, currentUser, taskUpsert, to const [jobIdState, setJobIdState] = useState(null); const [isTouched, setIsTouched] = useState(false); const location = useLocation(); + const notification = useNotification(); const { loading, error, data } = useQuery(QUERY_GET_TASKS_JOB_DETAILS_BY_ID, { variables: { id: jobIdState }, diff --git a/client/src/components/tech-job-clock-in-form/tech-job-clock-in-form.container.jsx b/client/src/components/tech-job-clock-in-form/tech-job-clock-in-form.container.jsx index 978cdf5cf..3dd5d88b2 100644 --- a/client/src/components/tech-job-clock-in-form/tech-job-clock-in-form.container.jsx +++ b/client/src/components/tech-job-clock-in-form/tech-job-clock-in-form.container.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { Button, Card, Form, notification, Space } from "antd"; +import { Button, Card, Form, Space } from "antd"; import axios from "axios"; import dayjs from "../../utils/day"; import React, { useState } from "react"; @@ -13,6 +13,7 @@ import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selecto import TechJobPrintTickets from "../tech-job-print-tickets/tech-job-print-tickets.component"; import TechClockInComponent from "./tech-job-clock-in-form.component"; import { useSplitTreatments } from "@splitsoftware/splitio-react"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ technician: selectTechnician, @@ -38,6 +39,7 @@ export function TechClockInContainer({ setTimeTicketContext, technician, bodysho refetchQueries: ["QUERY_ACTIVE_TIME_TICKETS"] }); const { t } = useTranslation(); + const notification = useNotification(); const emps = bodyshop.employees.filter((e) => e.id === (technician && technician.id))[0]; diff --git a/client/src/components/tech-job-clock-out-button/tech-job-clock-out-button.component.jsx b/client/src/components/tech-job-clock-out-button/tech-job-clock-out-button.component.jsx index abc6488ac..4e2dbbecd 100644 --- a/client/src/components/tech-job-clock-out-button/tech-job-clock-out-button.component.jsx +++ b/client/src/components/tech-job-clock-out-button/tech-job-clock-out-button.component.jsx @@ -1,5 +1,5 @@ import { useMutation, useQuery } from "@apollo/client"; -import { Button, Card, Col, Form, InputNumber, notification, Popover, Row, Select } from "antd"; +import { Button, Card, Col, Form, InputNumber, Popover, Row, Select } from "antd"; import axios from "axios"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; @@ -15,6 +15,7 @@ import { CalculateAllocationsTotals } from "../labor-allocations-table/labor-all import TechJobClockoutDelete from "../tech-job-clock-out-delete/tech-job-clock-out-delete.component"; import { LaborAllocationContainer } from "../time-ticket-modal/time-ticket-modal.component"; import { useSplitTreatments } from "@splitsoftware/splitio-react"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -33,6 +34,7 @@ export function TechClockOffButton({ const [loading, setLoading] = useState(false); const [updateTimeticket] = useMutation(UPDATE_TIME_TICKET); const [updateJobStatus] = useMutation(UPDATE_JOB_STATUS); + const notification = useNotification(); const [form] = Form.useForm(); const { treatments: { Enhanced_Payroll } diff --git a/client/src/components/tech-job-clock-out-delete/tech-job-clock-out-delete.component.jsx b/client/src/components/tech-job-clock-out-delete/tech-job-clock-out-delete.component.jsx index b0c33eb6b..03fb01fb2 100644 --- a/client/src/components/tech-job-clock-out-delete/tech-job-clock-out-delete.component.jsx +++ b/client/src/components/tech-job-clock-out-delete/tech-job-clock-out-delete.component.jsx @@ -1,14 +1,17 @@ import React from "react"; -import { notification, Popconfirm } from "antd"; +import { Popconfirm } from "antd"; import { DeleteFilled } from "@ant-design/icons"; import { DELETE_TIME_TICKET } from "../../graphql/timetickets.queries"; import { useTranslation } from "react-i18next"; import { useMutation } from "@apollo/client"; import { logImEXEvent } from "../../firebase/firebase.utils"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; export default function TechJobClockoutDelete({ timeTicketId, completedCallback }) { const [deleteTimeTicket] = useMutation(DELETE_TIME_TICKET); const { t } = useTranslation(); + const notification = useNotification(); + const handleDelete = async () => { logImEXEvent("tech_clock_delete"); diff --git a/client/src/components/tech-job-print-tickets/tech-job-print-tickets.component.jsx b/client/src/components/tech-job-print-tickets/tech-job-print-tickets.component.jsx index 3f060089f..a01fd7420 100644 --- a/client/src/components/tech-job-print-tickets/tech-job-print-tickets.component.jsx +++ b/client/src/components/tech-job-print-tickets/tech-job-print-tickets.component.jsx @@ -9,6 +9,7 @@ import DatePIckerRanges from "../../utils/DatePickerRanges"; import dayjs from "../../utils/day"; import { GenerateDocument } from "../../utils/RenderTemplate"; import { TemplateList } from "../../utils/TemplateConstants"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectTechnician, @@ -26,6 +27,7 @@ export function TechJobPrintTickets({ bodyshop, technician, event, attendacePrin const [form] = Form.useForm(); const [visibility, setVisibility] = useState(false); const Templates = TemplateList("report_center"); + const notification = useNotification(); useEffect(() => { if (visibility && event) { @@ -59,7 +61,8 @@ export function TechJobPrintTickets({ bodyshop, technician, event, attendacePrin attendacePrint === true ? Templates.attendance_employee.subject : Templates.timetickets_employee.subject }, values.sendby, - bodyshop + bodyshop, + notification ); } catch (error) { console.log(error); diff --git a/client/src/components/time-ticket-modal/time-ticket-modal.container.jsx b/client/src/components/time-ticket-modal/time-ticket-modal.container.jsx index b4ef464f2..5e0393e10 100644 --- a/client/src/components/time-ticket-modal/time-ticket-modal.container.jsx +++ b/client/src/components/time-ticket-modal/time-ticket-modal.container.jsx @@ -1,7 +1,7 @@ import { PageHeader } from "@ant-design/pro-layout"; import { useMutation, useQuery } from "@apollo/client"; import { useSplitTreatments } from "@splitsoftware/splitio-react"; -import { Button, Form, Modal, notification, Space } from "antd"; +import { Button, Form, Modal, Space } from "antd"; import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; @@ -14,6 +14,7 @@ import { selectBodyshop } from "../../redux/user/user.selectors"; import dayjs from "../../utils/day"; import TimeTicketsCommitToggleComponent from "../time-tickets-commit-toggle/time-tickets-commit-toggle.component"; import TimeTicketModalComponent from "./time-ticket-modal.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ timeTicketModal: selectTimeTicket, @@ -37,6 +38,7 @@ export function TimeTicketModalContainer({ timeTicketModal, toggleModalVisible, names: ["Enhanced_Payroll"], splitKey: bodyshop.imexshopid }); + const notification = useNotification(); const { data: EmployeeAutoCompleteData } = useQuery(QUERY_ACTIVE_EMPLOYEES, { skip: !timeTicketModal.open, diff --git a/client/src/components/time-ticket-shift-form/time-ticket-shift-form.container.jsx b/client/src/components/time-ticket-shift-form/time-ticket-shift-form.container.jsx index 937ff3e1a..5edbeb1de 100644 --- a/client/src/components/time-ticket-shift-form/time-ticket-shift-form.container.jsx +++ b/client/src/components/time-ticket-shift-form/time-ticket-shift-form.container.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { Button, Form, notification, Space } from "antd"; +import { Button, Form, Space } from "antd"; import axios from "axios"; import dayjs from "../../utils/day"; import React, { useMemo, useState } from "react"; @@ -11,6 +11,7 @@ import { selectTechnician } from "../../redux/tech/tech.selectors"; import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors"; import TechJobPrintTickets from "../tech-job-print-tickets/tech-job-print-tickets.component"; import TimeTicektShiftComponent from "./time-ticket-shift-form.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ currentUser: selectCurrentUser, @@ -27,6 +28,7 @@ export function TimeTicektShiftContainer({ bodyshop, technician, currentUser, is const [insertTimeTicket] = useMutation(INSERT_NEW_TIME_TICKET); const { t } = useTranslation(); const [loading, setLoading] = useState(false); + const notification = useNotification(); const employeeId = useMemo(() => { const assoc = bodyshop.associations.filter((a) => a.useremail === currentUser.email)[0]; diff --git a/client/src/components/time-ticket-task-modal/time-ticket-task-modal.container.jsx b/client/src/components/time-ticket-task-modal/time-ticket-task-modal.container.jsx index 724482f45..9f809c3a7 100644 --- a/client/src/components/time-ticket-task-modal/time-ticket-task-modal.container.jsx +++ b/client/src/components/time-ticket-task-modal/time-ticket-task-modal.container.jsx @@ -1,6 +1,6 @@ import React, { useCallback, useEffect, useState } from "react"; -import { Form, Modal, notification } from "antd"; +import { Form, Modal } from "antd"; import axios from "axios"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; @@ -13,6 +13,7 @@ import { useApolloClient } from "@apollo/client"; import { QUERY_COMPLETED_TASKS } from "../../graphql/jobs.queries"; import "./time-ticket-task-modal.styles.scss"; import { selectTechnician } from "../../redux/tech/tech.selectors"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ timeTicketTasksModal: selectTimeTicketTasks, @@ -39,6 +40,7 @@ export function TimeTickeTaskModalContainer({ const { t } = useTranslation(); const [loading, setLoading] = useState(false); const client = useApolloClient(); + const notification = useNotification(); async function handleFinish(values) { calculateTickets({ values, handleFinish: true }); diff --git a/client/src/components/time-tickets-attendance-table/time-tickets-attendance-table.component.jsx b/client/src/components/time-tickets-attendance-table/time-tickets-attendance-table.component.jsx index 90e894873..eeb40c155 100644 --- a/client/src/components/time-tickets-attendance-table/time-tickets-attendance-table.component.jsx +++ b/client/src/components/time-tickets-attendance-table/time-tickets-attendance-table.component.jsx @@ -6,6 +6,7 @@ import { GenerateDocument } from "../../utils/RenderTemplate"; import { TemplateList } from "../../utils/TemplateConstants"; import { useTranslation } from "react-i18next"; import dayjs from "../../utils/day"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const AttendanceCsv = TemplateList("special").attendance_detail_csv; @@ -14,6 +15,7 @@ export default function TimeTicketsAttendanceTable() { const { start, end } = searchParams; const { t } = useTranslation(); const [loading, setLoading] = useState(false); + const notification = useNotification(); const handleClick = async () => { setLoading(true); @@ -27,7 +29,9 @@ export default function TimeTicketsAttendanceTable() { } }, {}, - "text" + "text", + null, + notification ); setLoading(false); diff --git a/client/src/components/time-tickets-commit-toggle/time-tickets-commit-toggle.component.jsx b/client/src/components/time-tickets-commit-toggle/time-tickets-commit-toggle.component.jsx index 07aa3234d..0cb5741f1 100644 --- a/client/src/components/time-tickets-commit-toggle/time-tickets-commit-toggle.component.jsx +++ b/client/src/components/time-tickets-commit-toggle/time-tickets-commit-toggle.component.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { Button, notification } from "antd"; +import { Button } from "antd"; import dayjs from "../../utils/day"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; @@ -8,6 +8,7 @@ import { createStructuredSelector } from "reselect"; import { UPDATE_TIME_TICKET } from "../../graphql/timetickets.queries"; import { setModalContext } from "../../redux/modals/modals.actions"; import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -20,6 +21,7 @@ const mapDispatchToProps = (dispatch) => ({ export function TimeTicketsCommit({ bodyshop, currentUser, timeticket, disabled, refetch, setTimeTicketContext }) { const { t } = useTranslation(); const [updateTimeTicket] = useMutation(UPDATE_TIME_TICKET); + const notification = useNotification(); const [loading, setLoading] = useState(false); const handleCommit = async () => { diff --git a/client/src/components/time-tickets-commit/time-tickets-commit.component.jsx b/client/src/components/time-tickets-commit/time-tickets-commit.component.jsx index c817afd2e..82cbbb99e 100644 --- a/client/src/components/time-tickets-commit/time-tickets-commit.component.jsx +++ b/client/src/components/time-tickets-commit/time-tickets-commit.component.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { Button, notification } from "antd"; +import { Button } from "antd"; import dayjs from "../../utils/day"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; @@ -7,6 +7,7 @@ import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import { UPDATE_TIME_TICKETS } from "../../graphql/timetickets.queries"; import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -24,6 +25,7 @@ export function TimeTicketsCommit({ }) { const { t } = useTranslation(); const [updateTimeTickets] = useMutation(UPDATE_TIME_TICKETS); + const notification = useNotification(); const [loading, setLoading] = useState(false); const handleCommit = async () => { diff --git a/client/src/components/time-tickets-payroll-table/time-tickets-payroll-table.component.jsx b/client/src/components/time-tickets-payroll-table/time-tickets-payroll-table.component.jsx index 4fb24f399..0c8d44eca 100644 --- a/client/src/components/time-tickets-payroll-table/time-tickets-payroll-table.component.jsx +++ b/client/src/components/time-tickets-payroll-table/time-tickets-payroll-table.component.jsx @@ -6,6 +6,7 @@ import { GenerateDocument } from "../../utils/RenderTemplate"; import { TemplateList } from "../../utils/TemplateConstants"; import { useTranslation } from "react-i18next"; import dayjs from "../../utils/day"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const PayrollTemplate = TemplateList("special").exported_payroll; export default function TimeTicketsPayrollTable() { @@ -13,6 +14,7 @@ export default function TimeTicketsPayrollTable() { const { start, end } = searchParams; const { t } = useTranslation(); const [loading, setLoading] = useState(false); + const notification = useNotification(); const handleClick = async () => { setLoading(true); @@ -26,7 +28,9 @@ export default function TimeTicketsPayrollTable() { } }, {}, - "x" + "x", + null, + notification ); setLoading(false); diff --git a/client/src/components/tt-approve-button/tt-approve-button.component.jsx b/client/src/components/tt-approve-button/tt-approve-button.component.jsx index 48daee263..6028a8ca7 100644 --- a/client/src/components/tt-approve-button/tt-approve-button.component.jsx +++ b/client/src/components/tt-approve-button/tt-approve-button.component.jsx @@ -1,5 +1,5 @@ import { useApolloClient } from "@apollo/client"; -import { Button, notification } from "antd"; +import { Button } from "antd"; import _ from "lodash"; import dayjs from "../../utils/day"; import React, { useState } from "react"; @@ -10,6 +10,7 @@ import { INSERT_TIME_TICKET_AND_APPROVE } from "../../graphql/timetickets.querie import { QUERY_TT_APPROVALS_BY_IDS } from "../../graphql/tt-approvals.queries"; import { selectAuthLevel, selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors"; import { HasRbacAccess } from "../rbac-wrapper/rbac-wrapper.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -29,6 +30,7 @@ export function TtApproveButton({ }) { const { t } = useTranslation(); const client = useApolloClient(); + const notification = useNotification(); const [loading, setLoading] = useState(false); diff --git a/client/src/components/update-alert/update-alert.component.jsx b/client/src/components/update-alert/update-alert.component.jsx index 1f525a479..22b290a5c 100644 --- a/client/src/components/update-alert/update-alert.component.jsx +++ b/client/src/components/update-alert/update-alert.component.jsx @@ -1,5 +1,5 @@ import { AlertOutlined } from "@ant-design/icons"; -import { Alert, Button, Col, notification, Row, Space } from "antd"; +import { Alert, Button, Col, Row, Space } from "antd"; import i18n from "i18next"; import React, { useCallback, useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -9,6 +9,7 @@ import { selectUpdateAvailable } from "../../redux/application/application.selec import { useRegisterSW } from "virtual:pwa-register/react"; import InstanceRenderManager from "../../utils/instanceRenderMgr"; import useCountDown from "../../utils/countdownHook"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ updateAvailable: selectUpdateAvailable @@ -22,6 +23,8 @@ export function UpdateAlert({ updateAvailable }) { const { t } = useTranslation(); const [timerStarted, setTimerStarted] = useState(false); const [loading, setLoading] = useState(false); + const notification = useNotification(); + const [ timeLeft, { @@ -85,7 +88,7 @@ export function UpdateAlert({ updateAvailable }) { if (needRefresh && timerStarted && timeLeft <= 0) { ReloadNewVersion(); } - }, [timeLeft, t, needRefresh, ReloadNewVersion, timerStarted]); + }, [timeLeft, t, needRefresh, ReloadNewVersion, timerStarted, notification]); if (!needRefresh) return null; diff --git a/client/src/components/vehicle-detail-form/vehicle-detail-form.container.jsx b/client/src/components/vehicle-detail-form/vehicle-detail-form.container.jsx index 08d9a256e..c4530c4fc 100644 --- a/client/src/components/vehicle-detail-form/vehicle-detail-form.container.jsx +++ b/client/src/components/vehicle-detail-form/vehicle-detail-form.container.jsx @@ -1,5 +1,5 @@ import React, { useState } from "react"; -import { Button, Form, notification, Popconfirm } from "antd"; +import { Button, Form, Popconfirm } from "antd"; import { PageHeader } from "@ant-design/pro-layout"; import { useMutation } from "@apollo/client"; import VehicleDetailFormComponent from "./vehicle-detail-form.component"; @@ -7,6 +7,7 @@ import { useTranslation } from "react-i18next"; import dayjs from "../../utils/day"; import { DELETE_VEHICLE, UPDATE_VEHICLE } from "../../graphql/vehicles.queries"; import { useNavigate } from "react-router-dom"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; function VehicleDetailFormContainer({ vehicle, refetch }) { const { t } = useTranslation(); @@ -15,6 +16,7 @@ function VehicleDetailFormContainer({ vehicle, refetch }) { const [form] = Form.useForm(); const [loading, setLoading] = useState(false); const history = useNavigate(); + const notification = useNotification(); const handleDelete = async () => { setLoading(true); diff --git a/client/src/components/vehicle-detail-update-jobs/vehicle-detail-update-jobs.component.jsx b/client/src/components/vehicle-detail-update-jobs/vehicle-detail-update-jobs.component.jsx index d2aa52d6e..55f67e240 100644 --- a/client/src/components/vehicle-detail-update-jobs/vehicle-detail-update-jobs.component.jsx +++ b/client/src/components/vehicle-detail-update-jobs/vehicle-detail-update-jobs.component.jsx @@ -1,13 +1,16 @@ import React from "react"; -import { Button, notification } from "antd"; +import { Button } from "antd"; import { useTranslation } from "react-i18next"; import { useMutation } from "@apollo/client"; import { UPDATE_JOBS } from "../../graphql/jobs.queries"; import { logImEXEvent } from "../../firebase/firebase.utils"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; export default function VehicleDetailUpdateJobsComponent({ vehicle, selectedJobs, disabled }) { const { t } = useTranslation(); const [updateJobs] = useMutation(UPDATE_JOBS); + const notification = useNotification(); + const handlecClick = (e) => { logImEXEvent("vehicle_update_jobs"); diff --git a/client/src/components/vendors-form/vendors-form.container.jsx b/client/src/components/vendors-form/vendors-form.container.jsx index 775117903..faeb8d75c 100644 --- a/client/src/components/vendors-form/vendors-form.container.jsx +++ b/client/src/components/vendors-form/vendors-form.container.jsx @@ -1,5 +1,5 @@ import { useMutation, useQuery } from "@apollo/client"; -import { Form, notification } from "antd"; +import { Form } from "antd"; import queryString from "query-string"; import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -11,6 +11,7 @@ import { selectBodyshop } from "../../redux/user/user.selectors"; import AlertComponent from "../alert/alert.component"; import LoadingSpinner from "../loading-spinner/loading-spinner.component"; import VendorsFormComponent from "./vendors-form.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop @@ -29,6 +30,7 @@ function VendorsFormContainer({ refetch, bodyshop }) { nextFetchPolicy: "network-only", skip: !!!selectedvendor || selectedvendor === "new" }); + const notification = useNotification(); const [updateVendor] = useMutation(UPDATE_VENDOR); const [insertvendor] = useMutation(INSERT_NEW_VENDOR); diff --git a/client/src/components/vendors-phonebook-add/vendors-phonebook-add.component.jsx b/client/src/components/vendors-phonebook-add/vendors-phonebook-add.component.jsx index 82ead8fff..0f3d0db66 100644 --- a/client/src/components/vendors-phonebook-add/vendors-phonebook-add.component.jsx +++ b/client/src/components/vendors-phonebook-add/vendors-phonebook-add.component.jsx @@ -1,4 +1,4 @@ -import { Button, notification } from "antd"; +import { Button } from "antd"; import React, { useState } from "react"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; @@ -6,6 +6,7 @@ import { selectBodyshop } from "../../redux/user/user.selectors"; import { useTranslation } from "react-i18next"; import { useMutation } from "@apollo/client"; import { INSERT_NEW_PHONEBOOK } from "../../graphql/phonebook.queries"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop @@ -19,6 +20,7 @@ export function VendorsPhonebookAdd({ form, bodyshop, disabled }) { const [loading, setLoading] = useState(false); const [insertPhonebook] = useMutation(INSERT_NEW_PHONEBOOK); const { t } = useTranslation(); + const notification = useNotification(); const handleAdd = async () => { setLoading(true); diff --git a/client/src/contexts/Notifications/notificationContext.jsx b/client/src/contexts/Notifications/notificationContext.jsx new file mode 100644 index 000000000..59bcdf4fe --- /dev/null +++ b/client/src/contexts/Notifications/notificationContext.jsx @@ -0,0 +1,34 @@ +// NotificationProvider.jsx +import React, { createContext, useContext } from "react"; +import { notification } from "antd"; + +/** + * Create our NotificationContext to store the `api` object + * returned by notification.useNotification(). + */ +const NotificationContext = createContext(null); + +/** + * A custom hook to make usage easier in child components. + */ +export const useNotification = () => { + return useContext(NotificationContext); +}; + +/** + * The Provider itself: + * - Call notification.useNotification() to get [api, contextHolder]. + * - Render contextHolder somewhere high-level in your app (so the notifications mount properly). + * - Provide `api` via the NotificationContext. + */ +export const NotificationProvider = ({ children }) => { + const [api, contextHolder] = notification.useNotification(); + + return ( + + {/* contextHolder must be rendered in the DOM so notifications can appear */} + {contextHolder} + {children} + + ); +}; diff --git a/client/src/pages/contract-create/contract-create.page.container.jsx b/client/src/pages/contract-create/contract-create.page.container.jsx index c2ab7358e..bdbe8a057 100644 --- a/client/src/pages/contract-create/contract-create.page.container.jsx +++ b/client/src/pages/contract-create/contract-create.page.container.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { Card, Form, notification } from "antd"; +import { Card, Form } from "antd"; import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; @@ -14,6 +14,7 @@ import { selectBodyshop } from "../../redux/user/user.selectors"; import InstanceRenderManager from "../../utils/instanceRenderMgr"; import ContractCreatePageComponent from "./contract-create.page.component"; import UpsellComponent, { upsellEnum } from "../../components/upsell/upsell.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop @@ -35,6 +36,7 @@ export function ContractCreatePageContainer({ bodyshop, setBreadcrumbs, setSelec const [insertContract] = useMutation(INSERT_NEW_CONTRACT); const [intakeJob] = useMutation(UPDATE_JOB); + const notification = useNotification(); const handleFinish = async ({ addtoproduction, ...values }) => { if (!!selectedCarState[0] && !!selectedJobState[0]) { diff --git a/client/src/pages/contract-detail/contract-detail.page.component.jsx b/client/src/pages/contract-detail/contract-detail.page.component.jsx index e170548ea..d24f12110 100644 --- a/client/src/pages/contract-detail/contract-detail.page.component.jsx +++ b/client/src/pages/contract-detail/contract-detail.page.component.jsx @@ -11,6 +11,7 @@ import ContractJobBlock from "../../components/contract-job-block/contract-job-b import { setModalContext } from "../../redux/modals/modals.actions"; import { GenerateDocument } from "../../utils/RenderTemplate"; import { TemplateList } from "../../utils/TemplateConstants"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapDispatchToProps = (dispatch) => ({ setCourtesyCarReturnModalContext: (context) => @@ -27,6 +28,8 @@ export function ContractDetailPage({ saveLoading }) { const { t } = useTranslation(); + const notification = useNotification(); + return (
    @@ -48,7 +51,9 @@ export function ContractDetailPage({ variables: { id: contract.id } }, {}, - "p" + "p", + null, + notification ); }, items: [ diff --git a/client/src/pages/contract-detail/contract-detail.page.container.jsx b/client/src/pages/contract-detail/contract-detail.page.container.jsx index 911acde91..968d5ba2f 100644 --- a/client/src/pages/contract-detail/contract-detail.page.container.jsx +++ b/client/src/pages/contract-detail/contract-detail.page.container.jsx @@ -1,5 +1,5 @@ import { useMutation, useQuery } from "@apollo/client"; -import { Card, Form, notification } from "antd"; +import { Card, Form } from "antd"; import dayjs from "../../utils/day"; import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -17,6 +17,7 @@ import NotFound from "../../components/not-found/not-found.component"; import FeatureWrapperComponent from "../../components/feature-wrapper/feature-wrapper.component"; import InstanceRenderManager from "../../utils/instanceRenderMgr"; import UpsellComponent, { upsellEnum } from "../../components/upsell/upsell.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapDispatchToProps = (dispatch) => ({ setBreadcrumbs: (breadcrumbs) => dispatch(setBreadcrumbs(breadcrumbs)), @@ -30,6 +31,7 @@ export function ContractDetailPageContainer({ setBreadcrumbs, addRecentItem, set const [saveLoading, setsaveLoading] = useState(false); const [form] = Form.useForm(); const { contractId } = useParams(); + const notification = useNotification(); const { loading, error, data, refetch } = useQuery(QUERY_CONTRACT_BY_PK, { variables: { id: contractId }, diff --git a/client/src/pages/courtesy-car-create/courtesy-car-create.page.container.jsx b/client/src/pages/courtesy-car-create/courtesy-car-create.page.container.jsx index 451a32ea9..09f6f81e2 100644 --- a/client/src/pages/courtesy-car-create/courtesy-car-create.page.container.jsx +++ b/client/src/pages/courtesy-car-create/courtesy-car-create.page.container.jsx @@ -1,5 +1,5 @@ import { useMutation } from "@apollo/client"; -import { Card, Form, notification } from "antd"; +import { Card, Form } from "antd"; import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; @@ -13,6 +13,7 @@ import { selectBodyshop } from "../../redux/user/user.selectors"; import FeatureWrapperComponent from "../../components/feature-wrapper/feature-wrapper.component"; import InstanceRenderManager from "../../utils/instanceRenderMgr"; import UpsellComponent, { upsellEnum } from "../../components/upsell/upsell.component"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop @@ -28,6 +29,7 @@ export function CourtesyCarCreateContainer({ bodyshop, setBreadcrumbs, setSelect const [insertCourtesyCar] = useMutation(INSERT_NEW_COURTESY_CAR); const { t } = useTranslation(); const history = useNavigate(); + const notification = useNotification(); const handleFinish = async (values) => { setLoading(true); diff --git a/client/src/pages/courtesy-car-detail/courtesy-car-detail.page.container.jsx b/client/src/pages/courtesy-car-detail/courtesy-car-detail.page.container.jsx index 5fd1dc4b0..4d016c6fc 100644 --- a/client/src/pages/courtesy-car-detail/courtesy-car-detail.page.container.jsx +++ b/client/src/pages/courtesy-car-detail/courtesy-car-detail.page.container.jsx @@ -1,5 +1,5 @@ import { useMutation, useQuery } from "@apollo/client"; -import { Form, notification } from "antd"; +import { Form } from "antd"; import dayjs from "../../utils/day"; import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -17,6 +17,7 @@ import LoadingSpinner from "../../components/loading-spinner/loading-spinner.com import queryString from "query-string"; import { pageLimit } from "../../utils/config"; import InstanceRenderManager from "../../utils/instanceRenderMgr"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapDispatchToProps = (dispatch) => ({ setBreadcrumbs: (breadcrumbs) => dispatch(setBreadcrumbs(breadcrumbs)), @@ -27,6 +28,7 @@ const mapDispatchToProps = (dispatch) => ({ export function CourtesyCarDetailPageContainer({ setBreadcrumbs, addRecentItem, setSelectedHeader }) { const searchParams = queryString.parse(useLocation().search); const { page, sortcolumn, sortorder } = searchParams; + const notification = useNotification(); const { t } = useTranslation(); const [updateCourtesyCar] = useMutation(UPDATE_CC); diff --git a/client/src/pages/dms-payables/dms-payables.container.jsx b/client/src/pages/dms-payables/dms-payables.container.jsx index 21fd0f19e..e7c6c59fa 100644 --- a/client/src/pages/dms-payables/dms-payables.container.jsx +++ b/client/src/pages/dms-payables/dms-payables.container.jsx @@ -1,4 +1,4 @@ -import { Button, Card, Col, notification, Row, Select, Space } from "antd"; +import { Button, Card, Col, Row, Select, Space } from "antd"; import React, { useEffect, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; @@ -11,6 +11,7 @@ import { auth } from "../../firebase/firebase.utils"; import { setBreadcrumbs, setSelectedHeader } from "../../redux/application/application.actions"; import { selectBodyshop } from "../../redux/user/user.selectors"; import InstanceRenderManager from "../../utils/instanceRenderMgr"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop @@ -37,6 +38,7 @@ export function DmsContainer({ bodyshop, setBreadcrumbs, setSelectedHeader }) { const [logLevel, setLogLevel] = useState("DEBUG"); const history = useNavigate(); const [logs, setLogs] = useState([]); + const notification = useNotification(); const { state } = useLocation(); diff --git a/client/src/pages/dms/dms.container.jsx b/client/src/pages/dms/dms.container.jsx index 3b9fe6e42..209ab2f9c 100644 --- a/client/src/pages/dms/dms.container.jsx +++ b/client/src/pages/dms/dms.container.jsx @@ -1,5 +1,5 @@ import { useQuery } from "@apollo/client"; -import { Button, Card, Col, notification, Result, Row, Select, Space } from "antd"; +import { Button, Card, Col, Result, Row, Select, Space } from "antd"; import queryString from "query-string"; import React, { useEffect, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -20,6 +20,7 @@ import { insertAuditTrail, setBreadcrumbs, setSelectedHeader } from "../../redux import { selectBodyshop } from "../../redux/user/user.selectors"; import InstanceRenderManager from "../../utils/instanceRenderMgr"; import AuditTrailMapping from "../../utils/AuditTrailMappings"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop @@ -52,6 +53,7 @@ export function DmsContainer({ bodyshop, setBreadcrumbs, setSelectedHeader, inse const [logs, setLogs] = useState([]); const search = queryString.parse(useLocation().search); const { jobId } = search; + const notification = useNotification(); const { loading, error, data } = useQuery(QUERY_JOB_EXPORT_DMS, { variables: { id: jobId }, diff --git a/client/src/pages/jobs-close/jobs-close.component.jsx b/client/src/pages/jobs-close/jobs-close.component.jsx index 2585a8254..0833ddd18 100644 --- a/client/src/pages/jobs-close/jobs-close.component.jsx +++ b/client/src/pages/jobs-close/jobs-close.component.jsx @@ -8,7 +8,6 @@ import { Form, Input, InputNumber, - notification, Popconfirm, Row, Select, @@ -42,6 +41,7 @@ import { selectJobReadOnly } from "../../redux/application/application.selectors import { selectBodyshop } from "../../redux/user/user.selectors"; import AuditTrailMapping from "../../utils/AuditTrailMappings"; import JobCloseRoGuardContainer from "../../components/job-close-ro-guard/job-close-ro-guard.container"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -59,6 +59,7 @@ export function JobsCloseComponent({ job, bodyshop, jobRO, insertAuditTrail }) { // const history = useNavigate(); const [closeJob] = useMutation(UPDATE_JOB); const [loading, setLoading] = useState(false); + const notification = useNotification(); const { treatments: { Qb_Multi_Ar, ClosingPeriod } diff --git a/client/src/pages/jobs-create/jobs-create.container.jsx b/client/src/pages/jobs-create/jobs-create.container.jsx index 9602a2f94..b12cd7823 100644 --- a/client/src/pages/jobs-create/jobs-create.container.jsx +++ b/client/src/pages/jobs-create/jobs-create.container.jsx @@ -1,5 +1,5 @@ import { useLazyQuery, useMutation } from "@apollo/client"; -import { Form, notification } from "antd"; +import { Form } from "antd"; import _ from "lodash"; import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -13,6 +13,7 @@ import { selectBodyshop } from "../../redux/user/user.selectors"; import InstanceRenderManager from "../../utils/instanceRenderMgr"; import JobsCreateComponent from "./jobs-create.component"; import JobCreateContext from "./jobs-create.context"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop @@ -24,6 +25,8 @@ const mapDispatchToProps = (dispatch) => ({ function JobsCreateContainer({ bodyshop, setBreadcrumbs, setSelectedHeader }) { const { t } = useTranslation(); + const notification = useNotification(); + const contextState = useState({ vehicle: { new: false, diff --git a/client/src/pages/jobs-detail/jobs-detail.page.component.jsx b/client/src/pages/jobs-detail/jobs-detail.page.component.jsx index eded63067..d0e83da5d 100644 --- a/client/src/pages/jobs-detail/jobs-detail.page.component.jsx +++ b/client/src/pages/jobs-detail/jobs-detail.page.component.jsx @@ -10,7 +10,7 @@ import Icon, { } from "@ant-design/icons"; import { PageHeader } from "@ant-design/pro-layout"; import { useQuery } from "@apollo/client"; -import { Badge, Button, Divider, Form, notification, Space, Tabs } from "antd"; +import { Badge, Button, Divider, Form, Space, Tabs } from "antd"; import Axios from "axios"; import _ from "lodash"; import queryString from "query-string"; @@ -55,6 +55,7 @@ import AuditTrailMapping from "../../utils/AuditTrailMappings"; import { DateTimeFormat } from "../../utils/DateFormatter"; import dayjs from "../../utils/day"; import UndefinedToNull from "../../utils/undefinedtonull"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -100,6 +101,7 @@ export function JobsDetailPage({ fetchPolicy: "network-only", nextFetchPolicy: "network-only" }); + const notification = useNotification(); useEffect(() => { //form.setFieldsValue(transormJobToForm(job)); diff --git a/client/src/pages/manage/manage.page.component.jsx b/client/src/pages/manage/manage.page.component.jsx index a76bf6e5b..5dbf95dc5 100644 --- a/client/src/pages/manage/manage.page.component.jsx +++ b/client/src/pages/manage/manage.page.component.jsx @@ -1,4 +1,5 @@ -import { FloatButton, Layout, notification, Spin } from "antd"; +import { FloatButton, Layout, Spin } from "antd"; + // import preval from "preval.macro"; import React, { lazy, Suspense, useContext, useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -27,7 +28,7 @@ import "./manage.page.styles.scss"; import WssStatusDisplayComponent from "../../components/wss-status-display/wss-status-display.component.jsx"; import { selectAlerts } from "../../redux/application/application.selectors.js"; import { addAlerts } from "../../redux/application/application.actions.js"; - +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; const JobsPage = lazy(() => import("../jobs/jobs.page")); const CardPaymentModalContainer = lazy( @@ -122,6 +123,7 @@ export function Manage({ conflict, bodyshop, alerts, setAlerts }) { const { t } = useTranslation(); const [chatVisible] = useState(false); const { socket, clientId } = useContext(SocketContext); + const notification = useNotification(); // State to track displayed alerts const [displayedAlertIds, setDisplayedAlertIds] = useState([]); @@ -177,7 +179,7 @@ export function Manage({ conflict, bodyshop, alerts, setAlerts }) { }); }); } - }, [alerts, displayedAlertIds]); + }, [alerts, displayedAlertIds, notification]); useEffect(() => { const widgetId = InstanceRenderManager({ diff --git a/client/src/utils/RenderTemplate.js b/client/src/utils/RenderTemplate.js index fd6eb6e44..a85681ae5 100644 --- a/client/src/utils/RenderTemplate.js +++ b/client/src/utils/RenderTemplate.js @@ -1,6 +1,5 @@ import { gql } from "@apollo/client"; import jsreport from "@jsreport/browser-client"; -import { notification } from "antd"; import axios from "axios"; import _ from "lodash"; import { auth } from "../firebase/firebase.utils"; @@ -11,11 +10,13 @@ import cleanAxios from "./CleanAxios"; import { TemplateList } from "./TemplateConstants"; import { generateTemplate } from "./graphQLmodifier"; import InstanceRenderManager from "./instanceRenderMgr"; + const server = import.meta.env.VITE_APP_REPORTS_SERVER_URL; jsreport.serverUrl = server; let Templates; + export function GenerateTemplates() { //Required as a part of the transition to Vite. //Previous method had the template hash generating before translations loaded, resulting in empty files. @@ -27,7 +28,8 @@ export default async function RenderTemplate( bodyshop, renderAsHtml = false, renderAsExcel = false, - renderAsText = false + renderAsText = false, + notification ) { if (window.jsr3) { jsreport.serverUrl = "https://reports3.test.imex.online/"; @@ -72,8 +74,14 @@ export default async function RenderTemplate( ...contextData, ...templateObject.variables, ...templateObject.context, - headerpath: `/${InstanceRenderManager({ imex: bodyshop.imexshopid, rome: bodyshop.imexshopid })}/header.html`, - footerpath: `/${InstanceRenderManager({ imex: bodyshop.imexshopid, rome: bodyshop.imexshopid })}/footer.html`, + headerpath: `/${InstanceRenderManager({ + imex: bodyshop.imexshopid, + rome: bodyshop.imexshopid + })}/header.html`, + footerpath: `/${InstanceRenderManager({ + imex: bodyshop.imexshopid, + rome: bodyshop.imexshopid + })}/footer.html`, bodyshop: bodyshop, filters: templateObject?.filters, sorters: templateObject?.sorters, @@ -131,7 +139,7 @@ export default async function RenderTemplate( } } -export async function RenderTemplates(templateObjects, bodyshop, renderAsHtml = false) { +export async function RenderTemplates(templateObjects, bodyshop, renderAsHtml = false, notification) { //Query assets that match the template name. Must be in format <>.query let unsortedTemplatesAndData = []; let proms = []; @@ -259,7 +267,7 @@ export async function RenderTemplates(templateObjects, bodyshop, renderAsHtml = } } -export const GenerateDocument = async (template, messageOptions, sendType, jobid) => { +export const GenerateDocument = async (template, messageOptions, sendType, jobid, notification) => { const bodyshop = store.getState().user.bodyshop; if (sendType === "e") { store.dispatch( @@ -273,17 +281,17 @@ export const GenerateDocument = async (template, messageOptions, sendType, jobid }) ); } else if (sendType === "x") { - await RenderTemplate(template, bodyshop, false, true); + await RenderTemplate(template, bodyshop, false, true, false, notification); } else if (sendType === "text") { - await RenderTemplate(template, bodyshop, false, false, true); + await RenderTemplate(template, bodyshop, false, false, true, notification); } else { - await RenderTemplate(template, bodyshop); + await RenderTemplate(template, bodyshop, false, false, false, notification); } }; -export const GenerateDocuments = async (templates) => { +export const GenerateDocuments = async (templates, notification) => { const bodyshop = store.getState().user.bodyshop; - await RenderTemplates(templates, bodyshop); + await RenderTemplates(templates, bodyshop, false, notification); }; export const fetchFilterData = async ({ name }) => { diff --git a/client/src/utils/criticalPartsScan.js b/client/src/utils/criticalPartsScan.js index 11e96b69b..86efa61da 100644 --- a/client/src/utils/criticalPartsScan.js +++ b/client/src/utils/criticalPartsScan.js @@ -1,7 +1,6 @@ import axios from "axios"; -import { notification } from "antd"; -async function CriticalPartsScan(jobid) { +async function CriticalPartsScan(jobid, notification) { try { await axios.post("/job/partsscan", { jobid }); } catch (error) {