@dhis2/analytics 20.7.0 → 21.0.0-alpha.4

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 (42) hide show
  1. package/build/cjs/__demo__/OrgUnitDimension.stories.js +104 -0
  2. package/build/cjs/api/organisationUnits.js +100 -46
  3. package/build/cjs/components/FileMenu/DeleteDialog.js +2 -2
  4. package/build/cjs/components/FileMenu/FileMenu.js +2 -2
  5. package/build/cjs/components/FileMenu/GetLinkDialog.js +2 -2
  6. package/build/cjs/components/FileMenu/RenameDialog.js +2 -2
  7. package/build/cjs/components/FileMenu/SaveAsDialog.js +2 -2
  8. package/build/cjs/components/OrgUnitDimension/OrgUnitDimension.js +223 -193
  9. package/build/cjs/components/OrgUnitDimension/styles/OrgUnitDimension.style.js +5 -2
  10. package/build/cjs/components/PeriodDimension/FixedPeriodSelect.js +2 -2
  11. package/build/cjs/components/TransferOption.js +2 -2
  12. package/build/cjs/index.js +22 -4
  13. package/build/cjs/locales/en/translations.json +14 -0
  14. package/build/cjs/modules/list.js +25 -0
  15. package/build/cjs/modules/ouIdHelper/index.js +7 -1
  16. package/build/cjs/modules/relativeItems/index.js +1 -1
  17. package/build/cjs/visualizations/util/__tests__/getFilterText.spec.js +1 -1
  18. package/build/cjs/visualizations/util/getFilterText.js +1 -9
  19. package/build/es/__demo__/OrgUnitDimension.stories.js +93 -0
  20. package/build/es/api/organisationUnits.js +93 -43
  21. package/build/es/components/FileMenu/DeleteDialog.js +1 -1
  22. package/build/es/components/FileMenu/FileMenu.js +1 -1
  23. package/build/es/components/FileMenu/GetLinkDialog.js +1 -1
  24. package/build/es/components/FileMenu/RenameDialog.js +1 -1
  25. package/build/es/components/FileMenu/SaveAsDialog.js +1 -1
  26. package/build/es/components/OrgUnitDimension/OrgUnitDimension.js +224 -196
  27. package/build/es/components/OrgUnitDimension/styles/OrgUnitDimension.style.js +3 -2
  28. package/build/es/components/PeriodDimension/FixedPeriodSelect.js +6 -6
  29. package/build/es/components/TransferOption.js +12 -12
  30. package/build/es/index.js +2 -2
  31. package/build/es/locales/en/translations.json +14 -0
  32. package/build/es/modules/list.js +13 -0
  33. package/build/es/modules/ouIdHelper/index.js +3 -0
  34. package/build/es/modules/relativeItems/index.js +2 -2
  35. package/build/es/visualizations/util/__tests__/getFilterText.spec.js +1 -1
  36. package/build/es/visualizations/util/getFilterText.js +2 -10
  37. package/package.json +3 -2
  38. package/CHANGELOG.md +0 -2763
  39. package/build/cjs/api/organisationUnits-dataEngine.js +0 -119
  40. package/build/cjs/components/OrgUnitDimension/__tests__/OrgUnitDimension.spec.js +0 -96
  41. package/build/es/api/organisationUnits-dataEngine.js +0 -96
  42. package/build/es/components/OrgUnitDimension/__tests__/OrgUnitDimension.spec.js +0 -86
@@ -1,220 +1,248 @@
1
1
  import _JSXStyle from "styled-jsx/style";
2
-
3
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
4
-
5
- import { OrgUnitSelector, userOrgUnits } from '@dhis2/d2-ui-org-unit-dialog';
6
- import { CircularLoader, colors } from '@dhis2/ui';
7
- import sortBy from 'lodash/sortBy';
2
+ import { useDataEngine } from '@dhis2/app-runtime';
3
+ import { OrganisationUnitTree, Checkbox, MultiSelect, MultiSelectOption, Button } from '@dhis2/ui';
4
+ import cx from 'classnames';
8
5
  import PropTypes from 'prop-types';
9
- import React, { Component, Fragment } from 'react';
10
- import { apiFetchOrganisationUnitGroups, apiFetchOrganisationUnitLevels, apiFetchOrganisationUnits } from '../../api/organisationUnits';
11
- import { ouIdHelper } from '../../modules/ouIdHelper';
6
+ import React, { useEffect, useState } from 'react';
7
+ import { apiFetchOrganisationUnitGroups, apiFetchOrganisationUnitLevels } from '../../api/organisationUnits';
8
+ import i18n from '../../locales/index.js';
9
+ import { formatList } from '../../modules/list';
10
+ import { ouIdHelper, USER_ORG_UNIT, USER_ORG_UNIT_CHILDREN, USER_ORG_UNIT_GRANDCHILDREN } from '../../modules/ouIdHelper';
12
11
  import { DIMENSION_ID_ORGUNIT } from '../../modules/predefinedDimensions';
13
12
  import styles from './styles/OrgUnitDimension.style';
14
- export const defaultState = {
15
- root: undefined,
16
- roots: undefined,
17
- // use "selected" property for cloning org units while user org unit(s) is (are) selected
18
- selected: [],
19
- ouLevels: [],
20
- ouGroups: [],
21
- showOrgUnitsTree: true
22
- };
23
-
24
- class OrgUnitDimension extends Component {
25
- constructor(props) {
26
- super(props);
27
-
28
- _defineProperty(this, "showOrgUnitsTree", () => {
29
- this.setState({
30
- showOrgUnitsTree: true
31
- });
32
- });
33
-
34
- _defineProperty(this, "hideOrgUnitsTree", () => {
35
- this.setState({
36
- showOrgUnitsTree: false
37
- });
38
- });
39
-
40
- _defineProperty(this, "getUserOrgUnitsFromIds", ids => {
41
- return userOrgUnits.filter(ou => ids.includes(ou.id));
42
- });
43
-
44
- _defineProperty(this, "onLevelChange", event => {
45
- const levelIds = event.target.value.filter(id => !!id);
46
- this.props.onSelect({
47
- dimensionId: DIMENSION_ID_ORGUNIT,
48
- items: [...this.props.ouItems.filter(ou => !ouIdHelper.hasLevelPrefix(ou.id)), ...levelIds.map(id => {
49
- const levelOu = this.state.ouLevels.find(ou => ou.id === id);
50
- return { ...levelOu,
51
- id: ouIdHelper.addLevelPrefix(levelOu.id)
52
- };
53
- })]
13
+ const DYNAMIC_ORG_UNITS = [USER_ORG_UNIT, USER_ORG_UNIT_CHILDREN, USER_ORG_UNIT_GRANDCHILDREN];
14
+
15
+ const OrgUnitDimension = ({
16
+ roots,
17
+ selected,
18
+ onSelect
19
+ }) => {
20
+ const [ouLevels, setOuLevels] = useState([]);
21
+ const [ouGroups, setOuGroups] = useState([]);
22
+ const dataEngine = useDataEngine();
23
+
24
+ const onSelectItems = selectedItem => {
25
+ const {
26
+ id,
27
+ checked,
28
+ displayName,
29
+ path
30
+ } = selectedItem;
31
+ let result = [...selected];
32
+
33
+ if (checked && DYNAMIC_ORG_UNITS.includes(id)) {
34
+ result = [...result.filter(item => DYNAMIC_ORG_UNITS.includes(item.id) || ouIdHelper.hasLevelPrefix(item.id) || ouIdHelper.hasGroupPrefix(item.id)), {
35
+ id,
36
+ displayName
37
+ }];
38
+ } else if (checked) {
39
+ result.push({
40
+ id,
41
+ path,
42
+ name: displayName
54
43
  });
55
- });
56
-
57
- _defineProperty(this, "onGroupChange", event => {
58
- const groupIds = event.target.value.filter(id => !!id);
59
- this.props.onSelect({
60
- dimensionId: DIMENSION_ID_ORGUNIT,
61
- items: [...this.props.ouItems.filter(ou => !ouIdHelper.hasGroupPrefix(ou.id)), ...groupIds.map(id => {
62
- const groupOu = this.state.ouGroups.find(ou => ou.id === id);
63
- return { ...groupOu,
64
- id: ouIdHelper.addGroupPrefix(id)
65
- };
66
- })]
67
- });
68
- });
44
+ } else {
45
+ result = [...result.filter(item => item.id !== id)];
46
+ }
69
47
 
70
- _defineProperty(this, "onDeselectAllClick", () => this.props.onDeselect({
48
+ onSelect({
71
49
  dimensionId: DIMENSION_ID_ORGUNIT,
72
- itemIdsToRemove: this.props.ouItems.map(ou => ou.id)
73
- }));
74
-
75
- _defineProperty(this, "loadOrgUnitTree", (d2, displayNameProperty) => {
76
- apiFetchOrganisationUnits(d2, displayNameProperty).then(rootLevel => rootLevel.toArray()).then(roots => {
77
- this.setState({
78
- roots,
79
- root: roots[0]
80
- });
81
- });
50
+ items: result
82
51
  });
83
-
84
- _defineProperty(this, "loadOrgUnitGroups", (d2, displayNameProperty) => {
85
- apiFetchOrganisationUnitGroups(d2, displayNameProperty).then(organisationUnitGroups => this.setState({
86
- ouGroups: organisationUnitGroups
87
- }));
52
+ };
53
+
54
+ const clearSelection = () => onSelect({
55
+ dimensionId: DIMENSION_ID_ORGUNIT,
56
+ items: []
57
+ });
58
+
59
+ useEffect(() => {
60
+ const doFetchOuLevels = async () => {
61
+ const result = await apiFetchOrganisationUnitLevels(dataEngine);
62
+ result.sort((a, b) => a.level > b.level ? 1 : -1);
63
+ setOuLevels(result);
64
+ };
65
+
66
+ const doFetchOuGroups = async () => {
67
+ const result = await apiFetchOrganisationUnitGroups(dataEngine);
68
+ setOuGroups(result);
69
+ };
70
+
71
+ doFetchOuLevels();
72
+ doFetchOuGroups();
73
+ }, [dataEngine]);
74
+
75
+ const onLevelChange = ids => {
76
+ const items = ids.map(id => ({
77
+ id: ouIdHelper.addLevelPrefix(id),
78
+ name: ouLevels.find(level => level.id === id).displayName
79
+ }));
80
+ onSelect({
81
+ dimensionId: DIMENSION_ID_ORGUNIT,
82
+ items: [...selected.filter(ou => !ouIdHelper.hasLevelPrefix(ou.id)), ...items]
88
83
  });
84
+ };
89
85
 
90
- _defineProperty(this, "loadOrgUnitLevels", d2 => {
91
- apiFetchOrganisationUnitLevels(d2).then(organisationUnitLevels => this.setState({
92
- ouLevels: sortBy(organisationUnitLevels, ['level'])
93
- }));
86
+ const onGroupChange = ids => {
87
+ const items = ids.map(id => ({
88
+ id: ouIdHelper.addGroupPrefix(id),
89
+ name: ouGroups.find(group => group.id === id).displayName
90
+ }));
91
+ onSelect({
92
+ dimensionId: DIMENSION_ID_ORGUNIT,
93
+ items: [...selected.filter(ou => !ouIdHelper.hasGroupPrefix(ou.id)), ...items]
94
94
  });
95
+ };
96
+
97
+ const getSummary = () => {
98
+ let summary;
99
+
100
+ if (selected.length) {
101
+ const numberOfOrgUnits = selected.filter(item => !DYNAMIC_ORG_UNITS.includes(item.id) && !ouIdHelper.hasLevelPrefix(item.id) && !ouIdHelper.hasGroupPrefix(item.id)).length;
102
+ const numberOfLevels = selected.filter(item => ouIdHelper.hasLevelPrefix(item.id)).length;
103
+ const numberOfGroups = selected.filter(item => ouIdHelper.hasGroupPrefix(item.id)).length;
104
+ const userOrgUnits = selected.filter(item => DYNAMIC_ORG_UNITS.includes(item.id));
105
+ const parts = [];
106
+
107
+ if (numberOfOrgUnits) {
108
+ parts.push(i18n.t('{{count}} org units', {
109
+ count: numberOfOrgUnits,
110
+ defaultValue: '{{count}} org unit',
111
+ defaultValue_plural: '{{count}} org units'
112
+ }));
113
+ }
95
114
 
96
- _defineProperty(this, "handleOrgUnitClick", (event, orgUnit) => {
97
- const selected = this.props.ouItems;
98
-
99
- if (selected.some(ou => ou.path === orgUnit.path)) {
100
- this.props.onDeselect({
101
- dimensionId: DIMENSION_ID_ORGUNIT,
102
- itemIdsToRemove: [orgUnit.id]
103
- });
104
- } else {
105
- this.props.onSelect({
106
- dimensionId: DIMENSION_ID_ORGUNIT,
107
- items: [...selected, { ...orgUnit,
108
- name: orgUnit.name || orgUnit.displayName
109
- }]
110
- });
115
+ if (numberOfLevels) {
116
+ parts.push(i18n.t('{{count}} levels', {
117
+ count: numberOfLevels,
118
+ defaultValue: '{{count}} level',
119
+ defaultValue_plural: '{{count}} levels'
120
+ }));
111
121
  }
112
- });
113
122
 
114
- _defineProperty(this, "handleUserOrgUnitClick", (event, checked) => {
115
- if (checked) {
116
- if (!this.state.selected.length) {
117
- this.setState({
118
- selected: this.props.ouItems.slice()
119
- });
120
- }
121
-
122
- this.props.onSelect({
123
- dimensionId: DIMENSION_ID_ORGUNIT,
124
- items: [...this.props.ouItems.filter(ou => this.userOrgUnitIds.includes(ou.id)), userOrgUnits.find(ou => ou.id === event.target.name)]
125
- });
126
- } else {
127
- if (this.props.ouItems.length === 1 && this.state.selected.length > 0) {
128
- this.props.onSelect({
129
- dimensionId: DIMENSION_ID_ORGUNIT,
130
- items: this.state.selected
131
- });
132
- } else {
133
- this.props.onDeselect({
134
- dimensionId: DIMENSION_ID_ORGUNIT,
135
- itemIdsToRemove: [event.target.name]
136
- });
137
- }
123
+ if (numberOfGroups) {
124
+ parts.push(i18n.t('{{count}} groups', {
125
+ count: numberOfGroups,
126
+ defaultValue: '{{count}} group',
127
+ defaultValue_plural: '{{count}} groups'
128
+ }));
138
129
  }
139
- });
140
130
 
141
- _defineProperty(this, "handleMultipleOrgUnitsSelect", orgUnits => {
142
- const selected = this.props.ouItems;
143
- this.props.onSelect({
144
- dimensionId: DIMENSION_ID_ORGUNIT,
145
- items: [...selected, ...orgUnits.reduce((obj, ou) => {
146
- // avoid duplicates when clicking "Select children" multiple times
147
- if (!selected.find(i => i.id === ou.id)) {
148
- obj.push({ ...ou,
149
- name: ou.name || ou.displayName
150
- });
151
- }
152
-
153
- return obj;
154
- }, [])]
131
+ userOrgUnits.forEach(orgUnit => {
132
+ parts.push(orgUnit.name || orgUnit.displayName);
155
133
  });
156
- });
157
-
158
- _defineProperty(this, "render", () => {
159
- const ids = this.props.ouItems.map(ou => ou.id);
160
- const selected = this.props.ouItems.filter(ou => !this.userOrgUnitIds.includes(ou.id) && !ouIdHelper.hasLevelPrefix(ou.id) && !ouIdHelper.hasGroupPrefix(ou.id));
161
- const userOrgUnits = this.getUserOrgUnitsFromIds(ids);
162
- const level = ids.filter(ouIdHelper.hasLevelPrefix).map(ouIdHelper.removePrefix);
163
- const group = ids.filter(ouIdHelper.hasGroupPrefix).map(ouIdHelper.removePrefix);
164
- return /*#__PURE__*/React.createElement(Fragment, null, this.state.root && this.state.showOrgUnitsTree && /*#__PURE__*/React.createElement(OrgUnitSelector, {
165
- d2: this.props.d2,
166
- root: this.state.root,
167
- roots: this.state.roots,
168
- selected: selected,
169
- userOrgUnits: userOrgUnits,
170
- level: level,
171
- group: group,
172
- levelOptions: this.state.ouLevels,
173
- groupOptions: this.state.ouGroups,
174
- onLevelChange: this.onLevelChange,
175
- onGroupChange: this.onGroupChange,
176
- onDeselectAllClick: this.onDeselectAllClick,
177
- handleUserOrgUnitClick: this.handleUserOrgUnitClick,
178
- handleOrgUnitClick: this.handleOrgUnitClick,
179
- handleMultipleOrgUnitsSelect: this.handleMultipleOrgUnitsSelect,
180
- checkboxColor: "secondary",
181
- deselectAllTooltipFontColor: colors.grey900,
182
- deselectAllTooltipBackgroundColor: colors.grey300,
183
- displayNameProperty: this.props.displayNameProperty,
184
- isUserDataViewFallback: true
185
- }), !this.state.root && /*#__PURE__*/React.createElement("div", {
186
- className: "jsx-".concat(styles.__hash) + " " + "loader"
187
- }, /*#__PURE__*/React.createElement(CircularLoader, null)), /*#__PURE__*/React.createElement(_JSXStyle, {
188
- id: styles.__hash
189
- }, styles));
190
- });
191
-
192
- this.state = defaultState;
193
- this.userOrgUnitIds = userOrgUnits.map(ou => ou.id);
194
- this.loadOrgUnitTree(props.d2, props.displayNameProperty);
195
- this.loadOrgUnitGroups(props.d2, props.displayNameProperty);
196
- this.loadOrgUnitLevels(props.d2);
197
- }
198
-
199
- componentDidUpdate(prevProps) {
200
- const previousId = prevProps.current ? prevProps.current.id : null;
201
- const currentId = this.props.current ? this.props.current.id : null; // remount org units selector component to ensure
202
- // only selected org units are expanded
203
-
204
- if (previousId !== currentId) {
205
- this.hideOrgUnitsTree();
206
- setTimeout(this.showOrgUnitsTree, 0);
134
+ summary = i18n.t('Selected: {{commaSeparatedListOfOrganisationUnits}}', {
135
+ keySeparator: '>',
136
+ nsSeparator: '|',
137
+ commaSeparatedListOfOrganisationUnits: formatList(parts)
138
+ });
139
+ } else {
140
+ summary = i18n.t('Nothing selected');
207
141
  }
208
- }
209
142
 
210
- }
143
+ return summary;
144
+ };
145
+
146
+ return /*#__PURE__*/React.createElement("div", {
147
+ className: "jsx-".concat(styles.__hash) + " " + "container"
148
+ }, /*#__PURE__*/React.createElement("div", {
149
+ className: "jsx-".concat(styles.__hash) + " " + "userOrgUnitsWrapper"
150
+ }, /*#__PURE__*/React.createElement(Checkbox, {
151
+ label: i18n.t('User organisation unit'),
152
+ checked: selected.some(item => item.id === USER_ORG_UNIT),
153
+ onChange: ({
154
+ checked
155
+ }) => onSelectItems({
156
+ id: USER_ORG_UNIT,
157
+ checked,
158
+ displayName: i18n.t('User organisation unit')
159
+ }),
160
+ dense: true
161
+ }), /*#__PURE__*/React.createElement(Checkbox, {
162
+ label: i18n.t('User sub-units'),
163
+ checked: selected.some(item => item.id === USER_ORG_UNIT_CHILDREN),
164
+ onChange: ({
165
+ checked
166
+ }) => onSelectItems({
167
+ id: USER_ORG_UNIT_CHILDREN,
168
+ checked,
169
+ displayName: i18n.t('User sub-units')
170
+ }),
171
+ dense: true
172
+ }), /*#__PURE__*/React.createElement(Checkbox, {
173
+ label: i18n.t('User sub-x2-units'),
174
+ checked: selected.some(item => item.id === USER_ORG_UNIT_GRANDCHILDREN),
175
+ onChange: ({
176
+ checked
177
+ }) => onSelectItems({
178
+ id: USER_ORG_UNIT_GRANDCHILDREN,
179
+ checked,
180
+ displayName: i18n.t('User sub-x2-units')
181
+ }),
182
+ dense: true
183
+ })), /*#__PURE__*/React.createElement("div", {
184
+ className: "jsx-".concat(styles.__hash) + " " + (cx('orgUnitTreeWrapper', {
185
+ disabled: selected.some(item => DYNAMIC_ORG_UNITS.includes(item.id))
186
+ }) || "")
187
+ }, /*#__PURE__*/React.createElement(OrganisationUnitTree, {
188
+ roots: roots,
189
+ initiallyExpanded: [...(roots.length === 1 ? ["/".concat(roots[0])] : []), ...selected.filter(item => !DYNAMIC_ORG_UNITS.includes(item.id) && !ouIdHelper.hasLevelPrefix(item.id) && !ouIdHelper.hasGroupPrefix(item.id)).map(item => item.path.substring(0, item.path.lastIndexOf('/'))).filter(path => path)],
190
+ selected: selected.filter(item => !DYNAMIC_ORG_UNITS.includes(item.id) && !ouIdHelper.hasLevelPrefix(item.id) && !ouIdHelper.hasGroupPrefix(item.id)).map(item => item.path),
191
+ onChange: onSelectItems,
192
+ dataTest: 'org-unit-tree'
193
+ })), /*#__PURE__*/React.createElement("div", {
194
+ className: "jsx-".concat(styles.__hash) + " " + "selectsWrapper"
195
+ }, /*#__PURE__*/React.createElement(MultiSelect, {
196
+ selected: ouLevels.length ? selected.filter(item => ouIdHelper.hasLevelPrefix(item.id)).map(item => ouIdHelper.removePrefix(item.id)) : [],
197
+ onChange: ({
198
+ selected
199
+ }) => onLevelChange(selected),
200
+ placeholder: i18n.t('Select a level'),
201
+ loading: !ouLevels.length,
202
+ dense: true,
203
+ dataTest: 'org-unit-level-select'
204
+ }, ouLevels.map(level => /*#__PURE__*/React.createElement(MultiSelectOption, {
205
+ key: level.id,
206
+ value: level.id,
207
+ label: level.displayName,
208
+ dataTest: "org-unit-level-select-option-".concat(level.id)
209
+ }))), /*#__PURE__*/React.createElement(MultiSelect, {
210
+ selected: ouGroups.length ? selected.filter(item => ouIdHelper.hasGroupPrefix(item.id)).map(item => ouIdHelper.removePrefix(item.id)) : [],
211
+ onChange: ({
212
+ selected
213
+ }) => onGroupChange(selected),
214
+ placeholder: i18n.t('Select a group'),
215
+ loading: !ouGroups.length,
216
+ dense: true,
217
+ dataTest: 'org-unit-group-select'
218
+ }, ouGroups.map(group => /*#__PURE__*/React.createElement(MultiSelectOption, {
219
+ key: group.id,
220
+ value: group.id,
221
+ label: group.displayName,
222
+ dataTest: "org-unit-group-select-option-".concat(group.id)
223
+ })))), /*#__PURE__*/React.createElement("div", {
224
+ className: "jsx-".concat(styles.__hash) + " " + "summaryWrapper"
225
+ }, /*#__PURE__*/React.createElement("span", {
226
+ className: "jsx-".concat(styles.__hash) + " " + "summaryText"
227
+ }, getSummary()), /*#__PURE__*/React.createElement("div", {
228
+ className: "jsx-".concat(styles.__hash) + " " + "deselectButton"
229
+ }, /*#__PURE__*/React.createElement(Button, {
230
+ secondary: true,
231
+ small: true,
232
+ onClick: clearSelection,
233
+ disabled: !selected.length
234
+ }, i18n.t('Deselect all')))), /*#__PURE__*/React.createElement(_JSXStyle, {
235
+ id: styles.__hash
236
+ }, styles));
237
+ };
211
238
 
212
239
  OrgUnitDimension.propTypes = {
213
- current: PropTypes.object,
214
- d2: PropTypes.object,
215
- displayNameProperty: PropTypes.string,
216
- ouItems: PropTypes.array,
217
- onDeselect: PropTypes.func,
240
+ roots: PropTypes.arrayOf(PropTypes.string),
241
+ selected: PropTypes.arrayOf(PropTypes.shape({
242
+ id: PropTypes.string.isRequired,
243
+ name: PropTypes.string.isRequired,
244
+ path: PropTypes.string
245
+ })),
218
246
  onSelect: PropTypes.func
219
247
  };
220
248
  export default OrgUnitDimension;
@@ -1,3 +1,4 @@
1
- const _defaultExport = [".loader.jsx-3308394077{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;min-height:100px;}"];
2
- _defaultExport.__hash = "3308394077";
1
+ import { colors, spacers } from '@dhis2/ui';
2
+ const _defaultExport = [".container.jsx-3879278432{height:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}", ".orgUnitTreeWrapper.jsx-3879278432{height:382px;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;overflow:auto;}", ".orgUnitTreeWrapper.jsx-3879278432>*{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;}", ".disabled.jsx-3879278432{cursor:not-allowed;opacity:0.5;}", ".disabled.jsx-3879278432>*{pointer-events:none;}", ".userOrgUnitsWrapper.jsx-3879278432{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;background:".concat(colors.grey200, ";padding:").concat(spacers.dp8, " ").concat(spacers.dp8, " ").concat(spacers.dp8, " ").concat(spacers.dp24, ";margin-bottom:").concat(spacers.dp12, ";}"), ".userOrgUnitsWrapper.jsx-3879278432>*{margin-right:".concat(spacers.dp48, ";}"), ".selectsWrapper.jsx-3879278432{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:flex-start;-webkit-box-align:flex-start;-ms-flex-align:flex-start;align-items:flex-start;gap:".concat(spacers.dp8, ";margin-top:").concat(spacers.dp12, ";}"), ".selectsWrapper.jsx-3879278432>*{width:50%;}", ".summaryWrapper.jsx-3879278432{margin-top:".concat(spacers.dp8, ";}"), ".summaryText.jsx-3879278432{font-size:14px;line-height:18px;color:".concat(colors.grey700, ";}"), ".deselectButton.jsx-3879278432{display:inline-block;margin-left:".concat(spacers.dp8, ";}")];
3
+ _defaultExport.__hash = "3879278432";
3
4
  export default _defaultExport;
@@ -2,8 +2,8 @@ import _JSXStyle from "styled-jsx/style";
2
2
 
3
3
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
4
4
 
5
- import propTypes from '@dhis2/prop-types';
6
5
  import { SingleSelectField, SingleSelectOption } from '@dhis2/ui';
6
+ import PropTypes from 'prop-types';
7
7
  import React, { Component } from 'react';
8
8
  import i18n from '../../locales/index.js';
9
9
  import FixedPeriodFilter from './FixedPeriodFilter.js';
@@ -103,10 +103,10 @@ FixedPeriodSelect.defaultProps = {
103
103
  value: ''
104
104
  };
105
105
  FixedPeriodSelect.propTypes = {
106
- onChange: propTypes.func.isRequired,
107
- allowedPeriodTypes: propTypes.arrayOf(propTypes.string),
108
- className: propTypes.string,
109
- dataTest: propTypes.string,
110
- value: propTypes.string
106
+ onChange: PropTypes.func.isRequired,
107
+ allowedPeriodTypes: PropTypes.arrayOf(PropTypes.string),
108
+ className: PropTypes.string,
109
+ dataTest: PropTypes.string,
110
+ value: PropTypes.string
111
111
  };
112
112
  export default FixedPeriodSelect;
@@ -1,7 +1,7 @@
1
1
  import _JSXStyle from "styled-jsx/style";
2
- import propTypes from '@dhis2/prop-types';
3
2
  import { Tooltip } from '@dhis2/ui';
4
3
  import cx from 'classnames';
4
+ import PropTypes from 'prop-types';
5
5
  import React from 'react';
6
6
  import styles from './styles/TransferOption.style';
7
7
  export const TransferOption = ({
@@ -60,15 +60,15 @@ export const TransferOption = ({
60
60
  }, renderContent()) : renderContent());
61
61
  };
62
62
  TransferOption.propTypes = {
63
- label: propTypes.string.isRequired,
64
- value: propTypes.string.isRequired,
65
- active: propTypes.bool,
66
- dataTest: propTypes.string,
67
- disabled: propTypes.bool,
68
- highlighted: propTypes.bool,
69
- icon: propTypes.node,
70
- selected: propTypes.bool,
71
- tooltipText: propTypes.string,
72
- onClick: propTypes.func,
73
- onDoubleClick: propTypes.func
63
+ label: PropTypes.string.isRequired,
64
+ value: PropTypes.string.isRequired,
65
+ active: PropTypes.bool,
66
+ dataTest: PropTypes.string,
67
+ disabled: PropTypes.bool,
68
+ highlighted: PropTypes.bool,
69
+ icon: PropTypes.node,
70
+ selected: PropTypes.bool,
71
+ tooltipText: PropTypes.string,
72
+ onClick: PropTypes.func,
73
+ onDoubleClick: PropTypes.func
74
74
  };
package/build/es/index.js CHANGED
@@ -17,13 +17,13 @@ export { default as AboutAOUnit } from './components/AboutAOUnit/AboutAOUnit'; /
17
17
 
18
18
  export { default as Analytics } from './api/analytics/Analytics';
19
19
  export { apiFetchDimensions, apiFetchRecommendedIds } from './api/dimensions';
20
- export { apiFetchOrganisationUnitLevels, apiFetchOrganisationUnitRoots, apiFetchOrganisationUnit } from './api/organisationUnits-dataEngine'; // Modules: axis
20
+ export { apiFetchOrganisationUnitLevels, apiFetchOrganisationUnitRoots, apiFetchOrganisationUnit } from './api/organisationUnits'; // Modules: axis
21
21
 
22
22
  export { getAxisName, getAxisNameByLayoutType, hasCustomAxes } from './modules/axis'; // Modules: predefined dimensions
23
23
 
24
24
  export { DIMENSION_ID_DATA, DIMENSION_ID_PERIOD, DIMENSION_ID_ORGUNIT, DIMENSION_ID_ASSIGNED_CATEGORIES, DIMENSION_PROP_NO_ITEMS, filterOutPredefinedDimensions, getPredefinedDimensionProp, getDimensionById, getPredefinedDimensions, getFixedDimensions, getDynamicDimensions } from './modules/predefinedDimensions'; // Modules: ou utils
25
25
 
26
- export { ouIdHelper } from './modules/ouIdHelper';
26
+ export { ouIdHelper, USER_ORG_UNIT, USER_ORG_UNIT_CHILDREN, USER_ORG_UNIT_GRANDCHILDREN } from './modules/ouIdHelper';
27
27
  export { convertOuLevelsToUids } from './modules/ouLevelUtils'; // Modules: adapted ui layout
28
28
 
29
29
  export { getAdaptedUiLayoutByType } from './modules/getAdaptedUiLayoutByType'; // Modules: relativeItems
@@ -118,6 +118,20 @@
118
118
  "Options": "Options",
119
119
  "Hide": "Hide",
120
120
  "Update": "Update",
121
+ "{{count}} org units": "{{count}} org unit",
122
+ "{{count}} org units_plural": "{{count}} org units",
123
+ "{{count}} levels": "{{count}} level",
124
+ "{{count}} levels_plural": "{{count}} levels",
125
+ "{{count}} groups": "{{count}} group",
126
+ "{{count}} groups_plural": "{{count}} groups",
127
+ "Selected: {{commaSeparatedListOfOrganisationUnits}}": "Selected: {{commaSeparatedListOfOrganisationUnits}}",
128
+ "Nothing selected": "Nothing selected",
129
+ "User organisation unit": "User organisation unit",
130
+ "User sub-units": "User sub-units",
131
+ "User sub-x2-units": "User sub-x2-units",
132
+ "Select a level": "Select a level",
133
+ "Select a group": "Select a group",
134
+ "Deselect all": "Deselect all",
121
135
  "Period type": "Period type",
122
136
  "Year": "Year",
123
137
  "Select year": "Select year",
@@ -0,0 +1,13 @@
1
+ import i18n from '../locales/index.js';
2
+ export const formatList = items => {
3
+ // Wrap Intl.ListFormat in try/catch as DHIS2 locales are not always ISO 639 compliant
4
+ try {
5
+ const formatter = new Intl.ListFormat(i18n.language, {
6
+ style: 'long',
7
+ type: 'conjunction'
8
+ });
9
+ return formatter.format(items);
10
+ } catch (error) {
11
+ return items.join(', ');
12
+ }
13
+ };
@@ -1,5 +1,8 @@
1
1
  const LEVEL_ID_PREFIX = 'LEVEL';
2
2
  const GROUP_ID_PREFIX = 'OU_GROUP';
3
+ export const USER_ORG_UNIT = 'USER_ORGUNIT';
4
+ export const USER_ORG_UNIT_CHILDREN = 'USER_ORGUNIT_CHILDREN';
5
+ export const USER_ORG_UNIT_GRANDCHILDREN = 'USER_ORGUNIT_GRANDCHILDREN';
3
6
 
4
7
  const hasGroupPrefix = id => id.substr(0, GROUP_ID_PREFIX.length) === GROUP_ID_PREFIX;
5
8
 
@@ -1,4 +1,4 @@
1
1
  import { getRelativePeriodIds } from '../../components/PeriodDimension/utils/relativePeriods';
2
- import { ouIdHelper } from '../ouIdHelper';
2
+ import { ouIdHelper, USER_ORG_UNIT, USER_ORG_UNIT_CHILDREN, USER_ORG_UNIT_GRANDCHILDREN } from '../ouIdHelper';
3
3
  import { DIMENSION_ID_ASSIGNED_CATEGORIES, DIMENSION_ID_ORGUNIT, DIMENSION_ID_PERIOD } from '../predefinedDimensions';
4
- export const hasRelativeItems = (dimension, itemIds = []) => dimension === DIMENSION_ID_ASSIGNED_CATEGORIES || dimension === DIMENSION_ID_ORGUNIT && Array.isArray(itemIds) && itemIds.some(id => ouIdHelper.hasLevelPrefix(id) || ouIdHelper.hasGroupPrefix(id) || ['USER_ORGUNIT', 'USER_ORGUNIT_CHILDREN', 'USER_ORGUNIT_GRAND_CHILDREN'].includes(id)) || dimension === DIMENSION_ID_PERIOD && Array.isArray(itemIds) && itemIds.some(id => getRelativePeriodIds().includes(id));
4
+ export const hasRelativeItems = (dimension, itemIds = []) => dimension === DIMENSION_ID_ASSIGNED_CATEGORIES || dimension === DIMENSION_ID_ORGUNIT && Array.isArray(itemIds) && itemIds.some(id => ouIdHelper.hasLevelPrefix(id) || ouIdHelper.hasGroupPrefix(id) || [USER_ORG_UNIT, USER_ORG_UNIT_CHILDREN, USER_ORG_UNIT_GRANDCHILDREN].includes(id)) || dimension === DIMENSION_ID_PERIOD && Array.isArray(itemIds) && itemIds.some(id => getRelativePeriodIds().includes(id));
@@ -128,7 +128,7 @@ describe('getFilterText', () => {
128
128
  name: '02 of 2018',
129
129
  uid: '_201802_'
130
130
  };
131
- expect(getFilterText(filters, metaData)).toEqual('Clinics, Hospital - Last 2 months');
131
+ expect(getFilterText(filters, metaData)).toEqual('Clinics, Hospital - 01 of 2018, 02 of 2018');
132
132
  });
133
133
  });
134
134
  });
@@ -2,7 +2,7 @@ import { getOuLevelAndGroupText } from '../../modules/getOuLevelAndGroupText';
2
2
  import { dimensionGetItems } from '../../modules/layout/dimensionGetItems';
3
3
  import { dimensionIs } from '../../modules/layout/dimensionIs';
4
4
  import { ouIdHelper } from '../../modules/ouIdHelper';
5
- import { DIMENSION_ID_ORGUNIT, DIMENSION_ID_PERIOD } from '../../modules/predefinedDimensions';
5
+ import { DIMENSION_ID_ORGUNIT } from '../../modules/predefinedDimensions';
6
6
  export default function (filters, metaData) {
7
7
  if (!Array.isArray(filters) || !filters.length) {
8
8
  return '';
@@ -19,15 +19,7 @@ export default function (filters, metaData) {
19
19
  }) => ouIdHelper.hasGroupPrefix(id) || ouIdHelper.hasLevelPrefix(id))) {
20
20
  titleFragments.push(getOuLevelAndGroupText(filter, metaData));
21
21
  } else {
22
- let filterItems = [];
23
-
24
- if (dimensionIs(filter, DIMENSION_ID_PERIOD)) {
25
- filterItems = items.map(({
26
- id
27
- }) => id);
28
- } else {
29
- filterItems = metaData.dimensions[filter.dimension];
30
- }
22
+ const filterItems = metaData.dimensions[filter.dimension];
31
23
 
32
24
  if (Array.isArray(filterItems)) {
33
25
  l = filterItems.length;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dhis2/analytics",
3
- "version": "20.7.0",
3
+ "version": "21.0.0-alpha.4",
4
4
  "main": "./build/cjs/index.js",
5
5
  "module": "./build/es/index.js",
6
6
  "exports": {
@@ -35,7 +35,7 @@
35
35
  "@dhis2/cli-app-scripts": "^6.2.0",
36
36
  "@dhis2/cli-style": "^9.0.1",
37
37
  "@dhis2/d2-i18n": "^1.1.0",
38
- "@dhis2/ui": "^6.23.5",
38
+ "@dhis2/ui": "^7.7.2",
39
39
  "@sambego/storybook-state": "^2.0.1",
40
40
  "@storybook/addons": "^6.1.14",
41
41
  "@storybook/preset-create-react-app": "^3.1.7",
@@ -44,6 +44,7 @@
44
44
  "enzyme-adapter-react-16": "^1.15.6",
45
45
  "fs-extra": "^10.0.0",
46
46
  "jest-enzyme": "^7.0.2",
47
+ "prop-types": "^15",
47
48
  "styled-jsx": "3.3.2",
48
49
  "typeface-roboto": "^0.0.75"
49
50
  },