@dhis2-ui/organisation-unit-tree 10.16.2 → 10.16.3-alpha.1

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 (142) hide show
  1. package/package.json +8 -7
  2. package/src/__e2e__/children_as_child_nodes.js +23 -0
  3. package/src/__e2e__/common.js +70 -0
  4. package/src/__e2e__/controlled_expanded.js +89 -0
  5. package/src/__e2e__/displaying_loading_error.js +45 -0
  6. package/src/__e2e__/expanded.js +42 -0
  7. package/src/__e2e__/force_reload.js +66 -0
  8. package/src/__e2e__/get-organisation-unit-data.js +119 -0
  9. package/src/__e2e__/highlight.js +23 -0
  10. package/src/__e2e__/loading_state.js +37 -0
  11. package/src/__e2e__/multi_selection.js +24 -0
  12. package/src/__e2e__/namespace.js +1 -0
  13. package/src/__e2e__/no_selection.js +32 -0
  14. package/src/__e2e__/path_based_filtering.js +49 -0
  15. package/src/__e2e__/single_selection.js +46 -0
  16. package/src/__e2e__/sub_unit_as_root.js +28 -0
  17. package/src/__e2e__/tree_api.js +55 -0
  18. package/src/__stories__/collapsed.js +11 -0
  19. package/src/__stories__/custom-expanded-imperative-open.js +181 -0
  20. package/src/__stories__/custom-node-label.js +19 -0
  21. package/src/__stories__/development-stories.js +86 -0
  22. package/src/__stories__/expanded.js +12 -0
  23. package/src/__stories__/filtered-root.js +15 -0
  24. package/src/__stories__/filtered.js +13 -0
  25. package/src/__stories__/force-reload-all.js +46 -0
  26. package/src/__stories__/force-reload-one-unit.js +36 -0
  27. package/src/__stories__/highlighted.js +13 -0
  28. package/src/__stories__/indeterminate.js +13 -0
  29. package/src/__stories__/loading-error-grandchild.js +39 -0
  30. package/src/__stories__/loading.js +27 -0
  31. package/src/__stories__/multiple-roots.js +20 -0
  32. package/src/__stories__/no-selection.js +16 -0
  33. package/src/__stories__/replace-roots.js +28 -0
  34. package/src/__stories__/root-error.js +36 -0
  35. package/src/__stories__/root-loading.js +34 -0
  36. package/src/__stories__/rtl.js +14 -0
  37. package/src/__stories__/selected-multiple.js +18 -0
  38. package/src/__stories__/shared.js +192 -0
  39. package/src/__stories__/single-selection.js +16 -0
  40. package/src/features/children_as_child_nodes/index.js +29 -0
  41. package/src/features/children_as_child_nodes.feature +6 -0
  42. package/src/features/controlled_expanded/index.js +86 -0
  43. package/src/features/controlled_expanded.feature +11 -0
  44. package/src/features/displaying_loading_error/index.js +46 -0
  45. package/src/features/displaying_loading_error.feature +24 -0
  46. package/src/features/expanded/index.js +87 -0
  47. package/src/features/expanded.feature +27 -0
  48. package/src/features/force_reload/index.js +36 -0
  49. package/src/features/force_reload.feature +7 -0
  50. package/src/features/highlight/index.js +9 -0
  51. package/src/features/highlight.feature +5 -0
  52. package/src/features/loading_state/index.js +26 -0
  53. package/src/features/loading_state.feature +7 -0
  54. package/src/features/multi_selection/index.js +94 -0
  55. package/src/features/multi_selection.feature +31 -0
  56. package/src/features/no_selection/index.js +41 -0
  57. package/src/features/no_selection.feature +13 -0
  58. package/src/features/path_based_filtering/index.js +97 -0
  59. package/src/features/path_based_filtering.feature +24 -0
  60. package/src/features/single_selection/index.js +41 -0
  61. package/src/features/single_selection.feature +20 -0
  62. package/src/features/sub_unit_as_root/index.js +83 -0
  63. package/src/features/sub_unit_as_root.feature +34 -0
  64. package/src/features/tree_api/index.js +121 -0
  65. package/src/features/tree_api.feature +37 -0
  66. package/src/get-all-expanded-paths/get-all-expanded-paths.js +32 -0
  67. package/src/get-all-expanded-paths/get-all-expanded-paths.test.js +22 -0
  68. package/src/get-all-expanded-paths/index.js +1 -0
  69. package/src/helpers/index.js +3 -0
  70. package/src/helpers/is-path-included.js +15 -0
  71. package/src/helpers/left-trim-to-root-id.js +3 -0
  72. package/src/helpers/sort-node-children-alphabetically.js +5 -0
  73. package/src/index.js +6 -0
  74. package/src/locales/ar/translations.json +5 -0
  75. package/src/locales/cs/translations.json +5 -0
  76. package/src/locales/en/translations.json +5 -0
  77. package/src/locales/es/translations.json +5 -0
  78. package/src/locales/es_419/translations.json +5 -0
  79. package/src/locales/fr/translations.json +5 -0
  80. package/src/locales/index.js +50 -0
  81. package/src/locales/lo/translations.json +5 -0
  82. package/src/locales/nb/translations.json +5 -0
  83. package/src/locales/nl/translations.json +5 -0
  84. package/src/locales/pt/translations.json +5 -0
  85. package/src/locales/ru/translations.json +5 -0
  86. package/src/locales/uk/translations.json +5 -0
  87. package/src/locales/uz_Latn/translations.json +5 -0
  88. package/src/locales/uz_UZ_Cyrl/translations.json +5 -0
  89. package/src/locales/uz_UZ_Latn/translations.json +5 -0
  90. package/src/locales/vi/translations.json +5 -0
  91. package/src/locales/zh/translations.json +5 -0
  92. package/src/locales/zh_CN/translations.json +5 -0
  93. package/src/organisation-unit-node/compute-child-nodes.js +27 -0
  94. package/src/organisation-unit-node/compute-child-nodes.test.js +85 -0
  95. package/src/organisation-unit-node/error-message.js +23 -0
  96. package/src/organisation-unit-node/has-descendant-selected-paths.js +15 -0
  97. package/src/organisation-unit-node/has-descendant-selected-paths.test.js +30 -0
  98. package/src/organisation-unit-node/index.js +1 -0
  99. package/src/organisation-unit-node/label/disabled-selection-label.js +26 -0
  100. package/src/organisation-unit-node/label/icon-empty.js +31 -0
  101. package/src/organisation-unit-node/label/icon-folder-closed.js +38 -0
  102. package/src/organisation-unit-node/label/icon-folder-open.js +49 -0
  103. package/src/organisation-unit-node/label/icon-single.js +41 -0
  104. package/src/organisation-unit-node/label/icon.js +35 -0
  105. package/src/organisation-unit-node/label/iconized-checkbox.js +67 -0
  106. package/src/organisation-unit-node/label/index.js +1 -0
  107. package/src/organisation-unit-node/label/label-container.js +36 -0
  108. package/src/organisation-unit-node/label/label.js +146 -0
  109. package/src/organisation-unit-node/label/single-selection-label.js +60 -0
  110. package/src/organisation-unit-node/loading-spinner.js +22 -0
  111. package/src/organisation-unit-node/organisation-unit-node-children.js +123 -0
  112. package/src/organisation-unit-node/organisation-unit-node.js +190 -0
  113. package/src/organisation-unit-node/use-open-state.js +37 -0
  114. package/src/organisation-unit-node/use-open-state.test.js +111 -0
  115. package/src/organisation-unit-node/use-org-children.js +63 -0
  116. package/src/organisation-unit-node/use-org-children.test.js +314 -0
  117. package/src/organisation-unit-node/use-org-data/index.js +1 -0
  118. package/src/organisation-unit-node/use-org-data/use-org-data.js +40 -0
  119. package/src/organisation-unit-node/use-org-data/use-org-data.test.js +137 -0
  120. package/src/organisation-unit-tree/default-render-node-label/default-render-node-label.js +1 -0
  121. package/src/organisation-unit-tree/default-render-node-label/index.js +1 -0
  122. package/src/organisation-unit-tree/filter-root-ids.js +9 -0
  123. package/src/organisation-unit-tree/index.js +3 -0
  124. package/src/organisation-unit-tree/organisation-unit-tree-root-error.js +20 -0
  125. package/src/organisation-unit-tree/organisation-unit-tree-root-loading.js +22 -0
  126. package/src/organisation-unit-tree/organisation-unit-tree.js +253 -0
  127. package/src/organisation-unit-tree/organisation-unit-tree.test.js +77 -0
  128. package/src/organisation-unit-tree/use-expanded/create-expand-handlers.js +45 -0
  129. package/src/organisation-unit-tree/use-expanded/create-expand-handlers.test.js +54 -0
  130. package/src/organisation-unit-tree/use-expanded/index.js +1 -0
  131. package/src/organisation-unit-tree/use-expanded/use-expanded.js +42 -0
  132. package/src/organisation-unit-tree/use-expanded/use-expanded.test.js +73 -0
  133. package/src/organisation-unit-tree/use-force-reload.js +22 -0
  134. package/src/organisation-unit-tree/use-force-reload.test.js +43 -0
  135. package/src/organisation-unit-tree/use-root-org-data/index.js +1 -0
  136. package/src/organisation-unit-tree/use-root-org-data/patch-missing-display-name.js +20 -0
  137. package/src/organisation-unit-tree/use-root-org-data/patch-missing-display-name.test.js +24 -0
  138. package/src/organisation-unit-tree/use-root-org-data/use-root-org-data.js +60 -0
  139. package/src/organisation-unit-tree/use-root-org-data/use-root-org-unit.test.js +184 -0
  140. package/src/organisation-unit-tree.e2e.stories.js +28 -0
  141. package/src/organisation-unit-tree.prod.stories.js +70 -0
  142. package/src/prop-types.js +33 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dhis2-ui/organisation-unit-tree",
3
- "version": "10.16.2",
3
+ "version": "10.16.3-alpha.1",
4
4
  "description": "UI OrganisationUnitTree",
5
5
  "repository": {
6
6
  "type": "git",
@@ -35,17 +35,18 @@
35
35
  },
36
36
  "dependencies": {
37
37
  "@dhis2/prop-types": "^3.1.2",
38
- "@dhis2-ui/button": "10.16.2",
39
- "@dhis2-ui/checkbox": "10.16.2",
40
- "@dhis2-ui/loader": "10.16.2",
41
- "@dhis2-ui/node": "10.16.2",
42
- "@dhis2/ui-constants": "10.16.2",
38
+ "@dhis2-ui/button": "10.16.3-alpha.1",
39
+ "@dhis2-ui/checkbox": "10.16.3-alpha.1",
40
+ "@dhis2-ui/loader": "10.16.3-alpha.1",
41
+ "@dhis2-ui/node": "10.16.3-alpha.1",
42
+ "@dhis2/ui-constants": "10.16.3-alpha.1",
43
43
  "classnames": "^2.3.1",
44
44
  "prop-types": "^15.7.2"
45
45
  },
46
46
  "files": [
47
47
  "build",
48
- "types"
48
+ "types",
49
+ "src"
49
50
  ],
50
51
  "devDependencies": {
51
52
  "@dhis2/app-runtime": "^3.9.0",
@@ -0,0 +1,23 @@
1
+ import { CustomDataProvider } from '@dhis2/app-runtime'
2
+ import React from 'react'
3
+ import { OrganisationUnitTree } from '../index.js'
4
+ import {
5
+ StatefulMultiSelectionWrapper,
6
+ dataProviderData,
7
+ namespace,
8
+ } from './common.js'
9
+
10
+ export default { title: namespace }
11
+ export const ClosedWithChildren = () => (
12
+ <CustomDataProvider data={dataProviderData}>
13
+ <StatefulMultiSelectionWrapper>
14
+ {({ selected, onChange }) => (
15
+ <OrganisationUnitTree
16
+ roots="A0000000000"
17
+ onChange={onChange}
18
+ selected={selected}
19
+ />
20
+ )}
21
+ </StatefulMultiSelectionWrapper>
22
+ </CustomDataProvider>
23
+ )
@@ -0,0 +1,70 @@
1
+ /* eslint-disable react/display-name */
2
+ import { CustomDataProvider } from '@dhis2/app-runtime'
3
+ import PropTypes from 'prop-types'
4
+ import React, { useState } from 'react'
5
+ import { getOrganisationUnitData } from './get-organisation-unit-data.js'
6
+
7
+ export { getOrganisationUnitData } from './get-organisation-unit-data.js'
8
+ export { namespace } from './namespace.js'
9
+
10
+ export const delayResponse = (delay, response) => () =>
11
+ new Promise((resolve) => setTimeout(() => resolve(response), delay))
12
+
13
+ export const dataProviderData = {
14
+ organisationUnits: (_, { id, params = {} }) => {
15
+ console.log('id, params', id, params)
16
+ const data = getOrganisationUnitData(id, params)
17
+
18
+ if (!data) {
19
+ return Promise.reject(new Error('404 - Org unit not found'))
20
+ }
21
+
22
+ return Promise.resolve(data)
23
+ },
24
+ }
25
+
26
+ export const StatefulMultiSelectionWrapper = ({
27
+ children,
28
+ onSelectionChange = () => null,
29
+ }) => {
30
+ const [selected, setSelected] = useState([])
31
+
32
+ return children({
33
+ selected,
34
+ onChange: ({ selected: newSelected }) => {
35
+ setSelected(newSelected)
36
+ onSelectionChange(newSelected)
37
+ },
38
+ })
39
+ }
40
+
41
+ StatefulMultiSelectionWrapper.propTypes = {
42
+ children: PropTypes.func.isRequired,
43
+ onSelectionChange: PropTypes.func,
44
+ }
45
+
46
+ export const createDecoratorStatefulMultiSelection = (args) => {
47
+ return (Story) => (
48
+ <StatefulMultiSelectionWrapper
49
+ onSelectionChange={args?.onSelectionChange}
50
+ >
51
+ {({ selected, onChange }) => (
52
+ <Story selected={selected} onChange={onChange} />
53
+ )}
54
+ </StatefulMultiSelectionWrapper>
55
+ )
56
+ }
57
+
58
+ export const createDecoratorCustomDataProvider = (args) => {
59
+ const data = args?.data || dataProviderData
60
+
61
+ return (Story) => {
62
+ window.dataProviderData = data
63
+
64
+ return (
65
+ <CustomDataProvider data={data}>
66
+ <Story />
67
+ </CustomDataProvider>
68
+ )
69
+ }
70
+ }
@@ -0,0 +1,89 @@
1
+ import { Button } from '@dhis2-ui/button'
2
+ import React, { useState } from 'react'
3
+ import { OrganisationUnitTree, getAllExpandedOrgUnitPaths } from '../index.js'
4
+ import { createDecoratorCustomDataProvider } from './common.js'
5
+
6
+ window.initiallyExpandedPaths = ['/A0000000000/A0000000001']
7
+ window.orgUnitPathToExpand = '/A0000000000/A0000000001'
8
+
9
+ export const Controlled = () => {
10
+ const initiallyExpanded = getAllExpandedOrgUnitPaths(
11
+ window.initiallyExpandedPaths
12
+ )
13
+
14
+ const [expanded, setExpanded] = useState(initiallyExpanded)
15
+
16
+ const handleExpand = ({ path }) => {
17
+ if (!expanded.includes(path)) {
18
+ setExpanded([...expanded, path])
19
+ }
20
+ }
21
+
22
+ const handleCollapse = ({ path }) => {
23
+ const pathIndex = expanded.indexOf(path)
24
+
25
+ if (pathIndex !== -1) {
26
+ const updatedExpanded =
27
+ pathIndex === 0
28
+ ? expanded.slice(1)
29
+ : [
30
+ ...expanded.slice(0, pathIndex),
31
+ ...expanded.slice(pathIndex + 1),
32
+ ]
33
+
34
+ setExpanded(updatedExpanded)
35
+ }
36
+ }
37
+
38
+ const imperativeToggle = () => {
39
+ if (!expanded.includes('/A0000000000/A0000000001')) {
40
+ // Make sure that all required sub paths are included as well
41
+ const nextPaths = getAllExpandedOrgUnitPaths([
42
+ ...expanded,
43
+ window.orgUnitPathToExpand,
44
+ ])
45
+
46
+ return setExpanded(nextPaths)
47
+ }
48
+
49
+ setExpanded(expanded.filter((v) => v !== '/A0000000000/A0000000001'))
50
+ }
51
+
52
+ return (
53
+ <>
54
+ <OrganisationUnitTree
55
+ onChange={() => null}
56
+ name="Root org unit"
57
+ roots={['A0000000000']}
58
+ expanded={expanded}
59
+ handleExpand={handleExpand}
60
+ handleCollapse={handleCollapse}
61
+ />
62
+
63
+ <br />
64
+
65
+ <Button dataTest="org-unit-toggle" onClick={imperativeToggle}>
66
+ Toggle Org Unit 2
67
+ </Button>
68
+ </>
69
+ )
70
+ }
71
+
72
+ Controlled.decorators = [createDecoratorCustomDataProvider()]
73
+
74
+ export const MissingProps = () => {
75
+ const expanded = []
76
+ const handleExpand = () => null
77
+
78
+ return (
79
+ <OrganisationUnitTree
80
+ onChange={() => null}
81
+ name="Root org unit"
82
+ roots={['A0000000000']}
83
+ expanded={expanded}
84
+ handleExpand={handleExpand}
85
+ />
86
+ )
87
+ }
88
+
89
+ MissingProps.decorators = [createDecoratorCustomDataProvider()]
@@ -0,0 +1,45 @@
1
+ import { CustomDataProvider } from '@dhis2/app-runtime'
2
+ import React from 'react'
3
+ import { OrganisationUnitTree } from '../index.js'
4
+ import { StatefulMultiSelectionWrapper, dataProviderData } from './common.js'
5
+
6
+ const dataProviderDataWithError = {
7
+ organisationUnits: (...args) => {
8
+ const [, { id }] = args
9
+ if (id === 'A0000000001') {
10
+ return new Promise((resolve, reject) =>
11
+ setTimeout(() => {
12
+ reject(new Error('Foobar custom error message'))
13
+ }, 100)
14
+ )
15
+ }
16
+
17
+ return dataProviderData.organisationUnits(...args)
18
+ },
19
+ }
20
+
21
+ export const A0000000001LoadingError = () => (
22
+ <CustomDataProvider data={dataProviderDataWithError}>
23
+ <StatefulMultiSelectionWrapper>
24
+ {() => (
25
+ <OrganisationUnitTree
26
+ roots="A0000000000"
27
+ onChange={() => null}
28
+ />
29
+ )}
30
+ </StatefulMultiSelectionWrapper>
31
+ </CustomDataProvider>
32
+ )
33
+ export const A0000000001LoadingErrorAutoexpand = () => (
34
+ <CustomDataProvider data={dataProviderDataWithError}>
35
+ <StatefulMultiSelectionWrapper>
36
+ {() => (
37
+ <OrganisationUnitTree
38
+ autoExpandLoadingError
39
+ roots="A0000000000"
40
+ onChange={() => null}
41
+ />
42
+ )}
43
+ </StatefulMultiSelectionWrapper>
44
+ </CustomDataProvider>
45
+ )
@@ -0,0 +1,42 @@
1
+ import React from 'react'
2
+ import { OrganisationUnitTree } from '../index.js'
3
+ import {
4
+ createDecoratorCustomDataProvider,
5
+ createDecoratorStatefulMultiSelection,
6
+ } from './common.js'
7
+
8
+ const decorators = [
9
+ createDecoratorStatefulMultiSelection(),
10
+ createDecoratorCustomDataProvider(),
11
+ ]
12
+
13
+ export const NoInitiallyExpandedPaths = (_, { onChange, selected }) => (
14
+ <OrganisationUnitTree
15
+ roots="A0000000000"
16
+ selected={selected}
17
+ onChange={onChange}
18
+ />
19
+ )
20
+
21
+ NoInitiallyExpandedPaths.decorators = decorators
22
+
23
+ export const InitiallyExpandedPaths = (_, { onChange, selected }) => (
24
+ <OrganisationUnitTree
25
+ roots="A0000000000"
26
+ selected={selected}
27
+ onChange={onChange}
28
+ initiallyExpanded={['/A0000000000']}
29
+ />
30
+ )
31
+
32
+ InitiallyExpandedPaths.decorators = decorators
33
+
34
+ export const WithRootMainAndRootSubOrgUnit = (_, { onChange, selected }) => (
35
+ <OrganisationUnitTree
36
+ roots={['A0000000000', 'A0000000001']}
37
+ selected={selected}
38
+ onChange={onChange}
39
+ />
40
+ )
41
+
42
+ WithRootMainAndRootSubOrgUnit.decorators = decorators
@@ -0,0 +1,66 @@
1
+ import { CustomDataProvider } from '@dhis2/app-runtime'
2
+ import React, { useState } from 'react'
3
+ import { OrganisationUnitTree } from '../index.js'
4
+ import {
5
+ StatefulMultiSelectionWrapper,
6
+ dataProviderData,
7
+ delayResponse,
8
+ namespace,
9
+ } from './common.js'
10
+
11
+ const afterReloadData = {
12
+ organisationUnits: (...args) => {
13
+ const [, { id }] = args
14
+
15
+ if (id === 'A0000000000') {
16
+ return delayResponse(
17
+ 1000,
18
+ dataProviderData.organisationUnits(...args)
19
+ )()
20
+ }
21
+
22
+ if (id === 'A0000000001') {
23
+ return delayResponse(
24
+ 2200,
25
+ dataProviderData.organisationUnits(...args)
26
+ )()
27
+ }
28
+
29
+ return dataProviderData.organisationUnits(...args)
30
+ },
31
+ }
32
+
33
+ const ForceReloading_ = () => {
34
+ const [forceReload, setForceReload] = useState(false)
35
+
36
+ return (
37
+ <CustomDataProvider data={afterReloadData}>
38
+ <button
39
+ disabled={forceReload}
40
+ data-test="reload-all"
41
+ onClick={() => setForceReload(true)}
42
+ >
43
+ Force reload tree
44
+ </button>
45
+
46
+ <StatefulMultiSelectionWrapper>
47
+ {({ selected, onChange }) => (
48
+ <OrganisationUnitTree
49
+ roots="A0000000000"
50
+ onChange={onChange}
51
+ selected={selected}
52
+ forceReload={forceReload}
53
+ onChildrenLoaded={(data) => {
54
+ if (data.A0000000000) {
55
+ setForceReload(false)
56
+ }
57
+ }}
58
+ />
59
+ )}
60
+ </StatefulMultiSelectionWrapper>
61
+ </CustomDataProvider>
62
+ )
63
+ }
64
+
65
+ export default { title: namespace }
66
+ export const ForceReloading = () => <ForceReloading_ />
@@ -0,0 +1,119 @@
1
+ const createResponse = ({ fields, id, path, displayName, children }) => ({
2
+ ...(fields.includes('id') ? { id } : {}),
3
+ ...(fields.includes('path') ? { path } : {}),
4
+ ...(fields.includes('displayName') ? { displayName } : {}),
5
+ ...(fields.includes('children::size') ? { children: children.length } : {}),
6
+ ...(fields.includes('children[id,path,displayName]') ? { children } : {}),
7
+ })
8
+
9
+ export const getOrganisationUnitData = (id, { fields }) => {
10
+ let data
11
+
12
+ if (id === 'A0000000000') {
13
+ data = createResponse({
14
+ fields,
15
+ id: 'A0000000000',
16
+ path: '/A0000000000',
17
+ displayName: 'Org Unit 1',
18
+ children: [
19
+ {
20
+ id: 'A0000000001',
21
+ path: '/A0000000000/A0000000001',
22
+ displayName: 'Org Unit 2',
23
+ },
24
+ {
25
+ id: 'A0000000002',
26
+ path: '/A0000000000/A0000000002',
27
+ displayName: 'Org Unit 3',
28
+ },
29
+ {
30
+ id: 'A0000000006',
31
+ path: '/A0000000000/A0000000006',
32
+ displayName: 'Org Unit 7',
33
+ },
34
+ ],
35
+ })
36
+ }
37
+
38
+ if (id === 'A0000000001') {
39
+ data = createResponse({
40
+ fields,
41
+ id: 'A0000000001',
42
+ path: '/A0000000000/A0000000001',
43
+ displayName: 'Org Unit 2',
44
+ children: [
45
+ {
46
+ id: 'A0000000003',
47
+ path: '/A0000000000/A0000000001/A0000000003',
48
+ children: [],
49
+ displayName: 'Org Unit 4',
50
+ },
51
+ {
52
+ id: 'A0000000004',
53
+ path: '/A0000000000/A0000000001/A0000000004',
54
+ children: [],
55
+ displayName: 'Org Unit 5',
56
+ },
57
+ ],
58
+ })
59
+ }
60
+
61
+ if (id === 'A0000000002') {
62
+ data = createResponse({
63
+ fields,
64
+ displayName: 'Org Unit 3',
65
+ id: 'A0000000002',
66
+ path: '/A0000000000/A0000000002',
67
+ children: [],
68
+ })
69
+ }
70
+
71
+ if (id === 'A0000000003') {
72
+ data = createResponse({
73
+ fields,
74
+ displayName: 'Org Unit 4',
75
+ id: 'A0000000003',
76
+ path: '/A0000000000/A0000000001/A0000000003',
77
+ children: [
78
+ {
79
+ id: 'A0000000007',
80
+ path: '/A0000000000/A0000000001/A0000000003/A0000000007',
81
+ children: [],
82
+ displayName: 'Org Unit 8',
83
+ },
84
+ ],
85
+ })
86
+ }
87
+
88
+ if (id === 'A0000000004') {
89
+ data = createResponse({
90
+ fields,
91
+ displayName: 'Org Unit 5',
92
+ id: 'A0000000004',
93
+ path: '/A0000000000/A0000000001/A0000000004',
94
+ children: [],
95
+ })
96
+ }
97
+
98
+ if (id === 'A0000000006') {
99
+ data = createResponse({
100
+ fields,
101
+ displayName: 'Org Unit 7',
102
+ id: 'A0000000006',
103
+ path: '/A0000000000/A0000000006',
104
+ children: [],
105
+ })
106
+ }
107
+
108
+ if (id === 'A0000000007') {
109
+ data = createResponse({
110
+ fields,
111
+ displayName: 'Org Unit 8',
112
+ id: 'A0000000007',
113
+ path: '/A0000000000/A0000000001/A0000000003/A0000000007',
114
+ children: [],
115
+ })
116
+ }
117
+
118
+ return data
119
+ }
@@ -0,0 +1,23 @@
1
+ import { CustomDataProvider } from '@dhis2/app-runtime'
2
+ import React from 'react'
3
+ import { OrganisationUnitTree } from '../index.js'
4
+ import {
5
+ StatefulMultiSelectionWrapper,
6
+ dataProviderData,
7
+ namespace,
8
+ } from './common.js'
9
+
10
+ export default { title: namespace }
11
+ export const RootHighlighted = () => (
12
+ <CustomDataProvider data={dataProviderData}>
13
+ <StatefulMultiSelectionWrapper>
14
+ {({ onChange }) => (
15
+ <OrganisationUnitTree
16
+ roots="A0000000000"
17
+ onChange={onChange}
18
+ highlighted={['/A0000000000']}
19
+ />
20
+ )}
21
+ </StatefulMultiSelectionWrapper>
22
+ </CustomDataProvider>
23
+ )
@@ -0,0 +1,37 @@
1
+ import { CustomDataProvider } from '@dhis2/app-runtime'
2
+ import React from 'react'
3
+ import { OrganisationUnitTree } from '../index.js'
4
+ import {
5
+ StatefulMultiSelectionWrapper,
6
+ dataProviderData,
7
+ delayResponse,
8
+ } from './common.js'
9
+
10
+ const data = {
11
+ organisationUnits: (...args) => {
12
+ const [, { id }] = args
13
+
14
+ if (id === 'A0000000000') {
15
+ return dataProviderData.organisationUnits(...args)
16
+ }
17
+
18
+ if (id === 'A0000000001') {
19
+ return delayResponse(
20
+ 1000,
21
+ dataProviderData.organisationUnits(...args)
22
+ )()
23
+ }
24
+
25
+ return Promise.resolve({})
26
+ },
27
+ }
28
+
29
+ export const A0000000001Loading = () => (
30
+ <CustomDataProvider data={data}>
31
+ <StatefulMultiSelectionWrapper>
32
+ {({ onChange }) => (
33
+ <OrganisationUnitTree roots="A0000000000" onChange={onChange} />
34
+ )}
35
+ </StatefulMultiSelectionWrapper>
36
+ </CustomDataProvider>
37
+ )
@@ -0,0 +1,24 @@
1
+ import { CustomDataProvider } from '@dhis2/app-runtime'
2
+ import React from 'react'
3
+ import { OrganisationUnitTree } from '../index.js'
4
+ import { StatefulMultiSelectionWrapper, dataProviderData } from './common.js'
5
+
6
+ window.selection = []
7
+
8
+ export const MultipleSelection = () => (
9
+ <CustomDataProvider data={dataProviderData}>
10
+ <StatefulMultiSelectionWrapper
11
+ onSelectionChange={(newSelection) =>
12
+ (window.selection = newSelection)
13
+ }
14
+ >
15
+ {({ selected, onChange }) => (
16
+ <OrganisationUnitTree
17
+ roots="A0000000000"
18
+ onChange={onChange}
19
+ selected={selected}
20
+ />
21
+ )}
22
+ </StatefulMultiSelectionWrapper>
23
+ </CustomDataProvider>
24
+ )
@@ -0,0 +1 @@
1
+ export const namespace = 'OrganisationUnitTree'
@@ -0,0 +1,32 @@
1
+ import { CustomDataProvider } from '@dhis2/app-runtime'
2
+ import React from 'react'
3
+ import { OrganisationUnitTree } from '../index.js'
4
+ import { StatefulMultiSelectionWrapper, dataProviderData } from './common.js'
5
+
6
+ export const NoSelectionClosed = () => (
7
+ <CustomDataProvider data={dataProviderData}>
8
+ <StatefulMultiSelectionWrapper>
9
+ {({ onChange }) => (
10
+ <OrganisationUnitTree
11
+ disableSelection
12
+ roots="A0000000000"
13
+ onChange={onChange}
14
+ />
15
+ )}
16
+ </StatefulMultiSelectionWrapper>
17
+ </CustomDataProvider>
18
+ )
19
+ export const NoSelectionRootOpened = () => (
20
+ <CustomDataProvider data={dataProviderData}>
21
+ <StatefulMultiSelectionWrapper>
22
+ {({ onChange }) => (
23
+ <OrganisationUnitTree
24
+ disableSelection
25
+ roots="A0000000000"
26
+ onChange={onChange}
27
+ initiallyExpanded={['/A0000000000']}
28
+ />
29
+ )}
30
+ </StatefulMultiSelectionWrapper>
31
+ </CustomDataProvider>
32
+ )
@@ -0,0 +1,49 @@
1
+ import { CustomDataProvider } from '@dhis2/app-runtime'
2
+ import React from 'react'
3
+ import { OrganisationUnitTree } from '../index.js'
4
+ import { StatefulMultiSelectionWrapper, dataProviderData } from './common.js'
5
+
6
+ window.allUnits = []
7
+ for (let i = 0; i < 7; ++i) {
8
+ window.allUnits.push(`A000000000${i}`)
9
+ }
10
+
11
+ export const FilteredBy3LevelPath = () => (
12
+ <CustomDataProvider data={dataProviderData}>
13
+ <StatefulMultiSelectionWrapper>
14
+ {({ onChange }) => (
15
+ <OrganisationUnitTree
16
+ roots="A0000000000"
17
+ onChange={onChange}
18
+ initiallyExpanded={[
19
+ '/A0000000000',
20
+ '/A0000000000/A0000000001',
21
+ '/A0000000000/A0000000002',
22
+ ]}
23
+ filter={['/A0000000000/A0000000001/A0000000003']}
24
+ />
25
+ )}
26
+ </StatefulMultiSelectionWrapper>
27
+ </CustomDataProvider>
28
+ )
29
+ export const FilteredBy3LevelPathAnd2LevelPath = () => (
30
+ <CustomDataProvider data={dataProviderData}>
31
+ <StatefulMultiSelectionWrapper>
32
+ {({ onChange }) => (
33
+ <OrganisationUnitTree
34
+ roots="A0000000000"
35
+ onChange={onChange}
36
+ initiallyExpanded={[
37
+ '/A0000000000',
38
+ '/A0000000000/A0000000001',
39
+ '/A0000000000/A0000000002',
40
+ ]}
41
+ filter={[
42
+ '/A0000000000/A0000000001/A0000000003',
43
+ '/A0000000000/A0000000002',
44
+ ]}
45
+ />
46
+ )}
47
+ </StatefulMultiSelectionWrapper>
48
+ </CustomDataProvider>
49
+ )