@dhis2-ui/organisation-unit-tree 7.16.1 → 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
@@ -71,7 +71,7 @@ const Label = ({
71
71
  singleSelection,
72
72
  rootId
73
73
  }); // @TODO: It'd make more sense to pass the node as an object
74
- // isntead of spread it. But that'd be a breaking change
74
+ // instead of spread it. But that'd be a breaking change
75
75
 
76
76
  const payload = { ...node,
77
77
  path: fullPath,
@@ -125,10 +125,7 @@ Label.propTypes = {
125
125
  node: PropTypes.shape({
126
126
  displayName: PropTypes.string.isRequired,
127
127
  id: PropTypes.string.isRequired,
128
- children: PropTypes.arrayOf(PropTypes.shape({
129
- displayName: PropTypes.string.isRequired,
130
- id: PropTypes.string.isRequired
131
- })),
128
+ children: PropTypes.number,
132
129
  path: PropTypes.string
133
130
  }).isRequired,
134
131
  open: PropTypes.bool.isRequired,
@@ -0,0 +1,17 @@
1
+ import _JSXStyle from "styled-jsx/style";
2
+ import { CircularLoader } from '@dhis2-ui/loader';
3
+ import React from 'react';
4
+ const loadingSpinnerStyles = {
5
+ styles: /*#__PURE__*/React.createElement(_JSXStyle, {
6
+ id: "358163430"
7
+ }, [".extrasmall.jsx-358163430{display:block;margin:3px 0;}"]),
8
+ className: "jsx-358163430"
9
+ };
10
+ export const LoadingSpinner = () => /*#__PURE__*/React.createElement("div", {
11
+ className: "jsx-2503342345"
12
+ }, /*#__PURE__*/React.createElement(CircularLoader, {
13
+ extrasmall: true,
14
+ className: loadingSpinnerStyles.className
15
+ }), /*#__PURE__*/React.createElement("style", null, loadingSpinnerStyles.styles), /*#__PURE__*/React.createElement(_JSXStyle, {
16
+ id: "2503342345"
17
+ }, ["div.jsx-2503342345{width:24px;}"]));
@@ -0,0 +1,103 @@
1
+ import PropTypes from 'prop-types';
2
+ import React from 'react';
3
+ import { isPathIncluded } from '../helpers/index.js';
4
+ import i18n from '../locales/index.js';
5
+ import { orgUnitPathPropType } from '../prop-types.js';
6
+ import { LoadingSpinner } from './loading-spinner.js';
7
+ import { useOrgChildren } from './use-org-children.js';
8
+
9
+ const getFilteredChildren = ({
10
+ orgChildren,
11
+ filter,
12
+ node
13
+ }) => {
14
+ if (!(filter !== null && filter !== void 0 && filter.length)) {
15
+ return orgChildren;
16
+ }
17
+
18
+ return orgChildren.filter(child => {
19
+ return isPathIncluded(filter, `${node.path}/${child.id}`);
20
+ });
21
+ };
22
+
23
+ export const OrganisationUnitNodeChildren = ({
24
+ node,
25
+ autoExpandLoadingError,
26
+ dataTest,
27
+ disableSelection,
28
+ expanded,
29
+ filter,
30
+ highlighted,
31
+ isUserDataViewFallback,
32
+ onChange,
33
+ onChildrenLoaded,
34
+ onCollapse,
35
+ onExpand,
36
+ parentPath,
37
+ renderNodeLabel,
38
+ rootId,
39
+ selected,
40
+ singleSelection,
41
+ suppressAlphabeticalSorting,
42
+ OrganisationUnitNode
43
+ }) => {
44
+ const orgChildren = useOrgChildren({
45
+ node,
46
+ isUserDataViewFallback,
47
+ suppressAlphabeticalSorting,
48
+ onComplete: onChildrenLoaded
49
+ });
50
+ const displayChildren = orgChildren.called && !orgChildren.loading && !orgChildren.error;
51
+ const filteredChildren = displayChildren ? getFilteredChildren({
52
+ orgChildren: orgChildren.data,
53
+ filter,
54
+ node
55
+ }) : [];
56
+ return /*#__PURE__*/React.createElement(React.Fragment, null, orgChildren.loading && /*#__PURE__*/React.createElement(LoadingSpinner, null), orgChildren.error && `Error: ${orgChildren.error}`, displayChildren && !filteredChildren.length && i18n.t('No children match filter'), !!filteredChildren.length && filteredChildren.map(child => {
57
+ const childPath = `${parentPath}/${child.id}`;
58
+ return /*#__PURE__*/React.createElement(OrganisationUnitNode, {
59
+ autoExpandLoadingError: autoExpandLoadingError,
60
+ dataTest: dataTest,
61
+ disableSelection: disableSelection,
62
+ displayName: child.displayName,
63
+ expanded: expanded,
64
+ filter: filter,
65
+ highlighted: highlighted,
66
+ id: child.id,
67
+ isUserDataViewFallback: isUserDataViewFallback,
68
+ key: childPath,
69
+ onChange: onChange,
70
+ onChildrenLoaded: onChildrenLoaded,
71
+ onCollapse: onCollapse,
72
+ onExpand: onExpand,
73
+ path: childPath,
74
+ renderNodeLabel: renderNodeLabel,
75
+ rootId: rootId,
76
+ selected: selected,
77
+ singleSelection: singleSelection,
78
+ suppressAlphabeticalSorting: suppressAlphabeticalSorting
79
+ });
80
+ }));
81
+ };
82
+ OrganisationUnitNodeChildren.propTypes = {
83
+ // Prevent cirular imports
84
+ OrganisationUnitNode: PropTypes.func.isRequired,
85
+ dataTest: PropTypes.string.isRequired,
86
+ node: PropTypes.object.isRequired,
87
+ parentPath: PropTypes.string.isRequired,
88
+ renderNodeLabel: PropTypes.func.isRequired,
89
+ rootId: PropTypes.string.isRequired,
90
+ onChange: PropTypes.func.isRequired,
91
+ autoExpandLoadingError: PropTypes.bool,
92
+ disableSelection: PropTypes.bool,
93
+ expanded: PropTypes.arrayOf(orgUnitPathPropType),
94
+ filter: PropTypes.arrayOf(orgUnitPathPropType),
95
+ highlighted: PropTypes.arrayOf(orgUnitPathPropType),
96
+ isUserDataViewFallback: PropTypes.bool,
97
+ selected: PropTypes.arrayOf(orgUnitPathPropType),
98
+ singleSelection: PropTypes.bool,
99
+ suppressAlphabeticalSorting: PropTypes.bool,
100
+ onChildrenLoaded: PropTypes.func,
101
+ onCollapse: PropTypes.func,
102
+ onExpand: PropTypes.func
103
+ };
@@ -1,33 +1,16 @@
1
- import _JSXStyle from "styled-jsx/style";
2
- import { CircularLoader } from '@dhis2-ui/loader';
3
1
  import { Node } from '@dhis2-ui/node';
4
2
  import PropTypes from 'prop-types';
5
3
  import React from 'react';
6
4
  import { leftTrimToRootId } from '../helpers/index.js';
7
5
  import i18n from '../locales/index.js';
8
6
  import { orgUnitPathPropType } from '../prop-types.js';
9
- import { computeChildNodes } from './compute-child-nodes.js';
10
7
  import { ErrorMessage } from './error-message.js';
11
8
  import { hasDescendantSelectedPaths } from './has-descendant-selected-paths.js';
12
9
  import { Label } from './label/index.js';
10
+ import { LoadingSpinner } from './loading-spinner.js';
11
+ import { OrganisationUnitNodeChildren } from './organisation-unit-node-children.js';
13
12
  import { useOpenState } from './use-open-state.js';
14
13
  import { useOrgData } from './use-org-data/index.js';
15
- const loadingSpinnerStyles = {
16
- styles: /*#__PURE__*/React.createElement(_JSXStyle, {
17
- id: "358163430"
18
- }, [".extrasmall.jsx-358163430{display:block;margin:3px 0;}"]),
19
- className: "jsx-358163430"
20
- };
21
-
22
- const LoadingSpinner = () => /*#__PURE__*/React.createElement("div", {
23
- className: "jsx-2503342345"
24
- }, /*#__PURE__*/React.createElement(CircularLoader, {
25
- extrasmall: true,
26
- className: loadingSpinnerStyles.className
27
- }), /*#__PURE__*/React.createElement("style", null, loadingSpinnerStyles.styles), /*#__PURE__*/React.createElement(_JSXStyle, {
28
- id: "2503342345"
29
- }, ["div.jsx-2503342345{width:24px;}"]));
30
-
31
14
  export const OrganisationUnitNode = ({
32
15
  autoExpandLoadingError,
33
16
  dataTest,
@@ -49,22 +32,20 @@ export const OrganisationUnitNode = ({
49
32
  onCollapse,
50
33
  onExpand
51
34
  }) => {
52
- const {
53
- loading,
54
- error,
55
- data
56
- } = useOrgData(id, {
35
+ const orgData = useOrgData(id, {
57
36
  isUserDataViewFallback,
58
- suppressAlphabeticalSorting,
59
- displayName,
60
- onComplete: onChildrenLoaded
37
+ displayName
61
38
  });
62
39
  const strippedPath = leftTrimToRootId(path, rootId);
63
- const node = { ...data,
40
+ const node = {
41
+ // guarantee that displayName and id are avaiable before data loaded
42
+ displayName,
43
+ id,
44
+ ...(orgData.data || {}),
45
+ // do not override strippedPath with path from loaded data
64
46
  path: strippedPath
65
47
  };
66
- const childNodes = !loading && !error ? computeChildNodes(node, filter) : [];
67
- const hasChildren = !!childNodes.length;
48
+ const hasChildren = !!node.children && node.children > 0;
68
49
  const hasSelectedDescendants = hasDescendantSelectedPaths(strippedPath, selected, rootId);
69
50
  const isHighlighted = highlighted.includes(path);
70
51
  const {
@@ -72,7 +53,7 @@ export const OrganisationUnitNode = ({
72
53
  onToggleOpen
73
54
  } = useOpenState({
74
55
  autoExpandLoadingError,
75
- errorMessage: error && error.toString(),
56
+ errorMessage: orgData.error && orgData.error.toString(),
76
57
  path: strippedPath,
77
58
  expanded,
78
59
  onExpand,
@@ -83,14 +64,14 @@ export const OrganisationUnitNode = ({
83
64
  disableSelection,
84
65
  hasChildren,
85
66
  hasSelectedDescendants,
86
- loading,
87
- error,
67
+ loading: orgData.loading,
68
+ error: orgData.error,
88
69
  selected,
89
70
  open,
90
71
  path,
91
72
  singleSelection,
92
73
  node,
93
- label: node.displayName,
74
+ label: displayName,
94
75
  checked: isSelected,
95
76
  highlighted: isHighlighted
96
77
  });
@@ -98,7 +79,7 @@ export const OrganisationUnitNode = ({
98
79
  node: node,
99
80
  fullPath: path,
100
81
  open: open,
101
- loading: loading,
82
+ loading: orgData.loading,
102
83
  checked: isSelected,
103
84
  rootId: rootId,
104
85
  onChange: onChange,
@@ -122,45 +103,40 @@ export const OrganisationUnitNode = ({
122
103
  * 4. Child nodes: There are children and the node is open
123
104
  */
124
105
 
125
- const showPlaceholder = hasChildren && !open && !error;
126
- const showChildNodes = hasChildren && open && !error;
106
+ const showPlaceholder = hasChildren && !open && !orgData.error;
107
+ const showChildNodes = hasChildren && open && !orgData.error;
127
108
  return /*#__PURE__*/React.createElement(Node, {
128
109
  dataTest: `${dataTest}-node`,
129
110
  open: open,
130
111
  onOpen: onToggleOpen,
131
112
  onClose: onToggleOpen,
132
113
  component: label,
133
- icon: loading && /*#__PURE__*/React.createElement(LoadingSpinner, null)
134
- }, error && /*#__PURE__*/React.createElement(ErrorMessage, {
114
+ icon: orgData.loading && /*#__PURE__*/React.createElement(LoadingSpinner, null)
115
+ }, orgData.error && /*#__PURE__*/React.createElement(ErrorMessage, {
135
116
  dataTest: dataTest
136
117
  }, i18n.t('Could not load children')), showPlaceholder && /*#__PURE__*/React.createElement("span", {
137
118
  "data-test": `${dataTest}-placeholder`
138
- }), showChildNodes && childNodes.map(child => {
139
- const childPath = `${path}/${child.id}`;
140
- const grandChildNodes = computeChildNodes(child, filter);
141
- return /*#__PURE__*/React.createElement(OrganisationUnitNode, {
142
- autoExpandLoadingError: autoExpandLoadingError,
143
- childNodes: grandChildNodes,
144
- dataTest: dataTest,
145
- disableSelection: disableSelection,
146
- displayName: child.displayName,
147
- expanded: expanded,
148
- filter: filter,
149
- highlighted: highlighted,
150
- id: child.id,
151
- isUserDataViewFallback: isUserDataViewFallback,
152
- key: childPath,
153
- onChange: onChange,
154
- onChildrenLoaded: onChildrenLoaded,
155
- onCollapse: onCollapse,
156
- onExpand: onExpand,
157
- path: childPath,
158
- renderNodeLabel: renderNodeLabel,
159
- rootId: rootId,
160
- selected: selected,
161
- singleSelection: singleSelection,
162
- suppressAlphabeticalSorting: suppressAlphabeticalSorting
163
- });
119
+ }), showChildNodes && /*#__PURE__*/React.createElement(OrganisationUnitNodeChildren // Prevent cirular imports
120
+ , {
121
+ OrganisationUnitNode: OrganisationUnitNode,
122
+ node: node,
123
+ autoExpandLoadingError: autoExpandLoadingError,
124
+ dataTest: dataTest,
125
+ disableSelection: disableSelection,
126
+ expanded: expanded,
127
+ filter: filter,
128
+ highlighted: highlighted,
129
+ isUserDataViewFallback: isUserDataViewFallback,
130
+ onChange: onChange,
131
+ onChildrenLoaded: onChildrenLoaded,
132
+ onCollapse: onCollapse,
133
+ onExpand: onExpand,
134
+ parentPath: path,
135
+ renderNodeLabel: renderNodeLabel,
136
+ rootId: rootId,
137
+ selected: selected,
138
+ singleSelection: singleSelection,
139
+ suppressAlphabeticalSorting: suppressAlphabeticalSorting
164
140
  }));
165
141
  };
166
142
  OrganisationUnitNode.propTypes = {
@@ -0,0 +1,69 @@
1
+ import { useDataQuery } from '@dhis2/app-runtime';
2
+ import { useMemo, useEffect, useRef } from 'react';
3
+ import { sortNodeChildrenAlphabetically } from '../helpers/index.js';
4
+ const ORG_DATA_QUERY = {
5
+ orgUnit: {
6
+ resource: `organisationUnits`,
7
+ id: ({
8
+ id
9
+ }) => id,
10
+ params: {
11
+ fields: 'children[id,path,displayName]'
12
+ }
13
+ }
14
+ };
15
+ /**
16
+ * @param {string[]} ids
17
+ * @param {Object} options
18
+ * @param {string} options.displayName
19
+ * @param {boolean} [options.withChildren]
20
+ * @returns {Object}
21
+ */
22
+
23
+ export const useOrgChildren = ({
24
+ node,
25
+ suppressAlphabeticalSorting,
26
+ onComplete
27
+ }) => {
28
+ const onCompleteCalledRef = useRef(false);
29
+ const {
30
+ called,
31
+ loading,
32
+ error,
33
+ data
34
+ } = useDataQuery(ORG_DATA_QUERY, {
35
+ variables: {
36
+ id: node.id
37
+ }
38
+ });
39
+ const orgChildren = useMemo(() => {
40
+ if (!data) {
41
+ return undefined;
42
+ } // undefined or zero
43
+
44
+
45
+ if (!node.children) {
46
+ return [];
47
+ }
48
+
49
+ const {
50
+ orgUnit
51
+ } = data;
52
+ return suppressAlphabeticalSorting ? orgUnit.children : sortNodeChildrenAlphabetically(orgUnit.children);
53
+ }, [data, suppressAlphabeticalSorting]);
54
+ useEffect(() => {
55
+ if (onComplete && orgChildren && !onCompleteCalledRef.current) {
56
+ // For backwards compatibility: Pass entire node incl. children
57
+ onComplete({ ...node,
58
+ children: orgChildren
59
+ });
60
+ onCompleteCalledRef.current = true;
61
+ }
62
+ }, [onComplete, orgChildren, onCompleteCalledRef]);
63
+ return {
64
+ called,
65
+ loading,
66
+ error: error || null,
67
+ data: orgChildren
68
+ };
69
+ };
@@ -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
+ });