diff --git a/bodyshop_translations.babel b/bodyshop_translations.babel index 86da3ae37..503000cd2 100644 --- a/bodyshop_translations.babel +++ b/bodyshop_translations.babel @@ -694,6 +694,27 @@ + + bp + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + cancelledappointment false @@ -925,6 +946,27 @@ + + owner + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + priorappointments false @@ -967,6 +1009,48 @@ + + ro_number + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + scheduled_completion + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + scheduledfor false @@ -1072,6 +1156,27 @@ + + vehicle + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + @@ -1248,6 +1353,37 @@ + + audio + + + manager + + + description + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + + + audit @@ -4489,6 +4625,27 @@ + + duplicate_insurance_company + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + loading false @@ -4557,6 +4714,27 @@ + + accumulatePayableLines + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + address1 false @@ -9108,6 +9286,27 @@ + + gogcode + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + gst_override false @@ -9150,6 +9349,90 @@ + + item_type + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + item_type_freight + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + item_type_gog + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + item_type_paint + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + itemexemptcode false @@ -9528,6 +9811,27 @@ + + nontaxable + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + paa false @@ -9911,6 +10215,48 @@ + + taxable + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + taxable_flag + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + tow false @@ -11479,6 +11825,27 @@ + + rr_dealerid + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + title false @@ -11969,6 +12336,48 @@ + + parts_shop_management + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + parts_vendor_management + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + partslocations false @@ -16406,6 +16815,27 @@ + + status_normal + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + updatinglayout false @@ -18186,6 +18616,27 @@ + + select + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + @@ -19835,6 +20286,27 @@ + + optional + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + previous false @@ -20045,6 +20517,27 @@ + + select + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + selectall false @@ -20347,6 +20840,27 @@ + + undefined + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + @@ -21598,6 +22112,27 @@ + + selected + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + sendagain false @@ -21640,6 +22175,27 @@ + + settings + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + signin false @@ -24127,6 +24683,27 @@ + + updatelocation + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + @@ -25517,6 +26094,27 @@ + + bulk_location_help + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + convertedtolabor false @@ -27106,6 +27704,27 @@ + + invalidjoblines + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + invoicing false @@ -27127,6 +27746,27 @@ + + missingjoblineids + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + noaccess false @@ -27594,6 +28234,27 @@ + + admin_clerk + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + alt_transport false @@ -29166,6 +29827,27 @@ + + advisor + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + amount false @@ -29381,6 +30063,27 @@ + + first_name + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + id false @@ -29444,6 +30147,27 @@ + + last_name + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + lines false @@ -29465,6 +30189,27 @@ + + make_override + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + name1 false @@ -29594,6 +30339,27 @@ + + payer_type + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + @@ -41196,6 +41962,27 @@ + + openchat + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + @@ -41332,6 +42119,27 @@ + + mark_unread + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + maxtenimages false @@ -43967,6 +44775,27 @@ labels + + cell + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + create_new false @@ -44009,6 +44838,27 @@ + + email + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + existing_owners false @@ -44072,6 +44922,69 @@ + + home + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + other + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + phone + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + relatedjobs false @@ -44093,6 +45006,27 @@ + + sms + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + updateowner false @@ -44114,6 +45048,27 @@ + + work + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + @@ -44215,6 +45170,53 @@ + + labels + + + view_counts_only + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + view_timestamps + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + @@ -50181,6 +51183,27 @@ + + click_for_statuses + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + clm_no false @@ -50601,6 +51624,27 @@ + + partsreceived + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + partsstatus false @@ -54650,6 +55694,27 @@ + + payments_by_date_excel + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + payments_by_date_payment false @@ -60825,6 +61890,27 @@ + + parts + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + parts-queue false @@ -60846,6 +61932,27 @@ + + parts_settings + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + payments-all false @@ -61077,6 +62184,27 @@ + + simplified-parts-jobs + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + tasks false @@ -61793,6 +62921,27 @@ + + parts + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + parts-queue false @@ -61814,6 +62963,27 @@ + + parts_settings + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + payments-all false @@ -62129,6 +63299,27 @@ + + simplified-parts-jobs + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + tasks false @@ -63769,6 +64960,48 @@ + + dark_theme + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + light_theme + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + signout false @@ -63973,6 +65206,132 @@ + + notification_sound_disabled + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + notification_sound_enabled + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + notification_sound_help + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + notification_sound_off + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + notification_sound_on + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + play_sound_for_new_messages + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + profileinfo false @@ -63994,6 +65353,27 @@ + + user_settings + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + diff --git a/client/src/components/bill-cm-returns-table/bill-cm-returns-table.component.jsx b/client/src/components/bill-cm-returns-table/bill-cm-returns-table.component.jsx index 8a2263bda..951795a7b 100644 --- a/client/src/components/bill-cm-returns-table/bill-cm-returns-table.component.jsx +++ b/client/src/components/bill-cm-returns-table/bill-cm-returns-table.component.jsx @@ -52,6 +52,9 @@ export default function BillCmdReturnsTableComponent({ form, returnLoading, retu {fields.map((field, index) => ( + 0) + if (!!values.total && !!values.billlines && values.billlines.length > 0) { totals = CalculateBillTotal(values); - if (totals) + } + + if (totals) { return ( // TODO: Align is not correct // eslint-disable-next-line react/no-unknown-property @@ -414,7 +416,7 @@ export function BillFormComponent({ ); + } return null; }} 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 d1fb03369..73b0a21a9 100644 --- a/client/src/components/bill-form/bill-form.lines.component.jsx +++ b/client/src/components/bill-form/bill-form.lines.component.jsx @@ -90,6 +90,7 @@ export function BillEnterModalLinesComponent({ }); }; + // Only fill actual_cost when the user forward-tabs out of Retail (actual_price) const autofillActualCost = (index) => { Promise.resolve().then(() => { const retailRaw = form.getFieldValue(["billlines", index, "actual_price"]); @@ -164,10 +165,9 @@ export function BillEnterModalLinesComponent({ }} allowRemoved={form.getFieldValue("is_credit_memo") || false} onSelect={(value, opt) => { - const d = normalizeDiscount(discount); - const retail = Number(opt.cost); - const computedActual = Number.isFinite(retail) ? round2(retail * (1 - d)) : null; - + // IMPORTANT: + // Do NOT autofill actual_cost here. It should only fill when the user forward-tabs + // from Retail (actual_price) -> Actual Cost (actual_cost). setFieldsValue({ billlines: (getFieldValue("billlines") || []).map((item, idx) => { if (idx !== index) return item; @@ -178,7 +178,7 @@ export function BillEnterModalLinesComponent({ quantity: opt.part_qty || 1, actual_price: opt.cost, original_actual_price: opt.cost, - actual_cost: isBlank(item.actual_cost) ? computedActual : item.actual_cost, + // actual_cost intentionally untouched here cost_center: opt.part_type ? bodyshopHasDmsKey(bodyshop) ? opt.part_type !== "PAE" @@ -251,9 +251,9 @@ export function BillEnterModalLinesComponent({ autofillActualCost(index)} + // NOTE: Autofill should only happen on forward Tab out of Retail onKeyDown={(e) => { - if (e.key === "Tab") autofillActualCost(index); + if (e.key === "Tab" && !e.shiftKey) autofillActualCost(index); }} /> ), @@ -329,7 +329,7 @@ export function BillEnterModalLinesComponent({ disabled={disabled} controls={false} style={{ width: "100%", height: CONTROL_HEIGHT }} - onFocus={() => autofillActualCost(index)} + // NOTE: No auto-fill on focus/blur; only triggered from Retail on Tab /> @@ -517,7 +517,11 @@ export function BillEnterModalLinesComponent({ formItemProps: (field) => ({ key: `${field.name}fedtax`, valuePropName: "checked", - name: [field.name, "applicable_taxes", "federal"] + name: [field.name, "applicable_taxes", "federal"], + initialValue: InstanceRenderManager({ + imex: true, + rome: false + }) }), formInput: () => } 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 ab3384fce..11aed2922 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 @@ -57,7 +57,6 @@ const CardPaymentModalComponent = ({ QUERY_RO_AND_OWNER_BY_JOB_PKS, { fetchPolicy: "network-only", - notifyOnNetworkStatusChange: true } ); diff --git a/client/src/components/chat-popup/chat-popup.component.jsx b/client/src/components/chat-popup/chat-popup.component.jsx index f0805345a..1a3c03f2d 100644 --- a/client/src/components/chat-popup/chat-popup.component.jsx +++ b/client/src/components/chat-popup/chat-popup.component.jsx @@ -47,7 +47,6 @@ export function ChatPopupComponent({ chatVisible, selectedConversation, toggleCh const [getConversations, { loading, data, refetch, called }] = useLazyQuery(CONVERSATION_LIST_QUERY, { fetchPolicy: "network-only", nextFetchPolicy: "network-only", - notifyOnNetworkStatusChange: true, ...(pollInterval > 0 ? { pollInterval } : {}) }); diff --git a/client/src/components/dashboard-components/total-production-hours/total-production-hours.component.jsx b/client/src/components/dashboard-components/total-production-hours/total-production-hours.component.jsx index 5c29a1962..b9716e84b 100644 --- a/client/src/components/dashboard-components/total-production-hours/total-production-hours.component.jsx +++ b/client/src/components/dashboard-components/total-production-hours/total-production-hours.component.jsx @@ -36,7 +36,7 @@ export function DashboardTotalProductionHours({ bodyshop, data, ...cardProps }) diff --git a/client/src/components/dms-post-form/cdklike-dms-post-form.jsx b/client/src/components/dms-post-form/cdklike-dms-post-form.jsx index 43003a45f..9e006534b 100644 --- a/client/src/components/dms-post-form/cdklike-dms-post-form.jsx +++ b/client/src/components/dms-post-form/cdklike-dms-post-form.jsx @@ -404,7 +404,7 @@ export default function CdkLikePostForm({ bodyshop, socket, job, logsRef, mode, = - + document.body}>
diff --git a/client/src/components/job-parts-queue-count/job-parts-queue-count.component.jsx b/client/src/components/job-parts-queue-count/job-parts-queue-count.component.jsx index c7cc3a115..771d36f36 100644 --- a/client/src/components/job-parts-queue-count/job-parts-queue-count.component.jsx +++ b/client/src/components/job-parts-queue-count/job-parts-queue-count.component.jsx @@ -1,29 +1,65 @@ import { useMemo } from "react"; -import { Tag, Tooltip } from "antd"; +import { Tooltip } from "antd"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import { selectBodyshop } from "../../redux/user/user.selectors"; -import { useTranslation } from "react-i18next"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop }); -const mapDispatchToProps = () => ({ - //setUserLanguage: language => dispatch(setUserLanguage(language)) -}); +const mapDispatchToProps = () => ({}); + +const colorMap = { + gray: { bg: "#fafafa", border: "#d9d9d9", text: "#000000" }, + gold: { bg: "#fffbe6", border: "#ffe58f", text: "#d48806" }, + red: { bg: "#fff1f0", border: "#ffccc7", text: "#cf1322" }, + blue: { bg: "#e6f7ff", border: "#91d5ff", text: "#0958d9" }, + green: { bg: "#f6ffed", border: "#b7eb8f", text: "#389e0d" }, + orange: { bg: "#fff7e6", border: "#ffd591", text: "#d46b08" } +}; + +function CompactTag({ color = "gray", children, tooltip = "" }) { + const colors = colorMap[color] || colorMap.gray; + + return ( + + {children} + + ); +} export default connect(mapStateToProps, mapDispatchToProps)(JobPartsQueueCount); export function JobPartsQueueCount({ bodyshop, parts }) { - const { t } = useTranslation(); const partsStatus = useMemo(() => { if (!parts) return null; + const statusKeys = ["default_bo", "default_ordered", "default_received", "default_returned"]; + return parts.reduce( (acc, val) => { if (val.part_type === "PAS" || val.part_type === "PASL") return acc; - acc.total = acc.total + val.count; - acc[val.status] = acc[val.status] + val.count; + + acc.total += val.count; + + // NOTE: if val.status is null, object key becomes "null" + acc[val.status] = (acc[val.status] ?? 0) + val.count; + return acc; }, { @@ -34,45 +70,38 @@ export function JobPartsQueueCount({ bodyshop, parts }) { ); }, [bodyshop, parts]); - if (!parts) return null; + if (!parts || !partsStatus) return null; + return (
- - {partsStatus.total} - - - - {partsStatus["null"]} - - - - - {partsStatus[bodyshop.md_order_statuses.default_bo]} - - - - - {partsStatus[bodyshop.md_order_statuses.default_ordered]} - - - - - {partsStatus[bodyshop.md_order_statuses.default_received]} - - - - - {partsStatus[bodyshop.md_order_statuses.default_returned]} - - + + {partsStatus.total} + + + + {partsStatus["null"]} + + + + {partsStatus[bodyshop.md_order_statuses.default_bo]} + + + + {partsStatus[bodyshop.md_order_statuses.default_ordered]} + + + {partsStatus[bodyshop.md_order_statuses.default_received]} + + + {partsStatus[bodyshop.md_order_statuses.default_returned]} +
); } diff --git a/client/src/components/job-parts-received/job-parts-received.component.jsx b/client/src/components/job-parts-received/job-parts-received.component.jsx index 64521fb5f..dc6c42cbc 100644 --- a/client/src/components/job-parts-received/job-parts-received.component.jsx +++ b/client/src/components/job-parts-received/job-parts-received.component.jsx @@ -18,10 +18,17 @@ const mapStateToProps = createStructuredSelector({ * @param parts * @param displayMode * @param popoverPlacement + * @param countsOnly * @returns {JSX.Element} * @constructor */ -export function JobPartsReceived({ bodyshop, parts, displayMode = "full", popoverPlacement = "top" }) { +export function JobPartsReceived({ + bodyshop, + parts, + displayMode = "full", + popoverPlacement = "top", + countsOnly = false +}) { const [open, setOpen] = useState(false); const { t } = useTranslation(); @@ -61,6 +68,8 @@ export function JobPartsReceived({ bodyshop, parts, displayMode = "full", popove [canOpen] ); + if (countsOnly) return ; + const displayText = displayMode === "compact" ? summary.percentLabel : `${summary.percentLabel} (${summary.received}/${summary.total})`; @@ -74,7 +83,7 @@ export function JobPartsReceived({ bodyshop, parts, displayMode = "full", popove trigger={["click"]} placement={popoverPlacement} content={ -
+
} @@ -99,7 +108,8 @@ JobPartsReceived.propTypes = { bodyshop: PropTypes.object, parts: PropTypes.array, displayMode: PropTypes.oneOf(["full", "compact"]), - popoverPlacement: PropTypes.string + popoverPlacement: PropTypes.string, + countsOnly: PropTypes.bool }; export default connect(mapStateToProps)(JobPartsReceived); 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 509539e8d..bdb08ef01 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 @@ -157,7 +157,6 @@ export function JobsDetailHeaderActions({ variables: watcherVars, skip: !jobId, fetchPolicy: "cache-first", - notifyOnNetworkStatusChange: true }); const jobWatchersCount = jobWatchersData?.job_watchers?.length ?? job?.job_watchers?.length ?? 0; diff --git a/client/src/components/notification-center/notification-center.container.jsx b/client/src/components/notification-center/notification-center.container.jsx index c0bec13d0..109591228 100644 --- a/client/src/components/notification-center/notification-center.container.jsx +++ b/client/src/components/notification-center/notification-center.container.jsx @@ -56,7 +56,6 @@ const NotificationCenterContainer = ({ visible, onClose, bodyshop, unreadCount, where: whereClause }, fetchPolicy: "cache-and-network", - notifyOnNetworkStatusChange: true, errorPolicy: "all", pollInterval: isConnected ? 0 : day.duration(NOTIFICATION_POLL_INTERVAL_SECONDS, "seconds").asMilliseconds(), skip: skipQuery diff --git a/client/src/components/owner-name-display/owner-name-display.component.jsx b/client/src/components/owner-name-display/owner-name-display.component.jsx index 0b211fbf5..cc799f53d 100644 --- a/client/src/components/owner-name-display/owner-name-display.component.jsx +++ b/client/src/components/owner-name-display/owner-name-display.component.jsx @@ -2,6 +2,7 @@ import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import { store } from "../../redux/store"; import { selectBodyshop } from "../../redux/user/user.selectors"; +import { Tooltip } from "antd"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop @@ -11,15 +12,27 @@ const mapDispatchToProps = () => ({ }); export default connect(mapStateToProps, mapDispatchToProps)(OwnerNameDisplay); -export function OwnerNameDisplay({ bodyshop, ownerObject }) { +export function OwnerNameDisplay({ bodyshop, ownerObject, withToolTip = false }) { const emptyTest = ownerObject?.ownr_fn + ownerObject?.ownr_ln + ownerObject?.ownr_co_nm; if (!emptyTest || emptyTest === "null" || emptyTest.trim() === "") return "N/A"; - if (bodyshop.last_name_first) - return `${ownerObject?.ownr_ln || ""}, ${ownerObject?.ownr_fn || ""} ${ownerObject?.ownr_co_nm || ""}`.trim(); - - return `${ownerObject?.ownr_fn || ""} ${ownerObject?.ownr_ln || ""} ${ownerObject.ownr_co_nm || ""}`.trim(); + let returnString; + if (bodyshop.last_name_first) { + returnString = + `${ownerObject?.ownr_ln || ""}, ${ownerObject?.ownr_fn || ""} ${ownerObject?.ownr_co_nm || ""}`.trim(); + } else { + returnString = `${ownerObject?.ownr_fn || ""} ${ownerObject?.ownr_ln || ""} ${ownerObject.ownr_co_nm || ""}`.trim(); + } + if (withToolTip) { + return ( + + {returnString} + + ); + } else { + return returnString; + } } export function OwnerNameDisplayFunction(ownerObject, forceFirstLast = false) { diff --git a/client/src/components/owner-search-select/owner-search-select.component.jsx b/client/src/components/owner-search-select/owner-search-select.component.jsx index 9f6f5030a..bc5d7b105 100644 --- a/client/src/components/owner-search-select/owner-search-select.component.jsx +++ b/client/src/components/owner-search-select/owner-search-select.component.jsx @@ -16,9 +16,10 @@ const OwnerSearchSelect = ({ value, onChange, onBlur, disabled, ref }) => { SEARCH_OWNERS_BY_ID_FOR_AUTOCOMPLETE ); - const executeSearch = (v) => { - if (v && v.variables?.search !== "" && v.variables.search.length >= 2) callSearch({ variables: v.variables }); + const executeSearch = (variables) => { + if (variables?.search !== "" && variables?.search?.length >= 2) callSearch({ variables }); }; + const debouncedExecuteSearch = _.debounce(executeSearch, 500); const handleSearch = (value) => { diff --git a/client/src/components/parts-order-modal/parts-order-modal-price-change.component.jsx b/client/src/components/parts-order-modal/parts-order-modal-price-change.component.jsx index aa6ef3384..dc613245b 100644 --- a/client/src/components/parts-order-modal/parts-order-modal-price-change.component.jsx +++ b/client/src/components/parts-order-modal/parts-order-modal-price-change.component.jsx @@ -1,94 +1,121 @@ import { DownOutlined } from "@ant-design/icons"; -import { Dropdown, InputNumber, Space } from "antd"; +import { Button, Divider, Dropdown, InputNumber, Space, theme } from "antd"; +import { useState } from "react"; import { useTranslation } from "react-i18next"; import { logImEXEvent } from "../../firebase/firebase.utils"; +const DISCOUNT_PRESETS = [5, 10, 15, 20, 25, 40]; + export default function PartsOrderModalPriceChange({ form, field }) { const { t } = useTranslation(); - const menu = { - items: [ - { - key: "5", - label: t("parts_orders.labels.discount", { percent: "5%" }) - }, - { - key: "10", - label: t("parts_orders.labels.discount", { percent: "10%" }) - }, - { - key: "15", - label: t("parts_orders.labels.discount", { percent: "15%" }) - }, - { - key: "20", - label: t("parts_orders.labels.discount", { percent: "20%" }) - }, - { - key: "25", - label: t("parts_orders.labels.discount", { percent: "25%" }) - }, - { - key: "40", - label: t("parts_orders.labels.discount", { percent: "40%" }) - }, - { - key: "custom", - label: ( - - e.stopPropagation()} - onKeyUp={(e) => { - if (e.key === "Enter") { - const values = form.getFieldsValue(); - const { parts_order_lines } = values; + const { token } = theme.useToken(); - form.setFieldsValue({ - parts_order_lines: { - data: parts_order_lines.data.map((p, idx) => { - if (idx !== field.name) return p; - console.log(p, e.target.value, (p.act_price || 0) * ((100 - (e.target.value || 0)) / 100)); - return { - ...p, - act_price: (p.act_price || 0) * ((100 - (e.target.value || 0)) / 100) - }; - }) - } - }); - e.target.value = 0; - } - }} - min={0} - max={100} - /> - % - - ) + const [open, setOpen] = useState(false); + const [customPercent, setCustomPercent] = useState(0); + + const applyDiscountPercent = (percent) => { + const pct = Number(percent) || 0; + + const values = form.getFieldsValue(); + const parts_order_lines = values?.parts_order_lines; + const data = Array.isArray(parts_order_lines?.data) ? parts_order_lines.data : []; + if (!data.length) return; + + form.setFieldsValue({ + parts_order_lines: { + data: data.map((p, idx) => { + if (idx !== field.name) return p; + return { + ...p, + act_price: (p.act_price || 0) * ((100 - pct) / 100) + }; + }) } - ], + }); + }; + + const applyCustom = () => { + logImEXEvent("parts_order_manual_discount", {}); + applyDiscountPercent(customPercent); + setCustomPercent(0); + setOpen(false); + }; + + const menu = { + // Kill the menu “card” styling so our wrapper becomes the single card. + style: { + background: "transparent", + boxShadow: "none" + }, + items: DISCOUNT_PRESETS.map((pct) => ({ + key: String(pct), + label: t("parts_orders.labels.discount", { percent: `${pct}%` }) + })), onClick: ({ key }) => { logImEXEvent("parts_order_manual_discount", {}); - if (key === "custom") return; - const values = form.getFieldsValue(); - const { parts_order_lines } = values; - form.setFieldsValue({ - parts_order_lines: { - data: parts_order_lines.data.map((p, idx) => { - if (idx !== field.name) return p; - return { - ...p, - act_price: (p.act_price || 0) * ((100 - key) / 100) - }; - }) - } - }); + applyDiscountPercent(key); + setOpen(false); } }; return ( - + setOpen(nextOpen)} + getPopupContainer={(triggerNode) => triggerNode?.parentElement ?? document.body} + popupRender={(menus) => ( +
e.stopPropagation()} + onKeyDown={(e) => e.stopPropagation()} + > + {menus} + + + +
+ + (v === null || v === undefined ? "" : `${v}%`)} + parser={(v) => + String(v ?? "") + .replace("%", "") + .trim() + } + onChange={(v) => setCustomPercent(v ?? 0)} + onKeyDown={(e) => { + e.stopPropagation(); + if (e.key === "Enter") { + e.preventDefault(); + applyCustom(); + } + }} + /> + + +
+
+ )} + > - % - + %
); 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 1d68645be..d2e3deba3 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 @@ -17,7 +17,6 @@ import AuditTrailMapping from "../../utils/AuditTrailMappings"; import { GenerateDocument } from "../../utils/RenderTemplate"; import { TemplateList } from "../../utils/TemplateConstants"; import AlertComponent from "../alert/alert.component"; -import LoadingSpinner from "../loading-spinner/loading-spinner.component"; import PartsOrderModalComponent from "./parts-order-modal.component"; import axios from "axios"; import { useTreatmentsWithConfig } from "@splitsoftware/splitio-react"; @@ -66,7 +65,7 @@ export function PartsOrderModalContainer({ const sendTypeState = useState("e"); const sendType = sendTypeState[0]; - const { loading, error, data } = useQuery(QUERY_ALL_VENDORS_FOR_ORDER, { + const { error, data } = useQuery(QUERY_ALL_VENDORS_FOR_ORDER, { skip: !open, variables: { jobId: jobId }, fetchPolicy: "network-only", @@ -94,16 +93,6 @@ export function PartsOrderModalContainer({ }; }); - const missingIdx = forcedLines.findIndex((l) => !l?.job_line_id); - if (missingIdx !== -1) { - notification.error({ - title: t("parts_orders.errors.creating"), - description: `Missing job_line_id for parts line #${missingIdx + 1}` - }); - setSaving(false); - return; - } - let insertResult; try { insertResult = await insertPartOrder({ @@ -372,6 +361,7 @@ export function PartsOrderModalContainer({ } }, [open, linesToOrder, form]); + //This used to have a loading component spinner for the vendor data. With Apollo 4, the NetworkState isn't emitting correctly, so loading just gets set to true the second time, and no longer works as expected. return ( {error ? : null} - {loading ? ( - - ) : ( - - )} + ); diff --git a/client/src/components/parts-queue-list/parts-queue.list.component.jsx b/client/src/components/parts-queue-list/parts-queue.list.component.jsx index 6459d7a96..766ff9564 100644 --- a/client/src/components/parts-queue-list/parts-queue.list.component.jsx +++ b/client/src/components/parts-queue-list/parts-queue.list.component.jsx @@ -1,6 +1,6 @@ import { SyncOutlined } from "@ant-design/icons"; import { useQuery } from "@apollo/client/react"; -import { Button, Card, Input, Space, Table } from "antd"; +import { Button, Card, Checkbox, Input, Space, Table } from "antd"; import _ from "lodash"; import queryString from "query-string"; import { useState } from "react"; @@ -31,6 +31,8 @@ export function PartsQueueListComponent({ bodyshop }) { const { selected, sortcolumn, sortorder, statusFilters } = searchParams; const history = useNavigate(); const [filter, setFilter] = useLocalStorage("filter_parts_queue", null); + const [viewTimeStamp, setViewTimeStamp] = useLocalStorage("parts_queue_timestamps", false); + const [countsOnly, setCountsOnly] = useLocalStorage("parts_queue_counts_only", false); const { loading, error, data, refetch } = useQuery(QUERY_PARTS_QUEUE, { fetchPolicy: "network-only", @@ -92,6 +94,7 @@ export function PartsQueueListComponent({ bodyshop }) { title: t("jobs.fields.ro_number"), dataIndex: "ro_number", key: "ro_number", + width: "110px", sorter: (a, b) => alphaSort(a.ro_number, b.ro_number), sortOrder: sortcolumn === "ro_number" && sortorder, @@ -103,16 +106,20 @@ export function PartsQueueListComponent({ bodyshop }) { title: t("jobs.fields.owner"), dataIndex: "ownr_ln", key: "ownr_ln", + width: "8%", + ellipsis: { + showTitle: true + }, sorter: (a, b) => alphaSort(OwnerNameDisplayFunction(a), OwnerNameDisplayFunction(b)), sortOrder: sortcolumn === "ownr_ln" && sortorder, render: (text, record) => { return record.ownerid ? ( - + ) : ( - + ); } @@ -187,7 +194,7 @@ export function PartsQueueListComponent({ bodyshop }) { ellipsis: true, sorter: (a, b) => dateSort(a.scheduled_in, b.scheduled_in), sortOrder: sortcolumn === "scheduled_in" && sortorder, - render: (text, record) => {record.scheduled_in} + render: (text, record) => {record.scheduled_in} }, { title: t("jobs.fields.scheduled_completion"), @@ -196,7 +203,9 @@ export function PartsQueueListComponent({ bodyshop }) { ellipsis: true, sorter: (a, b) => dateSort(a.scheduled_completion, b.scheduled_completion), sortOrder: sortcolumn === "scheduled_completion" && sortorder, - render: (text, record) => {record.scheduled_completion} + render: (text, record) => ( + {record.scheduled_completion} + ) }, // { // title: t("vehicles.fields.plate_no"), @@ -227,16 +236,23 @@ export function PartsQueueListComponent({ bodyshop }) { title: t("jobs.fields.updated_at"), dataIndex: "updated_at", key: "updated_at", + width: "110px", sorter: (a, b) => dateSort(a.updated_at, b.updated_at), sortOrder: sortcolumn === "updated_at" && sortorder, - render: (text, record) => {record.updated_at} + render: (text, record) => {record.updated_at} }, { title: t("jobs.fields.partsstatus"), dataIndex: "partsstatus", key: "partsstatus", + width: countsOnly ? "180px" : "110px", render: (text, record) => ( - + ) }, { @@ -249,6 +265,7 @@ export function PartsQueueListComponent({ bodyshop }) { title: t("jobs.fields.queued_for_parts"), dataIndex: "queued_for_parts", key: "queued_for_parts", + width: "120px", sorter: (a, b) => a.queued_for_parts - b.queued_for_parts, sortOrder: sortcolumn === "queued_for_parts" && sortorder, filteredValue: filter?.queued_for_parts || null, @@ -275,6 +292,12 @@ export function PartsQueueListComponent({ bodyshop }) { + setCountsOnly(e.target.checked)}> + {t("parts.labels.view_counts_only")} + + setViewTimeStamp(e.target.checked)}> + {t("parts.labels.view_timestamps")} + { diff --git a/client/src/components/payment-form/payment-form.totalpayments.component.jsx b/client/src/components/payment-form/payment-form.totalpayments.component.jsx index b413158fe..27717919c 100644 --- a/client/src/components/payment-form/payment-form.totalpayments.component.jsx +++ b/client/src/components/payment-form/payment-form.totalpayments.component.jsx @@ -33,7 +33,7 @@ export default function PaymentFormTotalPayments({ jobid }) { {balance && ( )} 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 396c3dde5..9a10eceef 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 @@ -108,7 +108,7 @@ export function PrintCenterJobsLabels({ jobId }) { ); return ( - + trigger.parentElement}> ); diff --git a/client/src/components/vehicle-search-select/vehicle-search-select.component.jsx b/client/src/components/vehicle-search-select/vehicle-search-select.component.jsx index cffe871a5..b11851588 100644 --- a/client/src/components/vehicle-search-select/vehicle-search-select.component.jsx +++ b/client/src/components/vehicle-search-select/vehicle-search-select.component.jsx @@ -18,9 +18,10 @@ const VehicleSearchSelect = ({ value, onChange, onBlur, disabled, ref }) => { SEARCH_VEHICLES_BY_ID_FOR_AUTOCOMPLETE ); - const executeSearch = (v) => { - if (v && v.variables?.search !== "" && v.variables.search.length >= 2) callSearch({ variables: v.variables }); + const executeSearch = (variables) => { + if (variables?.search !== "" && variables?.search?.length >= 2) callSearch({ variables }); }; + const debouncedExecuteSearch = _.debounce(executeSearch, 500); const handleSearch = (value) => { diff --git a/client/src/pages/jobs-close/jobs-close.component.jsx b/client/src/pages/jobs-close/jobs-close.component.jsx index eb09d7d2c..9a429cb2a 100644 --- a/client/src/pages/jobs-close/jobs-close.component.jsx +++ b/client/src/pages/jobs-close/jobs-close.component.jsx @@ -510,7 +510,7 @@ export function JobsCloseComponent({ job, bodyshop, jobRO, insertAuditTrail, set = 0 ? "green" : "red" } }} diff --git a/client/src/pages/tech/tech.page.component.jsx b/client/src/pages/tech/tech.page.component.jsx index 678536ae4..4150f567f 100644 --- a/client/src/pages/tech/tech.page.component.jsx +++ b/client/src/pages/tech/tech.page.component.jsx @@ -17,7 +17,10 @@ import "./tech.page.styles.scss"; import UpsellComponent, { upsellEnum } from "../../components/upsell/upsell.component.jsx"; import { lazyDev } from "../../utils/lazyWithPreload.jsx"; -const TimeTicketModalContainer = lazyDev(() => import("../../components/time-ticket-modal/time-ticket-modal.container")); +const NoteUpsertModal = lazyDev(() => import("../../components/note-upsert-modal/note-upsert-modal.container.jsx")); +const TimeTicketModalContainer = lazyDev( + () => import("../../components/time-ticket-modal/time-ticket-modal.container") +); const EmailOverlayContainer = lazyDev(() => import("../../components/email-overlay/email-overlay.container.jsx")); const PrintCenterModalContainer = lazyDev( () => import("../../components/print-center-modal/print-center-modal.container") @@ -34,7 +37,9 @@ const TimeTicketModalTask = lazyDev( const TechAssignedProdJobs = lazyDev(() => import("../tech-assigned-prod-jobs/tech-assigned-prod-jobs.component")); const TechDispatchedParts = lazyDev(() => import("../tech-dispatched-parts/tech-dispatched-parts.page")); -const TaskUpsertModalContainer = lazyDev(() => import("../../components/task-upsert-modal/task-upsert-modal.container")); +const TaskUpsertModalContainer = lazyDev( + () => import("../../components/task-upsert-modal/task-upsert-modal.container") +); const { Content } = Layout; @@ -70,6 +75,8 @@ export function TechPage({ technician }) { + + {{ro_number}} has a data consistency issue. It may have been excluded for scheduling purposes. CODE: {{code}}.", @@ -59,18 +60,17 @@ "noarrivingjobs": "No Jobs are arriving.", "nocompletingjobs": "No Jobs scheduled for completion.", "nodateselected": "No date has been selected.", + "owner": "Owner", "priorappointments": "Previous Appointments", "reminder": "This is {{shopname}} reminding you about an appointment on {{date}} at {{time}}. Please let us know if you are not able to make the appointment. We look forward to seeing you soon. ", + "ro_number": "RO #", + "scheduled_completion": "Scheduled Completion", "scheduledfor": "Scheduled appointment for: ", "severalerrorsfound": "Several Jobs have issues which may prevent accurate smart scheduling. Click to expand.", "smartscheduling": "Smart Scheduling", "smspaymentreminder": "This is {{shopname}} reminding you about your remaining balance of {{amount}}. To pay for the said balance click the link {{payment_link}}.", "suggesteddates": "Suggested Dates", - "ro_number": "RO #", - "owner": "Owner", - "vehicle": "Vehicle", - "bp": "B/P", - "scheduled_completion": "Scheduled Completion" + "vehicle": "Vehicle" }, "successes": { "canceled": "Appointment canceled successfully.", @@ -90,6 +90,11 @@ "actions": "Actions" } }, + "audio": { + "manager": { + "description": "Click anywhere to enable the message ding." + } + }, "audit": { "fields": { "cc": "CC", @@ -149,11 +154,6 @@ "tasks_updated": "Task '{{title}}' updated by {{updatedBy}}" } }, - "audio": { - "manager": { - "description": "Click anywhere to enable the message ding." - } - }, "billlines": { "actions": { "newline": "New Line" @@ -281,9 +281,9 @@ }, "errors": { "creatingdefaultview": "Error creating default view.", + "duplicate_insurance_company": "Duplicate insurance company name. Each insurance company name must be unique", "loading": "Unable to load shop details. Please call technical support.", - "saving": "Error encountered while saving. {{message}}", - "duplicate_insurance_company": "Duplicate insurance company name. Each insurance company name must be unique" + "saving": "Error encountered while saving. {{message}}" }, "fields": { "ReceivableCustomField": "QBO Receivable Custom Field {{number}}", @@ -564,21 +564,18 @@ "responsibilitycenter_tax_tier": "Tax {{typeNum}} Tier {{typeNumIterator}}", "responsibilitycenter_tax_type": "Tax {{typeNum}} Type", "responsibilitycenters": { - "gogcode": "GOG Code (BreakOut)", - "item_type": "Item Type", - "item_type_gog": "GOG", - "item_type_paint": "Paint Materials", - "item_type_freight": "Freight", - "taxable_flag": "Taxable?", - "taxable": "Taxable", - "nontaxable": "Non-taxable", "ap": "Accounts Payable", "ar": "Accounts Receivable", "ats": "ATS", "federal_tax": "Federal Tax", "federal_tax_itc": "Federal Tax Credit", + "gogcode": "GOG Code (BreakOut)", "gst_override": "GST Override Account #", "invoiceexemptcode": "QuickBooks US - Invoice Tax Exempt Code", + "item_type": "Item Type", + "item_type_freight": "Freight", + "item_type_gog": "GOG", + "item_type_paint": "Paint Materials", "itemexemptcode": "QuickBooks US - Line Item Tax Exempt Code", "la1": "LA1", "la2": "LA2", @@ -597,6 +594,7 @@ "local_tax": "Local Tax", "mapa": "Paint Materials", "mash": "Shop Materials", + "nontaxable": "Non-taxable", "paa": "Aftermarket", "pac": "Chrome", "pag": "Glass", @@ -617,6 +615,8 @@ "state": "State Tax Applies" }, "state_tax": "State Tax", + "taxable": "Taxable", + "taxable_flag": "Taxable?", "tow": "Towing" }, "schedule_end_time": "Schedule Ending Time", @@ -678,8 +678,6 @@ "zip_post": "Zip/Postal Code" }, "labels": { - "parts_shop_management": "Shop Management", - "parts_vendor_management": "Vendor Management", "2tiername": "Name => RO", "2tiersetup": "2 Tier Setup", "2tiersource": "Source => RO", @@ -702,11 +700,11 @@ "payers": "Payers" }, "cdk_dealerid": "CDK Dealer ID", - "rr_dealerid": "Reynolds Store Number", "costsmapping": "Costs Mapping", "dms_allocations": "DMS Allocations", "pbs_serialnumber": "PBS Serial Number", "profitsmapping": "Profits Mapping", + "rr_dealerid": "Reynolds Store Number", "title": "DMS" }, "emaillater": "Email Later", @@ -733,6 +731,8 @@ "followers": "Notifications" }, "orderstatuses": "Order Statuses", + "parts_shop_management": "Shop Management", + "parts_vendor_management": "Vendor Management", "partslocations": "Parts Locations", "partsscan": "Parts Scanning", "printlater": "Print Later", @@ -1228,8 +1228,6 @@ }, "general": { "actions": { - "select": "Select", - "optional": "Optional", "add": "Add", "autoupdate": "{{app}} will automatically update in {{time}} seconds. Please save all changes.", "calculate": "Calculate", @@ -1249,6 +1247,7 @@ "login": "Login", "next": "Next", "ok": "Ok", + "optional": "Optional", "previous": "Previous", "print": "Print", "refresh": "Refresh", @@ -1259,6 +1258,7 @@ "save": "Save", "saveandnew": "Save and New", "saveas": "Save As", + "select": "Select", "selectall": "Select All", "send": "Send", "sendbysms": "Send by SMS", @@ -1288,8 +1288,7 @@ "vehicle": "Vehicle" }, "labels": { - "selected": "Selected", - "settings": "Settings", + "apply": "Apply", "actions": "Actions", "areyousure": "Are you sure?", "barcode": "Barcode", @@ -1343,8 +1342,10 @@ "search": "Search...", "searchresults": "Results for {{search}}", "selectdate": "Select date...", + "selected": "Selected", "sendagain": "Send Again", "sendby": "Send By", + "settings": "Settings", "signin": "Sign In", "sms": "SMS", "status": "Status", @@ -1587,13 +1588,13 @@ "labels": { "adjustmenttobeadded": "Adjustment to be added: {{adjustment}}", "billref": "Latest Bill", + "bulk_location_help": "This will set the same location on all selected lines.", "convertedtolabor": "This line has been converted to labor. Ensure you adjust the profit center for the amount accordingly.", "edit": "Edit Line", "ioucreated": "IOU", "new": "New Line", "nostatus": "No Status", - "presets": "Jobline Presets", - "bulk_location_help": "This will set the same location on all selected lines." + "presets": "Jobline Presets" }, "successes": { "created": "Job line created successfully.", @@ -1701,9 +1702,9 @@ "actual_delivery": "Actual Delivery", "actual_in": "Actual In", "acv_amount": "ACV Amount", - "admin_clerk": "Admin Clerk", "adjustment_bottom_line": "Adjustments", "adjustmenthours": "Adjustment Hours", + "admin_clerk": "Admin Clerk", "alt_transport": "Alt. Trans.", "area_of_damage_impact": { "10": "Left Front Side", @@ -1784,9 +1785,8 @@ "ded_status": "Deductible Status", "depreciation_taxes": "Betterment/Depreciation/Taxes", "dms": { - "first_name": "First Name", - "last_name": "Last Name", "address": "Customer Address", + "advisor": "Advisor #", "amount": "Amount", "center": "Center", "control_type": { @@ -1799,12 +1799,13 @@ "dms_model_override": "Override DMS Make/Model", "dms_unsold": "New, Unsold Vehicle", "dms_wip_acctnumber": "Cost WIP DMS Acct #", + "first_name": "First Name", "id": "DMS ID", "inservicedate": "In Service Date", "journal": "Journal #", - "make_override": "Make Override", - "advisor": "Advisor #", + "last_name": "Last Name", "lines": "Posting Lines", + "make_override": "Make Override", "name1": "Customer Name", "payer": { "amount": "Amount", @@ -1945,7 +1946,7 @@ "amount": "Amount", "name": "Name" }, - "queued_for_parts": "Queued for Parts", + "queued_for_parts": "Queued", "rate_ats": "ATS Rate", "rate_ats_flat": "ATS Flat Rate", "rate_la1": "LA1", @@ -2447,6 +2448,7 @@ "labels": { "addlabel": "Add a label to this conversation.", "archive": "Archive", + "mark_unread": "Mark as unread", "maxtenimages": "You can only select up to a maximum of 10 images at a time.", "messaging": "Messaging", "no_consent": "Opted-out", @@ -2459,8 +2461,7 @@ "selectmedia": "Select Media", "sentby": "Sent by {{by}} at {{time}}", "typeamessage": "Send a message...", - "unarchive": "Unarchive", - "mark_unread": "Mark as unread" + "unarchive": "Unarchive" }, "render": { "conversation_list": "Conversation List" @@ -2614,20 +2615,20 @@ "name": "Owner Details" }, "labels": { + "cell": "Cell", "create_new": "Create a new owner record.", "deleteconfirm": "Are you sure you want to delete this owner? This cannot be undone.", + "email": "Email", "existing_owners": "Existing Owners", "fromclaim": "Current Claim", "fromowner": "Historical Owner Record", - "relatedjobs": "Related Jobs", - "updateowner": "Update Owner", - "work": "Work", "home": "Home", - "cell": "Cell", "other": "Other", - "email": "Email", "phone": "Phone", - "sms": "SMS" + "relatedjobs": "Related Jobs", + "sms": "SMS", + "updateowner": "Update Owner", + "work": "Work" }, "successes": { "delete": "Owner deleted successfully.", @@ -2638,6 +2639,10 @@ "actions": { "order": "Order Parts", "orderinhouse": "Order as In House" + }, + "labels": { + "view_counts_only": "View Parts Counts Only", + "view_timestamps": "Show timestamps" } }, "parts_dispatch": { @@ -2987,8 +2992,6 @@ "settings": "Error saving board settings: {{error}}" }, "labels": { - "click_for_statuses": "Click to view parts statuses", - "partsreceived": "Parts Received", "actual_in": "Actual In", "addnewprofile": "Add New Profile", "alert": "Alert", @@ -3007,6 +3010,7 @@ "card_size": "Card Size", "cardcolor": "Colored Cards", "cardsettings": "Card Settings", + "click_for_statuses": "Click to view parts statuses", "clm_no": "Claim Number", "comment": "Comment", "compact": "Compact Cards", @@ -3027,6 +3031,7 @@ "orientation": "Board Orientation", "ownr_nm": "Customer Name", "paintpriority": "P/P", + "partsreceived": "Parts Received", "partsstatus": "Parts Status", "production_note": "Production Note", "refinishhours": "R", @@ -3573,17 +3578,12 @@ } }, "titles": { - "parts_settings": "Parts Management Settings | {{app}}", - "simplified-parts-jobs": "Parts Management | {{app}}", "accounting-payables": "Payables | {{app}}", "accounting-payments": "Payments | {{app}}", "accounting-receivables": "Receivables | {{app}}", "all_tasks": "All Tasks | {{app}}", "app": "", "bc": { - "simplified-parts-jobs": "Jobs", - "parts": "Parts", - "parts_settings": "Settings", "accounting-payables": "Payables", "accounting-payments": "Payments", "accounting-receivables": "Receivables", @@ -3615,7 +3615,9 @@ "my_tasks": "My Tasks", "owner-detail": "{{name}}", "owners": "Owners", + "parts": "Parts", "parts-queue": "Parts Queue", + "parts_settings": "Settings", "payments-all": "All Payments", "phonebook": "Phonebook", "productionboard": "Production Board - Visual", @@ -3627,6 +3629,7 @@ "shop-csi": "CSI Responses", "shop-templates": "Shop Templates", "shop-vendors": "Vendors", + "simplified-parts-jobs": "Jobs", "tasks": "Tasks", "temporarydocs": "Temporary Documents", "timetickets": "Time Tickets", @@ -3662,7 +3665,9 @@ "my_tasks": "My Tasks | {{app}}", "owners": "All Owners | {{app}}", "owners-detail": "{{name}} | {{app}}", + "parts": "", "parts-queue": "Parts Queue | {{app}}", + "parts_settings": "Parts Management Settings | {{app}}", "payments-all": "Payments | {{app}}", "phonebook": "Phonebook | {{app}}", "productionboard": "Production Board - Visual | {{app}}", @@ -3678,6 +3683,7 @@ "shop-csi": "CSI Responses | {{app}}", "shop-templates": "Shop Templates | {{app}}", "shop_vendors": "Vendors | {{app}}", + "simplified-parts-jobs": "Parts Management | {{app}}", "tasks": "Tasks", "techconsole": "Technician Console | {{app}}", "techjobclock": "Technician Job Clock | {{app}}", @@ -3838,10 +3844,10 @@ "user": { "actions": { "changepassword": "Change Password", - "signout": "Sign Out", - "updateprofile": "Update Profile", + "dark_theme": "Switch to Dark Theme", "light_theme": "Switch to Light Theme", - "dark_theme": "Switch to Dark Theme" + "signout": "Sign Out", + "updateprofile": "Update Profile" }, "errors": { "updating": "Error updating user or association {{message}}" @@ -3855,14 +3861,14 @@ "labels": { "actions": "Actions", "changepassword": "Change Password", - "profileinfo": "Profile Info", - "user_settings": "User Settings", - "play_sound_for_new_messages": "Play a sound for new messages", - "notification_sound_on": "Sound is ON", - "notification_sound_off": "Sound is OFF", - "notification_sound_enabled": "Notification sound enabled", "notification_sound_disabled": "Notification sound disabled", - "notification_sound_help": "Toggle the ding for incoming chat messages." + "notification_sound_enabled": "Notification sound enabled", + "notification_sound_help": "Toggle the ding for incoming chat messages.", + "notification_sound_off": "Sound is OFF", + "notification_sound_on": "Sound is ON", + "play_sound_for_new_messages": "Play a sound for new messages", + "profileinfo": "Profile Info", + "user_settings": "User Settings" }, "successess": { "passwordchanged": "Password changed successfully. " diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json index 70cd2b5da..5c7a31350 100644 --- a/client/src/translations/es/common.json +++ b/client/src/translations/es/common.json @@ -48,6 +48,7 @@ "arrivedon": "Llegado el:", "arrivingjobs": "", "blocked": "", + "bp": "", "cancelledappointment": "Cita cancelada para:", "completingjobs": "", "dataconsistency": "", @@ -59,18 +60,17 @@ "noarrivingjobs": "", "nocompletingjobs": "", "nodateselected": "No se ha seleccionado ninguna fecha.", + "owner": "", "priorappointments": "Nombramientos previos", "reminder": "", + "ro_number": "", + "scheduled_completion": "", "scheduledfor": "Cita programada para:", "severalerrorsfound": "", "smartscheduling": "", "smspaymentreminder": "", "suggesteddates": "", - "ro_number": "", - "owner": "", - "vehicle": "", - "bp": "", - "scheduled_completion": "" + "vehicle": "" }, "successes": { "canceled": "Cita cancelada con éxito.", @@ -90,6 +90,11 @@ "actions": "Comportamiento" } }, + "audio": { + "manager": { + "description": "" + } + }, "audit": { "fields": { "cc": "", @@ -149,11 +154,6 @@ "tasks_updated": "" } }, - "audio": { - "manager": { - "description": "" - } - }, "billlines": { "actions": { "newline": "" @@ -281,9 +281,9 @@ }, "errors": { "creatingdefaultview": "", + "duplicate_insurance_company": "", "loading": "No se pueden cargar los detalles de la tienda. Por favor llame al soporte técnico.", - "saving": "", - "duplicate_insurance_company": "" + "saving": "" }, "fields": { "ReceivableCustomField": "", @@ -564,21 +564,18 @@ "responsibilitycenter_tax_tier": "", "responsibilitycenter_tax_type": "", "responsibilitycenters": { - "gogcode": "", - "item_type": "Item Type", - "item_type_gog": "", - "item_type_paint": "", - "item_type_freight": "", - "taxable_flag": "", - "taxable": "", - "nontaxable": "", "ap": "", "ar": "", "ats": "", "federal_tax": "", "federal_tax_itc": "", + "gogcode": "", "gst_override": "", "invoiceexemptcode": "", + "item_type": "Item Type", + "item_type_freight": "", + "item_type_gog": "", + "item_type_paint": "", "itemexemptcode": "", "la1": "", "la2": "", @@ -597,6 +594,7 @@ "local_tax": "", "mapa": "", "mash": "", + "nontaxable": "", "paa": "", "pac": "", "pag": "", @@ -617,6 +615,8 @@ "state": "" }, "state_tax": "", + "taxable": "", + "taxable_flag": "", "tow": "" }, "schedule_end_time": "", @@ -678,8 +678,6 @@ "zip_post": "" }, "labels": { - "parts_shop_management": "", - "parts_vendor_management": "", "2tiername": "", "2tiersetup": "", "2tiersource": "", @@ -702,11 +700,11 @@ "payers": "" }, "cdk_dealerid": "", - "rr_dealerid": "", "costsmapping": "", "dms_allocations": "", "pbs_serialnumber": "", "profitsmapping": "", + "rr_dealerid": "", "title": "" }, "emaillater": "", @@ -733,6 +731,8 @@ "followers": "" }, "orderstatuses": "", + "parts_shop_management": "", + "parts_vendor_management": "", "partslocations": "", "partsscan": "", "printlater": "", @@ -1247,6 +1247,7 @@ "login": "", "next": "", "ok": "", + "optional": "", "previous": "", "print": "", "refresh": "", @@ -1257,6 +1258,7 @@ "save": "Salvar", "saveandnew": "", "saveas": "", + "select": "", "selectall": "", "send": "", "sendbysms": "", @@ -1286,9 +1288,8 @@ "vehicle": "" }, "labels": { - "selected": "", + "apply": "", "actions": "Comportamiento", - "settings": "", "areyousure": "", "barcode": "código de barras", "cancel": "", @@ -1341,8 +1342,10 @@ "search": "Buscar...", "searchresults": "", "selectdate": "", + "selected": "", "sendagain": "", "sendby": "", + "settings": "", "signin": "", "sms": "", "status": "", @@ -1585,13 +1588,13 @@ "labels": { "adjustmenttobeadded": "", "billref": "", + "bulk_location_help": "", "convertedtolabor": "", "edit": "Línea de edición", "ioucreated": "", "new": "Nueva línea", "nostatus": "", - "presets": "", - "bulk_location_help": "" + "presets": "" }, "successes": { "created": "", @@ -1700,8 +1703,8 @@ "actual_in": "Real en", "acv_amount": "", "adjustment_bottom_line": "Ajustes", - "admin_clerk": "", "adjustmenthours": "", + "admin_clerk": "", "alt_transport": "", "area_of_damage_impact": { "10": "", @@ -1782,9 +1785,8 @@ "ded_status": "Estado deducible", "depreciation_taxes": "Depreciación / Impuestos", "dms": { - "first_name": "", - "last_name": "", "address": "", + "advisor": "", "amount": "", "center": "", "control_type": { @@ -1795,21 +1797,23 @@ "dms_make": "", "dms_model": "", "dms_model_override": "", - "make_override": "", - "advisor": "", "dms_unsold": "", "dms_wip_acctnumber": "", + "first_name": "", "id": "", "inservicedate": "", "journal": "", + "last_name": "", "lines": "", + "make_override": "", "name1": "", "payer": { "amount": "", "control_type": "", "controlnumber": "", "dms_acctnumber": "", - "name": "" + "name": "", + "payer_type": "" }, "sale": "", "sale_dms_acctnumber": "", @@ -2444,6 +2448,7 @@ "labels": { "addlabel": "", "archive": "", + "mark_unread": "", "maxtenimages": "", "messaging": "Mensajería", "no_consent": "", @@ -2456,8 +2461,7 @@ "selectmedia": "", "sentby": "", "typeamessage": "Enviar un mensaje...", - "unarchive": "", - "mark_unread": "" + "unarchive": "" }, "render": { "conversation_list": "" @@ -2611,20 +2615,20 @@ "name": "" }, "labels": { + "cell": "", "create_new": "Crea un nuevo registro de propietario.", "deleteconfirm": "", + "email": "", "existing_owners": "Propietarios existentes", "fromclaim": "", "fromowner": "", - "relatedjobs": "", - "updateowner": "", - "work": "", "home": "", - "cell": "", "other": "", - "email": "", "phone": "", - "sms": "" + "relatedjobs": "", + "sms": "", + "updateowner": "", + "work": "" }, "successes": { "delete": "", @@ -2635,6 +2639,10 @@ "actions": { "order": "Pedido de piezas", "orderinhouse": "" + }, + "labels": { + "view_counts_only": "", + "view_timestamps": "" } }, "parts_dispatch": { @@ -2984,8 +2992,6 @@ "settings": "" }, "labels": { - "click_for_statuses": "", - "partsreceived": "", "actual_in": "", "addnewprofile": "", "alert": "", @@ -3004,6 +3010,7 @@ "card_size": "", "cardcolor": "", "cardsettings": "", + "click_for_statuses": "", "clm_no": "", "comment": "", "compact": "", @@ -3024,6 +3031,7 @@ "orientation": "", "ownr_nm": "", "paintpriority": "", + "partsreceived": "", "partsstatus": "", "production_note": "", "refinishhours": "", @@ -3570,18 +3578,12 @@ } }, "titles": { - "simplified-parts-jobs": "", - "parts": "", - "parts_settings": "", "accounting-payables": "", "accounting-payments": "", "accounting-receivables": "", "all_tasks": "", "app": "", "bc": { - "simplified-parts-jobs": "", - "parts": "", - "parts_settings": "", "accounting-payables": "", "accounting-payments": "", "accounting-receivables": "", @@ -3613,7 +3615,9 @@ "my_tasks": "", "owner-detail": "", "owners": "", + "parts": "", "parts-queue": "", + "parts_settings": "", "payments-all": "", "phonebook": "", "productionboard": "", @@ -3625,6 +3629,7 @@ "shop-csi": "", "shop-templates": "", "shop-vendors": "", + "simplified-parts-jobs": "", "tasks": "", "temporarydocs": "", "timetickets": "", @@ -3660,7 +3665,9 @@ "my_tasks": "", "owners": "Todos los propietarios | {{app}}", "owners-detail": "", + "parts": "", "parts-queue": "", + "parts_settings": "", "payments-all": "", "phonebook": "", "productionboard": "", @@ -3676,6 +3683,7 @@ "shop-csi": "", "shop-templates": "", "shop_vendors": "Vendedores | {{app}}", + "simplified-parts-jobs": "", "tasks": "", "techconsole": "{{app}}", "techjobclock": "{{app}}", @@ -3836,10 +3844,10 @@ "user": { "actions": { "changepassword": "", - "signout": "desconectar", - "updateprofile": "Actualización del perfil", + "dark_theme": "", "light_theme": "", - "dark_theme": "" + "signout": "desconectar", + "updateprofile": "Actualización del perfil" }, "errors": { "updating": "" @@ -3853,14 +3861,14 @@ "labels": { "actions": "", "changepassword": "", - "profileinfo": "", - "user_settings": "", - "play_sound_for_new_messages": "", - "notification_sound_on": "", - "notification_sound_off": "", - "notification_sound_enabled": "", "notification_sound_disabled": "", - "notification_sound_help": "" + "notification_sound_enabled": "", + "notification_sound_help": "", + "notification_sound_off": "", + "notification_sound_on": "", + "play_sound_for_new_messages": "", + "profileinfo": "", + "user_settings": "" }, "successess": { "passwordchanged": "" diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json index e199a33b2..e74e06bf0 100644 --- a/client/src/translations/fr/common.json +++ b/client/src/translations/fr/common.json @@ -48,6 +48,7 @@ "arrivedon": "Arrivé le:", "arrivingjobs": "", "blocked": "", + "bp": "", "cancelledappointment": "Rendez-vous annulé pour:", "completingjobs": "", "dataconsistency": "", @@ -59,18 +60,17 @@ "noarrivingjobs": "", "nocompletingjobs": "", "nodateselected": "Aucune date n'a été sélectionnée.", + "owner": "", "priorappointments": "Rendez-vous précédents", "reminder": "", + "ro_number": "", + "scheduled_completion": "", "scheduledfor": "Rendez-vous prévu pour:", "severalerrorsfound": "", "smartscheduling": "", "smspaymentreminder": "", "suggesteddates": "", - "ro_number": "", - "owner": "", - "vehicle": "", - "bp": "", - "scheduled_completion": "" + "vehicle": "" }, "successes": { "canceled": "Rendez-vous annulé avec succès.", @@ -90,6 +90,11 @@ "actions": "actes" } }, + "audio": { + "manager": { + "description": "" + } + }, "audit": { "fields": { "cc": "", @@ -149,11 +154,6 @@ "tasks_updated": "" } }, - "audio": { - "manager": { - "description": "" - } - }, "billlines": { "actions": { "newline": "" @@ -281,9 +281,9 @@ }, "errors": { "creatingdefaultview": "", + "duplicate_insurance_company": "", "loading": "Impossible de charger les détails de la boutique. Veuillez appeler le support technique.", - "saving": "", - "duplicate_insurance_company": "" + "saving": "" }, "fields": { "ReceivableCustomField": "", @@ -564,21 +564,18 @@ "responsibilitycenter_tax_tier": "", "responsibilitycenter_tax_type": "", "responsibilitycenters": { - "gogcode": "", - "item_type": "Item Type", - "item_type_gog": "", - "item_type_paint": "", - "item_type_freight": "", - "taxable_flag": "", - "taxable": "", - "nontaxable": "", "ap": "", "ar": "", "ats": "", "federal_tax": "", "federal_tax_itc": "", + "gogcode": "", "gst_override": "", "invoiceexemptcode": "", + "item_type": "Item Type", + "item_type_freight": "", + "item_type_gog": "", + "item_type_paint": "", "itemexemptcode": "", "la1": "", "la2": "", @@ -597,6 +594,7 @@ "local_tax": "", "mapa": "", "mash": "", + "nontaxable": "", "paa": "", "pac": "", "pag": "", @@ -617,6 +615,8 @@ "state": "" }, "state_tax": "", + "taxable": "", + "taxable_flag": "", "tow": "" }, "schedule_end_time": "", @@ -678,8 +678,6 @@ "zip_post": "" }, "labels": { - "parts_shop_management": "", - "parts_vendor_management": "", "2tiername": "", "2tiersetup": "", "2tiersource": "", @@ -702,11 +700,11 @@ "payers": "" }, "cdk_dealerid": "", - "rr_dealerid": "", "costsmapping": "", "dms_allocations": "", "pbs_serialnumber": "", "profitsmapping": "", + "rr_dealerid": "", "title": "" }, "emaillater": "", @@ -733,6 +731,8 @@ "followers": "" }, "orderstatuses": "", + "parts_shop_management": "", + "parts_vendor_management": "", "partslocations": "", "partsscan": "", "printlater": "", @@ -1247,6 +1247,7 @@ "login": "", "next": "", "ok": "", + "optional": "", "previous": "", "print": "", "refresh": "", @@ -1257,6 +1258,7 @@ "save": "sauvegarder", "saveandnew": "", "saveas": "", + "select": "", "selectall": "", "send": "", "sendbysms": "", @@ -1286,8 +1288,7 @@ "vehicle": "" }, "labels": { - "selected": "", - "settings": "", + "apply": "", "actions": "actes", "areyousure": "", "barcode": "code à barre", @@ -1341,8 +1342,10 @@ "search": "Chercher...", "searchresults": "", "selectdate": "", + "selected": "", "sendagain": "", "sendby": "", + "settings": "", "signin": "", "sms": "", "status": "", @@ -1585,13 +1588,13 @@ "labels": { "adjustmenttobeadded": "", "billref": "", + "bulk_location_help": "", "convertedtolabor": "", "edit": "Ligne d'édition", "ioucreated": "", "new": "Nouvelle ligne", "nostatus": "", - "presets": "", - "bulk_location_help": "" + "presets": "" }, "successes": { "created": "", @@ -1699,9 +1702,9 @@ "actual_delivery": "Livraison réelle", "actual_in": "En réel", "acv_amount": "", - "admin_clerk": "", "adjustment_bottom_line": "Ajustements", "adjustmenthours": "", + "admin_clerk": "", "alt_transport": "", "area_of_damage_impact": { "10": "", @@ -1782,9 +1785,8 @@ "ded_status": "Statut de franchise", "depreciation_taxes": "Amortissement / taxes", "dms": { - "first_name": "", - "last_name": "", "address": "", + "advisor": "", "amount": "", "center": "", "control_type": { @@ -1795,21 +1797,23 @@ "dms_make": "", "dms_model": "", "dms_model_override": "", - "make_override": "", - "advisor": "", "dms_unsold": "", "dms_wip_acctnumber": "", + "first_name": "", "id": "", "inservicedate": "", "journal": "", + "last_name": "", "lines": "", + "make_override": "", "name1": "", "payer": { "amount": "", "control_type": "", "controlnumber": "", "dms_acctnumber": "", - "name": "" + "name": "", + "payer_type": "" }, "sale": "", "sale_dms_acctnumber": "", @@ -2433,7 +2437,6 @@ "actions": { "link": "", "new": "", - "openchat": "" }, "errors": { @@ -2445,6 +2448,7 @@ "labels": { "addlabel": "", "archive": "", + "mark_unread": "", "maxtenimages": "", "messaging": "Messagerie", "no_consent": "", @@ -2457,8 +2461,7 @@ "selectmedia": "", "sentby": "", "typeamessage": "Envoyer un message...", - "unarchive": "", - "mark_unread": "" + "unarchive": "" }, "render": { "conversation_list": "" @@ -2612,20 +2615,20 @@ "name": "" }, "labels": { + "cell": "", "create_new": "Créez un nouvel enregistrement de propriétaire.", "deleteconfirm": "", + "email": "", "existing_owners": "Propriétaires existants", "fromclaim": "", "fromowner": "", - "relatedjobs": "", - "updateowner": "", - "work": "", "home": "", - "cell": "", "other": "", - "email": "", "phone": "", - "sms": "" + "relatedjobs": "", + "sms": "", + "updateowner": "", + "work": "" }, "successes": { "delete": "", @@ -2636,6 +2639,10 @@ "actions": { "order": "Commander des pièces", "orderinhouse": "" + }, + "labels": { + "view_counts_only": "", + "view_timestamps": "" } }, "parts_dispatch": { @@ -2985,8 +2992,6 @@ "settings": "" }, "labels": { - "click_for_statuses": "", - "partsreceived": "", "actual_in": "", "addnewprofile": "", "alert": "", @@ -3005,6 +3010,7 @@ "card_size": "", "cardcolor": "", "cardsettings": "", + "click_for_statuses": "", "clm_no": "", "comment": "", "compact": "", @@ -3025,6 +3031,7 @@ "orientation": "", "ownr_nm": "", "paintpriority": "", + "partsreceived": "", "partsstatus": "", "production_note": "", "refinishhours": "", @@ -3571,18 +3578,12 @@ } }, "titles": { - "simplified-parts-jobs": "", - "parts": "", - "parts_settings": "", "accounting-payables": "", "accounting-payments": "", "accounting-receivables": "", "all_tasks": "", "app": "", "bc": { - "simplified-parts-jobs": "", - "parts": "", - "parts_settings": "", "accounting-payables": "", "accounting-payments": "", "accounting-receivables": "", @@ -3614,7 +3615,9 @@ "my_tasks": "", "owner-detail": "", "owners": "", + "parts": "", "parts-queue": "", + "parts_settings": "", "payments-all": "", "phonebook": "", "productionboard": "", @@ -3626,6 +3629,7 @@ "shop-csi": "", "shop-templates": "", "shop-vendors": "", + "simplified-parts-jobs": "", "tasks": "", "temporarydocs": "", "timetickets": "", @@ -3661,7 +3665,9 @@ "my_tasks": "", "owners": "Tous les propriétaires | {{app}}", "owners-detail": "", + "parts": "", "parts-queue": "", + "parts_settings": "", "payments-all": "", "phonebook": "", "productionboard": "", @@ -3677,6 +3683,7 @@ "shop-csi": "", "shop-templates": "", "shop_vendors": "Vendeurs | {{app}}", + "simplified-parts-jobs": "", "tasks": "", "techconsole": "{{app}}", "techjobclock": "{{app}}", @@ -3837,10 +3844,10 @@ "user": { "actions": { "changepassword": "", - "signout": "Déconnexion", - "updateprofile": "Mettre à jour le profil", + "dark_theme": "", "light_theme": "", - "dark_theme": "" + "signout": "Déconnexion", + "updateprofile": "Mettre à jour le profil" }, "errors": { "updating": "" @@ -3854,14 +3861,14 @@ "labels": { "actions": "", "changepassword": "", - "profileinfo": "", - "user_settings": "", - "play_sound_for_new_messages": "", - "notification_sound_on": "", - "notification_sound_off": "", - "notification_sound_enabled": "", "notification_sound_disabled": "", - "notification_sound_help": "" + "notification_sound_enabled": "", + "notification_sound_help": "", + "notification_sound_off": "", + "notification_sound_on": "", + "play_sound_for_new_messages": "", + "profileinfo": "", + "user_settings": "" }, "successess": { "passwordchanged": "" diff --git a/client/src/utils/DateFormatter.jsx b/client/src/utils/DateFormatter.jsx index 574c1d229..f261a0d6d 100644 --- a/client/src/utils/DateFormatter.jsx +++ b/client/src/utils/DateFormatter.jsx @@ -5,8 +5,10 @@ export function DateFormatter(props) { return props.children ? dayjs(props.children).format(props.includeDay ? "ddd MM/DD/YYYY" : "MM/DD/YYYY") : null; } -export function DateTimeFormatter(props) { - return props.children ? dayjs(props.children).format(props.format ? props.format : "MM/DD/YYYY hh:mm a") : null; +export function DateTimeFormatter({ hideTime, ...props }) { + return props.children + ? dayjs(props.children).format(props.format ? props.format : `MM/DD/YYYY${hideTime ? "" : " hh:mm a"}`) + : null; } export function DateTimeFormatterFunction(date) { @@ -17,11 +19,11 @@ export function TimeFormatter(props) { return props.children ? dayjs(props.children).format(props.format ? props.format : "hh:mm a") : null; } -export function TimeAgoFormatter(props) { +export function TimeAgoFormatter({ removeAgoString = false, ...props }) { const m = dayjs(props.children); return props.children ? ( - - {m.fromNow()} + + {m.fromNow(removeAgoString)} ) : null; } diff --git a/client/src/utils/GraphQLClient.js b/client/src/utils/GraphQLClient.js index a03d82eec..299c0e547 100644 --- a/client/src/utils/GraphQLClient.js +++ b/client/src/utils/GraphQLClient.js @@ -248,7 +248,8 @@ const client = new ApolloClient({ watchQuery: { fetchPolicy: "network-only", nextFetchPolicy: "network-only", - errorPolicy: "ignore" + errorPolicy: "ignore", + notifyOnNetworkStatusChange: false }, query: { fetchPolicy: "network-only",