Merged in release/2025-08-29 (pull request #2518)

Release/2025 08 29
This commit is contained in:
Dave Richer
2025-08-27 19:27:22 +00:00
47 changed files with 6046 additions and 2150 deletions

View File

@@ -2,7 +2,7 @@ import { FloatButton, Layout, Spin } from "antd";
import { Route, Routes } from "react-router-dom";
// import preval from "preval.macro";
import { lazy, Suspense, useEffect, useState } from "react";
import { lazy, Suspense, useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
@@ -23,6 +23,7 @@ import UpdateAlert from "../../components/update-alert/update-alert.component";
import { selectBodyshop, selectInstanceConflict, selectPartsManagementOnly } from "../../redux/user/user.selectors";
import InstanceRenderManager from "../../utils/instanceRenderMgr.js";
import useAlertsNotifications from "../../hooks/useAlertsNotifications.jsx";
import { selectDarkMode } from "../../redux/application/application.selectors.js";
const PrintCenterModalContainer = lazy(
() => import("../../components/print-center-modal/print-center-modal.container")
@@ -107,22 +108,26 @@ const { Content } = Layout;
const mapStateToProps = createStructuredSelector({
conflict: selectInstanceConflict,
bodyshop: selectBodyshop,
partsManagementOnly: selectPartsManagementOnly
partsManagementOnly: selectPartsManagementOnly,
isDarkMode: selectDarkMode
});
export function Manage({ conflict, bodyshop, partsManagementOnly }) {
export function Manage({ conflict, bodyshop, partsManagementOnly, isDarkMode }) {
const { t } = useTranslation();
const [chatVisible] = useState(false);
const didMount = useRef(false);
// Centralized alerts handling (fetch + dedupe + notifications)
useAlertsNotifications();
useEffect(() => {
if (didMount.current) return; // prevents dev StrictMode double-run
didMount.current = true;
window.Canny("initChangelog", {
appID: "680bd2c7ee501290377f6686",
position: "top",
align: "left",
theme: "light" // options: light [default], dark, auto
theme: !isDarkMode ? "light" : "dark"
});
}, []);

View File

@@ -60,19 +60,19 @@ function SimplifiedPartsJobsDetailContainer({ setBreadcrumbs, addRecentItem, set
imex: "$t(titles.imexonline)",
rome: "$t(titles.romeonline)"
}),
ro_number: (data.jobs_by_pk && data.jobs_by_pk.ro_number) || t("general.labels.na")
ro_number: data.jobs_by_pk?.ro_number || t("general.labels.na")
});
setBreadcrumbs([
{ link: "/parts/", label: t("titles.bc.jobs") },
{ link: "/parts", label: t("titles.bc.parts") },
{
link: `/parts/jobs/${jobId}`,
label: t("titles.bc.jobs-detail", {
number: (data && data.jobs_by_pk && data.jobs_by_pk.ro_number) || t("general.labels.na")
number: (data?.jobs_by_pk && data.jobs_by_pk.ro_number) || t("general.labels.na")
})
}
]);
if (data && data.jobs_by_pk) {
if (data?.jobs_by_pk) {
setJobReadOnly(IsJobReadOnly(data.jobs_by_pk));
addRecentItem(

View File

@@ -22,7 +22,7 @@ export function SimplifiedPartsJobsPage({ setBreadcrumbs, setSelectedHeader }) {
})
});
setSelectedHeader("parts-queue");
setBreadcrumbs([{ link: "/parts", label: t("titles.bc.simplified-parts-jobs") }]);
setBreadcrumbs([{ link: "/parts", label: t("titles.bc.parts") }]);
}, [setBreadcrumbs, t, setSelectedHeader]);
return (

View File

@@ -3,7 +3,7 @@ import { FloatButton, Layout, Spin } from "antd";
import { lazy, Suspense, useEffect } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { Route, Routes } from "react-router-dom";
import { Navigate, Route, Routes, useLocation } from "react-router-dom";
import { createStructuredSelector } from "reselect";
import BreadCrumbs from "../../components/breadcrumbs/breadcrumbs.component.jsx";
import ConflictComponent from "../../components/conflict/conflict.component.jsx";
@@ -39,6 +39,15 @@ const mapStateToProps = createStructuredSelector({
export function SimplifiedPartsPage({ conflict, bodyshop }) {
const { t } = useTranslation();
// Redirector to strip '/parts/jobs' from path for non-detail routes
function JobsStripRedirect() {
// lazy import to avoid top-level import churn
const location = useLocation();
const { pathname, search, hash } = location;
const target = pathname.replace("/parts/jobs", "/parts") + (search || "") + (hash || "");
return <Navigate to={target} replace />;
}
// Centralized alerts handling (fetch + dedupe + notifications)
useAlertsNotifications();
@@ -67,6 +76,10 @@ export function SimplifiedPartsPage({ conflict, bodyshop }) {
<EmailOverlayContainer />
<PrintCenterModalContainer />
<Routes>
{/* Redirect legacy or relative routes that include '/jobs' segment */}
<Route path="jobs" element={<JobsStripRedirect />} />
<Route path="jobs/*" element={<JobsStripRedirect />} />
<Route
path="/"
element={

View File

@@ -42,33 +42,31 @@ export function VehicleDetailContainer({ setBreadcrumbs, addRecentItem, setSelec
imex: "$t(titles.imexonline)",
rome: "$t(titles.romeonline)"
}),
vehicle:
data && data.vehicles_by_pk
? `${(data.vehicles_by_pk && data.vehicles_by_pk.v_model_yr) || ""} ${
(data.vehicles_by_pk && data.vehicles_by_pk.v_make_desc) || ""
} ${(data.vehicles_by_pk && data.vehicles_by_pk.v_model_desc) || ""}`
: ""
vehicle: data?.vehicles_by_pk
? `${data.vehicles_by_pk?.v_model_yr || ""} ${
data.vehicles_by_pk?.v_make_desc || ""
} ${data.vehicles_by_pk?.v_model_desc || ""}`
: ""
});
setSelectedHeader("vehicles");
const crumbs = [];
if (isPartsEntry) crumbs.push({ link: "/parts/", label: t("titles.bc.jobs") });
if (isPartsEntry) crumbs.push({ link: "/parts", label: t("titles.bc.parts") });
crumbs.push({ link: `${basePath}/vehicles`, label: t("titles.bc.vehicles") });
crumbs.push({
link: `${basePath}/vehicles/${vehId}`,
label: t("titles.bc.vehicle-details", {
vehicle:
data && data.vehicles_by_pk
? `${(data.vehicles_by_pk && data.vehicles_by_pk.v_model_yr) || ""} ${
(data.vehicles_by_pk && data.vehicles_by_pk.v_make_desc) || ""
} ${(data.vehicles_by_pk && data.vehicles_by_pk.v_model_desc) || ""}`
: ""
vehicle: data?.vehicles_by_pk
? `${data.vehicles_by_pk?.v_model_yr || ""} ${
data.vehicles_by_pk?.v_make_desc || ""
} ${data.vehicles_by_pk?.v_model_desc || ""}`
: ""
})
});
setBreadcrumbs(crumbs);
if (data && data.vehicles_by_pk)
if (data?.vehicles_by_pk)
addRecentItem(
CreateRecentItem(
vehId,

View File

@@ -33,7 +33,7 @@ export function VehiclesPageContainer({ setBreadcrumbs, setSelectedHeader, isPar
if (isPartsEntry) {
setBreadcrumbs([
{ link: "/parts/", label: t("titles.bc.jobs") },
{ link: "/parts", label: t("titles.bc.parts") },
{ link: `${basePath}/vehicles`, label: t("titles.bc.vehicles") }
]);
} else {