@dhis2/analytics 26.4.1 → 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 (63) 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/PeriodDimension/PeriodDimension.js +5 -2
  15. package/build/cjs/components/PeriodDimension/PeriodTransfer.js +64 -31
  16. package/build/cjs/components/PeriodDimension/__tests__/__snapshots__/PeriodDimension.spec.js.snap +1 -1
  17. package/build/cjs/components/PeriodDimension/__tests__/__snapshots__/PeriodSelector.spec.js.snap +1 -12
  18. package/build/cjs/components/VisTypeIcon.js +6 -1
  19. package/build/cjs/index.js +43 -1
  20. package/build/cjs/locales/en/translations.json +5 -1
  21. package/build/cjs/modules/__tests__/getAdaptedUiLayoutByType.spec.js +15 -0
  22. package/build/cjs/modules/axis.js +4 -0
  23. package/build/cjs/modules/getAdaptedUiLayoutByType.js +9 -0
  24. package/build/cjs/modules/layoutTypes.js +4 -2
  25. package/build/cjs/modules/layoutUiRules/__tests__/rules.spec.js +13 -1
  26. package/build/cjs/modules/layoutUiRules/index.js +12 -0
  27. package/build/cjs/modules/layoutUiRules/rules.js +22 -2
  28. package/build/cjs/modules/layoutUiRules/rulesHelper.js +4 -2
  29. package/build/cjs/modules/layoutUiRules/rulesUtils.js +7 -2
  30. package/build/cjs/modules/visTypeToLayoutType.js +2 -1
  31. package/build/cjs/modules/visTypes.js +9 -3
  32. package/build/es/__fixtures__/fixtures.js +1 -0
  33. package/build/es/__fixtures__/json/api/analytics/outlierDetection.json +213 -0
  34. package/build/es/api/analytics/AnalyticsAggregate.js +27 -1
  35. package/build/es/api/analytics/AnalyticsBase.js +7 -7
  36. package/build/es/api/analytics/AnalyticsRequestBase.js +9 -5
  37. package/build/es/api/analytics/AnalyticsResponse.js +42 -39
  38. package/build/es/api/analytics/__tests__/Analytics.spec.js +5 -0
  39. package/build/es/api/analytics/__tests__/AnalyticsAggregate.spec.js +29 -0
  40. package/build/es/api/analytics/__tests__/AnalyticsBase.spec.js +34 -1
  41. package/build/es/components/DataDimension/DataDimension.js +27 -6
  42. package/build/es/components/DataDimension/DataTypeSelector.js +30 -9
  43. package/build/es/components/DataDimension/GroupSelector.js +7 -7
  44. package/build/es/components/DataDimension/ItemSelector.js +80 -62
  45. package/build/es/components/PeriodDimension/PeriodDimension.js +5 -2
  46. package/build/es/components/PeriodDimension/PeriodTransfer.js +65 -32
  47. package/build/es/components/PeriodDimension/__tests__/__snapshots__/PeriodDimension.spec.js.snap +1 -1
  48. package/build/es/components/PeriodDimension/__tests__/__snapshots__/PeriodSelector.spec.js.snap +1 -12
  49. package/build/es/components/VisTypeIcon.js +8 -3
  50. package/build/es/index.js +4 -4
  51. package/build/es/locales/en/translations.json +5 -1
  52. package/build/es/modules/__tests__/getAdaptedUiLayoutByType.spec.js +16 -1
  53. package/build/es/modules/axis.js +5 -1
  54. package/build/es/modules/getAdaptedUiLayoutByType.js +10 -1
  55. package/build/es/modules/layoutTypes.js +2 -1
  56. package/build/es/modules/layoutUiRules/__tests__/rules.spec.js +14 -2
  57. package/build/es/modules/layoutUiRules/index.js +2 -2
  58. package/build/es/modules/layoutUiRules/rules.js +22 -3
  59. package/build/es/modules/layoutUiRules/rulesHelper.js +3 -2
  60. package/build/es/modules/layoutUiRules/rulesUtils.js +6 -2
  61. package/build/es/modules/visTypeToLayoutType.js +4 -3
  62. package/build/es/modules/visTypes.js +7 -3
  63. package/package.json +6 -3
@@ -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 = {
@@ -16,7 +16,8 @@ const PeriodDimension = _ref => {
16
16
  onSelect,
17
17
  selectedPeriods,
18
18
  rightFooter,
19
- excludedPeriodTypes
19
+ excludedPeriodTypes,
20
+ infoBoxMessage
20
21
  } = _ref;
21
22
  const {
22
23
  systemInfo
@@ -44,7 +45,8 @@ const PeriodDimension = _ref => {
44
45
  };
45
46
  return /*#__PURE__*/React.createElement(PeriodTransfer, {
46
47
  onSelect: selectPeriods,
47
- initialSelectedPeriods: selectedPeriods,
48
+ selectedItems: selectedPeriods,
49
+ infoBoxMessage: infoBoxMessage,
48
50
  rightFooter: rightFooter,
49
51
  dataTest: 'period-dimension',
50
52
  excludedPeriodTypes: excludedPeriodTypes,
@@ -54,6 +56,7 @@ const PeriodDimension = _ref => {
54
56
  PeriodDimension.propTypes = {
55
57
  onSelect: PropTypes.func.isRequired,
56
58
  excludedPeriodTypes: PropTypes.arrayOf(PropTypes.string),
59
+ infoBoxMessage: PropTypes.string,
57
60
  rightFooter: PropTypes.node,
58
61
  selectedPeriods: PropTypes.array
59
62
  };
@@ -1,7 +1,7 @@
1
1
  import _JSXStyle from "styled-jsx/style";
2
2
  function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
3
3
  import { getNowInCalendar } from '@dhis2/multi-calendar-dates';
4
- import { TabBar, Tab, Transfer } from '@dhis2/ui';
4
+ import { IconInfo16, TabBar, Tab, Transfer } from '@dhis2/ui';
5
5
  import PropTypes from 'prop-types';
6
6
  import React, { useState } from 'react';
7
7
  import PeriodIcon from '../../assets/DimensionItemIcons/PeriodIcon.js'; //TODO: Reimplement the icon.js
@@ -14,15 +14,35 @@ import RelativePeriodFilter from './RelativePeriodFilter.js';
14
14
  import { getFixedPeriodsOptionsById } from './utils/fixedPeriods.js';
15
15
  import { MONTHLY, QUARTERLY } from './utils/index.js';
16
16
  import { getRelativePeriodsOptionsById } from './utils/relativePeriods.js';
17
- const PeriodTransfer = _ref => {
17
+ const RightHeader = _ref => {
18
+ let {
19
+ infoBoxMessage
20
+ } = _ref;
21
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("p", {
22
+ className: `jsx-${styles.__hash}` + " " + "rightHeader"
23
+ }, i18n.t('Selected Periods')), infoBoxMessage && /*#__PURE__*/React.createElement("div", {
24
+ className: `jsx-${styles.__hash}` + " " + "info-container"
25
+ }, /*#__PURE__*/React.createElement("div", {
26
+ className: `jsx-${styles.__hash}`
27
+ }, /*#__PURE__*/React.createElement(IconInfo16, null)), /*#__PURE__*/React.createElement("span", {
28
+ className: `jsx-${styles.__hash}` + " " + "info-text"
29
+ }, infoBoxMessage)), /*#__PURE__*/React.createElement(_JSXStyle, {
30
+ id: styles.__hash
31
+ }, styles));
32
+ };
33
+ RightHeader.propTypes = {
34
+ infoBoxMessage: PropTypes.string
35
+ };
36
+ const PeriodTransfer = _ref2 => {
18
37
  let {
19
38
  onSelect,
20
39
  dataTest,
21
- initialSelectedPeriods,
40
+ selectedItems,
22
41
  rightFooter,
23
42
  excludedPeriodTypes,
24
- periodsSettings
25
- } = _ref;
43
+ periodsSettings,
44
+ infoBoxMessage
45
+ } = _ref2;
26
46
  const defaultRelativePeriodType = excludedPeriodTypes.includes(MONTHLY) ? getRelativePeriodsOptionsById(QUARTERLY) : getRelativePeriodsOptionsById(MONTHLY);
27
47
  const defaultFixedPeriodType = excludedPeriodTypes.includes(MONTHLY) ? getFixedPeriodsOptionsById(QUARTERLY, periodsSettings) : getFixedPeriodsOptionsById(MONTHLY, periodsSettings);
28
48
  const now = getNowInCalendar(periodsSettings.calendar);
@@ -35,7 +55,6 @@ const PeriodTransfer = _ref => {
35
55
  reversePeriods: false
36
56
  });
37
57
  const [allPeriods, setAllPeriods] = useState(defaultRelativePeriodType.getPeriods());
38
- const [selectedPeriods, setSelectedPeriods] = useState(initialSelectedPeriods);
39
58
  const [isRelative, setIsRelative] = useState(true);
40
59
  const [relativeFilter, setRelativeFilter] = useState({
41
60
  periodType: defaultRelativePeriodType.id
@@ -44,6 +63,10 @@ const PeriodTransfer = _ref => {
44
63
  periodType: defaultFixedPeriodType.id,
45
64
  year: defaultFixedPeriodYear.toString()
46
65
  });
66
+ const isActive = value => {
67
+ const item = selectedItems.find(item => item.id === value);
68
+ return !item || item.isActive;
69
+ };
47
70
  const onIsRelativeClick = state => {
48
71
  if (state !== isRelative) {
49
72
  setIsRelative(state);
@@ -90,11 +113,6 @@ const PeriodTransfer = _ref => {
90
113
  })), /*#__PURE__*/React.createElement(_JSXStyle, {
91
114
  id: styles.__hash
92
115
  }, styles));
93
- const renderRightHeader = () => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("p", {
94
- className: `jsx-${styles.__hash}` + " " + "rightHeader"
95
- }, i18n.t('Selected Periods')), /*#__PURE__*/React.createElement(_JSXStyle, {
96
- id: styles.__hash
97
- }, styles));
98
116
  const onSelectFixedPeriods = filter => {
99
117
  setFixedFilter(filter);
100
118
  setAllPeriods(getFixedPeriodsOptionsById(filter.periodType, periodsSettings).getPeriods(fixedPeriodConfig(Number(filter.year)), periodsSettings));
@@ -105,45 +123,58 @@ const PeriodTransfer = _ref => {
105
123
  id: styles.__hash
106
124
  }, styles));
107
125
  return /*#__PURE__*/React.createElement(Transfer, {
108
- onChange: _ref2 => {
126
+ onChange: _ref3 => {
109
127
  let {
110
128
  selected
111
- } = _ref2;
112
- const formattedItems = selected.map(id => ({
113
- id,
114
- name: [...allPeriods, ...selectedPeriods].find(item => item.id === id).name
115
- }));
116
- setSelectedPeriods(formattedItems);
129
+ } = _ref3;
130
+ const formattedItems = selected.map(id => {
131
+ const matchingItem = [...allPeriods, ...selectedItems].find(item => item.id === id);
132
+ return {
133
+ id,
134
+ name: matchingItem.name,
135
+ isActive: matchingItem.isActive
136
+ };
137
+ });
117
138
  onSelect(formattedItems);
118
139
  },
119
- selected: selectedPeriods.map(period => period.id),
140
+ selected: selectedItems.map(period => period.id),
120
141
  leftHeader: renderLeftHeader(),
121
142
  enableOrderChange: true,
122
143
  height: TRANSFER_HEIGHT,
123
144
  optionsWidth: TRANSFER_OPTIONS_WIDTH,
124
145
  selectedWidth: TRANSFER_SELECTED_WIDTH,
125
146
  selectedEmptyComponent: renderEmptySelection(),
126
- rightHeader: renderRightHeader(),
147
+ rightHeader: /*#__PURE__*/React.createElement(RightHeader, {
148
+ infoBoxMessage: infoBoxMessage
149
+ }),
127
150
  rightFooter: rightFooter,
128
- options: [...allPeriods, ...selectedPeriods].map(_ref3 => {
151
+ options: [...allPeriods, ...selectedItems].map(_ref4 => {
129
152
  let {
130
153
  id,
131
154
  name
132
- } = _ref3;
155
+ } = _ref4;
133
156
  return {
134
157
  label: name,
135
158
  value: id
136
159
  };
137
160
  }),
138
- renderOption: props => /*#__PURE__*/React.createElement(TransferOption, _extends({}, props, {
139
- icon: PeriodIcon,
140
- dataTest: `${dataTest}-transfer-option`
141
- })),
161
+ renderOption: _ref5 => {
162
+ let {
163
+ value,
164
+ ...props
165
+ } = _ref5;
166
+ return /*#__PURE__*/React.createElement(TransferOption, _extends({}, props, {
167
+ value: value,
168
+ active: isActive(value),
169
+ icon: PeriodIcon,
170
+ dataTest: `${dataTest}-transfer-option`
171
+ }));
172
+ },
142
173
  dataTest: `${dataTest}-transfer`
143
174
  });
144
175
  };
145
176
  PeriodTransfer.defaultProps = {
146
- initialSelectedPeriods: [],
177
+ selectedItems: [],
147
178
  excludedPeriodTypes: [],
148
179
  periodsSettings: {
149
180
  calendar: 'gregory',
@@ -154,14 +185,16 @@ PeriodTransfer.propTypes = {
154
185
  onSelect: PropTypes.func.isRequired,
155
186
  dataTest: PropTypes.string,
156
187
  excludedPeriodTypes: PropTypes.arrayOf(PropTypes.string),
157
- initialSelectedPeriods: PropTypes.arrayOf(PropTypes.shape({
158
- id: PropTypes.string,
159
- name: PropTypes.string
160
- })),
188
+ infoBoxMessage: PropTypes.string,
161
189
  periodsSettings: PropTypes.shape({
162
190
  calendar: PropTypes.string,
163
191
  locale: PropTypes.string
164
192
  }),
165
- rightFooter: PropTypes.node
193
+ rightFooter: PropTypes.node,
194
+ selectedItems: PropTypes.arrayOf(PropTypes.shape({
195
+ id: PropTypes.string,
196
+ isActive: PropTypes.bool,
197
+ name: PropTypes.string
198
+ }))
166
199
  };
167
200
  export default PeriodTransfer;
@@ -4,7 +4,6 @@ exports[`The Period Dimension component matches the snapshot 1`] = `
4
4
  <PeriodTransfer
5
5
  dataTest="period-dimension"
6
6
  excludedPeriodTypes={Array []}
7
- initialSelectedPeriods={Array []}
8
7
  onSelect={[Function]}
9
8
  periodsSettings={
10
9
  Object {
@@ -13,5 +12,6 @@ exports[`The Period Dimension component matches the snapshot 1`] = `
13
12
  }
14
13
  }
15
14
  rightFooter={<React.Fragment />}
15
+ selectedItems={Array []}
16
16
  />
17
17
  `;
@@ -77,18 +77,7 @@ exports[`The Period Selector component matches the snapshot 1`] = `
77
77
  optionsWidth="420px"
78
78
  renderOption={[Function]}
79
79
  rightFooter={<React.Fragment />}
80
- rightHeader={
81
- <React.Fragment>
82
- <p
83
- className="rightHeader"
84
- >
85
- Selected Periods
86
- </p>
87
- <style>
88
-
89
- </style>
90
- </React.Fragment>
91
- }
80
+ rightHeader={<RightHeader />}
92
81
  selected={Array []}
93
82
  selectedEmptyComponent={
94
83
  <React.Fragment>
@@ -1,7 +1,7 @@
1
- import { IconTable16, IconVisualizationArea16, IconVisualizationAreaStacked16, IconVisualizationBar16, IconVisualizationBarStacked16, IconVisualizationColumn16, IconVisualizationColumnMulti16, IconVisualizationColumnStacked16, IconVisualizationGauge16, IconVisualizationLine16, IconVisualizationLinelist16, IconVisualizationLineMulti16, IconVisualizationPie16, IconVisualizationRadar16, IconVisualizationScatter16, IconVisualizationSingleValue16, IconTable24, IconVisualizationArea24, IconVisualizationAreaStacked24, IconVisualizationBar24, IconVisualizationBarStacked24, IconVisualizationColumn24, IconVisualizationLinelist24, IconVisualizationColumnMulti24, IconVisualizationColumnStacked24, IconVisualizationGauge24, IconVisualizationLine24, IconVisualizationLineMulti24, IconVisualizationPie24, IconVisualizationRadar24, IconVisualizationScatter24, IconVisualizationSingleValue24 } from '@dhis2/ui';
1
+ import { IconVisualizationArea16, IconVisualizationAreaStacked16, IconVisualizationBar16, IconVisualizationBarStacked16, IconVisualizationColumn16, IconVisualizationColumnMulti16, IconVisualizationColumnStacked16, IconVisualizationGauge16, IconVisualizationLine16, IconVisualizationLinelist16, IconVisualizationLineMulti16, IconVisualizationOutlierTable16, IconVisualizationPie16, IconVisualizationPivotTable16, IconVisualizationRadar16, IconVisualizationScatter16, IconVisualizationSingleValue16, IconVisualizationArea24, IconVisualizationAreaStacked24, IconVisualizationBar24, IconVisualizationBarStacked24, IconVisualizationColumn24, IconVisualizationLinelist24, IconVisualizationColumnMulti24, IconVisualizationColumnStacked24, IconVisualizationGauge24, IconVisualizationLine24, IconVisualizationLineMulti24, IconVisualizationOutlierTable24, IconVisualizationPie24, IconVisualizationPivotTable24, IconVisualizationRadar24, IconVisualizationScatter24, IconVisualizationSingleValue24 } from '@dhis2/ui';
2
2
  import PropTypes from 'prop-types';
3
3
  import React from 'react';
4
- import { VIS_TYPE_LINE_LIST, VIS_TYPE_PIVOT_TABLE, VIS_TYPE_COLUMN, VIS_TYPE_STACKED_COLUMN, VIS_TYPE_BAR, VIS_TYPE_STACKED_BAR, VIS_TYPE_LINE, VIS_TYPE_AREA, VIS_TYPE_STACKED_AREA, VIS_TYPE_PIE, VIS_TYPE_RADAR, VIS_TYPE_GAUGE, VIS_TYPE_YEAR_OVER_YEAR_LINE, VIS_TYPE_YEAR_OVER_YEAR_COLUMN, VIS_TYPE_SINGLE_VALUE, VIS_TYPE_SCATTER } from '../modules/visTypes.js';
4
+ import { VIS_TYPE_LINE_LIST, VIS_TYPE_PIVOT_TABLE, VIS_TYPE_COLUMN, VIS_TYPE_STACKED_COLUMN, VIS_TYPE_BAR, VIS_TYPE_STACKED_BAR, VIS_TYPE_LINE, VIS_TYPE_AREA, VIS_TYPE_STACKED_AREA, VIS_TYPE_PIE, VIS_TYPE_RADAR, VIS_TYPE_GAUGE, VIS_TYPE_YEAR_OVER_YEAR_LINE, VIS_TYPE_YEAR_OVER_YEAR_COLUMN, VIS_TYPE_SINGLE_VALUE, VIS_TYPE_SCATTER, VIS_TYPE_OUTLIER_TABLE } from '../modules/visTypes.js';
5
5
  export const VisTypeIcon = _ref => {
6
6
  let {
7
7
  type,
@@ -17,7 +17,7 @@ export const VisTypeIcon = _ref => {
17
17
  }
18
18
  case VIS_TYPE_PIVOT_TABLE:
19
19
  {
20
- VisIcon = useSmall ? IconTable16 : IconTable24;
20
+ VisIcon = useSmall ? IconVisualizationPivotTable16 : IconVisualizationPivotTable24;
21
21
  break;
22
22
  }
23
23
  case VIS_TYPE_BAR:
@@ -85,6 +85,11 @@ export const VisTypeIcon = _ref => {
85
85
  VisIcon = useSmall ? IconVisualizationScatter16 : IconVisualizationScatter24;
86
86
  break;
87
87
  }
88
+ case VIS_TYPE_OUTLIER_TABLE:
89
+ {
90
+ VisIcon = useSmall ? IconVisualizationOutlierTable16 : IconVisualizationOutlierTable24;
91
+ break;
92
+ }
88
93
  case VIS_TYPE_COLUMN:
89
94
  default:
90
95
  {
package/build/es/index.js CHANGED
@@ -97,15 +97,15 @@ export { getLayoutTypeByVisType } from './modules/visTypeToLayoutType.js';
97
97
 
98
98
  // Modules: visTypes
99
99
 
100
- export { VIS_TYPE_GROUP_ALL, VIS_TYPE_GROUP_CHARTS, VIS_TYPE_COLUMN, VIS_TYPE_STACKED_COLUMN, VIS_TYPE_BAR, VIS_TYPE_STACKED_BAR, VIS_TYPE_LINE, VIS_TYPE_AREA, VIS_TYPE_STACKED_AREA, VIS_TYPE_PIE, VIS_TYPE_RADAR, VIS_TYPE_GAUGE, VIS_TYPE_BUBBLE, VIS_TYPE_YEAR_OVER_YEAR_LINE, VIS_TYPE_YEAR_OVER_YEAR_COLUMN, VIS_TYPE_SINGLE_VALUE, VIS_TYPE_PIVOT_TABLE, VIS_TYPE_SCATTER, VIS_TYPE_LINE_LIST, visTypeDisplayNames, visTypeIcons, getDisplayNameByVisType, defaultVisType, isStacked, isMultiType, isYearOverYear, isDualAxisType, isSingleValue, isTwoCategoryChartType, isLegendSetType, isColumnBasedType, isVerticalType } from './modules/visTypes.js';
100
+ export { VIS_TYPE_GROUP_ALL, VIS_TYPE_GROUP_CHARTS, VIS_TYPE_COLUMN, VIS_TYPE_STACKED_COLUMN, VIS_TYPE_BAR, VIS_TYPE_STACKED_BAR, VIS_TYPE_LINE, VIS_TYPE_AREA, VIS_TYPE_STACKED_AREA, VIS_TYPE_PIE, VIS_TYPE_RADAR, VIS_TYPE_GAUGE, VIS_TYPE_BUBBLE, VIS_TYPE_YEAR_OVER_YEAR_LINE, VIS_TYPE_YEAR_OVER_YEAR_COLUMN, VIS_TYPE_SINGLE_VALUE, VIS_TYPE_PIVOT_TABLE, VIS_TYPE_SCATTER, VIS_TYPE_LINE_LIST, VIS_TYPE_OUTLIER_TABLE, visTypeDisplayNames, visTypeIcons, getDisplayNameByVisType, defaultVisType, isStacked, isMultiType, isYearOverYear, isDualAxisType, isSingleValue, isOutlierTable, isTwoCategoryChartType, isLegendSetType, isColumnBasedType, isVerticalType } from './modules/visTypes.js';
101
101
 
102
102
  // Modules: layoutTypes
103
103
 
104
- export { LAYOUT_TYPE_DEFAULT, LAYOUT_TYPE_PIE, LAYOUT_TYPE_SINGLE_VALUE, LAYOUT_TYPE_YEAR_OVER_YEAR, LAYOUT_TYPE_PIVOT_TABLE, LAYOUT_TYPE_SCATTER, LAYOUT_TYPE_LINE_LIST } from './modules/layoutTypes.js';
104
+ export { LAYOUT_TYPE_DEFAULT, LAYOUT_TYPE_PIE, LAYOUT_TYPE_SINGLE_VALUE, LAYOUT_TYPE_YEAR_OVER_YEAR, LAYOUT_TYPE_PIVOT_TABLE, LAYOUT_TYPE_SCATTER, LAYOUT_TYPE_LINE_LIST, LAYOUT_TYPE_OUTLIER_TABLE } from './modules/layoutTypes.js';
105
105
 
106
106
  // Modules: layoutUiRules
107
107
 
108
- export { getAvailableAxes, getDisallowedDimensions, getAxisMaxNumberOfItems, getAxisMaxNumberOfDimensions, getAxisMinNumberOfDimensions, hasAxisTooManyItems, getAxisPerLockedDimension, getAllLockedDimensionIds, canDimensionBeAddedToAxis, isDimensionLocked, isAxisFull, getTransferableDimension } from './modules/layoutUiRules/index.js';
108
+ export { getAvailableAxes, getDisallowedDimensions, getDimensionMaxNumberOfItems, getAxisMaxNumberOfItems, getAxisMaxNumberOfDimensions, getAxisMinNumberOfDimensions, hasAxisTooManyItems, hasDimensionTooManyItems, getAxisPerLockedDimension, getAllLockedDimensionIds, canDimensionBeAddedToAxis, isDimensionLocked, isAxisFull, getTransferableDimension } from './modules/layoutUiRules/index.js';
109
109
 
110
110
  // Visualizations
111
111
 
@@ -131,4 +131,4 @@ export { DAILY, WEEKLY, WEEKLYWED, WEEKLYTHU, WEEKLYSAT, WEEKLYSUN, WEEKS_THIS_Y
131
131
  export { getRelativePeriodsOptionsById } from './components/PeriodDimension/utils/relativePeriods.js';
132
132
  export { getFixedPeriodsOptionsById } from './components/PeriodDimension/utils/fixedPeriods.js';
133
133
  export { default as VisualizationOptions } from './components/Options/VisualizationOptions.js';
134
- export { DIMENSION_TYPE_INDICATOR, DIMENSION_TYPE_DATA_ELEMENT, DIMENSION_TYPE_DATA_SET, DIMENSION_TYPE_EVENT_DATA_ITEM, DIMENSION_TYPE_PROGRAM_INDICATOR, DIMENSION_TYPE_PROGRAM_DATA_ELEMENT, DIMENSION_TYPE_PROGRAM_ATTRIBUTE, DIMENSION_TYPE_DATA_ELEMENT_OPERAND, DIMENSION_TYPE_CATEGORY, DIMENSION_TYPE_CATEGORY_OPTION_GROUP_SET, DIMENSION_TYPE_ALL, DIMENSION_TYPE_DATA, DIMENSION_TYPE_DATA_ELEMENT_GROUP_SET, DIMENSION_TYPE_ORGANISATION_UNIT, DIMENSION_TYPE_PERIOD, DIMENSION_TYPE_ORGANISATION_UNIT_GROUP_SET, DIMENSION_TYPE_EXPRESSION_DIMENSION_ITEM } from './modules/dataTypes.js';
134
+ export { DIMENSION_TYPE_INDICATOR, DIMENSION_TYPE_DATA_ELEMENT, DIMENSION_TYPE_DATA_SET, DIMENSION_TYPE_EVENT_DATA_ITEM, DIMENSION_TYPE_PROGRAM_INDICATOR, DIMENSION_TYPE_PROGRAM_DATA_ELEMENT, DIMENSION_TYPE_PROGRAM_ATTRIBUTE, DIMENSION_TYPE_DATA_ELEMENT_OPERAND, DIMENSION_TYPE_CATEGORY, DIMENSION_TYPE_CATEGORY_OPTION_GROUP_SET, DIMENSION_TYPE_ALL, DIMENSION_TYPE_DATA, DIMENSION_TYPE_DATA_ELEMENT_GROUP_SET, DIMENSION_TYPE_ORGANISATION_UNIT, DIMENSION_TYPE_PERIOD, DIMENSION_TYPE_ORGANISATION_UNIT_GROUP_SET, DIMENSION_TYPE_EXPRESSION_DIMENSION_ITEM, dataTypeMap } from './modules/dataTypes.js';