- 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:
Dave Richer
2024-07-31 14:04:50 -04:00
parent bbc446ef01
commit 60908b123d
8 changed files with 7181 additions and 7030 deletions

View File

@@ -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;