@truedat/core 4.43.6 → 4.44.2
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 +12 -0
- package/package.json +3 -3
- package/src/api/queries.js +11 -0
- package/src/components/CatalogMenu.js +2 -2
- package/src/components/DomainSelector.js +42 -0
- package/src/components/DropdownMenuItem.js +1 -1
- package/src/components/TreeSelector.js +161 -0
- package/src/components/__tests__/CatalogMenu.spec.js +10 -4
- package/src/components/__tests__/DomainSelector.spec.js +59 -0
- package/src/components/__tests__/TreeSelector.spec.js +38 -0
- package/src/components/__tests__/__snapshots__/CatalogMenu.spec.js.snap +97 -39
- package/src/components/__tests__/__snapshots__/DomainSelector.spec.js.snap +3 -0
- package/src/components/__tests__/__snapshots__/TreeSelector.spec.js.snap +59 -0
- package/src/components/index.js +5 -1
- package/src/messages/en.js +2 -2
- package/src/messages/es.js +2 -2
- package/src/routes.js +108 -101
- package/src/services/__tests__/tree.spec.js +68 -0
- package/src/services/tree.js +44 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [4.44.1] 2022-05-11
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- [TD-4089] Changes RULE_IMPLEMENTATION routes to drop the "rule" parent
|
|
8
|
+
|
|
9
|
+
## [4.44.0] 2022-05-10
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- [TD-4723] New `DomainSelector` which loads domains using GraphQL query
|
|
14
|
+
|
|
3
15
|
## [4.43.6] 2022-05-05
|
|
4
16
|
|
|
5
17
|
### Changed
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truedat/core",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.44.2",
|
|
4
4
|
"description": "Truedat Web Core",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"jsnext:main": "src/index.js",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"@babel/plugin-transform-modules-commonjs": "^7.15.0",
|
|
33
33
|
"@babel/preset-env": "^7.15.0",
|
|
34
34
|
"@babel/preset-react": "^7.14.5",
|
|
35
|
-
"@truedat/test": "4.
|
|
35
|
+
"@truedat/test": "4.44.2",
|
|
36
36
|
"babel-jest": "^27.0.6",
|
|
37
37
|
"babel-plugin-dynamic-import-node": "^2.3.3",
|
|
38
38
|
"babel-plugin-lodash": "^3.3.4",
|
|
@@ -106,5 +106,5 @@
|
|
|
106
106
|
"react-dom": ">= 16.8.6 < 17",
|
|
107
107
|
"semantic-ui-react": ">= 0.88.2 < 2.1"
|
|
108
108
|
},
|
|
109
|
-
"gitHead": "
|
|
109
|
+
"gitHead": "ca0c5fffcba96736f7a2054f3c37789da8c30a9e"
|
|
110
110
|
}
|
|
@@ -14,8 +14,8 @@ import Submenu from "./Submenu";
|
|
|
14
14
|
const items = [{ name: "structures", routes: [STRUCTURES, SYSTEMS] }];
|
|
15
15
|
|
|
16
16
|
const adminItems = [
|
|
17
|
-
{ name: "
|
|
18
|
-
{ name: "
|
|
17
|
+
{ name: "structureTypes", routes: [STRUCTURE_TYPES] },
|
|
18
|
+
{ name: "structureTags", routes: [STRUCTURE_TAGS] },
|
|
19
19
|
];
|
|
20
20
|
|
|
21
21
|
const structureNoteItems = [
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import PropTypes from "prop-types";
|
|
4
|
+
import { useIntl } from "react-intl";
|
|
5
|
+
import { useQuery } from "@apollo/client";
|
|
6
|
+
import { accentInsensitivePathOrder } from "../services/sort";
|
|
7
|
+
import { stratify, flatten } from "../services/tree";
|
|
8
|
+
import { DOMAINS_QUERY } from "../api/queries";
|
|
9
|
+
import TreeSelector from "./TreeSelector";
|
|
10
|
+
|
|
11
|
+
export const DomainSelector = ({ action, onLoad, value, ...props }) => {
|
|
12
|
+
const { formatMessage } = useIntl();
|
|
13
|
+
const { loading, error, data } = useQuery(DOMAINS_QUERY, {
|
|
14
|
+
variables: { action },
|
|
15
|
+
onCompleted: onLoad,
|
|
16
|
+
});
|
|
17
|
+
if (error) return null;
|
|
18
|
+
if (loading) return null;
|
|
19
|
+
const options = _.flow(
|
|
20
|
+
_.propOr([], "domains"),
|
|
21
|
+
_.sortBy(accentInsensitivePathOrder("name")),
|
|
22
|
+
stratify({}),
|
|
23
|
+
flatten
|
|
24
|
+
)(data);
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<TreeSelector
|
|
28
|
+
options={options}
|
|
29
|
+
placeholder={formatMessage({ id: "domain.multiple.placeholder" })}
|
|
30
|
+
value={_.map(_.toString)(value)}
|
|
31
|
+
{...props}
|
|
32
|
+
/>
|
|
33
|
+
);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
DomainSelector.propTypes = {
|
|
37
|
+
action: PropTypes.string,
|
|
38
|
+
onLoad: PropTypes.func,
|
|
39
|
+
value: PropTypes.array,
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export default DomainSelector;
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import React, { useState, useEffect } from "react";
|
|
3
|
+
import { Dropdown, Form, Icon, Input, Label } from "semantic-ui-react";
|
|
4
|
+
import PropTypes from "prop-types";
|
|
5
|
+
import { lowerDeburr } from "../services/sort";
|
|
6
|
+
import { recursiveMatch, descendents, childIds } from "../services/tree";
|
|
7
|
+
import DropdownMenuItem from "./DropdownMenuItem";
|
|
8
|
+
|
|
9
|
+
export const match =
|
|
10
|
+
(query) =>
|
|
11
|
+
({ name }) =>
|
|
12
|
+
_.contains(query)(lowerDeburr(name));
|
|
13
|
+
export const matchAny = recursiveMatch(match);
|
|
14
|
+
|
|
15
|
+
export const TreeSelector = ({
|
|
16
|
+
options,
|
|
17
|
+
error,
|
|
18
|
+
label,
|
|
19
|
+
name,
|
|
20
|
+
onBlur,
|
|
21
|
+
onChange,
|
|
22
|
+
required = false,
|
|
23
|
+
placeholder,
|
|
24
|
+
value: initialValue = [],
|
|
25
|
+
}) => {
|
|
26
|
+
const [value, setValue] = useState(initialValue);
|
|
27
|
+
const [query, setQuery] = useState();
|
|
28
|
+
const [open, setOpen] = useState([]);
|
|
29
|
+
const [displayed, setDisplayed] = useState([]);
|
|
30
|
+
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
const ids = childIds(open)(options);
|
|
33
|
+
setDisplayed((displayed) => _.union(displayed)(ids));
|
|
34
|
+
}, [options, open, value]);
|
|
35
|
+
|
|
36
|
+
const handleOpen = (id) => {
|
|
37
|
+
const option = _.find({ id })(options);
|
|
38
|
+
const isOpen = _.contains(id)(open);
|
|
39
|
+
const childIds = _.map("id")(option.children);
|
|
40
|
+
const descendentIds = descendents(option);
|
|
41
|
+
|
|
42
|
+
if (isOpen) {
|
|
43
|
+
setOpen(_.without([id, ...descendentIds])(open));
|
|
44
|
+
setDisplayed(_.without(descendentIds)(displayed));
|
|
45
|
+
} else {
|
|
46
|
+
setOpen(_.union([id])(open));
|
|
47
|
+
setDisplayed(_.union(childIds)(displayed));
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const displayAll = () => {
|
|
52
|
+
const ids = _.map("id")(options);
|
|
53
|
+
setOpen(ids);
|
|
54
|
+
setDisplayed(ids);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const handleSearch = (e, { value }) => {
|
|
58
|
+
e.preventDefault();
|
|
59
|
+
setQuery(lowerDeburr(value));
|
|
60
|
+
if (!_.isEmpty(value)) {
|
|
61
|
+
displayAll();
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const handleClick = (e, id) => {
|
|
66
|
+
const ids = _.includes(id)(value)
|
|
67
|
+
? _.without([id])(value)
|
|
68
|
+
: _.union([id])(value);
|
|
69
|
+
setValue(ids);
|
|
70
|
+
onChange && onChange(e, { value: ids });
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const filterSearch = query ? _.filter(matchAny(query)) : _.identity;
|
|
74
|
+
|
|
75
|
+
const filterDisplayed = _.filter(
|
|
76
|
+
({ id, level }) => level === 0 || _.includes(id)(displayed)
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
const trigger = _.isEmpty(value) ? (
|
|
80
|
+
<label>{placeholder}</label>
|
|
81
|
+
) : (
|
|
82
|
+
_.map((id) => (
|
|
83
|
+
<Label key={id}>
|
|
84
|
+
{_.flow(_.find({ id }), _.prop("name"))(options)}
|
|
85
|
+
<Icon
|
|
86
|
+
name="delete"
|
|
87
|
+
onClick={(e) => {
|
|
88
|
+
e.preventDefault();
|
|
89
|
+
e.stopPropagation();
|
|
90
|
+
handleClick(e, id);
|
|
91
|
+
}}
|
|
92
|
+
/>
|
|
93
|
+
</Label>
|
|
94
|
+
))(value)
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
const items = _.flow(
|
|
98
|
+
filterSearch,
|
|
99
|
+
filterDisplayed,
|
|
100
|
+
_.map((option) => (
|
|
101
|
+
<DropdownMenuItem
|
|
102
|
+
key={option?.id}
|
|
103
|
+
check={false}
|
|
104
|
+
handleOpen={handleOpen}
|
|
105
|
+
handleClick={handleClick}
|
|
106
|
+
open={_.contains(option.id)(open)}
|
|
107
|
+
canOpen={!_.isEmpty(option.children)}
|
|
108
|
+
selected={_.contains(option.id)(value)}
|
|
109
|
+
{...option}
|
|
110
|
+
/>
|
|
111
|
+
))
|
|
112
|
+
)(options);
|
|
113
|
+
|
|
114
|
+
return (
|
|
115
|
+
<Form.Dropdown
|
|
116
|
+
error={error}
|
|
117
|
+
floating
|
|
118
|
+
label={label}
|
|
119
|
+
name={name}
|
|
120
|
+
onBlur={onBlur}
|
|
121
|
+
upward={false}
|
|
122
|
+
required={required}
|
|
123
|
+
trigger={trigger}
|
|
124
|
+
multiple
|
|
125
|
+
value={value}
|
|
126
|
+
>
|
|
127
|
+
<Dropdown.Menu>
|
|
128
|
+
<Input
|
|
129
|
+
icon="search"
|
|
130
|
+
iconPosition="left"
|
|
131
|
+
className="search"
|
|
132
|
+
onKeyDown={(e) => {
|
|
133
|
+
if (e.key === " ") {
|
|
134
|
+
e.stopPropagation();
|
|
135
|
+
}
|
|
136
|
+
}}
|
|
137
|
+
onChange={handleSearch}
|
|
138
|
+
onClick={(e) => {
|
|
139
|
+
e.preventDefault();
|
|
140
|
+
e.stopPropagation();
|
|
141
|
+
}}
|
|
142
|
+
/>
|
|
143
|
+
<Dropdown.Menu scrolling>{items}</Dropdown.Menu>
|
|
144
|
+
</Dropdown.Menu>
|
|
145
|
+
</Form.Dropdown>
|
|
146
|
+
);
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
TreeSelector.propTypes = {
|
|
150
|
+
error: PropTypes.bool,
|
|
151
|
+
label: PropTypes.string,
|
|
152
|
+
name: PropTypes.string,
|
|
153
|
+
onBlur: PropTypes.func,
|
|
154
|
+
onChange: PropTypes.func,
|
|
155
|
+
options: PropTypes.array,
|
|
156
|
+
placeholder: PropTypes.string,
|
|
157
|
+
required: PropTypes.bool,
|
|
158
|
+
value: PropTypes.array,
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
export default TreeSelector;
|
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { render } from "@truedat/test/render";
|
|
3
3
|
import { CatalogMenu } from "../CatalogMenu";
|
|
4
4
|
|
|
5
5
|
jest.mock("../../hooks", () => ({
|
|
6
|
-
|
|
6
|
+
...jest.requireActual("../../hooks"),
|
|
7
7
|
useAuthorized: jest.fn(() => true),
|
|
8
8
|
}));
|
|
9
9
|
|
|
10
|
+
const renderOpts = {
|
|
11
|
+
messages: {
|
|
12
|
+
en: {},
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
|
|
10
16
|
describe("<CatalogMenu />", () => {
|
|
11
17
|
it("matches the latest snapshot", () => {
|
|
12
|
-
const
|
|
13
|
-
expect(
|
|
18
|
+
const { container } = render(<CatalogMenu />, renderOpts);
|
|
19
|
+
expect(container).toMatchSnapshot();
|
|
14
20
|
});
|
|
15
21
|
});
|
|
@@ -0,0 +1,59 @@
|
|
|
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 { DOMAINS_QUERY } from "../../api/queries";
|
|
6
|
+
import DomainSelector from "../DomainSelector";
|
|
7
|
+
|
|
8
|
+
const action = "manageStructureTags";
|
|
9
|
+
|
|
10
|
+
const domainsMock = {
|
|
11
|
+
request: { query: DOMAINS_QUERY, variables: { action } },
|
|
12
|
+
result: {
|
|
13
|
+
data: {
|
|
14
|
+
domains: [
|
|
15
|
+
{ __typename: "Domain", id: "1", name: "foo", parentId: null },
|
|
16
|
+
{ __typename: "Domain", id: "2", name: "bar", parentId: "1" },
|
|
17
|
+
{ __typename: "Domain", id: "3", name: "baz", parentId: "2" },
|
|
18
|
+
{ __typename: "Domain", id: "4", name: "xyzzy", parentId: "99" },
|
|
19
|
+
],
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
const messages = {
|
|
24
|
+
en: {
|
|
25
|
+
"domain.multiple.placeholder": "Select domains",
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const renderOpts = { mocks: [domainsMock], messages };
|
|
30
|
+
|
|
31
|
+
describe("<DomainSelector />", () => {
|
|
32
|
+
it("matches latest snapshot", () => {
|
|
33
|
+
const props = { action, onChange: jest.fn() };
|
|
34
|
+
const { container } = render(<DomainSelector {...props} />, renderOpts);
|
|
35
|
+
expect(container).toMatchSnapshot();
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("calls onChange with selected values", async () => {
|
|
39
|
+
const props = { action, onChange: jest.fn() };
|
|
40
|
+
const { getByText, getByRole } = render(
|
|
41
|
+
<DomainSelector {...props} />,
|
|
42
|
+
renderOpts
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
await waitFor(() => {
|
|
46
|
+
expect(getByText("Select domains")).toBeTruthy();
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
userEvent.click(getByText("Select domains"));
|
|
50
|
+
|
|
51
|
+
await waitFor(() => {
|
|
52
|
+
expect(getByRole("option", { name: /foo/i })).toBeTruthy();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
userEvent.click(getByRole("option", { name: /foo/i }));
|
|
56
|
+
expect(props.onChange.mock.calls.length).toBe(1);
|
|
57
|
+
expect(props.onChange.mock.calls[0][1]).toEqual({ value: ["1"] });
|
|
58
|
+
});
|
|
59
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
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 TreeSelector from "../TreeSelector";
|
|
6
|
+
|
|
7
|
+
const baz = { id: "3", level: 2, name: "baz", children: [] };
|
|
8
|
+
const bar = { id: "2", level: 1, name: "bar", children: [baz] };
|
|
9
|
+
const foo = { id: "1", level: 0, name: "foo", children: [bar] };
|
|
10
|
+
const options = [foo, bar, baz];
|
|
11
|
+
|
|
12
|
+
const renderOpts = {};
|
|
13
|
+
const onChange = jest.fn();
|
|
14
|
+
const props = { options, placeholder: "Select a domain", onChange };
|
|
15
|
+
|
|
16
|
+
describe("<TreeSelector />", () => {
|
|
17
|
+
it("matches latest snapshot", () => {
|
|
18
|
+
const { container } = render(<TreeSelector {...props} />, renderOpts);
|
|
19
|
+
expect(container).toMatchSnapshot();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("calls onChange with selected values", async () => {
|
|
23
|
+
const { getByText, getByRole } = render(
|
|
24
|
+
<TreeSelector {...props} />,
|
|
25
|
+
renderOpts
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
userEvent.click(getByText("Select a domain"));
|
|
29
|
+
|
|
30
|
+
await waitFor(() => {
|
|
31
|
+
expect(getByRole("option", { name: /foo/i })).toBeTruthy();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
userEvent.click(getByRole("option", { name: /foo/i }));
|
|
35
|
+
expect(onChange.mock.calls.length).toBe(1);
|
|
36
|
+
expect(onChange.mock.calls[0][1]).toEqual({ value: ["1"] });
|
|
37
|
+
});
|
|
38
|
+
});
|
|
@@ -1,43 +1,101 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
3
|
exports[`<CatalogMenu /> matches the latest snapshot 1`] = `
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
"
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
"
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
4
|
+
<div>
|
|
5
|
+
<div>
|
|
6
|
+
<div
|
|
7
|
+
aria-expanded="false"
|
|
8
|
+
class="ui item dropdown"
|
|
9
|
+
role="listbox"
|
|
10
|
+
tabindex="0"
|
|
11
|
+
>
|
|
12
|
+
<a
|
|
13
|
+
class="ui"
|
|
14
|
+
href="/structures"
|
|
15
|
+
>
|
|
16
|
+
<i
|
|
17
|
+
aria-hidden="true"
|
|
18
|
+
class="block layout large icon"
|
|
19
|
+
/>
|
|
20
|
+
</a>
|
|
21
|
+
<div
|
|
22
|
+
class="menu transition"
|
|
23
|
+
>
|
|
24
|
+
<div
|
|
25
|
+
class="header selectable"
|
|
26
|
+
>
|
|
27
|
+
catalog
|
|
28
|
+
</div>
|
|
29
|
+
<div
|
|
30
|
+
class="divider"
|
|
31
|
+
/>
|
|
32
|
+
<a
|
|
33
|
+
aria-checked="false"
|
|
34
|
+
class="item"
|
|
35
|
+
href="/structures"
|
|
36
|
+
name="structures"
|
|
37
|
+
role="option"
|
|
38
|
+
>
|
|
39
|
+
<span
|
|
40
|
+
class="text"
|
|
41
|
+
>
|
|
42
|
+
structures
|
|
43
|
+
</span>
|
|
44
|
+
</a>
|
|
45
|
+
<a
|
|
46
|
+
aria-checked="false"
|
|
47
|
+
class="item"
|
|
48
|
+
href="/structureTypes"
|
|
49
|
+
name="structureTypes"
|
|
50
|
+
role="option"
|
|
51
|
+
>
|
|
52
|
+
<span
|
|
53
|
+
class="text"
|
|
54
|
+
>
|
|
55
|
+
structureTypes
|
|
56
|
+
</span>
|
|
57
|
+
</a>
|
|
58
|
+
<a
|
|
59
|
+
aria-checked="false"
|
|
60
|
+
class="item"
|
|
61
|
+
href="/structureTags"
|
|
62
|
+
name="structureTags"
|
|
63
|
+
role="option"
|
|
64
|
+
>
|
|
65
|
+
<span
|
|
66
|
+
class="text"
|
|
67
|
+
>
|
|
68
|
+
structureTags
|
|
69
|
+
</span>
|
|
70
|
+
</a>
|
|
71
|
+
<a
|
|
72
|
+
aria-checked="false"
|
|
73
|
+
class="item"
|
|
74
|
+
href="/structureNotes"
|
|
75
|
+
name="pending_structure_notes"
|
|
76
|
+
role="option"
|
|
77
|
+
>
|
|
78
|
+
<span
|
|
79
|
+
class="text"
|
|
80
|
+
>
|
|
81
|
+
pending_structure_notes
|
|
82
|
+
</span>
|
|
83
|
+
</a>
|
|
84
|
+
<a
|
|
85
|
+
aria-checked="false"
|
|
86
|
+
class="item"
|
|
87
|
+
href="/bulk_update_template_content_events"
|
|
88
|
+
name="structures_upload_events"
|
|
89
|
+
role="option"
|
|
90
|
+
>
|
|
91
|
+
<span
|
|
92
|
+
class="text"
|
|
93
|
+
>
|
|
94
|
+
structures_upload_events
|
|
95
|
+
</span>
|
|
96
|
+
</a>
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
43
101
|
`;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`<TreeSelector /> matches latest snapshot 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
class="field"
|
|
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 a domain
|
|
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
|
@@ -12,6 +12,7 @@ import DashboardMenu from "./DashboardMenu";
|
|
|
12
12
|
import DateFilter from "./DateFilter";
|
|
13
13
|
import DateRangeFilter from "./DateRangeFilter";
|
|
14
14
|
import DateTime from "./DateTime";
|
|
15
|
+
import DomainSelector from "./DomainSelector";
|
|
15
16
|
import DropdownMenuItem from "./DropdownMenuItem";
|
|
16
17
|
import ErrorBoundary from "./ErrorBoundary";
|
|
17
18
|
import FiltersLoader from "./FiltersLoader";
|
|
@@ -36,6 +37,7 @@ import SidebarToggle from "./SidebarToggle";
|
|
|
36
37
|
import SideMenu from "./SideMenu";
|
|
37
38
|
import Submenu from "./Submenu";
|
|
38
39
|
import TaxonomyMenu from "./TaxonomyMenu";
|
|
40
|
+
import TreeSelector from "./TreeSelector";
|
|
39
41
|
import Unauthorized from "./Unauthorized";
|
|
40
42
|
import UploadModal from "./UploadModal";
|
|
41
43
|
|
|
@@ -54,6 +56,7 @@ export {
|
|
|
54
56
|
DateFilter,
|
|
55
57
|
DateRangeFilter,
|
|
56
58
|
DateTime,
|
|
59
|
+
DomainSelector,
|
|
57
60
|
DropdownMenuItem,
|
|
58
61
|
ErrorBoundary,
|
|
59
62
|
FiltersLoader,
|
|
@@ -78,6 +81,7 @@ export {
|
|
|
78
81
|
SideMenu,
|
|
79
82
|
Submenu,
|
|
80
83
|
TaxonomyMenu,
|
|
84
|
+
TreeSelector,
|
|
81
85
|
Unauthorized,
|
|
82
|
-
UploadModal
|
|
86
|
+
UploadModal,
|
|
83
87
|
};
|
package/src/messages/en.js
CHANGED
|
@@ -92,8 +92,8 @@ export default {
|
|
|
92
92
|
"sidemenu.rules": "Quality Rules",
|
|
93
93
|
"sidemenu.search": "Search",
|
|
94
94
|
"sidemenu.sources": "Sources",
|
|
95
|
-
"sidemenu.
|
|
96
|
-
"sidemenu.
|
|
95
|
+
"sidemenu.structureTags": "Structure Tags",
|
|
96
|
+
"sidemenu.structureTypes": "Structure Types",
|
|
97
97
|
"sidemenu.structures": "Structures",
|
|
98
98
|
"sidemenu.structures_upload_events": "My loads",
|
|
99
99
|
"sidemenu.subscriptions": "Subscriptions",
|
package/src/messages/es.js
CHANGED
|
@@ -95,8 +95,8 @@ export default {
|
|
|
95
95
|
"sidemenu.rules": "Reglas",
|
|
96
96
|
"sidemenu.search": "Búsqueda",
|
|
97
97
|
"sidemenu.sources": "Orígenes",
|
|
98
|
-
"sidemenu.
|
|
99
|
-
"sidemenu.
|
|
98
|
+
"sidemenu.structureTags": "Etiquetas de estructura",
|
|
99
|
+
"sidemenu.structureTypes": "Tipos de estructura",
|
|
100
100
|
"sidemenu.structures": "Estructuras",
|
|
101
101
|
"sidemenu.structures_upload_events": "Mis cargas",
|
|
102
102
|
"sidemenu.subscriptions": "Suscripciones",
|
package/src/routes.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
2
|
import { compile } from "path-to-regexp";
|
|
3
3
|
|
|
4
|
-
export const GRANT_REQUEST_APPROVALS = "/grant_request_approvals";
|
|
5
4
|
export const CALLBACK = "/callback";
|
|
6
|
-
export const CONCEPT_VERSION = "/concepts/:business_concept_id/versions/:id";
|
|
7
5
|
export const CONCEPTS = "/concepts";
|
|
8
6
|
export const CONCEPTS_BULK_UPDATE = "/concepts/bulk_update";
|
|
9
7
|
export const CONCEPTS_NEW = "/concepts/new";
|
|
@@ -17,17 +15,17 @@ export const CONCEPT_LINKS_CONCEPTS =
|
|
|
17
15
|
"/concepts/:business_concept_id/versions/:id/links/concepts";
|
|
18
16
|
export const CONCEPT_LINKS_CONCEPTS_NEW =
|
|
19
17
|
"/concepts/:business_concept_id/versions/:id/links/concepts/new";
|
|
18
|
+
export const CONCEPT_LINKS_IMPLEMENTATIONS =
|
|
19
|
+
"/concepts/:business_concept_id/versions/:id/links/implementations";
|
|
20
20
|
export const CONCEPT_LINKS_STRUCTURES =
|
|
21
21
|
"/concepts/:business_concept_id/versions/:id/links/structures";
|
|
22
22
|
export const CONCEPT_LINKS_STRUCTURES_NEW =
|
|
23
23
|
"/concepts/:business_concept_id/versions/:id/links/structures/new";
|
|
24
|
-
|
|
25
|
-
export const CONCEPT_LINKS_IMPLEMENTATIONS =
|
|
26
|
-
"/concepts/:business_concept_id/versions/:id/links/implementations";
|
|
27
24
|
export const CONCEPT_RULES =
|
|
28
25
|
"/concepts/:business_concept_id/versions/:id/rules";
|
|
29
26
|
export const CONCEPT_RULES_NEW =
|
|
30
27
|
"/concepts/:business_concept_id/versions/:id/rules/new";
|
|
28
|
+
export const CONCEPT_VERSION = "/concepts/:business_concept_id/versions/:id";
|
|
31
29
|
export const CONFIGURATION = "/configurations/:external_id";
|
|
32
30
|
export const CONFIGURATIONS = "/configurations";
|
|
33
31
|
export const CONFIGURATION_CREATE = "/configurations/new";
|
|
@@ -44,11 +42,11 @@ export const DOMAIN_MEMBERS = "/domains/:id/members";
|
|
|
44
42
|
export const DOMAIN_MEMBERS_NEW = "/domains/:id/members/new";
|
|
45
43
|
export const DOMAIN_NEW = "/domains/:id/new";
|
|
46
44
|
export const EXECUTION_GROUP = "/executionGroups/:id";
|
|
47
|
-
export const GRANT_REQUESTS = "/grant_requests";
|
|
48
|
-
export const GRANT_REQUEST = "/grant_requests/:id";
|
|
49
|
-
|
|
50
45
|
export const GRANTS = "/grants";
|
|
51
46
|
export const GRANTS_REQUESTS_CHECKOUT = "/grants_requests/checkout";
|
|
47
|
+
export const GRANT_REQUEST = "/grant_requests/:id";
|
|
48
|
+
export const GRANT_REQUESTS = "/grant_requests";
|
|
49
|
+
export const GRANT_REQUEST_APPROVALS = "/grant_request_approvals";
|
|
52
50
|
export const GRAPH = "/graphs/:id";
|
|
53
51
|
export const GRAPHS = "/graphs";
|
|
54
52
|
export const GROUP = "/groups/:id";
|
|
@@ -57,13 +55,33 @@ export const GROUP_CREATE = "/groups/new";
|
|
|
57
55
|
export const GROUP_EDIT = "/groups/:id/edit";
|
|
58
56
|
export const IMPLEMENTATIONS = "/implementations";
|
|
59
57
|
export const IMPLEMENTATION_CONCEPT_LINKS =
|
|
60
|
-
"/
|
|
58
|
+
"/implementations/:implementation_id/links/concepts";
|
|
61
59
|
export const IMPLEMENTATION_CONCEPT_LINKS_NEW =
|
|
62
|
-
"/
|
|
60
|
+
"/implementations/:implementation_id/links/concepts/new";
|
|
63
61
|
export const IMPLEMENTATION_STRUCTURES =
|
|
64
|
-
"/
|
|
62
|
+
"/implementations/:implementation_id/structures";
|
|
65
63
|
export const IMPLEMENTATION_STRUCTURES_NEW =
|
|
66
|
-
"/
|
|
64
|
+
"/implementations/:implementation_id/structures/new";
|
|
65
|
+
export const IMPLEMENTATION_NEW = "/implementations/new";
|
|
66
|
+
export const IMPLEMENTATION_NEW_RAW = "/implementations/new_raw";
|
|
67
|
+
export const IMPLEMENTATION = "/implementations/:implementation_id(\\d+)";
|
|
68
|
+
export const IMPLEMENTATION_EVENTS =
|
|
69
|
+
"/implementations/:implementation_id/events";
|
|
70
|
+
export const IMPLEMENTATION_EDIT = "/implementations/:implementation_id/edit";
|
|
71
|
+
export const IMPLEMENTATION_CLONE = "/implementations/:implementation_id/clone";
|
|
72
|
+
export const IMPLEMENTATION_MOVE = "/implementations/:implementation_id/move";
|
|
73
|
+
export const IMPLEMENTATION_RESULT_DETAILS =
|
|
74
|
+
"/implementations/:implementation_id/results/:rule_result_id";
|
|
75
|
+
export const IMPLEMENTATION_RESULT_SEGMENTS_RESULTS =
|
|
76
|
+
"/implementations/:implementation_id/results/:rule_result_id/segment_results";
|
|
77
|
+
export const IMPLEMENTATION_RESULT_REMEDIATION_PLAN =
|
|
78
|
+
"/implementations/:implementation_id/results/:rule_result_id/remediation_plan";
|
|
79
|
+
export const IMPLEMENTATION_RESULT_DETAILS_REMEDIATION_PLAN =
|
|
80
|
+
"/implementations/:implementation_id/results/:rule_result_id/remediation_plan";
|
|
81
|
+
export const IMPLEMENTATION_RESULTS =
|
|
82
|
+
"/implementations/:implementation_id/results";
|
|
83
|
+
export const IMPLEMENTATION_RESULTS_DETAILS =
|
|
84
|
+
"/implementations/:implementation_id/detail";
|
|
67
85
|
export const INGEST = "/ingests/:id";
|
|
68
86
|
export const INGESTS = "/ingests";
|
|
69
87
|
export const INGESTS_NEW = "/ingests/new";
|
|
@@ -83,19 +101,19 @@ export const JOB = "/jobs/:id";
|
|
|
83
101
|
export const JOBS = "/jobs";
|
|
84
102
|
export const LINEAGE_EVENTS = "/lineage_events";
|
|
85
103
|
export const LOGIN = "/login";
|
|
86
|
-
export const MY_GRANT_REQUESTS = "/my_grant_requests";
|
|
87
104
|
export const MY_GRANTS = "/my_grants";
|
|
105
|
+
export const MY_GRANT_REQUESTS = "/my_grant_requests";
|
|
88
106
|
export const PASSWORD = "/password";
|
|
89
|
-
export const PENDING_STRUCTURE_NOTES = "/
|
|
107
|
+
export const PENDING_STRUCTURE_NOTES = "/structureNotes";
|
|
90
108
|
export const PROFILE_EXECUTION =
|
|
91
109
|
"/profileGroups/:group_id/profileExecutions/:id";
|
|
92
110
|
export const PROFILE_GROUP = "/profileGroups/:id";
|
|
93
111
|
export const QUALITY_DASHBOARD = "/quality_dashboard";
|
|
94
|
-
export const REMEDIATION_PLAN = "/rule_results/:rule_result_id/remediation";
|
|
95
112
|
export const REMEDIATION_EDIT =
|
|
96
|
-
"/rules/:id/implementations/:implementation_id/
|
|
113
|
+
"/rules/:id/implementations/:implementation_id/results/:rule_result_id/remediation/edit";
|
|
97
114
|
export const REMEDIATION_NEW =
|
|
98
|
-
"/rules/:id/implementations/:implementation_id/
|
|
115
|
+
"/rules/:id/implementations/:implementation_id/results/:rule_result_id/remediation/new";
|
|
116
|
+
export const REMEDIATION_PLAN = "/rule_results/:rule_result_id/remediation";
|
|
99
117
|
export const ROLE = "/roles/:id";
|
|
100
118
|
export const ROLES = "/roles";
|
|
101
119
|
export const ROLES_NEW = "/roles/new";
|
|
@@ -103,28 +121,9 @@ export const RULE = "/rules/:id(\\d+)";
|
|
|
103
121
|
export const RULES = "/rules";
|
|
104
122
|
export const RULE_EDIT = "/rules/:id/edit";
|
|
105
123
|
export const RULE_EVENTS = "/rules/:id/events";
|
|
106
|
-
export const RULE_IMPLEMENTATION =
|
|
107
|
-
"/rules/:id/implementations/:implementation_id(\\d+)";
|
|
108
124
|
export const RULE_IMPLEMENTATIONS = "/rules/:id/implementations";
|
|
109
|
-
export const RULE_IMPLEMENTATION_EVENTS =
|
|
110
|
-
"/rules/:id/implementations/:implementation_id/events";
|
|
111
125
|
export const RULE_IMPLEMENTATION_NEW = "/rules/:id/implementations/new";
|
|
112
|
-
export const
|
|
113
|
-
"/rules/:id/implementations/:implementation_id/edit";
|
|
114
|
-
export const RULE_IMPLEMENTATION_CLONE =
|
|
115
|
-
"/rules/:id/implementations/:implementation_id/clone";
|
|
116
|
-
export const RULE_IMPLEMENTATION_MOVE =
|
|
117
|
-
"/rules/:id/implementations/:implementation_id/move";
|
|
118
|
-
export const RULE_IMPLEMENTATION_RESULT_DETAILS =
|
|
119
|
-
"/rules/:id/implementations/:implementation_id/results/:rule_result_id";
|
|
120
|
-
export const RULE_IMPLEMENTATION_RESULT_SEGMENTS_RESULTS =
|
|
121
|
-
"/rules/:id/implementations/:implementation_id/results/:rule_result_id/segment_results";
|
|
122
|
-
export const RULE_IMPLEMENTATION_RESULT_REMEDIATION_PLAN =
|
|
123
|
-
"/rules/:id/implementations/:implementation_id/results/:rule_result_id/remediation_plan";
|
|
124
|
-
export const RULE_IMPLEMENTATION_RESULTS =
|
|
125
|
-
"/rules/:id/implementations/:implementation_id/results";
|
|
126
|
-
export const RULE_IMPLEMENTATION_RESULTS_DETAILS =
|
|
127
|
-
"/rules/:id/implementations/:implementation_id/detail";
|
|
126
|
+
export const RULE_IMPLEMENTATION_NEW_RAW = "/rules/:id/implementations/new_raw";
|
|
128
127
|
export const RULE_NEW = "/rules/new";
|
|
129
128
|
export const SAMPLE = "/sample";
|
|
130
129
|
export const SEARCH = "/search";
|
|
@@ -156,11 +155,11 @@ export const STRUCTURE_PARENTS = "/structures/:id/parents";
|
|
|
156
155
|
export const STRUCTURE_PROFILE = "/structures/:id/profile";
|
|
157
156
|
export const STRUCTURE_RULES_IMPLEMENTATIONS =
|
|
158
157
|
"/structures/:id/rules_implementations";
|
|
159
|
-
export const STRUCTURE_TAGS = "/
|
|
160
|
-
export const
|
|
161
|
-
export const
|
|
162
|
-
export const STRUCTURE_TYPES = "/
|
|
163
|
-
export const STRUCTURE_TYPES_EDIT = "/
|
|
158
|
+
export const STRUCTURE_TAGS = "/structureTags";
|
|
159
|
+
export const STRUCTURE_TAGS_EDIT = "/structureTags/:id/edit";
|
|
160
|
+
export const STRUCTURE_TAGS_NEW = "/structureTags/new";
|
|
161
|
+
export const STRUCTURE_TYPES = "/structureTypes";
|
|
162
|
+
export const STRUCTURE_TYPES_EDIT = "/structureTypes/:id/edit";
|
|
164
163
|
export const STRUCTURE_VERSION = "/structures/:id/versions/:version";
|
|
165
164
|
export const STRUCTURE_VERSIONS = "/structures/:id/versions";
|
|
166
165
|
export const STRUCTURE_VERSION_VERSIONS =
|
|
@@ -168,8 +167,8 @@ export const STRUCTURE_VERSION_VERSIONS =
|
|
|
168
167
|
export const STRUCTURES_UPLOAD_EVENTS = "/bulk_update_template_content_events";
|
|
169
168
|
export const SUBSCRIPTION = "/subscriptions/:id";
|
|
170
169
|
export const SUBSCRIPTIONS = "/subscriptions";
|
|
171
|
-
export const SUBSCRIPTION_NEW = "/subscriptions/new";
|
|
172
170
|
export const SUBSCRIPTION_EDIT = "/subscriptions/:id/edit";
|
|
171
|
+
export const SUBSCRIPTION_NEW = "/subscriptions/new";
|
|
173
172
|
export const SYSTEMS = "/systems";
|
|
174
173
|
export const SYSTEM_EDIT = "/systems/:id/edit";
|
|
175
174
|
export const SYSTEM_NEW = "/systems/new";
|
|
@@ -189,133 +188,139 @@ export const USER_EDIT = "/users/:id/edit";
|
|
|
189
188
|
export const USER_EDIT_PASSWORD = "/users/:id/password";
|
|
190
189
|
|
|
191
190
|
const routes = {
|
|
192
|
-
GRANT_REQUEST_APPROVALS,
|
|
193
191
|
CALLBACK,
|
|
192
|
+
CONCEPTS,
|
|
193
|
+
CONCEPTS_BULK_UPDATE,
|
|
194
|
+
CONCEPTS_NEW,
|
|
195
|
+
CONCEPTS_PENDING,
|
|
194
196
|
CONCEPT_ARCHIVE,
|
|
195
197
|
CONCEPT_EDIT,
|
|
196
198
|
CONCEPT_EVENTS,
|
|
197
|
-
CONCEPT_LINKS_CONCEPTS_NEW,
|
|
198
199
|
CONCEPT_LINKS_CONCEPTS,
|
|
199
|
-
|
|
200
|
-
CONCEPT_LINKS_STRUCTURES,
|
|
200
|
+
CONCEPT_LINKS_CONCEPTS_NEW,
|
|
201
201
|
CONCEPT_LINKS_IMPLEMENTATIONS,
|
|
202
|
-
|
|
202
|
+
CONCEPT_LINKS_STRUCTURES,
|
|
203
|
+
CONCEPT_LINKS_STRUCTURES_NEW,
|
|
203
204
|
CONCEPT_RULES,
|
|
205
|
+
CONCEPT_RULES_NEW,
|
|
204
206
|
CONCEPT_VERSION,
|
|
205
|
-
CONCEPTS_BULK_UPDATE,
|
|
206
|
-
CONCEPTS_NEW,
|
|
207
|
-
CONCEPTS_PENDING,
|
|
208
|
-
CONCEPTS,
|
|
209
|
-
CONFIGURATION_EDIT,
|
|
210
207
|
CONFIGURATION,
|
|
208
|
+
CONFIGURATION_EDIT,
|
|
211
209
|
DASHBOARD,
|
|
212
|
-
DOMAIN_ACTION,
|
|
213
|
-
DOMAIN_EDIT,
|
|
214
|
-
DOMAIN_MEMBERS_NEW,
|
|
215
|
-
DOMAIN_MEMBERS,
|
|
216
|
-
DOMAIN_NEW,
|
|
217
210
|
DOMAIN,
|
|
211
|
+
DOMAINS,
|
|
218
212
|
DOMAINS_ACTIONS,
|
|
219
213
|
DOMAINS_NEW,
|
|
220
214
|
DOMAINS_SEARCH,
|
|
221
|
-
|
|
215
|
+
DOMAIN_ACTION,
|
|
216
|
+
DOMAIN_EDIT,
|
|
217
|
+
DOMAIN_MEMBERS,
|
|
218
|
+
DOMAIN_MEMBERS_NEW,
|
|
219
|
+
DOMAIN_NEW,
|
|
222
220
|
EXECUTION_GROUP,
|
|
223
|
-
GRANT_REQUEST,
|
|
224
|
-
GRANT_REQUESTS,
|
|
225
221
|
GRANTS,
|
|
226
222
|
GRANTS_REQUESTS_CHECKOUT,
|
|
223
|
+
GRANT_REQUEST,
|
|
224
|
+
GRANT_REQUESTS,
|
|
225
|
+
GRANT_REQUEST_APPROVALS,
|
|
227
226
|
GRAPH,
|
|
228
227
|
GRAPHS,
|
|
229
|
-
GROUP_CREATE,
|
|
230
|
-
GROUP_EDIT,
|
|
231
228
|
GROUP,
|
|
232
229
|
GROUPS,
|
|
230
|
+
GROUP_CREATE,
|
|
231
|
+
GROUP_EDIT,
|
|
233
232
|
IMPLEMENTATIONS,
|
|
233
|
+
IMPLEMENTATION_NEW,
|
|
234
|
+
IMPLEMENTATION_NEW_RAW,
|
|
235
|
+
IMPLEMENTATION,
|
|
236
|
+
IMPLEMENTATION_EDIT,
|
|
237
|
+
IMPLEMENTATION_EVENTS,
|
|
238
|
+
IMPLEMENTATION_CLONE,
|
|
239
|
+
IMPLEMENTATION_MOVE,
|
|
240
|
+
IMPLEMENTATION_RESULT_DETAILS,
|
|
241
|
+
IMPLEMENTATION_RESULT_SEGMENTS_RESULTS,
|
|
242
|
+
IMPLEMENTATION_RESULT_REMEDIATION_PLAN,
|
|
243
|
+
IMPLEMENTATION_RESULTS,
|
|
244
|
+
IMPLEMENTATION_RESULTS_DETAILS,
|
|
245
|
+
INGEST,
|
|
246
|
+
INGESTS,
|
|
247
|
+
INGESTS_NEW,
|
|
248
|
+
INGESTS_PENDING,
|
|
234
249
|
INGEST_ARCHIVE,
|
|
235
250
|
INGEST_DUPLICATE,
|
|
236
251
|
INGEST_EDIT,
|
|
237
252
|
INGEST_EVENTS,
|
|
238
253
|
INGEST_EXECUTIONS,
|
|
239
|
-
INGEST_RELATIONS_INGESTS_NEW,
|
|
240
254
|
INGEST_RELATIONS_INGESTS,
|
|
241
|
-
|
|
255
|
+
INGEST_RELATIONS_INGESTS_NEW,
|
|
242
256
|
INGEST_RELATIONS_STRUCTURES,
|
|
243
|
-
|
|
244
|
-
INGESTS_NEW,
|
|
245
|
-
INGESTS_PENDING,
|
|
246
|
-
INGESTS,
|
|
257
|
+
INGEST_RELATIONS_STRUCTURES_NEW,
|
|
247
258
|
JOB,
|
|
248
259
|
JOBS,
|
|
249
260
|
LINEAGE_EVENTS,
|
|
250
261
|
LOGIN,
|
|
251
|
-
MY_GRANT_REQUESTS,
|
|
252
262
|
MY_GRANTS,
|
|
263
|
+
MY_GRANT_REQUESTS,
|
|
253
264
|
PASSWORD,
|
|
254
265
|
PENDING_STRUCTURE_NOTES,
|
|
255
266
|
PROFILE_EXECUTION,
|
|
256
267
|
PROFILE_GROUP,
|
|
257
268
|
QUALITY_DASHBOARD,
|
|
258
|
-
REMEDIATION_PLAN,
|
|
259
269
|
REMEDIATION_EDIT,
|
|
260
270
|
REMEDIATION_NEW,
|
|
271
|
+
REMEDIATION_PLAN,
|
|
261
272
|
ROLE,
|
|
262
|
-
ROLES_NEW,
|
|
263
273
|
ROLES,
|
|
274
|
+
ROLES_NEW,
|
|
275
|
+
RULE,
|
|
276
|
+
RULES,
|
|
264
277
|
RULE_EDIT,
|
|
265
278
|
RULE_EVENTS,
|
|
266
|
-
RULE_IMPLEMENTATION_CLONE,
|
|
267
|
-
RULE_IMPLEMENTATION_EDIT,
|
|
268
|
-
RULE_IMPLEMENTATION_EVENTS,
|
|
269
279
|
IMPLEMENTATION_CONCEPT_LINKS,
|
|
270
280
|
IMPLEMENTATION_CONCEPT_LINKS_NEW,
|
|
271
281
|
IMPLEMENTATION_STRUCTURES,
|
|
272
282
|
IMPLEMENTATION_STRUCTURES_NEW,
|
|
273
|
-
RULE_IMPLEMENTATION_MOVE,
|
|
274
283
|
RULE_IMPLEMENTATION_NEW,
|
|
275
|
-
|
|
276
|
-
RULE_IMPLEMENTATION_RESULT_SEGMENTS_RESULTS,
|
|
277
|
-
RULE_IMPLEMENTATION_RESULT_REMEDIATION_PLAN,
|
|
278
|
-
RULE_IMPLEMENTATION_RESULTS_DETAILS,
|
|
279
|
-
RULE_IMPLEMENTATION_RESULTS,
|
|
280
|
-
RULE_IMPLEMENTATION,
|
|
284
|
+
RULE_IMPLEMENTATION_NEW_RAW,
|
|
281
285
|
RULE_IMPLEMENTATIONS,
|
|
282
286
|
RULE_NEW,
|
|
283
|
-
RULE,
|
|
284
|
-
RULES,
|
|
285
287
|
SAMPLE,
|
|
288
|
+
SEARCH,
|
|
286
289
|
SEARCH_CONCEPTS,
|
|
287
290
|
SEARCH_INGESTS,
|
|
288
291
|
SEARCH_RESULTS,
|
|
289
292
|
SEARCH_STRUCTURES,
|
|
290
|
-
|
|
293
|
+
SOURCE,
|
|
294
|
+
SOURCES,
|
|
291
295
|
SOURCES_NEW,
|
|
292
296
|
SOURCE_EDIT,
|
|
293
297
|
SOURCE_JOB,
|
|
294
|
-
SOURCE_JOBS_NEW,
|
|
295
298
|
SOURCE_JOBS,
|
|
296
|
-
|
|
297
|
-
|
|
299
|
+
SOURCE_JOBS_NEW,
|
|
300
|
+
STRUCTURE,
|
|
301
|
+
STRUCTURES,
|
|
302
|
+
STRUCTURES_BULK_UPDATE,
|
|
298
303
|
STRUCTURE_CHILDREN,
|
|
299
304
|
STRUCTURE_EVENTS,
|
|
300
305
|
STRUCTURE_GRANTS,
|
|
301
306
|
STRUCTURE_IMPACT,
|
|
302
307
|
STRUCTURE_LINEAGE,
|
|
303
|
-
STRUCTURE_LINKS_NEW,
|
|
304
308
|
STRUCTURE_LINKS,
|
|
309
|
+
STRUCTURE_LINKS_NEW,
|
|
305
310
|
STRUCTURE_METADATA,
|
|
306
|
-
STRUCTURE_NOTES_EDIT,
|
|
307
311
|
STRUCTURE_NOTES,
|
|
312
|
+
STRUCTURE_NOTES_EDIT,
|
|
308
313
|
STRUCTURE_PARENTS,
|
|
309
314
|
STRUCTURE_PROFILE,
|
|
310
315
|
STRUCTURE_RULES_IMPLEMENTATIONS,
|
|
316
|
+
STRUCTURE_TAGS,
|
|
311
317
|
STRUCTURE_TAGS_EDIT,
|
|
312
318
|
STRUCTURE_TAGS_NEW,
|
|
313
|
-
STRUCTURE_TAGS,
|
|
314
|
-
STRUCTURE_TYPES_EDIT,
|
|
315
319
|
STRUCTURE_TYPES,
|
|
316
|
-
|
|
320
|
+
STRUCTURE_TYPES_EDIT,
|
|
317
321
|
STRUCTURE_VERSION,
|
|
318
322
|
STRUCTURE_VERSIONS,
|
|
323
|
+
STRUCTURE_VERSION_VERSIONS,
|
|
319
324
|
STRUCTURE,
|
|
320
325
|
STRUCTURES_BULK_UPDATE,
|
|
321
326
|
STRUCTURES,
|
|
@@ -324,23 +329,25 @@ const routes = {
|
|
|
324
329
|
SUBSCRIPTION_NEW,
|
|
325
330
|
SUBSCRIPTION,
|
|
326
331
|
SUBSCRIPTIONS,
|
|
332
|
+
SUBSCRIPTION_EDIT,
|
|
333
|
+
SUBSCRIPTION_NEW,
|
|
334
|
+
SYSTEMS,
|
|
327
335
|
SYSTEM_EDIT,
|
|
328
336
|
SYSTEM_NEW,
|
|
329
337
|
SYSTEM_STRUCTURES,
|
|
330
|
-
SYSTEMS,
|
|
331
|
-
TAGS_NEW,
|
|
332
338
|
TAGS,
|
|
333
|
-
|
|
334
|
-
TEMPLATE_SCOPE,
|
|
339
|
+
TAGS_NEW,
|
|
335
340
|
TEMPLATE,
|
|
336
|
-
TEMPLATES_NEW,
|
|
337
341
|
TEMPLATES,
|
|
342
|
+
TEMPLATES_NEW,
|
|
343
|
+
TEMPLATE_EDIT,
|
|
344
|
+
TEMPLATE_SCOPE,
|
|
338
345
|
UNAUTHORIZED,
|
|
339
|
-
USER_EDIT_PASSWORD,
|
|
340
|
-
USER_EDIT,
|
|
341
346
|
USER,
|
|
342
|
-
USERS_NEW,
|
|
343
347
|
USERS,
|
|
348
|
+
USERS_NEW,
|
|
349
|
+
USER_EDIT,
|
|
350
|
+
USER_EDIT_PASSWORD,
|
|
344
351
|
};
|
|
345
352
|
|
|
346
353
|
export const linkTo = _.mapValues(compile)(routes);
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import {
|
|
3
|
+
flatten,
|
|
4
|
+
childIds,
|
|
5
|
+
descendents,
|
|
6
|
+
recursiveMatch,
|
|
7
|
+
stratify,
|
|
8
|
+
} from "../tree";
|
|
9
|
+
|
|
10
|
+
const baz = { id: "3", name: "baz", children: [] };
|
|
11
|
+
const bar = { id: "2", name: "bar", children: [baz] };
|
|
12
|
+
const foo = { id: "1", name: "foo", children: [bar] };
|
|
13
|
+
const options = [foo];
|
|
14
|
+
|
|
15
|
+
describe("stratify", () => {
|
|
16
|
+
it("stratifies options", () => {
|
|
17
|
+
const foo = { id: 1, name: "foo" };
|
|
18
|
+
const bar = { id: 2, name: "bar", parentId: 1 };
|
|
19
|
+
const baz = { id: 3, name: "baz", parentId: 2 };
|
|
20
|
+
const xyzzy = { id: 4, name: "xyzzy", parentId: 99 };
|
|
21
|
+
const options = [foo, bar, baz, xyzzy];
|
|
22
|
+
const res = stratify({})(options);
|
|
23
|
+
expect(res).toEqual([
|
|
24
|
+
{
|
|
25
|
+
...foo,
|
|
26
|
+
level: 0,
|
|
27
|
+
children: [{ ...bar, children: [{ ...baz, children: [] }] }],
|
|
28
|
+
},
|
|
29
|
+
{ ...xyzzy, level: 0, children: [] },
|
|
30
|
+
]);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe("flatten", () => {
|
|
35
|
+
it("flattens stratified options and assigns level", () => {
|
|
36
|
+
const res = flatten(options);
|
|
37
|
+
expect(res).toEqual([
|
|
38
|
+
{ ...foo, level: 0 },
|
|
39
|
+
{ ...bar, level: 1 },
|
|
40
|
+
{ ...baz, level: 2 },
|
|
41
|
+
]);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
describe("childIds", () => {
|
|
46
|
+
it("returns ids of children", () => {
|
|
47
|
+
const res = childIds("1")(options);
|
|
48
|
+
expect(res).toEqual(["2"]);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
describe("descendents", () => {
|
|
53
|
+
it("returns descendent ids", () => {
|
|
54
|
+
const res = _.flatMap(descendents)(options);
|
|
55
|
+
expect(res).toEqual(["1", "2", "3"]);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
describe("recursiveMatch", () => {
|
|
60
|
+
it("matches recursively", () => {
|
|
61
|
+
const match =
|
|
62
|
+
(query) =>
|
|
63
|
+
({ name }) =>
|
|
64
|
+
_.contains(query)(name);
|
|
65
|
+
const res = _.filter(recursiveMatch(match)("baz"))(options);
|
|
66
|
+
expect(res).toEqual([foo]);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
|
|
3
|
+
const idFn = (d) => d.id;
|
|
4
|
+
const parentFn = (d) => d.parentId;
|
|
5
|
+
const nodeFn = ({ id, name, ...props }) => ({
|
|
6
|
+
id,
|
|
7
|
+
name,
|
|
8
|
+
children: [],
|
|
9
|
+
...props,
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export const stratify = (options) => (data) => {
|
|
13
|
+
const { node = nodeFn, id = idFn, parent = parentFn } = options || {};
|
|
14
|
+
const root = { children: [] };
|
|
15
|
+
const nodes = data.reduce((acc, d) => ({ ...acc, [id(d)]: node(d) }), {
|
|
16
|
+
root,
|
|
17
|
+
});
|
|
18
|
+
for (const d of data) {
|
|
19
|
+
const n = nodes[id(d)];
|
|
20
|
+
const p = nodes[parent(d)] || root;
|
|
21
|
+
p.children.push(n);
|
|
22
|
+
}
|
|
23
|
+
return root.children.map((c) => ({ ...c, level: 0 }));
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const flatten = (data, level = 0) =>
|
|
27
|
+
data.flatMap((d) =>
|
|
28
|
+
d.children?.length
|
|
29
|
+
? [{ ...d, level }, ...flatten(d.children, level + 1)]
|
|
30
|
+
: [{ ...d, level }]
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
export const recursiveMatch = (match) => (query) => (d) =>
|
|
34
|
+
match(query)(d) || _.some(recursiveMatch(match)(query))(d?.children);
|
|
35
|
+
|
|
36
|
+
export const descendents = ({ id, children }) =>
|
|
37
|
+
_.isArray(children) ? [id, ...children.flatMap(descendents)] : [id];
|
|
38
|
+
|
|
39
|
+
export const childIds = (ids) =>
|
|
40
|
+
_.flow(
|
|
41
|
+
_.filter(({ id }) => _.contains(id)(ids)),
|
|
42
|
+
_.flatMap("children"),
|
|
43
|
+
_.map("id")
|
|
44
|
+
);
|