diff --git a/client/src/components/production-board-kanban-card/production-board-kanban-card.component.jsx b/client/src/components/production-board-kanban-card/production-board-kanban-card.component.jsx
index 6ad15a466..4f45b274d 100644
--- a/client/src/components/production-board-kanban-card/production-board-kanban-card.component.jsx
+++ b/client/src/components/production-board-kanban-card/production-board-kanban-card.component.jsx
@@ -28,26 +28,28 @@ const cardColor = (ssbuckets, totalHrs) => {
const getContrastYIQ = (bgColor) =>
(bgColor.r * 299 + bgColor.g * 587 + bgColor.b * 114) / 1000 >= 128 ? "black" : "white";
-export default function ProductionBoardCard({ technician, card, bodyshop, cardSettings, clone, style }) {
+const findEmployeeById = (employees, id) => employees.find((e) => e.id === id);
+
+const EllipsesToolTip = React.memo(({ title, children }) => (
+
+ {children}
+
+));
+
+export default function ProductionBoardCard({ technician, card, bodyshop, cardSettings, clone }) {
const { t } = useTranslation();
const { metadata } = card;
- const employee_body = useMemo(
- () => metadata?.employee_body && bodyshop.employees.find((e) => e.id === metadata.employee_body),
- [metadata?.employee_body, bodyshop.employees]
- );
- const employee_prep = useMemo(
- () => metadata?.employee_prep && bodyshop.employees.find((e) => e.id === metadata.employee_prep),
- [metadata?.employee_prep, bodyshop.employees]
- );
- const employee_refinish = useMemo(
- () => metadata?.employee_refinish && bodyshop.employees.find((e) => e.id === metadata.employee_refinish),
- [metadata?.employee_refinish, bodyshop.employees]
- );
- const employee_csr = useMemo(
- () => metadata?.employee_csr && bodyshop.employees.find((e) => e.id === metadata.employee_csr),
- [metadata?.employee_csr, bodyshop.employees]
- );
+ const employees = useMemo(() => bodyshop.employees, [bodyshop.employees]);
+
+ const { employee_body, employee_prep, employee_refinish, employee_csr } = useMemo(() => {
+ return {
+ employee_body: metadata?.employee_body && findEmployeeById(employees, metadata.employee_body),
+ employee_prep: metadata?.employee_prep && findEmployeeById(employees, metadata.employee_prep),
+ employee_refinish: metadata?.employee_refinish && findEmployeeById(employees, metadata.employee_refinish),
+ employee_csr: metadata?.employee_csr && findEmployeeById(employees, metadata.employee_csr)
+ };
+ }, [metadata, employees]);
const pastDueAlert = useMemo(() => {
if (!metadata?.scheduled_completion) return null;
@@ -66,162 +68,176 @@ export default function ProductionBoardCard({ technician, card, bodyshop, cardSe
const bgColor = useMemo(() => cardColor(bodyshop.ssbuckets, totalHrs), [bodyshop.ssbuckets, totalHrs]);
const contrastYIQ = useMemo(() => getContrastYIQ(bgColor), [bgColor]);
+ const headerContent = (
+
+
+ {metadata?.suspended && }
+ {metadata?.iouparent && (
+
+
+
+ )}
+
+
+ {metadata?.ro_number || t("general.labels.na")}
+
+
+
+ );
+
+ const bodyContent = (
+
+ {cardSettings?.ownr_nm && (
+
+
+ {cardSettings.compact ? (
+ `${metadata.ownr_ln || ""} ${metadata.ownr_co_nm || ""}`
+ ) : (
+
+ )}
+
+
+ )}
+ {cardSettings?.model_info && (
+
+
+ {`${metadata.v_model_yr || ""} ${metadata.v_make_desc || ""} ${metadata.v_model_desc || ""}`}
+
+
+ )}
+ {cardSettings?.ins_co_nm && metadata.ins_co_nm && (
+
+ {metadata.ins_co_nm || ""}
+
+ )}
+ {cardSettings?.clm_no && metadata.clm_no && (
+
+ {metadata.clm_no || ""}
+
+ )}
+ {cardSettings?.employeeassignments && (
+
+
+
+
+ {`B: ${employee_body ? `${employee_body.first_name.substr(0, 3)} ${employee_body.last_name.charAt(0)}` : ""} ${metadata.labhrs.aggregate.sum.mod_lb_hrs || "?"}h`}
+
+
+
+
+ {`P: ${employee_prep ? `${employee_prep.first_name.substring(0, 3)} ${employee_prep.last_name.charAt(0)}` : ""}`}
+
+
+
+
+ {`R: ${employee_refinish ? `${employee_refinish.first_name.substring(0, 3)} ${employee_refinish.last_name.charAt(0)}` : ""} ${metadata.larhrs.aggregate.sum.mod_lb_hrs || "?"}h`}
+
+
+
+
+ {`C: ${employee_csr ? `${employee_csr.first_name} ${employee_csr.last_name}` : ""}`}
+
+
+
+
+ )}
+ {cardSettings?.actual_in && metadata.actual_in && (
+
+
+
+
+ {metadata.actual_in}
+
+
+
+ )}
+ {cardSettings?.scheduled_completion && metadata.scheduled_completion && (
+
+
+
+
+ {metadata.scheduled_completion}
+
+
+
+ )}
+ {cardSettings?.ats && metadata.alt_transport && (
+
+ {metadata.alt_transport || ""}
+
+ )}
+ {cardSettings?.sublets && (
+
+
+
+ )}
+ {cardSettings?.production_note && (
+
+
+
+ )}
+ {cardSettings?.partsstatus && (
+
+
+
+ )}
+
+ );
+
+ const isBodyEmpty = !(
+ cardSettings?.ownr_nm ||
+ cardSettings?.model_info ||
+ (cardSettings?.ins_co_nm && metadata.ins_co_nm) ||
+ (cardSettings?.clm_no && metadata.clm_no) ||
+ cardSettings?.employeeassignments ||
+ (cardSettings?.actual_in && metadata.actual_in) ||
+ (cardSettings?.scheduled_completion && metadata.scheduled_completion) ||
+ (cardSettings?.ats && metadata.alt_transport) ||
+ cardSettings?.sublets ||
+ cardSettings?.production_note ||
+ cardSettings?.partsstatus
+ );
return (
-
- {metadata?.suspended && }
- {metadata?.iouparent && (
-
-
-
- )}
-
-
- {metadata?.ro_number || t("general.labels.na")}
-
-
-
- }
+ title={isBodyEmpty ? null : headerContent}
extra={
-
-
-
+ !isBodyEmpty && (
+
+
+
+ )
}
>
-
- {cardSettings?.ownr_nm && (
-
-
- {cardSettings.compact ? (
- {`${metadata.ownr_ln || ""} ${metadata.ownr_co_nm || ""}`}
- ) : (
-
-
-
- )}
-
-
- )}
- {cardSettings?.model_info && (
-
-
- {`${metadata.v_model_yr || ""} ${metadata.v_make_desc || ""} ${metadata.v_model_desc || ""}`}
-
-
- )}
- {cardSettings?.ins_co_nm && metadata.ins_co_nm && (
-
-
- {metadata.ins_co_nm || ""}
-
-
- )}
- {cardSettings?.clm_no && metadata.clm_no && (
-
-
- {metadata.clm_no || ""}
-
-
- )}
- {cardSettings?.employeeassignments && (
-
-
-
-
- {`B: ${employee_body ? `${employee_body.first_name.substr(0, 3)} ${employee_body.last_name.charAt(0)}` : ""} ${metadata.labhrs.aggregate.sum.mod_lb_hrs || "?"}h`}
-
-
-
-
- {`P: ${employee_prep ? `${employee_prep.first_name.substring(0, 3)} ${employee_prep.last_name.charAt(0)}` : ""}`}
-
-
-
-
- {`R: ${employee_refinish ? `${employee_refinish.first_name.substring(0, 3)} ${employee_refinish.last_name.charAt(0)}` : ""} ${metadata.larhrs.aggregate.sum.mod_lb_hrs || "?"}h`}
-
-
-
-
- {`C: ${employee_csr ? `${employee_csr.first_name} ${employee_csr.last_name}` : ""}`}
-
-
-
-
- )}
- {cardSettings?.actual_in && metadata.actual_in && (
-
-
-
-
- {metadata.actual_in}
-
-
-
- )}
- {cardSettings?.scheduled_completion && metadata.scheduled_completion && (
-
-
-
-
- {metadata.scheduled_completion}
-
-
-
- )}
- {cardSettings?.ats && metadata.alt_transport && (
-
-
- {metadata.alt_transport || ""}
-
-
- )}
- {cardSettings?.sublets && (
-
-
-
- )}
- {cardSettings?.production_note && (
-
-
-
- )}
- {cardSettings?.partsstatus && (
-
-
-
- )}
-
+ {isBodyEmpty ? headerContent : bodyContent}
);
}
diff --git a/client/src/components/production-board-kanban/production-board-kanban.component.jsx b/client/src/components/production-board-kanban/production-board-kanban.component.jsx
index eac2f1849..069104924 100644
--- a/client/src/components/production-board-kanban/production-board-kanban.component.jsx
+++ b/client/src/components/production-board-kanban/production-board-kanban.component.jsx
@@ -17,7 +17,7 @@ import ProductionBoardFilters from "../production-board-filters/production-board
import ProductionListDetailComponent from "../production-list-detail/production-list-detail.component";
import CardColorLegend from "../production-board-kanban-card/production-board-kanban-card-color-legend.component";
import "./production-board-kanban.styles.scss";
-import { createBoardData } from "./production-board-kanban.utils.js";
+import { createBoardData, createFakeBoardData } from "./production-board-kanban.utils.js";
import ProductionBoardKanbanSettings from "./production-board-kanban.settings.component.jsx";
import cloneDeep from "lodash/cloneDeep";
import isEqual from "lodash/isEqual";
diff --git a/client/src/components/production-board-kanban/production-board-kanban.utils.js b/client/src/components/production-board-kanban/production-board-kanban.utils.js
index a10446928..61519d007 100644
--- a/client/src/components/production-board-kanban/production-board-kanban.utils.js
+++ b/client/src/components/production-board-kanban/production-board-kanban.utils.js
@@ -1,5 +1,5 @@
import { groupBy } from "lodash";
-import fakeData from "./testData/board600.json";
+import fakeData from "./testData/board1200.json";
const sortByParentId = (arr) => {
// return arr.reduce((accumulator, currentValue) => {
diff --git a/client/src/components/production-board-kanban/trello-board/controllers/Lane.jsx b/client/src/components/production-board-kanban/trello-board/controllers/Lane.jsx
index 83e5a5ec0..153ea0629 100644
--- a/client/src/components/production-board-kanban/trello-board/controllers/Lane.jsx
+++ b/client/src/components/production-board-kanban/trello-board/controllers/Lane.jsx
@@ -1,4 +1,4 @@
-import React, { forwardRef, useCallback, useEffect, useMemo, useState } from "react";
+import React, { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from "react";
import PropTypes from "prop-types";
import { bindActionCreators } from "redux";
import { connect } from "react-redux";
@@ -16,6 +16,24 @@ import ProductionBoardCard from "../../../production-board-kanban-card/productio
import HeightMemoryWrapper from "../components/Lane/HeightMemoryWrapper.jsx";
import SizeMemoryWrapper from "../components/Lane/SizeMemoryWrapper.jsx";
+const ListComponent = forwardRef(({ style, children, ...props }, ref) => (
+
+ {children}
+
+));
+
+const ItemComponent = ({ children, maxCardHeight, maxCardWidth, ...props }) => (
+
+ {children}
+
+);
+
+const ItemWrapper = React.memo(({ children, ...props }) => (
+
+ {children}
+
+));
+
/**
* Lane is a React component that represents a lane in a Trello-like board.
* @param id
@@ -57,6 +75,7 @@ const Lane = ({
}) => {
const [collapsed, setCollapsed] = useState(false);
const [isVisible, setIsVisible] = useState(true);
+ const laneRef = useRef(null);
useEffect(() => {
setIsVisible(false);
@@ -115,15 +134,6 @@ const Lane = ({
[isProcessing, technician, bodyshop, cardSettings, maxCardHeight, setMaxCardHeight, maxCardWidth, setMaxCardWidth]
);
- const ItemWrapper = useCallback(
- ({ children, ...props }) => (
-
- {children}
-
- ),
- []
- );
-
const renderDroppable = useCallback(
(provided, renderedCards) => {
const Component = orientation === "vertical" ? VirtuosoGrid : Virtuoso;
@@ -137,17 +147,10 @@ const Lane = ({
...commonProps,
listClassName: "grid-container",
itemClassName: "grid-item",
+ customScrollParent: laneRef.current,
components: {
- List: forwardRef(({ style, children, ...props }, ref) => (
-
- {children}
-
- )),
- Item: ({ children, ...props }) => (
-
- {children}
-
- )
+ List: ListComponent,
+ Item: ItemComponent
},
itemContent: (index, item) => {renderDraggable(index, item)},
overscan: { main: 10, reverse: 10 }
@@ -200,7 +203,7 @@ const Lane = ({
);
},
- [orientation, collapsed, isVisible, renderDraggable, maxLaneHeight, setMaxLaneHeight, maxCardHeight, maxCardWidth]
+ [orientation, collapsed, isVisible, renderDraggable, maxLaneHeight, setMaxLaneHeight, maxCardWidth]
);
const renderDragContainer = useCallback(
@@ -226,27 +229,15 @@ const Lane = ({
className={`clone ${snapshot.isDragging ? "is-dragging" : ""}`}
key={card.id}
>
- {/**/}
- {/**/}
);
}}
diff --git a/client/src/index.jsx b/client/src/index.jsx
index 1853f31fd..a5a4149cb 100644
--- a/client/src/index.jsx
+++ b/client/src/index.jsx
@@ -37,6 +37,7 @@ if (import.meta.env.PROD) {
ignoreErrors: [
"ResizeObserver loop",
+ "ResizeObserver loop limit exceeded",
"Module specifier, 'fs' does not start",
"Module specifier, 'zlib' does not start with"
],