Skip to content

Commit

Permalink
Feature/391 user journey segment page lib per page (#392)
Browse files Browse the repository at this point in the history
* [#391] Move enableEditCase state into general CaseUIState

* [#391] Initial layout for EnterIncomeData visual

* [#391] Add income target card on EnterIncomeData page

* [#391] Create VisualCardWrapper component

* [#391] Render household income bar chart

* [#391] Init UnderstandIncomeGap page

* [#391] Create visuals component

* [#391] Fetch questions on wrapper

* [#391] Create dashboardData state

* [#391] Render ChartIncomeGap

* [#391] Create CompareIncomeGap visualization

* [#391] Handle new user journey when prev case doesn't have any segments yet

* [#391] Debugging with test full case data for current complete new user journey

* [#391] Fix EnterIncomeData page onLoad & onValuesChange

* [#391] Refine EnterIncomeData calculation

* [#391] Handle enableEditCase state

* [#391] Fix EnterIncomeData value & dashboardData calculation

* [#391] Add answers & benchmark into segment put endpoint obj

* [#391] Create ChartExploreIncomeDriversBreakdown

* [#393] Initial AssessImpactMitigationStrategies page

* [#391] Create biggest impact on income & monetary contribution chart

* [#393] Initial binning driver form

* [#393] Set sensitivity analysis value into state
  • Loading branch information
wayangalihpratama authored Jan 20, 2025
1 parent 92840c9 commit 282ab33
Show file tree
Hide file tree
Showing 37 changed files with 2,962 additions and 202 deletions.
9 changes: 4 additions & 5 deletions backend/routes/segment.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
from db.connection import get_session
from models.segment import (
SegmentBase,
SegmentDict,
SegmentUpdateBase,
SegmentWithAnswersDict,
)
Expand All @@ -24,7 +23,7 @@

@segment_route.post(
"/segment",
response_model=List[SegmentDict],
response_model=List[SegmentWithAnswersDict],
summary="create segment",
name="segment:create",
tags=["Segment"],
Expand All @@ -45,12 +44,12 @@ def create_segment(
session=session, case_id=case_id, user_id=user.id
)
segments = crud_segment.add_segment(session=session, payloads=payload)
return [s.serialize for s in segments]
return [s.serialize_with_answers for s in segments]


@segment_route.put(
"/segment",
response_model=List[SegmentDict],
response_model=List[SegmentWithAnswersDict],
summary="update segment",
name="segment:update",
tags=["Segment"],
Expand All @@ -71,7 +70,7 @@ def update_segment(
crud_case.case_updated_by(
session=session, case_id=case_id, user_id=user.id
)
return [s.serialize for s in segments]
return [s.serialize_with_answers for s in segments]


@segment_route.delete(
Expand Down
26 changes: 26 additions & 0 deletions backend/tests/test_040_segment.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ async def test_create_segment(
"adult": 2.0,
"child": 3.0,
"number_of_farmers": None,
"answers": {},
"benchmark": None,
}
]
# with admin user cred
Expand Down Expand Up @@ -104,6 +106,8 @@ async def test_create_segment(
"adult": 3.0,
"child": 2.0,
"number_of_farmers": None,
"answers": {},
"benchmark": None,
},
{
"id": res[1]["id"],
Expand All @@ -114,6 +118,13 @@ async def test_create_segment(
"adult": 4.0,
"child": 2.0,
"number_of_farmers": None,
"answers": {
"current-1-1": 10000.0,
"current-1-2": None,
"feasible-1-1": None,
"feasible-1-2": None,
},
"benchmark": None,
},
]

Expand Down Expand Up @@ -156,6 +167,8 @@ async def test_update_segment(
"adult": 4.0,
"child": 2.0,
"number_of_farmers": None,
"answers": {},
"benchmark": None,
}
]
# with admin user cred
Expand Down Expand Up @@ -227,6 +240,8 @@ async def test_update_segment(
"adult": 5.0,
"child": 0.0,
"number_of_farmers": None,
"answers": {},
"benchmark": None,
},
{
"id": 2,
Expand All @@ -237,6 +252,8 @@ async def test_update_segment(
"adult": 6.0,
"child": 0.0,
"number_of_farmers": None,
"answers": {},
"benchmark": None,
},
{
"id": 3,
Expand All @@ -247,5 +264,14 @@ async def test_update_segment(
"adult": 4.0,
"child": 2.0,
"number_of_farmers": None,
"answers": {
"current-1-1": 10000.0,
"current-1-2": None,
"current-1-3": None,
"feasible-1-1": None,
"feasible-1-2": None,
"feasible-1-3": 500.0,
},
"benchmark": None,
},
]
48 changes: 48 additions & 0 deletions frontend/src/App.scss
Original file line number Diff line number Diff line change
Expand Up @@ -389,3 +389,51 @@
font-family: "TabletGothic" !important;
font-size: 12px;
}

.visual-card-wrapper {
padding: 0;
border-radius: 20px;

.ant-card-head {
padding: 12px 24px;
background: #dfdfdf;
border-radius: 20px 20px 0px 0px;

.title {
font-family: "RocGrotesk";
font-size: 16px;
font-style: normal;
font-weight: 700;
line-height: 157.15%;
}

.button-export {
border: 1px solid #01625f;
font-weight: 600;
font-size: 12px;
background: transparent;
color: #01625f;
border-radius: 40px;

&:hover {
border: 2px solid #01625f;
}
}
}

.ant-card-body {
padding: 18px 24px;
border-radius: 0px 0px 20px 20px;
background: #fff;
}

&.bordered {
.ant-card-head {
border: 1px solid #dfdfdf;
}
.ant-card-body {
border: 1px solid #dfdfdf;
border-top: none;
}
}
}
142 changes: 142 additions & 0 deletions frontend/src/components/chart/lib/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import { isEmpty } from "lodash";
import {
Legend,
TextStyle,
AxisLabelFormatter,
LabelStyle,
incomeTargetChartOption,
Color,
backgroundColor,
Easing,
NoData,
formatNumberToString,
thousandFormatter,
} from "../options/common";

export const getColumnStackBarOptions = ({
xAxis = { name: "", axisLabel: {} },
yAxis = { name: "", min: 0, max: 0 },
origin = [],
series = [],
showLabel = false,
grid = {},
}) => {
if (isEmpty(series) || !series) {
return NoData;
}

const legends = series.map((x) => ({
name: x.name,
icon: x?.symbol || "circle",
}));
const xAxisData = origin.map((x) => x.name);

const options = {
legend: {
...Legend,
data: legends,
top: 15,
left: "right",
orient: "vertical",
},
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow",
},
formatter: function (params) {
let res = "<div>";
res += "<b>" + params[0].axisValueLabel + "</b>";
res += "<ul style='list-style-type: none; margin: 0; padding: 0;'>";
params.forEach((param) => {
res += "<li>";
res += "<span>";
res += param.marker;
res += param.seriesName;
res += "</span>";
res +=
"<b style='float: right; margin-left: 12px;'>" +
thousandFormatter(param.value) +
"</b>";
res += "</li>";
});
res += "</ul>";
res += "</div>";
return res;
},
backgroundColor: "#ffffff",
...TextStyle,
},
grid: {
top: grid?.top ? grid.top : 25,
left: grid?.left ? grid.left : 50,
right: grid?.right ? grid.right : 190,
bottom: grid?.bottom ? grid.bottom : 25,
show: true,
containLabel: true,
label: {
color: "#222",
...TextStyle,
},
},
xAxis: {
...xAxis,
nameTextStyle: { ...TextStyle },
nameLocation: "middle",
nameGap: 50,
boundaryGap: true,
type: "category",
data: xAxisData,
axisLabel: {
width: 100,
interval: 0,
overflow: "break",
...TextStyle,
color: "#4b4b4e",
formatter: AxisLabelFormatter?.formatter,
...xAxis.axisLabel,
},
axisTick: {
alignWithLabel: true,
},
},
yAxis: {
...yAxis,
type: "value",
nameTextStyle: { ...TextStyle },
nameLocation: "middle",
nameGap: 75,
axisLabel: {
formatter: function (value) {
return formatNumberToString(value);
},
...TextStyle,
color: "#9292ab",
},
},
series: series.map((s) => {
s = {
...s,
barMaxWidth: 50,
emphasis: {
focus: "series",
},
};
if (s.type === "line") {
return { ...incomeTargetChartOption, ...s };
}
return {
...s,
label: {
...LabelStyle.label,
show: showLabel,
position: "inside",
},
};
}),
...Color,
...backgroundColor,
...Easing,
};
return options;
};
4 changes: 4 additions & 0 deletions frontend/src/components/chart/options/Bar.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
axisTitle,
NoData,
thousandFormatter,
formatNumberToString,
} from "./common";
import { sortBy, isEmpty, sumBy } from "lodash";

Expand Down Expand Up @@ -68,6 +69,9 @@ const Bar = ({
axisLabel: {
...TextStyle,
color: "#9292ab",
formatter: function (value) {
return formatNumberToString(value);
},
},
},
[horizontal ? "yAxis" : "xAxis"]: {
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/components/chart/options/ColumnBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
Legend,
thousandFormatter,
LabelStyle,
formatNumberToString,
} from "./common";
import { sortBy, isEmpty, groupBy, orderBy } from "lodash";

Expand Down Expand Up @@ -148,6 +149,9 @@ const ColumnBar = ({
axisLabel: {
...TextStyle,
color: "#9292ab",
formatter: function (value) {
return formatNumberToString(value);
},
},
},
[horizontal ? "yAxis" : "xAxis"]: {
Expand Down
10 changes: 6 additions & 4 deletions frontend/src/components/layout/ContentLayout.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ const ContentLayout = ({
justify="start"
className="title-wrapper"
>
<Col span={titleRighContent ? 12 : 24}>
<Col span={titleRighContent ? 8 : 24}>
{title ? (
<div data-testid="title" className="title">
{title}
Expand All @@ -111,9 +111,11 @@ const ContentLayout = ({
)}
</Col>
{titleRighContent && (
<Col span={12}>
<Row justify="end">
<Col>{titleRighContent}</Col>
<Col span={16}>
<Row>
<Col span={24} align="end">
{titleRighContent}
</Col>
</Row>
</Col>
)}
Expand Down
Loading

0 comments on commit 282ab33

Please sign in to comment.