Added graphs, fixed rps total calculation
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
import { Skeleton, Typography } from "antd";
|
||||
import React, { useMemo } from "react";
|
||||
import { Cell, Pie, PieChart, ResponsiveContainer } from "recharts";
|
||||
import ErrorResultAtom from "../error-result/error-result.atom";
|
||||
import Dinero from "dinero.js";
|
||||
export default function JobPartsGraphAtom({
|
||||
job,
|
||||
loading,
|
||||
price = "act_price",
|
||||
}) {
|
||||
const data = useMemo(() => {
|
||||
if (!job) return [];
|
||||
|
||||
const sums = job.joblines.reduce((acc, val) => {
|
||||
if (!acc[val.part_type]) {
|
||||
acc[val.part_type] = Dinero();
|
||||
}
|
||||
|
||||
acc[val.part_type] = acc[val.part_type].add(
|
||||
Dinero({ amount: Math.round((val[price] || 0) * 100) })
|
||||
);
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
return Object.keys(sums).map((key) => {
|
||||
return {
|
||||
name: key,
|
||||
value: sums[key].getAmount() / 100,
|
||||
label: sums[key].toFormat(),
|
||||
color: getColor(key),
|
||||
};
|
||||
});
|
||||
}, [job, price]);
|
||||
|
||||
if (loading) return <Skeleton active />;
|
||||
if (!job) return <ErrorResultAtom title="Error displaying job data." />;
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{ display: "flex", flexDirection: "column", alignItems: "center" }}
|
||||
>
|
||||
<Typography.Title level={4}>
|
||||
{price === "act_price" ? "Actual Price" : "Database Price"}
|
||||
</Typography.Title>
|
||||
<ResponsiveContainer width="100%" height={250}>
|
||||
<PieChart>
|
||||
<Pie
|
||||
data={data}
|
||||
innerRadius={40}
|
||||
outerRadius={50}
|
||||
fill="#8884d8"
|
||||
paddingAngle={5}
|
||||
dataKey="value"
|
||||
label={(entry) => `${entry.name} - ${entry.label}`}
|
||||
labelLine
|
||||
>
|
||||
{data.map((entry, index) => (
|
||||
<Cell key={`cell-${index}`} fill={entry.color} />
|
||||
))}
|
||||
</Pie>
|
||||
</PieChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const getColor = (key) => {
|
||||
switch (key) {
|
||||
case "PAA":
|
||||
return "tomato";
|
||||
case "PAL":
|
||||
return "dodgeblue";
|
||||
case "PAN":
|
||||
return "seagreen";
|
||||
default:
|
||||
return "slategray";
|
||||
}
|
||||
};
|
||||
@@ -84,7 +84,7 @@ export default function JobLinesTableMolecule({ loading, job }) {
|
||||
dataSource={joblines}
|
||||
scroll={{
|
||||
x: true,
|
||||
//y: "40rem"
|
||||
y: "20rem",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -1,28 +1,15 @@
|
||||
import { Skeleton, Space, Statistic } from "antd";
|
||||
import { Skeleton, Statistic } from "antd";
|
||||
import Dinero from "dinero.js";
|
||||
import React, { useMemo } from "react";
|
||||
import ErrorResultAtom from "../../atoms/error-result/error-result.atom";
|
||||
import TargetPriceDiffPcAtom from "../../atoms/target-price-diff/target-price-diff-pc.atom";
|
||||
import _ from "lodash";
|
||||
import Dinero from "dinero.js";
|
||||
|
||||
export default function JobsTargetsStatsMolecule({ loading, job }) {
|
||||
const currentRpsPc = useMemo(() => {
|
||||
if (!job) {
|
||||
return 0;
|
||||
}
|
||||
return (
|
||||
(_.sum(job.joblines.map((jl) => jl.price_diff_pc)) /
|
||||
job.joblines.length) *
|
||||
100
|
||||
).toFixed(1);
|
||||
}, [job]);
|
||||
|
||||
const currentRpsDollars = useMemo(() => {
|
||||
if (!job) {
|
||||
return 0;
|
||||
}
|
||||
return job.joblines.reduce((acc, val) => {
|
||||
console.log("val.price_diff :>> ", val.price_diff);
|
||||
if (val.price_diff > 0) {
|
||||
return acc.add(
|
||||
Dinero({ amount: Math.round((val.price_diff || 0) * 100) })
|
||||
@@ -33,6 +20,17 @@ export default function JobsTargetsStatsMolecule({ loading, job }) {
|
||||
}, Dinero());
|
||||
}, [job]);
|
||||
|
||||
const currentRpsPc = useMemo(() => {
|
||||
//TODO Redo this to do total of db price - act price / db price
|
||||
if (!job) {
|
||||
return 0;
|
||||
}
|
||||
const dbPriceSum = job.joblines.reduce((acc, val) => {
|
||||
return acc + val.db_price;
|
||||
}, 0);
|
||||
return (currentRpsDollars.getAmount() / dbPriceSum).toFixed(1);
|
||||
}, [job, currentRpsDollars]);
|
||||
|
||||
if (loading) return <Skeleton active />;
|
||||
if (!job) return <ErrorResultAtom title="Error displaying job data." />;
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import { createStructuredSelector } from "reselect";
|
||||
import { QUERY_JOB_BY_PK } from "../../../graphql/jobs.queries";
|
||||
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";
|
||||
import JobsDetailDescriptionMolecule from "../../molecules/jobs-detail-description/jobs-detail-description.molecule";
|
||||
import JobsLinesTableMolecule from "../../molecules/jobs-lines-table/jobs-lines-table.molecule";
|
||||
import JobsTargetsStatsMolecule from "../../molecules/jobs-targets-stats/jobs-targets-stats.molecule";
|
||||
@@ -40,14 +41,25 @@ export function JobsDetailOrganism({ selectedJobId }) {
|
||||
loading={loading}
|
||||
job={data ? data.jobs_by_pk : null}
|
||||
/>
|
||||
<JobsTargetsStatsMolecule
|
||||
loading={loading}
|
||||
job={data ? data.jobs_by_pk : null}
|
||||
/>
|
||||
<JobsLinesTableMolecule
|
||||
loading={loading}
|
||||
job={data ? data.jobs_by_pk : {}}
|
||||
/>
|
||||
<JobsTargetsStatsMolecule
|
||||
loading={loading}
|
||||
job={data ? data.jobs_by_pk : null}
|
||||
/>
|
||||
<div style={{ display: "flex", justifyContent: "space-evenly" }}>
|
||||
<JobsPartsGraphAtom
|
||||
job={data ? data.jobs_by_pk : null}
|
||||
loading={loading}
|
||||
/>
|
||||
<JobsPartsGraphAtom
|
||||
job={data ? data.jobs_by_pk : null}
|
||||
loading={loading}
|
||||
price="db_price"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { SyncOutlined } from "@ant-design/icons";
|
||||
import { useQuery } from "@apollo/client";
|
||||
import { Button, Divider, List, Space, Spin } from "antd";
|
||||
import { Button, List, Spin } from "antd";
|
||||
import React, { useState } from "react";
|
||||
import InfiniteScroll from "react-infinite-scroller";
|
||||
import { connect } from "react-redux";
|
||||
|
||||
Reference in New Issue
Block a user