From 8a4fee7aeadf66dbfa6f142eaa73115c321af3e8 Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Mon, 8 Jul 2024 17:57:26 -0400 Subject: [PATCH] - Daily checkpoint, speed (grid), and presentation Signed-off-by: Dave Richer --- ...production-board-kanban-card.component.jsx | 342 +++++++++--------- .../production-board-kanban.component.jsx | 2 +- .../production-board-kanban.utils.js | 2 +- .../trello-board/controllers/Lane.jsx | 57 ++- client/src/index.jsx | 1 + 5 files changed, 206 insertions(+), 198 deletions(-) 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" ],