@truedat/core 5.7.5 → 5.8.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/package.json +3 -3
- package/src/components/DropdownMenuItem.js +3 -1
- package/src/components/HierarchySelector.js +4 -2
- package/src/components/TreeSelector.js +7 -1
- package/src/components/__tests__/HierarchySelector.spec.js +1 -1
- package/src/components/__tests__/TreeSelector.spec.js +162 -0
- package/src/components/__tests__/__snapshots__/DomainSelector.spec.js.snap +15 -3
- package/src/components/__tests__/__snapshots__/DropdownMenuItem.spec.js.snap +5 -1
- package/src/components/__tests__/__snapshots__/FilterMultilevelDropdown.spec.js.snap +10 -2
- package/src/components/__tests__/__snapshots__/HierarchyFilterDropdown.spec.js.snap +5 -1
- package/src/components/__tests__/__snapshots__/HierarchySelector.spec.js.snap +5 -1
- package/src/components/__tests__/__snapshots__/TreeSelector.spec.js.snap +5 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truedat/core",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.8.0",
|
|
4
4
|
"description": "Truedat Web Core",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"jsnext:main": "src/index.js",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"@testing-library/jest-dom": "^5.16.5",
|
|
36
36
|
"@testing-library/react": "^12.0.0",
|
|
37
37
|
"@testing-library/user-event": "^13.2.1",
|
|
38
|
-
"@truedat/test": "5.
|
|
38
|
+
"@truedat/test": "5.8.0",
|
|
39
39
|
"babel-jest": "^28.1.0",
|
|
40
40
|
"babel-plugin-dynamic-import-node": "^2.3.3",
|
|
41
41
|
"babel-plugin-lodash": "^3.3.4",
|
|
@@ -117,5 +117,5 @@
|
|
|
117
117
|
"react-dom": ">= 16.8.6 < 17",
|
|
118
118
|
"semantic-ui-react": ">= 2.0.3 < 2.2"
|
|
119
119
|
},
|
|
120
|
-
"gitHead": "
|
|
120
|
+
"gitHead": "dd51c78f3143413ec2bc9a77001d3b648fe92d0a"
|
|
121
121
|
}
|
|
@@ -12,6 +12,7 @@ export const DropdownMenuItem = ({
|
|
|
12
12
|
open,
|
|
13
13
|
name,
|
|
14
14
|
level,
|
|
15
|
+
disabled = false,
|
|
15
16
|
}) => {
|
|
16
17
|
const handleOpen = (e) => {
|
|
17
18
|
e && e.preventDefault();
|
|
@@ -36,7 +37,7 @@ export const DropdownMenuItem = ({
|
|
|
36
37
|
{check && (
|
|
37
38
|
<Icon name={selected ? "check square outline" : "square outline"} />
|
|
38
39
|
)}
|
|
39
|
-
{name}
|
|
40
|
+
<span style={{ opacity: disabled ? 0.45 : 1 }}>{name}</span>
|
|
40
41
|
</div>
|
|
41
42
|
</Dropdown.Item>
|
|
42
43
|
);
|
|
@@ -52,6 +53,7 @@ DropdownMenuItem.propTypes = {
|
|
|
52
53
|
open: PropTypes.bool,
|
|
53
54
|
name: PropTypes.string,
|
|
54
55
|
level: PropTypes.number,
|
|
56
|
+
disabled: PropTypes.bool,
|
|
55
57
|
};
|
|
56
58
|
|
|
57
59
|
export default DropdownMenuItem;
|
|
@@ -9,14 +9,14 @@ import TreeSelector from "./TreeSelector";
|
|
|
9
9
|
|
|
10
10
|
const HierarchySelector = ({
|
|
11
11
|
multiple,
|
|
12
|
-
hierarchy
|
|
12
|
+
hierarchy,
|
|
13
13
|
onLoad,
|
|
14
14
|
value,
|
|
15
15
|
...props
|
|
16
16
|
}) => {
|
|
17
17
|
const { formatMessage } = useIntl();
|
|
18
|
+
const { data: data, error, loading } = useHierarchy(hierarchy.id);
|
|
18
19
|
|
|
19
|
-
const { data: data, error, loading } = useHierarchy(hierarchyId);
|
|
20
20
|
if (error) return null;
|
|
21
21
|
if (loading) return null;
|
|
22
22
|
onLoad(loading);
|
|
@@ -31,6 +31,7 @@ const HierarchySelector = ({
|
|
|
31
31
|
return (
|
|
32
32
|
<TreeSelector
|
|
33
33
|
options={options}
|
|
34
|
+
minDepth={_.pathOr(0, "min_depth")(hierarchy)}
|
|
34
35
|
placeholder={formatMessage({
|
|
35
36
|
id: multiple
|
|
36
37
|
? "hierarchy.multiple.placeholder"
|
|
@@ -46,6 +47,7 @@ const HierarchySelector = ({
|
|
|
46
47
|
HierarchySelector.propTypes = {
|
|
47
48
|
multiple: PropTypes.bool,
|
|
48
49
|
onLoad: PropTypes.func,
|
|
50
|
+
hierarchy: PropTypes.object,
|
|
49
51
|
value: PropTypes.oneOfType([PropTypes.array, PropTypes.number]),
|
|
50
52
|
};
|
|
51
53
|
|
|
@@ -74,6 +74,7 @@ export const TreeSelector = ({
|
|
|
74
74
|
onBlur,
|
|
75
75
|
onChange,
|
|
76
76
|
options,
|
|
77
|
+
minDepth = 0,
|
|
77
78
|
placeholder,
|
|
78
79
|
required = false,
|
|
79
80
|
value: initialValue,
|
|
@@ -143,6 +144,8 @@ export const TreeSelector = ({
|
|
|
143
144
|
<label>{placeholder}</label>
|
|
144
145
|
);
|
|
145
146
|
|
|
147
|
+
const isEnabled = ({ level }, minDepth) => level >= minDepth;
|
|
148
|
+
|
|
146
149
|
const items = _.flow(
|
|
147
150
|
filterSearch,
|
|
148
151
|
filterDisplayed,
|
|
@@ -152,9 +155,11 @@ export const TreeSelector = ({
|
|
|
152
155
|
key={option?.id}
|
|
153
156
|
check={check}
|
|
154
157
|
onOpen={handleOpen}
|
|
155
|
-
onClick={handleClick}
|
|
158
|
+
onClick={isEnabled(option, minDepth) ? handleClick : () => {}}
|
|
156
159
|
open={_.contains(option.id)(open)}
|
|
157
160
|
canOpen={!_.isEmpty(option.children)}
|
|
161
|
+
level={option.level}
|
|
162
|
+
disabled={!isEnabled(option, minDepth)}
|
|
158
163
|
selected={multiple ? _.contains(option.id)(value) : value === option.id}
|
|
159
164
|
{...option}
|
|
160
165
|
/>
|
|
@@ -208,6 +213,7 @@ TreeSelector.propTypes = {
|
|
|
208
213
|
onBlur: PropTypes.func,
|
|
209
214
|
onChange: PropTypes.func,
|
|
210
215
|
options: PropTypes.array,
|
|
216
|
+
minDepth: PropTypes.number,
|
|
211
217
|
placeholder: PropTypes.string,
|
|
212
218
|
required: PropTypes.bool,
|
|
213
219
|
value: PropTypes.oneOfType([PropTypes.array, PropTypes.string]),
|
|
@@ -61,4 +61,166 @@ describe("<TreeSelector />", () => {
|
|
|
61
61
|
expect(props.onChange.mock.calls.length).toBe(1);
|
|
62
62
|
expect(props.onChange.mock.calls[0][1]).toEqual({ value: "1" });
|
|
63
63
|
});
|
|
64
|
+
|
|
65
|
+
it("select node with allowed depth (multiple)", async () => {
|
|
66
|
+
const minDepth = 2;
|
|
67
|
+
|
|
68
|
+
const props = {
|
|
69
|
+
onChange: jest.fn(),
|
|
70
|
+
options,
|
|
71
|
+
placeholder: "Select a domain",
|
|
72
|
+
minDepth: minDepth,
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const { getByText, getByRole } = render(
|
|
76
|
+
<TreeSelector multiple {...props} />,
|
|
77
|
+
renderOpts
|
|
78
|
+
);
|
|
79
|
+
userEvent.click(getByText("Select a domain"));
|
|
80
|
+
|
|
81
|
+
await waitFor(() => {
|
|
82
|
+
expect(getByRole("option", { name: /foo/i })).toBeTruthy();
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
userEvent.click(
|
|
86
|
+
getByRole("option", { name: /foo/i }).querySelector(
|
|
87
|
+
'i[class="plus icon"]'
|
|
88
|
+
)
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
await waitFor(() => {
|
|
92
|
+
expect(getByRole("option", { name: /bar/i })).toBeTruthy();
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
userEvent.click(
|
|
96
|
+
getByRole("option", { name: /bar/i }).querySelector(
|
|
97
|
+
'i[class="plus icon"]'
|
|
98
|
+
)
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
await waitFor(() => {
|
|
102
|
+
expect(getByRole("option", { name: /baz/i })).toBeTruthy();
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
userEvent.click(getByRole("option", { name: /baz/i }));
|
|
106
|
+
expect(props.onChange.mock.calls.length).toBe(1);
|
|
107
|
+
expect(props.onChange.mock.calls[0][1]).toEqual({ value: ["3"] });
|
|
108
|
+
expect(props.options.find((op) => op.id === "3") >= minDepth);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it("select node with forbidden depth (multiple)", async () => {
|
|
112
|
+
const minDepth = 2;
|
|
113
|
+
|
|
114
|
+
const props = {
|
|
115
|
+
onChange: jest.fn(),
|
|
116
|
+
options,
|
|
117
|
+
placeholder: "Select a domain",
|
|
118
|
+
minDepth: minDepth,
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const { getByText, getByRole } = render(
|
|
122
|
+
<TreeSelector multiple {...props} />,
|
|
123
|
+
renderOpts
|
|
124
|
+
);
|
|
125
|
+
userEvent.click(getByText("Select a domain"));
|
|
126
|
+
|
|
127
|
+
await waitFor(() => {
|
|
128
|
+
expect(getByRole("option", { name: /foo/i })).toBeTruthy();
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
userEvent.click(
|
|
132
|
+
getByRole("option", { name: /foo/i }).querySelector(
|
|
133
|
+
'i[class="plus icon"]'
|
|
134
|
+
)
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
await waitFor(() => {
|
|
138
|
+
expect(getByRole("option", { name: /bar/i })).toBeTruthy();
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
userEvent.click(getByRole("option", { name: /bar/i }));
|
|
142
|
+
|
|
143
|
+
expect(props.onChange.mock.calls.length).toBe(0);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it("select node with allowed depth (single)", async () => {
|
|
147
|
+
const minDepth = 2;
|
|
148
|
+
|
|
149
|
+
const props = {
|
|
150
|
+
onChange: jest.fn(),
|
|
151
|
+
options,
|
|
152
|
+
placeholder: "Select a domain",
|
|
153
|
+
minDepth: minDepth,
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
const { getByText, getByRole } = render(
|
|
157
|
+
<TreeSelector {...props} />,
|
|
158
|
+
renderOpts
|
|
159
|
+
);
|
|
160
|
+
userEvent.click(getByText("Select a domain"));
|
|
161
|
+
|
|
162
|
+
await waitFor(() => {
|
|
163
|
+
expect(getByRole("option", { name: /foo/i })).toBeTruthy();
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
userEvent.click(
|
|
167
|
+
getByRole("option", { name: /foo/i }).querySelector(
|
|
168
|
+
'i[class="plus icon"]'
|
|
169
|
+
)
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
await waitFor(() => {
|
|
173
|
+
expect(getByRole("option", { name: /bar/i })).toBeTruthy();
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
userEvent.click(
|
|
177
|
+
getByRole("option", { name: /bar/i }).querySelector(
|
|
178
|
+
'i[class="plus icon"]'
|
|
179
|
+
)
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
await waitFor(() => {
|
|
183
|
+
expect(getByRole("option", { name: /baz/i })).toBeTruthy();
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
userEvent.click(getByRole("option", { name: /baz/i }));
|
|
187
|
+
expect(props.onChange.mock.calls.length).toBe(1);
|
|
188
|
+
expect(props.onChange.mock.calls[0][1]).toEqual({ value: "3" });
|
|
189
|
+
expect(props.options.find((op) => op.id === "3") >= minDepth);
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
it("select node with forbidden depth (single)", async () => {
|
|
193
|
+
const minDepth = 2;
|
|
194
|
+
|
|
195
|
+
const props = {
|
|
196
|
+
onChange: jest.fn(),
|
|
197
|
+
options,
|
|
198
|
+
placeholder: "Select a domain",
|
|
199
|
+
minDepth: minDepth,
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
const { getByText, getByRole } = render(
|
|
203
|
+
<TreeSelector {...props} />,
|
|
204
|
+
renderOpts
|
|
205
|
+
);
|
|
206
|
+
userEvent.click(getByText("Select a domain"));
|
|
207
|
+
|
|
208
|
+
await waitFor(() => {
|
|
209
|
+
expect(getByRole("option", { name: /foo/i })).toBeTruthy();
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
userEvent.click(
|
|
213
|
+
getByRole("option", { name: /foo/i }).querySelector(
|
|
214
|
+
'i[class="plus icon"]'
|
|
215
|
+
)
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
await waitFor(() => {
|
|
219
|
+
expect(getByRole("option", { name: /bar/i })).toBeTruthy();
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
userEvent.click(getByRole("option", { name: /bar/i }));
|
|
223
|
+
|
|
224
|
+
expect(props.onChange.mock.calls.length).toBe(0);
|
|
225
|
+
});
|
|
64
226
|
});
|
|
@@ -48,7 +48,11 @@ exports[`<DomainSelector /> matches latest snapshot 1`] = `
|
|
|
48
48
|
aria-hidden="true"
|
|
49
49
|
class="plus icon"
|
|
50
50
|
/>
|
|
51
|
-
|
|
51
|
+
<span
|
|
52
|
+
style="opacity: 1;"
|
|
53
|
+
>
|
|
54
|
+
barDomain
|
|
55
|
+
</span>
|
|
52
56
|
</div>
|
|
53
57
|
</div>
|
|
54
58
|
<div
|
|
@@ -63,7 +67,11 @@ exports[`<DomainSelector /> matches latest snapshot 1`] = `
|
|
|
63
67
|
aria-hidden="true"
|
|
64
68
|
class="icon"
|
|
65
69
|
/>
|
|
66
|
-
|
|
70
|
+
<span
|
|
71
|
+
style="opacity: 1;"
|
|
72
|
+
>
|
|
73
|
+
bazDomain
|
|
74
|
+
</span>
|
|
67
75
|
</div>
|
|
68
76
|
</div>
|
|
69
77
|
<div
|
|
@@ -78,7 +86,11 @@ exports[`<DomainSelector /> matches latest snapshot 1`] = `
|
|
|
78
86
|
aria-hidden="true"
|
|
79
87
|
class="icon"
|
|
80
88
|
/>
|
|
81
|
-
|
|
89
|
+
<span
|
|
90
|
+
style="opacity: 1;"
|
|
91
|
+
>
|
|
92
|
+
fooDomain
|
|
93
|
+
</span>
|
|
82
94
|
</div>
|
|
83
95
|
</div>
|
|
84
96
|
</div>
|
|
@@ -50,7 +50,11 @@ exports[`<FilterMultilevelDropdown /> matches the latest snapshot 1`] = `
|
|
|
50
50
|
aria-hidden="true"
|
|
51
51
|
class="square outline icon"
|
|
52
52
|
/>
|
|
53
|
-
|
|
53
|
+
<span
|
|
54
|
+
style="opacity: 1;"
|
|
55
|
+
>
|
|
56
|
+
Domain 1
|
|
57
|
+
</span>
|
|
54
58
|
</div>
|
|
55
59
|
</div>
|
|
56
60
|
<div
|
|
@@ -69,7 +73,11 @@ exports[`<FilterMultilevelDropdown /> matches the latest snapshot 1`] = `
|
|
|
69
73
|
aria-hidden="true"
|
|
70
74
|
class="square outline icon"
|
|
71
75
|
/>
|
|
72
|
-
|
|
76
|
+
<span
|
|
77
|
+
style="opacity: 1;"
|
|
78
|
+
>
|
|
79
|
+
Domain 3
|
|
80
|
+
</span>
|
|
73
81
|
</div>
|
|
74
82
|
</div>
|
|
75
83
|
</div>
|