@hedia/recommendation-screen 2.1.3-beta.6 → 2.1.3
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/coverage/clover.xml +29 -29
- package/coverage/coverage-final.json +27 -27
- package/coverage/lcov-report/index.html +1 -1
- package/coverage/lcov-report/src/RecommendationScreen.tsx.html +1 -1
- package/coverage/lcov-report/src/__tests__/index.html +1 -1
- package/coverage/lcov-report/src/__tests__/utils.tsx.html +1 -1
- package/coverage/lcov-report/src/components/Header.tsx.html +1 -1
- package/coverage/lcov-report/src/components/InfoBars.tsx.html +1 -1
- package/coverage/lcov-report/src/components/InvisibleNumberInput.tsx.html +1 -1
- package/coverage/lcov-report/src/components/LimitationMessage.tsx.html +1 -1
- package/coverage/lcov-report/src/components/LineSeparator.tsx.html +1 -1
- package/coverage/lcov-report/src/components/RecentInsulin.tsx.html +1 -1
- package/coverage/lcov-report/src/components/RecommendationModal.tsx.html +1 -1
- package/coverage/lcov-report/src/components/RecommendedCarbs.tsx.html +1 -1
- package/coverage/lcov-report/src/components/RecommendedInsulin.tsx.html +1 -1
- package/coverage/lcov-report/src/components/Remeasure.tsx.html +1 -1
- package/coverage/lcov-report/src/components/TransferToLogbook.tsx.html +1 -1
- package/coverage/lcov-report/src/components/TwoOptionModal.tsx.html +1 -1
- package/coverage/lcov-report/src/components/activity/Activity.tsx.html +1 -1
- package/coverage/lcov-report/src/components/activity/ActivityIcon.tsx.html +1 -1
- package/coverage/lcov-report/src/components/activity/ActivityIntensity.tsx.html +1 -1
- package/coverage/lcov-report/src/components/activity/index.html +1 -1
- package/coverage/lcov-report/src/components/index.html +1 -1
- package/coverage/lcov-report/src/components/mood/Emotion.tsx.html +1 -1
- package/coverage/lcov-report/src/components/mood/MoodIcon.tsx.html +1 -1
- package/coverage/lcov-report/src/components/mood/index.html +1 -1
- package/coverage/lcov-report/src/index.html +1 -1
- package/coverage/lcov-report/src/locale/i18nUtils.ts.html +1 -1
- package/coverage/lcov-report/src/locale/index.html +1 -1
- package/coverage/lcov-report/src/utils/AttentionMessages.tsx.html +1 -1
- package/coverage/lcov-report/src/utils/Constants.ts.html +1 -1
- package/coverage/lcov-report/src/utils/RecommendationError.tsx.html +1 -1
- package/coverage/lcov-report/src/utils/RecommendationUtils.ts.html +1 -1
- package/coverage/lcov-report/src/utils/Translations.ts.html +1 -1
- package/coverage/lcov-report/src/utils/Utils.ts.html +1 -1
- package/coverage/lcov-report/src/utils/Validations.ts.html +1 -1
- package/coverage/lcov-report/src/utils/index.html +1 -1
- package/index.js +5 -31
- package/package.json +1 -1
- package/src/RecommendationScreen.js +76 -101
- package/src/__tests__/RecommendationScreen.test.js +404 -409
- package/src/__tests__/RecommendationUtils.test.js +117 -119
- package/src/__tests__/Translate.test.js +14 -16
- package/src/__tests__/Utils.test.js +16 -18
- package/src/__tests__/Validations.test.js +30 -51
- package/src/__tests__/components/Activity.test.js +51 -56
- package/src/__tests__/components/Emotion.test.js +28 -33
- package/src/__tests__/components/Header.test.js +24 -29
- package/src/__tests__/components/InfoBars.test.js +59 -64
- package/src/__tests__/components/InvisibleNumberInput.test.js +22 -27
- package/src/__tests__/components/LimitationMessage.test.js +28 -33
- package/src/__tests__/components/MoodIcon.test.js +9 -14
- package/src/__tests__/components/RecommendationModal.test.js +56 -61
- package/src/__tests__/components/RecommendedCarbs.test.js +58 -63
- package/src/__tests__/components/RecommendedInsulin.test.js +60 -65
- package/src/__tests__/components/Remeasure.test.js +32 -37
- package/src/__tests__/components/TransferToLogbook.test.js +15 -20
- package/src/__tests__/components/TwoOptionModal.test.js +22 -27
- package/src/__tests__/utils.js +22 -38
- package/src/components/Header.js +34 -41
- package/src/components/Icon.js +2 -8
- package/src/components/InfoBars.js +36 -43
- package/src/components/InvisibleNumberInput.js +5 -11
- package/src/components/LimitationMessage.js +18 -40
- package/src/components/LineSeparator.js +7 -13
- package/src/components/RecentInsulin.js +33 -39
- package/src/components/RecommendationModal.js +59 -85
- package/src/components/RecommendedCarbs.js +93 -99
- package/src/components/RecommendedInsulin.js +46 -52
- package/src/components/Remeasure.js +36 -42
- package/src/components/TransferToLogbook.js +20 -26
- package/src/components/TwoOptionModal.js +39 -65
- package/src/components/activity/Activity.js +42 -48
- package/src/components/activity/ActivityIcon.js +15 -21
- package/src/components/activity/ActivityIntensity.js +19 -25
- package/src/components/mood/Emotion.js +17 -23
- package/src/components/mood/MoodIcon.js +11 -17
- package/src/locale/i18nUtils.js +17 -24
- package/src/types/enum.js +28 -31
- package/src/types/types.js +1 -2
- package/src/utils/AttentionMessages.js +24 -32
- package/src/utils/Constants.js +23 -26
- package/src/utils/RecommendationError.js +28 -54
- package/src/utils/RecommendationUtils.js +60 -72
- package/src/utils/Translations.js +6 -9
- package/src/utils/Utils.js +8 -12
- package/src/utils/Validations.js +77 -107
- package/tsconfig.json +3 -3
|
@@ -1,59 +1,33 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
const enum_1 = require("../types/enum");
|
|
8
|
-
const SAFETY_INSULIN_LIMIT = types_1.BolusCalculator.Constants.SAFETY_INSULIN_LIMIT;
|
|
9
|
-
class RecommendationError extends Error {
|
|
1
|
+
import { BolusCalculator } from "@hedia/types";
|
|
2
|
+
import { t } from "@lingui/macro";
|
|
3
|
+
import { i18n } from "../locale/i18nUtils";
|
|
4
|
+
import { RecommendationErrorEnum } from "../types/enum";
|
|
5
|
+
const SAFETY_INSULIN_LIMIT = BolusCalculator.Constants.SAFETY_INSULIN_LIMIT;
|
|
6
|
+
export class RecommendationError extends Error {
|
|
10
7
|
constructor(message, type) {
|
|
11
8
|
super(message);
|
|
12
9
|
this.type = type;
|
|
13
10
|
}
|
|
14
11
|
}
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
exports.LatestLogbook6HoursBGLError = LatestLogbook6HoursBGLError;
|
|
38
|
-
const CurrentBKLError = () => new RecommendationError(i18nUtils_1.i18n._(macro_1.t `Error. Hedia Calculator does not support your current blood ketone level.`), enum_1.RecommendationErrorEnum.CurrentBKL);
|
|
39
|
-
exports.CurrentBKLError = CurrentBKLError;
|
|
40
|
-
const TargetBGLError = () => new RecommendationError(i18nUtils_1.i18n._(macro_1.t `Error. Please verify that your target blood glucose value is correct.`), enum_1.RecommendationErrorEnum.TargetBGL);
|
|
41
|
-
exports.TargetBGLError = TargetBGLError;
|
|
42
|
-
const BolusInsulinDoseError = () => new RecommendationError(i18nUtils_1.i18n._(macro_1.t `Error. Hedia Calculator does not support an insulin dose greater than ${SAFETY_INSULIN_LIMIT} units`), enum_1.RecommendationErrorEnum.BolusInsulinDose);
|
|
43
|
-
exports.BolusInsulinDoseError = BolusInsulinDoseError;
|
|
44
|
-
const BolusInsulinSecondsPassedError = () => new RecommendationError(i18nUtils_1.i18n._(macro_1.t `Error. Hedia Calculator does not support insulin recommendations with boluses older than 4 hours`), enum_1.RecommendationErrorEnum.BolusInsulinSecondsPassed);
|
|
45
|
-
exports.BolusInsulinSecondsPassedError = BolusInsulinSecondsPassedError;
|
|
46
|
-
const RecentBolusError = () => new RecommendationError(i18nUtils_1.i18n._(macro_1.t `Error. Hedia Calculator could not find your recent boluses`), enum_1.RecommendationErrorEnum.RecentBolus);
|
|
47
|
-
exports.RecentBolusError = RecentBolusError;
|
|
48
|
-
const UserReminderError = () => new RecommendationError(i18nUtils_1.i18n._(macro_1.t `Error. Please verify your notifications settings.`), enum_1.RecommendationErrorEnum.UserReminder);
|
|
49
|
-
exports.UserReminderError = UserReminderError;
|
|
50
|
-
const InjectionMethodError = () => new RecommendationError(i18nUtils_1.i18n._(macro_1.t `Error. Hedia Calculator does not support your injection method.`), enum_1.RecommendationErrorEnum.InjectionMethod);
|
|
51
|
-
exports.InjectionMethodError = InjectionMethodError;
|
|
52
|
-
const LanguageError = () => new RecommendationError(i18nUtils_1.i18n._(macro_1.t `Error. Hedia Calculator does not support your current language.`), enum_1.RecommendationErrorEnum.Language);
|
|
53
|
-
exports.LanguageError = LanguageError;
|
|
54
|
-
const BloodKetoneUnitError = () => new RecommendationError(i18nUtils_1.i18n._(macro_1.t `Error. Hedia Calculator does not support your current blood ketone unit.`), enum_1.RecommendationErrorEnum.BloodKetoneUnit);
|
|
55
|
-
exports.BloodKetoneUnitError = BloodKetoneUnitError;
|
|
56
|
-
const BloodGlucoseUnitError = () => new RecommendationError(i18nUtils_1.i18n._(macro_1.t `Error. Hedia Calculator does not support your current blood glucose unit.`), enum_1.RecommendationErrorEnum.BloodGlucoseUnit);
|
|
57
|
-
exports.BloodGlucoseUnitError = BloodGlucoseUnitError;
|
|
58
|
-
const BloodKetonePropsError = () => new RecommendationError(i18nUtils_1.i18n._(macro_1.t `Error. Your blood ketone settings are invalid.`), enum_1.RecommendationErrorEnum.BloodKetoneProps);
|
|
59
|
-
exports.BloodKetonePropsError = BloodKetonePropsError;
|
|
12
|
+
export const ActivitySettingsError = () => new RecommendationError(i18n._(t `Error. Please verify that your activity settings are set up correctly.`), RecommendationErrorEnum.ActivitySettings);
|
|
13
|
+
export const ActivityDurationError = () => new RecommendationError(i18n._(t `Error. Hedia Calculator only supports activities with a duration of maximum 60 minutes.`), RecommendationErrorEnum.ActivityDuration);
|
|
14
|
+
export const ActivityDateError = () => new RecommendationError(i18n._(t `Hedia Calculator does not support activities that finished more than 4 hours ago.`), RecommendationErrorEnum.ActivityDate);
|
|
15
|
+
export const ActivityIntensityError = () => new RecommendationError(i18n._(t `Error. Hedia Calculator does not support your activity intensity value`), RecommendationErrorEnum.ActivityIntensity);
|
|
16
|
+
export const ActivityTypeError = () => new RecommendationError(i18n._(t `Error. Hedia Calculator does not support your activity type value`), RecommendationErrorEnum.ActivityType);
|
|
17
|
+
export const ActivityTargetBGLError = () => new RecommendationError(i18n._(t `Error. Please verify that your activity target blood glucose value is correct.`), RecommendationErrorEnum.ActivityTargetBGL);
|
|
18
|
+
export const CarbohydrateLimitError = () => new RecommendationError(i18n._(t `Hedia Calculator does not support insulin recommendations with more than 300 grams of carbohydrates present.`), RecommendationErrorEnum.CarbohydrateLimit);
|
|
19
|
+
export const InsulinSensitivityError = () => new RecommendationError(i18n._(t `Error. Please verify that your insulin sensitivity value is correct.`), RecommendationErrorEnum.InsulinSensitivity);
|
|
20
|
+
export const InsulinToCarbsRatioError = () => new RecommendationError(i18n._(t `Error. Please verify that your insulin to carb ratio value is correct.`), RecommendationErrorEnum.InsulinToCarbsRatio);
|
|
21
|
+
export const CurrentBGLError = () => new RecommendationError(i18n._(t `Error. Hedia Calculator does not support your current blood glucose level.`), RecommendationErrorEnum.CurrentBGL);
|
|
22
|
+
export const LatestLogbook6HoursBGLError = () => new RecommendationError(i18n._(t `Error. Hedia Calculator does not support the blood glucose level of your latest logbook entry from the last 6 hours.`), RecommendationErrorEnum.LatestLogbook6HoursBGL);
|
|
23
|
+
export const CurrentBKLError = () => new RecommendationError(i18n._(t `Error. Hedia Calculator does not support your current blood ketone level.`), RecommendationErrorEnum.CurrentBKL);
|
|
24
|
+
export const TargetBGLError = () => new RecommendationError(i18n._(t `Error. Please verify that your target blood glucose value is correct.`), RecommendationErrorEnum.TargetBGL);
|
|
25
|
+
export const BolusInsulinDoseError = () => new RecommendationError(i18n._(t `Error. Hedia Calculator does not support an insulin dose greater than ${SAFETY_INSULIN_LIMIT} units`), RecommendationErrorEnum.BolusInsulinDose);
|
|
26
|
+
export const BolusInsulinSecondsPassedError = () => new RecommendationError(i18n._(t `Error. Hedia Calculator does not support insulin recommendations with boluses older than 4 hours`), RecommendationErrorEnum.BolusInsulinSecondsPassed);
|
|
27
|
+
export const RecentBolusError = () => new RecommendationError(i18n._(t `Error. Hedia Calculator could not find your recent boluses`), RecommendationErrorEnum.RecentBolus);
|
|
28
|
+
export const UserReminderError = () => new RecommendationError(i18n._(t `Error. Please verify your notifications settings.`), RecommendationErrorEnum.UserReminder);
|
|
29
|
+
export const InjectionMethodError = () => new RecommendationError(i18n._(t `Error. Hedia Calculator does not support your injection method.`), RecommendationErrorEnum.InjectionMethod);
|
|
30
|
+
export const LanguageError = () => new RecommendationError(i18n._(t `Error. Hedia Calculator does not support your current language.`), RecommendationErrorEnum.Language);
|
|
31
|
+
export const BloodKetoneUnitError = () => new RecommendationError(i18n._(t `Error. Hedia Calculator does not support your current blood ketone unit.`), RecommendationErrorEnum.BloodKetoneUnit);
|
|
32
|
+
export const BloodGlucoseUnitError = () => new RecommendationError(i18n._(t `Error. Hedia Calculator does not support your current blood glucose unit.`), RecommendationErrorEnum.BloodGlucoseUnit);
|
|
33
|
+
export const BloodKetonePropsError = () => new RecommendationError(i18n._(t `Error. Your blood ketone settings are invalid.`), RecommendationErrorEnum.BloodKetoneProps);
|
|
@@ -1,119 +1,107 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const enum_1 = require("../types/enum");
|
|
9
|
-
const AttentionMessages_1 = require("./AttentionMessages");
|
|
10
|
-
const Constants_1 = require("./Constants");
|
|
11
|
-
const RecommendationError_1 = require("./RecommendationError");
|
|
12
|
-
const Utils_1 = require("./Utils");
|
|
13
|
-
function getBGLevel(currentBGL, latestLogbookFrom6Hours) {
|
|
1
|
+
import moment from "moment";
|
|
2
|
+
import { BgLevel, RecommendationReminders } from "../types/enum";
|
|
3
|
+
import { addPostponeActivityMessageUnder5MMOL, AttentionMessage, Messages } from "./AttentionMessages";
|
|
4
|
+
import { SEVERE_HYPERGLYCEMIA_START_MMOL } from "./Constants";
|
|
5
|
+
import { CurrentBGLError } from "./RecommendationError";
|
|
6
|
+
import { Utils } from "./Utils";
|
|
7
|
+
export function getBGLevel(currentBGL, latestLogbookFrom6Hours) {
|
|
14
8
|
if (currentBGL === null) {
|
|
15
|
-
return
|
|
9
|
+
return BgLevel.BGLevelNotProvided;
|
|
16
10
|
}
|
|
17
11
|
if (currentBGL >= 1.1 && currentBGL <= 2) {
|
|
18
|
-
return
|
|
12
|
+
return BgLevel.SevereHypoglycemia;
|
|
19
13
|
}
|
|
20
14
|
if (currentBGL > 2 && currentBGL <= 3.5) {
|
|
21
|
-
return
|
|
15
|
+
return BgLevel.Hypoglycemia;
|
|
22
16
|
}
|
|
23
17
|
if (currentBGL > 3.5 && currentBGL <= 4) {
|
|
24
|
-
return
|
|
18
|
+
return BgLevel.MildHypoglycemia;
|
|
25
19
|
}
|
|
26
20
|
if (currentBGL > 4 && currentBGL < 5) {
|
|
27
|
-
return
|
|
21
|
+
return BgLevel.NormoglycemiaUnder5MMOL;
|
|
28
22
|
}
|
|
29
23
|
if (currentBGL >= 5 && currentBGL <= 7) {
|
|
30
|
-
return
|
|
24
|
+
return BgLevel.Normoglycemia;
|
|
31
25
|
}
|
|
32
26
|
if (currentBGL > 7 && currentBGL < 15) {
|
|
33
|
-
return
|
|
27
|
+
return BgLevel.MildHyperglycemia;
|
|
34
28
|
}
|
|
35
29
|
if (currentBGL > 15 && currentBGL <= 33.3 && latestLogbookFrom6Hours
|
|
36
30
|
? isSevereHyperglycemia(latestLogbookFrom6Hours)
|
|
37
31
|
: false) {
|
|
38
|
-
return
|
|
32
|
+
return BgLevel.SevereHyperglycemia;
|
|
39
33
|
}
|
|
40
34
|
if (currentBGL >= 15 && currentBGL <= 33.3) {
|
|
41
|
-
return
|
|
35
|
+
return BgLevel.Hyperglycemia;
|
|
42
36
|
}
|
|
43
|
-
return
|
|
37
|
+
return BgLevel.UnsupportedBGLevel;
|
|
44
38
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const reminder = userReminder === undefined ? enum_1.RecommendationReminders.HediaReminderDefault : userReminder;
|
|
39
|
+
export function getReminder(bgLevel, carbohydrates, userReminder, activity) {
|
|
40
|
+
const reminder = userReminder === undefined ? RecommendationReminders.HediaReminderDefault : userReminder;
|
|
48
41
|
switch (bgLevel) {
|
|
49
|
-
case
|
|
50
|
-
case
|
|
51
|
-
case
|
|
52
|
-
return
|
|
53
|
-
case
|
|
54
|
-
case
|
|
55
|
-
case
|
|
56
|
-
case
|
|
57
|
-
return carbohydrates || activity ? reminder :
|
|
58
|
-
case
|
|
59
|
-
case
|
|
42
|
+
case BgLevel.SevereHypoglycemia:
|
|
43
|
+
case BgLevel.Hypoglycemia:
|
|
44
|
+
case BgLevel.MildHypoglycemia:
|
|
45
|
+
return RecommendationReminders.Reminder15Minutes;
|
|
46
|
+
case BgLevel.NormoglycemiaUnder5MMOL:
|
|
47
|
+
case BgLevel.Normoglycemia:
|
|
48
|
+
case BgLevel.MildHyperglycemia:
|
|
49
|
+
case BgLevel.BGLevelNotProvided:
|
|
50
|
+
return carbohydrates || activity ? reminder : RecommendationReminders.ReminderOff;
|
|
51
|
+
case BgLevel.Hyperglycemia:
|
|
52
|
+
case BgLevel.SevereHyperglycemia:
|
|
60
53
|
return isActivityWithin15Minutes(activity)
|
|
61
|
-
?
|
|
62
|
-
:
|
|
54
|
+
? RecommendationReminders.Reminder15Minutes
|
|
55
|
+
: RecommendationReminders.Reminder60Minutes;
|
|
63
56
|
default:
|
|
64
|
-
throw
|
|
57
|
+
throw CurrentBGLError();
|
|
65
58
|
}
|
|
66
59
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
const
|
|
70
|
-
const isAttentionMessageNull = AttentionMessages_1.AttentionMessage[key] === null;
|
|
60
|
+
export function getAttentionMessage(bgLevel, activity) {
|
|
61
|
+
const key = Utils.getKeyFromValue(BgLevel, bgLevel);
|
|
62
|
+
const isAttentionMessageNull = AttentionMessage[key] === null;
|
|
71
63
|
const isWithin15Minutes = isActivityWithin15Minutes(activity);
|
|
72
64
|
switch (bgLevel) {
|
|
73
|
-
case
|
|
74
|
-
case
|
|
75
|
-
case
|
|
65
|
+
case BgLevel.BGLevelNotProvided:
|
|
66
|
+
case BgLevel.Normoglycemia:
|
|
67
|
+
case BgLevel.MildHyperglycemia:
|
|
76
68
|
return null;
|
|
77
|
-
case
|
|
78
|
-
return isWithin15Minutes ?
|
|
79
|
-
case
|
|
80
|
-
case
|
|
81
|
-
case
|
|
69
|
+
case BgLevel.NormoglycemiaUnder5MMOL:
|
|
70
|
+
return isWithin15Minutes ? AttentionMessage.NormoglycemiaActivityUnder5MMOL() : null;
|
|
71
|
+
case BgLevel.SevereHypoglycemia:
|
|
72
|
+
case BgLevel.Hypoglycemia:
|
|
73
|
+
case BgLevel.MildHypoglycemia:
|
|
82
74
|
return isWithin15Minutes && !isAttentionMessageNull
|
|
83
|
-
?
|
|
84
|
-
:
|
|
85
|
-
case
|
|
86
|
-
return isWithin15Minutes ?
|
|
87
|
-
case
|
|
75
|
+
? addPostponeActivityMessageUnder5MMOL(AttentionMessage[key]())
|
|
76
|
+
: AttentionMessage[key]();
|
|
77
|
+
case BgLevel.Hyperglycemia:
|
|
78
|
+
return isWithin15Minutes ? AttentionMessage.HyperglycemiaActivity() : null;
|
|
79
|
+
case BgLevel.SevereHyperglycemia:
|
|
88
80
|
return isWithin15Minutes
|
|
89
|
-
?
|
|
90
|
-
:
|
|
81
|
+
? AttentionMessage.SevereHyperglycemiaActivity()
|
|
82
|
+
: AttentionMessage.SevereHyperglycemia();
|
|
91
83
|
default:
|
|
92
|
-
throw
|
|
84
|
+
throw CurrentBGLError();
|
|
93
85
|
}
|
|
94
86
|
}
|
|
95
|
-
|
|
96
|
-
function isSevereHyperglycemia(logbook) {
|
|
87
|
+
export function isSevereHyperglycemia(logbook) {
|
|
97
88
|
if (logbook !== null && logbook !== undefined) {
|
|
98
89
|
const { blood_glucose_millimolar } = logbook;
|
|
99
90
|
if (blood_glucose_millimolar !== null) {
|
|
100
|
-
return blood_glucose_millimolar >
|
|
91
|
+
return blood_glucose_millimolar > SEVERE_HYPERGLYCEMIA_START_MMOL;
|
|
101
92
|
}
|
|
102
93
|
}
|
|
103
94
|
return false;
|
|
104
95
|
}
|
|
105
|
-
|
|
106
|
-
function isActivityWithin15Minutes(activity) {
|
|
96
|
+
export function isActivityWithin15Minutes(activity) {
|
|
107
97
|
const minutes = activity?.activityDuration;
|
|
108
|
-
return
|
|
98
|
+
return moment
|
|
109
99
|
.utc(activity?.activityDate)
|
|
110
|
-
.isBetween(
|
|
100
|
+
.isBetween(moment.utc().subtract(minutes, `minutes`), moment.utc().add(15, `minutes`));
|
|
111
101
|
}
|
|
112
|
-
|
|
113
|
-
function getLimitationMessage(wasLimited, activityReduction) {
|
|
102
|
+
export function getLimitationMessage(wasLimited, activityReduction) {
|
|
114
103
|
const message = activityReduction
|
|
115
|
-
?
|
|
116
|
-
:
|
|
104
|
+
? Messages.RecommendationWasLimitedActivity(activityReduction)
|
|
105
|
+
: Messages.RecommendationWasLimited();
|
|
117
106
|
return wasLimited ? message : null;
|
|
118
107
|
}
|
|
119
|
-
exports.getLimitationMessage = getLimitationMessage;
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
light: () => i18nUtils_1.i18n._(macro_1.t `Light`),
|
|
8
|
-
moderate: () => i18nUtils_1.i18n._(macro_1.t `Moderate`),
|
|
9
|
-
hard: () => i18nUtils_1.i18n._(macro_1.t `Hard`),
|
|
1
|
+
import { t } from "@lingui/macro";
|
|
2
|
+
import { i18n } from "../locale/i18nUtils";
|
|
3
|
+
export const ActivityIntensityTranslations = {
|
|
4
|
+
light: () => i18n._(t `Light`),
|
|
5
|
+
moderate: () => i18n._(t `Moderate`),
|
|
6
|
+
hard: () => i18n._(t `Hard`),
|
|
10
7
|
};
|
package/src/utils/Utils.js
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const types_1 = require("@hedia/types");
|
|
5
|
-
const Constants_1 = require("./Constants");
|
|
6
|
-
const InjectionMethod = types_1.UserSettings.Enums.InjectionMethod;
|
|
1
|
+
import { BloodGlucoseUnit, BloodKetonesUnit, UserSettings } from "@hedia/types";
|
|
2
|
+
import { MGDL_PER_MMOLL_BGL, MGDL_PER_MMOLL_BKL } from "./Constants";
|
|
3
|
+
const InjectionMethod = UserSettings.Enums.InjectionMethod;
|
|
7
4
|
const { PenHalf, PenWhole, Pump } = InjectionMethod;
|
|
8
|
-
class Utils {
|
|
5
|
+
export class Utils {
|
|
9
6
|
static getRounding(method) {
|
|
10
7
|
switch (method) {
|
|
11
8
|
case PenWhole:
|
|
@@ -29,23 +26,22 @@ class Utils {
|
|
|
29
26
|
return value >= interval.min && value <= interval.max;
|
|
30
27
|
}
|
|
31
28
|
static convertBGLToMGDL(value) {
|
|
32
|
-
return Math.round(value *
|
|
29
|
+
return Math.round(value * MGDL_PER_MMOLL_BGL);
|
|
33
30
|
}
|
|
34
31
|
static displayedBGLValue(value, unit) {
|
|
35
|
-
return unit ===
|
|
32
|
+
return unit === BloodGlucoseUnit.MMOL_L ? `${value}` : `${Utils.convertBGLToMGDL(value)}`;
|
|
36
33
|
}
|
|
37
34
|
static convertBKLToMGDL(value) {
|
|
38
|
-
return Math.round(value *
|
|
35
|
+
return Math.round(value * MGDL_PER_MMOLL_BKL);
|
|
39
36
|
}
|
|
40
37
|
static displayedBKLValue(value, unit) {
|
|
41
|
-
return unit ===
|
|
38
|
+
return unit === BloodKetonesUnit.MMOL_L ? `${value}` : `${Utils.convertBKLToMGDL(value)}`;
|
|
42
39
|
}
|
|
43
40
|
static getKeyFromValue(keys, value) {
|
|
44
41
|
const values = Object.values(keys);
|
|
45
42
|
return Object.keys(keys)[values.indexOf(value)];
|
|
46
43
|
}
|
|
47
44
|
}
|
|
48
|
-
exports.Utils = Utils;
|
|
49
45
|
Utils.formatUnit = (unit) => {
|
|
50
46
|
const unitWithoutLastLetter = unit.substring(0, unit.length - 1);
|
|
51
47
|
const lastLetterUppercase = unit.substring(unit.length - 1, unit.length).toUpperCase();
|
package/src/utils/Validations.js
CHANGED
|
@@ -1,17 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
const Constants_1 = require("./Constants");
|
|
10
|
-
const RecommendationError_1 = require("./RecommendationError");
|
|
11
|
-
const Utils_1 = require("./Utils");
|
|
12
|
-
const { hard } = types_1.Activity.Enums.ActivityIntensity;
|
|
13
|
-
const { fromFortysix } = types_1.Activity.Enums.ActivityReductionIntervals;
|
|
14
|
-
function validateParams(props) {
|
|
1
|
+
import { Activity, BloodGlucoseUnit, BloodKetonesUnit, Languages, UserSettings } from "@hedia/types";
|
|
2
|
+
import moment from "moment";
|
|
3
|
+
import { ACTIVITY_BUFFER_MINUTES, ACTIVITY_DURATION_MINUTES_LIMITS, ACTIVITY_SETTINGS_INTERVAL_LIMITS, ACTIVITY_TARGET_BGL_MMOL_LIMITS, BOLUS_SECONDS_PASSED_LIMITS, CARBOHYDRATES_LIMTS, CURRENT_BGL_MMOL_LIMITS, CURRENT_BKL_MMOL_LIMITS, INSULIN_DOSE_LIMITS, INSULIN_SENSITIVITY_MMOL_LIMITS, INSULIN_TO_CARBS_RATIO_LIMITS, ONE_HOUR_MINUTES, REMINDER_HOURS_LIMITS, TARGET_BGL_MMOL_LIMITS, } from "./Constants";
|
|
4
|
+
import { ActivityDateError, ActivityDurationError, ActivityIntensityError, ActivitySettingsError, ActivityTargetBGLError, ActivityTypeError, BloodGlucoseUnitError, BloodKetonePropsError, BloodKetoneUnitError, BolusInsulinDoseError, BolusInsulinSecondsPassedError, CarbohydrateLimitError, CurrentBGLError, CurrentBKLError, InjectionMethodError, InsulinSensitivityError, InsulinToCarbsRatioError, LanguageError, LatestLogbook6HoursBGLError, RecentBolusError, TargetBGLError, UserReminderError, } from "./RecommendationError";
|
|
5
|
+
import { Utils } from "./Utils";
|
|
6
|
+
const { hard } = Activity.Enums.ActivityIntensity;
|
|
7
|
+
const { fromFortysix } = Activity.Enums.ActivityReductionIntervals;
|
|
8
|
+
export function validateParams(props) {
|
|
15
9
|
checkCalculatorParams(props.calculatorParams);
|
|
16
10
|
checkBGLUnit(props.bloodGlucoseUnit);
|
|
17
11
|
checkBKProps(props.bloodKetoneUnit, props.currentBKL);
|
|
@@ -25,59 +19,51 @@ function validateParams(props) {
|
|
|
25
19
|
checkActivityType(props.activityDisplayProps.activityType);
|
|
26
20
|
}
|
|
27
21
|
}
|
|
28
|
-
|
|
29
|
-
function checkBKProps(bloodKetoneUnit, currentBKL) {
|
|
22
|
+
export function checkBKProps(bloodKetoneUnit, currentBKL) {
|
|
30
23
|
if (currentBKL !== null && bloodKetoneUnit === null) {
|
|
31
|
-
throw
|
|
24
|
+
throw BloodKetonePropsError();
|
|
32
25
|
}
|
|
33
26
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
throw RecommendationError_1.LanguageError();
|
|
27
|
+
export function checkLanguage(language) {
|
|
28
|
+
if (!Object.values(Languages).includes(language)) {
|
|
29
|
+
throw LanguageError();
|
|
38
30
|
}
|
|
39
31
|
}
|
|
40
|
-
|
|
41
|
-
function checkLatestLogbook6Hours(logbook) {
|
|
32
|
+
export function checkLatestLogbook6Hours(logbook) {
|
|
42
33
|
if (logbook === undefined) {
|
|
43
|
-
throw
|
|
34
|
+
throw LatestLogbook6HoursBGLError();
|
|
44
35
|
}
|
|
45
36
|
if (logbook !== null) {
|
|
46
|
-
if (!
|
|
47
|
-
throw
|
|
37
|
+
if (!Utils.isInRange(logbook.blood_glucose_millimolar, CURRENT_BGL_MMOL_LIMITS)) {
|
|
38
|
+
throw LatestLogbook6HoursBGLError();
|
|
48
39
|
}
|
|
49
40
|
}
|
|
50
41
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const check = Object.values(types_1.UserSettings.Enums.InjectionMethod).some((method) => method === injectionMethod);
|
|
42
|
+
export function checkInjectionMethod(injectionMethod) {
|
|
43
|
+
const check = Object.values(UserSettings.Enums.InjectionMethod).some((method) => method === injectionMethod);
|
|
54
44
|
if (!check) {
|
|
55
|
-
throw
|
|
45
|
+
throw InjectionMethodError();
|
|
56
46
|
}
|
|
57
47
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const check = Object.values(types_1.BloodGlucoseUnit).some((enumUnit) => enumUnit === unit);
|
|
48
|
+
export function checkBGLUnit(unit) {
|
|
49
|
+
const check = Object.values(BloodGlucoseUnit).some((enumUnit) => enumUnit === unit);
|
|
61
50
|
if (!check) {
|
|
62
|
-
throw
|
|
51
|
+
throw BloodGlucoseUnitError();
|
|
63
52
|
}
|
|
64
53
|
}
|
|
65
|
-
|
|
66
|
-
function checkBKLUnit(unit) {
|
|
54
|
+
export function checkBKLUnit(unit) {
|
|
67
55
|
if (unit !== null) {
|
|
68
|
-
const check = Object.values(
|
|
56
|
+
const check = Object.values(BloodKetonesUnit).some((enumUnit) => enumUnit === unit);
|
|
69
57
|
if (!check) {
|
|
70
|
-
throw
|
|
58
|
+
throw BloodKetoneUnitError();
|
|
71
59
|
}
|
|
72
60
|
}
|
|
73
61
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
throw RecommendationError_1.UserReminderError();
|
|
62
|
+
export function checkUserReminder(userReminder) {
|
|
63
|
+
if (!Utils.isInRange(userReminder, REMINDER_HOURS_LIMITS)) {
|
|
64
|
+
throw UserReminderError();
|
|
78
65
|
}
|
|
79
66
|
}
|
|
80
|
-
exports.checkUserReminder = checkUserReminder;
|
|
81
67
|
function checkCalculatorParams(calculatorParams) {
|
|
82
68
|
checkActivity(calculatorParams.activity);
|
|
83
69
|
checkCarbohydrates(calculatorParams.carbohydrates);
|
|
@@ -89,7 +75,7 @@ function checkCalculatorParams(calculatorParams) {
|
|
|
89
75
|
checkRecentBolusesInsulinDose(calculatorParams.recentBoluses);
|
|
90
76
|
checkRecentBolusesSecondsPassed(calculatorParams.recentBoluses);
|
|
91
77
|
}
|
|
92
|
-
function checkActivity(activity) {
|
|
78
|
+
export function checkActivity(activity) {
|
|
93
79
|
if (activity) {
|
|
94
80
|
checkActivityDate(activity);
|
|
95
81
|
checkActivityDuration(activity.activityDuration);
|
|
@@ -98,119 +84,103 @@ function checkActivity(activity) {
|
|
|
98
84
|
checkActivityTargetBGL(activity.activitySettings.target);
|
|
99
85
|
}
|
|
100
86
|
}
|
|
101
|
-
|
|
102
|
-
function checkRecentBolus(recentBoluses) {
|
|
87
|
+
export function checkRecentBolus(recentBoluses) {
|
|
103
88
|
if (recentBoluses === null || recentBoluses === undefined) {
|
|
104
|
-
throw
|
|
89
|
+
throw RecentBolusError();
|
|
105
90
|
}
|
|
106
91
|
}
|
|
107
|
-
|
|
108
|
-
function checkRecentBolusesInsulinDose(recentBoluses) {
|
|
92
|
+
export function checkRecentBolusesInsulinDose(recentBoluses) {
|
|
109
93
|
recentBoluses.forEach((bolus) => {
|
|
110
|
-
if (!
|
|
111
|
-
throw
|
|
94
|
+
if (!Utils.isInRange(bolus.insulinDose, INSULIN_DOSE_LIMITS)) {
|
|
95
|
+
throw BolusInsulinDoseError();
|
|
112
96
|
}
|
|
113
97
|
});
|
|
114
98
|
}
|
|
115
|
-
|
|
116
|
-
function checkRecentBolusesSecondsPassed(recentBoluses) {
|
|
99
|
+
export function checkRecentBolusesSecondsPassed(recentBoluses) {
|
|
117
100
|
recentBoluses.forEach((bolus) => {
|
|
118
|
-
if (!
|
|
119
|
-
throw
|
|
101
|
+
if (!Utils.isInRange(bolus.secondsPassed, BOLUS_SECONDS_PASSED_LIMITS)) {
|
|
102
|
+
throw BolusInsulinSecondsPassedError();
|
|
120
103
|
}
|
|
121
104
|
});
|
|
122
105
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
throw RecommendationError_1.ActivityDurationError();
|
|
106
|
+
export function checkActivityDuration(activityDuration) {
|
|
107
|
+
if (!Utils.isInRange(activityDuration, ACTIVITY_DURATION_MINUTES_LIMITS)) {
|
|
108
|
+
throw ActivityDurationError();
|
|
127
109
|
}
|
|
128
110
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
const check = Object.values(types_1.Activity.Enums.ActivityIntensity).some((method) => method === activityIntensity);
|
|
111
|
+
export function checkActivityIntensity(activityIntensity) {
|
|
112
|
+
const check = Object.values(Activity.Enums.ActivityIntensity).some((method) => method === activityIntensity);
|
|
132
113
|
if (!check) {
|
|
133
|
-
throw
|
|
114
|
+
throw ActivityIntensityError();
|
|
134
115
|
}
|
|
135
116
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
const check = Object.values(types_1.Activity.Enums.ActivityEnum).some((method) => method === activityType);
|
|
117
|
+
export function checkActivityType(activityType) {
|
|
118
|
+
const check = Object.values(Activity.Enums.ActivityEnum).some((method) => method === activityType);
|
|
139
119
|
if (!check) {
|
|
140
|
-
throw
|
|
120
|
+
throw ActivityTypeError();
|
|
141
121
|
}
|
|
142
122
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
const maximumDate = moment_1.default
|
|
123
|
+
export function checkActivityDate(activity) {
|
|
124
|
+
const maximumDate = moment
|
|
146
125
|
.utc(activity.activityDate)
|
|
147
|
-
.add(activity.activityDuration +
|
|
148
|
-
if (
|
|
149
|
-
throw
|
|
126
|
+
.add(activity.activityDuration + ONE_HOUR_MINUTES * 4 + ACTIVITY_BUFFER_MINUTES, `minutes`);
|
|
127
|
+
if (moment.utc().isAfter(maximumDate)) {
|
|
128
|
+
throw ActivityDateError();
|
|
150
129
|
}
|
|
151
130
|
}
|
|
152
|
-
|
|
153
|
-
function checkActivitySettings(activitySettings) {
|
|
131
|
+
export function checkActivitySettings(activitySettings) {
|
|
154
132
|
for (const intensity of Object.keys(activitySettings)) {
|
|
155
133
|
const reductionIntervals = activitySettings[intensity];
|
|
156
134
|
for (const interval of Object.keys(reductionIntervals)) {
|
|
157
135
|
const value = activitySettings[intensity][interval];
|
|
158
|
-
const isInInterval =
|
|
136
|
+
const isInInterval = Utils.isInRange(value, ACTIVITY_SETTINGS_INTERVAL_LIMITS);
|
|
159
137
|
if (intensity === hard && interval === fromFortysix) {
|
|
160
138
|
if (!isInInterval && value !== null) {
|
|
161
|
-
throw
|
|
139
|
+
throw ActivitySettingsError();
|
|
162
140
|
}
|
|
163
141
|
}
|
|
164
142
|
else if (!isInInterval) {
|
|
165
|
-
throw
|
|
143
|
+
throw ActivitySettingsError();
|
|
166
144
|
}
|
|
167
145
|
}
|
|
168
146
|
}
|
|
169
147
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
throw RecommendationError_1.ActivityTargetBGLError();
|
|
148
|
+
export function checkActivityTargetBGL(activitySettingsTargetBGL) {
|
|
149
|
+
if (!Utils.isInRange(activitySettingsTargetBGL, ACTIVITY_TARGET_BGL_MMOL_LIMITS)) {
|
|
150
|
+
throw ActivityTargetBGLError();
|
|
174
151
|
}
|
|
175
152
|
}
|
|
176
|
-
|
|
177
|
-
function checkCurrentBGL(currentBGL) {
|
|
153
|
+
export function checkCurrentBGL(currentBGL) {
|
|
178
154
|
if (currentBGL !== null) {
|
|
179
|
-
if (!
|
|
180
|
-
throw
|
|
155
|
+
if (!Utils.isInRange(currentBGL, CURRENT_BGL_MMOL_LIMITS)) {
|
|
156
|
+
throw CurrentBGLError();
|
|
181
157
|
}
|
|
182
158
|
}
|
|
183
159
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
throw RecommendationError_1.TargetBGLError();
|
|
160
|
+
export function checkTargetBGL(targetBGL) {
|
|
161
|
+
if (!Utils.isInRange(targetBGL, TARGET_BGL_MMOL_LIMITS)) {
|
|
162
|
+
throw TargetBGLError();
|
|
188
163
|
}
|
|
189
164
|
}
|
|
190
|
-
|
|
191
|
-
function checkBloodKetoneLevel(currentBKL) {
|
|
165
|
+
export function checkBloodKetoneLevel(currentBKL) {
|
|
192
166
|
if (currentBKL !== null) {
|
|
193
|
-
if (!
|
|
194
|
-
throw
|
|
167
|
+
if (!Utils.isInRange(currentBKL, CURRENT_BKL_MMOL_LIMITS)) {
|
|
168
|
+
throw CurrentBKLError();
|
|
195
169
|
}
|
|
196
170
|
}
|
|
197
171
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
throw RecommendationError_1.InsulinSensitivityError();
|
|
172
|
+
export function checkInsulinSensitivity(insulinSensitivity) {
|
|
173
|
+
if (!Utils.isInRange(insulinSensitivity, INSULIN_SENSITIVITY_MMOL_LIMITS)) {
|
|
174
|
+
throw InsulinSensitivityError();
|
|
202
175
|
}
|
|
203
176
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
throw RecommendationError_1.InsulinToCarbsRatioError();
|
|
177
|
+
export function checkInsulinToCarbRatio(insulinToCarbRatio) {
|
|
178
|
+
if (!Utils.isInRange(insulinToCarbRatio, INSULIN_TO_CARBS_RATIO_LIMITS)) {
|
|
179
|
+
throw InsulinToCarbsRatioError();
|
|
208
180
|
}
|
|
209
181
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
throw RecommendationError_1.CarbohydrateLimitError();
|
|
182
|
+
export function checkCarbohydrates(carbohydrates) {
|
|
183
|
+
if (!Utils.isInRange(carbohydrates, CARBOHYDRATES_LIMTS)) {
|
|
184
|
+
throw CarbohydrateLimitError();
|
|
214
185
|
}
|
|
215
186
|
}
|
|
216
|
-
exports.checkCarbohydrates = checkCarbohydrates;
|