@dhis2/analytics 29.2.1 → 29.3.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 (31) hide show
  1. package/build/cjs/components/PeriodDimension/FixedPeriodFilter.js +5 -10
  2. package/build/cjs/components/PeriodDimension/FixedPeriodSelect.js +3 -1
  3. package/build/cjs/components/PeriodDimension/PeriodDimension.js +15 -5
  4. package/build/cjs/components/PeriodDimension/PeriodTransfer.js +110 -14
  5. package/build/cjs/components/PeriodDimension/RelativePeriodFilter.js +4 -6
  6. package/build/cjs/components/PeriodDimension/__tests__/PeriodDimension.spec.js +19 -6
  7. package/build/cjs/components/PeriodDimension/__tests__/fixedPeriods.spec.js +1 -1
  8. package/build/cjs/components/PeriodDimension/__tests__/utils.spec.js +1 -1
  9. package/build/cjs/components/PeriodDimension/useDataOutputPeriodTypes.js +153 -0
  10. package/build/cjs/components/PeriodDimension/utils/enabledPeriodTypes.js +179 -0
  11. package/build/cjs/components/PeriodDimension/utils/fixedPeriods.js +24 -42
  12. package/build/cjs/components/PeriodDimension/utils/index.js +7 -4
  13. package/build/cjs/index.js +8 -0
  14. package/build/cjs/locales/en/translations.json +8 -3
  15. package/build/cjs/visualizations/util/getFilterText.js +1 -1
  16. package/build/es/components/PeriodDimension/FixedPeriodFilter.js +5 -10
  17. package/build/es/components/PeriodDimension/FixedPeriodSelect.js +4 -2
  18. package/build/es/components/PeriodDimension/PeriodDimension.js +15 -5
  19. package/build/es/components/PeriodDimension/PeriodTransfer.js +115 -19
  20. package/build/es/components/PeriodDimension/RelativePeriodFilter.js +4 -6
  21. package/build/es/components/PeriodDimension/__tests__/PeriodDimension.spec.js +19 -6
  22. package/build/es/components/PeriodDimension/__tests__/fixedPeriods.spec.js +1 -1
  23. package/build/es/components/PeriodDimension/__tests__/utils.spec.js +1 -1
  24. package/build/es/components/PeriodDimension/useDataOutputPeriodTypes.js +147 -0
  25. package/build/es/components/PeriodDimension/utils/enabledPeriodTypes.js +168 -0
  26. package/build/es/components/PeriodDimension/utils/fixedPeriods.js +25 -43
  27. package/build/es/components/PeriodDimension/utils/index.js +6 -3
  28. package/build/es/index.js +1 -0
  29. package/build/es/locales/en/translations.json +8 -3
  30. package/build/es/visualizations/util/getFilterText.js +1 -1
  31. package/package.json +1 -1
@@ -10,20 +10,16 @@ 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 _PeriodFilterStyle = _interopRequireDefault(require("./styles/PeriodFilter.style.js"));
13
- var _fixedPeriods = require("./utils/fixedPeriods.js");
14
- var _index2 = require("./utils/index.js");
15
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
16
- const EXCLUDED_PERIOD_TYPES_PROP_DEFAULT = [];
17
14
  const FixedPeriodFilter = ({
18
- allowedPeriodTypes,
19
- excludedPeriodTypes = EXCLUDED_PERIOD_TYPES_PROP_DEFAULT,
15
+ availableOptions,
20
16
  currentPeriodType,
21
17
  currentYear,
22
18
  onSelectPeriodType,
23
19
  onSelectYear,
24
20
  dataTest
25
21
  }) => {
26
- const onlyAllowedTypeIsSelected = Array.isArray(allowedPeriodTypes) && allowedPeriodTypes.length === 1 && allowedPeriodTypes[0] === currentPeriodType;
22
+ const onlyAllowedTypeIsSelected = availableOptions.length === 1 && availableOptions[0].id === currentPeriodType;
27
23
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
28
24
  "data-test": dataTest,
29
25
  className: `jsx-${_PeriodFilterStyle.default.__hash}` + " " + "leftSection"
@@ -37,7 +33,7 @@ const FixedPeriodFilter = ({
37
33
  disabled: onlyAllowedTypeIsSelected,
38
34
  className: "filterElement",
39
35
  dataTest: `${dataTest}-period-type`
40
- }, (allowedPeriodTypes ? (0, _fixedPeriods.getFixedPeriodsOptions)().filter(option => allowedPeriodTypes.some(type => type === option.id)) : (0, _index2.filterPeriodTypesById)((0, _fixedPeriods.getFixedPeriodsOptions)(), excludedPeriodTypes)).map(option => /*#__PURE__*/_react.default.createElement(_ui.SingleSelectOption, {
36
+ }, availableOptions.map(option => /*#__PURE__*/_react.default.createElement(_ui.SingleSelectOption, {
41
37
  key: option.id,
42
38
  value: option.id,
43
39
  label: option.name,
@@ -60,12 +56,11 @@ const FixedPeriodFilter = ({
60
56
  }, _PeriodFilterStyle.default));
61
57
  };
62
58
  FixedPeriodFilter.propTypes = {
59
+ availableOptions: _propTypes.default.array.isRequired,
63
60
  currentPeriodType: _propTypes.default.string.isRequired,
64
61
  currentYear: _propTypes.default.string.isRequired,
65
62
  onSelectPeriodType: _propTypes.default.func.isRequired,
66
63
  onSelectYear: _propTypes.default.func.isRequired,
67
- allowedPeriodTypes: _propTypes.default.arrayOf(_propTypes.default.string),
68
- dataTest: _propTypes.default.string,
69
- excludedPeriodTypes: _propTypes.default.arrayOf(_propTypes.default.string)
64
+ dataTest: _propTypes.default.string
70
65
  };
71
66
  var _default = exports.default = FixedPeriodFilter;
@@ -69,13 +69,15 @@ class FixedPeriodSelect extends _react.Component {
69
69
  });
70
70
  }
71
71
  render() {
72
+ const allOptions = (0, _fixedPeriods.getFixedPeriodsOptions)();
73
+ const availableOptions = this.props.allowedPeriodTypes ? allOptions.filter(option => this.props.allowedPeriodTypes.includes(option.id)) : allOptions;
72
74
  return /*#__PURE__*/_react.default.createElement("div", {
73
75
  "data-test": this.props.dataTest,
74
76
  className: `jsx-${_FixedPeriodSelectStyle.default.__hash}` + " " + (this.props.className || "")
75
77
  }, /*#__PURE__*/_react.default.createElement("div", {
76
78
  className: `jsx-${_FixedPeriodSelectStyle.default.__hash}` + " " + "row"
77
79
  }, /*#__PURE__*/_react.default.createElement(_FixedPeriodFilter.default, {
78
- allowedPeriodTypes: this.props.allowedPeriodTypes,
80
+ availableOptions: availableOptions,
79
81
  currentPeriodType: this.state.periodType,
80
82
  currentYear: this.state.year,
81
83
  onSelectPeriodType: this.onSelectPeriodType,
@@ -9,6 +9,8 @@ var _propTypes = _interopRequireDefault(require("prop-types"));
9
9
  var _react = _interopRequireDefault(require("react"));
10
10
  var _predefinedDimensions = require("../../modules/predefinedDimensions.js");
11
11
  var _PeriodTransfer = _interopRequireDefault(require("./PeriodTransfer.js"));
12
+ var _useDataOutputPeriodTypes = require("./useDataOutputPeriodTypes.js");
13
+ var _enabledPeriodTypes = require("./utils/enabledPeriodTypes.js");
12
14
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
15
  const userSettingsQuery = {
14
16
  userSettings: {
@@ -27,10 +29,15 @@ const PeriodDimension = ({
27
29
  infoBoxMessage,
28
30
  height
29
31
  }) => {
32
+ const config = (0, _appRuntime.useConfig)();
30
33
  const {
31
34
  systemInfo
32
- } = (0, _appRuntime.useConfig)();
33
- const result = (0, _appRuntime.useDataQuery)(userSettingsQuery);
35
+ } = config;
36
+ const userSettingsResult = (0, _appRuntime.useDataQuery)(userSettingsQuery);
37
+ const {
38
+ supportsEnabledPeriodTypes,
39
+ enabledPeriodTypesData
40
+ } = (0, _useDataOutputPeriodTypes.useDataOutputPeriodTypes)();
34
41
  const {
35
42
  calendar = 'gregory'
36
43
  } = systemInfo;
@@ -40,7 +47,7 @@ const PeriodDimension = ({
40
47
  keyUiLocale: locale
41
48
  } = {}
42
49
  } = {}
43
- } = result;
50
+ } = userSettingsResult;
44
51
  const periodsSettings = {
45
52
  calendar,
46
53
  locale
@@ -51,15 +58,18 @@ const PeriodDimension = ({
51
58
  items: periods
52
59
  });
53
60
  };
61
+ const selectedPeriodsWithCustomDisplayNames = (0, _enabledPeriodTypes.applyPeriodNameOverrides)(selectedPeriods, enabledPeriodTypesData === null || enabledPeriodTypesData === void 0 ? void 0 : enabledPeriodTypesData.metaData);
54
62
  return /*#__PURE__*/_react.default.createElement(_PeriodTransfer.default, {
55
63
  onSelect: selectPeriods,
56
- selectedItems: selectedPeriods,
64
+ selectedItems: selectedPeriodsWithCustomDisplayNames,
57
65
  infoBoxMessage: infoBoxMessage,
58
66
  rightFooter: rightFooter,
59
67
  dataTest: 'period-dimension',
60
68
  excludedPeriodTypes: excludedPeriodTypes,
61
69
  periodsSettings: periodsSettings,
62
- height: height
70
+ height: height,
71
+ enabledPeriodTypesData: enabledPeriodTypesData,
72
+ supportsEnabledPeriodTypes: supportsEnabledPeriodTypes
63
73
  });
64
74
  };
65
75
  PeriodDimension.propTypes = {
@@ -16,6 +16,7 @@ var _DimensionSelectorStyle = _interopRequireDefault(require("../styles/Dimensio
16
16
  var _TransferOption = require("../TransferOption.js");
17
17
  var _FixedPeriodFilter = _interopRequireDefault(require("./FixedPeriodFilter.js"));
18
18
  var _RelativePeriodFilter = _interopRequireDefault(require("./RelativePeriodFilter.js"));
19
+ var _enabledPeriodTypes = require("./utils/enabledPeriodTypes.js");
19
20
  var _fixedPeriods = require("./utils/fixedPeriods.js");
20
21
  var _index2 = require("./utils/index.js");
21
22
  var _relativePeriods = require("./utils/relativePeriods.js");
@@ -52,10 +53,52 @@ const PeriodTransfer = ({
52
53
  excludedPeriodTypes = EXCLUDED_PERIOD_TYPES_PROP_DEFAULT,
53
54
  periodsSettings = PERIODS_SETTINGS_PROP_DEFAULT,
54
55
  infoBoxMessage,
55
- height = _dimensionSelectorHelper.TRANSFER_HEIGHT
56
+ height = _dimensionSelectorHelper.TRANSFER_HEIGHT,
57
+ enabledPeriodTypesData = null,
58
+ supportsEnabledPeriodTypes = false
56
59
  }) => {
57
- const defaultRelativePeriodType = excludedPeriodTypes.includes(_index2.MONTHLY) ? (0, _relativePeriods.getRelativePeriodsOptionsById)(_index2.QUARTERLY) : (0, _relativePeriods.getRelativePeriodsOptionsById)(_index2.MONTHLY);
58
- const defaultFixedPeriodType = excludedPeriodTypes.includes(_index2.MONTHLY) ? (0, _fixedPeriods.getFixedPeriodsOptionsById)(_index2.QUARTERLY, periodsSettings) : (0, _fixedPeriods.getFixedPeriodsOptionsById)(_index2.MONTHLY, periodsSettings);
60
+ const {
61
+ filteredFixedOptions,
62
+ filteredRelativeOptions
63
+ } = (0, _react.useMemo)(() => {
64
+ if (supportsEnabledPeriodTypes && enabledPeriodTypesData) {
65
+ const {
66
+ enabledTypes,
67
+ financialYearStart,
68
+ financialYearDisplayLabel,
69
+ weeklyDisplayLabel,
70
+ metaData
71
+ } = enabledPeriodTypesData;
72
+ const filteredFixed = (0, _enabledPeriodTypes.applyFixedPeriodTypeDisplayLabels)((0, _enabledPeriodTypes.filterEnabledFixedPeriodTypes)((0, _fixedPeriods.getFixedPeriodsOptions)(periodsSettings), enabledTypes), enabledTypes);
73
+ const filteredRelative = (0, _enabledPeriodTypes.applyDisplayLabelOverrides)((0, _enabledPeriodTypes.filterEnabledRelativePeriodTypes)((0, _relativePeriods.getRelativePeriodsOptions)(), enabledTypes, financialYearStart), {
74
+ financialYearDisplayLabel,
75
+ weeklyDisplayLabel,
76
+ metaData
77
+ });
78
+ return {
79
+ filteredFixedOptions: filteredFixed,
80
+ filteredRelativeOptions: filteredRelative
81
+ };
82
+ } else {
83
+ const allFixed = (0, _fixedPeriods.getFixedPeriodsOptions)(periodsSettings);
84
+ const allRelative = (0, _relativePeriods.getRelativePeriodsOptions)();
85
+ return {
86
+ filteredFixedOptions: (0, _index2.filterPeriodTypesById)(allFixed, excludedPeriodTypes),
87
+ filteredRelativeOptions: (0, _index2.filterPeriodTypesById)(allRelative, excludedPeriodTypes)
88
+ };
89
+ }
90
+ }, [supportsEnabledPeriodTypes, enabledPeriodTypesData, excludedPeriodTypes, periodsSettings]);
91
+ const analysisRelativePeriod = enabledPeriodTypesData === null || enabledPeriodTypesData === void 0 ? void 0 : enabledPeriodTypesData.analysisRelativePeriod;
92
+ const defaultRelativePeriodType = (() => {
93
+ if (analysisRelativePeriod) {
94
+ const match = filteredRelativeOptions.find(opt => opt.getPeriods().some(p => p.id === analysisRelativePeriod));
95
+ if (match) {
96
+ return match;
97
+ }
98
+ }
99
+ return filteredRelativeOptions.find(opt => opt.id === _index2.MONTHLY) || filteredRelativeOptions.find(opt => opt.id === _index2.QUARTERLY) || filteredRelativeOptions[0];
100
+ })();
101
+ const defaultFixedPeriodType = filteredFixedOptions.find(opt => opt.id === _index2.MONTHLY) || filteredFixedOptions.find(opt => opt.id === _index2.QUARTERLY) || filteredFixedOptions[0];
59
102
  const now = (0, _multiCalendarDates.getNowInCalendar)(periodsSettings.calendar);
60
103
  // use ".eraYear" rather than ".year" because in Ethiopian calendar, eraYear is what our users expect to see (for other calendars, it doesn't matter)
61
104
  // there is still a pending decision in Temporal regarding which era to use by default: https://github.com/js-temporal/temporal-polyfill/blob/9350ee7dd0d29f329fc097debf923a517c32f813/lib/calendar.ts#L1964
@@ -65,15 +108,52 @@ const PeriodTransfer = ({
65
108
  filterFuturePeriods: false,
66
109
  reversePeriods: false
67
110
  });
68
- const [allPeriods, setAllPeriods] = (0, _react.useState)(defaultRelativePeriodType.getPeriods());
111
+ const [userPeriods, setUserPeriods] = (0, _react.useState)(null);
69
112
  const [isRelative, setIsRelative] = (0, _react.useState)(true);
70
113
  const [relativeFilter, setRelativeFilter] = (0, _react.useState)({
71
- periodType: defaultRelativePeriodType.id
114
+ periodType: (defaultRelativePeriodType === null || defaultRelativePeriodType === void 0 ? void 0 : defaultRelativePeriodType.id) || ''
72
115
  });
73
116
  const [fixedFilter, setFixedFilter] = (0, _react.useState)({
74
- periodType: defaultFixedPeriodType.id,
117
+ periodType: (defaultFixedPeriodType === null || defaultFixedPeriodType === void 0 ? void 0 : defaultFixedPeriodType.id) || '',
75
118
  year: defaultFixedPeriodYear.toString()
76
119
  });
120
+ const effectiveRelativeFilterType = filteredRelativeOptions.some(opt => opt.id === relativeFilter.periodType) ? relativeFilter.periodType : (defaultRelativePeriodType === null || defaultRelativePeriodType === void 0 ? void 0 : defaultRelativePeriodType.id) || '';
121
+ const effectiveFixedFilterType = filteredFixedOptions.some(opt => opt.id === fixedFilter.periodType) ? fixedFilter.periodType : (defaultFixedPeriodType === null || defaultFixedPeriodType === void 0 ? void 0 : defaultFixedPeriodType.id) || '';
122
+ const prevEffectiveRelativeRef = (0, _react.useRef)(effectiveRelativeFilterType);
123
+ const prevEffectiveFixedRef = (0, _react.useRef)(effectiveFixedFilterType);
124
+ if (prevEffectiveRelativeRef.current !== effectiveRelativeFilterType) {
125
+ prevEffectiveRelativeRef.current = effectiveRelativeFilterType;
126
+ if (relativeFilter.periodType !== effectiveRelativeFilterType) {
127
+ setRelativeFilter({
128
+ periodType: effectiveRelativeFilterType
129
+ });
130
+ }
131
+ if (isRelative) {
132
+ setUserPeriods(null);
133
+ }
134
+ }
135
+ if (prevEffectiveFixedRef.current !== effectiveFixedFilterType) {
136
+ prevEffectiveFixedRef.current = effectiveFixedFilterType;
137
+ if (fixedFilter.periodType !== effectiveFixedFilterType) {
138
+ setFixedFilter(prev => ({
139
+ ...prev,
140
+ periodType: effectiveFixedFilterType
141
+ }));
142
+ }
143
+ if (!isRelative) {
144
+ setUserPeriods(null);
145
+ }
146
+ }
147
+ const derivedPeriods = (0, _react.useMemo)(() => {
148
+ if (isRelative) {
149
+ const opt = filteredRelativeOptions.find(o => o.id === effectiveRelativeFilterType);
150
+ return (opt === null || opt === void 0 ? void 0 : opt.getPeriods()) || [];
151
+ } else {
152
+ const opt = filteredFixedOptions.find(o => o.id === effectiveFixedFilterType);
153
+ return (opt === null || opt === void 0 ? void 0 : opt.getPeriods(fixedPeriodConfig(Number(fixedFilter.year)))) || [];
154
+ }
155
+ }, [isRelative, effectiveRelativeFilterType, effectiveFixedFilterType, filteredRelativeOptions, filteredFixedOptions, fixedFilter.year]);
156
+ const allPeriods = userPeriods !== null && userPeriods !== void 0 ? userPeriods : derivedPeriods;
77
157
  const isActive = value => {
78
158
  const item = selectedItems.find(item => item.id === value);
79
159
  return !item || item.isActive;
@@ -81,9 +161,15 @@ const PeriodTransfer = ({
81
161
  const onIsRelativeClick = state => {
82
162
  if (state !== isRelative) {
83
163
  setIsRelative(state);
84
- setAllPeriods(state ? (0, _relativePeriods.getRelativePeriodsOptionsById)(relativeFilter.periodType).getPeriods() : (0, _fixedPeriods.getFixedPeriodsOptionsById)(fixedFilter.periodType, periodsSettings).getPeriods(fixedPeriodConfig(Number(fixedFilter.year))));
164
+ setUserPeriods(null);
85
165
  }
86
166
  };
167
+ if (enabledPeriodTypesData !== null && enabledPeriodTypesData !== void 0 && enabledPeriodTypesData.noEnabledTypes) {
168
+ return /*#__PURE__*/_react.default.createElement(_ui.NoticeBox, {
169
+ warning: true,
170
+ title: _index.default.t('No period types available')
171
+ }, _index.default.t('No period types are enabled in the system. Please contact your system administrator.'));
172
+ }
87
173
  const renderLeftHeader = () => /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_ui.TabBar, null, /*#__PURE__*/_react.default.createElement(_ui.Tab, {
88
174
  selected: isRelative,
89
175
  onClick: () => onIsRelativeClick(true),
@@ -95,17 +181,18 @@ const PeriodTransfer = ({
95
181
  }, _index.default.t('Fixed periods'))), /*#__PURE__*/_react.default.createElement("div", {
96
182
  className: `jsx-${_DimensionSelectorStyle.default.__hash}` + " " + "filterContainer"
97
183
  }, isRelative ? /*#__PURE__*/_react.default.createElement(_RelativePeriodFilter.default, {
98
- currentFilter: relativeFilter.periodType,
184
+ currentFilter: effectiveRelativeFilterType,
99
185
  onSelectFilter: filter => {
100
186
  setRelativeFilter({
101
187
  periodType: filter
102
188
  });
103
- setAllPeriods((0, _relativePeriods.getRelativePeriodsOptionsById)(filter).getPeriods());
189
+ const selectedOption = filteredRelativeOptions.find(opt => opt.id === filter);
190
+ setUserPeriods((selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.getPeriods()) || []);
104
191
  },
105
192
  dataTest: `${dataTest}-relative-period-filter`,
106
- excludedPeriodTypes: excludedPeriodTypes
193
+ availableOptions: filteredRelativeOptions
107
194
  }) : /*#__PURE__*/_react.default.createElement(_FixedPeriodFilter.default, {
108
- currentPeriodType: fixedFilter.periodType,
195
+ currentPeriodType: effectiveFixedFilterType,
109
196
  currentYear: fixedFilter.year,
110
197
  onSelectPeriodType: periodType => {
111
198
  onSelectFixedPeriods({
@@ -120,14 +207,15 @@ const PeriodTransfer = ({
120
207
  });
121
208
  },
122
209
  dataTest: `${dataTest}-fixed-period-filter`,
123
- excludedPeriodTypes: excludedPeriodTypes
210
+ availableOptions: filteredFixedOptions
124
211
  })), /*#__PURE__*/_react.default.createElement(_style.default, {
125
212
  id: _DimensionSelectorStyle.default.__hash
126
213
  }, _DimensionSelectorStyle.default));
127
214
  const onSelectFixedPeriods = filter => {
128
215
  setFixedFilter(filter);
129
216
  if (filter.year.match(/[0-9]{4}/)) {
130
- setAllPeriods((0, _fixedPeriods.getFixedPeriodsOptionsById)(filter.periodType, periodsSettings).getPeriods(fixedPeriodConfig(Number(filter.year)), periodsSettings));
217
+ const selectedOption = filteredFixedOptions.find(opt => opt.id === filter.periodType);
218
+ setUserPeriods((selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.getPeriods(fixedPeriodConfig(Number(filter.year)))) || []);
131
219
  }
132
220
  };
133
221
  const renderEmptySelection = () => /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("p", {
@@ -182,6 +270,13 @@ const PeriodTransfer = ({
182
270
  PeriodTransfer.propTypes = {
183
271
  onSelect: _propTypes.default.func.isRequired,
184
272
  dataTest: _propTypes.default.string,
273
+ enabledPeriodTypesData: _propTypes.default.shape({
274
+ analysisRelativePeriod: _propTypes.default.string,
275
+ enabledTypes: _propTypes.default.array,
276
+ financialYearDisplayLabel: _propTypes.default.string,
277
+ financialYearStart: _propTypes.default.string,
278
+ noEnabledTypes: _propTypes.default.bool
279
+ }),
185
280
  excludedPeriodTypes: _propTypes.default.arrayOf(_propTypes.default.string),
186
281
  height: _propTypes.default.string,
187
282
  infoBoxMessage: _propTypes.default.string,
@@ -194,6 +289,7 @@ PeriodTransfer.propTypes = {
194
289
  id: _propTypes.default.string,
195
290
  isActive: _propTypes.default.bool,
196
291
  name: _propTypes.default.string
197
- }))
292
+ })),
293
+ supportsEnabledPeriodTypes: _propTypes.default.bool
198
294
  };
199
295
  var _default = exports.default = PeriodTransfer;
@@ -10,14 +10,12 @@ 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 _PeriodFilterStyle = _interopRequireDefault(require("./styles/PeriodFilter.style.js"));
13
- var _index2 = require("./utils/index.js");
14
- var _relativePeriods = require("./utils/relativePeriods.js");
15
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
16
14
  const RelativePeriodFilter = ({
17
15
  currentFilter,
18
16
  onSelectFilter,
19
17
  dataTest,
20
- excludedPeriodTypes
18
+ availableOptions
21
19
  }) => /*#__PURE__*/_react.default.createElement("div", {
22
20
  "data-test": dataTest,
23
21
  className: `jsx-${_PeriodFilterStyle.default.__hash}` + " " + "leftSection"
@@ -30,7 +28,7 @@ const RelativePeriodFilter = ({
30
28
  selected: currentFilter,
31
29
  className: "filterElement",
32
30
  dataTest: `${dataTest}-period-type`
33
- }, (0, _index2.filterPeriodTypesById)((0, _relativePeriods.getRelativePeriodsOptions)(), excludedPeriodTypes).map(option => /*#__PURE__*/_react.default.createElement(_ui.SingleSelectOption, {
31
+ }, availableOptions.map(option => /*#__PURE__*/_react.default.createElement(_ui.SingleSelectOption, {
34
32
  key: option.id,
35
33
  value: option.id,
36
34
  label: option.name,
@@ -39,9 +37,9 @@ const RelativePeriodFilter = ({
39
37
  id: _PeriodFilterStyle.default.__hash
40
38
  }, _PeriodFilterStyle.default));
41
39
  RelativePeriodFilter.propTypes = {
40
+ availableOptions: _propTypes.default.array.isRequired,
42
41
  currentFilter: _propTypes.default.string.isRequired,
43
42
  onSelectFilter: _propTypes.default.func.isRequired,
44
- dataTest: _propTypes.default.string,
45
- excludedPeriodTypes: _propTypes.default.arrayOf(_propTypes.default.string)
43
+ dataTest: _propTypes.default.string
46
44
  };
47
45
  var _default = exports.default = RelativePeriodFilter;
@@ -7,14 +7,27 @@ var _PeriodDimension = _interopRequireDefault(require("../PeriodDimension.js"));
7
7
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
8
8
  jest.mock('@dhis2/app-runtime', () => ({
9
9
  useConfig: () => ({
10
- systemInfo: {}
10
+ systemInfo: {},
11
+ serverVersion: {
12
+ minor: 42
13
+ }
11
14
  }),
12
- useDataQuery: () => ({
13
- data: {
14
- userSettings: {
15
- keyUiLocale: 'en'
16
- }
15
+ useDataQuery: jest.fn().mockImplementation((_query, options) => {
16
+ if (options !== null && options !== void 0 && options.lazy) {
17
+ return {
18
+ data: null,
19
+ error: undefined,
20
+ loading: false,
21
+ refetch: jest.fn()
22
+ };
17
23
  }
24
+ return {
25
+ data: {
26
+ userSettings: {
27
+ keyUiLocale: 'en'
28
+ }
29
+ }
30
+ };
18
31
  })
19
32
  }));
20
33
  global.ResizeObserver = jest.fn().mockImplementation(() => ({
@@ -8,7 +8,7 @@ describe('fixedPeriods utils', () => {
8
8
  describe('getOptions', () => {
9
9
  it('should return a list of available period ranges', () => {
10
10
  const periodIds = (0, _fixedPeriods.getFixedPeriodsOptions)().map(option => option.id);
11
- expect(periodIds).toEqual(['DAILY', 'WEEKLY', 'WEEKLYWED', 'WEEKLYTHU', 'WEEKLYSAT', 'WEEKLYSUN', 'BIWEEKLY', 'MONTHLY', 'BIMONTHLY', 'QUARTERLY', 'SIXMONTHLY', 'SIXMONTHLYAPR', 'YEARLY', 'FYNOV', 'FYOCT', 'FYJUL', 'FYAPR']);
11
+ expect(periodIds).toEqual(['DAILY', 'WEEKLY', 'WEEKLYWED', 'WEEKLYTHU', 'WEEKLYSAT', 'WEEKLYSUN', 'BIWEEKLY', 'MONTHLY', 'BIMONTHLY', 'QUARTERLY', 'SIXMONTHLY', 'SIXMONTHLYAPR', 'YEARLY', 'FYFEB', 'FYAPR', 'FYJUL', 'FYAUG', 'FYSEP', 'FYOCT', 'FYNOV']);
12
12
  });
13
13
  });
14
14
  describe('Daily period generator', () => {
@@ -8,7 +8,7 @@ describe('utils', () => {
8
8
  it('should filter fixed periods', () => {
9
9
  const excludedPeriodTypes = ['DAILY', 'WEEKLY', 'WEEKLYSAT', 'MONTHLY', 'FYOCT'];
10
10
  const periodIds = (0, _index.filterPeriodTypesById)((0, _fixedPeriods.getFixedPeriodsOptions)(), excludedPeriodTypes).map(option => option.id);
11
- expect(periodIds).toEqual(['WEEKLYWED', 'WEEKLYTHU', 'WEEKLYSUN', 'BIWEEKLY', 'BIMONTHLY', 'QUARTERLY', 'SIXMONTHLY', 'SIXMONTHLYAPR', 'YEARLY', 'FYNOV', 'FYJUL', 'FYAPR']);
11
+ expect(periodIds).toEqual(['WEEKLYWED', 'WEEKLYTHU', 'WEEKLYSUN', 'BIWEEKLY', 'BIMONTHLY', 'QUARTERLY', 'SIXMONTHLY', 'SIXMONTHLYAPR', 'YEARLY', 'FYFEB', 'FYAPR', 'FYJUL', 'FYAUG', 'FYSEP', 'FYNOV']);
12
12
  });
13
13
  it('should filter relative periods', () => {
14
14
  const excludedPeriodTypes = ['MONTHLY', 'BIMONTHLY'];
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useDataOutputPeriodTypes = void 0;
7
+ var _appRuntime = require("@dhis2/app-runtime");
8
+ var _react = require("react");
9
+ const v43Query = {
10
+ enabledPeriodTypes: {
11
+ resource: 'configuration/dataOutputPeriodTypes'
12
+ },
13
+ // v43-only: analyticsFinancialYearStart is removed in v44
14
+ financialYearStart: {
15
+ resource: 'systemSettings/analyticsFinancialYearStart'
16
+ },
17
+ analysisRelativePeriod: {
18
+ resource: 'systemSettings/keyAnalysisRelativePeriod'
19
+ },
20
+ // v43-only: analyticsWeeklyStart is removed in v44
21
+ weeklyStart: {
22
+ resource: 'systemSettings/analyticsWeeklyStart'
23
+ }
24
+ };
25
+
26
+ // v43-only: analyticsFinancialYearStart is removed in v44
27
+ const FY_SETTING_TO_SERVER_PT = {
28
+ FINANCIAL_YEAR_APRIL: 'FinancialApril',
29
+ FINANCIAL_YEAR_JULY: 'FinancialJuly',
30
+ FINANCIAL_YEAR_SEPTEMBER: 'FinancialSep',
31
+ FINANCIAL_YEAR_OCTOBER: 'FinancialOct',
32
+ FINANCIAL_YEAR_NOVEMBER: 'FinancialNov'
33
+ };
34
+
35
+ // v43-only: analyticsWeeklyStart is removed in v44
36
+ const WEEKLY_START_TO_SERVER_PT = {
37
+ WEEKLY: 'Weekly',
38
+ WEEKLY_WEDNESDAY: 'WeeklyWednesday',
39
+ WEEKLY_THURSDAY: 'WeeklyThursday',
40
+ WEEKLY_FRIDAY: 'WeeklyFriday',
41
+ WEEKLY_SATURDAY: 'WeeklySaturday',
42
+ WEEKLY_SUNDAY: 'WeeklySunday'
43
+ };
44
+ const useDataOutputPeriodTypes = () => {
45
+ const {
46
+ serverVersion
47
+ } = (0, _appRuntime.useConfig)();
48
+ const supportsEnabledPeriodTypes = serverVersion.minor >= 43;
49
+ const {
50
+ data: v43Data,
51
+ error: v43Error,
52
+ refetch: v43Refetch
53
+ } = (0, _appRuntime.useDataQuery)(v43Query, {
54
+ lazy: true
55
+ });
56
+ (0, _react.useEffect)(() => {
57
+ if (supportsEnabledPeriodTypes) {
58
+ v43Refetch();
59
+ }
60
+ }, [supportsEnabledPeriodTypes, v43Refetch]);
61
+ const enabledPeriodTypesData = (0, _react.useMemo)(() => {
62
+ var _v43Data$financialYea, _v43Data$weeklyStart, _v43Data$analysisRela;
63
+ if (!supportsEnabledPeriodTypes) {
64
+ return null;
65
+ }
66
+ if (v43Error || !(v43Data !== null && v43Data !== void 0 && v43Data.enabledPeriodTypes)) {
67
+ return null;
68
+ }
69
+ const enabledTypes = v43Data.enabledPeriodTypes;
70
+ if (!enabledTypes || enabledTypes.length === 0) {
71
+ return {
72
+ enabledTypes: [],
73
+ financialYearStart: null,
74
+ analysisRelativePeriod: null,
75
+ noEnabledTypes: true
76
+ };
77
+ }
78
+
79
+ // v43-only: financial year logic goes away in v44
80
+ let financialYearStart = null;
81
+ let financialYearDisplayLabel = null;
82
+ if ((_v43Data$financialYea = v43Data.financialYearStart) !== null && _v43Data$financialYea !== void 0 && _v43Data$financialYea.analyticsFinancialYearStart) {
83
+ const fyStartValue = v43Data.financialYearStart.analyticsFinancialYearStart;
84
+ const mappedFyPt = FY_SETTING_TO_SERVER_PT[fyStartValue];
85
+ const matchingPt = enabledTypes.find(pt => pt.name === mappedFyPt);
86
+ if (matchingPt) {
87
+ financialYearStart = fyStartValue;
88
+ if (matchingPt.displayLabel) {
89
+ financialYearDisplayLabel = matchingPt.displayLabel;
90
+ }
91
+ }
92
+ }
93
+
94
+ // v43-only: weekly start logic goes away in v44
95
+ let weeklyDisplayLabel = null;
96
+ if ((_v43Data$weeklyStart = v43Data.weeklyStart) !== null && _v43Data$weeklyStart !== void 0 && _v43Data$weeklyStart.analyticsWeeklyStart) {
97
+ const weeklyStartValue = v43Data.weeklyStart.analyticsWeeklyStart;
98
+ const mappedWeeklyPt = WEEKLY_START_TO_SERVER_PT[weeklyStartValue];
99
+ const matchingWeeklyPt = enabledTypes.find(pt => pt.name === mappedWeeklyPt);
100
+ if (matchingWeeklyPt !== null && matchingWeeklyPt !== void 0 && matchingWeeklyPt.displayLabel) {
101
+ weeklyDisplayLabel = matchingWeeklyPt.displayLabel;
102
+ }
103
+ }
104
+ const analysisRelativePeriod = ((_v43Data$analysisRela = v43Data.analysisRelativePeriod) === null || _v43Data$analysisRela === void 0 ? void 0 : _v43Data$analysisRela.keyAnalysisRelativePeriod) || null;
105
+ const metaData = {
106
+ ...(financialYearDisplayLabel && {
107
+ THIS_FINANCIAL_YEAR: {
108
+ name: `This ${financialYearDisplayLabel}`
109
+ },
110
+ LAST_FINANCIAL_YEAR: {
111
+ name: `Last ${financialYearDisplayLabel}`
112
+ },
113
+ LAST_5_FINANCIAL_YEARS: {
114
+ name: `Last 5 ${financialYearDisplayLabel}`
115
+ }
116
+ }),
117
+ ...(weeklyDisplayLabel && {
118
+ THIS_WEEK: {
119
+ name: `This ${weeklyDisplayLabel}`
120
+ },
121
+ LAST_WEEK: {
122
+ name: `Last ${weeklyDisplayLabel}`
123
+ },
124
+ LAST_4_WEEKS: {
125
+ name: `Last 4 ${weeklyDisplayLabel}`
126
+ },
127
+ LAST_12_WEEKS: {
128
+ name: `Last 12 ${weeklyDisplayLabel}`
129
+ },
130
+ LAST_52_WEEKS: {
131
+ name: `Last 52 ${weeklyDisplayLabel}`
132
+ },
133
+ WEEKS_THIS_YEAR: {
134
+ name: `${weeklyDisplayLabel} this year`
135
+ }
136
+ })
137
+ };
138
+ return {
139
+ enabledTypes,
140
+ financialYearStart,
141
+ financialYearDisplayLabel,
142
+ weeklyDisplayLabel,
143
+ analysisRelativePeriod,
144
+ metaData,
145
+ noEnabledTypes: false
146
+ };
147
+ }, [supportsEnabledPeriodTypes, v43Data, v43Error]);
148
+ return {
149
+ supportsEnabledPeriodTypes,
150
+ enabledPeriodTypesData
151
+ };
152
+ };
153
+ exports.useDataOutputPeriodTypes = useDataOutputPeriodTypes;