feature/IO-3388 - Parts Queue Fix

This commit is contained in:
Dave
2025-10-02 12:55:50 -04:00
parent 01664c52ec
commit 367ced88d8
14 changed files with 61 additions and 54 deletions

View File

@@ -90,7 +90,7 @@ export function JobDetailCardsPartsComponent({ loading, data, jobRO }) {
.filter(onlyUnique) .filter(onlyUnique)
.map((s) => { .map((s) => {
return { return {
text: s || "No Status*", text: s || t("dashboard.errors.status"),
value: [s] value: [s]
}; };
})) || })) ||
@@ -103,7 +103,7 @@ export function JobDetailCardsPartsComponent({ loading, data, jobRO }) {
<div> <div>
<CardTemplate loading={loading} title={t("jobs.labels.cards.parts")}> <CardTemplate loading={loading} title={t("jobs.labels.cards.parts")}>
<PartsStatusPie joblines_status={joblines_status} /> <PartsStatusPie joblines_status={joblines_status} />
<Table key="id" columns={columns} dataSource={filteredJobLines ? filteredJobLines : []} /> <Table key="id" columns={columns} dataSource={filteredJobLines || []} />
</CardTemplate> </CardTemplate>
</div> </div>
); );

View File

@@ -318,7 +318,7 @@ export function JobLinesComponent({
.filter(onlyUnique) .filter(onlyUnique)
.map((s) => { .map((s) => {
return { return {
text: s || "No Status*", text: s || t("dashboard.errors.status"),
value: [s] value: [s]
}; };
})) || })) ||

View File

@@ -1,8 +1,9 @@
import { useMemo } from "react"; import { useMemo } from "react";
import { Col, Row, Tag, Tooltip } from "antd"; import { Tag, Tooltip } from "antd";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { createStructuredSelector } from "reselect"; import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors"; import { selectBodyshop } from "../../redux/user/user.selectors";
import { useTranslation } from "react-i18next";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop bodyshop: selectBodyshop
@@ -11,65 +12,67 @@ const mapDispatchToProps = () => ({
//setUserLanguage: language => dispatch(setUserLanguage(language)) //setUserLanguage: language => dispatch(setUserLanguage(language))
}); });
export const DEFAULT_COL_LAYOUT = { xs: 24, sm: 24, md: 8, lg: 4, xl: 4, xxl: 4 };
export default connect(mapStateToProps, mapDispatchToProps)(JobPartsQueueCount); export default connect(mapStateToProps, mapDispatchToProps)(JobPartsQueueCount);
export function JobPartsQueueCount({ bodyshop, parts, defaultColLayout = DEFAULT_COL_LAYOUT }) { export function JobPartsQueueCount({ bodyshop, parts }) {
const { t } = useTranslation();
const partsStatus = useMemo(() => { const partsStatus = useMemo(() => {
if (!parts) return null; if (!parts) return null;
const statusKeys = ["default_bo", "default_ordered", "default_received", "default_returned"];
return parts.reduce( return parts.reduce(
(acc, val) => { (acc, val) => {
if (val.part_type === "PAS" || val.part_type === "PASL") return acc; if (val.part_type === "PAS" || val.part_type === "PASL") return acc;
acc.total = acc.total + val.count; acc.total = acc.total + val.count;
acc[val.status] = acc[val.status] + val.count; acc[val.status] = acc[val.status] + val.count;
return acc; return acc;
}, },
{ {
total: 0, total: 0,
null: 0, null: 0,
[bodyshop.md_order_statuses.default_bo]: 0, ...Object.fromEntries(statusKeys.map((key) => [bodyshop.md_order_statuses[key], 0]))
[bodyshop.md_order_statuses.default_ordered]: 0,
[bodyshop.md_order_statuses.default_received]: 0,
[bodyshop.md_order_statuses.default_returned]: 0
} }
); );
}, [bodyshop, parts]); }, [bodyshop, parts]);
if (!parts) return null; if (!parts) return null;
return ( return (
<Row> <div
<Col {...defaultColLayout}> style={{
<Tooltip title="Total"> display: "grid",
<Tag>{partsStatus.total}</Tag> gridTemplateColumns: "repeat(auto-fit, minmax(40px, 1fr))",
</Tooltip> gap: "8px",
</Col> width: "100%",
<Col {...defaultColLayout}> justifyItems: "start"
<Tooltip title="No Status"> }}
<Tag color="gold">{partsStatus["null"]}</Tag> >
</Tooltip> <Tooltip title="Total">
</Col> <Tag style={{ minWidth: "40px", textAlign: "center" }}>{partsStatus.total}</Tag>
<Col {...defaultColLayout}> </Tooltip>
<Tooltip title={bodyshop.md_order_statuses.default_ordered}> <Tooltip title={t("dashboard.errors.status_normal")}>
<Tag color="blue">{partsStatus[bodyshop.md_order_statuses.default_ordered]}</Tag> <Tag color="gold" style={{ minWidth: "40px", textAlign: "center" }}>
</Tooltip> {partsStatus["null"]}
</Col> </Tag>
<Col {...defaultColLayout}> </Tooltip>
<Tooltip title={bodyshop.md_order_statuses.default_received}> <Tooltip title={bodyshop.md_order_statuses.default_bo}>
<Tag color="green">{partsStatus[bodyshop.md_order_statuses.default_received]}</Tag> <Tag color="red" style={{ minWidth: "40px", textAlign: "center" }}>
</Tooltip> {partsStatus[bodyshop.md_order_statuses.default_bo]}
</Col> </Tag>
<Col {...defaultColLayout}> </Tooltip>
<Tooltip title={bodyshop.md_order_statuses.default_returned}> <Tooltip title={bodyshop.md_order_statuses.default_ordered}>
<Tag color="orange">{partsStatus[bodyshop.md_order_statuses.default_returned]}</Tag> <Tag color="blue" style={{ minWidth: "40px", textAlign: "center" }}>
</Tooltip> {partsStatus[bodyshop.md_order_statuses.default_ordered]}
</Col> </Tag>
<Col {...defaultColLayout}> </Tooltip>
<Tooltip title={bodyshop.md_order_statuses.default_bo}> <Tooltip title={bodyshop.md_order_statuses.default_received}>
<Tag color="red">{partsStatus[bodyshop.md_order_statuses.default_bo]}</Tag> <Tag color="green" style={{ minWidth: "40px", textAlign: "center" }}>
</Tooltip> {partsStatus[bodyshop.md_order_statuses.default_received]}
</Col> </Tag>
</Row> </Tooltip>
<Tooltip title={bodyshop.md_order_statuses.default_returned}>
<Tag color="orange" style={{ minWidth: "40px", textAlign: "center" }}>
{partsStatus[bodyshop.md_order_statuses.default_returned]}
</Tag>
</Tooltip>
</div>
); );
} }

View File

@@ -166,7 +166,7 @@ export function JobsList({ bodyshop }) {
.filter(onlyUnique) .filter(onlyUnique)
.map((s) => { .map((s) => {
return { return {
text: s || "No Status*", text: s || t("dashboard.errors.status"),
value: [s] value: [s]
}; };
}) })

View File

@@ -165,7 +165,7 @@ export function JobsReadyList({ bodyshop }) {
.filter(onlyUnique) .filter(onlyUnique)
.map((s) => { .map((s) => {
return { return {
text: s || "No Status*", text: s || t("dashboard.errors.status"),
value: [s] value: [s]
}; };
}) })

View File

@@ -145,7 +145,7 @@ export function PartsQueueJobLinesComponent({ loading, jobLines }) {
.filter(onlyUnique) .filter(onlyUnique)
.map((s) => { .map((s) => {
return { return {
text: s || "No Status*", text: s || t("dashboard.errors.status"),
value: [s] value: [s]
}; };
})) || })) ||

View File

@@ -171,7 +171,7 @@ export function PartsQueueListComponent({ bodyshop }) {
filters: filters:
bodyshop.md_ro_statuses.active_statuses.map((s) => { bodyshop.md_ro_statuses.active_statuses.map((s) => {
return { return {
text: s || "No Status*", text: s || t("dashboard.errors.status"),
value: [s] value: [s]
}; };
}) || [], }) || [],

View File

@@ -34,8 +34,9 @@ const getEmployeeName = (employeeId, employees) => {
return employee ? `${employee.first_name} ${employee.last_name}` : ""; return employee ? `${employee.first_name} ${employee.last_name}` : "";
}; };
const r = ({ technician, state, activeStatuses, data, bodyshop, refetch, treatments }) => { const productionListColumnsData = ({ technician, state, activeStatuses, data, bodyshop, refetch, treatments }) => {
const { Enhanced_Payroll } = treatments; const { Enhanced_Payroll } = treatments;
return [ return [
{ {
title: i18n.t("jobs.actions.viewdetail"), title: i18n.t("jobs.actions.viewdetail"),
@@ -313,7 +314,7 @@ const r = ({ technician, state, activeStatuses, data, bodyshop, refetch, treatme
activeStatuses activeStatuses
?.map((s) => { ?.map((s) => {
return { return {
text: s || "No Status*", text: s || i18n.t("dashboard.errors.status"),
value: [s] value: [s]
}; };
}) })
@@ -584,4 +585,4 @@ const r = ({ technician, state, activeStatuses, data, bodyshop, refetch, treatme
} }
]; ];
}; };
export default r; export default productionListColumnsData;

View File

@@ -103,7 +103,7 @@ export function SimplifiedPartsJobsListComponent({
return record.status || t("general.labels.na"); return record.status || t("general.labels.na");
}, },
filteredValue: filter?.status || null, filteredValue: filter?.status || null,
filters: bodyshop.md_ro_statuses?.parts_statuses.map((s) => { filters: bodyshop?.md_ro_statuses?.parts_statuses?.map((s) => {
return { text: s, value: [s] }; return { text: s, value: [s] };
}), }),
onFilter: (value, record) => value.includes(record.status) onFilter: (value, record) => value.includes(record.status)

View File

@@ -111,7 +111,7 @@ export function TechLookupJobsList({ bodyshop }) {
.filter(onlyUnique) .filter(onlyUnique)
.map((s) => { .map((s) => {
return { return {
text: s || "No Status*", text: s || t("dashboard.errors.status"),
value: [s] value: [s]
}; };
})) || })) ||

View File

@@ -97,7 +97,7 @@ export function TechAssignedProdJobs({ setTimeTicketTaskContext, technician, bod
.filter(onlyUnique) .filter(onlyUnique)
.map((s) => { .map((s) => {
return { return {
text: s || "No Status*", text: s || t("dashboard.errors.status"),
value: [s] value: [s]
}; };
})) || })) ||

View File

@@ -996,6 +996,7 @@
"insco": "No Ins. Co.*", "insco": "No Ins. Co.*",
"refreshrequired": "You must refresh the dashboard data to see this component.", "refreshrequired": "You must refresh the dashboard data to see this component.",
"status": "No Status*", "status": "No Status*",
"status_normal": "No Status",
"updatinglayout": "Error saving updated layout {{message}}" "updatinglayout": "Error saving updated layout {{message}}"
}, },
"labels": { "labels": {

View File

@@ -996,6 +996,7 @@
"insco": "", "insco": "",
"refreshrequired": "", "refreshrequired": "",
"status": "", "status": "",
"status_normal": "",
"updatinglayout": "" "updatinglayout": ""
}, },
"labels": { "labels": {

View File

@@ -996,6 +996,7 @@
"insco": "", "insco": "",
"refreshrequired": "", "refreshrequired": "",
"status": "", "status": "",
"status_normal": "",
"updatinglayout": "" "updatinglayout": ""
}, },
"labels": { "labels": {