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 5362f8dab..c6c276ea7 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 @@ -6,7 +6,7 @@ import { PauseCircleOutlined } from "@ant-design/icons"; import { Card, Col, Row, Space, Tooltip } from "antd"; -import React from "react"; +import React, { useMemo } from "react"; import { useTranslation } from "react-i18next"; import { Link } from "react-router-dom"; import { DateTimeFormatter } from "../../utils/DateFormatter"; @@ -18,60 +18,78 @@ import dayjs from "../../utils/day"; import OwnerNameDisplay from "../owner-name-display/owner-name-display.component"; import JobPartsQueueCount from "../job-parts-queue-count/job-parts-queue-count.component"; +/** + * Get the color of the card based on the total hours + * @param ssbuckets + * @param totalHrs + * @returns {{r: number, b: number, g: number}} + */ const cardColor = (ssbuckets, totalHrs) => { - const bucket = ssbuckets.filter((bucket) => bucket.gte <= totalHrs && (!!bucket.lt ? bucket.lt > totalHrs : true))[0]; + const bucket = ssbuckets.find((bucket) => bucket.gte <= totalHrs && (!bucket.lt || bucket.lt > totalHrs)); let color = { r: 255, g: 255, b: 255 }; if (bucket && bucket.color) { - color = bucket.color; - - if (bucket.color.rgb) { - color = bucket.color.rgb; - } + color = bucket.color.rgb || bucket.color; } return color; }; -function getContrastYIQ(bgColor) { - const yiq = (bgColor.r * 299 + bgColor.g * 587 + bgColor.b * 114) / 1000; - - return yiq >= 128 ? "black" : "white"; -} +/** + * Get the contrast color based on the background color + * @param bgColor + * @returns {string} + */ +const getContrastYIQ = (bgColor) => + (bgColor.r * 299 + bgColor.g * 587 + bgColor.b * 114) / 1000 >= 128 ? "black" : "white"; +/** + * Production Board Card component + * @param technician + * @param card + * @param bodyshop + * @param cardSettings + * @returns {Element} + * @constructor + */ export default function ProductionBoardCard({ technician, card, bodyshop, cardSettings }) { const { t } = useTranslation(); let employee_body, employee_prep, employee_refinish, employee_csr; - if (card && card.metadata && card.metadata.employee_body) { - employee_body = bodyshop.employees.find((e) => e.id === card.metadata.employee_body); + // Destructure metadata + const { metadata } = card; + + if (metadata?.employee_body) { + employee_body = bodyshop.employees.find((e) => e.id === metadata.employee_body); } - if (card && card.metadata && card.metadata.employee_prep) { - employee_prep = bodyshop.employees.find((e) => e.id === card.metadata.employee_prep); + if (metadata?.employee_prep) { + employee_prep = bodyshop.employees.find((e) => e.id === metadata.employee_prep); } - if (card && card.metadata && card.metadata.employee_refinish) { - employee_refinish = bodyshop.employees.find((e) => e.id === card.metadata.employee_refinish); + if (metadata?.employee_refinish) { + employee_refinish = bodyshop.employees.find((e) => e.id === metadata.employee_refinish); } - if (card && card.metadata && card.metadata.employee_csr) { - employee_csr = bodyshop.employees.find((e) => e.id === card.metadata.employee_csr); + if (metadata?.employee_csr) { + employee_csr = bodyshop.employees.find((e) => e.id === metadata.employee_csr); } - // if (card && card.metadata && card.metadata.employee_csr) { - // employee_csr = bodyshop.employees.find((e) => e.id === card.metadata.employee_csr); + // if (metadata.?employee_csr) { + // employee_csr = bodyshop.employees.find((e) => e.id === metadata.employee_csr); // } const pastDueAlert = - !!card?.metadata?.scheduled_completion && - ((dayjs().isSameOrAfter(dayjs(card.metadata.scheduled_completion), "day") && "production-completion-past") || - (dayjs().add(1, "day").isSame(dayjs(card.metadata.scheduled_completion), "day") && "production-completion-soon")); + !!metadata?.scheduled_completion && + ((dayjs().isSameOrAfter(dayjs(metadata.scheduled_completion), "day") && "production-completion-past") || + (dayjs().add(1, "day").isSame(dayjs(metadata.scheduled_completion), "day") && "production-completion-soon")); - const totalHrs = - card && card?.metadata?.labhrs && card?.metadata?.larhrs - ? card.metadata.labhrs.aggregate.sum.mod_lb_hrs + card.metadata.larhrs.aggregate.sum.mod_lb_hrs + const totalHrs = useMemo(() => { + return metadata?.labhrs && metadata?.larhrs + ? metadata.labhrs.aggregate.sum.mod_lb_hrs + metadata.larhrs.aggregate.sum.mod_lb_hrs : 0; + }, [metadata]); - const bgColor = cardColor(bodyshop.ssbuckets, totalHrs); + const bgColor = useMemo(() => cardColor(bodyshop.ssbuckets, totalHrs), [bodyshop.ssbuckets, totalHrs]); + const contrastYIQ = useMemo(() => getContrastYIQ(bgColor), [bgColor]); return ( - {card.metadata.suspended && } - {card.metadata.iouparent && ( + {metadata?.suspended && } + {metadata?.iouparent && ( )} - {card.metadata.ro_number || t("general.labels.na")} + {metadata?.ro_number || t("general.labels.na")} @@ -110,7 +128,7 @@ export default function ProductionBoardCard({ technician, card, bodyshop, cardSe {cardSettings && cardSettings.ownr_nm && ( {cardSettings && cardSettings.compact ? ( -
{`${card.metadata.ownr_ln || ""} ${card.metadata.ownr_co_nm || ""}`}
+
{`${metadata.ownr_ln || ""} ${metadata.ownr_co_nm || ""}`}
) : (
@@ -119,18 +137,18 @@ export default function ProductionBoardCard({ technician, card, bodyshop, cardSe )} -
{`${card.metadata.v_model_yr || ""} ${ - card.metadata.v_make_desc || "" - } ${card.metadata.v_model_desc || ""}`}
+
{`${metadata.v_model_yr || ""} ${ + metadata.v_make_desc || "" + } ${metadata.v_model_desc || ""}`}
- {cardSettings && cardSettings.ins_co_nm && card.metadata.ins_co_nm && ( + {cardSettings && cardSettings.ins_co_nm && metadata.ins_co_nm && ( -
{card.metadata.ins_co_nm || ""}
+
{metadata.ins_co_nm || ""}
)} - {cardSettings && cardSettings.clm_no && card.metadata.clm_no && ( + {cardSettings && cardSettings.clm_no && metadata.clm_no && ( -
{card.metadata.clm_no || ""}
+
{metadata.clm_no || ""}
)} @@ -139,7 +157,7 @@ export default function ProductionBoardCard({ technician, card, bodyshop, cardSe {`B: ${ employee_body ? `${employee_body.first_name.substr(0, 3)} ${employee_body.last_name.charAt(0)}` : "" - } ${card.metadata.labhrs.aggregate.sum.mod_lb_hrs || "?"}h`} + } ${metadata.labhrs.aggregate.sum.mod_lb_hrs || "?"}h`} {`P: ${ employee_prep ? `${employee_prep.first_name.substr(0, 3)} ${employee_prep.last_name.charAt(0)}` : "" }`} @@ -147,7 +165,7 @@ export default function ProductionBoardCard({ technician, card, bodyshop, cardSe employee_refinish ? `${employee_refinish.first_name.substr(0, 3)} ${employee_refinish.last_name.charAt(0)}` : "" - } ${card.metadata.larhrs.aggregate.sum.mod_lb_hrs || "?"}h`} + } ${metadata.larhrs.aggregate.sum.mod_lb_hrs || "?"}h`} {`C: ${ employee_csr ? `${employee_csr.first_name} ${employee_csr.last_name}` : "" }`} @@ -158,48 +176,56 @@ export default function ProductionBoardCard({ technician, card, bodyshop, cardSe {`B: ${ - card.metadata.labhrs.aggregate.sum.mod_lb_hrs || "?" + metadata.labhrs.aggregate.sum.mod_lb_hrs || "?" } hrs`} {`R: ${ - card.metadata.larhrs.aggregate.sum.mod_lb_hrs || "?" + metadata.larhrs.aggregate.sum.mod_lb_hrs || "?" } hrs`} )} */} - {cardSettings && cardSettings.actual_in && card.metadata.actual_in && ( + {cardSettings && cardSettings.actual_in && metadata.actual_in && ( - {card.metadata.actual_in} + {metadata.actual_in} )} - {cardSettings && cardSettings.scheduled_completion && card.metadata.scheduled_completion && ( + {cardSettings && cardSettings.scheduled_completion && metadata.scheduled_completion && ( - {card.metadata.scheduled_completion} + {metadata.scheduled_completion} )} - {cardSettings && cardSettings.ats && card.metadata.alt_transport && ( + {cardSettings && cardSettings.ats && metadata.alt_transport && ( -
{card.metadata.alt_transport || ""}
+
{metadata.alt_transport || ""}
)} {cardSettings && cardSettings.sublets && ( - + )} {cardSettings && cardSettings.production_note && ( - {cardSettings && cardSettings.production_note && } + {cardSettings && cardSettings.production_note && ( + + )} )} {cardSettings && cardSettings.partsstatus && ( - + )}
diff --git a/client/src/components/trello-board/components/index.js b/client/src/components/trello-board/components/index.js index 79ed0f445..59a41d085 100644 --- a/client/src/components/trello-board/components/index.js +++ b/client/src/components/trello-board/components/index.js @@ -6,11 +6,12 @@ import NewLaneForm from "./NewLaneForm.jsx"; import NewCardForm from "./NewCardForm.jsx"; import AddCardLink from "./AddCardLink"; import NewLaneSection from "./NewLaneSection.jsx"; -import { BoardWrapper, GlobalStyleHorizontal, GlobalStyleVertical, ScrollableLane, Section } from "../styles/Base"; +import { BoardWrapper, StyleHorizontal, GlobalStyle, StyleVertical, ScrollableLane, Section } from "../styles/Base"; const exports = { - GlobalStyleHorizontal, - GlobalStyleVertical, + StyleHorizontal, + StyleVertical, + GlobalStyle, BoardWrapper, Loader, ScrollableLane, diff --git a/client/src/components/trello-board/controllers/Board.jsx b/client/src/components/trello-board/controllers/Board.jsx index 42d67802d..406a124bd 100644 --- a/client/src/components/trello-board/controllers/Board.jsx +++ b/client/src/components/trello-board/controllers/Board.jsx @@ -7,19 +7,21 @@ const Board = ({ id, className, components, orientation, ...additionalProps }) = const [storeId] = useState(id || v1()); const allClassNames = classNames("react-trello-board", className || ""); - - const GlobalStyle = orientation === "horizontal" ? components.GlobalStyleHorizontal : components.GlobalStyleVertical; + const OrientationStyle = orientation === "horizontal" ? components.StyleHorizontal : components.StyleVertical; return ( - - - + <> + + + + + ); }; diff --git a/client/src/components/trello-board/styles/Base.js b/client/src/components/trello-board/styles/Base.js index 89461680a..bbcedd6ef 100644 --- a/client/src/components/trello-board/styles/Base.js +++ b/client/src/components/trello-board/styles/Base.js @@ -24,48 +24,12 @@ const getSectionStyles = (props) => { return ""; }; -export const GlobalStyleHorizontal = styled.div` +export const GlobalStyle = createGlobalStyle` .comPlainTextContentEditable { -webkit-user-modify: read-write-plaintext-only; cursor: text; } - .comPlainTextContentEditable--has-placeholder::before { - content: attr(placeholder); - opacity: 0.5; - color: inherit; - cursor: text; - } - - .react_trello_dragClass { - transform: rotate(3deg); - } - - .react_trello_dragLaneClass { - transform: rotate(3deg); - } - - .icon-overflow-menu-horizontal:before { - content: "\\E91F"; - } - - .icon-lg, - .icon-sm { - color: #798d99; - } - - .icon-lg { - height: 32px; - font-size: 16px; - line-height: 32px; - width: 32px; - } -`; -export const GlobalStyleVertical = styled.div` - .comPlainTextContentEditable { - -webkit-user-modify: read-write-plaintext-only; - cursor: text; - } .smooth-dnd-container.horizontal { } @@ -100,23 +64,21 @@ export const GlobalStyleVertical = styled.div` width: 32px; } + .react-trello-column-header { + border-radius: 5px; + } +`; + +export const StyleHorizontal = styled.div``; + +export const StyleVertical = styled.div` + .react-trello-column-header { + text-align: left; + } .smooth-dnd-container { // TODO ? This is the question. We need the same drag-zone we get in horizontal mode min-height: 50px; // Not needed, just for extra landing space } - - .react-trello-lane { - border: 1px solid #ccc; - border-radius: 5px; - } - - .react-trello-column-header { - border: 1px solid #ccc; - border-radius: 5px; - padding: 5px; - text-align: left; - } - .react-trello-board { overflow-y: hidden !important; } @@ -225,7 +187,7 @@ export const ScrollableLane = styled.div` align-self: center; // TODO: This was commented out to match existing board style //max-height: 90vh; - margin-top: 10px; + //margin-top: 10px; flex-direction: column; justify-content: space-between; `;