Compare commits

..

1 Commits

Author SHA1 Message Date
Allan Carr
b2239351f6 IO-2952 RBAC Defaults
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-01-20 15:11:13 -08:00
10 changed files with 50 additions and 84 deletions

View File

@@ -62,17 +62,7 @@
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,19 +133,15 @@ 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);
pollForIntelliPay(() => { SetIntellipayCallbackFunctions();
SetIntellipayCallbackFunctions(); window.intellipay.autoOpen();
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);
pollForIntelliPay(() => { SetIntellipayCallbackFunctions();
SetIntellipayCallbackFunctions(); window.intellipay.isAutoOpen = true;
window.intellipay.isAutoOpen = true; window.intellipay.initialize();
window.intellipay.initialize();
});
} }
} catch (error) { } catch (error) {
notification.open({ notification.open({
@@ -349,27 +345,3 @@ 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,23 +38,28 @@ class ErrorBoundary extends React.Component {
} }
handleErrorSubmit = () => { handleErrorSubmit = () => {
window.$crisp.push([ InstanceRenderManager({
"do", executeFunction: true,
"message:send", args: [],
[ imex: () => {
"text", window.$crisp.push([
`I hit the following error: \n\n "do",
"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,7 +650,14 @@ function Header({
icon: <Icon component={QuestionCircleFilled} />, icon: <Icon component={QuestionCircleFilled} />,
label: t("menus.header.help"), label: t("menus.header.help"),
onClick: () => { onClick: () => {
window.open("https://help.imex.online/", "_blank"); window.open(
InstanceRenderManager({
imex: "https://help.imex.online/",
rome: "https://rometech.com//"
}),
"_blank"
);
} }
}, },
...(InstanceRenderManager({ ...(InstanceRenderManager({

View File

@@ -1,8 +1,7 @@
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 { some } from "lodash"; import React, { useState } from "react";
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";
@@ -19,14 +18,7 @@ const mapStateToProps = createStructuredSelector({
jobRO: selectJobReadOnly jobRO: selectJobReadOnly
}); });
const mapDispatchToProps = (dispatch) => ({ const mapDispatchToProps = (dispatch) => ({
insertAuditTrail: ({ jobid, operation, type }) => insertAuditTrail: ({ jobid, operation, type }) => dispatch(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 }) {
@@ -35,7 +27,6 @@ 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()) {
@@ -78,8 +69,6 @@ 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
@@ -88,12 +77,9 @@ export function JobsConvertButton({ bodyshop, job, refetch, jobRO, insertAuditTr
onFinish={handleConvert} onFinish={handleConvert}
initialValues={{ initialValues={{
driveable: true, driveable: true,
towin: job.towin, towin: false,
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
@@ -223,7 +209,7 @@ export function JobsConvertButton({ bodyshop, job, refetch, jobRO, insertAuditTr
<Switch /> <Switch />
</Form.Item> </Form.Item>
<Space wrap> <Space wrap>
<Button disabled={submitDisabled()} type="primary" danger onClick={() => form.submit()} loading={loading}> <Button 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>
@@ -245,6 +231,11 @@ 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

@@ -35,6 +35,7 @@ const ret = {
"bills:reexport": 3, "bills:reexport": 3,
"employees:page": 5, "employees:page": 5,
"employee_teams:page": 5,
"owners:list": 2, "owners:list": 2,
"owners:detail": 3, "owners:detail": 3,
@@ -67,6 +68,9 @@ const ret = {
"timetickets:list": 3, "timetickets:list": 3,
"timetickets:edit": 4, "timetickets:edit": 4,
"timetickets:shiftedit": 5, "timetickets:shiftedit": 5,
"timetickets:editcommitted": 5,
"ttapprovals:view": 5,
"ttapprovals:approve": 5,
"users:editaccess": 4, "users:editaccess": 4,

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.jsx") () => import("../../components/card-payment-modal/card-payment-modal.container.")
); );
const JobsDetailPage = lazy(() => import("../jobs-detail/jobs-detail.page.container")); const JobsDetailPage = lazy(() => import("../jobs-detail/jobs-detail.page.container"));

View File

@@ -26,7 +26,6 @@ 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";
@@ -48,6 +47,7 @@ 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,18 +234,16 @@ 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", "session:segments", [["imex"]]]); window.$crisp.push(["set", "user:nickname", [payload.displayName || payload.email]]);
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,7 +818,6 @@ 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(),