- Clean up Card Settings
- Code refactor for maintainability - Allow users to adjust the order of the statistics via drag and drop Signed-off-by: Dave Richer <dave@imexsystems.ca>
This commit is contained in:
@@ -1,6 +1,27 @@
|
||||
import React, { useMemo } from "react";
|
||||
import { Statistic, Card } from "antd";
|
||||
import { Card, Statistic } from "antd";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import PropTypes from "prop-types";
|
||||
import { statisticsItems } from "./defaultKanbanSettings.js";
|
||||
|
||||
export const StatisticType = {
|
||||
HOURS: "hours",
|
||||
AMOUNT: "amount",
|
||||
JOBS: "jobs"
|
||||
};
|
||||
|
||||
const mergeStatistics = (items, values) => {
|
||||
const valuesMap = values.reduce((acc, value) => {
|
||||
acc[value.id] = value;
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
return items.map((item) => ({
|
||||
...item,
|
||||
value: valuesMap[item.id]?.value,
|
||||
type: valuesMap[item.id]?.type
|
||||
}));
|
||||
};
|
||||
|
||||
const ProductionStatistics = ({ data, cardSettings, reducerData }) => {
|
||||
const { t } = useTranslation();
|
||||
@@ -30,10 +51,10 @@ const ProductionStatistics = ({ data, cardSettings, reducerData }) => {
|
||||
};
|
||||
|
||||
const formatValue = (value, type) => {
|
||||
if (type === "Jobs") {
|
||||
if (type === StatisticType.JOBS) {
|
||||
return value.toFixed(0);
|
||||
}
|
||||
if (type === "Hrs") {
|
||||
if (type === StatisticType.HOURS) {
|
||||
return value.toFixed(2);
|
||||
}
|
||||
return value;
|
||||
@@ -102,44 +123,100 @@ const ProductionStatistics = ({ data, cardSettings, reducerData }) => {
|
||||
return parseFloat(total.toFixed(2));
|
||||
}, [reducerData, cardSettings.totalAmountOnBoard]);
|
||||
|
||||
const statistics = [
|
||||
{ value: totalHrs, title: t("total_hours_in_production"), suffix: t("production.statistics.hours") },
|
||||
{
|
||||
value: totalAmountInProduction,
|
||||
title: t("total_amount_in_production"),
|
||||
prefix: t("production.statistics.currency_symbol")
|
||||
},
|
||||
{ value: totalLAB, title: t("total_lab_in_production"), suffix: t("production.statistics.hours") },
|
||||
{ value: totalLAR, title: t("total_lar_in_production"), suffix: t("production.statistics.hours") },
|
||||
{ value: jobsInProduction, title: t("jobs_in_production"), suffix: "Jobs" },
|
||||
{ value: totalHrsOnBoard, title: t("total_hours_on_board"), suffix: t("production.statistics.hours") },
|
||||
{
|
||||
value: totalAmountOnBoard,
|
||||
title: t("total_amount_on_board"),
|
||||
prefix: t("production.statistics.currency_symbol")
|
||||
},
|
||||
{ value: totalLABOnBoard, title: t("total_lab_on_board"), suffix: t("production.statistics.hours") },
|
||||
{ value: totalLAROnBoard, title: t("total_lar_on_board"), suffix: t("production.statistics.hours") },
|
||||
{ value: jobsOnBoard, title: t("total_jobs_on_board"), suffix: "Jobs" }
|
||||
];
|
||||
const statistics = useMemo(
|
||||
() =>
|
||||
mergeStatistics(statisticsItems, [
|
||||
{ id: 0, value: totalHrs, type: StatisticType.HOURS },
|
||||
{ id: 1, value: totalAmountInProduction, type: StatisticType.AMOUNT },
|
||||
{ id: 2, value: totalLAB, type: StatisticType.HOURS },
|
||||
{ id: 3, value: totalLAR, type: StatisticType.HOURS },
|
||||
{ id: 4, value: jobsInProduction, type: StatisticType.JOBS },
|
||||
{ id: 5, value: totalHrsOnBoard, type: StatisticType.HOURS },
|
||||
{ id: 6, value: totalAmountOnBoard, type: StatisticType.AMOUNT },
|
||||
{ id: 7, value: totalLABOnBoard, type: StatisticType.HOURS },
|
||||
{ id: 8, value: totalLAROnBoard, type: StatisticType.HOURS },
|
||||
{ id: 9, value: jobsOnBoard, type: StatisticType.JOBS }
|
||||
]),
|
||||
[
|
||||
totalHrs,
|
||||
totalAmountInProduction,
|
||||
totalLAB,
|
||||
totalLAR,
|
||||
jobsInProduction,
|
||||
totalHrsOnBoard,
|
||||
totalAmountOnBoard,
|
||||
totalLABOnBoard,
|
||||
totalLAROnBoard,
|
||||
jobsOnBoard
|
||||
]
|
||||
);
|
||||
|
||||
const sortedStatistics = useMemo(() => {
|
||||
const sorted = [];
|
||||
cardSettings.statisticsOrder.forEach((orderId) => {
|
||||
const value = statistics.find((stat) => stat.id === orderId);
|
||||
if (value.value !== null) {
|
||||
sorted.push(value);
|
||||
}
|
||||
});
|
||||
|
||||
return sorted;
|
||||
}, [statistics, cardSettings.statisticsOrder]);
|
||||
|
||||
return (
|
||||
<div style={{ display: "flex", gap: "5px", flexWrap: "wrap", marginBottom: "5px" }}>
|
||||
{statistics.map(
|
||||
(stat, index) =>
|
||||
stat.value !== null && (
|
||||
<Card key={index}>
|
||||
<Statistic
|
||||
title={t(`production.statistics.${stat.title}`)}
|
||||
value={formatValue(stat.value, stat.suffix)}
|
||||
prefix={stat.prefix}
|
||||
suffix={stat.suffix}
|
||||
/>
|
||||
</Card>
|
||||
)
|
||||
)}
|
||||
{sortedStatistics.map((stat) => (
|
||||
<Card styles={{ body: { padding: "8px" } }} key={stat.id}>
|
||||
<Statistic
|
||||
title={t(`production.statistics.${stat.label}`)}
|
||||
value={formatValue(stat.value, stat.type)}
|
||||
prefix={stat.type === StatisticType.AMOUNT ? t("production.statistics.currency_symbol") : undefined}
|
||||
suffix={
|
||||
stat.type === StatisticType.HOURS
|
||||
? t("production.statistics.hours")
|
||||
: stat.type === StatisticType.JOBS
|
||||
? t("production.statistics.jobs")
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
ProductionStatistics.propTypes = {
|
||||
data: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
labhrs: PropTypes.object,
|
||||
larhrs: PropTypes.object,
|
||||
job_totals: PropTypes.object
|
||||
})
|
||||
).isRequired,
|
||||
cardSettings: PropTypes.shape({
|
||||
totalHrs: PropTypes.bool,
|
||||
totalLAB: PropTypes.bool,
|
||||
totalLAR: PropTypes.bool,
|
||||
jobsInProduction: PropTypes.bool,
|
||||
totalAmountInProduction: PropTypes.bool,
|
||||
totalHrsOnBoard: PropTypes.bool,
|
||||
totalLABOnBoard: PropTypes.bool,
|
||||
totalLAROnBoard: PropTypes.bool,
|
||||
jobsOnBoard: PropTypes.bool,
|
||||
totalAmountOnBoard: PropTypes.bool,
|
||||
statisticsOrder: PropTypes.arrayOf(PropTypes.number)
|
||||
}).isRequired,
|
||||
reducerData: PropTypes.shape({
|
||||
lanes: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
cards: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
metadata: PropTypes.object
|
||||
})
|
||||
).isRequired
|
||||
})
|
||||
).isRequired
|
||||
})
|
||||
};
|
||||
|
||||
export default ProductionStatistics;
|
||||
|
||||
Reference in New Issue
Block a user