@dhis2/analytics 24.0.7 → 24.1.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/CHANGELOG.md CHANGED
@@ -1,3 +1,24 @@
1
+ # [24.1.0](https://github.com/dhis2/analytics/compare/v24.0.9...v24.1.0) (2022-09-12)
2
+
3
+
4
+ ### Features
5
+
6
+ * add renderId prop in AboutAO and Interpretation units ([#1337](https://github.com/dhis2/analytics/issues/1337)) ([91618c3](https://github.com/dhis2/analytics/commit/91618c35d56d33a080aea44169e48d71176ee739))
7
+
8
+ ## [24.0.9](https://github.com/dhis2/analytics/compare/v24.0.8...v24.0.9) (2022-09-08)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * enable onShare callback and allow refresh AboutAOUnit (DHIS2-13667) ([#1332](https://github.com/dhis2/analytics/issues/1332)) ([80c2819](https://github.com/dhis2/analytics/commit/80c2819c62773947d7a3a2c3daa643f563e75880))
14
+
15
+ ## [24.0.8](https://github.com/dhis2/analytics/compare/v24.0.7...v24.0.8) (2022-09-06)
16
+
17
+
18
+ ### Bug Fixes
19
+
20
+ * prevent empty values from displaying a legend color ([#1335](https://github.com/dhis2/analytics/issues/1335)) ([5b6567e](https://github.com/dhis2/analytics/commit/5b6567e75ea1d5252f314108998ff24f181f182b))
21
+
1
22
  ## [24.0.7](https://github.com/dhis2/analytics/compare/v24.0.6...v24.0.7) (2022-08-27)
2
23
 
3
24
 
package/README.md CHANGED
@@ -1,9 +1,25 @@
1
1
  # Analytics
2
2
 
3
- master: ![DHIS2: Test](https://github.com/dhis2/analytics/workflows/DHIS2:%20Test/badge.svg) ![DHIS2: Release](https://github.com/dhis2/analytics/workflows/DHIS2:%20Release/badge.svg)
3
+ **master**
4
+ [![Test](https://github.com/dhis2/analytics/actions/workflows/node-test.yml/badge.svg)](https://github.com/dhis2/analytics/actions/workflows/node-test.yml) [![DHIS2: Release](https://github.com/dhis2/analytics/actions/workflows/node-publish.yml/badge.svg)](https://github.com/dhis2/analytics/actions/workflows/node-publish.yml)
4
5
 
5
- 4.x:
6
- ![DHIS2: Test](https://github.com/dhis2/analytics/workflows/DHIS2:%20Test/badge.svg?branch=4.x) ![DHIS2: Release](https://github.com/dhis2/analytics/workflows/DHIS2:%20Release/badge.svg?branch=4.x)
6
+ **21.x**
7
+ [![Test](https://github.com/dhis2/analytics/actions/workflows/node-test.yml/badge.svg?branch=21.x)](https://github.com/dhis2/analytics/actions/workflows/node-test.yml) [![DHIS2: Release](https://github.com/dhis2/analytics/actions/workflows/node-publish.yml/badge.svg?branch=21.x)](https://github.com/dhis2/analytics/actions/workflows/node-publish.yml)
8
+
9
+ **20.x**
10
+ [![Test](https://github.com/dhis2/analytics/actions/workflows/node-test.yml/badge.svg?branch=20.x)](https://github.com/dhis2/analytics/actions/workflows/node-test.yml) [![DHIS2: Release](https://github.com/dhis2/analytics/actions/workflows/node-publish.yml/badge.svg?branch=20.x)](https://github.com/dhis2/analytics/actions/workflows/node-publish.yml)
11
+
12
+ **16.x**
13
+ [![Test](https://github.com/dhis2/analytics/actions/workflows/node-test.yml/badge.svg?branch=16.x)](https://github.com/dhis2/analytics/actions/workflows/node-test.yml) [![DHIS2: Release](https://github.com/dhis2/analytics/actions/workflows/node-publish.yml/badge.svg?branch=16.x)](https://github.com/dhis2/analytics/actions/workflows/node-publish.yml)
14
+
15
+ **11.0.x**
16
+ [![Test](https://github.com/dhis2/analytics/actions/workflows/node-test.yml/badge.svg?branch=11.0.x)](https://github.com/dhis2/analytics/actions/workflows/node-test.yml) [![DHIS2: Release](https://github.com/dhis2/analytics/actions/workflows/node-publish.yml/badge.svg?branch=11.0.x)](https://github.com/dhis2/analytics/actions/workflows/node-publish.yml)
17
+
18
+ **4.x**
19
+ [![Test](https://github.com/dhis2/analytics/actions/workflows/node-test.yml/badge.svg?branch=4.x)](https://github.com/dhis2/analytics/actions/workflows/node-test.yml) [![DHIS2: Release](https://github.com/dhis2/analytics/actions/workflows/node-publish.yml/badge.svg?branch=4.x)](https://github.com/dhis2/analytics/actions/workflows/node-publish.yml)
20
+
21
+ **2.4.x**
22
+ [![Test](https://github.com/dhis2/analytics/actions/workflows/node-test.yml/badge.svg?branch=2.4.x)](https://github.com/dhis2/analytics/actions/workflows/node-test.yml) [![DHIS2: Release](https://github.com/dhis2/analytics/actions/workflows/node-publish.yml/badge.svg?branch=2.4.x)](https://github.com/dhis2/analytics/actions/workflows/node-publish.yml)
7
23
 
8
24
  ## Overview
9
25
 
@@ -25,21 +41,9 @@ To publish, simply mark the commit using [semantic release terminology](https://
25
41
 
26
42
  The master branch follows semantic versioning according to spec.
27
43
 
28
- ### 16.x branch
29
-
30
- Commits to the 16.x branch cannot trigger a major version bump, even if it is technically a breaking change. This is because 17.0.0 has already been published. In the unlikely case that you need to commit a change that is considered breaking, you will have to mark it to only trigger a patch or minor bump, then make sure to update the apps that are locked to the 16.x version of analytics
31
-
32
- ### 11.0.x branch
33
-
34
- Commits to the 11.0.x branch cannot trigger a major or minor version bump, even if it is technically a breaking or feature change. This is because 11.1.0 and 12.0.0 have already been published. In the unlikely case that you need to commit a change that is considered breaking or feature, you will have to mark it to only trigger a patch bump, then make sure to update the apps that are locked to the 11.0.x version of analytics
35
-
36
- ### 4.x branch
37
-
38
- Commits to the 4.x branch cannot trigger a major version bump, even if it is technically a breaking change. This is because 5.0.0 has already been published. In the unlikely case that you need to commit a change that is considered breaking, you will have to mark it to only trigger a patch or minor bump, then make sure to update the apps that are locked to the 4.x version of analytics
39
-
40
- ### 2.4.x branch
44
+ ### .x branches
41
45
 
42
- Commits to the 2.4.x branch cannot trigger a major or minor version bump, even if it is technically a breaking or feature change. This is because 2.5.0 and 3.0.0 have already been published. In the unlikely case that you need to commit a change that is considered breaking or feature, you will have to mark it to only trigger a patch bump, then make sure to update the apps that are locked to the 2.4.x version of analytics
46
+ Commits to .x branches (e.g. 16.x) cannot trigger a major version bump, even if it is technically a breaking change. This is because the next version has already been published. Additionally, branches that use .x for the patch version (e.g. 11.0.x, 2.4.x), cannot trigger a minor version bump. In the unlikely case that you need to commit a change that would trigger a version bump that's not possible, you will have to mark it to only trigger a patch or minor bump respectively, then make sure to update the apps that are locked to the .x version of analytics
43
47
 
44
48
  ## Report an issue
45
49
 
@@ -70,12 +70,13 @@ const getUnsubscribeMutation = (type, id) => ({
70
70
  type: 'delete'
71
71
  });
72
72
 
73
- const AboutAOUnit = _ref3 => {
73
+ const AboutAOUnit = /*#__PURE__*/(0, _react.forwardRef)((_ref3, ref) => {
74
74
  var _data$ao$createdBy;
75
75
 
76
76
  let {
77
77
  type,
78
- id
78
+ id,
79
+ renderId
79
80
  } = _ref3;
80
81
  const [isExpanded, setIsExpanded] = (0, _react.useState)(true);
81
82
  const queries = (0, _react.useMemo)(() => getQueries(type), [type]);
@@ -116,7 +117,10 @@ const AboutAOUnit = _ref3 => {
116
117
  id
117
118
  });
118
119
  }
119
- }, [id, refetch]);
120
+ }, [id, renderId, refetch]);
121
+ (0, _react.useImperativeHandle)(ref, () => ({
122
+ refresh: refetch
123
+ }), [refetch]);
120
124
 
121
125
  const getAccessLevelString = access => {
122
126
  const re = new RegExp("(?<accessLevel>".concat(READ_AND_WRITE, "?)"));
@@ -233,11 +237,12 @@ const AboutAOUnit = _ref3 => {
233
237
  }, _d2I18n.default.t('Subscribe')))))), /*#__PURE__*/_react.default.createElement(_style.default, {
234
238
  id: _AboutAOUnitStyle.default.__hash
235
239
  }, _AboutAOUnitStyle.default));
236
- };
237
-
240
+ });
241
+ AboutAOUnit.displayName = 'AboutUnit';
238
242
  AboutAOUnit.propTypes = {
239
243
  id: _propTypes.default.string.isRequired,
240
- type: _propTypes.default.string.isRequired
244
+ type: _propTypes.default.string.isRequired,
245
+ renderId: _propTypes.default.number
241
246
  };
242
247
  var _default = AboutAOUnit;
243
248
  exports.default = _default;
@@ -51,7 +51,7 @@ const FileMenu = _ref => {
51
51
  onSave,
52
52
  onSaveAs,
53
53
  onRename,
54
- // onShare,
54
+ onShare,
55
55
  onDelete,
56
56
  onError,
57
57
  onTranslate
@@ -106,10 +106,10 @@ const FileMenu = _ref => {
106
106
 
107
107
  case 'sharing':
108
108
  return /*#__PURE__*/_react.default.createElement(_ui.SharingDialog, {
109
- open: true,
110
109
  type: fileType,
111
110
  id: fileObject.id,
112
- onClose: onDialogClose
111
+ onClose: onDialogClose,
112
+ onSave: onShare
113
113
  });
114
114
 
115
115
  case 'getlink':
@@ -265,6 +265,7 @@ FileMenu.defaultProps = {
265
265
  onOpen: Function.prototype,
266
266
  onRename: Function.prototype,
267
267
  onSaveAs: Function.prototype,
268
+ onShare: Function.prototype,
268
269
  onTranslate: Function.prototype
269
270
  };
270
271
  FileMenu.propTypes = {
@@ -280,7 +281,7 @@ FileMenu.propTypes = {
280
281
  onRename: _propTypes.default.func,
281
282
  onSave: _propTypes.default.func,
282
283
  onSaveAs: _propTypes.default.func,
283
- // onShare: PropTypes.func,
284
+ onShare: _propTypes.default.func,
284
285
  onTranslate: _propTypes.default.func
285
286
  };
286
287
  var _default = FileMenu;
@@ -51,7 +51,8 @@ const InterpretationsUnit = /*#__PURE__*/(0, _react.forwardRef)((_ref2, ref) =>
51
51
  id,
52
52
  onInterpretationClick,
53
53
  onReplyIconClick,
54
- disabled
54
+ disabled,
55
+ renderId
55
56
  } = _ref2;
56
57
  const [isExpanded, setIsExpanded] = (0, _react.useState)(true);
57
58
  const {
@@ -78,7 +79,7 @@ const InterpretationsUnit = /*#__PURE__*/(0, _react.forwardRef)((_ref2, ref) =>
78
79
  id
79
80
  });
80
81
  }
81
- }, [type, id, refetch]);
82
+ }, [type, id, renderId, refetch]);
82
83
  return /*#__PURE__*/_react.default.createElement("div", {
83
84
  className: _style.default.dynamic([["4120713286", [_ui.spacers.dp16, _ui.colors.grey400, _ui.colors.white, _ui.spacers.dp32, _ui.colors.grey900]]]) + " " + ((0, _classnames.default)('container', {
84
85
  expanded: isExpanded
@@ -128,6 +129,7 @@ InterpretationsUnit.propTypes = {
128
129
  id: _propTypes.default.string.isRequired,
129
130
  type: _propTypes.default.string.isRequired,
130
131
  disabled: _propTypes.default.bool,
132
+ renderId: _propTypes.default.number,
131
133
  onInterpretationClick: _propTypes.default.func,
132
134
  onReplyIconClick: _propTypes.default.func
133
135
  };
@@ -0,0 +1,162 @@
1
+ "use strict";
2
+
3
+ var _legends = require("../legends.js");
4
+
5
+ const positiveLegendSet = {
6
+ legends: [{
7
+ startValue: 65,
8
+ endValue: 75,
9
+ color: '#2171b5',
10
+ id: 'ZuBlFGK8U7D',
11
+ name: '65 - 74'
12
+ }, {
13
+ startValue: 35,
14
+ endValue: 45,
15
+ color: '#9ecae1',
16
+ id: 'XTmLeJHmd3m',
17
+ name: '35 - 44'
18
+ }, {
19
+ startValue: 75,
20
+ endValue: 85,
21
+ color: '#08519c',
22
+ id: 'VPEprgLdi1g',
23
+ name: '75 - 84'
24
+ }, {
25
+ startValue: 25,
26
+ endValue: 35,
27
+ color: '#c6dbef',
28
+ id: 'CqUnYcUy2eb',
29
+ name: '25 - 34'
30
+ }, {
31
+ startValue: 15,
32
+ endValue: 25,
33
+ color: '#deebf7',
34
+ id: 'evLlhbRsG6e',
35
+ name: '15 - 24'
36
+ }, {
37
+ startValue: 0,
38
+ endValue: 5,
39
+ color: '#FFFFFF',
40
+ id: 'GHcJ24t8oEs',
41
+ name: '0 - 4'
42
+ }, {
43
+ startValue: 85,
44
+ endValue: 150,
45
+ color: '#08306b',
46
+ id: 'dPFk7tcCg7U',
47
+ name: '85+'
48
+ }, {
49
+ startValue: 45,
50
+ endValue: 55,
51
+ color: '#6baed6',
52
+ id: 'uHBR7cbKoy3',
53
+ name: '45 - 54'
54
+ }, {
55
+ startValue: 5,
56
+ endValue: 15,
57
+ color: '#f7fbff',
58
+ id: 'RUD8IwOsXEW',
59
+ name: '5 - 14'
60
+ }, {
61
+ startValue: 55,
62
+ endValue: 65,
63
+ color: '#4292c6',
64
+ id: 'UojF9VGBvnE',
65
+ name: '55 - 64'
66
+ }],
67
+ name: 'Positive'
68
+ };
69
+ const negativeLegendSet = {
70
+ legends: [{
71
+ startValue: -48,
72
+ endValue: -36,
73
+ color: '#fecc5c',
74
+ id: 'TR60hS8mQag',
75
+ name: '-48 - -36'
76
+ }, {
77
+ startValue: -1000,
78
+ endValue: -60,
79
+ color: '#D10AFF',
80
+ id: 'nxCTJlHd9V2',
81
+ name: 'Critically low'
82
+ }, {
83
+ startValue: -24,
84
+ endValue: -12,
85
+ color: '#f03b20',
86
+ id: 'JOYfGUtyLJF',
87
+ name: '-24 - -12'
88
+ }, {
89
+ startValue: -60,
90
+ endValue: -48,
91
+ color: '#ffffb2',
92
+ id: 'JodoDUR31ig',
93
+ name: '-60 - -48'
94
+ }, {
95
+ startValue: -12,
96
+ endValue: 0,
97
+ color: '#bd0026',
98
+ id: 'rFFEKuATWaZ',
99
+ name: '-12 - 0'
100
+ }, {
101
+ startValue: 0,
102
+ endValue: 10000,
103
+ color: '#A3A3A3',
104
+ id: 'rOD16kf9YzA',
105
+ name: 'Out of bounds'
106
+ }, {
107
+ startValue: -36,
108
+ endValue: -24,
109
+ color: '#fd8d3c',
110
+ id: 'i682LxWmGQ6',
111
+ name: '-36 - -24'
112
+ }],
113
+ name: 'Negative'
114
+ };
115
+ const tests = [{
116
+ legendSet: positiveLegendSet,
117
+ value: 60,
118
+ expected: '#4292c6'
119
+ }, {
120
+ legendSet: positiveLegendSet,
121
+ value: '60.0',
122
+ expected: '#4292c6'
123
+ }, {
124
+ legendSet: positiveLegendSet,
125
+ value: 0,
126
+ expected: '#FFFFFF'
127
+ }, {
128
+ legendSet: positiveLegendSet,
129
+ value: '',
130
+ expected: null
131
+ }, {
132
+ legendSet: positiveLegendSet,
133
+ value: ' ',
134
+ expected: null
135
+ }, {
136
+ legendSet: positiveLegendSet,
137
+ value: 'ABC',
138
+ expected: null
139
+ }, {
140
+ legendSet: negativeLegendSet,
141
+ value: -50,
142
+ expected: '#ffffb2'
143
+ }, {
144
+ legendSet: negativeLegendSet,
145
+ value: '-50.0',
146
+ expected: '#ffffb2'
147
+ }, {
148
+ legendSet: negativeLegendSet,
149
+ value: 0,
150
+ expected: '#A3A3A3'
151
+ }, {
152
+ legendSet: negativeLegendSet,
153
+ value: '',
154
+ expected: null
155
+ }];
156
+ describe('getColorByValueFromLegendSet', () => {
157
+ tests.forEach(t => {
158
+ it("Legend set: ".concat(t.legendSet.name, ", value: ").concat(t.value, ", expected: ").concat(t.expected), () => {
159
+ expect((0, _legends.getColorByValueFromLegendSet)(t.legendSet, t.value)).toEqual(t.expected);
160
+ });
161
+ });
162
+ });
@@ -16,8 +16,8 @@ exports.LEGEND_DISPLAY_STYLE_TEXT = LEGEND_DISPLAY_STYLE_TEXT;
16
16
  const getLegendByValueFromLegendSet = (legendSet, value) => {
17
17
  var _legendSet$legends;
18
18
 
19
- return legendSet === null || legendSet === void 0 ? void 0 : (_legendSet$legends = legendSet.legends) === null || _legendSet$legends === void 0 ? void 0 : _legendSet$legends.find(legend => value >= legend.startValue && value < legend.endValue // TODO: Confirm inclusive/exclusive bounds
20
- );
19
+ return Number.isInteger(parseInt(value)) ? legendSet === null || legendSet === void 0 ? void 0 : (_legendSet$legends = legendSet.legends) === null || _legendSet$legends === void 0 ? void 0 : _legendSet$legends.find(legend => value >= legend.startValue && value < legend.endValue // TODO: Confirm inclusive/exclusive bounds
20
+ ) : null;
21
21
  };
22
22
 
23
23
  exports.getLegendByValueFromLegendSet = getLegendByValueFromLegendSet;
@@ -5,7 +5,7 @@ import { Button, CircularLoader, IconChevronDown24, IconChevronUp24, IconClock16
5
5
  import cx from 'classnames';
6
6
  import moment from 'moment';
7
7
  import PropTypes from 'prop-types';
8
- import React, { useEffect, useMemo, useState } from 'react';
8
+ import React, { useEffect, useMemo, useState, forwardRef, useImperativeHandle } from 'react';
9
9
  import { formatList } from '../../modules/list.js';
10
10
  import styles from './styles/AboutAOUnit.style.js';
11
11
  import { getTranslatedString, AOTypeMap } from './utils.js';
@@ -46,12 +46,13 @@ const getUnsubscribeMutation = (type, id) => ({
46
46
  type: 'delete'
47
47
  });
48
48
 
49
- const AboutAOUnit = _ref3 => {
49
+ const AboutAOUnit = /*#__PURE__*/forwardRef((_ref3, ref) => {
50
50
  var _data$ao$createdBy;
51
51
 
52
52
  let {
53
53
  type,
54
- id
54
+ id,
55
+ renderId
55
56
  } = _ref3;
56
57
  const [isExpanded, setIsExpanded] = useState(true);
57
58
  const queries = useMemo(() => getQueries(type), [type]);
@@ -92,7 +93,10 @@ const AboutAOUnit = _ref3 => {
92
93
  id
93
94
  });
94
95
  }
95
- }, [id, refetch]);
96
+ }, [id, renderId, refetch]);
97
+ useImperativeHandle(ref, () => ({
98
+ refresh: refetch
99
+ }), [refetch]);
96
100
 
97
101
  const getAccessLevelString = access => {
98
102
  const re = new RegExp("(?<accessLevel>".concat(READ_AND_WRITE, "?)"));
@@ -209,10 +213,11 @@ const AboutAOUnit = _ref3 => {
209
213
  }, i18n.t('Subscribe')))))), /*#__PURE__*/React.createElement(_JSXStyle, {
210
214
  id: styles.__hash
211
215
  }, styles));
212
- };
213
-
216
+ });
217
+ AboutAOUnit.displayName = 'AboutUnit';
214
218
  AboutAOUnit.propTypes = {
215
219
  id: PropTypes.string.isRequired,
216
- type: PropTypes.string.isRequired
220
+ type: PropTypes.string.isRequired,
221
+ renderId: PropTypes.number
217
222
  };
218
223
  export default AboutAOUnit;
@@ -25,7 +25,7 @@ export const FileMenu = _ref => {
25
25
  onSave,
26
26
  onSaveAs,
27
27
  onRename,
28
- // onShare,
28
+ onShare,
29
29
  onDelete,
30
30
  onError,
31
31
  onTranslate
@@ -80,10 +80,10 @@ export const FileMenu = _ref => {
80
80
 
81
81
  case 'sharing':
82
82
  return /*#__PURE__*/React.createElement(SharingDialog, {
83
- open: true,
84
83
  type: fileType,
85
84
  id: fileObject.id,
86
- onClose: onDialogClose
85
+ onClose: onDialogClose,
86
+ onSave: onShare
87
87
  });
88
88
 
89
89
  case 'getlink':
@@ -237,6 +237,7 @@ FileMenu.defaultProps = {
237
237
  onOpen: Function.prototype,
238
238
  onRename: Function.prototype,
239
239
  onSaveAs: Function.prototype,
240
+ onShare: Function.prototype,
240
241
  onTranslate: Function.prototype
241
242
  };
242
243
  FileMenu.propTypes = {
@@ -252,7 +253,7 @@ FileMenu.propTypes = {
252
253
  onRename: PropTypes.func,
253
254
  onSave: PropTypes.func,
254
255
  onSaveAs: PropTypes.func,
255
- // onShare: PropTypes.func,
256
+ onShare: PropTypes.func,
256
257
  onTranslate: PropTypes.func
257
258
  };
258
259
  export default FileMenu;
@@ -29,7 +29,8 @@ export const InterpretationsUnit = /*#__PURE__*/forwardRef((_ref2, ref) => {
29
29
  id,
30
30
  onInterpretationClick,
31
31
  onReplyIconClick,
32
- disabled
32
+ disabled,
33
+ renderId
33
34
  } = _ref2;
34
35
  const [isExpanded, setIsExpanded] = useState(true);
35
36
  const {
@@ -56,7 +57,7 @@ export const InterpretationsUnit = /*#__PURE__*/forwardRef((_ref2, ref) => {
56
57
  id
57
58
  });
58
59
  }
59
- }, [type, id, refetch]);
60
+ }, [type, id, renderId, refetch]);
60
61
  return /*#__PURE__*/React.createElement("div", {
61
62
  className: _JSXStyle.dynamic([["4120713286", [spacers.dp16, colors.grey400, colors.white, spacers.dp32, colors.grey900]]]) + " " + (cx('container', {
62
63
  expanded: isExpanded
@@ -105,6 +106,7 @@ InterpretationsUnit.propTypes = {
105
106
  id: PropTypes.string.isRequired,
106
107
  type: PropTypes.string.isRequired,
107
108
  disabled: PropTypes.bool,
109
+ renderId: PropTypes.number,
108
110
  onInterpretationClick: PropTypes.func,
109
111
  onReplyIconClick: PropTypes.func
110
112
  };
@@ -0,0 +1,159 @@
1
+ import { getColorByValueFromLegendSet } from '../legends.js';
2
+ const positiveLegendSet = {
3
+ legends: [{
4
+ startValue: 65,
5
+ endValue: 75,
6
+ color: '#2171b5',
7
+ id: 'ZuBlFGK8U7D',
8
+ name: '65 - 74'
9
+ }, {
10
+ startValue: 35,
11
+ endValue: 45,
12
+ color: '#9ecae1',
13
+ id: 'XTmLeJHmd3m',
14
+ name: '35 - 44'
15
+ }, {
16
+ startValue: 75,
17
+ endValue: 85,
18
+ color: '#08519c',
19
+ id: 'VPEprgLdi1g',
20
+ name: '75 - 84'
21
+ }, {
22
+ startValue: 25,
23
+ endValue: 35,
24
+ color: '#c6dbef',
25
+ id: 'CqUnYcUy2eb',
26
+ name: '25 - 34'
27
+ }, {
28
+ startValue: 15,
29
+ endValue: 25,
30
+ color: '#deebf7',
31
+ id: 'evLlhbRsG6e',
32
+ name: '15 - 24'
33
+ }, {
34
+ startValue: 0,
35
+ endValue: 5,
36
+ color: '#FFFFFF',
37
+ id: 'GHcJ24t8oEs',
38
+ name: '0 - 4'
39
+ }, {
40
+ startValue: 85,
41
+ endValue: 150,
42
+ color: '#08306b',
43
+ id: 'dPFk7tcCg7U',
44
+ name: '85+'
45
+ }, {
46
+ startValue: 45,
47
+ endValue: 55,
48
+ color: '#6baed6',
49
+ id: 'uHBR7cbKoy3',
50
+ name: '45 - 54'
51
+ }, {
52
+ startValue: 5,
53
+ endValue: 15,
54
+ color: '#f7fbff',
55
+ id: 'RUD8IwOsXEW',
56
+ name: '5 - 14'
57
+ }, {
58
+ startValue: 55,
59
+ endValue: 65,
60
+ color: '#4292c6',
61
+ id: 'UojF9VGBvnE',
62
+ name: '55 - 64'
63
+ }],
64
+ name: 'Positive'
65
+ };
66
+ const negativeLegendSet = {
67
+ legends: [{
68
+ startValue: -48,
69
+ endValue: -36,
70
+ color: '#fecc5c',
71
+ id: 'TR60hS8mQag',
72
+ name: '-48 - -36'
73
+ }, {
74
+ startValue: -1000,
75
+ endValue: -60,
76
+ color: '#D10AFF',
77
+ id: 'nxCTJlHd9V2',
78
+ name: 'Critically low'
79
+ }, {
80
+ startValue: -24,
81
+ endValue: -12,
82
+ color: '#f03b20',
83
+ id: 'JOYfGUtyLJF',
84
+ name: '-24 - -12'
85
+ }, {
86
+ startValue: -60,
87
+ endValue: -48,
88
+ color: '#ffffb2',
89
+ id: 'JodoDUR31ig',
90
+ name: '-60 - -48'
91
+ }, {
92
+ startValue: -12,
93
+ endValue: 0,
94
+ color: '#bd0026',
95
+ id: 'rFFEKuATWaZ',
96
+ name: '-12 - 0'
97
+ }, {
98
+ startValue: 0,
99
+ endValue: 10000,
100
+ color: '#A3A3A3',
101
+ id: 'rOD16kf9YzA',
102
+ name: 'Out of bounds'
103
+ }, {
104
+ startValue: -36,
105
+ endValue: -24,
106
+ color: '#fd8d3c',
107
+ id: 'i682LxWmGQ6',
108
+ name: '-36 - -24'
109
+ }],
110
+ name: 'Negative'
111
+ };
112
+ const tests = [{
113
+ legendSet: positiveLegendSet,
114
+ value: 60,
115
+ expected: '#4292c6'
116
+ }, {
117
+ legendSet: positiveLegendSet,
118
+ value: '60.0',
119
+ expected: '#4292c6'
120
+ }, {
121
+ legendSet: positiveLegendSet,
122
+ value: 0,
123
+ expected: '#FFFFFF'
124
+ }, {
125
+ legendSet: positiveLegendSet,
126
+ value: '',
127
+ expected: null
128
+ }, {
129
+ legendSet: positiveLegendSet,
130
+ value: ' ',
131
+ expected: null
132
+ }, {
133
+ legendSet: positiveLegendSet,
134
+ value: 'ABC',
135
+ expected: null
136
+ }, {
137
+ legendSet: negativeLegendSet,
138
+ value: -50,
139
+ expected: '#ffffb2'
140
+ }, {
141
+ legendSet: negativeLegendSet,
142
+ value: '-50.0',
143
+ expected: '#ffffb2'
144
+ }, {
145
+ legendSet: negativeLegendSet,
146
+ value: 0,
147
+ expected: '#A3A3A3'
148
+ }, {
149
+ legendSet: negativeLegendSet,
150
+ value: '',
151
+ expected: null
152
+ }];
153
+ describe('getColorByValueFromLegendSet', () => {
154
+ tests.forEach(t => {
155
+ it("Legend set: ".concat(t.legendSet.name, ", value: ").concat(t.value, ", expected: ").concat(t.expected), () => {
156
+ expect(getColorByValueFromLegendSet(t.legendSet, t.value)).toEqual(t.expected);
157
+ });
158
+ });
159
+ });
@@ -5,8 +5,8 @@ export const LEGEND_DISPLAY_STYLE_TEXT = 'TEXT';
5
5
  export const getLegendByValueFromLegendSet = (legendSet, value) => {
6
6
  var _legendSet$legends;
7
7
 
8
- return legendSet === null || legendSet === void 0 ? void 0 : (_legendSet$legends = legendSet.legends) === null || _legendSet$legends === void 0 ? void 0 : _legendSet$legends.find(legend => value >= legend.startValue && value < legend.endValue // TODO: Confirm inclusive/exclusive bounds
9
- );
8
+ return Number.isInteger(parseInt(value)) ? legendSet === null || legendSet === void 0 ? void 0 : (_legendSet$legends = legendSet.legends) === null || _legendSet$legends === void 0 ? void 0 : _legendSet$legends.find(legend => value >= legend.startValue && value < legend.endValue // TODO: Confirm inclusive/exclusive bounds
9
+ ) : null;
10
10
  };
11
11
  export const getColorByValueFromLegendSet = (legendSet, value) => {
12
12
  const legend = getLegendByValueFromLegendSet(legendSet, value);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dhis2/analytics",
3
- "version": "24.0.7",
3
+ "version": "24.1.0",
4
4
  "main": "./build/cjs/index.js",
5
5
  "module": "./build/es/index.js",
6
6
  "exports": {