diff --git a/client/src/components/bill-form/bill-form.component.jsx b/client/src/components/bill-form/bill-form.component.jsx index e7fca63af..036ac0012 100644 --- a/client/src/components/bill-form/bill-form.component.jsx +++ b/client/src/components/bill-form/bill-form.component.jsx @@ -1,16 +1,17 @@ -import Icon, {UploadOutlined} from "@ant-design/icons"; -import {useApolloClient} from "@apollo/client"; -import {useSplitTreatments} from "@splitsoftware/splitio-react"; -import {Alert, Divider, Form, Input, Select, Space, Statistic, Switch, Upload,} from "antd"; +import Icon, { UploadOutlined } from "@ant-design/icons"; +import { useApolloClient } from "@apollo/client"; +import { useSplitTreatments } from "@splitsoftware/splitio-react"; +import { Alert, Divider, Form, Input, Select, Space, Statistic, Switch, Upload, } from "antd"; +import React, { useEffect, useState } from "react"; +import { useTranslation } from "react-i18next"; +import { MdOpenInNew } from "react-icons/md"; +import { connect } from "react-redux"; +import { Link } from "react-router-dom"; +import { createStructuredSelector } from "reselect"; +import { CHECK_BILL_INVOICE_NUMBER } from "../../graphql/bills.queries"; +import { selectBodyshop } from "../../redux/user/user.selectors"; import dayjs from "../../utils/day"; -import React, {useEffect, useState} from "react"; -import {useTranslation} from "react-i18next"; -import {MdOpenInNew} from "react-icons/md"; -import {connect} from "react-redux"; -import {Link} from "react-router-dom"; -import {createStructuredSelector} from "reselect"; -import {CHECK_BILL_INVOICE_NUMBER} from "../../graphql/bills.queries"; -import {selectBodyshop} from "../../redux/user/user.selectors"; +import InstanceRenderManager from "../../utils/instanceRenderMgr"; import AlertComponent from "../alert/alert.component"; import BillFormLinesExtended from "../bill-form-lines-extended/bill-form-lines-extended.component"; import FormDatePicker from "../form-date-picker/form-date-picker.component"; @@ -20,8 +21,7 @@ import JobSearchSelect from "../job-search-select/job-search-select.component"; import LayoutFormRow from "../layout-form-row/layout-form-row.component"; import VendorSearchSelect from "../vendor-search-select/vendor-search-select.component"; import BillFormLines from "./bill-form.lines.component"; -import {CalculateBillTotal} from "./bill-form.totals.utility"; -import InstanceRenderManager from "../../utils/instanceRenderMgr"; +import { CalculateBillTotal } from "./bill-form.totals.utility"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -149,9 +149,9 @@ export function BillFormComponent({ convertedOnly notExported={false} onBlur={() => { - if (form.getFieldValue("jobid") !== null) { + if (form.getFieldValue("jobid") !== null && form.getFieldValue("jobid") !== undefined) { loadLines({variables: {id: form.getFieldValue("jobid")}}); - if (form.getFieldValue("vendorid") !== null) { + if (form.getFieldValue("vendorid") !== null && form.getFieldValue("vendorid") !== undefined) { loadOutstandingReturns({ variables: { jobId: form.getFieldValue("jobid"), diff --git a/client/src/components/chat-affix/chat-affix.container.jsx b/client/src/components/chat-affix/chat-affix.container.jsx index 0cae7763a..0ce09211e 100644 --- a/client/src/components/chat-affix/chat-affix.container.jsx +++ b/client/src/components/chat-affix/chat-affix.container.jsx @@ -62,7 +62,7 @@ export function ChatAffixContainer({bodyshop, chatVisible}) { SubscribeToTopic(); // eslint-disable-next-line react-hooks/exhaustive-deps - }, [bodyshop]); + }, []); useEffect(() => { function handleMessage(payload) { diff --git a/client/src/components/form-fields-changed-alert/form-fields-changed-alert.component.jsx b/client/src/components/form-fields-changed-alert/form-fields-changed-alert.component.jsx index f4e278315..1d5576720 100644 --- a/client/src/components/form-fields-changed-alert/form-fields-changed-alert.component.jsx +++ b/client/src/components/form-fields-changed-alert/form-fields-changed-alert.component.jsx @@ -19,7 +19,6 @@ export default function FormsFieldChanged({form, skipPrompt}) { style={{margin: 0, padding: 0, minHeight: "unset"}} > {() => { - console.log("should update",form.isFieldsTouched()) const errors = form.getFieldsError().filter((e) => e.errors.length > 0); if (form.isFieldsTouched()) return ( 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 574d029e0..e20f186c3 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,13 +1,13 @@ -import {useMutation} from "@apollo/client"; -import {Button, Form, notification, Popover, Tooltip} from "antd"; -import {t} from "i18next"; -import React, {useState} from "react"; -import {UPDATE_LINE_PPC} from "../../graphql/jobs-lines.queries"; +import { useMutation } from "@apollo/client"; +import { Button, Form, notification, Popover, Tooltip } from "antd"; +import axios from "axios"; +import { t } from "i18next"; +import React, { useState } from "react"; +import { UPDATE_LINE_PPC } from "../../graphql/jobs-lines.queries"; 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 axios from "axios"; -import InstanceRenderManager from "../../utils/instanceRenderMgr"; export default function JobLinesPartPriceChange({job, line, refetch}) { const [loading, setLoading] = useState(false); @@ -54,7 +54,9 @@ export default function JobLinesPartPriceChange({job, line, refetch}) { } }; - const popcontent = ( + const popcontent = InstanceRenderManager({ + imex: null, + rome: (
-
- ); + ), + promanager: null + }) ; return ( - + {line.db_ref === "900510" || line.db_ref === "900511" ? line.prt_dsmk_m diff --git a/client/src/components/job-detail-lines/job-lines.component.jsx b/client/src/components/job-detail-lines/job-lines.component.jsx index 4ec5c4bab..f8f3198d5 100644 --- a/client/src/components/job-detail-lines/job-lines.component.jsx +++ b/client/src/components/job-detail-lines/job-lines.component.jsx @@ -8,9 +8,9 @@ import { SyncOutlined, WarningFilled, } from '@ant-design/icons'; -import { useMutation } from '@apollo/client'; -import { Button, Checkbox, Dropdown, Input, Space, Table, Tag } from 'antd'; import { PageHeader } from '@ant-design/pro-layout'; +import { useMutation } from '@apollo/client'; +import { Button, Dropdown, Input, Space, Table, Tag } from 'antd'; import axios from 'axios'; import React, { useState } from 'react'; import { useTranslation } from 'react-i18next'; @@ -29,19 +29,19 @@ import JobLinesBillRefernece from '../job-lines-bill-reference/job-lines-bill-re // import AllocationsAssignmentContainer from "../allocations-assignment/allocations-assignment.container"; // import AllocationsBulkAssignmentContainer from "../allocations-bulk-assignment/allocations-bulk-assignment.container"; // import AllocationsEmployeeLabelContainer from "../allocations-employee-label/allocations-employee-label.container"; +import { useSplitTreatments } from '@splitsoftware/splitio-react'; import _ from 'lodash'; +import { selectBodyshop } from '../../redux/user/user.selectors'; +import dayjs from '../../utils/day'; +import { HasFeatureAccess } from '../feature-wrapper/feature-wrapper.component'; import JobCreateIOU from '../job-create-iou/job-create-iou.component'; +import JobLineBulkAssignComponent from '../job-line-bulk-assign/job-line-bulk-assign.component'; +import JobLineDispatchButton from '../job-line-dispatch-button/job-line-dispatch-button.component'; +import JoblineTeamAssignment from '../job-line-team-assignment/job-line-team-assignmnent.component'; import JobSendPartPriceChangeComponent from '../job-send-parts-price-change/job-send-parts-price-change.component'; import PartsOrderModalContainer from '../parts-order-modal/parts-order-modal.container'; import JobLinesExpander from './job-lines-expander.component'; -import { selectBodyshop } from '../../redux/user/user.selectors'; -import dayjs from '../../utils/day'; import JobLinesPartPriceChange from './job-lines-part-price-change.component'; -import JoblineTeamAssignment from '../job-line-team-assignment/job-line-team-assignmnent.component'; -import JobLineDispatchButton from '../job-line-dispatch-button/job-line-dispatch-button.component'; -import JobLineBulkAssignComponent from '../job-line-bulk-assign/job-line-bulk-assign.component'; -import { useSplitTreatments } from '@splitsoftware/splitio-react'; -import { HasFeatureAccess } from '../feature-wrapper/feature-wrapper.component'; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -219,12 +219,12 @@ export function JobLinesComponent({ key: 'part_qty', }, - { - title: t('joblines.fields.tax_part'), - dataIndex: 'tax_part', - key: 'tax_part', - render: (text, record) => , - }, + // { + // title: t('joblines.fields.tax_part'), + // dataIndex: 'tax_part', + // key: 'tax_part', + // render: (text, record) => , + // }, // { // title: t("joblines.fields.total"), // dataIndex: "total", 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 90a760a4c..594102bd2 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 @@ -57,7 +57,7 @@ export function JobLineDispatchButton({ parts_dispatch_lines: { data: selectedLines.map((l) => ({ joblineid: l.id, - quantity: l.part_qty, + quantity: l.part_qty, })), }, }, @@ -65,6 +65,7 @@ export function JobLineDispatchButton({ }, }); if (result.errors) { + console.log("🚀 ~ handleConvert ~ result.errors:", result.errors) notification.open({ type: "error", message: t("parts_dispatch.errors.creating", { @@ -86,6 +87,7 @@ export function JobLineDispatchButton({ } setVisible(false); } catch (error) { + console.log("🚀 ~ handleConvert ~ error:", error) notification.open({ type: "error", message: t("parts_dispatch.errors.creating", { @@ -136,7 +138,7 @@ export function JobLineDispatchButton({ )} - + } > {!context || (context && !context.id) ? null : ( diff --git a/client/src/components/schedule-calendar-wrapper/schedule-calendar-header.component.jsx b/client/src/components/schedule-calendar-wrapper/schedule-calendar-header.component.jsx index 5150345f6..a91946e45 100644 --- a/client/src/components/schedule-calendar-wrapper/schedule-calendar-header.component.jsx +++ b/client/src/components/schedule-calendar-wrapper/schedule-calendar-header.component.jsx @@ -1,5 +1,5 @@ import Icon from "@ant-design/icons"; -import {Popover} from "antd"; +import {Popover, Space} from "antd"; import _ from "lodash"; import dayjs from "../../utils/day"; @@ -135,7 +135,7 @@ export function ScheduleCalendarHeaderComponent({ const LoadComponent = loadData ? (
-
+ -
+
    {Object.keys(ATSToday).map((key, idx) => ( diff --git a/client/src/components/update-alert/update-alert.component.jsx b/client/src/components/update-alert/update-alert.component.jsx index 4434c6b0e..c17e1c10a 100644 --- a/client/src/components/update-alert/update-alert.component.jsx +++ b/client/src/components/update-alert/update-alert.component.jsx @@ -1,18 +1,13 @@ +import { AlertOutlined } from '@ant-design/icons'; import { Alert, Button, Col, Row, Space } from 'antd'; import i18n from 'i18next'; import React from 'react'; +import { useTranslation } from 'react-i18next'; import { connect } from 'react-redux'; import { createStructuredSelector } from 'reselect'; import { selectUpdateAvailable } from '../../redux/application/application.selectors'; -import { AlertOutlined } from '@ant-design/icons'; -import { useTranslation } from 'react-i18next'; -import { setUpdateAvailable } from '../../redux/application/application.actions'; -import { store } from '../../redux/store'; -//import * as serviceWorkerRegistration from '../../serviceWorkerRegistration'; -import InstanceRenderManager from '../../utils/instanceRenderMgr'; import { useRegisterSW } from 'virtual:pwa-register/react'; - -let globalRegistration; +import InstanceRenderManager from '../../utils/instanceRenderMgr'; const mapStateToProps = createStructuredSelector({ updateAvailable: selectUpdateAvailable, @@ -46,7 +41,9 @@ export function UpdateAlert({ updateAvailable }) { console.log('SW registration error', error); }, }); - console.log(`SW Status => Refresh? ${needRefresh} - offlineReady? ${offlineReady}`); + + if (import.meta.env.DEV) + console.log(`SW Status => Refresh? ${needRefresh} - offlineReady? ${offlineReady}`); if (!needRefresh) return null; return ( diff --git a/client/src/pages/tech-dispatched-parts/tech-dispatched-parts.page.jsx b/client/src/pages/tech-dispatched-parts/tech-dispatched-parts.page.jsx index 8d90502c6..fa17f6acd 100644 --- a/client/src/pages/tech-dispatched-parts/tech-dispatched-parts.page.jsx +++ b/client/src/pages/tech-dispatched-parts/tech-dispatched-parts.page.jsx @@ -13,6 +13,7 @@ import {GET_UNACCEPTED_PARTS_DISPATCH} from "../../graphql/parts-dispatch.querie import {selectTechnician} from "../../redux/tech/tech.selectors"; import {selectBodyshop} from "../../redux/user/user.selectors"; import {alphaSort} from "../../utils/sorters"; +import { useSplitTreatments } from "@splitsoftware/splitio-react"; const mapStateToProps = createStructuredSelector({ //currentUser: selectCurrentUser @@ -25,6 +26,12 @@ export function TechDispatchedParts({technician, bodyshop}) { const searchParams = queryString.parse(useLocation().search); const {page} = searchParams; + const {treatments: {Enhanced_Payroll}} = useSplitTreatments({ + attributes: {}, + names: ["Enhanced_Payroll"], + splitKey: bodyshop.imexshopid, + }); + const {loading, error, data, refetch} = useQuery( GET_UNACCEPTED_PARTS_DISPATCH, { @@ -73,7 +80,7 @@ export function TechDispatchedParts({technician, bodyshop}) { } ${record.job.v_model_desc || ""}`} ), }, - { + ...Enhanced_Payroll.treatment=== 'on' ? [ { title: t("general.labels.actions"), dataIndex: "actions", key: "actions", @@ -83,7 +90,9 @@ export function TechDispatchedParts({technician, bodyshop}) { {t("timetickets.actions.claimtasks")} ), - }, + },] : [] + + ]; const handleTableChange = (pagination, filters, sorter) => { searchParams.page = pagination.current; diff --git a/client/src/redux/user/user.sagas.js b/client/src/redux/user/user.sagas.js index ff35594c6..6f00c390d 100644 --- a/client/src/redux/user/user.sagas.js +++ b/client/src/redux/user/user.sagas.js @@ -220,24 +220,26 @@ export function* signInSuccessSaga({payload}) { LogRocket.identify(payload.email); try { - InstanceRenderManager({ - executeFunction: true, - imex: () => { - window.$crisp.push([ - "set", - "user:nickname", - [payload.displayName || payload.email], - ]); - - window.$crisp.push(["set", "session:segments", [["user"]]]); - } }) - - Sentry.setUser({ - email: payload.email, - username: payload.displayName || payload.email, - }); + InstanceRenderManager({ + executeFunction: true, + args:[], + imex: () => { + window.$crisp.push(['set', 'user:nickname', [payload.displayName || payload.email]]); + window.$crisp.push(['set', 'session:segments', [['user']]]); + }, + + }); } catch (error) { - console.log("Error updating Crisp settings.", error); + console.log('Error updating Crisp settings.', error); + } + + try { + Sentry.setUser({ + email: payload.email, + username: payload.displayName || payload.email, + }); + } catch (error) { + console.log('Error setting Sentry user.', error); } setUserId(analytics, payload.email); diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json index 0fa460752..084c55688 100644 --- a/client/src/translations/en_us/common.json +++ b/client/src/translations/en_us/common.json @@ -2342,7 +2342,7 @@ "associatedbills": "This parts order cannot", "backordering": "Error backordering part {{message}}.", "creating": "Error encountered when creating parts order. ", - "oec": "Error creating EMS files for OEC. {{error}}", + "oec": "Error creating EMS files for parts order. {{error}}", "saving": "Error saving parts order. {{error}}.", "updating": "Error updating parts order/parts order line. {{error}}." }, @@ -2379,7 +2379,7 @@ "mark_as_received": "Mark as Received?", "newpartsorder": "New Parts Order", "notyetordered": "This part has not yet been ordered.", - "oec": "Order via OEC", + "oec": "Order via EMS", "order_type": "Order Type", "orderhistory": "Order History", "parts_order": "Parts Order", diff --git a/client/src/translations/i18n.js b/client/src/translations/i18n.js index 7e3b8b941..12173a881 100644 --- a/client/src/translations/i18n.js +++ b/client/src/translations/i18n.js @@ -20,7 +20,7 @@ i18n //lng: "en", detection: {}, fallbackLng: 'en-US', - debug: import.meta.env.PROD ? false : true, + debug: import.meta.env.DEV, //keySeparator: false, // we do not use keys in form messages.welcome interpolation: { escapeValue: false, // react already safes from xss diff --git a/client/src/utils/useEffectDebugger.js b/client/src/utils/useEffectDebugger.js new file mode 100644 index 000000000..7f46efd47 --- /dev/null +++ b/client/src/utils/useEffectDebugger.js @@ -0,0 +1,37 @@ +import { useEffect, useRef } from 'react'; + +const usePrevious = (value, initialValue) => { + const ref = useRef(initialValue); + useEffect(() => { + ref.current = value; + }); + return ref.current; +}; + +const useEffectDebugger = (effectHook, dependencies, dependencyNames = []) => { + const previousDeps = usePrevious(dependencies, []); + + const changedDeps = dependencies.reduce((accum, dependency, index) => { + if (dependency !== previousDeps[index]) { + const keyName = dependencyNames[index] || index; + return { + ...accum, + [keyName]: { + before: previousDeps[index], + after: dependency, + }, + }; + } + + return accum; + }, {}); + + if (Object.keys(changedDeps).length) { + console.log('[use-effect-debugger] ', changedDeps); + } + + // eslint-disable-next-line react-hooks/exhaustive-deps + useEffect(effectHook, dependencies); +}; + +export default useEffectDebugger;