Compare commits

...

13 Commits

Author SHA1 Message Date
Allan Carr
e8cda88a33 IO-3075 Crisp in Rome Online
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-01-28 16:17:11 -08:00
Allan Carr
71a74c5437 Merged in hotfix/2025-01-23 (pull request #2082)
Hotfix/2025 01 23
2025-01-23 23:21:28 +00:00
Allan Carr
6fe4d982f5 Merged in feature/IO-3108-Job-Totals-USA-PASL (pull request #2081)
Feature/IO-3108 Job Totals USA PASL
2025-01-23 23:20:44 +00:00
Allan Carr
5ec032d8d6 IO-3108 Remove Console Log
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-01-23 15:21:10 -08:00
Allan Carr
2718a66fb0 IO-3108 Adjust Initial Values/FieldValues
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-01-23 15:19:33 -08:00
Allan Carr
4c737371e3 IO-3108 Adjust Initial Values
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-01-23 14:49:51 -08:00
Dave Richer
ee7a3d0bdf Merged in hotfix/2025-01-23 (pull request #2079)
Hotfix/2025 01 23
2025-01-23 21:01:43 +00:00
Allan Carr
181af581e5 Merged in feature/IO-3108-Job-Totals-USA-PASL (pull request #2078)
IO-3108 Job Totals USA PASL

Approved-by: Dave Richer
2025-01-23 21:00:43 +00:00
Dave Richer
11e2f5d83d feature/IO-3108-Job-Totals-USA-PASL - Fix submit button for Product Fruits reasons, to go into hotfix 2025-01-23 12:57:10 -08:00
Allan Carr
cbc723fa38 IO-3108 Job Totals USA PASL
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-01-23 12:05:35 -08:00
Allan Carr
95c310119f Merged in hotfix/2025-01-22 (pull request #2073)
IO-3099 check for intellipay initialization before calling. rename files to remove erroneous period.
2025-01-22 16:52:28 +00:00
Allan Carr
ebe1facbd1 Merged in feature/IO-3099-wait-for-intellipay (pull request #2072)
IO-3099 check for intellipay initialization before calling. rename files to remove erroneous period.
2025-01-22 16:50:08 +00:00
Patrick Fic
b021992552 IO-3099 check for intellipay initialization before calling. rename files to remove erroneous period. 2025-01-20 12:16:24 -08:00
9 changed files with 84 additions and 46 deletions

View File

@@ -62,7 +62,17 @@
t = d.getElementsByTagName("script")[0]; t = d.getElementsByTagName("script")[0];
t.parentNode.insertBefore(s, t); t.parentNode.insertBefore(s, t);
</script> </script>
<script type="text/javascript">
window.$crisp = [];
window.CRISP_WEBSITE_ID = "36724f62-2eb0-4b29-9cdd-9905fb99913e";
(function () {
d = document;
s = d.createElement("script");
s.src = "https://client.crisp.chat/l.js";
s.async = 1;
d.getElementsByTagName("head")[0].appendChild(s);
})();
</script>
<% } %> <% } %>
<script> <script>
!(function () { !(function () {

View File

@@ -133,15 +133,19 @@ const CardPaymentModalComponent = ({
if (window.intellipay) { if (window.intellipay) {
// eslint-disable-next-line no-eval // eslint-disable-next-line no-eval
eval(response.data); eval(response.data);
SetIntellipayCallbackFunctions(); pollForIntelliPay(() => {
window.intellipay.autoOpen(); SetIntellipayCallbackFunctions();
window.intellipay.autoOpen();
});
} else { } else {
const rg = document.createRange(); const rg = document.createRange();
const node = rg.createContextualFragment(response.data); const node = rg.createContextualFragment(response.data);
document.documentElement.appendChild(node); document.documentElement.appendChild(node);
SetIntellipayCallbackFunctions(); pollForIntelliPay(() => {
window.intellipay.isAutoOpen = true; SetIntellipayCallbackFunctions();
window.intellipay.initialize(); window.intellipay.isAutoOpen = true;
window.intellipay.initialize();
});
} }
} catch (error) { } catch (error) {
notification.open({ notification.open({
@@ -345,3 +349,27 @@ const CardPaymentModalComponent = ({
}; };
export default connect(mapStateToProps, mapDispatchToProps)(CardPaymentModalComponent); export default connect(mapStateToProps, mapDispatchToProps)(CardPaymentModalComponent);
//Poll for window.IntelliPay.fixAmount for 5 seconds. If it doesn't come up, just try anyways to force the possible error.
function pollForIntelliPay(callbackFunction) {
const timeout = 5000;
const interval = 150; // Poll every 100 milliseconds
const startTime = Date.now();
function checkFixAmount() {
if (window.intellipay && window.intellipay.fixAmount !== undefined) {
callbackFunction();
return;
}
if (Date.now() - startTime >= timeout) {
console.log("Stopped polling IntelliPay after 10 seconds. Attemping to set functions anyways.");
callbackFunction();
return;
}
setTimeout(checkFixAmount, interval);
}
checkFixAmount();
}

View File

@@ -6,7 +6,7 @@ import { createStructuredSelector } from "reselect";
import { toggleModalVisible } from "../../redux/modals/modals.actions"; import { toggleModalVisible } from "../../redux/modals/modals.actions";
import { selectCardPayment } from "../../redux/modals/modals.selectors"; import { selectCardPayment } from "../../redux/modals/modals.selectors";
import { selectBodyshop } from "../../redux/user/user.selectors"; import { selectBodyshop } from "../../redux/user/user.selectors";
import CardPaymentModalComponent from "./card-payment-modal.component."; import CardPaymentModalComponent from "./card-payment-modal.component";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
cardPaymentModal: selectCardPayment, cardPaymentModal: selectCardPayment,

View File

@@ -1,10 +1,10 @@
import * as Sentry from "@sentry/react";
import { Button, Col, Collapse, Result, Row, Space } from "antd"; import { Button, Col, Collapse, Result, Row, Space } from "antd";
import React from "react"; import React from "react";
import { withTranslation } from "react-i18next"; import { withTranslation } from "react-i18next";
import { logImEXEvent } from "../../firebase/firebase.utils";
import * as Sentry from "@sentry/react";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { createStructuredSelector } from "reselect"; import { createStructuredSelector } from "reselect";
import { logImEXEvent } from "../../firebase/firebase.utils";
import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors"; import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors";
import InstanceRenderManager from "../../utils/instanceRenderMgr"; import InstanceRenderManager from "../../utils/instanceRenderMgr";
@@ -38,28 +38,23 @@ class ErrorBoundary extends React.Component {
} }
handleErrorSubmit = () => { handleErrorSubmit = () => {
InstanceRenderManager({ window.$crisp.push([
executeFunction: true, "do",
args: [], "message:send",
imex: () => { [
window.$crisp.push([ "text",
"do", `I hit the following error: \n\n
"message:send",
[
"text",
`I hit the following error: \n\n
${this.state.error.message}\n\n ${this.state.error.message}\n\n
${this.state.error.stack}\n\n ${this.state.error.stack}\n\n
URL:${window.location} as ${this.props.currentUser.email} for ${ URL:${window.location} as ${this.props.currentUser.email} for ${
this.props.bodyshop && this.props.bodyshop.name this.props.bodyshop && this.props.bodyshop.name
} }
` `
] ]
]); ]);
window.$crisp.push(["do", "chat:open"]);
window.$crisp.push(["do", "chat:open"]);
}
});
// const errorDescription = `**Please add relevant details about what you were doing before you encountered this issue** // const errorDescription = `**Please add relevant details about what you were doing before you encountered this issue**
// ---- // ----

View File

@@ -650,14 +650,7 @@ function Header({
icon: <Icon component={QuestionCircleFilled} />, icon: <Icon component={QuestionCircleFilled} />,
label: t("menus.header.help"), label: t("menus.header.help"),
onClick: () => { onClick: () => {
window.open( window.open("https://help.imex.online/", "_blank");
InstanceRenderManager({
imex: "https://help.imex.online/",
rome: "https://rometech.com//"
}),
"_blank"
);
} }
}, },
...(InstanceRenderManager({ ...(InstanceRenderManager({

View File

@@ -1,7 +1,8 @@
import { useMutation } from "@apollo/client"; import { useMutation } from "@apollo/client";
import { Button, Form, Input, notification, Popover, Select, Space, Switch } from "antd"; import { Button, Form, Input, notification, Popover, Select, Space, Switch } from "antd";
import axios from "axios"; import axios from "axios";
import React, { useState } from "react"; import { some } from "lodash";
import React, { useCallback, useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { createStructuredSelector } from "reselect"; import { createStructuredSelector } from "reselect";
@@ -18,7 +19,14 @@ const mapStateToProps = createStructuredSelector({
jobRO: selectJobReadOnly jobRO: selectJobReadOnly
}); });
const mapDispatchToProps = (dispatch) => ({ const mapDispatchToProps = (dispatch) => ({
insertAuditTrail: ({ jobid, operation, type }) => dispatch(insertAuditTrail({ jobid, operation, type })) insertAuditTrail: ({ jobid, operation, type }) =>
dispatch(
insertAuditTrail({
jobid,
operation,
type
})
)
}); });
export function JobsConvertButton({ bodyshop, job, refetch, jobRO, insertAuditTrail, parentFormIsFieldsTouched }) { export function JobsConvertButton({ bodyshop, job, refetch, jobRO, insertAuditTrail, parentFormIsFieldsTouched }) {
@@ -27,6 +35,7 @@ export function JobsConvertButton({ bodyshop, job, refetch, jobRO, insertAuditTr
const [mutationConvertJob] = useMutation(CONVERT_JOB_TO_RO); const [mutationConvertJob] = useMutation(CONVERT_JOB_TO_RO);
const { t } = useTranslation(); const { t } = useTranslation();
const [form] = Form.useForm(); const [form] = Form.useForm();
const allFormValues = Form.useWatch([], form);
const handleConvert = async ({ employee_csr, category, ...values }) => { const handleConvert = async ({ employee_csr, category, ...values }) => {
if (parentFormIsFieldsTouched()) { if (parentFormIsFieldsTouched()) {
@@ -69,6 +78,8 @@ export function JobsConvertButton({ bodyshop, job, refetch, jobRO, insertAuditTr
setLoading(false); setLoading(false);
}; };
const submitDisabled = useCallback(() => some(allFormValues, (v) => v === undefined), [allFormValues]);
const popMenu = ( const popMenu = (
<div> <div>
<Form <Form
@@ -77,9 +88,12 @@ export function JobsConvertButton({ bodyshop, job, refetch, jobRO, insertAuditTr
onFinish={handleConvert} onFinish={handleConvert}
initialValues={{ initialValues={{
driveable: true, driveable: true,
towin: false, towin: job.towin,
ca_gst_registrant: job.ca_gst_registrant,
employee_csr: job.employee_csr, employee_csr: job.employee_csr,
category: job.category category: job.category,
referral_source: job.referral_source,
referral_source_extra: job.referral_source_extra ?? ""
}} }}
> >
<Form.Item <Form.Item
@@ -209,7 +223,7 @@ export function JobsConvertButton({ bodyshop, job, refetch, jobRO, insertAuditTr
<Switch /> <Switch />
</Form.Item> </Form.Item>
<Space wrap> <Space wrap>
<Button type="primary" danger onClick={() => form.submit()} loading={loading}> <Button disabled={submitDisabled()} type="primary" danger onClick={() => form.submit()} loading={loading}>
{t("jobs.actions.convert")} {t("jobs.actions.convert")}
</Button> </Button>
<Button onClick={() => setOpen(false)}>{t("general.actions.close")}</Button> <Button onClick={() => setOpen(false)}>{t("general.actions.close")}</Button>
@@ -231,11 +245,6 @@ export function JobsConvertButton({ bodyshop, job, refetch, jobRO, insertAuditTr
loading={loading} loading={loading}
onClick={() => { onClick={() => {
setOpen(true); setOpen(true);
form.setFieldsValue({
driveable: true,
towin: false,
employee_csr: job.employee_csr
});
}} }}
> >
{t("jobs.actions.convert")} {t("jobs.actions.convert")}

View File

@@ -31,7 +31,7 @@ import { addAlerts } from "../../redux/application/application.actions.js";
const JobsPage = lazy(() => import("../jobs/jobs.page")); const JobsPage = lazy(() => import("../jobs/jobs.page"));
const CardPaymentModalContainer = lazy( const CardPaymentModalContainer = lazy(
() => import("../../components/card-payment-modal/card-payment-modal.container.") () => import("../../components/card-payment-modal/card-payment-modal.container.jsx")
); );
const JobsDetailPage = lazy(() => import("../jobs-detail/jobs-detail.page.container")); const JobsDetailPage = lazy(() => import("../jobs-detail/jobs-detail.page.container"));

View File

@@ -26,6 +26,7 @@ import {
updateCurrentUser updateCurrentUser
} from "../../firebase/firebase.utils"; } from "../../firebase/firebase.utils";
import { QUERY_EULA } from "../../graphql/bodyshop.queries"; import { QUERY_EULA } from "../../graphql/bodyshop.queries";
import cleanAxios from "../../utils/CleanAxios";
import client from "../../utils/GraphQLClient"; import client from "../../utils/GraphQLClient";
import dayjs from "../../utils/day"; import dayjs from "../../utils/day";
import InstanceRenderManager from "../../utils/instanceRenderMgr"; import InstanceRenderManager from "../../utils/instanceRenderMgr";
@@ -47,7 +48,6 @@ import {
validatePasswordResetSuccess validatePasswordResetSuccess
} from "./user.actions"; } from "./user.actions";
import UserActionTypes from "./user.types"; import UserActionTypes from "./user.types";
import cleanAxios from "../../utils/CleanAxios";
const fpPromise = FingerprintJS.load(); const fpPromise = FingerprintJS.load();
@@ -234,16 +234,18 @@ export function* signInSuccessSaga({ payload }) {
LogRocket.identify(payload.email); LogRocket.identify(payload.email);
try { try {
window.$crisp.push(["set", "user:nickname", [payload.displayName || payload.email]]);
window.$crisp.push(["set", "session:segments", [["user"]]]);
InstanceRenderManager({ InstanceRenderManager({
executeFunction: true, executeFunction: true,
args: [], args: [],
imex: () => { imex: () => {
window.$crisp.push(["set", "user:nickname", [payload.displayName || payload.email]]); window.$crisp.push(["set", "session:segments", [["imex"]]]);
window.$crisp.push(["set", "session:segments", [["user"]]]);
}, },
rome: () => { rome: () => {
window.$zoho.salesiq.visitor.name(payload.displayName || payload.email); window.$zoho.salesiq.visitor.name(payload.displayName || payload.email);
window.$zoho.salesiq.visitor.email(payload.email); window.$zoho.salesiq.visitor.email(payload.email);
window.$crisp.push(["set", "session:segments", [["rome"]]]);
} }
}); });
} catch (error) { } catch (error) {

View File

@@ -818,6 +818,7 @@ function CalculateTaxesTotals(job, otherTotals) {
PAG: Dinero(), PAG: Dinero(),
PAO: Dinero(), PAO: Dinero(),
PAS: Dinero(), PAS: Dinero(),
PASL: Dinero(),
PAP: Dinero(), PAP: Dinero(),
PAM: Dinero(), PAM: Dinero(),