Refactored target percentage to use redux and only be calculated once per job.

This commit is contained in:
Patrick Fic
2020-10-19 13:34:23 -07:00
parent a11c44e444
commit 2c62eb09b7
11 changed files with 108 additions and 85 deletions

View File

@@ -1,9 +1,9 @@
export default (part_type) => {
switch (part_type) {
case "PAA":
return "Aftermarket";
return "A/M";
case "PAE":
return "Existing";
return "Exist.";
case "PAN":
return "OEM";
case "PAL":

View File

@@ -1,40 +1,22 @@
import React, { useMemo } from "react";
import { AlertFilled } from "@ant-design/icons";
import React from "react";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../../redux/user/user.selectors";
import { selectSelectedJobTargetPc } from "../../../redux/application/application.selectors";
import "./price-diff-pc-formatter.styles.scss";
import { AlertFilled } from "@ant-design/icons";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
});
const mapDispatchToProps = (dispatch) => ({
//setUserLanguage: language => dispatch(setUserLanguage(language))
selectedJobTargetPc: selectSelectedJobTargetPc,
});
export function PriceDiffPcFormatterAtom({
bodyshop,
price_diff_pc,
group,
v_age,
selectedJobTargetPc,
}) {
const metTarget = useMemo(() => {
const targetsForGroup = bodyshop.targets.filter((t) => t.group === group);
if (!targetsForGroup) return 0;
const targetPc = targetsForGroup.filter(
(t) => t.ageGte <= v_age && (t.ageLt ? t.ageLt > v_age : true)
);
if (targetPc.length === 0) return false;
else if (targetPc.length === 1) return price_diff_pc >= targetPc[0].target;
else {
alert("Multiple targets match.");
return false;
}
}, [bodyshop, group, price_diff_pc, v_age]);
return (
<div
style={{
color: metTarget ? "green" : "red",
color: price_diff_pc > selectedJobTargetPc ? "green" : "red",
display: "flex",
alignItems: "center",
}}
@@ -46,7 +28,4 @@ export function PriceDiffPcFormatterAtom({
</div>
);
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(PriceDiffPcFormatterAtom);
export default connect(mapStateToProps, null)(PriceDiffPcFormatterAtom);

View File

@@ -1,39 +0,0 @@
import { Statistic } from "antd";
import React, { useMemo } from "react";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../../redux/user/user.selectors";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
});
const mapDispatchToProps = (dispatch) => ({
//setUserLanguage: language => dispatch(setUserLanguage(language))
});
export function PriceDiffPcFormatterAtom({ bodyshop, group, v_age }) {
const metTarget = useMemo(() => {
const targetsForGroup = bodyshop.targets.filter((t) => t.group === group);
if (!targetsForGroup) return 0;
const targetPc = targetsForGroup.filter(
(t) => t.ageGte <= v_age && (t.ageLt ? t.ageLt > v_age : true)
);
if (targetPc.length === 0) return 0;
else if (targetPc.length === 1) return targetPc[0].target;
else {
return 0;
}
}, [bodyshop, group, v_age]);
return (
<Statistic
title="Target RPS %"
value={(metTarget * 100).toFixed(1)}
suffix="%"
/>
);
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(PriceDiffPcFormatterAtom);

View File

@@ -1,10 +1,27 @@
import { Skeleton, Statistic } from "antd";
import Dinero from "dinero.js";
import React, { useMemo } from "react";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectSelectedJobTargetPc } from "../../../redux/application/application.selectors";
import ErrorResultAtom from "../../atoms/error-result/error-result.atom";
import TargetPriceDiffPcAtom from "../../atoms/target-price-diff/target-price-diff-pc.atom";
export default function JobsTargetsStatsMolecule({ loading, job }) {
const mapStateToProps = createStructuredSelector({
selectedJobTargetPc: selectSelectedJobTargetPc,
});
const mapDispatchToProps = (dispatch) => ({
//setUserLanguage: language => dispatch(setUserLanguage(language))
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(JobsTargetsStatsMolecule);
export function JobsTargetsStatsMolecule({
loading,
job,
selectedJobTargetPc,
}) {
const currentRpsDollars = useMemo(() => {
if (!job) {
return 0;
@@ -44,8 +61,20 @@ export default function JobsTargetsStatsMolecule({ loading, job }) {
marginBottom: "1rem",
}}
>
<TargetPriceDiffPcAtom v_age={job.v_age} group={job.group} />
<Statistic title="Current RPS %" value={currentRpsPc} suffix="%" />
<Statistic
title="Target RPS %"
value={(selectedJobTargetPc * 100).toFixed(1)}
suffix="%"
/>
<Statistic
title="Current RPS %"
valueStyle={{
color:
selectedJobTargetPc * 100 > currentRpsPc ? "tomato" : "seagreen",
}}
value={currentRpsPc}
suffix="%"
/>
<Statistic title="Current RPS $" value={currentRpsDollars.toFormat()} />
</div>
);

View File

@@ -1,9 +1,10 @@
import { useQuery } from "@apollo/client";
import { Result } from "antd";
import React from "react";
import React, { useEffect } from "react";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { QUERY_JOB_BY_PK } from "../../../graphql/jobs.queries";
import { setSelectedJobTargetPc } from "../../../redux/application/application.actions";
import { selectSelectedJobId } from "../../../redux/application/application.selectors";
import ErrorResultAtom from "../../atoms/error-result/error-result.atom";
import JobsPartsGraphAtom from "../../atoms/jobs-parts-graph/jobs-parts-graph.atom";
@@ -18,14 +19,23 @@ const mapStateToProps = createStructuredSelector({
});
const mapDispatchToProps = (dispatch) => ({
//setUserLanguage: language => dispatch(setUserLanguage(language))
setSelectedJobTargetPc: (job) => dispatch(setSelectedJobTargetPc(job)),
});
export function JobsDetailOrganism({ selectedJobId }) {
export function JobsDetailOrganism({ selectedJobId, setSelectedJobTargetPc }) {
const { loading, error, data } = useQuery(QUERY_JOB_BY_PK, {
variables: { jobId: selectedJobId },
skip: !selectedJobId,
});
useEffect(() => {
if (data)
setSelectedJobTargetPc({
group: data.jobs_by_pk.group,
v_age: data.jobs_by_pk.v_age,
});
}, [data, setSelectedJobTargetPc]);
if (!selectedJobId) return <Result title="No job selected." />;
if (error)
return (