@dhis2/analytics 26.4.0 → 26.5.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.
Files changed (79) hide show
  1. package/build/cjs/__fixtures__/fixtures.js +1 -0
  2. package/build/cjs/__fixtures__/json/api/analytics/outlierDetection.json +213 -0
  3. package/build/cjs/api/analytics/AnalyticsAggregate.js +27 -1
  4. package/build/cjs/api/analytics/AnalyticsBase.js +8 -7
  5. package/build/cjs/api/analytics/AnalyticsRequestBase.js +9 -5
  6. package/build/cjs/api/analytics/AnalyticsResponse.js +42 -39
  7. package/build/cjs/api/analytics/__tests__/Analytics.spec.js +5 -0
  8. package/build/cjs/api/analytics/__tests__/AnalyticsAggregate.spec.js +29 -0
  9. package/build/cjs/api/analytics/__tests__/AnalyticsBase.spec.js +36 -2
  10. package/build/cjs/components/DataDimension/DataDimension.js +31 -7
  11. package/build/cjs/components/DataDimension/DataTypeSelector.js +29 -8
  12. package/build/cjs/components/DataDimension/GroupSelector.js +7 -7
  13. package/build/cjs/components/DataDimension/ItemSelector.js +79 -61
  14. package/build/cjs/components/Interpretations/InterpretationModal/InterpretationModal.js +13 -4
  15. package/build/cjs/components/Interpretations/InterpretationModal/InterpretationThread.js +3 -0
  16. package/build/cjs/components/Interpretations/InterpretationsUnit/InterpretationList.js +3 -0
  17. package/build/cjs/components/Interpretations/InterpretationsUnit/InterpretationsUnit.js +15 -4
  18. package/build/cjs/components/Interpretations/common/Interpretation/Interpretation.js +7 -2
  19. package/build/cjs/components/Interpretations/common/Interpretation/useLike.js +12 -2
  20. package/build/cjs/components/PeriodDimension/PeriodDimension.js +5 -2
  21. package/build/cjs/components/PeriodDimension/PeriodTransfer.js +64 -31
  22. package/build/cjs/components/PeriodDimension/__tests__/__snapshots__/PeriodDimension.spec.js.snap +1 -1
  23. package/build/cjs/components/PeriodDimension/__tests__/__snapshots__/PeriodSelector.spec.js.snap +1 -12
  24. package/build/cjs/components/VisTypeIcon.js +6 -1
  25. package/build/cjs/index.js +43 -1
  26. package/build/cjs/locales/en/translations.json +5 -1
  27. package/build/cjs/modules/__tests__/getAdaptedUiLayoutByType.spec.js +15 -0
  28. package/build/cjs/modules/axis.js +4 -0
  29. package/build/cjs/modules/getAdaptedUiLayoutByType.js +9 -0
  30. package/build/cjs/modules/layoutTypes.js +4 -2
  31. package/build/cjs/modules/layoutUiRules/__tests__/rules.spec.js +13 -1
  32. package/build/cjs/modules/layoutUiRules/index.js +12 -0
  33. package/build/cjs/modules/layoutUiRules/rules.js +22 -2
  34. package/build/cjs/modules/layoutUiRules/rulesHelper.js +4 -2
  35. package/build/cjs/modules/layoutUiRules/rulesUtils.js +7 -2
  36. package/build/cjs/modules/visTypeToLayoutType.js +2 -1
  37. package/build/cjs/modules/visTypes.js +9 -3
  38. package/build/cjs/visualizations/config/adapters/dhis_highcharts/subtitle/index.js +3 -2
  39. package/build/cjs/visualizations/config/adapters/dhis_highcharts/title/index.js +3 -2
  40. package/build/es/__fixtures__/fixtures.js +1 -0
  41. package/build/es/__fixtures__/json/api/analytics/outlierDetection.json +213 -0
  42. package/build/es/api/analytics/AnalyticsAggregate.js +27 -1
  43. package/build/es/api/analytics/AnalyticsBase.js +7 -7
  44. package/build/es/api/analytics/AnalyticsRequestBase.js +9 -5
  45. package/build/es/api/analytics/AnalyticsResponse.js +42 -39
  46. package/build/es/api/analytics/__tests__/Analytics.spec.js +5 -0
  47. package/build/es/api/analytics/__tests__/AnalyticsAggregate.spec.js +29 -0
  48. package/build/es/api/analytics/__tests__/AnalyticsBase.spec.js +34 -1
  49. package/build/es/components/DataDimension/DataDimension.js +27 -6
  50. package/build/es/components/DataDimension/DataTypeSelector.js +30 -9
  51. package/build/es/components/DataDimension/GroupSelector.js +7 -7
  52. package/build/es/components/DataDimension/ItemSelector.js +80 -62
  53. package/build/es/components/Interpretations/InterpretationModal/InterpretationModal.js +13 -4
  54. package/build/es/components/Interpretations/InterpretationModal/InterpretationThread.js +3 -0
  55. package/build/es/components/Interpretations/InterpretationsUnit/InterpretationList.js +3 -0
  56. package/build/es/components/Interpretations/InterpretationsUnit/InterpretationsUnit.js +15 -4
  57. package/build/es/components/Interpretations/common/Interpretation/Interpretation.js +7 -2
  58. package/build/es/components/Interpretations/common/Interpretation/useLike.js +12 -2
  59. package/build/es/components/PeriodDimension/PeriodDimension.js +5 -2
  60. package/build/es/components/PeriodDimension/PeriodTransfer.js +65 -32
  61. package/build/es/components/PeriodDimension/__tests__/__snapshots__/PeriodDimension.spec.js.snap +1 -1
  62. package/build/es/components/PeriodDimension/__tests__/__snapshots__/PeriodSelector.spec.js.snap +1 -12
  63. package/build/es/components/VisTypeIcon.js +8 -3
  64. package/build/es/index.js +4 -4
  65. package/build/es/locales/en/translations.json +5 -1
  66. package/build/es/modules/__tests__/getAdaptedUiLayoutByType.spec.js +16 -1
  67. package/build/es/modules/axis.js +5 -1
  68. package/build/es/modules/getAdaptedUiLayoutByType.js +10 -1
  69. package/build/es/modules/layoutTypes.js +2 -1
  70. package/build/es/modules/layoutUiRules/__tests__/rules.spec.js +14 -2
  71. package/build/es/modules/layoutUiRules/index.js +2 -2
  72. package/build/es/modules/layoutUiRules/rules.js +22 -3
  73. package/build/es/modules/layoutUiRules/rulesHelper.js +3 -2
  74. package/build/es/modules/layoutUiRules/rulesUtils.js +6 -2
  75. package/build/es/modules/visTypeToLayoutType.js +4 -3
  76. package/build/es/modules/visTypes.js +7 -3
  77. package/build/es/visualizations/config/adapters/dhis_highcharts/subtitle/index.js +3 -2
  78. package/build/es/visualizations/config/adapters/dhis_highcharts/title/index.js +3 -2
  79. package/package.json +6 -3
@@ -1,20 +1,33 @@
1
1
  import { useConfig } from '@dhis2/app-runtime';
2
2
  import PropTypes from 'prop-types';
3
- import React from 'react';
3
+ import React, { createContext, useContext, useCallback, useEffect, useState } from 'react';
4
+ import { dataTypeMap, DIMENSION_TYPE_EXPRESSION_DIMENSION_ITEM } from '../../modules/dataTypes.js';
4
5
  import { DIMENSION_ID_DATA } from '../../modules/predefinedDimensions.js';
5
6
  import ItemSelector from './ItemSelector.js';
7
+ const DataDimensionCtx = /*#__PURE__*/createContext({});
6
8
  const DataDimension = _ref => {
7
9
  let {
8
10
  onSelect,
9
11
  selectedDimensions,
10
12
  displayNameProp,
13
+ enabledDataTypes,
11
14
  infoBoxMessage,
12
- onCalculationSave
15
+ onCalculationSave,
16
+ visType
13
17
  } = _ref;
14
18
  const {
15
19
  serverVersion
16
20
  } = useConfig();
17
- const supportsEDI = `${serverVersion.major}.${serverVersion.minor}.${serverVersion.patch || 0}` >= '2.40.0';
21
+ const filterDataTypesByVersion = useCallback(dataTypes => dataTypes.filter(_ref2 => {
22
+ let {
23
+ id
24
+ } = _ref2;
25
+ return (
26
+ // Calculations only available from 2.40
27
+ id !== DIMENSION_TYPE_EXPRESSION_DIMENSION_ITEM || serverVersion.minor >= 40
28
+ );
29
+ }), [serverVersion.minor]);
30
+ const [dataTypes, setDataTypes] = useState(filterDataTypesByVersion(enabledDataTypes || Object.values(dataTypeMap)));
18
31
  const onSelectItems = selectedItem => onSelect({
19
32
  dimensionId: DIMENSION_ID_DATA,
20
33
  items: selectedItem.map(item => ({
@@ -24,7 +37,12 @@ const DataDimension = _ref => {
24
37
  expression: item.expression
25
38
  }))
26
39
  });
27
- return /*#__PURE__*/React.createElement(ItemSelector, {
40
+ useEffect(() => enabledDataTypes && setDataTypes(filterDataTypesByVersion(enabledDataTypes)), [enabledDataTypes, filterDataTypesByVersion]);
41
+ return /*#__PURE__*/React.createElement(DataDimensionCtx.Provider, {
42
+ value: {
43
+ visType
44
+ }
45
+ }, /*#__PURE__*/React.createElement(ItemSelector, {
28
46
  selectedItems: selectedDimensions.map(item => ({
29
47
  value: item.id,
30
48
  label: item.name,
@@ -37,9 +55,9 @@ const DataDimension = _ref => {
37
55
  displayNameProp: displayNameProp,
38
56
  infoBoxMessage: infoBoxMessage,
39
57
  dataTest: 'data-dimension',
40
- supportsEDI: supportsEDI,
58
+ dataTypes: dataTypes,
41
59
  onEDISave: onCalculationSave
42
- });
60
+ }));
43
61
  };
44
62
  DataDimension.propTypes = {
45
63
  displayNameProp: PropTypes.string.isRequired,
@@ -51,11 +69,14 @@ DataDimension.propTypes = {
51
69
  type: PropTypes.string
52
70
  })).isRequired,
53
71
  onSelect: PropTypes.func.isRequired,
72
+ enabledDataTypes: PropTypes.array,
54
73
  infoBoxMessage: PropTypes.string,
74
+ visType: PropTypes.string,
55
75
  onCalculationSave: PropTypes.func
56
76
  };
57
77
  DataDimension.defaultProps = {
58
78
  selectedDimensions: [],
59
79
  onSelect: Function.prototype
60
80
  };
81
+ export const useDataDimensionContext = () => useContext(DataDimensionCtx);
61
82
  export default DataDimension;
@@ -3,22 +3,43 @@ import { SingleSelectField, SingleSelectOption } from '@dhis2/ui';
3
3
  import PropTypes from 'prop-types';
4
4
  import React from 'react';
5
5
  import i18n from '../../locales/index.js';
6
- import { DIMENSION_TYPE_ALL, dataTypeMap as dataTypes, DIMENSION_TYPE_EXPRESSION_DIMENSION_ITEM } from '../../modules/dataTypes.js';
6
+ import { DIMENSION_TYPE_ALL, dataTypeMap } from '../../modules/dataTypes.js';
7
+ import { getDisplayNameByVisType } from '../../modules/visTypes.js';
8
+ import { useDataDimensionContext } from './DataDimension.js';
7
9
  import styles from './styles/DataTypeSelector.style.js';
8
10
  const DataTypeSelector = _ref => {
9
- var _dataTypes$currentDat;
10
11
  let {
11
12
  currentDataType,
13
+ dataTypes,
12
14
  onChange,
13
- dataTest,
14
- includeCalculations
15
+ dataTest
15
16
  } = _ref;
17
+ const {
18
+ visType
19
+ } = useDataDimensionContext();
20
+ const label = i18n.t('Data Type');
16
21
  return /*#__PURE__*/React.createElement("div", {
17
22
  className: `jsx-${styles.__hash}` + " " + "container"
18
- }, /*#__PURE__*/React.createElement(SingleSelectField, {
19
- label: i18n.t('Data Type'),
23
+ }, dataTypes.length === 1 ? /*#__PURE__*/React.createElement(SingleSelectField, {
24
+ label: label,
20
25
  dataTest: dataTest,
21
- selected: ((_dataTypes$currentDat = dataTypes[currentDataType]) === null || _dataTypes$currentDat === void 0 ? void 0 : _dataTypes$currentDat.id) || DIMENSION_TYPE_ALL,
26
+ selected: dataTypes[0].id,
27
+ onChange: ref => onChange(ref.selected),
28
+ dense: true,
29
+ disabled: true,
30
+ helpText: visType ? i18n.t('Only {{dataType}} can be used in {{visType}}', {
31
+ dataType: dataTypeMap[dataTypes[0].id].getName(),
32
+ visType: getDisplayNameByVisType(visType)
33
+ }) : ''
34
+ }, dataTypes.map(type => /*#__PURE__*/React.createElement(SingleSelectOption, {
35
+ value: type.id,
36
+ key: type.id,
37
+ label: type.getName(),
38
+ dataTest: `${dataTest}-option-${type.id}`
39
+ }))) : /*#__PURE__*/React.createElement(SingleSelectField, {
40
+ label: label,
41
+ dataTest: dataTest,
42
+ selected: currentDataType || DIMENSION_TYPE_ALL,
22
43
  onChange: ref => onChange(ref.selected),
23
44
  dense: true
24
45
  }, /*#__PURE__*/React.createElement(SingleSelectOption, {
@@ -26,7 +47,7 @@ const DataTypeSelector = _ref => {
26
47
  key: DIMENSION_TYPE_ALL,
27
48
  label: i18n.t('All types'),
28
49
  dataTest: `${dataTest}-option-all`
29
- }), Object.values(dataTypes).filter(type => type.id !== DIMENSION_TYPE_EXPRESSION_DIMENSION_ITEM || includeCalculations).map(type => /*#__PURE__*/React.createElement(SingleSelectOption, {
50
+ }), dataTypes.map(type => /*#__PURE__*/React.createElement(SingleSelectOption, {
30
51
  value: type.id,
31
52
  key: type.id,
32
53
  label: type.getName(),
@@ -39,6 +60,6 @@ DataTypeSelector.propTypes = {
39
60
  currentDataType: PropTypes.string.isRequired,
40
61
  onChange: PropTypes.func.isRequired,
41
62
  dataTest: PropTypes.string,
42
- includeCalculations: PropTypes.bool
63
+ dataTypes: PropTypes.array
43
64
  };
44
65
  export default DataTypeSelector;
@@ -25,15 +25,15 @@ const GroupSelector = _ref => {
25
25
  const [isLoading, setIsLoading] = useState(true);
26
26
  const defaultGroup = (_dataTypes$dataType = dataTypes[dataType]) === null || _dataTypes$dataType === void 0 ? void 0 : _dataTypes$dataType.defaultGroup;
27
27
  const subGroupType = (_dataTypes$dataType2 = dataTypes[dataType]) === null || _dataTypes$dataType2 === void 0 ? void 0 : _dataTypes$dataType2.subGroup;
28
- const fetchGroups = async () => {
29
- setIsLoading(true);
30
- const result = await apiFetchGroups(dataEngine, dataType, displayNameProp);
31
- setGroups(result);
32
- setIsLoading(false);
33
- };
34
28
  useEffect(() => {
29
+ const fetchGroups = async () => {
30
+ setIsLoading(true);
31
+ const result = await apiFetchGroups(dataEngine, dataType, displayNameProp);
32
+ setGroups(result);
33
+ setIsLoading(false);
34
+ };
35
35
  fetchGroups();
36
- }, [dataType]);
36
+ }, [dataEngine, dataType, displayNameProp]);
37
37
  return /*#__PURE__*/React.createElement("div", {
38
38
  className: `jsx-${styles.__hash}` + " " + "container"
39
39
  }, /*#__PURE__*/React.createElement(_JSXStyle, {
@@ -7,7 +7,7 @@ import React, { useState } from 'react';
7
7
  import { apiFetchOptions } from '../../api/dimensions.js';
8
8
  import i18n from '../../locales/index.js';
9
9
  import { DATA_SETS_CONSTANTS, REPORTING_RATE } from '../../modules/dataSets.js';
10
- import { dataTypeMap as dataTypes, DIMENSION_TYPE_ALL, DIMENSION_TYPE_DATA_ELEMENT, DIMENSION_TYPE_DATA_SET, DIMENSION_TYPE_EVENT_DATA_ITEM, DIMENSION_TYPE_PROGRAM_INDICATOR, DIMENSION_TYPE_INDICATOR, TOTALS, DIMENSION_TYPE_EXPRESSION_DIMENSION_ITEM } from '../../modules/dataTypes.js';
10
+ import { DIMENSION_TYPE_ALL, DIMENSION_TYPE_DATA_ELEMENT, DIMENSION_TYPE_DATA_SET, DIMENSION_TYPE_EVENT_DATA_ITEM, DIMENSION_TYPE_PROGRAM_INDICATOR, DIMENSION_TYPE_INDICATOR, TOTALS, DIMENSION_TYPE_EXPRESSION_DIMENSION_ITEM } from '../../modules/dataTypes.js';
11
11
  import { getIcon, getTooltipText } from '../../modules/dimensionListItem.js';
12
12
  import { TRANSFER_HEIGHT, TRANSFER_OPTIONS_WIDTH, TRANSFER_SELECTED_WIDTH } from '../../modules/dimensionSelectorHelper.js';
13
13
  import { useDebounce, useDidUpdateEffect } from '../../modules/utils.js';
@@ -21,14 +21,14 @@ const LeftHeader = _ref => {
21
21
  searchTerm,
22
22
  setSearchTerm,
23
23
  dataType,
24
+ dataTypes,
24
25
  setDataType,
25
26
  group,
26
27
  setGroup,
27
28
  subGroup,
28
29
  setSubGroup,
29
30
  displayNameProp,
30
- dataTest,
31
- supportsEDI
31
+ dataTest
32
32
  } = _ref;
33
33
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
34
34
  className: `jsx-${styles.__hash}` + " " + "leftHeader"
@@ -49,8 +49,8 @@ const LeftHeader = _ref => {
49
49
  currentDataType: dataType,
50
50
  onChange: setDataType,
51
51
  dataTest: `${dataTest}-data-types-select-field`,
52
- includeCalculations: supportsEDI
53
- }), dataTypes[dataType] && dataType !== DIMENSION_TYPE_EXPRESSION_DIMENSION_ITEM && /*#__PURE__*/React.createElement(GroupSelector, {
52
+ dataTypes: dataTypes
53
+ }), ![DIMENSION_TYPE_EXPRESSION_DIMENSION_ITEM, DIMENSION_TYPE_ALL].includes(dataType) && /*#__PURE__*/React.createElement(GroupSelector, {
54
54
  dataType: dataType,
55
55
  displayNameProp: displayNameProp,
56
56
  currentGroup: group,
@@ -65,6 +65,7 @@ const LeftHeader = _ref => {
65
65
  LeftHeader.propTypes = {
66
66
  dataTest: PropTypes.string,
67
67
  dataType: PropTypes.string,
68
+ dataTypes: PropTypes.array,
68
69
  displayNameProp: PropTypes.string,
69
70
  group: PropTypes.string,
70
71
  searchTerm: PropTypes.string,
@@ -72,8 +73,7 @@ LeftHeader.propTypes = {
72
73
  setGroup: PropTypes.func,
73
74
  setSearchTerm: PropTypes.func,
74
75
  setSubGroup: PropTypes.func,
75
- subGroup: PropTypes.string,
76
- supportsEDI: PropTypes.bool
76
+ subGroup: PropTypes.string
77
77
  };
78
78
  const EmptySelection = () => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("p", {
79
79
  className: `jsx-${styles.__hash}` + " " + "emptyList"
@@ -82,22 +82,22 @@ const EmptySelection = () => /*#__PURE__*/React.createElement(React.Fragment, nu
82
82
  }, styles));
83
83
  const RightHeader = _ref3 => {
84
84
  let {
85
- infoText
85
+ infoBoxMessage
86
86
  } = _ref3;
87
87
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("p", {
88
88
  className: `jsx-${styles.__hash}` + " " + "rightHeader"
89
- }, i18n.t('Selected Items')), infoText && /*#__PURE__*/React.createElement("div", {
89
+ }, i18n.t('Selected Items')), infoBoxMessage && /*#__PURE__*/React.createElement("div", {
90
90
  className: `jsx-${styles.__hash}` + " " + "info-container"
91
91
  }, /*#__PURE__*/React.createElement("div", {
92
92
  className: `jsx-${styles.__hash}`
93
93
  }, /*#__PURE__*/React.createElement(IconInfo16, null)), /*#__PURE__*/React.createElement("span", {
94
94
  className: `jsx-${styles.__hash}` + " " + "info-text"
95
- }, infoText)), /*#__PURE__*/React.createElement(_JSXStyle, {
95
+ }, infoBoxMessage)), /*#__PURE__*/React.createElement(_JSXStyle, {
96
96
  id: styles.__hash
97
97
  }, styles));
98
98
  };
99
99
  RightHeader.propTypes = {
100
- infoText: PropTypes.string
100
+ infoBoxMessage: PropTypes.string
101
101
  };
102
102
  const SourceEmptyPlaceholder = _ref4 => {
103
103
  let {
@@ -129,6 +129,9 @@ const SourceEmptyPlaceholder = _ref4 => {
129
129
  case DIMENSION_TYPE_PROGRAM_INDICATOR:
130
130
  message = i18n.t('No program indicators found');
131
131
  break;
132
+ case DIMENSION_TYPE_EXPRESSION_DIMENSION_ITEM:
133
+ message = i18n.t('No calculations found');
134
+ break;
132
135
  default:
133
136
  message = i18n.t('No data');
134
137
  break;
@@ -138,32 +141,37 @@ const SourceEmptyPlaceholder = _ref4 => {
138
141
  switch (dataType) {
139
142
  case DIMENSION_TYPE_INDICATOR:
140
143
  message = i18n.t('No indicators found for "{{- searchTerm}}"', {
141
- searchTerm: searchTerm
144
+ searchTerm
142
145
  });
143
146
  break;
144
147
  case DIMENSION_TYPE_DATA_ELEMENT:
145
148
  message = i18n.t('No data elements found for "{{- searchTerm}}"', {
146
- searchTerm: searchTerm
149
+ searchTerm
147
150
  });
148
151
  break;
149
152
  case DIMENSION_TYPE_DATA_SET:
150
153
  message = i18n.t('No data sets found for "{{- searchTerm}}"', {
151
- searchTerm: searchTerm
154
+ searchTerm
152
155
  });
153
156
  break;
154
157
  case DIMENSION_TYPE_EVENT_DATA_ITEM:
155
158
  message = i18n.t('No event data items found for "{{- searchTerm}}"', {
156
- searchTerm: searchTerm
159
+ searchTerm
157
160
  });
158
161
  break;
159
162
  case DIMENSION_TYPE_PROGRAM_INDICATOR:
160
163
  message = i18n.t('No program indicators found for "{{- searchTerm}}"', {
161
- searchTerm: searchTerm
164
+ searchTerm
165
+ });
166
+ break;
167
+ case DIMENSION_TYPE_EXPRESSION_DIMENSION_ITEM:
168
+ message = i18n.t('No calculations found for "{{- searchTerm}}"', {
169
+ searchTerm
162
170
  });
163
171
  break;
164
172
  default:
165
173
  message = i18n.t('Nothing found for "{{- searchTerm}}"', {
166
- searchTerm: searchTerm
174
+ searchTerm
167
175
  });
168
176
  break;
169
177
  }
@@ -191,18 +199,27 @@ const ItemSelector = _ref5 => {
191
199
  rightFooter,
192
200
  displayNameProp,
193
201
  infoBoxMessage,
202
+ dataTypes,
194
203
  dataTest,
195
- supportsEDI,
196
204
  onEDISave
197
205
  } = _ref5;
198
206
  const [state, setState] = useState({
199
207
  searchTerm: '',
208
+ dataTypes,
200
209
  filter: {
201
- dataType: DIMENSION_TYPE_ALL
210
+ dataType: dataTypes.length === 1 ? dataTypes[0].id : DIMENSION_TYPE_ALL,
211
+ group: null,
212
+ subGroup: dataTypes.length === 1 && dataTypes[0].id === DIMENSION_TYPE_DATA_ELEMENT ? TOTALS : null
202
213
  },
203
214
  options: [],
204
215
  loading: true,
205
- nextPage: 1
216
+ nextPage: 1,
217
+ supportsEDI: dataTypes.map(_ref6 => {
218
+ let {
219
+ id
220
+ } = _ref6;
221
+ return id;
222
+ }).includes(DIMENSION_TYPE_EXPRESSION_DIMENSION_ITEM)
206
223
  });
207
224
  const [currentCalculation, setCurrentCalculation] = useState();
208
225
  const dataEngine = useDataEngine();
@@ -210,15 +227,12 @@ const ItemSelector = _ref5 => {
210
227
  ...state,
211
228
  searchTerm
212
229
  }));
213
- const setFilter = filter => setState(state => ({
214
- ...state,
215
- filter
216
- }));
217
230
  const debouncedSearchTerm = useDebounce(state.searchTerm, 500);
218
231
  const fetchItems = async page => {
219
232
  var _result$dimensionItem;
220
233
  setState(state => ({
221
234
  ...state,
235
+ nextPage: page === 1 ? 1 : state.nextPage,
222
236
  loading: true
223
237
  }));
224
238
  const result = await apiFetchOptions({
@@ -281,11 +295,6 @@ const ItemSelector = _ref5 => {
281
295
  }
282
296
  };
283
297
  useDidUpdateEffect(() => {
284
- setState(state => ({
285
- ...state,
286
- loading: true,
287
- nextPage: 1
288
- }));
289
298
  fetchItems(1);
290
299
  }, [debouncedSearchTerm, state.filter]);
291
300
  const onChange = newSelected => {
@@ -314,13 +323,13 @@ const ItemSelector = _ref5 => {
314
323
  var _find;
315
324
  return (_find = [...state.options, ...selectedItems].find(item => item.value === value)) === null || _find === void 0 ? void 0 : _find.type;
316
325
  };
317
- const onSaveCalculation = async _ref6 => {
326
+ const onSaveCalculation = async _ref7 => {
318
327
  let {
319
328
  id,
320
329
  name,
321
330
  expression,
322
331
  isNew
323
- } = _ref6;
332
+ } = _ref7;
324
333
  onEDISave({
325
334
  id,
326
335
  name,
@@ -343,10 +352,10 @@ const ItemSelector = _ref5 => {
343
352
  }]);
344
353
  }
345
354
  };
346
- const onDeleteCalculation = _ref7 => {
355
+ const onDeleteCalculation = _ref8 => {
347
356
  let {
348
357
  id
349
- } = _ref7;
358
+ } = _ref8;
350
359
  // close the modal
351
360
  setCurrentCalculation();
352
361
 
@@ -356,11 +365,37 @@ const ItemSelector = _ref5 => {
356
365
  // unselect the deleted calculation
357
366
  onSelect([...selectedItems.filter(item => item.value !== id)]);
358
367
  };
368
+ const onSetGroup = group => setState(state => ({
369
+ ...state,
370
+ nextPage: 1,
371
+ filter: {
372
+ ...state.filter,
373
+ group
374
+ }
375
+ }));
376
+ const onSetSubGroup = subGroup => setState(state => ({
377
+ ...state,
378
+ nextPage: 1,
379
+ filter: {
380
+ ...state.filter,
381
+ subGroup
382
+ }
383
+ }));
384
+ const onSetDataType = dataType => setState(state => ({
385
+ ...state,
386
+ nextPage: 1,
387
+ filter: {
388
+ ...state.filter,
389
+ dataType,
390
+ group: null,
391
+ subGroup: dataType === DIMENSION_TYPE_DATA_ELEMENT ? TOTALS : null
392
+ }
393
+ }));
359
394
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Transfer, {
360
- onChange: _ref8 => {
395
+ onChange: _ref9 => {
361
396
  let {
362
397
  selected
363
- } = _ref8;
398
+ } = _ref9;
364
399
  return onChange(selected);
365
400
  },
366
401
  selected: selectedItems.map(item => item.value),
@@ -377,36 +412,19 @@ const ItemSelector = _ref5 => {
377
412
  }),
378
413
  onEndReached: onEndReached,
379
414
  leftHeader: /*#__PURE__*/React.createElement(LeftHeader, {
415
+ dataTypes: state.dataTypes,
380
416
  dataType: state.filter.dataType,
381
- setDataType: dataType => {
382
- setFilter({
383
- ...state.filter,
384
- dataType,
385
- group: null,
386
- subGroup: dataType === DIMENSION_TYPE_DATA_ELEMENT ? TOTALS : null
387
- });
388
- },
417
+ setDataType: onSetDataType,
389
418
  group: state.filter.group,
390
- setGroup: group => {
391
- setFilter({
392
- ...state.filter,
393
- group
394
- });
395
- },
419
+ setGroup: onSetGroup,
396
420
  subGroup: state.filter.subGroup,
397
- setSubGroup: subGroup => {
398
- setFilter({
399
- ...state.filter,
400
- subGroup
401
- });
402
- },
421
+ setSubGroup: onSetSubGroup,
403
422
  searchTerm: state.searchTerm,
404
423
  setSearchTerm: setSearchTerm,
405
424
  displayNameProp: displayNameProp,
406
- dataTest: `${dataTest}-left-header`,
407
- supportsEDI: supportsEDI
425
+ dataTest: `${dataTest}-left-header`
408
426
  }),
409
- leftFooter: supportsEDI ? /*#__PURE__*/React.createElement("div", {
427
+ leftFooter: state.supportsEDI ? /*#__PURE__*/React.createElement("div", {
410
428
  className: `jsx-${styles.__hash}` + " " + "calculation-button"
411
429
  }, /*#__PURE__*/React.createElement(Button, {
412
430
  icon: /*#__PURE__*/React.createElement(IconAdd24, null),
@@ -419,7 +437,7 @@ const ItemSelector = _ref5 => {
419
437
  selectedWidth: TRANSFER_SELECTED_WIDTH,
420
438
  selectedEmptyComponent: /*#__PURE__*/React.createElement(EmptySelection, null),
421
439
  rightHeader: /*#__PURE__*/React.createElement(RightHeader, {
422
- infoText: infoBoxMessage
440
+ infoBoxMessage: infoBoxMessage
423
441
  }),
424
442
  rightFooter: rightFooter,
425
443
  renderOption: props => {
@@ -433,7 +451,7 @@ const ItemSelector = _ref5 => {
433
451
  expression: props.expression
434
452
  }),
435
453
  dataTest: `${dataTest}-transfer-option`,
436
- onEditClick: getItemType(props.value) === DIMENSION_TYPE_EXPRESSION_DIMENSION_ITEM && !(((_props$access = props.access) === null || _props$access === void 0 ? void 0 : _props$access.write) === false) && supportsEDI ? () => setCurrentCalculation({
454
+ onEditClick: getItemType(props.value) === DIMENSION_TYPE_EXPRESSION_DIMENSION_ITEM && !(((_props$access = props.access) === null || _props$access === void 0 ? void 0 : _props$access.write) === false) && state.supportsEDI ? () => setCurrentCalculation({
437
455
  id: props.value,
438
456
  name: props.label,
439
457
  expression: props.expression
@@ -443,7 +461,7 @@ const ItemSelector = _ref5 => {
443
461
  },
444
462
 
445
463
  dataTest: `${dataTest}-transfer`
446
- }), currentCalculation && supportsEDI && /*#__PURE__*/React.createElement(CalculationModal, {
464
+ }), currentCalculation && state.supportsEDI && /*#__PURE__*/React.createElement(CalculationModal, {
447
465
  calculation: currentCalculation,
448
466
  onSave: onSaveCalculation,
449
467
  onClose: () => setCurrentCalculation(),
@@ -457,6 +475,7 @@ ItemSelector.propTypes = {
457
475
  displayNameProp: PropTypes.string.isRequired,
458
476
  onSelect: PropTypes.func.isRequired,
459
477
  dataTest: PropTypes.string,
478
+ dataTypes: PropTypes.array,
460
479
  infoBoxMessage: PropTypes.string,
461
480
  noItemsMessage: PropTypes.string,
462
481
  rightFooter: PropTypes.node,
@@ -467,7 +486,6 @@ ItemSelector.propTypes = {
467
486
  type: PropTypes.string,
468
487
  expression: PropTypes.string
469
488
  })),
470
- supportsEDI: PropTypes.bool,
471
489
  onEDISave: PropTypes.func
472
490
  };
473
491
  ItemSelector.defaultProps = {
@@ -64,7 +64,7 @@ const InterpretationModal = _ref2 => {
64
64
  });
65
65
  const interpretation = data === null || data === void 0 ? void 0 : data.interpretation;
66
66
  const shouldRenderModalContent = !error && interpretation;
67
- const shouldCssHideModal = loading || isVisualizationLoading;
67
+ const loadingInProgress = loading || isVisualizationLoading;
68
68
  const handleClose = () => {
69
69
  if (isDirty) {
70
70
  onInterpretationUpdate();
@@ -80,6 +80,14 @@ const InterpretationModal = _ref2 => {
80
80
  id: interpretationId
81
81
  });
82
82
  };
83
+ const onLikeToggled = _ref3 => {
84
+ let {
85
+ likedBy
86
+ } = _ref3;
87
+ setIsDirty(true);
88
+ interpretation.likedBy = likedBy;
89
+ interpretation.likes = likedBy.length;
90
+ };
83
91
  const onInterpretationDeleted = () => {
84
92
  setIsDirty(false);
85
93
  onInterpretationUpdate();
@@ -92,11 +100,11 @@ const InterpretationModal = _ref2 => {
92
100
  });
93
101
  }
94
102
  }, [interpretationId, refetch]);
95
- return /*#__PURE__*/React.createElement(React.Fragment, null, shouldCssHideModal && /*#__PURE__*/React.createElement(Layer, null, /*#__PURE__*/React.createElement(CenteredContent, null, /*#__PURE__*/React.createElement(CircularLoader, null))), /*#__PURE__*/React.createElement(Modal, {
103
+ return /*#__PURE__*/React.createElement(React.Fragment, null, loadingInProgress && /*#__PURE__*/React.createElement(Layer, null, /*#__PURE__*/React.createElement(CenteredContent, null, /*#__PURE__*/React.createElement(CircularLoader, null))), /*#__PURE__*/React.createElement(Modal, {
96
104
  fluid: true,
97
105
  onClose: handleClose,
98
106
  className: cx(modalCSS.className, {
99
- hidden: shouldCssHideModal
107
+ hidden: loadingInProgress
100
108
  }),
101
109
  dataTest: "interpretation-modal"
102
110
  }, /*#__PURE__*/React.createElement("h1", {
@@ -134,7 +142,8 @@ const InterpretationModal = _ref2 => {
134
142
  onInterpretationDeleted: onInterpretationDeleted,
135
143
  onThreadUpdated: onThreadUpdated,
136
144
  initialFocus: initialFocus,
137
- downloadMenuComponent: downloadMenuComponent
145
+ downloadMenuComponent: downloadMenuComponent,
146
+ onLikeToggled: onLikeToggled
138
147
  }))))), /*#__PURE__*/React.createElement(ModalActions, null, /*#__PURE__*/React.createElement(Button, {
139
148
  disabled: fetching,
140
149
  onClick: handleClose
@@ -14,6 +14,7 @@ const InterpretationThread = _ref => {
14
14
  fetching,
15
15
  interpretation,
16
16
  onInterpretationDeleted,
17
+ onLikeToggled,
17
18
  initialFocus,
18
19
  onThreadUpdated,
19
20
  downloadMenuComponent: DownloadMenu,
@@ -48,6 +49,7 @@ const InterpretationThread = _ref => {
48
49
  }, /*#__PURE__*/React.createElement(Interpretation, {
49
50
  currentUser: currentUser,
50
51
  interpretation: interpretation,
52
+ onLikeToggled: onLikeToggled,
51
53
  onReplyIconClick: interpretationAccess.comment ? () => {
52
54
  var _focusRef$current;
53
55
  return (_focusRef$current = focusRef.current) === null || _focusRef$current === void 0 ? void 0 : _focusRef$current.focus();
@@ -79,6 +81,7 @@ InterpretationThread.propTypes = {
79
81
  fetching: PropTypes.bool.isRequired,
80
82
  interpretation: PropTypes.object.isRequired,
81
83
  onInterpretationDeleted: PropTypes.func.isRequired,
84
+ onLikeToggled: PropTypes.func.isRequired,
82
85
  dashboardRedirectUrl: PropTypes.string,
83
86
  downloadMenuComponent: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
84
87
  initialFocus: PropTypes.bool,
@@ -21,6 +21,7 @@ export const InterpretationList = _ref => {
21
21
  currentUser,
22
22
  interpretations,
23
23
  onInterpretationClick,
24
+ onLikeToggled,
24
25
  onReplyIconClick,
25
26
  refresh,
26
27
  disabled,
@@ -58,6 +59,7 @@ export const InterpretationList = _ref => {
58
59
  interpretation: interpretation,
59
60
  currentUser: currentUser,
60
61
  onClick: onInterpretationClick,
62
+ onLikeToggled: onLikeToggled,
61
63
  onReplyIconClick: onReplyIconClick,
62
64
  onDeleted: refresh,
63
65
  onUpdated: refresh,
@@ -73,6 +75,7 @@ InterpretationList.propTypes = {
73
75
  interpretations: PropTypes.array.isRequired,
74
76
  refresh: PropTypes.func.isRequired,
75
77
  onInterpretationClick: PropTypes.func.isRequired,
78
+ onLikeToggled: PropTypes.func.isRequired,
76
79
  onReplyIconClick: PropTypes.func.isRequired,
77
80
  dashboardRedirectUrl: PropTypes.string,
78
81
  disabled: PropTypes.bool
@@ -35,14 +35,15 @@ export const InterpretationsUnit = /*#__PURE__*/forwardRef((_ref2, ref) => {
35
35
  dashboardRedirectUrl
36
36
  } = _ref2;
37
37
  const [isExpanded, setIsExpanded] = useState(true);
38
+ const [interpretations, setInterpretations] = useState([]);
38
39
  const showNoTimeDimensionHelpText = type === 'eventVisualization' && !visualizationHasTimeDimension;
39
40
  const {
40
- data,
41
41
  loading,
42
42
  fetching,
43
43
  refetch
44
44
  } = useDataQuery(interpretationsQuery, {
45
- lazy: true
45
+ lazy: true,
46
+ onComplete: data => setInterpretations(data.interpretations.interpretations)
46
47
  });
47
48
  const onCompleteAction = useCallback(() => {
48
49
  refetch({
@@ -61,6 +62,15 @@ export const InterpretationsUnit = /*#__PURE__*/forwardRef((_ref2, ref) => {
61
62
  });
62
63
  }
63
64
  }, [type, id, renderId, refetch]);
65
+ const onLikeToggled = _ref3 => {
66
+ let {
67
+ id,
68
+ likedBy
69
+ } = _ref3;
70
+ const interpretation = interpretations.find(interp => interp.id === id);
71
+ interpretation.likedBy = likedBy;
72
+ interpretation.likes = likedBy.length;
73
+ };
64
74
  return /*#__PURE__*/React.createElement("div", {
65
75
  className: _JSXStyle.dynamic([["4120713286", [spacers.dp16, colors.grey400, colors.white, spacers.dp32, colors.grey900]]]) + " " + (cx('container', {
66
76
  expanded: isExpanded
@@ -82,7 +92,7 @@ export const InterpretationsUnit = /*#__PURE__*/forwardRef((_ref2, ref) => {
82
92
  className: _JSXStyle.dynamic([["4120713286", [spacers.dp16, colors.grey400, colors.white, spacers.dp32, colors.grey900]]]) + " " + "loader"
83
93
  }, /*#__PURE__*/React.createElement(CircularLoader, {
84
94
  small: true
85
- })), data && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(InterpretationForm, {
95
+ })), interpretations && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(InterpretationForm, {
86
96
  currentUser: currentUser,
87
97
  type: type,
88
98
  id: id,
@@ -91,8 +101,9 @@ export const InterpretationsUnit = /*#__PURE__*/forwardRef((_ref2, ref) => {
91
101
  showNoTimeDimensionHelpText: showNoTimeDimensionHelpText
92
102
  }), /*#__PURE__*/React.createElement(InterpretationList, {
93
103
  currentUser: currentUser,
94
- interpretations: data.interpretations.interpretations,
104
+ interpretations: interpretations,
95
105
  onInterpretationClick: onInterpretationClick,
106
+ onLikeToggled: onLikeToggled,
96
107
  onReplyIconClick: onReplyIconClick,
97
108
  refresh: onCompleteAction,
98
109
  disabled: disabled,