@dhis2-ui/organisation-unit-tree 7.16.3 → 8.0.2
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__/common.js +51 -24
- package/build/cjs/__e2e__/tree_api.stories.e2e.js +13 -5
- package/build/cjs/__stories__/development-stories.js +1 -3
- package/build/cjs/__stories__/shared.js +50 -17
- package/build/cjs/features/controlled_expanded/index.js +9 -3
- package/build/cjs/features/tree_api/index.js +4 -3
- package/build/cjs/helpers/sort-node-children-alphabetically.js +2 -17
- package/build/cjs/locales/ar/translations.json +1 -0
- package/build/cjs/locales/cs/translations.json +1 -0
- package/build/cjs/locales/en/translations.json +3 -2
- package/build/cjs/locales/es/translations.json +1 -0
- package/build/cjs/locales/nb/translations.json +1 -0
- package/build/cjs/locales/uz/translations.json +1 -0
- package/build/cjs/locales/uz_Latn/translations.json +1 -0
- package/build/cjs/locales/vi/translations.json +1 -0
- package/build/cjs/locales/zh/translations.json +1 -0
- package/build/cjs/locales/zh_CN/translations.json +1 -0
- package/build/cjs/organisation-unit-node/label/label.js +2 -5
- package/build/cjs/organisation-unit-node/loading-spinner.js +32 -0
- package/build/cjs/organisation-unit-node/organisation-unit-node-children.js +120 -0
- package/build/cjs/organisation-unit-node/organisation-unit-node.js +43 -68
- package/build/cjs/organisation-unit-node/use-org-children.js +81 -0
- package/build/cjs/organisation-unit-node/use-org-children.test.js +319 -0
- package/build/cjs/organisation-unit-node/use-org-data/use-org-data.js +10 -33
- package/build/cjs/organisation-unit-node/use-org-data/use-org-data.test.js +3 -169
- package/build/cjs/organisation-unit-tree/organisation-unit-tree.js +4 -2
- package/build/cjs/organisation-unit-tree/use-root-org-data/use-root-org-data.js +7 -5
- package/build/es/__e2e__/common.js +52 -24
- package/build/es/__e2e__/tree_api.stories.e2e.js +13 -5
- package/build/es/__stories__/development-stories.js +1 -3
- package/build/es/__stories__/shared.js +51 -17
- package/build/es/features/controlled_expanded/index.js +9 -3
- package/build/es/features/tree_api/index.js +4 -3
- package/build/es/helpers/sort-node-children-alphabetically.js +2 -17
- package/build/es/locales/ar/translations.json +1 -0
- package/build/es/locales/cs/translations.json +1 -0
- package/build/es/locales/en/translations.json +3 -2
- package/build/es/locales/es/translations.json +1 -0
- package/build/es/locales/nb/translations.json +1 -0
- package/build/es/locales/uz/translations.json +1 -0
- package/build/es/locales/uz_Latn/translations.json +1 -0
- package/build/es/locales/vi/translations.json +1 -0
- package/build/es/locales/zh/translations.json +1 -0
- package/build/es/locales/zh_CN/translations.json +1 -0
- package/build/es/organisation-unit-node/label/label.js +2 -5
- package/build/es/organisation-unit-node/loading-spinner.js +17 -0
- package/build/es/organisation-unit-node/organisation-unit-node-children.js +103 -0
- package/build/es/organisation-unit-node/organisation-unit-node.js +41 -65
- package/build/es/organisation-unit-node/use-org-children.js +69 -0
- package/build/es/organisation-unit-node/use-org-children.test.js +311 -0
- package/build/es/organisation-unit-node/use-org-data/use-org-data.js +10 -31
- package/build/es/organisation-unit-node/use-org-data/use-org-data.test.js +3 -169
- package/build/es/organisation-unit-tree/organisation-unit-tree.js +4 -2
- package/build/es/organisation-unit-tree/use-root-org-data/use-root-org-data.js +7 -5
- package/package.json +5 -5
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
import { CustomDataProvider } from '@dhis2/app-runtime';
|
|
2
|
+
import { renderHook } from '@testing-library/react-hooks';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { useOrgChildren } from './use-org-children.js';
|
|
5
|
+
describe('OrganisationUnitTree - useOrgChildren', () => {
|
|
6
|
+
const dataProviderData = {
|
|
7
|
+
organisationUnits: jest.fn((type, {
|
|
8
|
+
id
|
|
9
|
+
}) => {
|
|
10
|
+
if (id === 'A0000000000') {
|
|
11
|
+
return {
|
|
12
|
+
children: [{
|
|
13
|
+
id: 'A0000000001',
|
|
14
|
+
path: '/A0000000000/A0000000001',
|
|
15
|
+
children: [],
|
|
16
|
+
displayName: 'Org Unit 2'
|
|
17
|
+
}]
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return Promise.reject(`No org unit with id "${id}"`);
|
|
22
|
+
})
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const wrapper = ({
|
|
26
|
+
children
|
|
27
|
+
}) => /*#__PURE__*/React.createElement(CustomDataProvider, {
|
|
28
|
+
data: dataProviderData
|
|
29
|
+
}, children);
|
|
30
|
+
|
|
31
|
+
const node = {
|
|
32
|
+
id: 'A0000000000',
|
|
33
|
+
path: '/A0000000000',
|
|
34
|
+
displayName: 'Org Unit 1',
|
|
35
|
+
children: 1
|
|
36
|
+
};
|
|
37
|
+
it('should respond with `loading: true`, `error: null` and `data: null` initially', async () => {
|
|
38
|
+
const {
|
|
39
|
+
result,
|
|
40
|
+
waitForNextUpdate
|
|
41
|
+
} = renderHook(() => useOrgChildren({
|
|
42
|
+
node
|
|
43
|
+
}), {
|
|
44
|
+
wrapper
|
|
45
|
+
});
|
|
46
|
+
expect(result.current).toEqual({
|
|
47
|
+
called: true,
|
|
48
|
+
loading: true,
|
|
49
|
+
error: null,
|
|
50
|
+
data: undefined
|
|
51
|
+
}); // Prevent the following error log with
|
|
52
|
+
// "Warning: An update to TestComponent inside a test was not wrapped
|
|
53
|
+
// in act(...)."
|
|
54
|
+
|
|
55
|
+
await waitForNextUpdate();
|
|
56
|
+
});
|
|
57
|
+
it('should provide the org unit data', async () => {
|
|
58
|
+
const {
|
|
59
|
+
result,
|
|
60
|
+
waitForNextUpdate
|
|
61
|
+
} = renderHook(() => useOrgChildren({
|
|
62
|
+
node
|
|
63
|
+
}), {
|
|
64
|
+
wrapper
|
|
65
|
+
});
|
|
66
|
+
await waitForNextUpdate();
|
|
67
|
+
expect(result.current).toEqual({
|
|
68
|
+
called: true,
|
|
69
|
+
loading: false,
|
|
70
|
+
error: null,
|
|
71
|
+
data: [{
|
|
72
|
+
id: 'A0000000001',
|
|
73
|
+
path: '/A0000000000/A0000000001',
|
|
74
|
+
children: [],
|
|
75
|
+
displayName: 'Org Unit 2'
|
|
76
|
+
}]
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
it('should provide the error', async () => {
|
|
80
|
+
const errorWrapper = ({
|
|
81
|
+
children
|
|
82
|
+
}) => /*#__PURE__*/React.createElement(CustomDataProvider, {
|
|
83
|
+
data: {
|
|
84
|
+
organisationUnits: async () => {
|
|
85
|
+
throw new Error('Error message');
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}, children);
|
|
89
|
+
|
|
90
|
+
const {
|
|
91
|
+
result,
|
|
92
|
+
waitForNextUpdate
|
|
93
|
+
} = renderHook(() => useOrgChildren({
|
|
94
|
+
node
|
|
95
|
+
}), {
|
|
96
|
+
wrapper: errorWrapper
|
|
97
|
+
});
|
|
98
|
+
await waitForNextUpdate();
|
|
99
|
+
expect(result.current).toEqual({
|
|
100
|
+
called: true,
|
|
101
|
+
loading: false,
|
|
102
|
+
error: new Error('Error message'),
|
|
103
|
+
data: undefined
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
it('should call the onComplete callback', async () => {
|
|
107
|
+
const onComplete = jest.fn();
|
|
108
|
+
const options = {
|
|
109
|
+
onComplete,
|
|
110
|
+
node
|
|
111
|
+
};
|
|
112
|
+
const {
|
|
113
|
+
waitForNextUpdate
|
|
114
|
+
} = renderHook(() => useOrgChildren(options), {
|
|
115
|
+
wrapper
|
|
116
|
+
});
|
|
117
|
+
await waitForNextUpdate();
|
|
118
|
+
expect(onComplete).toHaveBeenCalledWith({
|
|
119
|
+
id: 'A0000000000',
|
|
120
|
+
path: '/A0000000000',
|
|
121
|
+
displayName: 'Org Unit 1',
|
|
122
|
+
children: [{
|
|
123
|
+
id: 'A0000000001',
|
|
124
|
+
path: '/A0000000000/A0000000001',
|
|
125
|
+
children: [],
|
|
126
|
+
displayName: 'Org Unit 2'
|
|
127
|
+
}]
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
it("should sort the node's children alphabetically by default", async () => {
|
|
131
|
+
const dataProviderDataWithUnsortedChildren = {
|
|
132
|
+
organisationUnits: jest.fn((type, {
|
|
133
|
+
id
|
|
134
|
+
}) => {
|
|
135
|
+
if (id === 'A0000000000') {
|
|
136
|
+
return {
|
|
137
|
+
children: [{
|
|
138
|
+
id: 'A0000000002',
|
|
139
|
+
path: '/A0000000000/A0000000002',
|
|
140
|
+
children: [],
|
|
141
|
+
displayName: 'Org Unit 3'
|
|
142
|
+
}, {
|
|
143
|
+
id: 'A0000000001',
|
|
144
|
+
path: '/A0000000000/A0000000001',
|
|
145
|
+
children: [],
|
|
146
|
+
displayName: 'Org Unit 2'
|
|
147
|
+
}]
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return Promise.reject(`No org unit with id "${id}"`);
|
|
152
|
+
})
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
const wrapperWithUnsortedChildren = ({
|
|
156
|
+
children
|
|
157
|
+
}) => /*#__PURE__*/React.createElement(CustomDataProvider, {
|
|
158
|
+
data: dataProviderDataWithUnsortedChildren
|
|
159
|
+
}, children);
|
|
160
|
+
|
|
161
|
+
const {
|
|
162
|
+
result,
|
|
163
|
+
waitForNextUpdate
|
|
164
|
+
} = renderHook(() => useOrgChildren({
|
|
165
|
+
node: { ...node,
|
|
166
|
+
children: 2
|
|
167
|
+
}
|
|
168
|
+
}), {
|
|
169
|
+
wrapper: wrapperWithUnsortedChildren
|
|
170
|
+
});
|
|
171
|
+
await waitForNextUpdate();
|
|
172
|
+
expect(result.current).toEqual({
|
|
173
|
+
called: true,
|
|
174
|
+
loading: false,
|
|
175
|
+
error: null,
|
|
176
|
+
data: [{
|
|
177
|
+
id: 'A0000000001',
|
|
178
|
+
path: '/A0000000000/A0000000001',
|
|
179
|
+
children: [],
|
|
180
|
+
displayName: 'Org Unit 2'
|
|
181
|
+
}, {
|
|
182
|
+
id: 'A0000000002',
|
|
183
|
+
path: '/A0000000000/A0000000002',
|
|
184
|
+
children: [],
|
|
185
|
+
displayName: 'Org Unit 3'
|
|
186
|
+
}]
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
it(`should not sort the node's children alphabetically when "suppressAlphabeticalSorting" is true`, async () => {
|
|
190
|
+
const dataProviderDataWithUnsortedChildren = {
|
|
191
|
+
organisationUnits: jest.fn((type, {
|
|
192
|
+
id
|
|
193
|
+
}) => {
|
|
194
|
+
if (id === 'A0000000000') {
|
|
195
|
+
return {
|
|
196
|
+
children: [{
|
|
197
|
+
id: 'A0000000002',
|
|
198
|
+
path: '/A0000000000/A0000000002',
|
|
199
|
+
children: [],
|
|
200
|
+
displayName: 'Org Unit 3'
|
|
201
|
+
}, {
|
|
202
|
+
id: 'A0000000001',
|
|
203
|
+
path: '/A0000000000/A0000000001',
|
|
204
|
+
children: [],
|
|
205
|
+
displayName: 'Org Unit 2'
|
|
206
|
+
}]
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return Promise.reject(`No org unit with id "${id}"`);
|
|
211
|
+
})
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
const wrapperWithUnsortedChildren = ({
|
|
215
|
+
children
|
|
216
|
+
}) => /*#__PURE__*/React.createElement(CustomDataProvider, {
|
|
217
|
+
data: dataProviderDataWithUnsortedChildren
|
|
218
|
+
}, children);
|
|
219
|
+
|
|
220
|
+
const options = {
|
|
221
|
+
node: { ...node,
|
|
222
|
+
children: 2
|
|
223
|
+
},
|
|
224
|
+
suppressAlphabeticalSorting: true
|
|
225
|
+
};
|
|
226
|
+
const {
|
|
227
|
+
result,
|
|
228
|
+
waitForNextUpdate
|
|
229
|
+
} = renderHook(() => useOrgChildren(options), {
|
|
230
|
+
wrapper: wrapperWithUnsortedChildren
|
|
231
|
+
});
|
|
232
|
+
await waitForNextUpdate();
|
|
233
|
+
expect(result.current).toEqual({
|
|
234
|
+
called: true,
|
|
235
|
+
loading: false,
|
|
236
|
+
error: null,
|
|
237
|
+
data: [{
|
|
238
|
+
id: 'A0000000002',
|
|
239
|
+
path: '/A0000000000/A0000000002',
|
|
240
|
+
children: [],
|
|
241
|
+
displayName: 'Org Unit 3'
|
|
242
|
+
}, {
|
|
243
|
+
id: 'A0000000001',
|
|
244
|
+
path: '/A0000000000/A0000000001',
|
|
245
|
+
children: [],
|
|
246
|
+
displayName: 'Org Unit 2'
|
|
247
|
+
}]
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
it(`should not sort the node's children alphabetically when "suppressAlphabeticalSorting" is true`, async () => {
|
|
251
|
+
const dataProviderDataWithUnsortedChildren = {
|
|
252
|
+
organisationUnits: jest.fn((type, {
|
|
253
|
+
id
|
|
254
|
+
}) => {
|
|
255
|
+
if (id === 'A0000000000') {
|
|
256
|
+
return {
|
|
257
|
+
children: [{
|
|
258
|
+
id: 'A0000000002',
|
|
259
|
+
path: '/A0000000000/A0000000002',
|
|
260
|
+
children: [],
|
|
261
|
+
displayName: 'Org Unit 3'
|
|
262
|
+
}, {
|
|
263
|
+
id: 'A0000000001',
|
|
264
|
+
path: '/A0000000000/A0000000001',
|
|
265
|
+
children: [],
|
|
266
|
+
displayName: 'Org Unit 2'
|
|
267
|
+
}]
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return Promise.reject(`No org unit with id "${id}"`);
|
|
272
|
+
})
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
const wrapperWithUnsortedChildren = ({
|
|
276
|
+
children
|
|
277
|
+
}) => /*#__PURE__*/React.createElement(CustomDataProvider, {
|
|
278
|
+
data: dataProviderDataWithUnsortedChildren
|
|
279
|
+
}, children);
|
|
280
|
+
|
|
281
|
+
const options = {
|
|
282
|
+
node: { ...node,
|
|
283
|
+
children: 2
|
|
284
|
+
},
|
|
285
|
+
suppressAlphabeticalSorting: true
|
|
286
|
+
};
|
|
287
|
+
const {
|
|
288
|
+
result,
|
|
289
|
+
waitForNextUpdate
|
|
290
|
+
} = renderHook(() => useOrgChildren(options), {
|
|
291
|
+
wrapper: wrapperWithUnsortedChildren
|
|
292
|
+
});
|
|
293
|
+
await waitForNextUpdate();
|
|
294
|
+
expect(result.current).toEqual({
|
|
295
|
+
called: true,
|
|
296
|
+
loading: false,
|
|
297
|
+
error: null,
|
|
298
|
+
data: [{
|
|
299
|
+
id: 'A0000000002',
|
|
300
|
+
path: '/A0000000000/A0000000002',
|
|
301
|
+
children: [],
|
|
302
|
+
displayName: 'Org Unit 3'
|
|
303
|
+
}, {
|
|
304
|
+
id: 'A0000000001',
|
|
305
|
+
path: '/A0000000000/A0000000001',
|
|
306
|
+
children: [],
|
|
307
|
+
displayName: 'Org Unit 2'
|
|
308
|
+
}]
|
|
309
|
+
});
|
|
310
|
+
});
|
|
311
|
+
});
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { useDataQuery } from '@dhis2/app-runtime';
|
|
2
|
-
import { useMemo, useEffect } from 'react';
|
|
3
|
-
import { sortNodeChildrenAlphabetically } from '../../helpers/index.js';
|
|
4
2
|
const ORG_DATA_QUERY = {
|
|
5
3
|
orgUnit: {
|
|
6
4
|
resource: `organisationUnits`,
|
|
@@ -11,7 +9,7 @@ const ORG_DATA_QUERY = {
|
|
|
11
9
|
isUserDataViewFallback
|
|
12
10
|
}) => ({
|
|
13
11
|
isUserDataViewFallback,
|
|
14
|
-
fields: ['
|
|
12
|
+
fields: ['path', 'children::size']
|
|
15
13
|
})
|
|
16
14
|
}
|
|
17
15
|
};
|
|
@@ -19,24 +17,18 @@ const ORG_DATA_QUERY = {
|
|
|
19
17
|
* @param {string[]} ids
|
|
20
18
|
* @param {Object} options
|
|
21
19
|
* @param {string} options.displayName
|
|
22
|
-
* @param {
|
|
20
|
+
* @param {bool} options.isUserDataViewFallback
|
|
23
21
|
* @returns {Object}
|
|
24
22
|
*/
|
|
25
23
|
|
|
26
24
|
export const useOrgData = (id, {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
onComplete,
|
|
30
|
-
displayName
|
|
25
|
+
displayName,
|
|
26
|
+
isUserDataViewFallback
|
|
31
27
|
}) => {
|
|
32
28
|
if (!displayName) {
|
|
33
29
|
throw new Error('"displayName" is required');
|
|
34
30
|
}
|
|
35
31
|
|
|
36
|
-
const defaultData = {
|
|
37
|
-
id,
|
|
38
|
-
displayName
|
|
39
|
-
};
|
|
40
32
|
const variables = {
|
|
41
33
|
id,
|
|
42
34
|
isUserDataViewFallback
|
|
@@ -44,30 +36,17 @@ export const useOrgData = (id, {
|
|
|
44
36
|
const {
|
|
45
37
|
loading,
|
|
46
38
|
error,
|
|
47
|
-
data
|
|
39
|
+
data = {}
|
|
48
40
|
} = useDataQuery(ORG_DATA_QUERY, {
|
|
49
41
|
variables
|
|
50
42
|
});
|
|
51
|
-
const transformedData = useMemo(() => {
|
|
52
|
-
if (!data) {
|
|
53
|
-
return defaultData;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const {
|
|
57
|
-
orgUnit: node
|
|
58
|
-
} = data;
|
|
59
|
-
const transformed = suppressAlphabeticalSorting ? node : sortNodeChildrenAlphabetically(node);
|
|
60
|
-
const merged = { ...defaultData,
|
|
61
|
-
...transformed
|
|
62
|
-
};
|
|
63
|
-
return merged;
|
|
64
|
-
}, [data, suppressAlphabeticalSorting, id, displayName]);
|
|
65
|
-
useEffect(() => {
|
|
66
|
-
onComplete && onComplete(transformedData);
|
|
67
|
-
}, [onComplete, transformedData]);
|
|
68
43
|
return {
|
|
69
44
|
loading,
|
|
70
45
|
error: error || null,
|
|
71
|
-
data:
|
|
46
|
+
data: {
|
|
47
|
+
id,
|
|
48
|
+
displayName,
|
|
49
|
+
...data.orgUnit
|
|
50
|
+
}
|
|
72
51
|
};
|
|
73
52
|
};
|
|
@@ -23,13 +23,7 @@ describe('OrganisationUnitTree - useOrgData', () => {
|
|
|
23
23
|
return {
|
|
24
24
|
id: 'A0000000000',
|
|
25
25
|
path: '/A0000000000',
|
|
26
|
-
displayName: 'Org Unit 1'
|
|
27
|
-
children: [{
|
|
28
|
-
id: 'A0000000001',
|
|
29
|
-
path: '/A0000000000/A0000000001',
|
|
30
|
-
children: [],
|
|
31
|
-
displayName: 'Org Unit 2'
|
|
32
|
-
}]
|
|
26
|
+
displayName: 'Org Unit 1'
|
|
33
27
|
};
|
|
34
28
|
}
|
|
35
29
|
|
|
@@ -43,7 +37,7 @@ describe('OrganisationUnitTree - useOrgData', () => {
|
|
|
43
37
|
data: dataProviderData
|
|
44
38
|
}, children);
|
|
45
39
|
|
|
46
|
-
it('should respond with `loading:
|
|
40
|
+
it('should respond with `loading: true`, `error: null` and `data: { displayName, id }` initially', () => {
|
|
47
41
|
const {
|
|
48
42
|
result
|
|
49
43
|
} = renderHook(() => useOrgData('A0000000000', {
|
|
@@ -76,13 +70,7 @@ describe('OrganisationUnitTree - useOrgData', () => {
|
|
|
76
70
|
data: {
|
|
77
71
|
id: 'A0000000000',
|
|
78
72
|
path: '/A0000000000',
|
|
79
|
-
displayName: 'Org Unit 1'
|
|
80
|
-
children: [{
|
|
81
|
-
id: 'A0000000001',
|
|
82
|
-
path: '/A0000000000/A0000000001',
|
|
83
|
-
children: [],
|
|
84
|
-
displayName: 'Org Unit 2'
|
|
85
|
-
}]
|
|
73
|
+
displayName: 'Org Unit 1'
|
|
86
74
|
}
|
|
87
75
|
});
|
|
88
76
|
});
|
|
@@ -115,30 +103,6 @@ describe('OrganisationUnitTree - useOrgData', () => {
|
|
|
115
103
|
}
|
|
116
104
|
});
|
|
117
105
|
});
|
|
118
|
-
it('should call the onComplete callback', async () => {
|
|
119
|
-
const onComplete = jest.fn();
|
|
120
|
-
const options = {
|
|
121
|
-
onComplete,
|
|
122
|
-
displayName: 'Display name'
|
|
123
|
-
};
|
|
124
|
-
const {
|
|
125
|
-
waitForNextUpdate
|
|
126
|
-
} = renderHook(() => useOrgData('A0000000000', options), {
|
|
127
|
-
wrapper
|
|
128
|
-
});
|
|
129
|
-
await waitForNextUpdate();
|
|
130
|
-
expect(onComplete).toHaveBeenCalledWith({
|
|
131
|
-
id: 'A0000000000',
|
|
132
|
-
path: '/A0000000000',
|
|
133
|
-
displayName: 'Org Unit 1',
|
|
134
|
-
children: [{
|
|
135
|
-
id: 'A0000000001',
|
|
136
|
-
path: '/A0000000000/A0000000001',
|
|
137
|
-
children: [],
|
|
138
|
-
displayName: 'Org Unit 2'
|
|
139
|
-
}]
|
|
140
|
-
});
|
|
141
|
-
});
|
|
142
106
|
it('should send the "isUserDataViewFallback" parameter with value "undefined"', async () => {
|
|
143
107
|
const options = {
|
|
144
108
|
displayName: 'Display name'
|
|
@@ -174,134 +138,4 @@ describe('OrganisationUnitTree - useOrgData', () => {
|
|
|
174
138
|
}), expect.objectContaining({}) // contains the `signal`
|
|
175
139
|
);
|
|
176
140
|
});
|
|
177
|
-
it("should sort the node's children alphabetically by default", async () => {
|
|
178
|
-
const dataProviderDataWithUnsortedChildren = {
|
|
179
|
-
organisationUnits: jest.fn((type, {
|
|
180
|
-
id
|
|
181
|
-
}) => {
|
|
182
|
-
if (id === 'A0000000000') {
|
|
183
|
-
return {
|
|
184
|
-
id: 'A0000000000',
|
|
185
|
-
path: '/A0000000000',
|
|
186
|
-
displayName: 'Org Unit 1',
|
|
187
|
-
children: [{
|
|
188
|
-
id: 'A0000000002',
|
|
189
|
-
path: '/A0000000000/A0000000002',
|
|
190
|
-
children: [],
|
|
191
|
-
displayName: 'Org Unit 3'
|
|
192
|
-
}, {
|
|
193
|
-
id: 'A0000000001',
|
|
194
|
-
path: '/A0000000000/A0000000001',
|
|
195
|
-
children: [],
|
|
196
|
-
displayName: 'Org Unit 2'
|
|
197
|
-
}]
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
return Promise.reject(`No org unit with id "${id}"`);
|
|
202
|
-
})
|
|
203
|
-
};
|
|
204
|
-
|
|
205
|
-
const wrapperWithUnsortedChildren = ({
|
|
206
|
-
children
|
|
207
|
-
}) => /*#__PURE__*/React.createElement(CustomDataProvider, {
|
|
208
|
-
data: dataProviderDataWithUnsortedChildren
|
|
209
|
-
}, children);
|
|
210
|
-
|
|
211
|
-
const {
|
|
212
|
-
result,
|
|
213
|
-
waitForNextUpdate
|
|
214
|
-
} = renderHook(() => useOrgData('A0000000000', {
|
|
215
|
-
displayName: 'Display name'
|
|
216
|
-
}), {
|
|
217
|
-
wrapper: wrapperWithUnsortedChildren
|
|
218
|
-
});
|
|
219
|
-
await waitForNextUpdate();
|
|
220
|
-
expect(result.current).toEqual({
|
|
221
|
-
loading: false,
|
|
222
|
-
error: null,
|
|
223
|
-
data: {
|
|
224
|
-
id: 'A0000000000',
|
|
225
|
-
path: '/A0000000000',
|
|
226
|
-
displayName: 'Org Unit 1',
|
|
227
|
-
children: [{
|
|
228
|
-
id: 'A0000000001',
|
|
229
|
-
path: '/A0000000000/A0000000001',
|
|
230
|
-
children: [],
|
|
231
|
-
displayName: 'Org Unit 2'
|
|
232
|
-
}, {
|
|
233
|
-
id: 'A0000000002',
|
|
234
|
-
path: '/A0000000000/A0000000002',
|
|
235
|
-
children: [],
|
|
236
|
-
displayName: 'Org Unit 3'
|
|
237
|
-
}]
|
|
238
|
-
}
|
|
239
|
-
});
|
|
240
|
-
});
|
|
241
|
-
it(`should not sort the node's children alphabetically when "suppressAlphabeticalSorting" is true`, async () => {
|
|
242
|
-
const dataProviderDataWithUnsortedChildren = {
|
|
243
|
-
organisationUnits: jest.fn((type, {
|
|
244
|
-
id
|
|
245
|
-
}) => {
|
|
246
|
-
if (id === 'A0000000000') {
|
|
247
|
-
return {
|
|
248
|
-
id: 'A0000000000',
|
|
249
|
-
path: '/A0000000000',
|
|
250
|
-
displayName: 'Org Unit 1',
|
|
251
|
-
children: [{
|
|
252
|
-
id: 'A0000000002',
|
|
253
|
-
path: '/A0000000000/A0000000002',
|
|
254
|
-
children: [],
|
|
255
|
-
displayName: 'Org Unit 3'
|
|
256
|
-
}, {
|
|
257
|
-
id: 'A0000000001',
|
|
258
|
-
path: '/A0000000000/A0000000001',
|
|
259
|
-
children: [],
|
|
260
|
-
displayName: 'Org Unit 2'
|
|
261
|
-
}]
|
|
262
|
-
};
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
return Promise.reject(`No org unit with id "${id}"`);
|
|
266
|
-
})
|
|
267
|
-
};
|
|
268
|
-
|
|
269
|
-
const wrapperWithUnsortedChildren = ({
|
|
270
|
-
children
|
|
271
|
-
}) => /*#__PURE__*/React.createElement(CustomDataProvider, {
|
|
272
|
-
data: dataProviderDataWithUnsortedChildren
|
|
273
|
-
}, children);
|
|
274
|
-
|
|
275
|
-
const options = {
|
|
276
|
-
displayName: 'Display name',
|
|
277
|
-
suppressAlphabeticalSorting: true
|
|
278
|
-
};
|
|
279
|
-
const {
|
|
280
|
-
result,
|
|
281
|
-
waitForNextUpdate
|
|
282
|
-
} = renderHook(() => useOrgData('A0000000000', options), {
|
|
283
|
-
wrapper: wrapperWithUnsortedChildren
|
|
284
|
-
});
|
|
285
|
-
await waitForNextUpdate();
|
|
286
|
-
expect(result.current).toEqual({
|
|
287
|
-
loading: false,
|
|
288
|
-
error: null,
|
|
289
|
-
data: {
|
|
290
|
-
id: 'A0000000000',
|
|
291
|
-
path: '/A0000000000',
|
|
292
|
-
displayName: 'Org Unit 1',
|
|
293
|
-
children: [{
|
|
294
|
-
id: 'A0000000002',
|
|
295
|
-
path: '/A0000000000/A0000000002',
|
|
296
|
-
children: [],
|
|
297
|
-
displayName: 'Org Unit 3'
|
|
298
|
-
}, {
|
|
299
|
-
id: 'A0000000001',
|
|
300
|
-
path: '/A0000000000/A0000000001',
|
|
301
|
-
children: [],
|
|
302
|
-
displayName: 'Org Unit 2'
|
|
303
|
-
}]
|
|
304
|
-
}
|
|
305
|
-
});
|
|
306
|
-
});
|
|
307
141
|
});
|
|
@@ -37,6 +37,7 @@ const OrganisationUnitTree = ({
|
|
|
37
37
|
const reloadId = useForceReload(forceReload);
|
|
38
38
|
const [prevReloadId, setPrevReloadId] = useState(reloadId);
|
|
39
39
|
const {
|
|
40
|
+
called,
|
|
40
41
|
loading,
|
|
41
42
|
error,
|
|
42
43
|
data,
|
|
@@ -66,11 +67,12 @@ const OrganisationUnitTree = ({
|
|
|
66
67
|
|
|
67
68
|
return () => console.warn('@TODO: Why does this component unmount after a force reload?');
|
|
68
69
|
}, [reloadId, prevReloadId, refetch]);
|
|
70
|
+
const isLoading = !called || loading;
|
|
69
71
|
return /*#__PURE__*/React.createElement("div", {
|
|
70
72
|
"data-test": dataTest
|
|
71
|
-
},
|
|
73
|
+
}, isLoading && /*#__PURE__*/React.createElement(RootLoading, null), error && /*#__PURE__*/React.createElement(RootError, {
|
|
72
74
|
error: error
|
|
73
|
-
}), !error && !
|
|
75
|
+
}), !error && !isLoading && rootIds.map(rootId => {
|
|
74
76
|
const rootNode = data[rootId];
|
|
75
77
|
return /*#__PURE__*/React.createElement(OrganisationUnitNode, {
|
|
76
78
|
key: rootNode.path,
|
|
@@ -9,8 +9,7 @@ export const createRootQuery = ids => ids.reduce((query, id) => ({ ...query,
|
|
|
9
9
|
isUserDataViewFallback
|
|
10
10
|
}) => ({
|
|
11
11
|
isUserDataViewFallback,
|
|
12
|
-
fields: ['displayName', 'path', 'id']
|
|
13
|
-
paging: false
|
|
12
|
+
fields: ['displayName', 'path', 'id']
|
|
14
13
|
})
|
|
15
14
|
}
|
|
16
15
|
}), {});
|
|
@@ -29,18 +28,21 @@ export const useRootOrgData = (ids, {
|
|
|
29
28
|
const variables = {
|
|
30
29
|
isUserDataViewFallback
|
|
31
30
|
};
|
|
31
|
+
const rootOrgUnits = useDataQuery(query, {
|
|
32
|
+
variables
|
|
33
|
+
});
|
|
32
34
|
const {
|
|
35
|
+
called,
|
|
33
36
|
loading,
|
|
34
37
|
error,
|
|
35
38
|
data,
|
|
36
39
|
refetch
|
|
37
|
-
} =
|
|
38
|
-
variables
|
|
39
|
-
});
|
|
40
|
+
} = rootOrgUnits;
|
|
40
41
|
const patchedData = useMemo(() => {
|
|
41
42
|
return data ? patchMissingDisplayName(data) : data;
|
|
42
43
|
}, [data]);
|
|
43
44
|
return {
|
|
45
|
+
called,
|
|
44
46
|
loading,
|
|
45
47
|
error: error || null,
|
|
46
48
|
data: patchedData || null,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dhis2-ui/organisation-unit-tree",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.0.2",
|
|
4
4
|
"description": "UI OrganisationUnitTree",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -34,10 +34,10 @@
|
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@dhis2/prop-types": "^3.0.0-beta.1",
|
|
37
|
-
"@dhis2-ui/checkbox": "
|
|
38
|
-
"@dhis2-ui/loader": "
|
|
39
|
-
"@dhis2-ui/node": "
|
|
40
|
-
"@dhis2/ui-constants": "
|
|
37
|
+
"@dhis2-ui/checkbox": "8.0.2",
|
|
38
|
+
"@dhis2-ui/loader": "8.0.2",
|
|
39
|
+
"@dhis2-ui/node": "8.0.2",
|
|
40
|
+
"@dhis2/ui-constants": "8.0.2",
|
|
41
41
|
"classnames": "^2.3.1",
|
|
42
42
|
"prop-types": "^15.7.2"
|
|
43
43
|
},
|