- Daily checkpoint, speed (grid), and presentation
Signed-off-by: Dave Richer <dave@imexsystems.ca>
This commit is contained in:
@@ -28,26 +28,28 @@ const cardColor = (ssbuckets, totalHrs) => {
|
|||||||
const getContrastYIQ = (bgColor) =>
|
const getContrastYIQ = (bgColor) =>
|
||||||
(bgColor.r * 299 + bgColor.g * 587 + bgColor.b * 114) / 1000 >= 128 ? "black" : "white";
|
(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 }) => (
|
||||||
|
<Tooltip title={title}>
|
||||||
|
<div className="ellipses">{children}</div>
|
||||||
|
</Tooltip>
|
||||||
|
));
|
||||||
|
|
||||||
|
export default function ProductionBoardCard({ technician, card, bodyshop, cardSettings, clone }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { metadata } = card;
|
const { metadata } = card;
|
||||||
|
|
||||||
const employee_body = useMemo(
|
const employees = useMemo(() => bodyshop.employees, [bodyshop.employees]);
|
||||||
() => metadata?.employee_body && bodyshop.employees.find((e) => e.id === metadata.employee_body),
|
|
||||||
[metadata?.employee_body, bodyshop.employees]
|
const { employee_body, employee_prep, employee_refinish, employee_csr } = useMemo(() => {
|
||||||
);
|
return {
|
||||||
const employee_prep = useMemo(
|
employee_body: metadata?.employee_body && findEmployeeById(employees, metadata.employee_body),
|
||||||
() => metadata?.employee_prep && bodyshop.employees.find((e) => e.id === metadata.employee_prep),
|
employee_prep: metadata?.employee_prep && findEmployeeById(employees, metadata.employee_prep),
|
||||||
[metadata?.employee_prep, bodyshop.employees]
|
employee_refinish: metadata?.employee_refinish && findEmployeeById(employees, metadata.employee_refinish),
|
||||||
);
|
employee_csr: metadata?.employee_csr && findEmployeeById(employees, metadata.employee_csr)
|
||||||
const employee_refinish = useMemo(
|
};
|
||||||
() => metadata?.employee_refinish && bodyshop.employees.find((e) => e.id === metadata.employee_refinish),
|
}, [metadata, employees]);
|
||||||
[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 pastDueAlert = useMemo(() => {
|
const pastDueAlert = useMemo(() => {
|
||||||
if (!metadata?.scheduled_completion) return null;
|
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 bgColor = useMemo(() => cardColor(bodyshop.ssbuckets, totalHrs), [bodyshop.ssbuckets, totalHrs]);
|
||||||
const contrastYIQ = useMemo(() => getContrastYIQ(bgColor), [bgColor]);
|
const contrastYIQ = useMemo(() => getContrastYIQ(bgColor), [bgColor]);
|
||||||
|
|
||||||
|
const headerContent = (
|
||||||
|
<Space>
|
||||||
|
<ProductionAlert
|
||||||
|
record={{
|
||||||
|
id: card.id,
|
||||||
|
production_vars: card?.metadata.production_vars,
|
||||||
|
refetch: card?.refetch
|
||||||
|
}}
|
||||||
|
key="alert"
|
||||||
|
/>
|
||||||
|
{metadata?.suspended && <PauseCircleOutlined style={{ color: "orangered" }} />}
|
||||||
|
{metadata?.iouparent && (
|
||||||
|
<EllipsesToolTip title={t("jobs.labels.iou")}>
|
||||||
|
<BranchesOutlined style={{ color: "orangered" }} />
|
||||||
|
</EllipsesToolTip>
|
||||||
|
)}
|
||||||
|
<span style={{ fontWeight: "bolder" }}>
|
||||||
|
<Link to={technician ? `/tech/joblookup?selected=${card.id}` : `/manage/jobs/${card.id}`}>
|
||||||
|
{metadata?.ro_number || t("general.labels.na")}
|
||||||
|
</Link>
|
||||||
|
</span>
|
||||||
|
</Space>
|
||||||
|
);
|
||||||
|
|
||||||
|
const bodyContent = (
|
||||||
|
<Row>
|
||||||
|
{cardSettings?.ownr_nm && (
|
||||||
|
<Col span={24}>
|
||||||
|
<EllipsesToolTip title={`${metadata.ownr_ln || ""} ${metadata.ownr_co_nm || ""}`}>
|
||||||
|
{cardSettings.compact ? (
|
||||||
|
`${metadata.ownr_ln || ""} ${metadata.ownr_co_nm || ""}`
|
||||||
|
) : (
|
||||||
|
<OwnerNameDisplay ownerObject={card} />
|
||||||
|
)}
|
||||||
|
</EllipsesToolTip>
|
||||||
|
</Col>
|
||||||
|
)}
|
||||||
|
{cardSettings?.model_info && (
|
||||||
|
<Col span={24}>
|
||||||
|
<EllipsesToolTip
|
||||||
|
title={`${metadata.v_model_yr || ""} ${metadata.v_make_desc || ""} ${metadata.v_model_desc || ""}`}
|
||||||
|
>
|
||||||
|
{`${metadata.v_model_yr || ""} ${metadata.v_make_desc || ""} ${metadata.v_model_desc || ""}`}
|
||||||
|
</EllipsesToolTip>
|
||||||
|
</Col>
|
||||||
|
)}
|
||||||
|
{cardSettings?.ins_co_nm && metadata.ins_co_nm && (
|
||||||
|
<Col span={cardSettings.compact ? 24 : 12}>
|
||||||
|
<EllipsesToolTip title={metadata.ins_co_nm || ""}>{metadata.ins_co_nm || ""}</EllipsesToolTip>
|
||||||
|
</Col>
|
||||||
|
)}
|
||||||
|
{cardSettings?.clm_no && metadata.clm_no && (
|
||||||
|
<Col span={cardSettings.compact ? 24 : 12}>
|
||||||
|
<EllipsesToolTip title={metadata.clm_no || ""}>{metadata.clm_no || ""}</EllipsesToolTip>
|
||||||
|
</Col>
|
||||||
|
)}
|
||||||
|
{cardSettings?.employeeassignments && (
|
||||||
|
<Col span={24}>
|
||||||
|
<Row>
|
||||||
|
<Col span={cardSettings.compact ? 24 : 12}>
|
||||||
|
<EllipsesToolTip
|
||||||
|
title={`B: ${employee_body ? `${employee_body.first_name.substr(0, 3)} ${employee_body.last_name.charAt(0)}` : ""} ${metadata.labhrs.aggregate.sum.mod_lb_hrs || "?"}h`}
|
||||||
|
>
|
||||||
|
{`B: ${employee_body ? `${employee_body.first_name.substr(0, 3)} ${employee_body.last_name.charAt(0)}` : ""} ${metadata.labhrs.aggregate.sum.mod_lb_hrs || "?"}h`}
|
||||||
|
</EllipsesToolTip>
|
||||||
|
</Col>
|
||||||
|
<Col span={cardSettings.compact ? 24 : 12}>
|
||||||
|
<EllipsesToolTip
|
||||||
|
title={`P: ${employee_prep ? `${employee_prep.first_name.substr(0, 3)} ${employee_prep.last_name.charAt(0)}` : ""}`}
|
||||||
|
>
|
||||||
|
{`P: ${employee_prep ? `${employee_prep.first_name.substring(0, 3)} ${employee_prep.last_name.charAt(0)}` : ""}`}
|
||||||
|
</EllipsesToolTip>
|
||||||
|
</Col>
|
||||||
|
<Col span={cardSettings.compact ? 24 : 12}>
|
||||||
|
<EllipsesToolTip
|
||||||
|
title={`R: ${employee_refinish ? `${employee_refinish.first_name.substring(0, 3)} ${employee_refinish.last_name.charAt(0)}` : ""} ${metadata.larhrs.aggregate.sum.mod_lb_hrs || "?"}h`}
|
||||||
|
>
|
||||||
|
{`R: ${employee_refinish ? `${employee_refinish.first_name.substring(0, 3)} ${employee_refinish.last_name.charAt(0)}` : ""} ${metadata.larhrs.aggregate.sum.mod_lb_hrs || "?"}h`}
|
||||||
|
</EllipsesToolTip>
|
||||||
|
</Col>
|
||||||
|
<Col span={cardSettings.compact ? 24 : 12}>
|
||||||
|
<EllipsesToolTip
|
||||||
|
title={`C: ${employee_csr ? `${employee_csr.first_name} ${employee_csr.last_name}` : ""}`}
|
||||||
|
>
|
||||||
|
{`C: ${employee_csr ? `${employee_csr.first_name} ${employee_csr.last_name}` : ""}`}
|
||||||
|
</EllipsesToolTip>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Col>
|
||||||
|
)}
|
||||||
|
{cardSettings?.actual_in && metadata.actual_in && (
|
||||||
|
<Col span={cardSettings.compact ? 24 : 12}>
|
||||||
|
<EllipsesToolTip title={metadata.actual_in}>
|
||||||
|
<Space>
|
||||||
|
<DownloadOutlined />
|
||||||
|
<DateTimeFormatter format="MM/DD">{metadata.actual_in}</DateTimeFormatter>
|
||||||
|
</Space>
|
||||||
|
</EllipsesToolTip>
|
||||||
|
</Col>
|
||||||
|
)}
|
||||||
|
{cardSettings?.scheduled_completion && metadata.scheduled_completion && (
|
||||||
|
<Col span={cardSettings.compact ? 24 : 12}>
|
||||||
|
<EllipsesToolTip title={metadata.scheduled_completion}>
|
||||||
|
<Space className={pastDueAlert}>
|
||||||
|
<CalendarOutlined />
|
||||||
|
<DateTimeFormatter format="MM/DD">{metadata.scheduled_completion}</DateTimeFormatter>
|
||||||
|
</Space>
|
||||||
|
</EllipsesToolTip>
|
||||||
|
</Col>
|
||||||
|
)}
|
||||||
|
{cardSettings?.ats && metadata.alt_transport && (
|
||||||
|
<Col span={12}>
|
||||||
|
<EllipsesToolTip title={metadata.alt_transport}>{metadata.alt_transport || ""}</EllipsesToolTip>
|
||||||
|
</Col>
|
||||||
|
)}
|
||||||
|
{cardSettings?.sublets && (
|
||||||
|
<Col span={12}>
|
||||||
|
<ProductionSubletsManageComponent subletJobLines={metadata.subletLines} />
|
||||||
|
</Col>
|
||||||
|
)}
|
||||||
|
{cardSettings?.production_note && (
|
||||||
|
<Col span={24}>
|
||||||
|
<ProductionListColumnProductionNote
|
||||||
|
record={{
|
||||||
|
production_vars: card?.metadata.production_vars,
|
||||||
|
id: card?.id,
|
||||||
|
refetch: card?.refetch
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
)}
|
||||||
|
{cardSettings?.partsstatus && (
|
||||||
|
<Col span={24}>
|
||||||
|
<JobPartsQueueCount parts={metadata.joblines_status} />
|
||||||
|
</Col>
|
||||||
|
)}
|
||||||
|
</Row>
|
||||||
|
);
|
||||||
|
|
||||||
|
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 (
|
return (
|
||||||
<Card
|
<Card
|
||||||
className="react-trello-card"
|
className="react-trello-card"
|
||||||
size="small"
|
size="small"
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: cardSettings?.cardcolor && `rgba(${bgColor.r},${bgColor.g},${bgColor.b},${bgColor.a})`,
|
backgroundColor: cardSettings?.cardcolor && `rgba(${bgColor.r},${bgColor.g},${bgColor.b},${bgColor.a})`,
|
||||||
color: cardSettings?.cardcolor && contrastYIQ,
|
color: cardSettings?.cardcolor && contrastYIQ
|
||||||
...style
|
|
||||||
}}
|
}}
|
||||||
title={
|
title={isBodyEmpty ? null : headerContent}
|
||||||
<Space>
|
|
||||||
<ProductionAlert
|
|
||||||
record={{
|
|
||||||
id: card.id,
|
|
||||||
production_vars: card?.metadata.production_vars,
|
|
||||||
refetch: card?.refetch
|
|
||||||
}}
|
|
||||||
key="alert"
|
|
||||||
/>
|
|
||||||
{metadata?.suspended && <PauseCircleOutlined style={{ color: "orangered" }} />}
|
|
||||||
{metadata?.iouparent && (
|
|
||||||
<Tooltip title={t("jobs.labels.iou")}>
|
|
||||||
<BranchesOutlined style={{ color: "orangered" }} />
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
|
||||||
<span style={{ fontWeight: "bolder" }}>
|
|
||||||
<Link to={technician ? `/tech/joblookup?selected=${card.id}` : `/manage/jobs/${card.id}`}>
|
|
||||||
{metadata?.ro_number || t("general.labels.na")}
|
|
||||||
</Link>
|
|
||||||
</span>
|
|
||||||
</Space>
|
|
||||||
}
|
|
||||||
extra={
|
extra={
|
||||||
<Link to={{ search: `?selected=${card.id}` }}>
|
!isBodyEmpty && (
|
||||||
<EyeFilled />
|
<Link to={{ search: `?selected=${card.id}` }}>
|
||||||
</Link>
|
<EyeFilled />
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Row>
|
{isBodyEmpty ? headerContent : bodyContent}
|
||||||
{cardSettings?.ownr_nm && (
|
|
||||||
<Col span={24}>
|
|
||||||
<Tooltip title={`${metadata.ownr_ln || ""} ${metadata.ownr_co_nm || ""}`}>
|
|
||||||
{cardSettings.compact ? (
|
|
||||||
<div className="ellipses">{`${metadata.ownr_ln || ""} ${metadata.ownr_co_nm || ""}`}</div>
|
|
||||||
) : (
|
|
||||||
<div className="ellipses">
|
|
||||||
<OwnerNameDisplay ownerObject={card} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</Tooltip>
|
|
||||||
</Col>
|
|
||||||
)}
|
|
||||||
{cardSettings?.model_info && (
|
|
||||||
<Col span={24}>
|
|
||||||
<Tooltip
|
|
||||||
title={`${metadata.v_model_yr || ""} ${metadata.v_make_desc || ""} ${metadata.v_model_desc || ""}`}
|
|
||||||
>
|
|
||||||
<div className="ellipses">{`${metadata.v_model_yr || ""} ${metadata.v_make_desc || ""} ${metadata.v_model_desc || ""}`}</div>
|
|
||||||
</Tooltip>
|
|
||||||
</Col>
|
|
||||||
)}
|
|
||||||
{cardSettings?.ins_co_nm && metadata.ins_co_nm && (
|
|
||||||
<Col span={cardSettings.compact ? 24 : 12}>
|
|
||||||
<Tooltip title={metadata.ins_co_nm || ""}>
|
|
||||||
<div className="ellipses">{metadata.ins_co_nm || ""}</div>
|
|
||||||
</Tooltip>
|
|
||||||
</Col>
|
|
||||||
)}
|
|
||||||
{cardSettings?.clm_no && metadata.clm_no && (
|
|
||||||
<Col span={cardSettings.compact ? 24 : 12}>
|
|
||||||
<Tooltip title={metadata.clm_no || ""}>
|
|
||||||
<div className="ellipses">{metadata.clm_no || ""}</div>
|
|
||||||
</Tooltip>
|
|
||||||
</Col>
|
|
||||||
)}
|
|
||||||
{cardSettings?.employeeassignments && (
|
|
||||||
<Col span={24}>
|
|
||||||
<Row>
|
|
||||||
<Col span={cardSettings.compact ? 24 : 12}>
|
|
||||||
<Tooltip
|
|
||||||
title={`B: ${employee_body ? `${employee_body.first_name.substr(0, 3)} ${employee_body.last_name.charAt(0)}` : ""} ${metadata.labhrs.aggregate.sum.mod_lb_hrs || "?"}h`}
|
|
||||||
>
|
|
||||||
<div className="ellipses">{`B: ${employee_body ? `${employee_body.first_name.substr(0, 3)} ${employee_body.last_name.charAt(0)}` : ""} ${metadata.labhrs.aggregate.sum.mod_lb_hrs || "?"}h`}</div>
|
|
||||||
</Tooltip>
|
|
||||||
</Col>
|
|
||||||
<Col span={cardSettings.compact ? 24 : 12}>
|
|
||||||
<Tooltip
|
|
||||||
title={`P: ${employee_prep ? `${employee_prep.first_name.substr(0, 3)} ${employee_prep.last_name.charAt(0)}` : ""}`}
|
|
||||||
>
|
|
||||||
<div className="ellipses">{`P: ${employee_prep ? `${employee_prep.first_name.substring(0, 3)} ${employee_prep.last_name.charAt(0)}` : ""}`}</div>
|
|
||||||
</Tooltip>
|
|
||||||
</Col>
|
|
||||||
<Col span={cardSettings.compact ? 24 : 12}>
|
|
||||||
<Tooltip
|
|
||||||
title={`R: ${employee_refinish ? `${employee_refinish.first_name.substring(0, 3)} ${employee_refinish.last_name.charAt(0)}` : ""} ${metadata.larhrs.aggregate.sum.mod_lb_hrs || "?"}h`}
|
|
||||||
>
|
|
||||||
<div className="ellipses">{`R: ${employee_refinish ? `${employee_refinish.first_name.substring(0, 3)} ${employee_refinish.last_name.charAt(0)}` : ""} ${metadata.larhrs.aggregate.sum.mod_lb_hrs || "?"}h`}</div>
|
|
||||||
</Tooltip>
|
|
||||||
</Col>
|
|
||||||
<Col span={cardSettings.compact ? 24 : 12}>
|
|
||||||
<Tooltip title={`C: ${employee_csr ? `${employee_csr.first_name} ${employee_csr.last_name}` : ""}`}>
|
|
||||||
<div className="ellipses">{`C: ${employee_csr ? `${employee_csr.first_name} ${employee_csr.last_name}` : ""}`}</div>
|
|
||||||
</Tooltip>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
</Col>
|
|
||||||
)}
|
|
||||||
{cardSettings?.actual_in && metadata.actual_in && (
|
|
||||||
<Col span={cardSettings.compact ? 24 : 12}>
|
|
||||||
<Tooltip title={metadata.actual_in}>
|
|
||||||
<Space>
|
|
||||||
<DownloadOutlined />
|
|
||||||
<DateTimeFormatter format="MM/DD">{metadata.actual_in}</DateTimeFormatter>
|
|
||||||
</Space>
|
|
||||||
</Tooltip>
|
|
||||||
</Col>
|
|
||||||
)}
|
|
||||||
{cardSettings?.scheduled_completion && metadata.scheduled_completion && (
|
|
||||||
<Col span={cardSettings.compact ? 24 : 12}>
|
|
||||||
<Tooltip title={metadata.scheduled_completion}>
|
|
||||||
<Space className={pastDueAlert}>
|
|
||||||
<CalendarOutlined />
|
|
||||||
<DateTimeFormatter format="MM/DD">{metadata.scheduled_completion}</DateTimeFormatter>
|
|
||||||
</Space>
|
|
||||||
</Tooltip>
|
|
||||||
</Col>
|
|
||||||
)}
|
|
||||||
{cardSettings?.ats && metadata.alt_transport && (
|
|
||||||
<Col span={12}>
|
|
||||||
<Tooltip title={metadata.alt_transport}>
|
|
||||||
<div className="ellipses">{metadata.alt_transport || ""}</div>
|
|
||||||
</Tooltip>
|
|
||||||
</Col>
|
|
||||||
)}
|
|
||||||
{cardSettings?.sublets && (
|
|
||||||
<Col span={12}>
|
|
||||||
<ProductionSubletsManageComponent subletJobLines={metadata.subletLines} />
|
|
||||||
</Col>
|
|
||||||
)}
|
|
||||||
{cardSettings?.production_note && (
|
|
||||||
<Col span={24}>
|
|
||||||
<ProductionListColumnProductionNote
|
|
||||||
record={{
|
|
||||||
production_vars: card?.metadata.production_vars,
|
|
||||||
id: card?.id,
|
|
||||||
refetch: card?.refetch
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
)}
|
|
||||||
{cardSettings?.partsstatus && (
|
|
||||||
<Col span={24}>
|
|
||||||
<JobPartsQueueCount parts={metadata.joblines_status} />
|
|
||||||
</Col>
|
|
||||||
)}
|
|
||||||
</Row>
|
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import ProductionBoardFilters from "../production-board-filters/production-board
|
|||||||
import ProductionListDetailComponent from "../production-list-detail/production-list-detail.component";
|
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 CardColorLegend from "../production-board-kanban-card/production-board-kanban-card-color-legend.component";
|
||||||
import "./production-board-kanban.styles.scss";
|
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 ProductionBoardKanbanSettings from "./production-board-kanban.settings.component.jsx";
|
||||||
import cloneDeep from "lodash/cloneDeep";
|
import cloneDeep from "lodash/cloneDeep";
|
||||||
import isEqual from "lodash/isEqual";
|
import isEqual from "lodash/isEqual";
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { groupBy } from "lodash";
|
import { groupBy } from "lodash";
|
||||||
import fakeData from "./testData/board600.json";
|
import fakeData from "./testData/board1200.json";
|
||||||
|
|
||||||
const sortByParentId = (arr) => {
|
const sortByParentId = (arr) => {
|
||||||
// return arr.reduce((accumulator, currentValue) => {
|
// return arr.reduce((accumulator, currentValue) => {
|
||||||
|
|||||||
@@ -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 PropTypes from "prop-types";
|
||||||
import { bindActionCreators } from "redux";
|
import { bindActionCreators } from "redux";
|
||||||
import { connect } from "react-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 HeightMemoryWrapper from "../components/Lane/HeightMemoryWrapper.jsx";
|
||||||
import SizeMemoryWrapper from "../components/Lane/SizeMemoryWrapper.jsx";
|
import SizeMemoryWrapper from "../components/Lane/SizeMemoryWrapper.jsx";
|
||||||
|
|
||||||
|
const ListComponent = forwardRef(({ style, children, ...props }, ref) => (
|
||||||
|
<div ref={ref} {...props} style={{ ...style }}>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
));
|
||||||
|
|
||||||
|
const ItemComponent = ({ children, maxCardHeight, maxCardWidth, ...props }) => (
|
||||||
|
<div style={{ minWidth: maxCardWidth, minHeight: maxCardHeight }} {...props}>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
const ItemWrapper = React.memo(({ children, ...props }) => (
|
||||||
|
<div {...props} className="item-wrapper">
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lane is a React component that represents a lane in a Trello-like board.
|
* Lane is a React component that represents a lane in a Trello-like board.
|
||||||
* @param id
|
* @param id
|
||||||
@@ -57,6 +75,7 @@ const Lane = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const [collapsed, setCollapsed] = useState(false);
|
const [collapsed, setCollapsed] = useState(false);
|
||||||
const [isVisible, setIsVisible] = useState(true);
|
const [isVisible, setIsVisible] = useState(true);
|
||||||
|
const laneRef = useRef(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setIsVisible(false);
|
setIsVisible(false);
|
||||||
@@ -115,15 +134,6 @@ const Lane = ({
|
|||||||
[isProcessing, technician, bodyshop, cardSettings, maxCardHeight, setMaxCardHeight, maxCardWidth, setMaxCardWidth]
|
[isProcessing, technician, bodyshop, cardSettings, maxCardHeight, setMaxCardHeight, maxCardWidth, setMaxCardWidth]
|
||||||
);
|
);
|
||||||
|
|
||||||
const ItemWrapper = useCallback(
|
|
||||||
({ children, ...props }) => (
|
|
||||||
<div {...props} className="item-wrapper">
|
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
|
|
||||||
const renderDroppable = useCallback(
|
const renderDroppable = useCallback(
|
||||||
(provided, renderedCards) => {
|
(provided, renderedCards) => {
|
||||||
const Component = orientation === "vertical" ? VirtuosoGrid : Virtuoso;
|
const Component = orientation === "vertical" ? VirtuosoGrid : Virtuoso;
|
||||||
@@ -137,17 +147,10 @@ const Lane = ({
|
|||||||
...commonProps,
|
...commonProps,
|
||||||
listClassName: "grid-container",
|
listClassName: "grid-container",
|
||||||
itemClassName: "grid-item",
|
itemClassName: "grid-item",
|
||||||
|
customScrollParent: laneRef.current,
|
||||||
components: {
|
components: {
|
||||||
List: forwardRef(({ style, children, ...props }, ref) => (
|
List: ListComponent,
|
||||||
<div ref={ref} {...props} style={{ ...style }}>
|
Item: ItemComponent
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
)),
|
|
||||||
Item: ({ children, ...props }) => (
|
|
||||||
<div style={{ minWidth: maxCardWidth, minHeight: maxCardHeight }} {...props}>
|
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
itemContent: (index, item) => <ItemWrapper>{renderDraggable(index, item)}</ItemWrapper>,
|
itemContent: (index, item) => <ItemWrapper>{renderDraggable(index, item)}</ItemWrapper>,
|
||||||
overscan: { main: 10, reverse: 10 }
|
overscan: { main: 10, reverse: 10 }
|
||||||
@@ -200,7 +203,7 @@ const Lane = ({
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
[orientation, collapsed, isVisible, renderDraggable, maxLaneHeight, setMaxLaneHeight, maxCardHeight, maxCardWidth]
|
[orientation, collapsed, isVisible, renderDraggable, maxLaneHeight, setMaxLaneHeight, maxCardWidth]
|
||||||
);
|
);
|
||||||
|
|
||||||
const renderDragContainer = useCallback(
|
const renderDragContainer = useCallback(
|
||||||
@@ -226,27 +229,15 @@ const Lane = ({
|
|||||||
className={`clone ${snapshot.isDragging ? "is-dragging" : ""}`}
|
className={`clone ${snapshot.isDragging ? "is-dragging" : ""}`}
|
||||||
key={card.id}
|
key={card.id}
|
||||||
>
|
>
|
||||||
{/*<SizeMemoryWrapper*/}
|
|
||||||
{/* maxHeight={maxCardHeight}*/}
|
|
||||||
{/* setMaxHeight={setMaxCardHeight}*/}
|
|
||||||
{/* maxWidth={maxCardWidth}*/}
|
|
||||||
{/* setMaxWidth={setMaxCardWidth}*/}
|
|
||||||
{/*>*/}
|
|
||||||
<ProductionBoardCard
|
<ProductionBoardCard
|
||||||
technician={technician}
|
technician={technician}
|
||||||
bodyshop={bodyshop}
|
bodyshop={bodyshop}
|
||||||
cardSettings={cardSettings}
|
cardSettings={cardSettings}
|
||||||
key={card.id}
|
key={card.id}
|
||||||
className="react-trello-card"
|
className="react-trello-card"
|
||||||
style={{
|
|
||||||
minHeight: maxCardHeight,
|
|
||||||
minWidth: maxCardWidth,
|
|
||||||
background_color: "red !important"
|
|
||||||
}}
|
|
||||||
card={card}
|
card={card}
|
||||||
clone={false}
|
clone={false}
|
||||||
/>
|
/>
|
||||||
{/*</SizeMemoryWrapper>*/}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ if (import.meta.env.PROD) {
|
|||||||
|
|
||||||
ignoreErrors: [
|
ignoreErrors: [
|
||||||
"ResizeObserver loop",
|
"ResizeObserver loop",
|
||||||
|
"ResizeObserver loop limit exceeded",
|
||||||
"Module specifier, 'fs' does not start",
|
"Module specifier, 'fs' does not start",
|
||||||
"Module specifier, 'zlib' does not start with"
|
"Module specifier, 'zlib' does not start with"
|
||||||
],
|
],
|
||||||
|
|||||||
Reference in New Issue
Block a user