108 lines
3.2 KiB
JavaScript
108 lines
3.2 KiB
JavaScript
import { useMemo } from "react";
|
|
import { Tooltip } from "antd";
|
|
import { connect } from "react-redux";
|
|
import { createStructuredSelector } from "reselect";
|
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
|
|
|
const mapStateToProps = createStructuredSelector({
|
|
bodyshop: selectBodyshop
|
|
});
|
|
const mapDispatchToProps = () => ({});
|
|
|
|
const colorMap = {
|
|
gray: { bg: "#fafafa", border: "#d9d9d9", text: "#000000" },
|
|
gold: { bg: "#fffbe6", border: "#ffe58f", text: "#d48806" },
|
|
red: { bg: "#fff1f0", border: "#ffccc7", text: "#cf1322" },
|
|
blue: { bg: "#e6f7ff", border: "#91d5ff", text: "#0958d9" },
|
|
green: { bg: "#f6ffed", border: "#b7eb8f", text: "#389e0d" },
|
|
orange: { bg: "#fff7e6", border: "#ffd591", text: "#d46b08" }
|
|
};
|
|
|
|
function CompactTag({ color = "gray", children, tooltip = "" }) {
|
|
const colors = colorMap[color] || colorMap.gray;
|
|
|
|
return (
|
|
<span
|
|
style={{
|
|
display: "inline-flex",
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
padding: "0 2px",
|
|
fontSize: "12px",
|
|
lineHeight: "20px",
|
|
backgroundColor: colors.bg,
|
|
border: `1px solid ${colors.border}`,
|
|
borderRadius: "2px",
|
|
color: colors.text,
|
|
minWidth: "24px",
|
|
textAlign: "center"
|
|
}}
|
|
>
|
|
<Tooltip title={tooltip}>{children}</Tooltip>
|
|
</span>
|
|
);
|
|
}
|
|
|
|
export default connect(mapStateToProps, mapDispatchToProps)(JobPartsQueueCount);
|
|
|
|
export function JobPartsQueueCount({ bodyshop, parts }) {
|
|
const partsStatus = useMemo(() => {
|
|
if (!parts) return null;
|
|
|
|
const statusKeys = ["default_bo", "default_ordered", "default_received", "default_returned"];
|
|
|
|
return parts.reduce(
|
|
(acc, val) => {
|
|
if (val.part_type === "PAS" || val.part_type === "PASL") return acc;
|
|
|
|
acc.total += val.count;
|
|
|
|
// NOTE: if val.status is null, object key becomes "null"
|
|
acc[val.status] = (acc[val.status] ?? 0) + val.count;
|
|
|
|
return acc;
|
|
},
|
|
{
|
|
total: 0,
|
|
null: 0,
|
|
...Object.fromEntries(statusKeys.map((key) => [bodyshop.md_order_statuses[key], 0]))
|
|
}
|
|
);
|
|
}, [bodyshop, parts]);
|
|
|
|
if (!parts || !partsStatus) return null;
|
|
|
|
return (
|
|
<div
|
|
style={{
|
|
display: "inline-flex", // ✅ shrink-wraps, fixes the “extra box” to the right
|
|
gap: 2,
|
|
alignItems: "center",
|
|
whiteSpace: "nowrap"
|
|
}}
|
|
>
|
|
<CompactTag tooltip="Total" color="gray">
|
|
{partsStatus.total}
|
|
</CompactTag>
|
|
|
|
<CompactTag tooltip="No Status" color="gold">
|
|
{partsStatus["null"]}
|
|
</CompactTag>
|
|
|
|
<CompactTag tooltip={bodyshop.md_order_statuses.default_bo} color="red">
|
|
{partsStatus[bodyshop.md_order_statuses.default_bo]}
|
|
</CompactTag>
|
|
|
|
<CompactTag tooltip={bodyshop.md_order_statuses.default_ordered} color="blue">
|
|
{partsStatus[bodyshop.md_order_statuses.default_ordered]}
|
|
</CompactTag>
|
|
<CompactTag tooltip={bodyshop.md_order_statuses.default_received} color="green">
|
|
{partsStatus[bodyshop.md_order_statuses.default_received]}
|
|
</CompactTag>
|
|
<CompactTag tooltip={bodyshop.md_order_statuses.default_returned} color="orange">
|
|
{partsStatus[bodyshop.md_order_statuses.default_returned]}
|
|
</CompactTag>
|
|
</div>
|
|
);
|
|
}
|