@dhis2-ui/organisation-unit-tree 7.16.3 → 8.0.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 (37) hide show
  1. package/build/cjs/__e2e__/common.js +51 -24
  2. package/build/cjs/__e2e__/tree_api.stories.e2e.js +13 -5
  3. package/build/cjs/__stories__/development-stories.js +1 -3
  4. package/build/cjs/__stories__/shared.js +50 -17
  5. package/build/cjs/features/controlled_expanded/index.js +9 -3
  6. package/build/cjs/features/tree_api/index.js +4 -3
  7. package/build/cjs/helpers/sort-node-children-alphabetically.js +2 -17
  8. package/build/cjs/locales/en/translations.json +3 -2
  9. package/build/cjs/organisation-unit-node/label/label.js +2 -5
  10. package/build/cjs/organisation-unit-node/loading-spinner.js +32 -0
  11. package/build/cjs/organisation-unit-node/organisation-unit-node-children.js +120 -0
  12. package/build/cjs/organisation-unit-node/organisation-unit-node.js +43 -68
  13. package/build/cjs/organisation-unit-node/use-org-children.js +81 -0
  14. package/build/cjs/organisation-unit-node/use-org-children.test.js +319 -0
  15. package/build/cjs/organisation-unit-node/use-org-data/use-org-data.js +10 -33
  16. package/build/cjs/organisation-unit-node/use-org-data/use-org-data.test.js +3 -169
  17. package/build/cjs/organisation-unit-tree/organisation-unit-tree.js +4 -2
  18. package/build/cjs/organisation-unit-tree/use-root-org-data/use-root-org-data.js +7 -5
  19. package/build/es/__e2e__/common.js +52 -24
  20. package/build/es/__e2e__/tree_api.stories.e2e.js +13 -5
  21. package/build/es/__stories__/development-stories.js +1 -3
  22. package/build/es/__stories__/shared.js +51 -17
  23. package/build/es/features/controlled_expanded/index.js +9 -3
  24. package/build/es/features/tree_api/index.js +4 -3
  25. package/build/es/helpers/sort-node-children-alphabetically.js +2 -17
  26. package/build/es/locales/en/translations.json +3 -2
  27. package/build/es/organisation-unit-node/label/label.js +2 -5
  28. package/build/es/organisation-unit-node/loading-spinner.js +17 -0
  29. package/build/es/organisation-unit-node/organisation-unit-node-children.js +103 -0
  30. package/build/es/organisation-unit-node/organisation-unit-node.js +41 -65
  31. package/build/es/organisation-unit-node/use-org-children.js +69 -0
  32. package/build/es/organisation-unit-node/use-org-children.test.js +311 -0
  33. package/build/es/organisation-unit-node/use-org-data/use-org-data.js +10 -31
  34. package/build/es/organisation-unit-node/use-org-data/use-org-data.test.js +3 -169
  35. package/build/es/organisation-unit-tree/organisation-unit-tree.js +4 -2
  36. package/build/es/organisation-unit-tree/use-root-org-data/use-root-org-data.js +7 -5
  37. package/package.json +5 -5
@@ -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: ['id', 'path', 'children[id,path,displayName]']
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 {boolean} [options.withChildren]
20
+ * @param {bool} options.isUserDataViewFallback
23
21
  * @returns {Object}
24
22
  */
25
23
 
26
24
  export const useOrgData = (id, {
27
- isUserDataViewFallback,
28
- suppressAlphabeticalSorting,
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: transformedData
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: false`, `error: null` and `data: { displayName, id }` initially', () => {
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
- }, loading && /*#__PURE__*/React.createElement(RootLoading, null), error && /*#__PURE__*/React.createElement(RootError, {
73
+ }, isLoading && /*#__PURE__*/React.createElement(RootLoading, null), error && /*#__PURE__*/React.createElement(RootError, {
72
74
  error: error
73
- }), !error && !loading && rootIds.map(rootId => {
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
- } = useDataQuery(query, {
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": "7.16.3",
3
+ "version": "8.0.0",
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": "7.16.3",
38
- "@dhis2-ui/loader": "7.16.3",
39
- "@dhis2-ui/node": "7.16.3",
40
- "@dhis2/ui-constants": "7.16.3",
37
+ "@dhis2-ui/checkbox": "8.0.0",
38
+ "@dhis2-ui/loader": "8.0.0",
39
+ "@dhis2-ui/node": "8.0.0",
40
+ "@dhis2/ui-constants": "8.0.0",
41
41
  "classnames": "^2.3.1",
42
42
  "prop-types": "^15.7.2"
43
43
  },