Aded joblines status view and updated graph to use the view. BOD-110
This commit is contained in:
@@ -145,7 +145,7 @@ export function JobDetailCards({ setPrintCenterContext }) {
|
||||
data={data ? data.jobs_by_pk : null}
|
||||
/>
|
||||
</Col>
|
||||
<Col {...colBreakPoints}>
|
||||
<Col span={24}>
|
||||
<JobDetailCardsPartsComponent
|
||||
loading={loading}
|
||||
data={data ? data.jobs_by_pk : null}
|
||||
|
||||
@@ -1,14 +1,144 @@
|
||||
import React from "react";
|
||||
import React, { useState, useMemo } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import CardTemplate from "./job-detail-cards.template.component";
|
||||
import { PieChart, Pie, Sector, ResponsiveContainer } from "recharts";
|
||||
|
||||
export default function JobDetailCardsPartsComponent({ loading, data }) {
|
||||
const { t } = useTranslation();
|
||||
const { joblines_status } = data;
|
||||
// console.log(
|
||||
// "JobDetailCardsPartsComponent -> joblines_stats",
|
||||
// joblines_status
|
||||
// );
|
||||
|
||||
const memoizedData = useMemo(() => Calculatedata(joblines_status), [
|
||||
joblines_status,
|
||||
]);
|
||||
|
||||
console.log("memoizedData :>> ", memoizedData);
|
||||
const [state, setState] = useState({ activeIndex: 0 });
|
||||
|
||||
const onPieEnter = (data, index) => {
|
||||
setState({
|
||||
activeIndex: index,
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<CardTemplate loading={loading} title={t("jobs.labels.cards.parts")}>
|
||||
Placeholder piechart.
|
||||
<PieChart width={400} height={400}>
|
||||
<Pie
|
||||
activeIndex={state.activeIndex}
|
||||
activeShape={renderActiveShape}
|
||||
data={memoizedData}
|
||||
cx={200}
|
||||
cy={200}
|
||||
innerRadius={60}
|
||||
outerRadius={80}
|
||||
fill="#8884d8"
|
||||
dataKey="value"
|
||||
onMouseEnter={onPieEnter}
|
||||
/>
|
||||
</PieChart>
|
||||
</CardTemplate>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const Calculatedata = (data) => {
|
||||
console.log("calculating data", data);
|
||||
|
||||
if (data.length > 0) {
|
||||
const statusMapping = {};
|
||||
data.map((i) => {
|
||||
if (!statusMapping[i.status])
|
||||
statusMapping[i.status] = { name: i.status || "No Status*", value: 0 };
|
||||
statusMapping[i.status].value = statusMapping[i.status].value + i.count;
|
||||
return null;
|
||||
});
|
||||
return Object.keys(statusMapping).map((key) => {
|
||||
return statusMapping[key];
|
||||
});
|
||||
} else {
|
||||
return [
|
||||
{ name: "Group A", value: 400 },
|
||||
{ name: "Group B", value: 300 },
|
||||
{ name: "Group C", value: 300 },
|
||||
{ name: "Group D", value: 200 },
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
const renderActiveShape = (props) => {
|
||||
const RADIAN = Math.PI / 180;
|
||||
const {
|
||||
cx,
|
||||
cy,
|
||||
midAngle,
|
||||
innerRadius,
|
||||
outerRadius,
|
||||
startAngle,
|
||||
endAngle,
|
||||
fill,
|
||||
payload,
|
||||
percent,
|
||||
value,
|
||||
} = props;
|
||||
const sin = Math.sin(-RADIAN * midAngle);
|
||||
const cos = Math.cos(-RADIAN * midAngle);
|
||||
const sx = cx + (outerRadius + 10) * cos;
|
||||
const sy = cy + (outerRadius + 10) * sin;
|
||||
const mx = cx + (outerRadius + 30) * cos;
|
||||
const my = cy + (outerRadius + 30) * sin;
|
||||
const ex = mx + (cos >= 0 ? 1 : -1) * 22;
|
||||
const ey = my;
|
||||
const textAnchor = cos >= 0 ? "start" : "end";
|
||||
|
||||
return (
|
||||
<g>
|
||||
<text x={cx} y={cy} dy={8} textAnchor="middle" fill={fill}>
|
||||
{payload.name}
|
||||
</text>
|
||||
<Sector
|
||||
cx={cx}
|
||||
cy={cy}
|
||||
innerRadius={innerRadius}
|
||||
outerRadius={outerRadius}
|
||||
startAngle={startAngle}
|
||||
endAngle={endAngle}
|
||||
fill={fill}
|
||||
/>
|
||||
<Sector
|
||||
cx={cx}
|
||||
cy={cy}
|
||||
startAngle={startAngle}
|
||||
endAngle={endAngle}
|
||||
innerRadius={outerRadius + 6}
|
||||
outerRadius={outerRadius + 10}
|
||||
fill={fill}
|
||||
/>
|
||||
<path
|
||||
d={`M${sx},${sy}L${mx},${my}L${ex},${ey}`}
|
||||
stroke={fill}
|
||||
fill="none"
|
||||
/>
|
||||
<circle cx={ex} cy={ey} r={2} fill={fill} stroke="none" />
|
||||
<text
|
||||
x={ex + (cos >= 0 ? 1 : -1) * 12}
|
||||
y={ey}
|
||||
textAnchor={textAnchor}
|
||||
fill="#333"
|
||||
>{`Count: ${value}`}</text>
|
||||
<text
|
||||
x={ex + (cos >= 0 ? 1 : -1) * 12}
|
||||
y={ey}
|
||||
dy={18}
|
||||
textAnchor={textAnchor}
|
||||
fill="#999"
|
||||
>
|
||||
{`(${(percent * 100).toFixed(2)}%)`}
|
||||
</text>
|
||||
</g>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -4,26 +4,14 @@ import { connect } from "react-redux";
|
||||
import {
|
||||
Area,
|
||||
Bar,
|
||||
|
||||
|
||||
CartesianGrid, ComposedChart,
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Legend, Line,
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ResponsiveContainer, Tooltip, XAxis,
|
||||
YAxis
|
||||
CartesianGrid,
|
||||
ComposedChart,
|
||||
Legend,
|
||||
Line,
|
||||
ResponsiveContainer,
|
||||
Tooltip,
|
||||
XAxis,
|
||||
YAxis,
|
||||
} from "recharts";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
|
||||
@@ -415,6 +415,11 @@ export const QUERY_JOB_CARD_DETAILS = gql`
|
||||
ownr_ln
|
||||
ownr_ph1
|
||||
ownr_ea
|
||||
joblines_status {
|
||||
part_type
|
||||
count
|
||||
status
|
||||
}
|
||||
owner {
|
||||
id
|
||||
allow_text_message
|
||||
@@ -463,6 +468,7 @@ export const QUERY_JOB_CARD_DETAILS = gql`
|
||||
date_closed
|
||||
date_scheduled
|
||||
date_estimated
|
||||
|
||||
notes {
|
||||
id
|
||||
text
|
||||
|
||||
Reference in New Issue
Block a user