@dhis2-ui/organisation-unit-tree 10.16.3 → 10.16.5
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.
- package/build/cjs/__e2e__/children_as_child_nodes.js +8 -11
- package/build/cjs/__e2e__/common.js +19 -26
- package/build/cjs/__e2e__/controlled_expanded.js +7 -10
- package/build/cjs/__e2e__/displaying_loading_error.js +1 -4
- package/build/cjs/__e2e__/expanded.js +25 -34
- package/build/cjs/__e2e__/force_reload.js +15 -22
- package/build/cjs/__e2e__/get-organisation-unit-data.js +25 -29
- package/build/cjs/__e2e__/highlight.js +7 -10
- package/build/cjs/__e2e__/loading_state.js +7 -13
- package/build/cjs/__e2e__/multi_selection.js +8 -11
- package/build/cjs/__e2e__/no_selection.js +15 -21
- package/build/cjs/__e2e__/path_based_filtering.js +16 -22
- package/build/cjs/__e2e__/single_selection.js +10 -16
- package/build/cjs/__e2e__/sub_unit_as_root.js +5 -7
- package/build/cjs/__e2e__/tree_api.js +15 -21
- package/build/cjs/__stories__/custom-expanded-imperative-open.js +7 -10
- package/build/cjs/__stories__/custom-node-label.js +4 -5
- package/build/cjs/__stories__/development-stories.js +6 -8
- package/build/cjs/__stories__/force-reload-all.js +1 -2
- package/build/cjs/__stories__/loading-error-grandchild.js +1 -4
- package/build/cjs/__stories__/loading.js +1 -4
- package/build/cjs/__stories__/multiple-roots.js +9 -12
- package/build/cjs/__stories__/root-error.js +1 -4
- package/build/cjs/__stories__/root-loading.js +1 -4
- package/build/cjs/__stories__/shared.js +46 -79
- package/build/cjs/features/controlled_expanded/index.js +3 -6
- package/build/cjs/locales/index.js +49 -27
- package/build/cjs/organisation-unit-node/error-message.js +10 -13
- package/build/cjs/organisation-unit-node/label/disabled-selection-label.js +9 -12
- package/build/cjs/organisation-unit-node/label/icon-empty.js +19 -22
- package/build/cjs/organisation-unit-node/label/icon-folder-closed.js +25 -28
- package/build/cjs/organisation-unit-node/label/icon-folder-open.js +34 -37
- package/build/cjs/organisation-unit-node/label/icon-single.js +28 -31
- package/build/cjs/organisation-unit-node/label/icon.js +6 -7
- package/build/cjs/organisation-unit-node/label/iconized-checkbox.js +12 -13
- package/build/cjs/organisation-unit-node/label/label-container.js +13 -16
- package/build/cjs/organisation-unit-node/label/label.js +27 -30
- package/build/cjs/organisation-unit-node/label/single-selection-label.js +18 -21
- package/build/cjs/organisation-unit-node/organisation-unit-node-children.js +27 -29
- package/build/cjs/organisation-unit-node/organisation-unit-node.js +22 -23
- package/build/cjs/organisation-unit-node/use-open-state.js +8 -9
- package/build/cjs/organisation-unit-node/use-org-children.js +14 -21
- package/build/cjs/organisation-unit-node/use-org-children.test.js +40 -59
- package/build/cjs/organisation-unit-node/use-org-data/use-org-data.js +13 -20
- package/build/cjs/organisation-unit-node/use-org-data/use-org-data.test.js +17 -27
- package/build/cjs/organisation-unit-tree/default-render-node-label/default-render-node-label.js +3 -6
- package/build/cjs/organisation-unit-tree/organisation-unit-tree-root-error.js +9 -12
- package/build/cjs/organisation-unit-tree/organisation-unit-tree-root-loading.js +10 -13
- package/build/cjs/organisation-unit-tree/organisation-unit-tree.js +41 -35
- package/build/cjs/organisation-unit-tree/organisation-unit-tree.test.js +78 -7
- package/build/cjs/organisation-unit-tree/use-expanded/create-expand-handlers.js +14 -17
- package/build/cjs/organisation-unit-tree/use-expanded/use-expanded.js +8 -9
- package/build/cjs/organisation-unit-tree/use-root-org-data/patch-missing-display-name.js +1 -2
- package/build/cjs/organisation-unit-tree/use-root-org-data/use-root-org-data.js +10 -14
- package/build/cjs/organisation-unit-tree/use-root-org-data/use-root-org-unit.test.js +32 -46
- package/build/es/__e2e__/children_as_child_nodes.js +8 -11
- package/build/es/__e2e__/common.js +18 -24
- package/build/es/__e2e__/controlled_expanded.js +6 -8
- package/build/es/__e2e__/displaying_loading_error.js +1 -4
- package/build/es/__e2e__/expanded.js +25 -34
- package/build/es/__e2e__/force_reload.js +14 -20
- package/build/es/__e2e__/get-organisation-unit-data.js +25 -29
- package/build/es/__e2e__/highlight.js +7 -10
- package/build/es/__e2e__/loading_state.js +7 -13
- package/build/es/__e2e__/multi_selection.js +8 -11
- package/build/es/__e2e__/no_selection.js +15 -21
- package/build/es/__e2e__/path_based_filtering.js +16 -22
- package/build/es/__e2e__/single_selection.js +10 -16
- package/build/es/__e2e__/sub_unit_as_root.js +4 -5
- package/build/es/__e2e__/tree_api.js +15 -21
- package/build/es/__stories__/custom-expanded-imperative-open.js +6 -8
- package/build/es/__stories__/custom-node-label.js +4 -5
- package/build/es/__stories__/development-stories.js +5 -6
- package/build/es/__stories__/loading-error-grandchild.js +1 -4
- package/build/es/__stories__/loading.js +1 -4
- package/build/es/__stories__/multiple-roots.js +9 -12
- package/build/es/__stories__/root-error.js +1 -4
- package/build/es/__stories__/root-loading.js +1 -4
- package/build/es/__stories__/shared.js +45 -77
- package/build/es/features/controlled_expanded/index.js +3 -6
- package/build/es/locales/index.js +40 -18
- package/build/es/organisation-unit-node/error-message.js +10 -13
- package/build/es/organisation-unit-node/label/disabled-selection-label.js +9 -12
- package/build/es/organisation-unit-node/label/icon-empty.js +19 -22
- package/build/es/organisation-unit-node/label/icon-folder-closed.js +25 -28
- package/build/es/organisation-unit-node/label/icon-folder-open.js +34 -37
- package/build/es/organisation-unit-node/label/icon-single.js +28 -31
- package/build/es/organisation-unit-node/label/icon.js +6 -7
- package/build/es/organisation-unit-node/label/iconized-checkbox.js +12 -13
- package/build/es/organisation-unit-node/label/label-container.js +13 -16
- package/build/es/organisation-unit-node/label/label.js +27 -30
- package/build/es/organisation-unit-node/label/single-selection-label.js +18 -21
- package/build/es/organisation-unit-node/organisation-unit-node-children.js +27 -29
- package/build/es/organisation-unit-node/organisation-unit-node.js +22 -23
- package/build/es/organisation-unit-node/use-open-state.js +8 -9
- package/build/es/organisation-unit-node/use-org-children.js +14 -21
- package/build/es/organisation-unit-node/use-org-children.test.js +40 -59
- package/build/es/organisation-unit-node/use-org-data/use-org-data.js +13 -20
- package/build/es/organisation-unit-node/use-org-data/use-org-data.test.js +17 -27
- package/build/es/organisation-unit-tree/default-render-node-label/default-render-node-label.js +3 -6
- package/build/es/organisation-unit-tree/organisation-unit-tree-root-error.js +9 -12
- package/build/es/organisation-unit-tree/organisation-unit-tree-root-loading.js +10 -13
- package/build/es/organisation-unit-tree/organisation-unit-tree.js +34 -27
- package/build/es/organisation-unit-tree/organisation-unit-tree.test.js +71 -0
- package/build/es/organisation-unit-tree/use-expanded/create-expand-handlers.js +14 -17
- package/build/es/organisation-unit-tree/use-expanded/use-expanded.js +8 -9
- package/build/es/organisation-unit-tree/use-root-org-data/patch-missing-display-name.js +1 -2
- package/build/es/organisation-unit-tree/use-root-org-data/use-root-org-data.js +10 -14
- package/build/es/organisation-unit-tree/use-root-org-data/use-root-org-unit.test.js +32 -46
- package/package.json +6 -6
- package/src/locales/index.js +57 -18
- package/src/organisation-unit-tree/organisation-unit-tree.js +14 -3
- package/src/organisation-unit-tree/organisation-unit-tree.test.js +64 -0
- package/src/organisation-unit-tree/use-root-org-data/use-root-org-unit.test.js +14 -14
|
@@ -4,10 +4,9 @@ import React from 'react';
|
|
|
4
4
|
import { useOrgChildren } from './use-org-children.js';
|
|
5
5
|
describe('OrganisationUnitTree - useOrgChildren', () => {
|
|
6
6
|
const dataProviderData = {
|
|
7
|
-
organisationUnits: jest.fn((type,
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
} = _ref;
|
|
7
|
+
organisationUnits: jest.fn((type, {
|
|
8
|
+
id
|
|
9
|
+
}) => {
|
|
11
10
|
if (id === 'A0000000000') {
|
|
12
11
|
return {
|
|
13
12
|
children: [{
|
|
@@ -21,14 +20,11 @@ describe('OrganisationUnitTree - useOrgChildren', () => {
|
|
|
21
20
|
return Promise.reject(`No org unit with id "${id}"`);
|
|
22
21
|
})
|
|
23
22
|
};
|
|
24
|
-
const wrapper =
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
data: dataProviderData
|
|
30
|
-
}, children);
|
|
31
|
-
};
|
|
23
|
+
const wrapper = ({
|
|
24
|
+
children
|
|
25
|
+
}) => /*#__PURE__*/React.createElement(CustomDataProvider, {
|
|
26
|
+
data: dataProviderData
|
|
27
|
+
}, children);
|
|
32
28
|
const node = {
|
|
33
29
|
id: 'A0000000000',
|
|
34
30
|
path: '/A0000000000',
|
|
@@ -78,18 +74,15 @@ describe('OrganisationUnitTree - useOrgChildren', () => {
|
|
|
78
74
|
});
|
|
79
75
|
});
|
|
80
76
|
it('should provide the error', async () => {
|
|
81
|
-
const errorWrapper =
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
organisationUnits: async () => {
|
|
88
|
-
throw new Error('Error message');
|
|
89
|
-
}
|
|
77
|
+
const errorWrapper = ({
|
|
78
|
+
children
|
|
79
|
+
}) => /*#__PURE__*/React.createElement(CustomDataProvider, {
|
|
80
|
+
data: {
|
|
81
|
+
organisationUnits: async () => {
|
|
82
|
+
throw new Error('Error message');
|
|
90
83
|
}
|
|
91
|
-
}
|
|
92
|
-
};
|
|
84
|
+
}
|
|
85
|
+
}, children);
|
|
93
86
|
const {
|
|
94
87
|
result
|
|
95
88
|
} = renderHook(() => useOrgChildren({
|
|
@@ -131,10 +124,9 @@ describe('OrganisationUnitTree - useOrgChildren', () => {
|
|
|
131
124
|
});
|
|
132
125
|
it("should sort the node's children alphabetically by default", async () => {
|
|
133
126
|
const dataProviderDataWithUnsortedChildren = {
|
|
134
|
-
organisationUnits: jest.fn((type,
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
} = _ref4;
|
|
127
|
+
organisationUnits: jest.fn((type, {
|
|
128
|
+
id
|
|
129
|
+
}) => {
|
|
138
130
|
if (id === 'A0000000000') {
|
|
139
131
|
return {
|
|
140
132
|
children: [{
|
|
@@ -153,14 +145,11 @@ describe('OrganisationUnitTree - useOrgChildren', () => {
|
|
|
153
145
|
return Promise.reject(`No org unit with id "${id}"`);
|
|
154
146
|
})
|
|
155
147
|
};
|
|
156
|
-
const wrapperWithUnsortedChildren =
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
data: dataProviderDataWithUnsortedChildren
|
|
162
|
-
}, children);
|
|
163
|
-
};
|
|
148
|
+
const wrapperWithUnsortedChildren = ({
|
|
149
|
+
children
|
|
150
|
+
}) => /*#__PURE__*/React.createElement(CustomDataProvider, {
|
|
151
|
+
data: dataProviderDataWithUnsortedChildren
|
|
152
|
+
}, children);
|
|
164
153
|
const {
|
|
165
154
|
result
|
|
166
155
|
} = renderHook(() => useOrgChildren({
|
|
@@ -192,10 +181,9 @@ describe('OrganisationUnitTree - useOrgChildren', () => {
|
|
|
192
181
|
});
|
|
193
182
|
it(`should not sort the node's children alphabetically when "suppressAlphabeticalSorting" is true`, async () => {
|
|
194
183
|
const dataProviderDataWithUnsortedChildren = {
|
|
195
|
-
organisationUnits: jest.fn((type,
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
} = _ref6;
|
|
184
|
+
organisationUnits: jest.fn((type, {
|
|
185
|
+
id
|
|
186
|
+
}) => {
|
|
199
187
|
if (id === 'A0000000000') {
|
|
200
188
|
return {
|
|
201
189
|
children: [{
|
|
@@ -214,14 +202,11 @@ describe('OrganisationUnitTree - useOrgChildren', () => {
|
|
|
214
202
|
return Promise.reject(`No org unit with id "${id}"`);
|
|
215
203
|
})
|
|
216
204
|
};
|
|
217
|
-
const wrapperWithUnsortedChildren =
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
data: dataProviderDataWithUnsortedChildren
|
|
223
|
-
}, children);
|
|
224
|
-
};
|
|
205
|
+
const wrapperWithUnsortedChildren = ({
|
|
206
|
+
children
|
|
207
|
+
}) => /*#__PURE__*/React.createElement(CustomDataProvider, {
|
|
208
|
+
data: dataProviderDataWithUnsortedChildren
|
|
209
|
+
}, children);
|
|
225
210
|
const options = {
|
|
226
211
|
node: {
|
|
227
212
|
...node,
|
|
@@ -255,10 +240,9 @@ describe('OrganisationUnitTree - useOrgChildren', () => {
|
|
|
255
240
|
});
|
|
256
241
|
it(`should not sort the node's children alphabetically when "suppressAlphabeticalSorting" is true`, async () => {
|
|
257
242
|
const dataProviderDataWithUnsortedChildren = {
|
|
258
|
-
organisationUnits: jest.fn((type,
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
} = _ref8;
|
|
243
|
+
organisationUnits: jest.fn((type, {
|
|
244
|
+
id
|
|
245
|
+
}) => {
|
|
262
246
|
if (id === 'A0000000000') {
|
|
263
247
|
return {
|
|
264
248
|
children: [{
|
|
@@ -277,14 +261,11 @@ describe('OrganisationUnitTree - useOrgChildren', () => {
|
|
|
277
261
|
return Promise.reject(`No org unit with id "${id}"`);
|
|
278
262
|
})
|
|
279
263
|
};
|
|
280
|
-
const wrapperWithUnsortedChildren =
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
data: dataProviderDataWithUnsortedChildren
|
|
286
|
-
}, children);
|
|
287
|
-
};
|
|
264
|
+
const wrapperWithUnsortedChildren = ({
|
|
265
|
+
children
|
|
266
|
+
}) => /*#__PURE__*/React.createElement(CustomDataProvider, {
|
|
267
|
+
data: dataProviderDataWithUnsortedChildren
|
|
268
|
+
}, children);
|
|
288
269
|
const options = {
|
|
289
270
|
node: {
|
|
290
271
|
...node,
|
|
@@ -2,21 +2,15 @@ import { useDataQuery } from '@dhis2/app-runtime';
|
|
|
2
2
|
const ORG_DATA_QUERY = {
|
|
3
3
|
orgUnit: {
|
|
4
4
|
resource: `organisationUnits`,
|
|
5
|
-
id:
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
} = _ref2;
|
|
15
|
-
return {
|
|
16
|
-
isUserDataViewFallback,
|
|
17
|
-
fields: ['path', 'children::size']
|
|
18
|
-
};
|
|
19
|
-
}
|
|
5
|
+
id: ({
|
|
6
|
+
id
|
|
7
|
+
}) => id,
|
|
8
|
+
params: ({
|
|
9
|
+
isUserDataViewFallback
|
|
10
|
+
}) => ({
|
|
11
|
+
isUserDataViewFallback,
|
|
12
|
+
fields: ['path', 'children::size']
|
|
13
|
+
})
|
|
20
14
|
}
|
|
21
15
|
};
|
|
22
16
|
|
|
@@ -27,11 +21,10 @@ const ORG_DATA_QUERY = {
|
|
|
27
21
|
* @param {bool} options.isUserDataViewFallback
|
|
28
22
|
* @returns {Object}
|
|
29
23
|
*/
|
|
30
|
-
export const useOrgData = (id,
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
} = _ref3;
|
|
24
|
+
export const useOrgData = (id, {
|
|
25
|
+
displayName,
|
|
26
|
+
isUserDataViewFallback
|
|
27
|
+
}) => {
|
|
35
28
|
if (!displayName) {
|
|
36
29
|
throw new Error('"displayName" is required');
|
|
37
30
|
}
|
|
@@ -5,10 +5,7 @@ import { useOrgData } from './use-org-data.js';
|
|
|
5
5
|
describe('OrganisationUnitTree - useOrgData', () => {
|
|
6
6
|
// @TODO: Figure out why this is necessary at all...
|
|
7
7
|
const origError = console.error;
|
|
8
|
-
jest.spyOn(console, 'error').mockImplementation(
|
|
9
|
-
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
10
|
-
args[_key] = arguments[_key];
|
|
11
|
-
}
|
|
8
|
+
jest.spyOn(console, 'error').mockImplementation((...args) => {
|
|
12
9
|
const [err] = args;
|
|
13
10
|
if (!err.toString().match(/^Warning: An update to/)) {
|
|
14
11
|
origError(...args);
|
|
@@ -18,10 +15,9 @@ describe('OrganisationUnitTree - useOrgData', () => {
|
|
|
18
15
|
console.error.mockRestore();
|
|
19
16
|
});
|
|
20
17
|
const dataProviderData = {
|
|
21
|
-
organisationUnits: jest.fn((type,
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
} = _ref;
|
|
18
|
+
organisationUnits: jest.fn((type, {
|
|
19
|
+
id
|
|
20
|
+
}) => {
|
|
25
21
|
if (id === 'A0000000000') {
|
|
26
22
|
return {
|
|
27
23
|
id: 'A0000000000',
|
|
@@ -32,14 +28,11 @@ describe('OrganisationUnitTree - useOrgData', () => {
|
|
|
32
28
|
return Promise.reject(`No org unit with id "${id}"`);
|
|
33
29
|
})
|
|
34
30
|
};
|
|
35
|
-
const wrapper =
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
data: dataProviderData
|
|
41
|
-
}, children);
|
|
42
|
-
};
|
|
31
|
+
const wrapper = ({
|
|
32
|
+
children
|
|
33
|
+
}) => /*#__PURE__*/React.createElement(CustomDataProvider, {
|
|
34
|
+
data: dataProviderData
|
|
35
|
+
}, children);
|
|
43
36
|
it('should respond with `loading: true`, `error: null` and `data: { displayName, id }` initially', () => {
|
|
44
37
|
const {
|
|
45
38
|
result
|
|
@@ -78,18 +71,15 @@ describe('OrganisationUnitTree - useOrgData', () => {
|
|
|
78
71
|
});
|
|
79
72
|
});
|
|
80
73
|
it('should provide the error', async () => {
|
|
81
|
-
const errorWrapper =
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
organisationUnits: async () => {
|
|
88
|
-
throw new Error('Error message');
|
|
89
|
-
}
|
|
74
|
+
const errorWrapper = ({
|
|
75
|
+
children
|
|
76
|
+
}) => /*#__PURE__*/React.createElement(CustomDataProvider, {
|
|
77
|
+
data: {
|
|
78
|
+
organisationUnits: async () => {
|
|
79
|
+
throw new Error('Error message');
|
|
90
80
|
}
|
|
91
|
-
}
|
|
92
|
-
};
|
|
81
|
+
}
|
|
82
|
+
}, children);
|
|
93
83
|
const {
|
|
94
84
|
result
|
|
95
85
|
} = renderHook(() => useOrgData('A0000000000', {
|
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
import PropTypes from 'prop-types';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import i18n from '../locales/index.js';
|
|
4
|
-
export const OrganisationUnitTreeRootError =
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
nsSeparator: '>'
|
|
14
|
-
}));
|
|
15
|
-
};
|
|
4
|
+
export const OrganisationUnitTreeRootError = ({
|
|
5
|
+
dataTest = 'dhis2-uiwidgets-orgunittree-error',
|
|
6
|
+
error
|
|
7
|
+
}) => /*#__PURE__*/React.createElement("div", {
|
|
8
|
+
"data-test": dataTest
|
|
9
|
+
}, i18n.t('Error: {{ ERRORMESSAGE }}', {
|
|
10
|
+
ERRORMESSAGE: error,
|
|
11
|
+
nsSeparator: '>'
|
|
12
|
+
}));
|
|
16
13
|
OrganisationUnitTreeRootError.propTypes = {
|
|
17
14
|
error: PropTypes.string.isRequired,
|
|
18
15
|
dataTest: PropTypes.string
|
|
@@ -2,19 +2,16 @@ import _JSXStyle from "styled-jsx/style";
|
|
|
2
2
|
import { CircularLoader } from '@dhis2-ui/loader';
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
4
|
import React from 'react';
|
|
5
|
-
export const OrganisationUnitTreeRootLoading =
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
id: "814846266"
|
|
16
|
-
}, ["div.jsx-814846266{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;}"]));
|
|
17
|
-
};
|
|
5
|
+
export const OrganisationUnitTreeRootLoading = ({
|
|
6
|
+
dataTest = 'dhis2-uiwidgets-orgunittree-loading'
|
|
7
|
+
}) => /*#__PURE__*/React.createElement("div", {
|
|
8
|
+
"data-test": dataTest,
|
|
9
|
+
className: "jsx-814846266"
|
|
10
|
+
}, /*#__PURE__*/React.createElement(CircularLoader, {
|
|
11
|
+
small: true
|
|
12
|
+
}), /*#__PURE__*/React.createElement(_JSXStyle, {
|
|
13
|
+
id: "814846266"
|
|
14
|
+
}, ["div.jsx-814846266{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;}"]));
|
|
18
15
|
OrganisationUnitTreeRootLoading.propTypes = {
|
|
19
16
|
dataTest: PropTypes.string
|
|
20
17
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { requiredIf } from '@dhis2/prop-types';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import React, { useEffect, useState } from 'react';
|
|
3
|
+
import React, { useEffect, useMemo, useState } from 'react';
|
|
4
|
+
import { sortNodeChildrenAlphabetically } from '../helpers/index.js';
|
|
4
5
|
import { OrganisationUnitNode } from '../organisation-unit-node/index.js';
|
|
5
6
|
import { orgUnitPathPropType } from '../prop-types.js';
|
|
6
7
|
import { defaultRenderNodeLabel } from './default-render-node-label/index.js';
|
|
@@ -13,30 +14,29 @@ import { useRootOrgData } from './use-root-org-data/index.js';
|
|
|
13
14
|
|
|
14
15
|
// A stable object to reference
|
|
15
16
|
const staticArray = [];
|
|
16
|
-
const OrganisationUnitTree =
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
} = _ref;
|
|
17
|
+
const OrganisationUnitTree = ({
|
|
18
|
+
onChange,
|
|
19
|
+
roots,
|
|
20
|
+
autoExpandLoadingError,
|
|
21
|
+
dataTest = 'dhis2-uiwidgets-orgunittree',
|
|
22
|
+
disableSelection,
|
|
23
|
+
displayProperty = 'displayName',
|
|
24
|
+
forceReload,
|
|
25
|
+
highlighted = staticArray,
|
|
26
|
+
isUserDataViewFallback,
|
|
27
|
+
initiallyExpanded = staticArray,
|
|
28
|
+
filter = staticArray,
|
|
29
|
+
renderNodeLabel = defaultRenderNodeLabel,
|
|
30
|
+
selected = staticArray,
|
|
31
|
+
singleSelection,
|
|
32
|
+
suppressAlphabeticalSorting,
|
|
33
|
+
expanded: expandedControlled,
|
|
34
|
+
handleExpand: handleExpandControlled,
|
|
35
|
+
handleCollapse: handleCollapseControlled,
|
|
36
|
+
onExpand,
|
|
37
|
+
onCollapse,
|
|
38
|
+
onChildrenLoaded
|
|
39
|
+
}) => {
|
|
40
40
|
const rootIds = filterRootIds(filter, Array.isArray(roots) ? roots : [roots]);
|
|
41
41
|
const reloadId = useForceReload(forceReload);
|
|
42
42
|
const [prevReloadId, setPrevReloadId] = useState(reloadId);
|
|
@@ -72,12 +72,19 @@ const OrganisationUnitTree = _ref => {
|
|
|
72
72
|
return () => console.warn('@TODO: Why does this component unmount after a force reload?');
|
|
73
73
|
}, [reloadId, prevReloadId, refetch]);
|
|
74
74
|
const isLoading = !called || loading;
|
|
75
|
+
const sortedRoots = useMemo(() => {
|
|
76
|
+
if (!data) {
|
|
77
|
+
return staticArray;
|
|
78
|
+
}
|
|
79
|
+
const rootNodes = rootIds.map(rootId => data[rootId]);
|
|
80
|
+
return suppressAlphabeticalSorting ? rootNodes : sortNodeChildrenAlphabetically(rootNodes);
|
|
81
|
+
}, [data, rootIds, suppressAlphabeticalSorting]);
|
|
75
82
|
return /*#__PURE__*/React.createElement("div", {
|
|
76
83
|
"data-test": dataTest
|
|
77
84
|
}, isLoading && /*#__PURE__*/React.createElement(OrganisationUnitTreeRootLoading, null), error && /*#__PURE__*/React.createElement(OrganisationUnitTreeRootError, {
|
|
78
85
|
error: error
|
|
79
|
-
}), !error && !isLoading &&
|
|
80
|
-
const
|
|
86
|
+
}), !error && !isLoading && sortedRoots.map(rootNode => {
|
|
87
|
+
const rootId = rootNode.id;
|
|
81
88
|
return /*#__PURE__*/React.createElement(OrganisationUnitNode, {
|
|
82
89
|
key: rootNode.path,
|
|
83
90
|
rootId: rootId,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CustomDataProvider } from '@dhis2/app-runtime';
|
|
2
|
+
import { render } from '@testing-library/react';
|
|
2
3
|
import { shallow } from 'enzyme';
|
|
3
4
|
import React from 'react';
|
|
4
5
|
import { OrganisationUnitTree } from './organisation-unit-tree.js';
|
|
@@ -52,4 +53,74 @@ describe('OrganisationUnitTree', () => {
|
|
|
52
53
|
});
|
|
53
54
|
});
|
|
54
55
|
});
|
|
56
|
+
describe('Root node sorting', () => {
|
|
57
|
+
// displayNames intentionally out of alphabetical order relative to ids
|
|
58
|
+
const rootNodes = {
|
|
59
|
+
A001: {
|
|
60
|
+
id: 'A001',
|
|
61
|
+
path: '/A001',
|
|
62
|
+
displayName: 'Bravo'
|
|
63
|
+
},
|
|
64
|
+
A002: {
|
|
65
|
+
id: 'A002',
|
|
66
|
+
path: '/A002',
|
|
67
|
+
displayName: 'Alpha'
|
|
68
|
+
},
|
|
69
|
+
A003: {
|
|
70
|
+
id: 'A003',
|
|
71
|
+
path: '/A003',
|
|
72
|
+
displayName: 'Charlie'
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
const dataProvider = {
|
|
76
|
+
organisationUnits: (type, {
|
|
77
|
+
id
|
|
78
|
+
}) => {
|
|
79
|
+
const node = rootNodes[id];
|
|
80
|
+
if (node) {
|
|
81
|
+
// children: 0 so nodes don't try to load descendants
|
|
82
|
+
return {
|
|
83
|
+
...node,
|
|
84
|
+
children: 0
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
return Promise.reject(`No org unit with id "${id}"`);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
it('sorts root nodes alphabetically by displayName by default', async () => {
|
|
91
|
+
const {
|
|
92
|
+
container,
|
|
93
|
+
findByText
|
|
94
|
+
} = render(/*#__PURE__*/React.createElement(CustomDataProvider, {
|
|
95
|
+
data: dataProvider
|
|
96
|
+
}, /*#__PURE__*/React.createElement(OrganisationUnitTree, {
|
|
97
|
+
roots: ['A001', 'A002', 'A003'],
|
|
98
|
+
onChange: () => {}
|
|
99
|
+
})));
|
|
100
|
+
await findByText('Alpha');
|
|
101
|
+
const {
|
|
102
|
+
textContent
|
|
103
|
+
} = container;
|
|
104
|
+
expect(textContent.indexOf('Alpha')).toBeLessThan(textContent.indexOf('Bravo'));
|
|
105
|
+
expect(textContent.indexOf('Bravo')).toBeLessThan(textContent.indexOf('Charlie'));
|
|
106
|
+
});
|
|
107
|
+
it('keeps the provided roots order when suppressAlphabeticalSorting is true', async () => {
|
|
108
|
+
const {
|
|
109
|
+
container,
|
|
110
|
+
findByText
|
|
111
|
+
} = render(/*#__PURE__*/React.createElement(CustomDataProvider, {
|
|
112
|
+
data: dataProvider
|
|
113
|
+
}, /*#__PURE__*/React.createElement(OrganisationUnitTree, {
|
|
114
|
+
roots: ['A003', 'A001', 'A002'],
|
|
115
|
+
suppressAlphabeticalSorting: true,
|
|
116
|
+
onChange: () => {}
|
|
117
|
+
})));
|
|
118
|
+
await findByText('Charlie');
|
|
119
|
+
const {
|
|
120
|
+
textContent
|
|
121
|
+
} = container;
|
|
122
|
+
expect(textContent.indexOf('Charlie')).toBeLessThan(textContent.indexOf('Bravo'));
|
|
123
|
+
expect(textContent.indexOf('Bravo')).toBeLessThan(textContent.indexOf('Alpha'));
|
|
124
|
+
});
|
|
125
|
+
});
|
|
55
126
|
});
|
|
@@ -6,18 +6,16 @@
|
|
|
6
6
|
* @param {Function} [args.onCollapse]
|
|
7
7
|
* @returns {{ handleExpand: Function, handleCollapse: Function }}
|
|
8
8
|
*/
|
|
9
|
-
export const createExpandHandlers =
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
...rest
|
|
20
|
-
} = _ref2;
|
|
9
|
+
export const createExpandHandlers = ({
|
|
10
|
+
expanded,
|
|
11
|
+
setExpanded,
|
|
12
|
+
onExpand,
|
|
13
|
+
onCollapse
|
|
14
|
+
}) => {
|
|
15
|
+
const handleExpand = ({
|
|
16
|
+
path,
|
|
17
|
+
...rest
|
|
18
|
+
}) => {
|
|
21
19
|
if (!expanded.includes(path)) {
|
|
22
20
|
setExpanded([...expanded, path]);
|
|
23
21
|
if (onExpand) {
|
|
@@ -28,11 +26,10 @@ export const createExpandHandlers = _ref => {
|
|
|
28
26
|
}
|
|
29
27
|
}
|
|
30
28
|
};
|
|
31
|
-
const handleCollapse =
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
} = _ref3;
|
|
29
|
+
const handleCollapse = ({
|
|
30
|
+
path,
|
|
31
|
+
...rest
|
|
32
|
+
}) => {
|
|
36
33
|
const pathIndex = expanded.indexOf(path);
|
|
37
34
|
if (pathIndex !== -1) {
|
|
38
35
|
const updatedExpanded = pathIndex === 0 ? expanded.slice(1) : [...expanded.slice(0, pathIndex), ...expanded.slice(pathIndex + 1)];
|
|
@@ -8,15 +8,14 @@ import { createExpandHandlers } from './create-expand-handlers.js';
|
|
|
8
8
|
* @param {Function} [onCollapse]
|
|
9
9
|
* @returns {{ expanded: string[], handleExpand: Function, handleCollapse: Function }}
|
|
10
10
|
*/
|
|
11
|
-
export const useExpanded =
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
} = _ref;
|
|
11
|
+
export const useExpanded = ({
|
|
12
|
+
initiallyExpanded,
|
|
13
|
+
onExpand,
|
|
14
|
+
onCollapse,
|
|
15
|
+
expandedControlled,
|
|
16
|
+
handleExpandControlled,
|
|
17
|
+
handleCollapseControlled
|
|
18
|
+
}) => {
|
|
20
19
|
const isControlled = !!expandedControlled;
|
|
21
20
|
const allInitiallyExpandedPaths = isControlled ? [] : getAllExpandedPaths(initiallyExpanded);
|
|
22
21
|
const [expanded, setExpanded] = useState(allInitiallyExpandedPaths);
|
|
@@ -11,8 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
export const patchMissingDisplayName = nodes => {
|
|
13
13
|
const nodeEntries = Object.entries(nodes);
|
|
14
|
-
const nodesWithDisplayName = nodeEntries.map(
|
|
15
|
-
let [id, node] = _ref;
|
|
14
|
+
const nodesWithDisplayName = nodeEntries.map(([id, node]) => {
|
|
16
15
|
const displayName = node.displayName || '';
|
|
17
16
|
return [id, {
|
|
18
17
|
...node,
|
|
@@ -6,15 +6,12 @@ export const createRootQuery = (ids, displayProperty) => ids.reduce((query, id)
|
|
|
6
6
|
[id]: {
|
|
7
7
|
id,
|
|
8
8
|
resource: `organisationUnits`,
|
|
9
|
-
params:
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
fields: [displayProperty === 'displayName' ? 'displayName' : `${displayProperty}~rename(displayName)`, 'path', 'id']
|
|
16
|
-
};
|
|
17
|
-
}
|
|
9
|
+
params: ({
|
|
10
|
+
isUserDataViewFallback
|
|
11
|
+
}) => ({
|
|
12
|
+
isUserDataViewFallback,
|
|
13
|
+
fields: [displayProperty === 'displayName' ? 'displayName' : `${displayProperty}~rename(displayName)`, 'path', 'id']
|
|
14
|
+
})
|
|
18
15
|
}
|
|
19
16
|
}), {});
|
|
20
17
|
|
|
@@ -26,11 +23,10 @@ export const createRootQuery = (ids, displayProperty) => ids.reduce((query, id)
|
|
|
26
23
|
* @param {'displayName'|'displayShortName'} [options.displayProperty]
|
|
27
24
|
* @returns {Object}
|
|
28
25
|
*/
|
|
29
|
-
export const useRootOrgData =
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
} = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
26
|
+
export const useRootOrgData = (ids, {
|
|
27
|
+
isUserDataViewFallback,
|
|
28
|
+
displayProperty = 'displayName'
|
|
29
|
+
} = {}) => {
|
|
34
30
|
const query = useMemo(() => createRootQuery(ids, displayProperty), [ids, displayProperty]);
|
|
35
31
|
const variables = {
|
|
36
32
|
isUserDataViewFallback
|