@truedat/core 5.3.2 → 5.4.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/CHANGELOG.md +8 -0
- package/package.json +3 -3
- package/src/components/HierarchySelector.js +52 -0
- package/src/components/TreeSelector.js +10 -2
- package/src/components/__tests__/HierarchySelector.spec.js +91 -0
- package/src/components/__tests__/__snapshots__/CatalogMenu.spec.js.snap +1 -1
- package/src/components/__tests__/__snapshots__/DomainSelector.spec.js.snap +1 -1
- package/src/components/__tests__/__snapshots__/HierarchySelector.spec.js.snap +59 -0
- package/src/components/__tests__/__snapshots__/TreeSelector.spec.js.snap +1 -1
- package/src/components/index.js +2 -0
- package/src/messages/en.js +2 -1
- package/src/messages/es.js +2 -1
- package/src/routes.js +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [5.3.3] 2023-03-13
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- [TD-3806] Hierarchy Selector
|
|
8
|
+
|
|
3
9
|
## [5.3.2] 2023-03-13
|
|
4
10
|
|
|
5
11
|
### Fixed
|
|
@@ -12,6 +18,8 @@
|
|
|
12
18
|
|
|
13
19
|
- [TD-5509] Structure to structure link form Routes
|
|
14
20
|
|
|
21
|
+
## [5.2.9] 2023-02-28
|
|
22
|
+
|
|
15
23
|
### Added
|
|
16
24
|
|
|
17
25
|
- [TD-5599] Submenu and Routes for Tasks
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truedat/core",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.4.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.3.
|
|
38
|
+
"@truedat/test": "5.3.3",
|
|
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": "e8b1b4b4323f098ac213ecbd53fe6a005254a672"
|
|
121
121
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import PropTypes from "prop-types";
|
|
4
|
+
import { useIntl } from "react-intl";
|
|
5
|
+
import { useHierarchy } from "@truedat/df/hooks/useHierarchies";
|
|
6
|
+
import { accentInsensitivePathOrder } from "../services/sort";
|
|
7
|
+
import { stratify, flatten } from "../services/tree";
|
|
8
|
+
import TreeSelector from "./TreeSelector";
|
|
9
|
+
|
|
10
|
+
const HierarchySelector = ({
|
|
11
|
+
multiple,
|
|
12
|
+
hierarchy: hierarchyId,
|
|
13
|
+
onLoad,
|
|
14
|
+
value,
|
|
15
|
+
...props
|
|
16
|
+
}) => {
|
|
17
|
+
const { formatMessage } = useIntl();
|
|
18
|
+
|
|
19
|
+
const { data: data, error, loading } = useHierarchy(hierarchyId);
|
|
20
|
+
if (error) return null;
|
|
21
|
+
if (loading) return null;
|
|
22
|
+
onLoad(loading);
|
|
23
|
+
|
|
24
|
+
const options = _.flow(
|
|
25
|
+
_.propOr([], "nodes"),
|
|
26
|
+
_.sortBy(accentInsensitivePathOrder("name")),
|
|
27
|
+
stratify({}),
|
|
28
|
+
flatten
|
|
29
|
+
)(data);
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<TreeSelector
|
|
33
|
+
options={options}
|
|
34
|
+
placeholder={formatMessage({
|
|
35
|
+
id: multiple
|
|
36
|
+
? "hierarchy.multiple.placeholder"
|
|
37
|
+
: "hierarchy.selector.placeholder",
|
|
38
|
+
})}
|
|
39
|
+
value={value}
|
|
40
|
+
multiple={multiple}
|
|
41
|
+
{...props}
|
|
42
|
+
/>
|
|
43
|
+
);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
HierarchySelector.propTypes = {
|
|
47
|
+
multiple: PropTypes.bool,
|
|
48
|
+
onLoad: PropTypes.func,
|
|
49
|
+
value: PropTypes.oneOfType([PropTypes.array, PropTypes.number]),
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export default HierarchySelector;
|
|
@@ -12,6 +12,11 @@ export const match =
|
|
|
12
12
|
_.contains(query)(lowerDeburr(name));
|
|
13
13
|
export const matchAny = recursiveMatch(match);
|
|
14
14
|
|
|
15
|
+
const maybeMapKeys = _.map((option) => ({
|
|
16
|
+
...option,
|
|
17
|
+
id: _.has("key")(option) ? option.key : option.id,
|
|
18
|
+
}));
|
|
19
|
+
|
|
15
20
|
export const SelectedLabels = ({
|
|
16
21
|
disabled,
|
|
17
22
|
onClick,
|
|
@@ -51,6 +56,7 @@ const toggle = (id) => (value) =>
|
|
|
51
56
|
_.includes(id)(value) ? _.without([id])(value) : _.union([id])(value);
|
|
52
57
|
|
|
53
58
|
const labelValues = _.cond([
|
|
59
|
+
[_.isNumber, _.castArray],
|
|
54
60
|
[_.isArray, _.identity],
|
|
55
61
|
[_.isEmpty, _.constant([])],
|
|
56
62
|
[_.isString, _.castArray],
|
|
@@ -85,7 +91,7 @@ export const TreeSelector = ({
|
|
|
85
91
|
}, [options, open, value]);
|
|
86
92
|
|
|
87
93
|
const handleOpen = (id) => {
|
|
88
|
-
const option = _.find({ id })(options);
|
|
94
|
+
const option = _.find({ id })(maybeMapKeys(options));
|
|
89
95
|
const isOpen = _.contains(id)(open);
|
|
90
96
|
const childIds = _.map("id")(option.children);
|
|
91
97
|
const descendentIds = descendents(option);
|
|
@@ -129,7 +135,7 @@ export const TreeSelector = ({
|
|
|
129
135
|
<SelectedLabels
|
|
130
136
|
disabled={disabled}
|
|
131
137
|
placeholder={placeholder}
|
|
132
|
-
options={options}
|
|
138
|
+
options={maybeMapKeys(options)}
|
|
133
139
|
onClick={handleClick}
|
|
134
140
|
value={labelValues(value)}
|
|
135
141
|
/>
|
|
@@ -140,6 +146,7 @@ export const TreeSelector = ({
|
|
|
140
146
|
const items = _.flow(
|
|
141
147
|
filterSearch,
|
|
142
148
|
filterDisplayed,
|
|
149
|
+
maybeMapKeys,
|
|
143
150
|
_.map((option) => (
|
|
144
151
|
<DropdownMenuItem
|
|
145
152
|
key={option?.id}
|
|
@@ -156,6 +163,7 @@ export const TreeSelector = ({
|
|
|
156
163
|
|
|
157
164
|
return (
|
|
158
165
|
<Form.Dropdown
|
|
166
|
+
className="fix-dropdown-selector"
|
|
159
167
|
error={error}
|
|
160
168
|
floating
|
|
161
169
|
label={label}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { waitFor } from "@testing-library/react";
|
|
3
|
+
import userEvent from "@testing-library/user-event";
|
|
4
|
+
import { render } from "@truedat/test/render";
|
|
5
|
+
import HierarchySelector from "../HierarchySelector";
|
|
6
|
+
import en from "../../messages/en";
|
|
7
|
+
|
|
8
|
+
const hierarchy = {
|
|
9
|
+
id: 123,
|
|
10
|
+
nodes: [
|
|
11
|
+
{
|
|
12
|
+
id: 1,
|
|
13
|
+
parentId: null,
|
|
14
|
+
name: "foo",
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
id: 2,
|
|
18
|
+
parentId: 1,
|
|
19
|
+
name: "bar",
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
jest.mock("react-router-dom", () => ({
|
|
25
|
+
...jest.requireActual("react-router-dom"),
|
|
26
|
+
useParams: () => ({ id: 123 }),
|
|
27
|
+
}));
|
|
28
|
+
|
|
29
|
+
jest.mock("@truedat/df/hooks/useHierarchies", () => {
|
|
30
|
+
const originalModule = jest.requireActual("@truedat/df/hooks/useHierarchies");
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
__esModule: true,
|
|
34
|
+
...originalModule,
|
|
35
|
+
useHierarchy: jest.fn(() => ({
|
|
36
|
+
data: hierarchy,
|
|
37
|
+
loading: false,
|
|
38
|
+
})),
|
|
39
|
+
};
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const renderOpts = {
|
|
43
|
+
messages: {
|
|
44
|
+
en: {
|
|
45
|
+
...en,
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
fallback: "lazy",
|
|
49
|
+
};
|
|
50
|
+
const props = {
|
|
51
|
+
hierarchy,
|
|
52
|
+
loading: false,
|
|
53
|
+
multiple: true,
|
|
54
|
+
onChange: jest.fn(),
|
|
55
|
+
onLoad: jest.fn(),
|
|
56
|
+
hierarchy: 123,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
describe("<HierarchySelector />", () => {
|
|
60
|
+
it("matches latest snapshot", async () => {
|
|
61
|
+
const { container, queryByText } = render(
|
|
62
|
+
<HierarchySelector {...props} />,
|
|
63
|
+
renderOpts
|
|
64
|
+
);
|
|
65
|
+
await waitFor(() => {
|
|
66
|
+
expect(queryByText(/foo/)).toBeInTheDocument();
|
|
67
|
+
});
|
|
68
|
+
expect(container).toMatchSnapshot();
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it("calls onChange with selected values", async () => {
|
|
72
|
+
const { getByText, getByRole } = render(
|
|
73
|
+
<HierarchySelector {...props} />,
|
|
74
|
+
renderOpts
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
await waitFor(() => {
|
|
78
|
+
expect(getByText(/Select Hierarchies/)).toBeTruthy();
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
userEvent.click(getByText(/Select Hierarchies/));
|
|
82
|
+
|
|
83
|
+
await waitFor(() => {
|
|
84
|
+
expect(getByRole("option", { name: /foo/i })).toBeTruthy();
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
userEvent.click(getByRole("option", { name: /foo/i }));
|
|
88
|
+
expect(props.onChange.mock.calls.length).toBe(1);
|
|
89
|
+
expect(props.onChange.mock.calls[0][1]).toEqual({ value: [1] });
|
|
90
|
+
});
|
|
91
|
+
});
|
|
@@ -97,7 +97,7 @@ exports[`<CatalogMenu /> matches the latest snapshot 1`] = `
|
|
|
97
97
|
<a
|
|
98
98
|
aria-checked="false"
|
|
99
99
|
class="item"
|
|
100
|
-
href="/
|
|
100
|
+
href="/bulkUpdateTemplateContentEvents"
|
|
101
101
|
name="structures_upload_events"
|
|
102
102
|
role="option"
|
|
103
103
|
>
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`<HierarchySelector /> matches latest snapshot 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
class="field fix-dropdown-selector"
|
|
7
|
+
>
|
|
8
|
+
<div
|
|
9
|
+
aria-expanded="false"
|
|
10
|
+
aria-multiselectable="true"
|
|
11
|
+
class="ui floating multiple dropdown"
|
|
12
|
+
role="listbox"
|
|
13
|
+
tabindex="0"
|
|
14
|
+
>
|
|
15
|
+
<label>
|
|
16
|
+
Select Hierarchies
|
|
17
|
+
</label>
|
|
18
|
+
<i
|
|
19
|
+
aria-hidden="true"
|
|
20
|
+
class="dropdown icon"
|
|
21
|
+
/>
|
|
22
|
+
<div
|
|
23
|
+
class="menu transition"
|
|
24
|
+
>
|
|
25
|
+
<div
|
|
26
|
+
class="ui left icon input search"
|
|
27
|
+
>
|
|
28
|
+
<input
|
|
29
|
+
type="text"
|
|
30
|
+
/>
|
|
31
|
+
<i
|
|
32
|
+
aria-hidden="true"
|
|
33
|
+
class="search icon"
|
|
34
|
+
/>
|
|
35
|
+
</div>
|
|
36
|
+
<div
|
|
37
|
+
class="scrolling menu transition"
|
|
38
|
+
>
|
|
39
|
+
<div
|
|
40
|
+
aria-selected="false"
|
|
41
|
+
class="item"
|
|
42
|
+
role="option"
|
|
43
|
+
>
|
|
44
|
+
<div
|
|
45
|
+
style="margin-left: 0px;"
|
|
46
|
+
>
|
|
47
|
+
<i
|
|
48
|
+
aria-hidden="true"
|
|
49
|
+
class="plus icon"
|
|
50
|
+
/>
|
|
51
|
+
foo
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
59
|
+
`;
|
package/src/components/index.js
CHANGED
|
@@ -23,6 +23,7 @@ import FiltersLoader from "./FiltersLoader";
|
|
|
23
23
|
import GlossaryMenu from "./GlossaryMenu";
|
|
24
24
|
import GrantMenu from "./GrantMenu";
|
|
25
25
|
import GroupActions from "./GroupActions";
|
|
26
|
+
import HierarchySelector from "./HierarchySelector";
|
|
26
27
|
import HistoryBackButton from "./HistoryBackButton";
|
|
27
28
|
import IngestMenu from "./IngestMenu";
|
|
28
29
|
import LineageMenu from "./LineageMenu";
|
|
@@ -75,6 +76,7 @@ export {
|
|
|
75
76
|
GlossaryMenu,
|
|
76
77
|
GrantMenu,
|
|
77
78
|
GroupActions,
|
|
79
|
+
HierarchySelector,
|
|
78
80
|
HistoryBackButton,
|
|
79
81
|
IngestMenu,
|
|
80
82
|
LineageMenu,
|
package/src/messages/en.js
CHANGED
|
@@ -56,7 +56,8 @@ export default {
|
|
|
56
56
|
"form.validation.required": "{prop} is required",
|
|
57
57
|
"form.validation.minLength": "{prop} must have at least {value} characters",
|
|
58
58
|
"form.validation.email.invalid": "Invalid email address",
|
|
59
|
-
|
|
59
|
+
"hierarchy.multiple.placeholder": "Select Hierarchies",
|
|
60
|
+
"hierarchy.selector.placeholder": "Select Hierarchy",
|
|
60
61
|
"i18n.actions.createMessage": "Create message",
|
|
61
62
|
|
|
62
63
|
"i18n.message.form.messageId.placeholder": "Message ID",
|
package/src/messages/es.js
CHANGED
|
@@ -56,7 +56,8 @@ export default {
|
|
|
56
56
|
"form.validation.required": "{prop} es un campo requerido",
|
|
57
57
|
"form.validation.minLength": "{prop} debe tener al menos {value} elementos",
|
|
58
58
|
"form.validation.email.invalid": "Dirección de email inválida",
|
|
59
|
-
|
|
59
|
+
"hierarchy.multiple.placeholder": "Seleccionar Jerarquías",
|
|
60
|
+
"hierarchy.selector.placeholder": "Seleccionar Jerarquía",
|
|
60
61
|
"i18n.actions.createMessage": "Crear mensaje",
|
|
61
62
|
|
|
62
63
|
"i18n.message.form.messageId.placeholder": "Id del mensaje",
|
package/src/routes.js
CHANGED
|
@@ -174,8 +174,8 @@ export const SOURCE_JOBS = "/sources/:sourceId/jobs";
|
|
|
174
174
|
export const SOURCE_JOBS_NEW = "/sources/:sourceId/jobs/new";
|
|
175
175
|
export const STRUCTURE = "/structures/:id";
|
|
176
176
|
export const STRUCTURES = "/structures";
|
|
177
|
-
export const STRUCTURES_BULK_UPDATE = "/structures/
|
|
178
|
-
export const STRUCTURES_UPLOAD_EVENTS = "/
|
|
177
|
+
export const STRUCTURES_BULK_UPDATE = "/structures/bulkUpdate";
|
|
178
|
+
export const STRUCTURES_UPLOAD_EVENTS = "/bulkUpdateTemplateContentEvents";
|
|
179
179
|
export const STRUCTURE_CHILDREN = "/structures/:id/children";
|
|
180
180
|
export const STRUCTURE_EVENTS = "/structures/:id/events";
|
|
181
181
|
export const STRUCTURE_GRANTS = "/structures/:id/grants";
|