@@ -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"
|
||||
});
|
||||
}, []);
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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={
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user