@dhis2-ui/selector-bar 7.10.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.
- package/README.md +6 -0
- package/build/cjs/index.js +21 -0
- package/build/cjs/locales/en/translations.json +3 -0
- package/build/cjs/locales/index.js +27 -0
- package/build/cjs/selector-bar/__stories__/common.js +252 -0
- package/build/cjs/selector-bar/__stories__/keep-org-unit-expanded.js +71 -0
- package/build/cjs/selector-bar/__stories__/with-multiple-rows.js +108 -0
- package/build/cjs/selector-bar/__stories__/with-right-hand-side-content.js +79 -0
- package/build/cjs/selector-bar/__stories__/with-some-inputs.js +68 -0
- package/build/cjs/selector-bar/index.js +13 -0
- package/build/cjs/selector-bar/selector-bar.js +78 -0
- package/build/cjs/selector-bar/selector-bar.stories.js +43 -0
- package/build/cjs/selector-bar/selector-bar.test.js +78 -0
- package/build/cjs/selector-bar-item/features/toggle-children/index.js +24 -0
- package/build/cjs/selector-bar-item/features/toggle-children.feature +11 -0
- package/build/cjs/selector-bar-item/index.js +13 -0
- package/build/cjs/selector-bar-item/selector-bar-item.js +100 -0
- package/build/cjs/selector-bar-item/selector-bar-item.stories.e2e.js +98 -0
- package/build/es/index.js +2 -0
- package/build/es/locales/en/translations.json +3 -0
- package/build/es/locales/index.js +13 -0
- package/build/es/selector-bar/__stories__/common.js +213 -0
- package/build/es/selector-bar/__stories__/keep-org-unit-expanded.js +54 -0
- package/build/es/selector-bar/__stories__/with-multiple-rows.js +92 -0
- package/build/es/selector-bar/__stories__/with-right-hand-side-content.js +64 -0
- package/build/es/selector-bar/__stories__/with-some-inputs.js +54 -0
- package/build/es/selector-bar/index.js +1 -0
- package/build/es/selector-bar/selector-bar.js +60 -0
- package/build/es/selector-bar/selector-bar.stories.js +7 -0
- package/build/es/selector-bar/selector-bar.test.js +64 -0
- package/build/es/selector-bar-item/features/toggle-children/index.js +21 -0
- package/build/es/selector-bar-item/features/toggle-children.feature +11 -0
- package/build/es/selector-bar-item/index.js +1 -0
- package/build/es/selector-bar-item/selector-bar-item.js +77 -0
- package/build/es/selector-bar-item/selector-bar-item.stories.e2e.js +79 -0
- package/package.json +59 -0
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import _JSXStyle from "styled-jsx/style";
|
|
2
|
+
import { Menu, MenuItem } from '@dhis2-ui/menu';
|
|
3
|
+
import { OrganisationUnitTree } from '@dhis2-ui/organisation-unit-tree';
|
|
4
|
+
import { CustomDataProvider } from '@dhis2/app-runtime';
|
|
5
|
+
import { colors } from '@dhis2/ui-constants';
|
|
6
|
+
import React, { useState } from 'react';
|
|
7
|
+
export const decoratorCommonStyles = fn => /*#__PURE__*/React.createElement(React.Fragment, null, fn(), /*#__PURE__*/React.createElement(_JSXStyle, {
|
|
8
|
+
id: "3746816729",
|
|
9
|
+
dynamic: [colors.grey100]
|
|
10
|
+
}, [`body{background:${colors.grey100};padding:0 !important;}`, "div#root{padding:0;}"]));
|
|
11
|
+
export const getOrganisationUnitData = id => {
|
|
12
|
+
let data;
|
|
13
|
+
|
|
14
|
+
if (id === 'A0000000000') {
|
|
15
|
+
data = {
|
|
16
|
+
id: 'A0000000000',
|
|
17
|
+
path: '/A0000000000',
|
|
18
|
+
displayName: 'Org Unit 1',
|
|
19
|
+
children: [{
|
|
20
|
+
id: 'A0000000001',
|
|
21
|
+
path: '/A0000000000/A0000000001',
|
|
22
|
+
children: [{
|
|
23
|
+
id: 'A0000000003'
|
|
24
|
+
}, {
|
|
25
|
+
id: 'A0000000004'
|
|
26
|
+
}],
|
|
27
|
+
displayName: 'Org Unit 2'
|
|
28
|
+
}, {
|
|
29
|
+
id: 'A0000000002',
|
|
30
|
+
path: '/A0000000000/A0000000002',
|
|
31
|
+
children: [],
|
|
32
|
+
displayName: 'Org Unit 3'
|
|
33
|
+
}, {
|
|
34
|
+
id: 'A0000000006',
|
|
35
|
+
path: '/A0000000000/A0000000006',
|
|
36
|
+
children: [],
|
|
37
|
+
displayName: 'Org Unit 7'
|
|
38
|
+
}]
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (id === 'A0000000001') {
|
|
43
|
+
data = {
|
|
44
|
+
id: 'A0000000001',
|
|
45
|
+
path: '/A0000000000/A0000000001',
|
|
46
|
+
displayName: 'Org Unit 2',
|
|
47
|
+
children: [{
|
|
48
|
+
id: 'A0000000003',
|
|
49
|
+
path: '/A0000000000/A0000000001/A0000000003',
|
|
50
|
+
children: [],
|
|
51
|
+
displayName: 'Org Unit 4'
|
|
52
|
+
}, {
|
|
53
|
+
id: 'A0000000004',
|
|
54
|
+
path: '/A0000000000/A0000000001/A0000000004',
|
|
55
|
+
children: [],
|
|
56
|
+
displayName: 'Org Unit 5'
|
|
57
|
+
}]
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (id === 'A0000000002') {
|
|
62
|
+
data = {
|
|
63
|
+
displayName: 'Org Unit 3',
|
|
64
|
+
id: 'A0000000002',
|
|
65
|
+
path: '/A0000000000/A0000000002',
|
|
66
|
+
children: []
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (id === 'A0000000003') {
|
|
71
|
+
data = {
|
|
72
|
+
displayName: 'Org Unit 4',
|
|
73
|
+
id: 'A0000000003',
|
|
74
|
+
path: '/A0000000000/A0000000001/A0000000003',
|
|
75
|
+
children: [{
|
|
76
|
+
id: 'A0000000007',
|
|
77
|
+
path: '/A0000000000/A0000000001/A0000000003/A0000000007',
|
|
78
|
+
children: [],
|
|
79
|
+
displayName: 'Org Unit 8'
|
|
80
|
+
}]
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (id === 'A0000000004') {
|
|
85
|
+
data = {
|
|
86
|
+
displayName: 'Org Unit 5',
|
|
87
|
+
id: 'A0000000004',
|
|
88
|
+
path: '/A0000000000/A0000000001/A0000000004',
|
|
89
|
+
children: []
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (id === 'A0000000006') {
|
|
94
|
+
data = {
|
|
95
|
+
displayName: 'Org Unit 7',
|
|
96
|
+
id: 'A0000000006',
|
|
97
|
+
path: '/A0000000000/A0000000006',
|
|
98
|
+
children: []
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (id === 'A0000000007') {
|
|
103
|
+
data = {
|
|
104
|
+
displayName: 'Org Unit 8',
|
|
105
|
+
id: 'A0000000007',
|
|
106
|
+
path: '/A0000000000/A0000000001/A0000000003/A0000000007',
|
|
107
|
+
children: []
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return data;
|
|
112
|
+
};
|
|
113
|
+
export const dataProviderData = {
|
|
114
|
+
organisationUnits: (_, {
|
|
115
|
+
id
|
|
116
|
+
}) => {
|
|
117
|
+
const data = getOrganisationUnitData(id);
|
|
118
|
+
|
|
119
|
+
if (!data) {
|
|
120
|
+
return Promise.reject(new Error('404 - Org unit not found'));
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return Promise.resolve(data);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
export const createDecoratorCustomDataProvider = args => {
|
|
127
|
+
const data = (args === null || args === void 0 ? void 0 : args.data) || dataProviderData;
|
|
128
|
+
return Story => {
|
|
129
|
+
window.dataProviderData = data;
|
|
130
|
+
return /*#__PURE__*/React.createElement(CustomDataProvider, {
|
|
131
|
+
data: data
|
|
132
|
+
}, /*#__PURE__*/React.createElement(Story, null));
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
export const createStatefulDecorator = args => {
|
|
136
|
+
return fn => {
|
|
137
|
+
const [workflow, setWorkflow] = useState((args === null || args === void 0 ? void 0 : args.workflow) || null);
|
|
138
|
+
const [workflowOpen, setWorkflowOpen] = useState((args === null || args === void 0 ? void 0 : args.workflowOpen) || false);
|
|
139
|
+
const [dataSet, setDataSet] = useState((args === null || args === void 0 ? void 0 : args.dataSet) || null);
|
|
140
|
+
const [dataSetOpen, setDataSetOpen] = useState((args === null || args === void 0 ? void 0 : args.dataSetOpen) || false);
|
|
141
|
+
const [orgUnit, setOrgUnit] = useState((args === null || args === void 0 ? void 0 : args.orgUnit) || null);
|
|
142
|
+
const [orgUnitOpen, setOrgUnitOpen] = useState((args === null || args === void 0 ? void 0 : args.orgUnitOpen) || false);
|
|
143
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, fn({
|
|
144
|
+
workflow,
|
|
145
|
+
setWorkflow,
|
|
146
|
+
workflowOpen,
|
|
147
|
+
setWorkflowOpen,
|
|
148
|
+
dataSet,
|
|
149
|
+
setDataSet,
|
|
150
|
+
dataSetOpen,
|
|
151
|
+
setDataSetOpen,
|
|
152
|
+
orgUnit,
|
|
153
|
+
setOrgUnit,
|
|
154
|
+
orgUnitOpen,
|
|
155
|
+
setOrgUnitOpen
|
|
156
|
+
}));
|
|
157
|
+
};
|
|
158
|
+
};
|
|
159
|
+
export const workflows = [{
|
|
160
|
+
value: 'm<4y',
|
|
161
|
+
label: 'Mortality < 4 years'
|
|
162
|
+
}, {
|
|
163
|
+
value: 'm<5y',
|
|
164
|
+
label: 'Mortality < 5 years'
|
|
165
|
+
}];
|
|
166
|
+
export const dataSets = [{
|
|
167
|
+
value: 'data-set-1',
|
|
168
|
+
label: 'Data set 1'
|
|
169
|
+
}, {
|
|
170
|
+
value: 'data-set-2',
|
|
171
|
+
label: 'Data set 2'
|
|
172
|
+
}, {
|
|
173
|
+
value: 'data-set-3',
|
|
174
|
+
label: 'Data set 3'
|
|
175
|
+
}];
|
|
176
|
+
export const MenuSelect = ({
|
|
177
|
+
values,
|
|
178
|
+
selected,
|
|
179
|
+
onChange
|
|
180
|
+
}) => {
|
|
181
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
182
|
+
style: {
|
|
183
|
+
width: 400
|
|
184
|
+
}
|
|
185
|
+
}, /*#__PURE__*/React.createElement(Menu, null, values.map(({
|
|
186
|
+
value,
|
|
187
|
+
label
|
|
188
|
+
}) => /*#__PURE__*/React.createElement(MenuItem, {
|
|
189
|
+
key: value,
|
|
190
|
+
label: label,
|
|
191
|
+
active: selected === value,
|
|
192
|
+
onClick: () => onChange({
|
|
193
|
+
selected: value
|
|
194
|
+
})
|
|
195
|
+
}))));
|
|
196
|
+
};
|
|
197
|
+
export const OrgUnitSelect = ({
|
|
198
|
+
onChange,
|
|
199
|
+
selected
|
|
200
|
+
}) => {
|
|
201
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
202
|
+
style: {
|
|
203
|
+
width: 400,
|
|
204
|
+
minHeight: 400,
|
|
205
|
+
maxHeight: '70vh'
|
|
206
|
+
}
|
|
207
|
+
}, /*#__PURE__*/React.createElement(OrganisationUnitTree, {
|
|
208
|
+
singleSelection: true,
|
|
209
|
+
onChange: onChange,
|
|
210
|
+
roots: ['A0000000000'],
|
|
211
|
+
selected: selected
|
|
212
|
+
}));
|
|
213
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { OrganisationUnitTree } from '@dhis2-ui/organisation-unit-tree';
|
|
2
|
+
import React, { useState } from 'react';
|
|
3
|
+
import { SelectorBar, SelectorBarItem } from '../../index.js';
|
|
4
|
+
import { createStatefulDecorator, decoratorCommonStyles, createDecoratorCustomDataProvider } from './common.js';
|
|
5
|
+
export const KeepOrgUnitExpanded = (_, {
|
|
6
|
+
orgUnit,
|
|
7
|
+
setOrgUnit,
|
|
8
|
+
orgUnitOpen,
|
|
9
|
+
setOrgUnitOpen
|
|
10
|
+
}) => {
|
|
11
|
+
const [expanded, setExpanded] = useState([]);
|
|
12
|
+
|
|
13
|
+
const handleExpand = ({
|
|
14
|
+
path
|
|
15
|
+
}) => setExpanded([...expanded, path]);
|
|
16
|
+
|
|
17
|
+
const handleCollapse = ({
|
|
18
|
+
path
|
|
19
|
+
}) => setExpanded(expanded.filter(p => p !== path));
|
|
20
|
+
|
|
21
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(SelectorBar, {
|
|
22
|
+
disableClearSelections: !orgUnit,
|
|
23
|
+
onClearSelectionClick: () => setOrgUnit(null)
|
|
24
|
+
}, /*#__PURE__*/React.createElement(SelectorBarItem, {
|
|
25
|
+
label: "Org unit",
|
|
26
|
+
value: orgUnit === null || orgUnit === void 0 ? void 0 : orgUnit.displayName,
|
|
27
|
+
noValueMessage: "Choose an organisation unit",
|
|
28
|
+
open: orgUnitOpen,
|
|
29
|
+
setOpen: setOrgUnitOpen
|
|
30
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
31
|
+
style: {
|
|
32
|
+
width: 400,
|
|
33
|
+
minHeight: 400,
|
|
34
|
+
maxHeight: '70vh'
|
|
35
|
+
}
|
|
36
|
+
}, /*#__PURE__*/React.createElement(OrganisationUnitTree, {
|
|
37
|
+
singleSelection: true,
|
|
38
|
+
roots: ['A0000000000'],
|
|
39
|
+
selected: orgUnit ? [orgUnit.path] : [],
|
|
40
|
+
onChange: (nextOrgUnit, evt) => {
|
|
41
|
+
evt.stopPropagation();
|
|
42
|
+
setOrgUnit(nextOrgUnit);
|
|
43
|
+
setOrgUnitOpen(false);
|
|
44
|
+
},
|
|
45
|
+
expanded: expanded,
|
|
46
|
+
handleExpand: handleExpand,
|
|
47
|
+
handleCollapse: handleCollapse
|
|
48
|
+
})))), /*#__PURE__*/React.createElement("p", {
|
|
49
|
+
style: {
|
|
50
|
+
padding: '0 16px'
|
|
51
|
+
}
|
|
52
|
+
}, "This story illustrates how to keep states between mount/unmount cycles of the component rendered inside the selector bar icon"));
|
|
53
|
+
};
|
|
54
|
+
KeepOrgUnitExpanded.decorators = [decoratorCommonStyles, createStatefulDecorator(), createDecoratorCustomDataProvider()];
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import _JSXStyle from "styled-jsx/style";
|
|
2
|
+
import { OrganisationUnitTree } from '@dhis2-ui/organisation-unit-tree';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { SelectorBar, SelectorBarItem } from '../../index.js';
|
|
5
|
+
import { MenuSelect, createDecoratorCustomDataProvider, createStatefulDecorator, dataSets, decoratorCommonStyles, workflows } from './common.js';
|
|
6
|
+
export const WithMultipleRows = (_, {
|
|
7
|
+
workflow,
|
|
8
|
+
setWorkflow,
|
|
9
|
+
workflowOpen,
|
|
10
|
+
setWorkflowOpen,
|
|
11
|
+
dataSet,
|
|
12
|
+
setDataSet,
|
|
13
|
+
dataSetOpen,
|
|
14
|
+
setDataSetOpen,
|
|
15
|
+
orgUnit,
|
|
16
|
+
setOrgUnit,
|
|
17
|
+
orgUnitOpen,
|
|
18
|
+
setOrgUnitOpen
|
|
19
|
+
}) => {
|
|
20
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
21
|
+
className: "jsx-3203152640" + " " + "narrow-container"
|
|
22
|
+
}, /*#__PURE__*/React.createElement(SelectorBar, {
|
|
23
|
+
disableClearSelections: true,
|
|
24
|
+
onClearSelectionClick: () => null
|
|
25
|
+
}, /*#__PURE__*/React.createElement(SelectorBarItem, {
|
|
26
|
+
disabled: false,
|
|
27
|
+
label: "Workflow",
|
|
28
|
+
value: workflow === null || workflow === void 0 ? void 0 : workflow.label,
|
|
29
|
+
noValueMessage: "Choose a workflow",
|
|
30
|
+
open: workflowOpen,
|
|
31
|
+
setOpen: setWorkflowOpen
|
|
32
|
+
}, /*#__PURE__*/React.createElement(MenuSelect, {
|
|
33
|
+
values: workflows,
|
|
34
|
+
selected: workflow === null || workflow === void 0 ? void 0 : workflow.value,
|
|
35
|
+
onChange: ({
|
|
36
|
+
selected
|
|
37
|
+
}) => {
|
|
38
|
+
setWorkflow(workflows.find(currentWorkflow => selected === currentWorkflow.value));
|
|
39
|
+
setWorkflowOpen(false);
|
|
40
|
+
}
|
|
41
|
+
})), /*#__PURE__*/React.createElement(SelectorBarItem, {
|
|
42
|
+
disabled: !workflow,
|
|
43
|
+
label: "Data set",
|
|
44
|
+
value: dataSet === null || dataSet === void 0 ? void 0 : dataSet.label,
|
|
45
|
+
noValueMessage: "Choose a data set",
|
|
46
|
+
open: dataSetOpen,
|
|
47
|
+
setOpen: setDataSetOpen
|
|
48
|
+
}, /*#__PURE__*/React.createElement(MenuSelect, {
|
|
49
|
+
values: dataSets,
|
|
50
|
+
selected: dataSet === null || dataSet === void 0 ? void 0 : dataSet.value,
|
|
51
|
+
onChange: ({
|
|
52
|
+
selected
|
|
53
|
+
}) => {
|
|
54
|
+
setDataSet(dataSets.find(currentWorkflow => selected === currentWorkflow.value));
|
|
55
|
+
setDataSetOpen(false);
|
|
56
|
+
}
|
|
57
|
+
})), /*#__PURE__*/React.createElement(SelectorBarItem, {
|
|
58
|
+
disabled: !workflow && !dataSet,
|
|
59
|
+
label: "Org unit",
|
|
60
|
+
value: orgUnit === null || orgUnit === void 0 ? void 0 : orgUnit.displayName,
|
|
61
|
+
noValueMessage: "Choose an organisation unit",
|
|
62
|
+
open: orgUnitOpen,
|
|
63
|
+
setOpen: setOrgUnitOpen
|
|
64
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
65
|
+
style: {
|
|
66
|
+
width: 400,
|
|
67
|
+
minHeight: 400,
|
|
68
|
+
maxHeight: '70vh'
|
|
69
|
+
},
|
|
70
|
+
className: "jsx-3203152640"
|
|
71
|
+
}, /*#__PURE__*/React.createElement(OrganisationUnitTree, {
|
|
72
|
+
singleSelection: true,
|
|
73
|
+
onChange: (nextOrgUnit, evt) => {
|
|
74
|
+
evt.stopPropagation();
|
|
75
|
+
setOrgUnit(nextOrgUnit);
|
|
76
|
+
setOrgUnitOpen(false);
|
|
77
|
+
},
|
|
78
|
+
roots: ['A0000000000'],
|
|
79
|
+
selected: orgUnit ? [orgUnit.path] : []
|
|
80
|
+
})))), /*#__PURE__*/React.createElement("p", {
|
|
81
|
+
style: {
|
|
82
|
+
padding: '0 16px',
|
|
83
|
+
textAlign: 'center'
|
|
84
|
+
},
|
|
85
|
+
className: "jsx-3203152640"
|
|
86
|
+
}, "This story shows the selection bar component with multiple rows when a workflow has been selected."), /*#__PURE__*/React.createElement(_JSXStyle, {
|
|
87
|
+
id: "3203152640"
|
|
88
|
+
}, [".narrow-container.jsx-3203152640{margin:0 auto;width:100%;max-width:600px;}"]));
|
|
89
|
+
};
|
|
90
|
+
WithMultipleRows.decorators = [decoratorCommonStyles, createStatefulDecorator({
|
|
91
|
+
workflow: workflows[0]
|
|
92
|
+
}), createDecoratorCustomDataProvider()];
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import _JSXStyle from "styled-jsx/style";
|
|
2
|
+
import { Button } from '@dhis2-ui/button';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { SelectorBar, SelectorBarItem } from '../../index.js';
|
|
5
|
+
import { OrgUnitSelect, MenuSelect, createDecoratorCustomDataProvider, createStatefulDecorator, decoratorCommonStyles, workflows } from './common.js';
|
|
6
|
+
|
|
7
|
+
const RHSContent = () => /*#__PURE__*/React.createElement("div", {
|
|
8
|
+
className: "jsx-876392447" + " " + "rhs-content"
|
|
9
|
+
}, /*#__PURE__*/React.createElement(Button, {
|
|
10
|
+
small: true
|
|
11
|
+
}, "Options"), /*#__PURE__*/React.createElement(_JSXStyle, {
|
|
12
|
+
id: "876392447"
|
|
13
|
+
}, [".rhs-content.jsx-876392447{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;height:40px;padding:0 16px;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}"]));
|
|
14
|
+
|
|
15
|
+
export const WithAdditionalContent = (_, {
|
|
16
|
+
workflow,
|
|
17
|
+
setWorkflow,
|
|
18
|
+
workflowOpen,
|
|
19
|
+
setWorkflowOpen,
|
|
20
|
+
orgUnit,
|
|
21
|
+
setOrgUnit,
|
|
22
|
+
orgUnitOpen,
|
|
23
|
+
setOrgUnitOpen
|
|
24
|
+
}) => {
|
|
25
|
+
return /*#__PURE__*/React.createElement(SelectorBar, {
|
|
26
|
+
disableClearSelections: !workflow || !orgUnit,
|
|
27
|
+
onClearSelectionClick: () => {
|
|
28
|
+
setWorkflow(null);
|
|
29
|
+
setOrgUnit(null);
|
|
30
|
+
},
|
|
31
|
+
additionalContent: /*#__PURE__*/React.createElement(RHSContent, null)
|
|
32
|
+
}, /*#__PURE__*/React.createElement(SelectorBarItem, {
|
|
33
|
+
disabled: false,
|
|
34
|
+
label: "Workflow",
|
|
35
|
+
value: workflow === null || workflow === void 0 ? void 0 : workflow.label,
|
|
36
|
+
noValueMessage: "Choose a workflow",
|
|
37
|
+
open: workflowOpen,
|
|
38
|
+
setOpen: setWorkflowOpen
|
|
39
|
+
}, /*#__PURE__*/React.createElement(MenuSelect, {
|
|
40
|
+
values: workflows,
|
|
41
|
+
selected: workflow === null || workflow === void 0 ? void 0 : workflow.value,
|
|
42
|
+
onChange: ({
|
|
43
|
+
selected
|
|
44
|
+
}) => {
|
|
45
|
+
setWorkflow(workflows.find(currentWorkflow => selected === currentWorkflow.value));
|
|
46
|
+
setWorkflowOpen(false);
|
|
47
|
+
}
|
|
48
|
+
})), /*#__PURE__*/React.createElement(SelectorBarItem, {
|
|
49
|
+
disabled: !workflow,
|
|
50
|
+
label: "Org unit",
|
|
51
|
+
value: orgUnit === null || orgUnit === void 0 ? void 0 : orgUnit.displayName,
|
|
52
|
+
noValueMessage: "Choose an organisation unit",
|
|
53
|
+
open: orgUnitOpen,
|
|
54
|
+
setOpen: setOrgUnitOpen
|
|
55
|
+
}, /*#__PURE__*/React.createElement(OrgUnitSelect, {
|
|
56
|
+
selected: orgUnit ? [orgUnit.path] : [],
|
|
57
|
+
onChange: (nextOrgUnit, evt) => {
|
|
58
|
+
evt.stopPropagation();
|
|
59
|
+
setOrgUnit(nextOrgUnit);
|
|
60
|
+
setOrgUnitOpen(false);
|
|
61
|
+
}
|
|
62
|
+
})));
|
|
63
|
+
};
|
|
64
|
+
WithAdditionalContent.decorators = [decoratorCommonStyles, createStatefulDecorator(), createDecoratorCustomDataProvider()];
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { SelectorBar, SelectorBarItem } from '../../index.js';
|
|
3
|
+
import { OrgUnitSelect, MenuSelect, createDecoratorCustomDataProvider, createStatefulDecorator, decoratorCommonStyles, workflows } from './common.js';
|
|
4
|
+
export const WithSomeInputs = (_, {
|
|
5
|
+
workflow,
|
|
6
|
+
setWorkflow,
|
|
7
|
+
workflowOpen,
|
|
8
|
+
setWorkflowOpen,
|
|
9
|
+
orgUnit,
|
|
10
|
+
setOrgUnit,
|
|
11
|
+
orgUnitOpen,
|
|
12
|
+
setOrgUnitOpen
|
|
13
|
+
}) => {
|
|
14
|
+
return /*#__PURE__*/React.createElement(SelectorBar, {
|
|
15
|
+
disableClearSelections: !workflow && !orgUnit,
|
|
16
|
+
onClearSelectionClick: () => {
|
|
17
|
+
setWorkflow(null);
|
|
18
|
+
setOrgUnit(null);
|
|
19
|
+
}
|
|
20
|
+
}, /*#__PURE__*/React.createElement(SelectorBarItem, {
|
|
21
|
+
disabled: false,
|
|
22
|
+
label: "Workflow",
|
|
23
|
+
value: workflow === null || workflow === void 0 ? void 0 : workflow.label,
|
|
24
|
+
noValueMessage: "Choose a workflow",
|
|
25
|
+
open: workflowOpen,
|
|
26
|
+
setOpen: setWorkflowOpen
|
|
27
|
+
}, /*#__PURE__*/React.createElement(MenuSelect, {
|
|
28
|
+
values: workflows,
|
|
29
|
+
selected: workflow === null || workflow === void 0 ? void 0 : workflow.value,
|
|
30
|
+
onChange: ({
|
|
31
|
+
selected
|
|
32
|
+
}) => {
|
|
33
|
+
setWorkflow(workflows.find(currentWorkflow => selected === currentWorkflow.value));
|
|
34
|
+
setWorkflowOpen(false);
|
|
35
|
+
}
|
|
36
|
+
})), /*#__PURE__*/React.createElement(SelectorBarItem, {
|
|
37
|
+
disabled: !workflow,
|
|
38
|
+
label: "Org unit",
|
|
39
|
+
value: orgUnit === null || orgUnit === void 0 ? void 0 : orgUnit.displayName,
|
|
40
|
+
noValueMessage: "Choose an organisation unit",
|
|
41
|
+
open: orgUnitOpen,
|
|
42
|
+
setOpen: setOrgUnitOpen
|
|
43
|
+
}, /*#__PURE__*/React.createElement(OrgUnitSelect, {
|
|
44
|
+
selected: orgUnit ? [orgUnit.path] : [],
|
|
45
|
+
onChange: (nextOrgUnit, evt) => {
|
|
46
|
+
evt.stopPropagation();
|
|
47
|
+
setOrgUnit(nextOrgUnit);
|
|
48
|
+
setOrgUnitOpen(false);
|
|
49
|
+
}
|
|
50
|
+
})));
|
|
51
|
+
};
|
|
52
|
+
WithSomeInputs.decorators = [decoratorCommonStyles, createStatefulDecorator({
|
|
53
|
+
workflow: workflows[0]
|
|
54
|
+
}), createDecoratorCustomDataProvider()];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SelectorBar } from './selector-bar.js';
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import _JSXStyle from "styled-jsx/style";
|
|
2
|
+
import { Button } from '@dhis2-ui/button';
|
|
3
|
+
import i18n from '@dhis2/d2-i18n';
|
|
4
|
+
import { colors, spacers } from '@dhis2/ui-constants';
|
|
5
|
+
import cx from 'classnames';
|
|
6
|
+
import PropTypes from 'prop-types';
|
|
7
|
+
import React from 'react';
|
|
8
|
+
|
|
9
|
+
const ClearSelection = ({
|
|
10
|
+
disabled,
|
|
11
|
+
onClick
|
|
12
|
+
}) => {
|
|
13
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
14
|
+
className: _JSXStyle.dynamic([["3676026375", [spacers.dp8]]]) + " " + "clear-selections"
|
|
15
|
+
}, /*#__PURE__*/React.createElement(Button, {
|
|
16
|
+
small: true,
|
|
17
|
+
secondary: true,
|
|
18
|
+
disabled: disabled,
|
|
19
|
+
onClick: onClick
|
|
20
|
+
}, i18n.t('Clear selections')), /*#__PURE__*/React.createElement(_JSXStyle, {
|
|
21
|
+
id: "3676026375",
|
|
22
|
+
dynamic: [spacers.dp8]
|
|
23
|
+
}, [`.clear-selections.__jsx-style-dynamic-selector{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:40px;padding:0 ${spacers.dp8};}`]));
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
ClearSelection.propTypes = {
|
|
27
|
+
disabled: PropTypes.bool,
|
|
28
|
+
onClick: PropTypes.func
|
|
29
|
+
};
|
|
30
|
+
export const SelectorBar = ({
|
|
31
|
+
children,
|
|
32
|
+
onClearSelectionClick,
|
|
33
|
+
disableClearSelections,
|
|
34
|
+
additionalContent
|
|
35
|
+
}) => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
|
|
36
|
+
className: _JSXStyle.dynamic([["720742913", [colors.white, colors.grey400,
|
|
37
|
+
/*
|
|
38
|
+
* Specs define the space to be 12px.
|
|
39
|
+
* 8px already come from the clear selection component
|
|
40
|
+
*/
|
|
41
|
+
'']]]) + " " + (cx('container', {
|
|
42
|
+
withRHSContents: additionalContent
|
|
43
|
+
}) || "")
|
|
44
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
45
|
+
className: _JSXStyle.dynamic([["720742913", [colors.white, colors.grey400, '']]]) + " " + "controls"
|
|
46
|
+
}, children, onClearSelectionClick && /*#__PURE__*/React.createElement(ClearSelection, {
|
|
47
|
+
disabled: disableClearSelections,
|
|
48
|
+
onClick: onClearSelectionClick
|
|
49
|
+
})), additionalContent && /*#__PURE__*/React.createElement("div", {
|
|
50
|
+
className: _JSXStyle.dynamic([["720742913", [colors.white, colors.grey400, '']]]) + " " + "additional-contents"
|
|
51
|
+
}, additionalContent), /*#__PURE__*/React.createElement(_JSXStyle, {
|
|
52
|
+
id: "720742913",
|
|
53
|
+
dynamic: [colors.white, colors.grey400, '']
|
|
54
|
+
}, [`.container.__jsx-style-dynamic-selector{background:${colors.white};box-shadow:inset 0 -1px 0 0 ${colors.grey400};padding-bottom:1px;}`, ".withRHSContents.__jsx-style-dynamic-selector{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}", ".controls.__jsx-style-dynamic-selector{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;gap:1px;}", `.additional-contents.__jsx-style-dynamic-selector{${''} padding-left:4px;}`])));
|
|
55
|
+
SelectorBar.propTypes = {
|
|
56
|
+
children: PropTypes.any.isRequired,
|
|
57
|
+
additionalContent: PropTypes.any,
|
|
58
|
+
disableClearSelections: PropTypes.bool,
|
|
59
|
+
onClearSelectionClick: PropTypes.func
|
|
60
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
title: 'Actions/SelectionBar'
|
|
3
|
+
};
|
|
4
|
+
export { WithSomeInputs } from './__stories__/with-some-inputs.js';
|
|
5
|
+
export { WithAdditionalContent } from './__stories__/with-right-hand-side-content.js';
|
|
6
|
+
export { KeepOrgUnitExpanded } from './__stories__/keep-org-unit-expanded.js';
|
|
7
|
+
export { WithMultipleRows } from './__stories__/with-multiple-rows.js';
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import '@testing-library/jest-dom';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { SelectorBarItem } from '../selector-bar-item/index.js';
|
|
5
|
+
import { SelectorBar } from './selector-bar.js';
|
|
6
|
+
|
|
7
|
+
const noop = () => null;
|
|
8
|
+
|
|
9
|
+
describe('SelectorBar', () => {
|
|
10
|
+
it('should render the selection bar items', () => {
|
|
11
|
+
render( /*#__PURE__*/React.createElement(SelectorBar, null, /*#__PURE__*/React.createElement(SelectorBarItem, {
|
|
12
|
+
label: "Selection bar item 1",
|
|
13
|
+
noValueMessage: "No value message 1",
|
|
14
|
+
open: false,
|
|
15
|
+
setOpen: noop
|
|
16
|
+
}, "Content"), /*#__PURE__*/React.createElement(SelectorBarItem, {
|
|
17
|
+
label: "Selection bar item 2",
|
|
18
|
+
noValueMessage: "No value message 2",
|
|
19
|
+
open: false,
|
|
20
|
+
setOpen: noop
|
|
21
|
+
}, "Content")));
|
|
22
|
+
expect(screen.getByText('Selection bar item 1')).not.toBeNull();
|
|
23
|
+
expect(screen.getByText('Selection bar item 2')).not.toBeNull();
|
|
24
|
+
});
|
|
25
|
+
it('should not disable the clear selection button by default', () => {
|
|
26
|
+
render( /*#__PURE__*/React.createElement(SelectorBar, {
|
|
27
|
+
onClearSelectionClick: noop
|
|
28
|
+
}, /*#__PURE__*/React.createElement(SelectorBarItem, {
|
|
29
|
+
label: "label",
|
|
30
|
+
noValueMessage: "msg",
|
|
31
|
+
open: false,
|
|
32
|
+
setOpen: noop
|
|
33
|
+
}, "Content")));
|
|
34
|
+
const clearBtn = screen.getByText('Clear selections');
|
|
35
|
+
expect(clearBtn).not.toBeNull();
|
|
36
|
+
expect(clearBtn).not.toBeDisabled();
|
|
37
|
+
});
|
|
38
|
+
it('should disable the clear selection button', () => {
|
|
39
|
+
render( /*#__PURE__*/React.createElement(SelectorBar, {
|
|
40
|
+
disableClearSelections: true,
|
|
41
|
+
onClearSelectionClick: noop
|
|
42
|
+
}, /*#__PURE__*/React.createElement(SelectorBarItem, {
|
|
43
|
+
label: "label",
|
|
44
|
+
noValueMessage: "msg",
|
|
45
|
+
open: false,
|
|
46
|
+
setOpen: noop
|
|
47
|
+
}, "Content")));
|
|
48
|
+
const clearBtn = screen.getByText('Clear selections');
|
|
49
|
+
expect(clearBtn).not.toBeNull();
|
|
50
|
+
expect(clearBtn).toBeDisabled();
|
|
51
|
+
});
|
|
52
|
+
it('should render the optional content', () => {
|
|
53
|
+
render( /*#__PURE__*/React.createElement(SelectorBar, {
|
|
54
|
+
additionalContent: /*#__PURE__*/React.createElement("div", null, "Foobar")
|
|
55
|
+
}, /*#__PURE__*/React.createElement(SelectorBarItem, {
|
|
56
|
+
label: "label",
|
|
57
|
+
noValueMessage: "msg",
|
|
58
|
+
open: false,
|
|
59
|
+
setOpen: noop
|
|
60
|
+
}, "Content")));
|
|
61
|
+
const extraContent = screen.getByText('Foobar');
|
|
62
|
+
expect(extraContent).not.toBeNull();
|
|
63
|
+
});
|
|
64
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Given, When, Then } from 'cypress-cucumber-preprocessor/steps';
|
|
2
|
+
Given('the selector bar item is closed', () => {
|
|
3
|
+
cy.visitStory('SelectorBarItem', 'closed no value');
|
|
4
|
+
});
|
|
5
|
+
Given('the selector bar item is open', () => {
|
|
6
|
+
cy.visitStory('SelectorBarItem', 'open no value');
|
|
7
|
+
});
|
|
8
|
+
When('the user opens the selector bar item', () => {
|
|
9
|
+
cy.contains('Selection bar item', {
|
|
10
|
+
selector: 'button'
|
|
11
|
+
}).click();
|
|
12
|
+
});
|
|
13
|
+
When('the user closes the selector bar item', () => {
|
|
14
|
+
cy.get('body').click('topLeft');
|
|
15
|
+
});
|
|
16
|
+
Then('the children should be displayed', () => {
|
|
17
|
+
cy.get('[data-test="dhis2-uiwidgets-singleselectfield"]').should('exist');
|
|
18
|
+
});
|
|
19
|
+
Then('the children should not be displayed', () => {
|
|
20
|
+
cy.get('[data-test="dhis2-uiwidgets-singleselectfield"]').should('not.exist');
|
|
21
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Feature: The display of the children can be toggled
|
|
2
|
+
|
|
3
|
+
Scenario: The children are being opened
|
|
4
|
+
Given the selector bar item is closed
|
|
5
|
+
When the user opens the selector bar item
|
|
6
|
+
Then the children should be displayed
|
|
7
|
+
|
|
8
|
+
Scenario: The children are being closed
|
|
9
|
+
Given the selector bar item is open
|
|
10
|
+
When the user closes the selector bar item
|
|
11
|
+
Then the children should not be displayed
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SelectorBarItem } from './selector-bar-item.js';
|