@hedia/recommendation-screen 1.2.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.idea/workspace.xml +30 -30
- package/package.json +1 -1
- package/src/RecommendationScreen.d.ts +3 -0
- package/src/RecommendationScreen.jsx +50 -41
- package/src/RecommendationScreen.tsx +80 -56
- package/src/components/InvisibleNumberInput.d.ts +1 -0
- package/src/components/InvisibleNumberInput.jsx +1 -1
- package/src/components/InvisibleNumberInput.tsx +3 -0
- package/src/components/RecommendedCarbs.d.ts +0 -2
- package/src/components/RecommendedCarbs.jsx +8 -3
- package/src/components/RecommendedCarbs.tsx +10 -5
- package/src/components/RecommendedInsulin.d.ts +3 -3
- package/src/components/RecommendedInsulin.jsx +18 -6
- package/src/components/RecommendedInsulin.tsx +24 -10
- package/src/components/activity/ActivityIcon.jsx +1 -1
- package/src/components/activity/ActivityIcon.tsx +1 -1
- package/src/types/enum.d.ts +9 -10
- package/src/types/enum.js +9 -10
- package/src/types/enum.ts +0 -1
- package/src/types/types.ts +1 -0
- package/src/utils/AttentionMessages.d.ts +1 -1
- package/src/utils/AttentionMessages.jsx +1 -1
- package/src/utils/AttentionMessages.tsx +1 -1
- package/src/utils/Constants.d.ts +3 -0
- package/src/utils/Constants.js +4 -1
- package/src/utils/Constants.ts +5 -0
- package/src/utils/RecommendationError.d.ts +0 -1
- package/src/utils/RecommendationError.jsx +1 -3
- package/src/utils/RecommendationError.tsx +0 -7
- package/src/utils/RecommendationUtils.d.ts +2 -3
- package/src/utils/RecommendationUtils.js +3 -4
- package/src/utils/RecommendationUtils.ts +2 -4
- package/src/utils/Utils.d.ts +1 -0
- package/src/utils/Utils.js +4 -0
- package/src/utils/Utils.ts +4 -0
- package/src/utils/Validations.js +15 -11
- package/src/utils/Validations.ts +16 -11
package/.idea/workspace.xml
CHANGED
|
@@ -28,9 +28,7 @@
|
|
|
28
28
|
</select>
|
|
29
29
|
</component>
|
|
30
30
|
<component name="ChangeListManager">
|
|
31
|
-
<list default="true" id="bceba75c-4c15-4bdc-9b41-023f63a30830" name="Default Changelist" comment=""
|
|
32
|
-
<change beforePath="$PROJECT_DIR$/src/components/InvisibleNumberInput.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/InvisibleNumberInput.tsx" afterDir="false" />
|
|
33
|
-
</list>
|
|
31
|
+
<list default="true" id="bceba75c-4c15-4bdc-9b41-023f63a30830" name="Default Changelist" comment="" />
|
|
34
32
|
<option name="SHOW_DIALOG" value="false" />
|
|
35
33
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
|
36
34
|
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
|
@@ -169,7 +167,9 @@
|
|
|
169
167
|
<workItem from="1599031274561" duration="12226000" />
|
|
170
168
|
<workItem from="1599119614705" duration="6081000" />
|
|
171
169
|
<workItem from="1599205746476" duration="8368000" />
|
|
172
|
-
<workItem from="1599465060245" duration="
|
|
170
|
+
<workItem from="1599465060245" duration="4905000" />
|
|
171
|
+
<workItem from="1599554723490" duration="10979000" />
|
|
172
|
+
<workItem from="1599637277136" duration="3405000" />
|
|
173
173
|
</task>
|
|
174
174
|
<servers />
|
|
175
175
|
</component>
|
|
@@ -229,48 +229,48 @@
|
|
|
229
229
|
<state x="0" y="123" width="1792" height="897" key="DiffContextDialog/1792.-195.3440.1417/0.23.1792.1097@0.23.1792.1097" timestamp="1597747801467" />
|
|
230
230
|
<state x="0" y="123" width="1792" height="897" key="DiffContextDialog/1792.-410.1920.1057/0.23.1792.1097@0.23.1792.1097" timestamp="1597836504040" />
|
|
231
231
|
<state x="1792" y="-314" width="1920" height="865" key="DiffContextDialog/1792.-410.1920.1057/0.23.1792.1097@1792.-410.1920.1057" timestamp="1598603549140" />
|
|
232
|
-
<state width="
|
|
233
|
-
<screen x="
|
|
232
|
+
<state width="918" height="257" key="GridCell.Tab.0.bottom" timestamp="1599641656861">
|
|
233
|
+
<screen x="1792" y="-410" width="1920" height="1057" />
|
|
234
234
|
</state>
|
|
235
235
|
<state width="1750" height="261" key="GridCell.Tab.0.bottom/-1920.-66.1920.1057/0.23.1792.1097@0.23.1792.1097" timestamp="1596194051670" />
|
|
236
|
-
<state width="
|
|
236
|
+
<state width="1678" height="366" key="GridCell.Tab.0.bottom/0.23.1792.1097@0.23.1792.1097" timestamp="1599585643328" />
|
|
237
237
|
<state width="1750" height="383" key="GridCell.Tab.0.bottom/1792.-195.3440.1417/0.23.1792.1097@0.23.1792.1097" timestamp="1597945008184" />
|
|
238
|
-
<state width="1678" height="
|
|
238
|
+
<state width="1678" height="366" key="GridCell.Tab.0.bottom/1792.-195.3440.1417/0.23.1792.1097@1792.-195.3440.1417" timestamp="1599567565615" />
|
|
239
239
|
<state width="1276" height="270" key="GridCell.Tab.0.bottom/1792.-410.1920.1057/0.23.1792.1097@0.23.1792.1097" timestamp="1599230158300" />
|
|
240
|
-
<state width="
|
|
241
|
-
<state width="
|
|
242
|
-
<screen x="
|
|
240
|
+
<state width="918" height="257" key="GridCell.Tab.0.bottom/1792.-410.1920.1057/0.23.1792.1097@1792.-410.1920.1057" timestamp="1599641656861" />
|
|
241
|
+
<state width="918" height="257" key="GridCell.Tab.0.center" timestamp="1599641656860">
|
|
242
|
+
<screen x="1792" y="-410" width="1920" height="1057" />
|
|
243
243
|
</state>
|
|
244
244
|
<state width="1750" height="261" key="GridCell.Tab.0.center/-1920.-66.1920.1057/0.23.1792.1097@0.23.1792.1097" timestamp="1596194051669" />
|
|
245
|
-
<state width="
|
|
245
|
+
<state width="1678" height="366" key="GridCell.Tab.0.center/0.23.1792.1097@0.23.1792.1097" timestamp="1599585643327" />
|
|
246
246
|
<state width="1750" height="383" key="GridCell.Tab.0.center/1792.-195.3440.1417/0.23.1792.1097@0.23.1792.1097" timestamp="1597945008183" />
|
|
247
|
-
<state width="1678" height="
|
|
247
|
+
<state width="1678" height="366" key="GridCell.Tab.0.center/1792.-195.3440.1417/0.23.1792.1097@1792.-195.3440.1417" timestamp="1599567565614" />
|
|
248
248
|
<state width="1276" height="270" key="GridCell.Tab.0.center/1792.-410.1920.1057/0.23.1792.1097@0.23.1792.1097" timestamp="1599230158300" />
|
|
249
|
-
<state width="
|
|
250
|
-
<state width="
|
|
251
|
-
<screen x="
|
|
249
|
+
<state width="918" height="257" key="GridCell.Tab.0.center/1792.-410.1920.1057/0.23.1792.1097@1792.-410.1920.1057" timestamp="1599641656860" />
|
|
250
|
+
<state width="918" height="257" key="GridCell.Tab.0.left" timestamp="1599641656860">
|
|
251
|
+
<screen x="1792" y="-410" width="1920" height="1057" />
|
|
252
252
|
</state>
|
|
253
253
|
<state width="1750" height="261" key="GridCell.Tab.0.left/-1920.-66.1920.1057/0.23.1792.1097@0.23.1792.1097" timestamp="1596194051668" />
|
|
254
|
-
<state width="
|
|
254
|
+
<state width="1678" height="366" key="GridCell.Tab.0.left/0.23.1792.1097@0.23.1792.1097" timestamp="1599585643327" />
|
|
255
255
|
<state width="1750" height="383" key="GridCell.Tab.0.left/1792.-195.3440.1417/0.23.1792.1097@0.23.1792.1097" timestamp="1597945008182" />
|
|
256
|
-
<state width="1678" height="
|
|
256
|
+
<state width="1678" height="366" key="GridCell.Tab.0.left/1792.-195.3440.1417/0.23.1792.1097@1792.-195.3440.1417" timestamp="1599567565614" />
|
|
257
257
|
<state width="1276" height="270" key="GridCell.Tab.0.left/1792.-410.1920.1057/0.23.1792.1097@0.23.1792.1097" timestamp="1599230158299" />
|
|
258
|
-
<state width="
|
|
259
|
-
<state width="
|
|
260
|
-
<screen x="
|
|
258
|
+
<state width="918" height="257" key="GridCell.Tab.0.left/1792.-410.1920.1057/0.23.1792.1097@1792.-410.1920.1057" timestamp="1599641656860" />
|
|
259
|
+
<state width="918" height="257" key="GridCell.Tab.0.right" timestamp="1599641656861">
|
|
260
|
+
<screen x="1792" y="-410" width="1920" height="1057" />
|
|
261
261
|
</state>
|
|
262
262
|
<state width="1750" height="261" key="GridCell.Tab.0.right/-1920.-66.1920.1057/0.23.1792.1097@0.23.1792.1097" timestamp="1596194051669" />
|
|
263
|
-
<state width="
|
|
263
|
+
<state width="1678" height="366" key="GridCell.Tab.0.right/0.23.1792.1097@0.23.1792.1097" timestamp="1599585643328" />
|
|
264
264
|
<state width="1750" height="383" key="GridCell.Tab.0.right/1792.-195.3440.1417/0.23.1792.1097@0.23.1792.1097" timestamp="1597945008183" />
|
|
265
|
-
<state width="1678" height="
|
|
265
|
+
<state width="1678" height="366" key="GridCell.Tab.0.right/1792.-195.3440.1417/0.23.1792.1097@1792.-195.3440.1417" timestamp="1599567565614" />
|
|
266
266
|
<state width="1276" height="270" key="GridCell.Tab.0.right/1792.-410.1920.1057/0.23.1792.1097@0.23.1792.1097" timestamp="1599230158300" />
|
|
267
|
-
<state width="
|
|
268
|
-
<state x="
|
|
269
|
-
<screen x="1792" y="-
|
|
267
|
+
<state width="918" height="257" key="GridCell.Tab.0.right/1792.-410.1920.1057/0.23.1792.1097@1792.-410.1920.1057" timestamp="1599641656861" />
|
|
268
|
+
<state x="2340" y="-140" key="IDE.errors.dialog" timestamp="1599637300780">
|
|
269
|
+
<screen x="1792" y="-410" width="1920" height="1057" />
|
|
270
270
|
</state>
|
|
271
271
|
<state x="511" y="303" key="IDE.errors.dialog/1792.-195.3440.1417/0.23.1792.1097@0.23.1792.1097" timestamp="1597308623997" />
|
|
272
272
|
<state x="2773" y="167" key="IDE.errors.dialog/1792.-195.3440.1417/0.23.1792.1097@1792.-195.3440.1417" timestamp="1598973647546" />
|
|
273
|
-
<state x="2340" y="-140" key="IDE.errors.dialog/1792.-410.1920.1057/0.23.1792.1097@1792.-410.1920.1057" timestamp="
|
|
273
|
+
<state x="2340" y="-140" key="IDE.errors.dialog/1792.-410.1920.1057/0.23.1792.1097@1792.-410.1920.1057" timestamp="1599637300780" />
|
|
274
274
|
<state x="0" y="23" width="1792" height="1097" key="MergeDialog" timestamp="1597409959598">
|
|
275
275
|
<screen x="0" y="23" width="1792" height="1097" />
|
|
276
276
|
</state>
|
|
@@ -307,14 +307,14 @@
|
|
|
307
307
|
<screen x="1792" y="-410" width="1920" height="1057" />
|
|
308
308
|
</state>
|
|
309
309
|
<state x="2477" y="-143" key="refactoring.ChangeSignatureDialog/1792.-410.1920.1057/0.23.1792.1097@1792.-410.1920.1057" timestamp="1599040674381" />
|
|
310
|
-
<state x="2178" y="-174" width="718" height="652" key="search.everywhere.popup" timestamp="
|
|
310
|
+
<state x="2178" y="-174" width="718" height="652" key="search.everywhere.popup" timestamp="1599645055979">
|
|
311
311
|
<screen x="1792" y="-410" width="1920" height="1057" />
|
|
312
312
|
</state>
|
|
313
313
|
<state x="360" y="268" width="670" height="676" key="search.everywhere.popup/-1920.-66.1920.1057/0.23.1792.1097@0.23.1792.1097" timestamp="1596101738778" />
|
|
314
314
|
<state x="360" y="268" width="670" height="676" key="search.everywhere.popup/0.23.1792.1097@0.23.1792.1097" timestamp="1596191050648" />
|
|
315
315
|
<state x="360" y="268" width="671" height="677" key="search.everywhere.popup/1792.-195.3440.1417/0.23.1792.1097@0.23.1792.1097" timestamp="1597748285464" />
|
|
316
|
-
<state x="2484" y="121" width="1287" height="875" key="search.everywhere.popup/1792.-195.3440.1417/0.23.1792.1097@1792.-195.3440.1417" timestamp="
|
|
316
|
+
<state x="2484" y="121" width="1287" height="875" key="search.everywhere.popup/1792.-195.3440.1417/0.23.1792.1097@1792.-195.3440.1417" timestamp="1599560052196" />
|
|
317
317
|
<state x="360" y="268" width="671" height="677" key="search.everywhere.popup/1792.-410.1920.1057/0.23.1792.1097@0.23.1792.1097" timestamp="1599216348282" />
|
|
318
|
-
<state x="2178" y="-174" width="718" height="652" key="search.everywhere.popup/1792.-410.1920.1057/0.23.1792.1097@1792.-410.1920.1057" timestamp="
|
|
318
|
+
<state x="2178" y="-174" width="718" height="652" key="search.everywhere.popup/1792.-410.1920.1057/0.23.1792.1097@1792.-410.1920.1057" timestamp="1599645055979" />
|
|
319
319
|
</component>
|
|
320
320
|
</project>
|
package/package.json
CHANGED
|
@@ -42,8 +42,11 @@ interface IState {
|
|
|
42
42
|
export default class RecommendationScreen extends React.Component<IRecommendationProps, IState> {
|
|
43
43
|
private readonly timer;
|
|
44
44
|
private readonly suggestedCarbs;
|
|
45
|
+
private readonly hasError;
|
|
45
46
|
private scrollView;
|
|
46
47
|
constructor(props: IRecommendationProps);
|
|
48
|
+
componentWillUnmount(): void;
|
|
49
|
+
recalculateInsulin: (calculatorParams: Calculator.IRecommendationParams) => void;
|
|
47
50
|
onExit: () => void;
|
|
48
51
|
updateRemeasureTime: (remeasureTime: number) => void;
|
|
49
52
|
handleNoRecentInsulin: () => void;
|
|
@@ -51,13 +51,20 @@ react_native_1.YellowBox.ignoreWarnings([`Setting a timer`]);
|
|
|
51
51
|
class RecommendationScreen extends react_1.default.Component {
|
|
52
52
|
constructor(props) {
|
|
53
53
|
super(props);
|
|
54
|
+
this.hasError = false;
|
|
55
|
+
this.recalculateInsulin = (calculatorParams) => {
|
|
56
|
+
const { bolus } = Calculator.calculateRecommendation(RecommendationUtils_1.assignTargetBGL(calculatorParams));
|
|
57
|
+
this.setState({
|
|
58
|
+
insulinRecommendation: Utils_1.Utils.roundValue(bolus, this.props.injectionMethod),
|
|
59
|
+
enteredInsulin: undefined,
|
|
60
|
+
});
|
|
61
|
+
};
|
|
54
62
|
this.onExit = () => {
|
|
55
63
|
if (this.state.isRecommendationDisplayed) {
|
|
56
64
|
this.setState({ exitModal: true }, () => this.props.showBolusBar(!this.state.exitModal));
|
|
57
65
|
}
|
|
58
66
|
else {
|
|
59
67
|
this.props.exitCallback();
|
|
60
|
-
clearTimeout(this.timer);
|
|
61
68
|
}
|
|
62
69
|
};
|
|
63
70
|
this.updateRemeasureTime = (remeasureTime) => {
|
|
@@ -71,10 +78,11 @@ class RecommendationScreen extends react_1.default.Component {
|
|
|
71
78
|
});
|
|
72
79
|
};
|
|
73
80
|
this.updateCarbRecommendation = (enteredCarbs) => {
|
|
74
|
-
this.
|
|
81
|
+
const providedCarbs = this.props.calculatorParams.carbohydrates;
|
|
82
|
+
this.setState({ enteredCarbs }, () => this.recalculateInsulin({ ...this.props.calculatorParams, carbohydrates: providedCarbs + enteredCarbs }));
|
|
75
83
|
};
|
|
76
84
|
this.removeCarbRecommendation = () => {
|
|
77
|
-
this.setState({ enteredCarbs: null, carbRecommendation: null });
|
|
85
|
+
this.setState({ enteredCarbs: null, carbRecommendation: null }, () => this.recalculateInsulin({ ...this.props.calculatorParams }));
|
|
78
86
|
};
|
|
79
87
|
this.declineCarbRecommendation = () => {
|
|
80
88
|
this.hideAttentionModal();
|
|
@@ -93,7 +101,6 @@ class RecommendationScreen extends react_1.default.Component {
|
|
|
93
101
|
};
|
|
94
102
|
this.closeCalculation = () => {
|
|
95
103
|
this.hideExitModal();
|
|
96
|
-
clearTimeout(this.timer);
|
|
97
104
|
this.props.closeCalculationCallback();
|
|
98
105
|
};
|
|
99
106
|
this.handleMoodSelected = (selectedMood) => {
|
|
@@ -106,14 +113,9 @@ class RecommendationScreen extends react_1.default.Component {
|
|
|
106
113
|
if (this.state.exitModal) {
|
|
107
114
|
this.hideExitModal();
|
|
108
115
|
}
|
|
109
|
-
this.
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
}, {
|
|
113
|
-
suggested: this.state.insulinRecommendation,
|
|
114
|
-
entered: this.state.enteredInsulin,
|
|
115
|
-
}, this.state.remeasureTime);
|
|
116
|
-
clearTimeout(this.timer);
|
|
116
|
+
const carbs = { suggested: this.suggestedCarbs, entered: this.state.enteredCarbs };
|
|
117
|
+
const insulin = { suggested: this.state.insulinRecommendation, entered: this.state.enteredInsulin };
|
|
118
|
+
this.props.transferToLogbook(carbs, insulin, this.state.remeasureTime);
|
|
117
119
|
};
|
|
118
120
|
this.getBGLevelAttentionMessage = () => {
|
|
119
121
|
const { calculatorParams, latestLogbookFrom6Hours } = this.props;
|
|
@@ -132,42 +134,49 @@ class RecommendationScreen extends react_1.default.Component {
|
|
|
132
134
|
return RecommendationUtils_1.getLimitationMessage(wasLimited, activityReduction);
|
|
133
135
|
};
|
|
134
136
|
try {
|
|
135
|
-
Validations_1.validateParams(props);
|
|
137
|
+
Validations_1.validateParams(this.props);
|
|
138
|
+
i18nUtils_1.changeLanguage(props.language);
|
|
139
|
+
const { recentBoluses } = this.props?.calculatorParams;
|
|
140
|
+
const { bolus, carbRecommendation, activityReduction, wasLimited, activeInsulin, } = Calculator.calculateRecommendation(RecommendationUtils_1.assignTargetBGL(this.props.calculatorParams));
|
|
141
|
+
this.suggestedCarbs = carbRecommendation;
|
|
142
|
+
this.state = {
|
|
143
|
+
remeasureTime: this.getBGLevelRemeasurementReminder(),
|
|
144
|
+
isRecommendationDisplayed: recentBoluses?.length !== 0,
|
|
145
|
+
insulinRecommendation: Utils_1.Utils.roundValue(bolus, props.injectionMethod),
|
|
146
|
+
wasLimited,
|
|
147
|
+
activityReduction,
|
|
148
|
+
bolus,
|
|
149
|
+
carbRecommendation,
|
|
150
|
+
activeInsulin,
|
|
151
|
+
selectedMood: null,
|
|
152
|
+
recommendationModal: wasLimited || !!Math.round(carbRecommendation) || !!this.getBGLevelAttentionMessage(),
|
|
153
|
+
exitModal: false,
|
|
154
|
+
};
|
|
155
|
+
this.timer = setTimeout(() => {
|
|
156
|
+
props.onError(RecommendationError_1.TimeoutLimitError());
|
|
157
|
+
}, enum_1.Milliseconds.Minute * 15);
|
|
136
158
|
}
|
|
137
159
|
catch (error) {
|
|
138
|
-
|
|
160
|
+
this.hasError = true;
|
|
161
|
+
this.props.onError(error);
|
|
139
162
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
this.suggestedCarbs = carbRecommendation;
|
|
144
|
-
const activeInsulin = Calculator.calculateActiveInsulin(recentBoluses ?? []);
|
|
145
|
-
this.state = {
|
|
146
|
-
remeasureTime: this.getBGLevelRemeasurementReminder(),
|
|
147
|
-
isRecommendationDisplayed: recentBoluses?.length !== 0,
|
|
148
|
-
insulinRecommendation: Utils_1.Utils.roundValue(bolus, props.injectionMethod),
|
|
149
|
-
wasLimited,
|
|
150
|
-
activityReduction,
|
|
151
|
-
bolus,
|
|
152
|
-
carbRecommendation,
|
|
153
|
-
activeInsulin,
|
|
154
|
-
selectedMood: null,
|
|
155
|
-
recommendationModal: wasLimited || !!Math.round(carbRecommendation) || !!this.getBGLevelAttentionMessage(),
|
|
156
|
-
exitModal: false,
|
|
157
|
-
};
|
|
158
|
-
this.timer = setTimeout(() => {
|
|
159
|
-
props.onError(RecommendationError_1.TimeoutLimitError());
|
|
160
|
-
}, enum_1.Milliseconds.Minute * 15);
|
|
163
|
+
}
|
|
164
|
+
componentWillUnmount() {
|
|
165
|
+
clearTimeout(this.timer);
|
|
161
166
|
}
|
|
162
167
|
render() {
|
|
163
|
-
|
|
164
|
-
|
|
168
|
+
if (this.hasError) {
|
|
169
|
+
return <react_native_1.View style={containerStyles.container}/>;
|
|
170
|
+
}
|
|
171
|
+
const { activeInsulin, recommendationModal, carbRecommendation, enteredCarbs, enteredInsulin, insulinRecommendation, activityReduction, isRecommendationDisplayed, } = this.state;
|
|
172
|
+
const { calculatorParams, units } = this.props;
|
|
165
173
|
const { currentBGL, carbohydrates } = calculatorParams;
|
|
174
|
+
const displayedBGL = units === enum_1.BGUnit.MMOL_L ? currentBGL : Utils_1.Utils.convertToMGDL(currentBGL);
|
|
166
175
|
return (<react_2.I18nProvider language={this.props.language} i18n={i18nUtils_1.i18n}>
|
|
167
176
|
<react_native_1.ScrollView style={containerStyles.container} ref={(view) => (this.scrollView = view)}>
|
|
168
177
|
<Header_1.default exitCallback={this.onExit}/>
|
|
169
178
|
<InfoBars_1.default style={{ flex: 5 }} label={i18nUtils_1.i18n._(macro_1.t `Active Insulin`)} value={activeInsulin ? `${activeInsulin.toFixed(1)}` : null} units={i18nUtils_1.i18n._(macro_1.t `units`)} showZeroAsDash={false}/>
|
|
170
|
-
<InfoBars_1.default label={i18nUtils_1.i18n._(macro_1.t `Blood Glucose Level`)} value={currentBGL ? `${
|
|
179
|
+
<InfoBars_1.default label={i18nUtils_1.i18n._(macro_1.t `Blood Glucose Level`)} value={currentBGL ? `${displayedBGL}` : null} units={this.props.units} showZeroAsDash={true}/>
|
|
171
180
|
<react_native_1.View style={containerStyles.calcContainer}>
|
|
172
181
|
<react_native_1.View style={containerStyles.calcMargin}>
|
|
173
182
|
<react_native_1.View style={[
|
|
@@ -176,15 +185,15 @@ class RecommendationScreen extends react_1.default.Component {
|
|
|
176
185
|
borderColor: carbRecommendation ? Constants_1.BORDER_COLOUR_TEAL : Constants_1.BORDER_COLOUR_GREY,
|
|
177
186
|
},
|
|
178
187
|
]}>
|
|
179
|
-
<RecommendedCarbs_1.default enteredCarbs={`${carbohydrates}`} changedRecommendedCarbs={this.updateCarbRecommendation} recommendedCarbs={`${enteredCarbs ?? Math.round(carbRecommendation)}`} removeRecommendedCarbs={this.removeCarbRecommendation}
|
|
188
|
+
<RecommendedCarbs_1.default enteredCarbs={`${carbohydrates}`} changedRecommendedCarbs={this.updateCarbRecommendation} recommendedCarbs={`${enteredCarbs ?? Math.round(carbRecommendation)}`} removeRecommendedCarbs={this.removeCarbRecommendation}/>
|
|
180
189
|
<Remeasure_1.default onSliderChange={this.updateRemeasureTime} remeasureTime={this.state.remeasureTime}/>
|
|
181
190
|
</react_native_1.View>
|
|
182
191
|
</react_native_1.View>
|
|
183
192
|
</react_native_1.View>
|
|
184
193
|
{this.props.calculatorParams.activity && this.props.activityType !== null ? (<Activity_1.default activity={this.props.calculatorParams.activity} activityType={this.props.activityType} activityReduction={this.state.activityReduction}/>) : null}
|
|
185
|
-
{!this.state.isRecommendationDisplayed ? (<RecentInsulin_1.default onRecentInsulinYes={this.props.onRecentInsulinYes} onRecentInsulinNo={this.handleNoRecentInsulin}/>) : (<RecommendedInsulin_1.default injectionMethod={this.props.injectionMethod} insulinRecommendation={
|
|
194
|
+
{!this.state.isRecommendationDisplayed ? (<RecentInsulin_1.default onRecentInsulinYes={this.props.onRecentInsulinYes} onRecentInsulinNo={this.handleNoRecentInsulin}/>) : (<RecommendedInsulin_1.default injectionMethod={this.props.injectionMethod} insulinRecommendation={insulinRecommendation} enteredInsulin={enteredInsulin} activityReduction={activityReduction} updateRecommendedInsulin={this.updateInsulinRecommendation}/>)}
|
|
186
195
|
<Emotion_1.default moodSelected={this.handleMoodSelected} currentMood={this.state.selectedMood}/>
|
|
187
|
-
<TransferToLogbook_1.default visible={
|
|
196
|
+
<TransferToLogbook_1.default visible={isRecommendationDisplayed} transfer={this.handleTransfer}/>
|
|
188
197
|
<RecommendationModal_1.default isVisible={recommendationModal} suggestedCarbohydrates={carbRecommendation} attentionMessage={this.getBGLevelAttentionMessage()} limitationMessage={this.getLimitationAttentionMessage()} onClickOkButton={this.hideAttentionModal} onAcceptCarbohydrates={this.acceptCarbRecommendation} onDeclineCarbohydrates={this.declineCarbRecommendation}/>
|
|
189
198
|
</react_native_1.ScrollView>
|
|
190
199
|
{this.state.exitModal ? (<ExitModal_1.default onSave={this.handleTransfer} onCloseCalculation={this.closeCalculation} onClose={this.hideExitModal}/>) : null}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { ScrollView, StyleSheet, View, YellowBox } from "react-native";
|
|
3
|
+
|
|
3
4
|
import { ActivityEnum, BGUnit, InjectionMethod, Languages, Milliseconds, MoodEnum } from "./types/enum";
|
|
4
5
|
import { BACKGROUND_COLOUR_PURPLE, BORDER_COLOUR_GREY, BORDER_COLOUR_TEAL } from "./utils/Constants";
|
|
5
6
|
|
|
@@ -24,10 +25,10 @@ import { changeLanguage, i18n } from "./locale/i18nUtils";
|
|
|
24
25
|
import { IActivity, logbookEntry } from "./types/types";
|
|
25
26
|
import { AttentionMessage } from "./utils/AttentionMessages";
|
|
26
27
|
import {
|
|
28
|
+
assignTargetBGL,
|
|
27
29
|
getAttentionMessage,
|
|
28
30
|
getBGLevel,
|
|
29
31
|
getLimitationMessage,
|
|
30
|
-
getParams,
|
|
31
32
|
getReminder,
|
|
32
33
|
} from "./utils/RecommendationUtils";
|
|
33
34
|
import { Utils } from "./utils/Utils";
|
|
@@ -81,52 +82,68 @@ interface IState {
|
|
|
81
82
|
export default class RecommendationScreen extends React.Component<IRecommendationProps, IState> {
|
|
82
83
|
private readonly timer: ReturnType<typeof setTimeout>;
|
|
83
84
|
private readonly suggestedCarbs: number;
|
|
85
|
+
private readonly hasError: boolean = false;
|
|
84
86
|
private scrollView: ScrollView;
|
|
85
87
|
|
|
86
88
|
constructor(props: IRecommendationProps) {
|
|
87
89
|
super(props);
|
|
88
90
|
try {
|
|
89
|
-
validateParams(props);
|
|
91
|
+
validateParams(this.props);
|
|
92
|
+
|
|
93
|
+
changeLanguage(props.language);
|
|
94
|
+
|
|
95
|
+
const { recentBoluses } = this.props?.calculatorParams;
|
|
96
|
+
const {
|
|
97
|
+
bolus,
|
|
98
|
+
carbRecommendation,
|
|
99
|
+
activityReduction,
|
|
100
|
+
wasLimited,
|
|
101
|
+
activeInsulin,
|
|
102
|
+
} = Calculator.calculateRecommendation(assignTargetBGL(this.props.calculatorParams));
|
|
103
|
+
|
|
104
|
+
this.suggestedCarbs = carbRecommendation;
|
|
105
|
+
|
|
106
|
+
this.state = {
|
|
107
|
+
remeasureTime: this.getBGLevelRemeasurementReminder(),
|
|
108
|
+
isRecommendationDisplayed: recentBoluses?.length !== 0,
|
|
109
|
+
insulinRecommendation: Utils.roundValue(bolus, props.injectionMethod),
|
|
110
|
+
wasLimited,
|
|
111
|
+
activityReduction,
|
|
112
|
+
bolus,
|
|
113
|
+
carbRecommendation,
|
|
114
|
+
activeInsulin,
|
|
115
|
+
selectedMood: null,
|
|
116
|
+
recommendationModal:
|
|
117
|
+
wasLimited || !!Math.round(carbRecommendation) || !!this.getBGLevelAttentionMessage(),
|
|
118
|
+
exitModal: false,
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
this.timer = setTimeout((): void => {
|
|
122
|
+
props.onError(TimeoutLimitError());
|
|
123
|
+
}, Milliseconds.Minute * 15);
|
|
90
124
|
} catch (error) {
|
|
91
|
-
|
|
125
|
+
this.hasError = true;
|
|
126
|
+
this.props.onError(error);
|
|
92
127
|
}
|
|
128
|
+
}
|
|
93
129
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const { recentBoluses } = props?.calculatorParams;
|
|
97
|
-
const { bolus, carbRecommendation, activityReduction, wasLimited } = Calculator.calculateRecommendation(
|
|
98
|
-
getParams(this.props),
|
|
99
|
-
);
|
|
100
|
-
|
|
101
|
-
this.suggestedCarbs = carbRecommendation;
|
|
102
|
-
|
|
103
|
-
const activeInsulin = Calculator.calculateActiveInsulin(recentBoluses ?? []);
|
|
104
|
-
|
|
105
|
-
this.state = {
|
|
106
|
-
remeasureTime: this.getBGLevelRemeasurementReminder(),
|
|
107
|
-
isRecommendationDisplayed: recentBoluses?.length !== 0,
|
|
108
|
-
insulinRecommendation: Utils.roundValue(bolus, props.injectionMethod),
|
|
109
|
-
wasLimited,
|
|
110
|
-
activityReduction,
|
|
111
|
-
bolus,
|
|
112
|
-
carbRecommendation,
|
|
113
|
-
activeInsulin,
|
|
114
|
-
selectedMood: null,
|
|
115
|
-
recommendationModal: wasLimited || !!Math.round(carbRecommendation) || !!this.getBGLevelAttentionMessage(),
|
|
116
|
-
exitModal: false,
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
this.timer = setTimeout((): void => {
|
|
120
|
-
props.onError(TimeoutLimitError());
|
|
121
|
-
}, Milliseconds.Minute * 15);
|
|
130
|
+
public componentWillUnmount(): void {
|
|
131
|
+
clearTimeout(this.timer);
|
|
122
132
|
}
|
|
123
133
|
|
|
134
|
+
public recalculateInsulin = (calculatorParams: Calculator.IRecommendationParams): void => {
|
|
135
|
+
const { bolus } = Calculator.calculateRecommendation(assignTargetBGL(calculatorParams));
|
|
136
|
+
this.setState({
|
|
137
|
+
insulinRecommendation: Utils.roundValue(bolus, this.props.injectionMethod),
|
|
138
|
+
enteredInsulin: undefined,
|
|
139
|
+
});
|
|
140
|
+
};
|
|
141
|
+
|
|
124
142
|
public onExit = (): void => {
|
|
125
143
|
if (this.state.isRecommendationDisplayed) {
|
|
126
144
|
this.setState({ exitModal: true }, (): void => this.props.showBolusBar(!this.state.exitModal));
|
|
127
145
|
} else {
|
|
128
146
|
this.props.exitCallback();
|
|
129
|
-
clearTimeout(this.timer);
|
|
130
147
|
}
|
|
131
148
|
};
|
|
132
149
|
|
|
@@ -143,11 +160,16 @@ export default class RecommendationScreen extends React.Component<IRecommendatio
|
|
|
143
160
|
};
|
|
144
161
|
|
|
145
162
|
public updateCarbRecommendation = (enteredCarbs: number): void => {
|
|
146
|
-
this.
|
|
163
|
+
const providedCarbs = this.props.calculatorParams.carbohydrates;
|
|
164
|
+
this.setState({ enteredCarbs }, (): void =>
|
|
165
|
+
this.recalculateInsulin({ ...this.props.calculatorParams, carbohydrates: providedCarbs + enteredCarbs }),
|
|
166
|
+
);
|
|
147
167
|
};
|
|
148
168
|
|
|
149
169
|
public removeCarbRecommendation = (): void => {
|
|
150
|
-
this.setState({ enteredCarbs: null, carbRecommendation: null })
|
|
170
|
+
this.setState({ enteredCarbs: null, carbRecommendation: null }, (): void =>
|
|
171
|
+
this.recalculateInsulin({ ...this.props.calculatorParams }),
|
|
172
|
+
);
|
|
151
173
|
};
|
|
152
174
|
|
|
153
175
|
public declineCarbRecommendation = (): void => {
|
|
@@ -168,7 +190,6 @@ export default class RecommendationScreen extends React.Component<IRecommendatio
|
|
|
168
190
|
};
|
|
169
191
|
public closeCalculation = (): void => {
|
|
170
192
|
this.hideExitModal();
|
|
171
|
-
clearTimeout(this.timer);
|
|
172
193
|
this.props.closeCalculationCallback();
|
|
173
194
|
};
|
|
174
195
|
|
|
@@ -184,19 +205,9 @@ export default class RecommendationScreen extends React.Component<IRecommendatio
|
|
|
184
205
|
if (this.state.exitModal) {
|
|
185
206
|
this.hideExitModal();
|
|
186
207
|
}
|
|
187
|
-
this.
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
entered: this.state.enteredCarbs,
|
|
191
|
-
},
|
|
192
|
-
{
|
|
193
|
-
suggested: this.state.insulinRecommendation,
|
|
194
|
-
entered: this.state.enteredInsulin,
|
|
195
|
-
},
|
|
196
|
-
this.state.remeasureTime,
|
|
197
|
-
);
|
|
198
|
-
|
|
199
|
-
clearTimeout(this.timer);
|
|
208
|
+
const carbs: IResult = { suggested: this.suggestedCarbs, entered: this.state.enteredCarbs };
|
|
209
|
+
const insulin: IResult = { suggested: this.state.insulinRecommendation, entered: this.state.enteredInsulin };
|
|
210
|
+
this.props.transferToLogbook(carbs, insulin, this.state.remeasureTime);
|
|
200
211
|
};
|
|
201
212
|
|
|
202
213
|
public getBGLevelAttentionMessage = (): AttentionMessage => {
|
|
@@ -218,9 +229,23 @@ export default class RecommendationScreen extends React.Component<IRecommendatio
|
|
|
218
229
|
};
|
|
219
230
|
|
|
220
231
|
public render(): JSX.Element {
|
|
221
|
-
|
|
222
|
-
|
|
232
|
+
if (this.hasError) {
|
|
233
|
+
return <View style={containerStyles.container} />;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const {
|
|
237
|
+
activeInsulin,
|
|
238
|
+
recommendationModal,
|
|
239
|
+
carbRecommendation,
|
|
240
|
+
enteredCarbs,
|
|
241
|
+
enteredInsulin,
|
|
242
|
+
insulinRecommendation,
|
|
243
|
+
activityReduction,
|
|
244
|
+
isRecommendationDisplayed,
|
|
245
|
+
} = this.state;
|
|
246
|
+
const { calculatorParams, units } = this.props;
|
|
223
247
|
const { currentBGL, carbohydrates } = calculatorParams;
|
|
248
|
+
const displayedBGL = units === BGUnit.MMOL_L ? currentBGL : Utils.convertToMGDL(currentBGL);
|
|
224
249
|
|
|
225
250
|
return (
|
|
226
251
|
<I18nProvider language={this.props.language} i18n={i18n}>
|
|
@@ -235,7 +260,7 @@ export default class RecommendationScreen extends React.Component<IRecommendatio
|
|
|
235
260
|
/>
|
|
236
261
|
<InfoBars
|
|
237
262
|
label={i18n._(t`Blood Glucose Level`)}
|
|
238
|
-
value={currentBGL ? `${
|
|
263
|
+
value={currentBGL ? `${displayedBGL}` : null}
|
|
239
264
|
units={this.props.units}
|
|
240
265
|
showZeroAsDash={true}
|
|
241
266
|
/>
|
|
@@ -254,7 +279,6 @@ export default class RecommendationScreen extends React.Component<IRecommendatio
|
|
|
254
279
|
changedRecommendedCarbs={this.updateCarbRecommendation}
|
|
255
280
|
recommendedCarbs={`${enteredCarbs ?? Math.round(carbRecommendation)}`}
|
|
256
281
|
removeRecommendedCarbs={this.removeCarbRecommendation}
|
|
257
|
-
onError={this.props.onError}
|
|
258
282
|
/>
|
|
259
283
|
<Remeasure
|
|
260
284
|
onSliderChange={this.updateRemeasureTime}
|
|
@@ -278,14 +302,14 @@ export default class RecommendationScreen extends React.Component<IRecommendatio
|
|
|
278
302
|
) : (
|
|
279
303
|
<RecommendedInsulin
|
|
280
304
|
injectionMethod={this.props.injectionMethod}
|
|
281
|
-
insulinRecommendation={
|
|
282
|
-
|
|
305
|
+
insulinRecommendation={insulinRecommendation}
|
|
306
|
+
enteredInsulin={enteredInsulin}
|
|
307
|
+
activityReduction={activityReduction}
|
|
283
308
|
updateRecommendedInsulin={this.updateInsulinRecommendation}
|
|
284
|
-
onError={this.props.onError}
|
|
285
309
|
/>
|
|
286
310
|
)}
|
|
287
311
|
<Emotion moodSelected={this.handleMoodSelected} currentMood={this.state.selectedMood} />
|
|
288
|
-
<TransferToLogbook visible={
|
|
312
|
+
<TransferToLogbook visible={isRecommendationDisplayed} transfer={this.handleTransfer} />
|
|
289
313
|
<RecommendationModal
|
|
290
314
|
isVisible={recommendationModal}
|
|
291
315
|
suggestedCarbohydrates={carbRecommendation}
|
|
@@ -51,7 +51,7 @@ class InvisibleNumberInput extends react_1.default.Component {
|
|
|
51
51
|
});
|
|
52
52
|
}
|
|
53
53
|
render() {
|
|
54
|
-
return (<react_native_1.TextInput accessibilityLabel="InvisibleNumberInput" value={`${this.state.value}`} ref={(textInput) => (this.textInput = textInput)} style={inputStyles.textInput} keyboardType="numeric" onChangeText={this.handleOnChangeText} onEndEditing={this.onEndEdit}/>);
|
|
54
|
+
return (<react_native_1.TextInput accessibilityLabel="InvisibleNumberInput" value={`${this.state.value}`} ref={(textInput) => (this.textInput = textInput)} style={inputStyles.textInput} keyboardType="numeric" onChangeText={this.handleOnChangeText} onEndEditing={this.onEndEdit} maxLength={this.props.maxLength} selectTextOnFocus/>);
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
exports.default = InvisibleNumberInput;
|
|
@@ -6,6 +6,7 @@ interface IProps {
|
|
|
6
6
|
decimalPlaces: number;
|
|
7
7
|
cleanPartialInput: boolean;
|
|
8
8
|
negativeAllowed: boolean;
|
|
9
|
+
maxLength?: number;
|
|
9
10
|
visible(toggle: () => void): void;
|
|
10
11
|
onEnd?(value: number): void;
|
|
11
12
|
partialInput?(value: string): void;
|
|
@@ -74,6 +75,8 @@ export default class InvisibleNumberInput extends React.Component<IProps, IState
|
|
|
74
75
|
keyboardType="numeric"
|
|
75
76
|
onChangeText={this.handleOnChangeText}
|
|
76
77
|
onEndEditing={this.onEndEdit}
|
|
78
|
+
maxLength={this.props.maxLength}
|
|
79
|
+
selectTextOnFocus
|
|
77
80
|
/>
|
|
78
81
|
);
|
|
79
82
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { RecommendationError } from "../utils/RecommendationError";
|
|
3
2
|
interface ICalculationRow {
|
|
4
3
|
label: string;
|
|
5
4
|
info: string;
|
|
@@ -11,7 +10,6 @@ interface IProps {
|
|
|
11
10
|
enteredCarbs: string;
|
|
12
11
|
removeRecommendedCarbs(): void;
|
|
13
12
|
changedRecommendedCarbs(value: number): void;
|
|
14
|
-
onError(error: RecommendationError): void;
|
|
15
13
|
}
|
|
16
14
|
interface IState {
|
|
17
15
|
partialInput: string;
|
|
@@ -29,14 +29,19 @@ class RecommendedCarbs extends react_1.default.Component {
|
|
|
29
29
|
this.handleChangedCarbs = (carbs) => {
|
|
30
30
|
if (carbs >= 0) {
|
|
31
31
|
if (carbs > 300) {
|
|
32
|
-
|
|
32
|
+
this.setState({ partialInput: this.props.recommendedCarbs });
|
|
33
|
+
return react_native_1.Alert.alert(i18nUtils_1.i18n._(`Attention`), RecommendationError_1.CarbohydrateLimitError().message, [
|
|
34
|
+
{
|
|
35
|
+
text: i18nUtils_1.i18n._(`OK`),
|
|
36
|
+
},
|
|
37
|
+
]);
|
|
33
38
|
}
|
|
34
39
|
this.props.changedRecommendedCarbs(carbs);
|
|
35
40
|
}
|
|
36
41
|
};
|
|
37
42
|
this.renderRecommendedCarbs = () => {
|
|
38
43
|
const shownCarbs = this.state.partialInput ?? Math.round(Number(this.props.recommendedCarbs));
|
|
39
|
-
const totalCarbs = Math.round(parseFloat(this.props.enteredCarbs) +
|
|
44
|
+
const totalCarbs = Math.round(parseFloat(this.props.enteredCarbs) + Number(shownCarbs));
|
|
40
45
|
return (<react_1.default.Fragment>
|
|
41
46
|
<react_native_1.View style={calculationStyles.borderContainer}>
|
|
42
47
|
<react_native_1.View style={calculationStyles.recommendedContainer}>
|
|
@@ -72,7 +77,7 @@ class RecommendedCarbs extends react_1.default.Component {
|
|
|
72
77
|
value: totalCarbs.toString(),
|
|
73
78
|
units: i18nUtils_1.i18n._(macro_1.t `g carbs`),
|
|
74
79
|
})}
|
|
75
|
-
<InvisibleNumberInput_1.default negativeAllowed={false} cleanPartialInput={true} decimalPlaces={0} visible={(callback) => (this.callbackInput = callback)} partialInput={this.handlePartialInput} onEnd={this.handleChangedCarbs} startValue={this.props.recommendedCarbs}/>
|
|
80
|
+
<InvisibleNumberInput_1.default negativeAllowed={false} cleanPartialInput={true} decimalPlaces={0} visible={(callback) => (this.callbackInput = callback)} partialInput={this.handlePartialInput} onEnd={this.handleChangedCarbs} startValue={this.props.recommendedCarbs} maxLength={3}/>
|
|
76
81
|
</react_1.default.Fragment>);
|
|
77
82
|
};
|
|
78
83
|
this.renderRow = (row) => {
|