Skip to content

Commit

Permalink
[#391] Fix EnterIncomeData value & dashboardData calculation
Browse files Browse the repository at this point in the history
  • Loading branch information
wayangalihpratama committed Jan 20, 2025
1 parent 2a2107b commit 8ca1e80
Show file tree
Hide file tree
Showing 11 changed files with 254 additions and 14 deletions.
12 changes: 6 additions & 6 deletions frontend/src/pages/cases/Case.js
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,6 @@ const Case = () => {
q.text.toLowerCase().includes("cost")
);
// eol generate questions

const mappedData = currentCase.segments.map((segment) => {
const answers = isEmpty(segment?.answers) ? {} : segment.answers;
const remappedAnswers = Object.keys(answers).map((key) => {
Expand All @@ -379,11 +378,12 @@ const Case = () => {
(q) =>
q.id === parseInt(questionId) &&
q.parent === 1 &&
q.commodityId === commodity.id
q.commodityId === commodity.commodity
);
const question = flattenedQuestionGroups.find(
(q) =>
q.id === parseInt(questionId) && q.commodity_id === commodity.id
q.id === parseInt(questionId) &&
q.commodity_id === commodity.commodity
);
const totalOtherDiversifiedIncome =
question?.question_type === "diversified" && !question.parent;
Expand All @@ -393,8 +393,8 @@ const Case = () => {
commodityFocus: commodityFocus,
commodityType: commodity.commodity_type,
caseCommodityId: parseInt(caseCommodityId),
commodityId: commodity.id,
commodityName: commodityNames[commodity.id],
commodityId: commodity.commodity,
commodityName: commodityNames[commodity.commodity],
questionId: parseInt(questionId),
value: answers?.[key] || 0, // if not found set as 0 to calculated inside array reduce
isTotalFeasibleFocusIncome:
Expand Down Expand Up @@ -497,7 +497,7 @@ const Case = () => {
currentFocusCommodityCoP,
total_feasible_focus_commodity_cost_of_production:
feasibleFocusCommodityCoP,
answers: answers,
answers: remappedAnswers,
};
});
CaseVisualState.update((s) => ({
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/pages/cases/components/EnterIncomeDataForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ const EnterIncomeDataDriver = ({
}

updateCurrentSegmentState({
answers: { ...segment?.answers, ...allValues },
answers: { ...segment?.answers, ...form.getFieldsValue() },
});
};

Expand Down Expand Up @@ -447,9 +447,9 @@ const EnterIncomeDataDriver = ({
)}
<Col span={24}>
<Form
form={form}
name={`enter-income-data-${segment.id}-${group.id}`}
layout="vertical"
form={form}
onValuesChange={onValuesChange}
initialValues={initialDriverValues}
>
Expand Down
88 changes: 88 additions & 0 deletions frontend/src/pages/cases/components/IncomeDriversDropdown.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import React, { useMemo } from "react";
import { Select } from "antd";
import { selectProps } from "../../../lib";
import { uniqBy, capitalize } from "lodash";

const otherCommodities = ["secondary", "tertiary"];

const IncomeDriversDropdown = ({
selectedSegmentData,
options = [],
value,
onChange,
}) => {
const driverOptionsDropdown = useMemo(() => {
if (!selectedSegmentData) {
return [];
}
const focusCommodityAnswers = selectedSegmentData.answers.filter(
(a) => a.commodityFocus && a.question.question_type !== "diversified"
);
const driverQuestions =
uniqBy(
focusCommodityAnswers.map((a) => a.question),
"id"
).find((q) => !q.parent)?.childrens || [];
const focusRes = driverQuestions
.map((q) => ({
label: q.text,
type: "focus",
value: q.id,
childrens: q.childrens.map((q) => ({ ...q, type: "focus" })),
}))
.filter((x) => x.value !== 2); // remove land driver from dropdown
// add secondary - tertiary value
const additonalCommodities = otherCommodities
.map((x) => {
const commodity = selectedSegmentData.answers.find(
(a) =>
a.commodityType === x && a.question.question_type !== "diversified"
);
if (!commodity) {
return false;
}
return {
text: `Total ${capitalize(x)} / Non Primary - ${
commodity.commodityName
}`,
type: x,
id: x,
};
})
.filter((x) => x);
// add diversified questions
let diversifiedQuestions = selectedSegmentData.answers
.filter(
(a) =>
a.commodityType === "diversified" &&
a.question.question_type === "diversified"
)
.flatMap((a) => a.question);
diversifiedQuestions = uniqBy(diversifiedQuestions, "id").map((q) => ({
...q,
type: "diversified",
}));
const diversifiedRes = [
{
label: "Diversified Income",
type: "diversified",
value: "diversified",
childrens: [...additonalCommodities, ...diversifiedQuestions],
},
];
return [...focusRes, ...diversifiedRes];
}, [selectedSegmentData]);

return (
<Select
options={driverOptionsDropdown}
placeholder="Select Driver"
value={value}
onChange={onChange}
{...selectProps}
allowClear={false}
/>
);
};

export default IncomeDriversDropdown;
30 changes: 30 additions & 0 deletions frontend/src/pages/cases/components/SegmentSelector.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React, { useEffect } from "react";
import { Radio } from "antd";
import { CaseVisualState } from "../store";

const SegmentSelector = ({ selectedSegment, setSelectedSegment }) => {
const dashboardData = CaseVisualState.useState((s) => s.dashboardData);

useEffect(() => {
if (!selectedSegment && dashboardData?.length > 0) {
setSelectedSegment(dashboardData[0].id);
}
}, [selectedSegment, dashboardData]);

const handleChangeSegmentSelector = (e) => {
const value = e.target.value;
setSelectedSegment(value);
};

return (
<Radio.Group value={selectedSegment} onChange={handleChangeSegmentSelector}>
{dashboardData.map((d) => (
<Radio.Button key={d.id} value={d.id}>
{d.name}
</Radio.Button>
))}
</Radio.Group>
);
};

export default SegmentSelector;
41 changes: 38 additions & 3 deletions frontend/src/pages/cases/components/VisualCardWrapper.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,28 @@
import React from "react";
import React, { useState, useEffect, useMemo } from "react";
import { Row, Col, Card, Space, Button } from "antd";
import { InfoCircleOutlined } from "@ant-design/icons";
import { SegmentSelector, IncomeDriversDropdown } from "../components";
import { CaseVisualState } from "../store";

const VisualCardWrapper = ({
children,
title,
bordered = false,
showSegmentSelector = false,
showIncomeDriversDropdown = false,
}) => {
const dashboardData = CaseVisualState.useState((s) => s.dashboardData);

const [selectedSegment, setSelectedSegment] = useState(null);
const [selectedDriver, setSelectedDriver] = useState(null);

const selectedSegmentData = useMemo(() => {
if (!selectedSegment || !dashboardData.length) {
return null;
}
return dashboardData.find((d) => d.id === selectedSegment);
}, [dashboardData, selectedSegment]);

const VisualCardWrapper = ({ children, title, bordered = false }) => {
return (
<Card
className={`visual-card-wrapper ${bordered ? "bordered" : ""}`}
Expand All @@ -24,7 +44,22 @@ const VisualCardWrapper = ({ children, title, bordered = false }) => {
</Row>
}
>
{children}
<Row gutter={[20, 20]}>
{showSegmentSelector && (
<Col span={24}>
<SegmentSelector
selectedSegment={selectedSegment}
setSelectedSegment={setSelectedSegment}
/>
</Col>
)}
{showIncomeDriversDropdown && (
<Col span={24}>
<IncomeDriversDropdown selectedSegmentData={selectedSegmentData} />
</Col>
)}
<Col span={24}>{children}</Col>
</Row>
</Card>
);
};
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/pages/cases/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ export { default as SegmentForm } from "./SegmentForm";
export { default as CaseForm } from "./CaseForm";
export { default as EnterIncomeDataForm } from "./EnterIncomeDataForm";
export { default as VisualCardWrapper } from "./VisualCardWrapper";
export { default as SegmentSelector } from "./SegmentSelector";
export { default as IncomeDriversDropdown } from "./IncomeDriversDropdown";
3 changes: 2 additions & 1 deletion frontend/src/pages/cases/steps/EnterIncomeData.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ const EnterIncomeData = ({ segment, setbackfunction, setnextfunction }) => {
const incomeDataDrivers = CaseVisualState.useState(
(s) => s.incomeDataDrivers
);
// TODO :: Wrong calculation on my totalIncome

const [messageApi, contextHolder] = message.useMessage();

Expand All @@ -86,6 +85,7 @@ const EnterIncomeData = ({ segment, setbackfunction, setnextfunction }) => {
.map((prev) => {
prev = {
...prev,
benchmark: null, // set to null
answers: removeUndefinedObjectValue(prev?.answers || {}),
};
let findPayload = currentCase.segments.find(
Expand All @@ -97,6 +97,7 @@ const EnterIncomeData = ({ segment, setbackfunction, setnextfunction }) => {
}
findPayload = {
...findPayload,
benchmark: null, // set to null
answers: removeUndefinedObjectValue(findPayload?.answers || {}),
};
const equal = isEqual(
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/pages/cases/steps/SetIncomeTarget.js
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ const SetIncomeTarget = ({ segment, setbackfunction, setnextfunction }) => {
.map((prev) => {
prev = {
...prev,
benchmark: null, // set to null
answers: removeUndefinedObjectValue(prev?.answers || {}),
};
let findPayload = currentCase.segments.find(
Expand All @@ -325,6 +326,7 @@ const SetIncomeTarget = ({ segment, setbackfunction, setnextfunction }) => {
}
findPayload = {
...findPayload,
benchmark: null, // set to null
answers: removeUndefinedObjectValue(findPayload?.answers || {}),
};
const equal = isEqual(
Expand Down
5 changes: 3 additions & 2 deletions frontend/src/pages/cases/steps/UnderstandIncomeGap.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { Row, Col, Card, Space } from "antd";
import {
ChartIncomeGap,
CompareIncomeGap,
ChartIncomeDriverAcrossSegments,
// ChartIncomeDriverAcrossSegments,
ChartExploreIncomeDriverBreakdown,
} from "../visualizations";

/**
Expand Down Expand Up @@ -58,7 +59,7 @@ const UnderstandIncomeGap = ({ setbackfunction, setnextfunction }) => {
<CompareIncomeGap />
</Col>
<Col span={24}>
<ChartIncomeDriverAcrossSegments />
<ChartExploreIncomeDriverBreakdown />
</Col>
{/* EOL Chart */}
</Row>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import React, { useState } from "react";
import { Card, Col, Row, Space } from "antd";
import { VisualCardWrapper } from "../components";
import { CaseVisualState, CurrentCaseState } from "../store";

const otherCommodities = ["secondary", "tertiary"];
const currentColors = [
"#1b726f", // Dark Cyan
"#81e4ab", // Pale Green
"#fecb21", // Maximum Yellow Red
"#4eb8ff", // Dodger Blue
"#ff8f4e", // Atomic Tangerine
"#725b1b", // Olive Brown
"#ad1b72", // Rose Red
"#214b72", // Prussian Blue
"#724a1b", // Raw Sienna
"#1b7272", // Skobeloff
"#721b49", // Plum Purple
"#1b724a", // Jungle Green
"#721b1b", // Persian Red
"#4a721b", // Olive Drab
"#1b4a72", // Dark Slate Blue
"#1b7261", // Tropical Rain Forest
];

const feasibleColors = [
"#9cc2c1", // Silver Sand (Lighter Version of #1b726f)
"#ddf8e9", // Honeydew (Lighter Version of #81e4ab)
"#ffeeb8", // Moccasin (Lighter Version of #fecb21)
"#d0ecff", // Lavender Blue (Lighter Version of #4eb8ff)
"#ffe1d0", // Peach Yellow (Lighter Version of #ff8f4e)
"#9e8a4d", // Shadow (Lighter Version of #725b1b)
"#d44a94", // Blush (Lighter Version of #ad1b72)
"#41799d", // Steel Blue (Lighter Version of #214b72)
"#ad8a4d", // Café Au Lait (Lighter Version of #724a1b)
"#4d9e9e", // Viridian Green (Lighter Version of #1b7272)
"#94486e", // Mulberry (Lighter Version of #721b49)
"#4d944a", // Turtle Green (Lighter Version of #1b724a)
"#944848", // Chestnut Rose (Lighter Version of #721b1b)
"#6e9448", // La Palma (Lighter Version of #4a721b)
"#486e94", // Jelly Bean (Lighter Version of #1b4a72)
"#487e6e", // Jaguar (Lighter Version of #1b7261)
];

const ChartExploreIncomeDriverBreakdown = () => {
const dashboardData = CaseVisualState.useState((s) => s.dashboardData);
const currentCase = CurrentCaseState.useState((s) => s);

const [axisTitle, setAxisTitle] = useState(currentCase.currency);
const [loading, setLoading] = useState(false);

return (
<Card className="card-visual-wrapper">
<Row gutter={[20, 20]} align="middle">
<Col span={16}>
<VisualCardWrapper
title="Explore income driver breakdown"
showIncomeDriversDropdown={true}
showSegmentSelector={true}
bordered
>
Chart
</VisualCardWrapper>
</Col>
<Col span={8}>
<Space direction="vertical">
<div className="section-title">Explore income driver breakdown</div>
<div className="section-description">
This graph lets you dive into a specific income driver and see how
its sub-components contribute. Use it to identify the largest and
smallest contributors and spot variations across segments
</div>
</Space>
</Col>
</Row>
</Card>
);
};

export default ChartExploreIncomeDriverBreakdown;
1 change: 1 addition & 0 deletions frontend/src/pages/cases/visualizations/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export { default as EnterIncomeDataVisual } from "./EnterIncomeDataVisual";
export { default as ChartIncomeGap } from "./ChartIncomeGap";
export { default as CompareIncomeGap } from "./CompareIncomeGap";
export { default as ChartIncomeDriverAcrossSegments } from "./ChartIncomeDriverAcrossSegments";
export { default as ChartExploreIncomeDriverBreakdown } from "./ChartExploreIncomeDriverBreakdown";

0 comments on commit 8ca1e80

Please sign in to comment.