Merged in release/2025-10-17 (pull request #2633)

Release/2025 10 17  into Master-AIO - IO-3373 - IO-3404 - IO-3385
This commit is contained in:
Dave Richer
2025-10-17 18:59:37 +00:00
5 changed files with 77 additions and 43 deletions

View File

@@ -12,6 +12,7 @@ import GlobalLoadingBar from "../components/global-loading-bar/global-loading-ba
import { setDarkMode } from "../redux/application/application.actions";
import { selectDarkMode } from "../redux/application/application.selectors";
import { selectCurrentUser } from "../redux/user/user.selectors.js";
import { signOutStart } from "../redux/user/user.actions";
import client from "../utils/GraphQLClient";
import App from "./App";
import getTheme from "./themeProvider";
@@ -20,14 +21,13 @@ import getTheme from "./themeProvider";
const config = {
core: {
authorizationKey: import.meta.env.VITE_APP_SPLIT_API,
key: "anon" // Default key, overridden dynamically by SplitClientProvider
key: "anon"
}
};
// Custom provider to manage the Split client key based on imexshopid from Redux
function SplitClientProvider({ children }) {
const imexshopid = useSelector((state) => state.user.imexshopid); // Access imexshopid from Redux store
const splitClient = useSplitClient({ key: imexshopid || "anon" }); // Use imexshopid or fallback to "anon"
const imexshopid = useSelector((state) => state.user.imexshopid);
const splitClient = useSplitClient({ key: imexshopid || "anon" });
useEffect(() => {
if (splitClient && imexshopid) {
console.log(`Split client initialized with key: ${imexshopid}, isReady: ${splitClient.isReady}`);
@@ -36,40 +36,66 @@ function SplitClientProvider({ children }) {
return children;
}
const mapDispatchToProps = (dispatch) => ({
setDarkMode: (isDarkMode) => dispatch(setDarkMode(isDarkMode))
});
const mapStateToProps = createStructuredSelector({
currentUser: selectCurrentUser
});
function AppContainer({ currentUser, setDarkMode }) {
const mapDispatchToProps = (dispatch) => ({
setDarkMode: (isDarkMode) => dispatch(setDarkMode(isDarkMode)),
signOutStart: () => dispatch(signOutStart())
});
function AppContainer({ currentUser, setDarkMode, signOutStart }) {
const { t } = useTranslation();
const isDarkMode = useSelector(selectDarkMode);
const theme = useMemo(() => getTheme(isDarkMode), [isDarkMode]);
// Update data-theme attribute when dark mode changes
// Global seamless logout listener with redirect to /signin
useEffect(() => {
const handleSeamlessLogout = (event) => {
if (event.data?.type !== "seamlessLogoutRequest") return;
const requestOrigin = event.origin;
if (currentUser?.authorized !== true) {
window.parent.postMessage(
{ type: "seamlessLogoutResponse", status: "already_logged_out" },
requestOrigin || "*"
);
return;
}
signOutStart();
window.parent.postMessage({ type: "seamlessLogoutResponse", status: "logged_out" }, requestOrigin || "*");
};
window.addEventListener("message", handleSeamlessLogout);
return () => {
window.removeEventListener("message", handleSeamlessLogout);
};
}, [signOutStart, currentUser]);
// Update data-theme attribute
useEffect(() => {
document.documentElement.setAttribute("data-theme", isDarkMode ? "dark" : "light");
return () => document.documentElement.removeAttribute("data-theme");
}, [isDarkMode]);
// Sync Redux darkMode with localStorage on user change
// Sync darkMode with localStorage
useEffect(() => {
if (currentUser?.uid) {
const savedMode = localStorage.getItem(`dark-mode-${currentUser.uid}`);
if (savedMode !== null) {
setDarkMode(JSON.parse(savedMode));
} else {
setDarkMode(false); // default to light mode
setDarkMode(false);
}
} else {
setDarkMode(false);
}
}, [currentUser?.uid]);
}, [currentUser?.uid, setDarkMode]);
// Persist darkMode to localStorage when it or user changes
// Persist darkMode
useEffect(() => {
if (currentUser?.uid) {
localStorage.setItem(`dark-mode-${currentUser.uid}`, JSON.stringify(isDarkMode));

View File

@@ -196,7 +196,7 @@ export function DashboardGridComponent({ currentUser }) {
<PageHeader
extra={
<Space>
<Button onClick={refetch}>
<Button onClick={() => refetch()}>
<SyncOutlined />
</Button>
<Dropdown menu={menu} trigger={["click"]}>

View File

@@ -15,21 +15,29 @@ export const EmailSettings = {
export const TemplateList = (type, context) => {
//const { bodyshop } = store.getState().user;
const casl = InstanceRenderManager({
imex: {
casl_authorization: {
title: i18n.t("printcenter.jobs.casl_authorization"),
description: "",
subject: i18n.t("printcenter.jobs.casl_authorization"),
key: "casl_authorization",
disabled: false,
group: "authorization",
regions: {
CA: true
}
}
},
rome: {}
});
return {
//If there's no type or the type is job, send it back.
...(!type || type === "job"
? {
casl_authorization: {
title: i18n.t("printcenter.jobs.casl_authorization"),
description: "",
subject: i18n.t("printcenter.jobs.casl_authorization"),
key: "casl_authorization",
disabled: false,
group: "authorization",
regions: {
CA: true
}
},
...casl,
fippa_authorization: {
title: i18n.t("printcenter.jobs.fippa_authorization"),
description: "",

View File

@@ -24,7 +24,7 @@ exports.totalsSsu = async function (req, res) {
const BearerToken = req.BearerToken;
const client = req.userGraphQLClient;
logger.log("job-totals-ssu-USA", "DEBUG", req?.user?.email, id);
logger.log("job-totals-ssu-USA", "debug", req?.user?.email, id);
try {
const job = await client.setHeaders({ Authorization: BearerToken }).request(queries.GET_JOB_BY_PK, {
@@ -49,7 +49,7 @@ exports.totalsSsu = async function (req, res) {
res.status(200).send();
} catch (error) {
logger.log("job-totals-ssu-USA-error", "ERROR", req?.user?.email, id, {
logger.log("job-totals-ssu-USA-error", "error", req?.user?.email, id, {
jobid: id,
error: error.message,
stack: error.stack
@@ -95,7 +95,7 @@ async function TotalsServerSide(req, res) {
ret.totals.subtotal = ret.totals.subtotal.add(ret.totals.ttl_adjustment);
ret.totals.total_repairs = ret.totals.total_repairs.add(ret.totals.ttl_adjustment);
ret.totals.net_repairs = ret.totals.net_repairs.add(ret.totals.ttl_adjustment);
logger.log("job-totals-USA-ttl-adj", "DEBUG", null, job.id, {
logger.log("job-totals-USA-ttl-adj", "debug", null, job.id, {
adjAmount: ttlDifference
});
}
@@ -116,7 +116,7 @@ async function TotalsServerSide(req, res) {
ret.totals.ttl_tax_adjustment = Dinero({ amount: Math.round(ttlTaxDifference * 100) });
ret.totals.total_repairs = ret.totals.total_repairs.add(ret.totals.ttl_tax_adjustment);
ret.totals.net_repairs = ret.totals.net_repairs.add(ret.totals.ttl_tax_adjustment);
logger.log("job-totals-USA-ttl-tax-adj", "DEBUG", null, job.id, {
logger.log("job-totals-USA-ttl-tax-adj", "debug", null, job.id, {
adjAmount: ttlTaxDifference
});
}
@@ -124,7 +124,7 @@ async function TotalsServerSide(req, res) {
return ret;
} catch (error) {
logger.log("job-totals-ssu-USA-error", "ERROR", req.user?.email, job.id, {
logger.log("job-totals-ssu-USA-error", "error", req.user?.email, job.id, {
jobid: job.id,
error: error.message,
stack: error.stack
@@ -142,7 +142,7 @@ async function Totals(req, res) {
const logger = req.logger;
const client = req.userGraphQLClient;
logger.log("job-totals-ssu-USA", "DEBUG", req.user.email, job.id, {
logger.log("job-totals-ssu-USA", "debug", req.user.email, job.id, {
jobid: job.id,
id: id
});
@@ -159,7 +159,7 @@ async function Totals(req, res) {
res.status(200).json(ret);
} catch (error) {
logger.log("job-totals-ssu-USA-error", "ERROR", req.user.email, job.id, {
logger.log("job-totals-ssu-USA-error", "error", req.user.email, job.id, {
jobid: job.id,
error: error.message,
stack: error.stack
@@ -240,7 +240,7 @@ async function AtsAdjustmentsIfRequired({ job, client, user }) {
job.joblines.push(newAtsLine);
}
} catch (error) {
logger.log("job-totals-ssu-ats-error", "ERROR", user?.email, job.id, {
logger.log("job-totals-ssu-ats-error", "error", user?.email, job.id, {
jobid: job.id,
error: error.message,
stack: error.stack
@@ -258,7 +258,7 @@ async function AtsAdjustmentsIfRequired({ job, client, user }) {
job.joblines[atsLineIndex].act_price = atsAmount;
}
} catch (error) {
logger.log("job-totals-ssu-ats-error", "ERROR", user?.email, job.id, {
logger.log("job-totals-ssu-ats-error", "error", user?.email, job.id, {
jobid: job.id,
atsLineIndex: atsLineIndex,
atsAmount: atsAmount,
@@ -1055,7 +1055,7 @@ function CalculateTaxesTotals(job, otherTotals) {
}
}
} catch (error) {
logger.log("job-totals-USA Key with issue", "error", null, job.id, {
logger.log("job-totals-USA Key with issue", "warn", null, job.id, {
key: key,
error: error.message,
stack: error.stack

View File

@@ -23,7 +23,7 @@ exports.totalsSsu = async function (req, res) {
const BearerToken = req.BearerToken;
const client = req.userGraphQLClient;
logger.log("job-totals-ssu", "DEBUG", req.user.email, id, null);
logger.log("job-totals-ssu", "debug", req.user.email, id, null);
try {
const job = await client.setHeaders({ Authorization: BearerToken }).request(queries.GET_JOB_BY_PK, {
@@ -49,7 +49,7 @@ exports.totalsSsu = async function (req, res) {
res.status(200).send();
} catch (error) {
logger.log("job-totals-ssu-error", "ERROR", req.user.email, id, {
logger.log("job-totals-ssu-error", "error", req.user.email, id, {
jobid: id,
error: error.message,
stack: error.stack
@@ -73,7 +73,7 @@ async function TotalsServerSide(req, res) {
return ret;
} catch (error) {
logger.log("job-totals-ssu-error", "ERROR", req?.user?.email, job.id, {
logger.log("job-totals-ssu-error", "error", req?.user?.email, job.id, {
jobid: job.id,
error: error.message,
stack: error.stack
@@ -91,7 +91,7 @@ async function Totals(req, res) {
const logger = req.logger;
const client = req.userGraphQLClient;
logger.log("job-totals-ssu", "DEBUG", req.user.email, job.id, {
logger.log("job-totals-ssu", "debug", req.user.email, job.id, {
jobid: job.id,
id: id
});
@@ -108,7 +108,7 @@ async function Totals(req, res) {
res.status(200).json(ret);
} catch (error) {
logger.log("job-totals-ssu-error", "ERROR", req.user.email, job.id, {
logger.log("job-totals-ssu-error", "error", req.user.email, job.id, {
jobid: job.id,
error: error.message,
stack: error.stack
@@ -189,7 +189,7 @@ async function AtsAdjustmentsIfRequired({ job, client, user }) {
job.joblines.push(newAtsLine);
}
} catch (error) {
logger.log("job-totals-ssu-ats-error", "ERROR", user?.email, job.id, {
logger.log("job-totals-ssu-ats-error", "error", user?.email, job.id, {
jobid: job.id,
error: error.message,
stack: error.stack
@@ -207,7 +207,7 @@ async function AtsAdjustmentsIfRequired({ job, client, user }) {
job.joblines[atsLineIndex].act_price = atsAmount;
}
} catch (error) {
logger.log("job-totals-ssu-ats-error", "ERROR", user?.email, job.id, {
logger.log("job-totals-ssu-ats-error", "error", user?.email, job.id, {
jobid: job.id,
atsLineIndex: atsLineIndex,
atsAmount: atsAmount,