@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
@@ -10,22 +10,43 @@ var _propTypes = _interopRequireDefault(require("prop-types"));
10
10
  var _react = _interopRequireDefault(require("react"));
11
11
  var _index = _interopRequireDefault(require("../../locales/index.js"));
12
12
  var _dataTypes = require("../../modules/dataTypes.js");
13
+ var _visTypes = require("../../modules/visTypes.js");
14
+ var _DataDimension = require("./DataDimension.js");
13
15
  var _DataTypeSelectorStyle = _interopRequireDefault(require("./styles/DataTypeSelector.style.js"));
14
16
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
17
  const DataTypeSelector = _ref => {
16
- var _dataTypes$currentDat;
17
18
  let {
18
19
  currentDataType,
20
+ dataTypes,
19
21
  onChange,
20
- dataTest,
21
- includeCalculations
22
+ dataTest
22
23
  } = _ref;
24
+ const {
25
+ visType
26
+ } = (0, _DataDimension.useDataDimensionContext)();
27
+ const label = _index.default.t('Data Type');
23
28
  return /*#__PURE__*/_react.default.createElement("div", {
24
29
  className: `jsx-${_DataTypeSelectorStyle.default.__hash}` + " " + "container"
25
- }, /*#__PURE__*/_react.default.createElement(_ui.SingleSelectField, {
26
- label: _index.default.t('Data Type'),
30
+ }, dataTypes.length === 1 ? /*#__PURE__*/_react.default.createElement(_ui.SingleSelectField, {
31
+ label: label,
27
32
  dataTest: dataTest,
28
- selected: ((_dataTypes$currentDat = _dataTypes.dataTypeMap[currentDataType]) === null || _dataTypes$currentDat === void 0 ? void 0 : _dataTypes$currentDat.id) || _dataTypes.DIMENSION_TYPE_ALL,
33
+ selected: dataTypes[0].id,
34
+ onChange: ref => onChange(ref.selected),
35
+ dense: true,
36
+ disabled: true,
37
+ helpText: visType ? _index.default.t('Only {{dataType}} can be used in {{visType}}', {
38
+ dataType: _dataTypes.dataTypeMap[dataTypes[0].id].getName(),
39
+ visType: (0, _visTypes.getDisplayNameByVisType)(visType)
40
+ }) : ''
41
+ }, dataTypes.map(type => /*#__PURE__*/_react.default.createElement(_ui.SingleSelectOption, {
42
+ value: type.id,
43
+ key: type.id,
44
+ label: type.getName(),
45
+ dataTest: `${dataTest}-option-${type.id}`
46
+ }))) : /*#__PURE__*/_react.default.createElement(_ui.SingleSelectField, {
47
+ label: label,
48
+ dataTest: dataTest,
49
+ selected: currentDataType || _dataTypes.DIMENSION_TYPE_ALL,
29
50
  onChange: ref => onChange(ref.selected),
30
51
  dense: true
31
52
  }, /*#__PURE__*/_react.default.createElement(_ui.SingleSelectOption, {
@@ -33,7 +54,7 @@ const DataTypeSelector = _ref => {
33
54
  key: _dataTypes.DIMENSION_TYPE_ALL,
34
55
  label: _index.default.t('All types'),
35
56
  dataTest: `${dataTest}-option-all`
36
- }), Object.values(_dataTypes.dataTypeMap).filter(type => type.id !== _dataTypes.DIMENSION_TYPE_EXPRESSION_DIMENSION_ITEM || includeCalculations).map(type => /*#__PURE__*/_react.default.createElement(_ui.SingleSelectOption, {
57
+ }), dataTypes.map(type => /*#__PURE__*/_react.default.createElement(_ui.SingleSelectOption, {
37
58
  value: type.id,
38
59
  key: type.id,
39
60
  label: type.getName(),
@@ -46,7 +67,7 @@ DataTypeSelector.propTypes = {
46
67
  currentDataType: _propTypes.default.string.isRequired,
47
68
  onChange: _propTypes.default.func.isRequired,
48
69
  dataTest: _propTypes.default.string,
49
- includeCalculations: _propTypes.default.bool
70
+ dataTypes: _propTypes.default.array
50
71
  };
51
72
  var _default = DataTypeSelector;
52
73
  exports.default = _default;
@@ -34,15 +34,15 @@ const GroupSelector = _ref => {
34
34
  const [isLoading, setIsLoading] = (0, _react.useState)(true);
35
35
  const defaultGroup = (_dataTypes$dataType = _dataTypes.dataTypeMap[dataType]) === null || _dataTypes$dataType === void 0 ? void 0 : _dataTypes$dataType.defaultGroup;
36
36
  const subGroupType = (_dataTypes$dataType2 = _dataTypes.dataTypeMap[dataType]) === null || _dataTypes$dataType2 === void 0 ? void 0 : _dataTypes$dataType2.subGroup;
37
- const fetchGroups = async () => {
38
- setIsLoading(true);
39
- const result = await (0, _dimensions.apiFetchGroups)(dataEngine, dataType, displayNameProp);
40
- setGroups(result);
41
- setIsLoading(false);
42
- };
43
37
  (0, _react.useEffect)(() => {
38
+ const fetchGroups = async () => {
39
+ setIsLoading(true);
40
+ const result = await (0, _dimensions.apiFetchGroups)(dataEngine, dataType, displayNameProp);
41
+ setGroups(result);
42
+ setIsLoading(false);
43
+ };
44
44
  fetchGroups();
45
- }, [dataType]);
45
+ }, [dataEngine, dataType, displayNameProp]);
46
46
  return /*#__PURE__*/_react.default.createElement("div", {
47
47
  className: `jsx-${_GroupSelectorStyle.default.__hash}` + " " + "container"
48
48
  }, /*#__PURE__*/_react.default.createElement(_style.default, {
@@ -30,14 +30,14 @@ const LeftHeader = _ref => {
30
30
  searchTerm,
31
31
  setSearchTerm,
32
32
  dataType,
33
+ dataTypes,
33
34
  setDataType,
34
35
  group,
35
36
  setGroup,
36
37
  subGroup,
37
38
  setSubGroup,
38
39
  displayNameProp,
39
- dataTest,
40
- supportsEDI
40
+ dataTest
41
41
  } = _ref;
42
42
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
43
43
  className: `jsx-${_DimensionSelectorStyle.default.__hash}` + " " + "leftHeader"
@@ -58,8 +58,8 @@ const LeftHeader = _ref => {
58
58
  currentDataType: dataType,
59
59
  onChange: setDataType,
60
60
  dataTest: `${dataTest}-data-types-select-field`,
61
- includeCalculations: supportsEDI
62
- }), _dataTypes.dataTypeMap[dataType] && dataType !== _dataTypes.DIMENSION_TYPE_EXPRESSION_DIMENSION_ITEM && /*#__PURE__*/_react.default.createElement(_GroupSelector.default, {
61
+ dataTypes: dataTypes
62
+ }), ![_dataTypes.DIMENSION_TYPE_EXPRESSION_DIMENSION_ITEM, _dataTypes.DIMENSION_TYPE_ALL].includes(dataType) && /*#__PURE__*/_react.default.createElement(_GroupSelector.default, {
63
63
  dataType: dataType,
64
64
  displayNameProp: displayNameProp,
65
65
  currentGroup: group,
@@ -74,6 +74,7 @@ const LeftHeader = _ref => {
74
74
  LeftHeader.propTypes = {
75
75
  dataTest: _propTypes.default.string,
76
76
  dataType: _propTypes.default.string,
77
+ dataTypes: _propTypes.default.array,
77
78
  displayNameProp: _propTypes.default.string,
78
79
  group: _propTypes.default.string,
79
80
  searchTerm: _propTypes.default.string,
@@ -81,8 +82,7 @@ LeftHeader.propTypes = {
81
82
  setGroup: _propTypes.default.func,
82
83
  setSearchTerm: _propTypes.default.func,
83
84
  setSubGroup: _propTypes.default.func,
84
- subGroup: _propTypes.default.string,
85
- supportsEDI: _propTypes.default.bool
85
+ subGroup: _propTypes.default.string
86
86
  };
87
87
  const EmptySelection = () => /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("p", {
88
88
  className: `jsx-${_DimensionSelectorStyle.default.__hash}` + " " + "emptyList"
@@ -91,22 +91,22 @@ const EmptySelection = () => /*#__PURE__*/_react.default.createElement(_react.de
91
91
  }, _DimensionSelectorStyle.default));
92
92
  const RightHeader = _ref3 => {
93
93
  let {
94
- infoText
94
+ infoBoxMessage
95
95
  } = _ref3;
96
96
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("p", {
97
97
  className: `jsx-${_DimensionSelectorStyle.default.__hash}` + " " + "rightHeader"
98
- }, _index.default.t('Selected Items')), infoText && /*#__PURE__*/_react.default.createElement("div", {
98
+ }, _index.default.t('Selected Items')), infoBoxMessage && /*#__PURE__*/_react.default.createElement("div", {
99
99
  className: `jsx-${_DimensionSelectorStyle.default.__hash}` + " " + "info-container"
100
100
  }, /*#__PURE__*/_react.default.createElement("div", {
101
101
  className: `jsx-${_DimensionSelectorStyle.default.__hash}`
102
102
  }, /*#__PURE__*/_react.default.createElement(_ui.IconInfo16, null)), /*#__PURE__*/_react.default.createElement("span", {
103
103
  className: `jsx-${_DimensionSelectorStyle.default.__hash}` + " " + "info-text"
104
- }, infoText)), /*#__PURE__*/_react.default.createElement(_style.default, {
104
+ }, infoBoxMessage)), /*#__PURE__*/_react.default.createElement(_style.default, {
105
105
  id: _DimensionSelectorStyle.default.__hash
106
106
  }, _DimensionSelectorStyle.default));
107
107
  };
108
108
  RightHeader.propTypes = {
109
- infoText: _propTypes.default.string
109
+ infoBoxMessage: _propTypes.default.string
110
110
  };
111
111
  const SourceEmptyPlaceholder = _ref4 => {
112
112
  let {
@@ -138,6 +138,9 @@ const SourceEmptyPlaceholder = _ref4 => {
138
138
  case _dataTypes.DIMENSION_TYPE_PROGRAM_INDICATOR:
139
139
  message = _index.default.t('No program indicators found');
140
140
  break;
141
+ case _dataTypes.DIMENSION_TYPE_EXPRESSION_DIMENSION_ITEM:
142
+ message = _index.default.t('No calculations found');
143
+ break;
141
144
  default:
142
145
  message = _index.default.t('No data');
143
146
  break;
@@ -147,32 +150,37 @@ const SourceEmptyPlaceholder = _ref4 => {
147
150
  switch (dataType) {
148
151
  case _dataTypes.DIMENSION_TYPE_INDICATOR:
149
152
  message = _index.default.t('No indicators found for "{{- searchTerm}}"', {
150
- searchTerm: searchTerm
153
+ searchTerm
151
154
  });
152
155
  break;
153
156
  case _dataTypes.DIMENSION_TYPE_DATA_ELEMENT:
154
157
  message = _index.default.t('No data elements found for "{{- searchTerm}}"', {
155
- searchTerm: searchTerm
158
+ searchTerm
156
159
  });
157
160
  break;
158
161
  case _dataTypes.DIMENSION_TYPE_DATA_SET:
159
162
  message = _index.default.t('No data sets found for "{{- searchTerm}}"', {
160
- searchTerm: searchTerm
163
+ searchTerm
161
164
  });
162
165
  break;
163
166
  case _dataTypes.DIMENSION_TYPE_EVENT_DATA_ITEM:
164
167
  message = _index.default.t('No event data items found for "{{- searchTerm}}"', {
165
- searchTerm: searchTerm
168
+ searchTerm
166
169
  });
167
170
  break;
168
171
  case _dataTypes.DIMENSION_TYPE_PROGRAM_INDICATOR:
169
172
  message = _index.default.t('No program indicators found for "{{- searchTerm}}"', {
170
- searchTerm: searchTerm
173
+ searchTerm
174
+ });
175
+ break;
176
+ case _dataTypes.DIMENSION_TYPE_EXPRESSION_DIMENSION_ITEM:
177
+ message = _index.default.t('No calculations found for "{{- searchTerm}}"', {
178
+ searchTerm
171
179
  });
172
180
  break;
173
181
  default:
174
182
  message = _index.default.t('Nothing found for "{{- searchTerm}}"', {
175
- searchTerm: searchTerm
183
+ searchTerm
176
184
  });
177
185
  break;
178
186
  }
@@ -200,18 +208,27 @@ const ItemSelector = _ref5 => {
200
208
  rightFooter,
201
209
  displayNameProp,
202
210
  infoBoxMessage,
211
+ dataTypes,
203
212
  dataTest,
204
- supportsEDI,
205
213
  onEDISave
206
214
  } = _ref5;
207
215
  const [state, setState] = (0, _react.useState)({
208
216
  searchTerm: '',
217
+ dataTypes,
209
218
  filter: {
210
- dataType: _dataTypes.DIMENSION_TYPE_ALL
219
+ dataType: dataTypes.length === 1 ? dataTypes[0].id : _dataTypes.DIMENSION_TYPE_ALL,
220
+ group: null,
221
+ subGroup: dataTypes.length === 1 && dataTypes[0].id === _dataTypes.DIMENSION_TYPE_DATA_ELEMENT ? _dataTypes.TOTALS : null
211
222
  },
212
223
  options: [],
213
224
  loading: true,
214
- nextPage: 1
225
+ nextPage: 1,
226
+ supportsEDI: dataTypes.map(_ref6 => {
227
+ let {
228
+ id
229
+ } = _ref6;
230
+ return id;
231
+ }).includes(_dataTypes.DIMENSION_TYPE_EXPRESSION_DIMENSION_ITEM)
215
232
  });
216
233
  const [currentCalculation, setCurrentCalculation] = (0, _react.useState)();
217
234
  const dataEngine = (0, _appRuntime.useDataEngine)();
@@ -219,15 +236,12 @@ const ItemSelector = _ref5 => {
219
236
  ...state,
220
237
  searchTerm
221
238
  }));
222
- const setFilter = filter => setState(state => ({
223
- ...state,
224
- filter
225
- }));
226
239
  const debouncedSearchTerm = (0, _utils.useDebounce)(state.searchTerm, 500);
227
240
  const fetchItems = async page => {
228
241
  var _result$dimensionItem;
229
242
  setState(state => ({
230
243
  ...state,
244
+ nextPage: page === 1 ? 1 : state.nextPage,
231
245
  loading: true
232
246
  }));
233
247
  const result = await (0, _dimensions.apiFetchOptions)({
@@ -290,11 +304,6 @@ const ItemSelector = _ref5 => {
290
304
  }
291
305
  };
292
306
  (0, _utils.useDidUpdateEffect)(() => {
293
- setState(state => ({
294
- ...state,
295
- loading: true,
296
- nextPage: 1
297
- }));
298
307
  fetchItems(1);
299
308
  }, [debouncedSearchTerm, state.filter]);
300
309
  const onChange = newSelected => {
@@ -323,13 +332,13 @@ const ItemSelector = _ref5 => {
323
332
  var _find;
324
333
  return (_find = [...state.options, ...selectedItems].find(item => item.value === value)) === null || _find === void 0 ? void 0 : _find.type;
325
334
  };
326
- const onSaveCalculation = async _ref6 => {
335
+ const onSaveCalculation = async _ref7 => {
327
336
  let {
328
337
  id,
329
338
  name,
330
339
  expression,
331
340
  isNew
332
- } = _ref6;
341
+ } = _ref7;
333
342
  onEDISave({
334
343
  id,
335
344
  name,
@@ -352,10 +361,10 @@ const ItemSelector = _ref5 => {
352
361
  }]);
353
362
  }
354
363
  };
355
- const onDeleteCalculation = _ref7 => {
364
+ const onDeleteCalculation = _ref8 => {
356
365
  let {
357
366
  id
358
- } = _ref7;
367
+ } = _ref8;
359
368
  // close the modal
360
369
  setCurrentCalculation();
361
370
 
@@ -365,11 +374,37 @@ const ItemSelector = _ref5 => {
365
374
  // unselect the deleted calculation
366
375
  onSelect([...selectedItems.filter(item => item.value !== id)]);
367
376
  };
377
+ const onSetGroup = group => setState(state => ({
378
+ ...state,
379
+ nextPage: 1,
380
+ filter: {
381
+ ...state.filter,
382
+ group
383
+ }
384
+ }));
385
+ const onSetSubGroup = subGroup => setState(state => ({
386
+ ...state,
387
+ nextPage: 1,
388
+ filter: {
389
+ ...state.filter,
390
+ subGroup
391
+ }
392
+ }));
393
+ const onSetDataType = dataType => setState(state => ({
394
+ ...state,
395
+ nextPage: 1,
396
+ filter: {
397
+ ...state.filter,
398
+ dataType,
399
+ group: null,
400
+ subGroup: dataType === _dataTypes.DIMENSION_TYPE_DATA_ELEMENT ? _dataTypes.TOTALS : null
401
+ }
402
+ }));
368
403
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_ui.Transfer, {
369
- onChange: _ref8 => {
404
+ onChange: _ref9 => {
370
405
  let {
371
406
  selected
372
- } = _ref8;
407
+ } = _ref9;
373
408
  return onChange(selected);
374
409
  },
375
410
  selected: selectedItems.map(item => item.value),
@@ -386,36 +421,19 @@ const ItemSelector = _ref5 => {
386
421
  }),
387
422
  onEndReached: onEndReached,
388
423
  leftHeader: /*#__PURE__*/_react.default.createElement(LeftHeader, {
424
+ dataTypes: state.dataTypes,
389
425
  dataType: state.filter.dataType,
390
- setDataType: dataType => {
391
- setFilter({
392
- ...state.filter,
393
- dataType,
394
- group: null,
395
- subGroup: dataType === _dataTypes.DIMENSION_TYPE_DATA_ELEMENT ? _dataTypes.TOTALS : null
396
- });
397
- },
426
+ setDataType: onSetDataType,
398
427
  group: state.filter.group,
399
- setGroup: group => {
400
- setFilter({
401
- ...state.filter,
402
- group
403
- });
404
- },
428
+ setGroup: onSetGroup,
405
429
  subGroup: state.filter.subGroup,
406
- setSubGroup: subGroup => {
407
- setFilter({
408
- ...state.filter,
409
- subGroup
410
- });
411
- },
430
+ setSubGroup: onSetSubGroup,
412
431
  searchTerm: state.searchTerm,
413
432
  setSearchTerm: setSearchTerm,
414
433
  displayNameProp: displayNameProp,
415
- dataTest: `${dataTest}-left-header`,
416
- supportsEDI: supportsEDI
434
+ dataTest: `${dataTest}-left-header`
417
435
  }),
418
- leftFooter: supportsEDI ? /*#__PURE__*/_react.default.createElement("div", {
436
+ leftFooter: state.supportsEDI ? /*#__PURE__*/_react.default.createElement("div", {
419
437
  className: `jsx-${_DimensionSelectorStyle.default.__hash}` + " " + "calculation-button"
420
438
  }, /*#__PURE__*/_react.default.createElement(_ui.Button, {
421
439
  icon: /*#__PURE__*/_react.default.createElement(_ui.IconAdd24, null),
@@ -428,7 +446,7 @@ const ItemSelector = _ref5 => {
428
446
  selectedWidth: _dimensionSelectorHelper.TRANSFER_SELECTED_WIDTH,
429
447
  selectedEmptyComponent: /*#__PURE__*/_react.default.createElement(EmptySelection, null),
430
448
  rightHeader: /*#__PURE__*/_react.default.createElement(RightHeader, {
431
- infoText: infoBoxMessage
449
+ infoBoxMessage: infoBoxMessage
432
450
  }),
433
451
  rightFooter: rightFooter,
434
452
  renderOption: props => {
@@ -442,7 +460,7 @@ const ItemSelector = _ref5 => {
442
460
  expression: props.expression
443
461
  }),
444
462
  dataTest: `${dataTest}-transfer-option`,
445
- onEditClick: getItemType(props.value) === _dataTypes.DIMENSION_TYPE_EXPRESSION_DIMENSION_ITEM && !(((_props$access = props.access) === null || _props$access === void 0 ? void 0 : _props$access.write) === false) && supportsEDI ? () => setCurrentCalculation({
463
+ onEditClick: getItemType(props.value) === _dataTypes.DIMENSION_TYPE_EXPRESSION_DIMENSION_ITEM && !(((_props$access = props.access) === null || _props$access === void 0 ? void 0 : _props$access.write) === false) && state.supportsEDI ? () => setCurrentCalculation({
446
464
  id: props.value,
447
465
  name: props.label,
448
466
  expression: props.expression
@@ -452,7 +470,7 @@ const ItemSelector = _ref5 => {
452
470
  },
453
471
 
454
472
  dataTest: `${dataTest}-transfer`
455
- }), currentCalculation && supportsEDI && /*#__PURE__*/_react.default.createElement(_CalculationModal.default, {
473
+ }), currentCalculation && state.supportsEDI && /*#__PURE__*/_react.default.createElement(_CalculationModal.default, {
456
474
  calculation: currentCalculation,
457
475
  onSave: onSaveCalculation,
458
476
  onClose: () => setCurrentCalculation(),
@@ -466,6 +484,7 @@ ItemSelector.propTypes = {
466
484
  displayNameProp: _propTypes.default.string.isRequired,
467
485
  onSelect: _propTypes.default.func.isRequired,
468
486
  dataTest: _propTypes.default.string,
487
+ dataTypes: _propTypes.default.array,
469
488
  infoBoxMessage: _propTypes.default.string,
470
489
  noItemsMessage: _propTypes.default.string,
471
490
  rightFooter: _propTypes.default.node,
@@ -476,7 +495,6 @@ ItemSelector.propTypes = {
476
495
  type: _propTypes.default.string,
477
496
  expression: _propTypes.default.string
478
497
  })),
479
- supportsEDI: _propTypes.default.bool,
480
498
  onEDISave: _propTypes.default.func
481
499
  };
482
500
  ItemSelector.defaultProps = {
@@ -73,7 +73,7 @@ const InterpretationModal = _ref2 => {
73
73
  });
74
74
  const interpretation = data === null || data === void 0 ? void 0 : data.interpretation;
75
75
  const shouldRenderModalContent = !error && interpretation;
76
- const shouldCssHideModal = loading || isVisualizationLoading;
76
+ const loadingInProgress = loading || isVisualizationLoading;
77
77
  const handleClose = () => {
78
78
  if (isDirty) {
79
79
  onInterpretationUpdate();
@@ -89,6 +89,14 @@ const InterpretationModal = _ref2 => {
89
89
  id: interpretationId
90
90
  });
91
91
  };
92
+ const onLikeToggled = _ref3 => {
93
+ let {
94
+ likedBy
95
+ } = _ref3;
96
+ setIsDirty(true);
97
+ interpretation.likedBy = likedBy;
98
+ interpretation.likes = likedBy.length;
99
+ };
92
100
  const onInterpretationDeleted = () => {
93
101
  setIsDirty(false);
94
102
  onInterpretationUpdate();
@@ -101,11 +109,11 @@ const InterpretationModal = _ref2 => {
101
109
  });
102
110
  }
103
111
  }, [interpretationId, refetch]);
104
- return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, shouldCssHideModal && /*#__PURE__*/_react.default.createElement(_ui.Layer, null, /*#__PURE__*/_react.default.createElement(_ui.CenteredContent, null, /*#__PURE__*/_react.default.createElement(_ui.CircularLoader, null))), /*#__PURE__*/_react.default.createElement(_ui.Modal, {
112
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, loadingInProgress && /*#__PURE__*/_react.default.createElement(_ui.Layer, null, /*#__PURE__*/_react.default.createElement(_ui.CenteredContent, null, /*#__PURE__*/_react.default.createElement(_ui.CircularLoader, null))), /*#__PURE__*/_react.default.createElement(_ui.Modal, {
105
113
  fluid: true,
106
114
  onClose: handleClose,
107
115
  className: (0, _classnames.default)(modalCSS.className, {
108
- hidden: shouldCssHideModal
116
+ hidden: loadingInProgress
109
117
  }),
110
118
  dataTest: "interpretation-modal"
111
119
  }, /*#__PURE__*/_react.default.createElement("h1", {
@@ -143,7 +151,8 @@ const InterpretationModal = _ref2 => {
143
151
  onInterpretationDeleted: onInterpretationDeleted,
144
152
  onThreadUpdated: onThreadUpdated,
145
153
  initialFocus: initialFocus,
146
- downloadMenuComponent: downloadMenuComponent
154
+ downloadMenuComponent: downloadMenuComponent,
155
+ onLikeToggled: onLikeToggled
147
156
  }))))), /*#__PURE__*/_react.default.createElement(_ui.ModalActions, null, /*#__PURE__*/_react.default.createElement(_ui.Button, {
148
157
  disabled: fetching,
149
158
  onClick: handleClose
@@ -23,6 +23,7 @@ const InterpretationThread = _ref => {
23
23
  fetching,
24
24
  interpretation,
25
25
  onInterpretationDeleted,
26
+ onLikeToggled,
26
27
  initialFocus,
27
28
  onThreadUpdated,
28
29
  downloadMenuComponent: DownloadMenu,
@@ -57,6 +58,7 @@ const InterpretationThread = _ref => {
57
58
  }, /*#__PURE__*/_react.default.createElement(_index.Interpretation, {
58
59
  currentUser: currentUser,
59
60
  interpretation: interpretation,
61
+ onLikeToggled: onLikeToggled,
60
62
  onReplyIconClick: interpretationAccess.comment ? () => {
61
63
  var _focusRef$current;
62
64
  return (_focusRef$current = focusRef.current) === null || _focusRef$current === void 0 ? void 0 : _focusRef$current.focus();
@@ -89,6 +91,7 @@ InterpretationThread.propTypes = {
89
91
  fetching: _propTypes.default.bool.isRequired,
90
92
  interpretation: _propTypes.default.object.isRequired,
91
93
  onInterpretationDeleted: _propTypes.default.func.isRequired,
94
+ onLikeToggled: _propTypes.default.func.isRequired,
92
95
  dashboardRedirectUrl: _propTypes.default.string,
93
96
  downloadMenuComponent: _propTypes.default.oneOfType([_propTypes.default.object, _propTypes.default.func]),
94
97
  initialFocus: _propTypes.default.bool,
@@ -28,6 +28,7 @@ const InterpretationList = _ref => {
28
28
  currentUser,
29
29
  interpretations,
30
30
  onInterpretationClick,
31
+ onLikeToggled,
31
32
  onReplyIconClick,
32
33
  refresh,
33
34
  disabled,
@@ -65,6 +66,7 @@ const InterpretationList = _ref => {
65
66
  interpretation: interpretation,
66
67
  currentUser: currentUser,
67
68
  onClick: onInterpretationClick,
69
+ onLikeToggled: onLikeToggled,
68
70
  onReplyIconClick: onReplyIconClick,
69
71
  onDeleted: refresh,
70
72
  onUpdated: refresh,
@@ -81,6 +83,7 @@ InterpretationList.propTypes = {
81
83
  interpretations: _propTypes.default.array.isRequired,
82
84
  refresh: _propTypes.default.func.isRequired,
83
85
  onInterpretationClick: _propTypes.default.func.isRequired,
86
+ onLikeToggled: _propTypes.default.func.isRequired,
84
87
  onReplyIconClick: _propTypes.default.func.isRequired,
85
88
  dashboardRedirectUrl: _propTypes.default.string,
86
89
  disabled: _propTypes.default.bool
@@ -44,14 +44,15 @@ const InterpretationsUnit = /*#__PURE__*/(0, _react.forwardRef)((_ref2, ref) =>
44
44
  dashboardRedirectUrl
45
45
  } = _ref2;
46
46
  const [isExpanded, setIsExpanded] = (0, _react.useState)(true);
47
+ const [interpretations, setInterpretations] = (0, _react.useState)([]);
47
48
  const showNoTimeDimensionHelpText = type === 'eventVisualization' && !visualizationHasTimeDimension;
48
49
  const {
49
- data,
50
50
  loading,
51
51
  fetching,
52
52
  refetch
53
53
  } = (0, _appRuntime.useDataQuery)(interpretationsQuery, {
54
- lazy: true
54
+ lazy: true,
55
+ onComplete: data => setInterpretations(data.interpretations.interpretations)
55
56
  });
56
57
  const onCompleteAction = (0, _react.useCallback)(() => {
57
58
  refetch({
@@ -70,6 +71,15 @@ const InterpretationsUnit = /*#__PURE__*/(0, _react.forwardRef)((_ref2, ref) =>
70
71
  });
71
72
  }
72
73
  }, [type, id, renderId, refetch]);
74
+ const onLikeToggled = _ref3 => {
75
+ let {
76
+ id,
77
+ likedBy
78
+ } = _ref3;
79
+ const interpretation = interpretations.find(interp => interp.id === id);
80
+ interpretation.likedBy = likedBy;
81
+ interpretation.likes = likedBy.length;
82
+ };
73
83
  return /*#__PURE__*/_react.default.createElement("div", {
74
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', {
75
85
  expanded: isExpanded
@@ -91,7 +101,7 @@ const InterpretationsUnit = /*#__PURE__*/(0, _react.forwardRef)((_ref2, ref) =>
91
101
  className: _style.default.dynamic([["4120713286", [_ui.spacers.dp16, _ui.colors.grey400, _ui.colors.white, _ui.spacers.dp32, _ui.colors.grey900]]]) + " " + "loader"
92
102
  }, /*#__PURE__*/_react.default.createElement(_ui.CircularLoader, {
93
103
  small: true
94
- })), data && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_InterpretationForm.InterpretationForm, {
104
+ })), interpretations && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_InterpretationForm.InterpretationForm, {
95
105
  currentUser: currentUser,
96
106
  type: type,
97
107
  id: id,
@@ -100,8 +110,9 @@ const InterpretationsUnit = /*#__PURE__*/(0, _react.forwardRef)((_ref2, ref) =>
100
110
  showNoTimeDimensionHelpText: showNoTimeDimensionHelpText
101
111
  }), /*#__PURE__*/_react.default.createElement(_InterpretationList.InterpretationList, {
102
112
  currentUser: currentUser,
103
- interpretations: data.interpretations.interpretations,
113
+ interpretations: interpretations,
104
114
  onInterpretationClick: onInterpretationClick,
115
+ onLikeToggled: onLikeToggled,
105
116
  onReplyIconClick: onReplyIconClick,
106
117
  refresh: onCompleteAction,
107
118
  disabled: disabled,
@@ -25,7 +25,8 @@ const Interpretation = _ref => {
25
25
  disabled,
26
26
  onReplyIconClick,
27
27
  dashboardRedirectUrl,
28
- isInThread
28
+ isInThread,
29
+ onLikeToggled
29
30
  } = _ref;
30
31
  const [isUpdateMode, setIsUpdateMode] = (0, _react.useState)(false);
31
32
  const [showSharingDialog, setShowSharingDialog] = (0, _react.useState)(false);
@@ -36,7 +37,10 @@ const Interpretation = _ref => {
36
37
  } = (0, _useLike.useLike)({
37
38
  interpretation,
38
39
  currentUser,
39
- onComplete: onUpdated
40
+ onComplete: likedBy => onLikeToggled({
41
+ id: interpretation.id,
42
+ likedBy
43
+ })
40
44
  });
41
45
  const shouldShowButton = Boolean(!!onClick && !disabled & !dashboardRedirectUrl);
42
46
  const interpretationAccess = (0, _index.getInterpretationAccess)(interpretation, currentUser);
@@ -123,6 +127,7 @@ Interpretation.propTypes = {
123
127
  currentUser: _propTypes.default.object.isRequired,
124
128
  interpretation: _propTypes.default.object.isRequired,
125
129
  onDeleted: _propTypes.default.func.isRequired,
130
+ onLikeToggled: _propTypes.default.func.isRequired,
126
131
  onReplyIconClick: _propTypes.default.func.isRequired,
127
132
  onUpdated: _propTypes.default.func.isRequired,
128
133
  dashboardRedirectUrl: _propTypes.default.string,
@@ -24,12 +24,22 @@ const useLike = _ref => {
24
24
  const [like, {
25
25
  loading: likeLoading
26
26
  }] = (0, _appRuntime.useDataMutation)(likeMutationRef.current, {
27
- onComplete
27
+ onComplete: () => {
28
+ const newLikedBy = interpretation.likedBy.concat({
29
+ id: currentUser.id
30
+ });
31
+ setIsLikedByCurrentUser(true);
32
+ onComplete(newLikedBy);
33
+ }
28
34
  });
29
35
  const [unlike, {
30
36
  loading: unlikeLoading
31
37
  }] = (0, _appRuntime.useDataMutation)(unlikeMutationRef.current, {
32
- onComplete
38
+ onComplete: () => {
39
+ const newLikedBy = interpretation.likedBy.filter(lb => lb.id !== currentUser.id);
40
+ setIsLikedByCurrentUser(false);
41
+ onComplete(newLikedBy);
42
+ }
33
43
  });
34
44
  const [isLikedByCurrentUser, setIsLikedByCurrentUser] = (0, _react.useState)(false);
35
45
  const toggleLike = () => {
@@ -23,7 +23,8 @@ const PeriodDimension = _ref => {
23
23
  onSelect,
24
24
  selectedPeriods,
25
25
  rightFooter,
26
- excludedPeriodTypes
26
+ excludedPeriodTypes,
27
+ infoBoxMessage
27
28
  } = _ref;
28
29
  const {
29
30
  systemInfo
@@ -51,7 +52,8 @@ const PeriodDimension = _ref => {
51
52
  };
52
53
  return /*#__PURE__*/_react.default.createElement(_PeriodTransfer.default, {
53
54
  onSelect: selectPeriods,
54
- initialSelectedPeriods: selectedPeriods,
55
+ selectedItems: selectedPeriods,
56
+ infoBoxMessage: infoBoxMessage,
55
57
  rightFooter: rightFooter,
56
58
  dataTest: 'period-dimension',
57
59
  excludedPeriodTypes: excludedPeriodTypes,
@@ -61,6 +63,7 @@ const PeriodDimension = _ref => {
61
63
  PeriodDimension.propTypes = {
62
64
  onSelect: _propTypes.default.func.isRequired,
63
65
  excludedPeriodTypes: _propTypes.default.arrayOf(_propTypes.default.string),
66
+ infoBoxMessage: _propTypes.default.string,
64
67
  rightFooter: _propTypes.default.node,
65
68
  selectedPeriods: _propTypes.default.array
66
69
  };