Skip to content

Commit

Permalink
Develop (#397)
Browse files Browse the repository at this point in the history
* New User Journey (#388)

* Feature/user journey step 1

* [#383] Move current case page into old-cases

* [#383] Init new case page

* [#383] Load cases data in new case page

* [#383] New cases page

* [#383] Implement new case filter

* [#383] Implement new case settings modal visual

* [#383] Handle case settings behaviour with new state management

* [#383] Handle save new case settings without segments value

* [#383] Support add segments when create case settings

* [#383] Support segments payload on update case endpoint

* [#383] Handle new case setting with segments correctly

* [#383] Breakdown case settings into components

* [#383] Initial new case detail page with sidebar

* [#383] Handle load case detail in edit case page

* [#383] Set step sidebar as fixed sidebar

* [#383] Render case title and case settings form in CaseWrapper

* [#383] Refactor the export function, static, & lib to correct place

* [#383] Load current case settings value correctly

* [#385] Refine step path and load related page

* [#385] Handle close case setting modal after saved success

* [#385] Init set income target page layout

* [#385] Refine segment tabs as a wrapper to be reused in another page

* [#385] Load region options in set an income target page

* [#385] Load income target value and source when select region

* [#385] Add segment id into form name for SetIncomeTarget

* [#385] Fix yarn lint

* [#385] Finalize set income target state update

* [#385] Load initial value for SetIncomeTarget

* [#385] Add Back/Next button on parent and send the props into children

* [#385] Handle change hh adult/child value

* [#385] Handle save SetIncomeTarget

* [#383] Handle number of farmers field on segment

* Feature/389 user journey breakdown step pages into different url (#390)

* [#389] Handle EnterIncomeData page button function

* [#389] Handle case button on UnderstandIncomeGap

* [#389] Handle case button on AssessImpactMitigationStrategies

* [#389] Handle case button on ClosingGap

* [#389] Handle EnterIncomeData right element (visuals) position in SegmentTabsWrapper

* [#389] Get commodity questions

* [#389] Add Total Income section

* [#389] Fetch and regroup driver questions to follow new design layout

* [#389] Move renderPercentageTag fn into lib file

* [#389] Initial render driver questions

* [#389] Render unit name and current/feasible value field

* [#389] Handle disable input/lock when questions breakdown

* [#389] Handle onValuesChange of income drivers

* [#389] Handle total value in section, parent, and general total income

* [#389] Handle income percentage value

* [#389] Init handle save EnterIncomeData

* [#389] Handle save EnterIncomeData value properly

* Feature/391 user journey segment page lib per page (#392)

* [#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

* Feature/395 user journey update state management (#396)

* [#395] Create line chart for sensitivity analysis page

* [#395] Create sensitivity analysis heatmap chart

* [#395] Create adjust income target section

* [#395] Handle save sensitivity analysis config

* [#395] Handle initial load sensitivity analysis data

* [#395] Fix onLoad sensitivity analysis bugs

* [#395] Initial adjut income target modal

* [#395] Add style into adjust income target modal

* [#395] Handle save adjusted income target

* [#395] Move segment tabs wrapper into a layout component

* [#395] Initial scenario modeling page

* [#395] Initial render driver question for scenario modeling

* [#395] Add segment selector into scenario modeling page

* [#395] Refactor scenario modeling input

* [#395] Create tree select dropdown for scenario modeling

* [#395] Manage scenario form detail value & scenario driver

* [#395] Manage scenario income driver initial and on change value
  • Loading branch information
wayangalihpratama authored Jan 23, 2025
1 parent c0f6987 commit a15f4f7
Show file tree
Hide file tree
Showing 17 changed files with 2,062 additions and 118 deletions.
3 changes: 2 additions & 1 deletion frontend/src/App.scss
Original file line number Diff line number Diff line change
Expand Up @@ -401,10 +401,11 @@

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

.button-export {
Expand Down
153 changes: 71 additions & 82 deletions frontend/src/pages/cases/Case.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useState, useEffect, useMemo } from "react";
import { Spin, Tabs, Row, Col } from "antd";
import { CaseWrapper } from "./layout";
import React, { useState, useEffect } from "react";
import { Spin } from "antd";
import { CaseWrapper, SegmentTabsWrapper } from "./layout";
import { useParams, useNavigate } from "react-router-dom";
import { api, flatten, getFunctionDefaultValue } from "../../lib";
import {
Expand Down Expand Up @@ -80,90 +80,12 @@ const renderPage = (key, navigate) => {
case stepPath.step4.label:
return <AssessImpactMitigationStrategies />;
case stepPath.step5.label:
return (
<SegmentTabsWrapper>
<ClosingGap />
</SegmentTabsWrapper>
);
return <ClosingGap />;
default:
return navigate("/not-found");
}
};

const SegmentTabsWrapper = ({ children, setbackfunction, setnextfunction }) => {
const currentCase = CurrentCaseState.useState((s) => s);
const { activeSegmentId } = CaseUIState.useState((s) => s.general);
const childrenCount = React.Children.count(children);

const segmentTabItems = useMemo(() => {
return currentCase.segments.map((segment) => ({
label: segment.name,
key: segment.id,
children:
childrenCount === 1
? React.Children.map(children, (child) =>
React.isValidElement(child)
? React.cloneElement(child, {
segment,
setbackfunction,
setnextfunction,
})
: null
)
: React.Children.map(children, (child) =>
child.key === "left"
? React.isValidElement(child)
? React.cloneElement(child, {
segment,
setbackfunction,
setnextfunction,
})
: null
: null
),
}));
}, [
currentCase.segments,
children,
setbackfunction,
setnextfunction,
childrenCount,
]);

return (
<Row id="steps" gutter={[20, 20]}>
<Col span={childrenCount === 1 ? 24 : 16}>
<Tabs
className="step-segment-tabs-container"
type="card"
items={segmentTabItems}
tabBarGutter={5}
activeKey={activeSegmentId || currentCase?.segments?.[0]?.id || null}
onChange={(val) => {
CaseUIState.update((s) => ({
...s,
general: {
...s.general,
activeSegmentId: val,
},
}));
}}
/>
</Col>
{childrenCount > 1 &&
React.Children.map(children, (child, index) =>
child.key === "right" ? (
React.isValidElement(child) ? (
<Col key={index} span={8}>
{child}
</Col>
) : null
) : null
)}
</Row>
);
};

const Case = () => {
const navigate = useNavigate();
const { caseId, step } = useParams();
Expand Down Expand Up @@ -512,6 +434,73 @@ const Case = () => {
totalIncomeQuestions,
]);

// Fetch visualizaton config for sensitivity analysis and scenario modeling page
useEffect(() => {
if (currentCase.id) {
api.get(`visualization/case/${currentCase.id}`).then((res) => {
const { data } = res;
// Sensitivity analysis
const sensitivityAnalysisTmp = data.find(
(v) => v.tab === "sensitivity_analysis"
);
if (!isEmpty(sensitivityAnalysisTmp)) {
CaseVisualState.update((s) => ({
...s,
sensitivityAnalysis: {
...s.sensitivityAnalysis,
...sensitivityAnalysisTmp,
},
prevSensitivityAnalysis: {
...s.prevSensitivityAnalysis,
...sensitivityAnalysisTmp,
},
}));
}
// Scenario modeling
const scenarioModelingTmp = data.find(
(v) => v.tab === "scenario_modeling"
);
if (!isEmpty(scenarioModelingTmp)) {
CaseVisualState.update((s) => ({
...s,
scenarioModeling: {
...s.scenarioModeling,
...scenarioModelingTmp,
config: {
...scenarioModelingTmp.config,
scenarioData: scenarioModelingTmp.config.scenarioData.map(
(x) => ({
...x,
percentage:
typeof x?.percentage !== "undefined"
? x.percentage
: scenarioModelingTmp.config.percentage,
})
),
},
},
prevScenarioModeling: {
...s.prevScenarioModeling,
...scenarioModelingTmp,
config: {
...scenarioModelingTmp.config,
scenarioData: scenarioModelingTmp.config.scenarioData.map(
(x) => ({
...x,
percentage:
typeof x?.percentage !== "undefined"
? x.percentage
: scenarioModelingTmp.config.percentage,
})
),
},
},
}));
}
});
}
}, [currentCase.id]);

return (
<CaseWrapper caseId={caseId} step={step} currentCase={currentCase}>
{loading ? <Loading /> : renderPage(step, navigate)}
Expand Down
23 changes: 13 additions & 10 deletions frontend/src/pages/cases/components/BinningDriverForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useMemo } from "react";
import { Row, Col, Form, Select, InputNumber } from "antd";
import { InputNumberThousandFormatter } from "../../../lib";
import { selectProps } from "../../../lib";
import { CaseUIState } from "../store";

const binningDriverFormStyles = {
inputNumber: {
Expand All @@ -24,6 +25,8 @@ const BinningDriverForm = ({
dataSource = [],
selected = [],
}) => {
const { enableEditCase } = CaseUIState.useState((s) => s.general);

const drivers = useMemo(() => {
if (!selectedSegment) {
return [];
Expand Down Expand Up @@ -84,7 +87,7 @@ const BinningDriverForm = ({
className="binning-input"
{...selectProps}
options={options["x-axis-driver"]}
// disabled={!enableEditCase}
disabled={!enableEditCase}
placeholder="Select driver"
/>
</Form.Item>
Expand All @@ -97,7 +100,7 @@ const BinningDriverForm = ({
<InputNumber
className="binning-input"
{...InputNumberThousandFormatter}
// disabled={!enableEditCase}
disabled={!enableEditCase}
controls={false}
style={binningDriverFormStyles.inputNumber}
/>
Expand All @@ -111,7 +114,7 @@ const BinningDriverForm = ({
<InputNumber
className="binning-input"
{...InputNumberThousandFormatter}
// disabled={!enableEditCase}
disabled={!enableEditCase}
controls={false}
style={binningDriverFormStyles.inputNumber}
/>
Expand All @@ -131,7 +134,7 @@ const BinningDriverForm = ({
className="binning-input"
{...selectProps}
options={options["y-axis-driver"]}
// disabled={!enableEditCase}
disabled={!enableEditCase}
placeholder="Select driver"
/>
</Form.Item>
Expand All @@ -144,7 +147,7 @@ const BinningDriverForm = ({
<InputNumber
className="binning-input"
{...InputNumberThousandFormatter}
// disabled={!enableEditCase}
disabled={!enableEditCase}
controls={false}
style={binningDriverFormStyles.inputNumber}
/>
Expand All @@ -158,7 +161,7 @@ const BinningDriverForm = ({
<InputNumber
className="binning-input"
{...InputNumberThousandFormatter}
// disabled={!enableEditCase}
disabled={!enableEditCase}
controls={false}
style={binningDriverFormStyles.inputNumber}
/>
Expand All @@ -178,7 +181,7 @@ const BinningDriverForm = ({
className="binning-input"
{...selectProps}
options={options["binning-driver-name"]}
// disabled={!enableEditCase}
disabled={!enableEditCase}
placeholder="Select driver"
/>
</Form.Item>
Expand All @@ -193,7 +196,7 @@ const BinningDriverForm = ({
<InputNumber
className="binning-input"
{...InputNumberThousandFormatter}
// disabled={!enableEditCase}
disabled={!enableEditCase}
controls={false}
style={binningDriverFormStyles.inputNumber}
/>
Expand All @@ -207,7 +210,7 @@ const BinningDriverForm = ({
<InputNumber
className="binning-input"
{...InputNumberThousandFormatter}
// disabled={!enableEditCase}
disabled={!enableEditCase}
controls={false}
style={binningDriverFormStyles.inputNumber}
/>
Expand All @@ -221,7 +224,7 @@ const BinningDriverForm = ({
<InputNumber
className="binning-input"
{...InputNumberThousandFormatter}
// disabled={!enableEditCase}
disabled={!enableEditCase}
controls={false}
style={binningDriverFormStyles.inputNumber}
/>
Expand Down
Loading

0 comments on commit a15f4f7

Please sign in to comment.