@truedat/bg 4.40.1 → 4.40.4
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 +5 -5
- package/src/concepts/components/ConceptTabPane.js +6 -1
- package/src/concepts/components/ConceptTabs.js +28 -6
- package/src/concepts/components/__tests__/ConceptManageDomain.spec.js +0 -2
- package/src/concepts/components/__tests__/ConceptTabs.spec.js +32 -0
- package/src/concepts/components/__tests__/__snapshots__/ConceptManageDomain.spec.js.snap +1 -0
- package/src/concepts/components/__tests__/__snapshots__/ConceptTabPane.spec.js.snap +4 -0
- package/src/concepts/components/__tests__/__snapshots__/ConceptTabs.spec.js.snap +52 -0
- package/src/concepts/relations/components/ConceptImplementationLinks.js +70 -0
- package/src/concepts/relations/components/ConceptRelationRow.js +6 -2
- package/src/concepts/relations/components/ConceptRelationsRoutes.js +7 -0
- package/src/concepts/relations/components/ImplementationLinksAction.js +35 -0
- package/src/concepts/relations/components/__tests__/ConceptImplementationLinks.spec.js +30 -0
- package/src/concepts/relations/components/__tests__/ImplementationLinksAction.spec.js +31 -0
- package/src/concepts/relations/components/__tests__/__snapshots__/ConceptImplementationLinks.spec.js.snap +20 -0
- package/src/concepts/relations/components/__tests__/__snapshots__/ConceptRelationRow.spec.js.snap +1 -0
- package/src/concepts/relations/components/__tests__/__snapshots__/ConceptRelationsRoutes.spec.js.snap +5 -0
- package/src/concepts/relations/components/__tests__/__snapshots__/ImplementationLinksAction.spec.js.snap +10 -0
- package/src/concepts/relations/selectors/__tests__/getConceptImplementationLinks.spec.js +54 -0
- package/src/concepts/relations/selectors/getConceptImplementationLinks.js +34 -0
- package/src/concepts/relations/selectors/getConceptLinks.js +19 -18
- package/src/concepts/relations/selectors/index.js +2 -1
- package/src/messages/en.js +13 -1
- package/src/messages/es.js +14 -1
- package/src/taxonomy/components/DomainDropdownSelector.js +7 -3
- package/src/taxonomy/components/__tests__/__snapshots__/DomainDropdownSelector.spec.js.snap +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [4.40.3] 2022-03-14
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- [TD-4271] Support for linking implementations with business_concepts
|
|
8
|
+
|
|
9
|
+
## [4.40.2] 2022-03-14
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- [TD-4500] Support for data structures with multiple domain_ids
|
|
14
|
+
|
|
3
15
|
## [4.40.0] 2022-03-07
|
|
4
16
|
|
|
5
17
|
### Changed
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truedat/bg",
|
|
3
|
-
"version": "4.40.
|
|
3
|
+
"version": "4.40.4",
|
|
4
4
|
"description": "Truedat Web Business Glossary",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"jsnext:main": "src/index.js",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"@testing-library/jest-dom": "^5.14.1",
|
|
35
35
|
"@testing-library/react": "^12.0.0",
|
|
36
36
|
"@testing-library/user-event": "^13.2.1",
|
|
37
|
-
"@truedat/test": "4.
|
|
37
|
+
"@truedat/test": "4.40.4",
|
|
38
38
|
"babel-jest": "^27.0.6",
|
|
39
39
|
"babel-plugin-dynamic-import-node": "^2.3.3",
|
|
40
40
|
"babel-plugin-lodash": "^3.3.4",
|
|
@@ -83,8 +83,8 @@
|
|
|
83
83
|
]
|
|
84
84
|
},
|
|
85
85
|
"dependencies": {
|
|
86
|
-
"@truedat/core": "4.40.
|
|
87
|
-
"@truedat/df": "4.40.
|
|
86
|
+
"@truedat/core": "4.40.4",
|
|
87
|
+
"@truedat/df": "4.40.4",
|
|
88
88
|
"file-saver": "^2.0.5",
|
|
89
89
|
"moment": "^2.24.0",
|
|
90
90
|
"path-to-regexp": "^1.7.0",
|
|
@@ -104,5 +104,5 @@
|
|
|
104
104
|
"react-dom": ">= 16.8.6 < 17",
|
|
105
105
|
"semantic-ui-react": ">= 0.88.2 < 2.1"
|
|
106
106
|
},
|
|
107
|
-
"gitHead": "
|
|
107
|
+
"gitHead": "e9f62f91507d810f91963967a5f3afa20100c1b9"
|
|
108
108
|
}
|
|
@@ -6,9 +6,10 @@ import {
|
|
|
6
6
|
CONCEPT_EVENTS,
|
|
7
7
|
CONCEPT_LINKS_CONCEPTS,
|
|
8
8
|
CONCEPT_LINKS_STRUCTURES,
|
|
9
|
+
CONCEPT_LINKS_IMPLEMENTATIONS,
|
|
9
10
|
CONCEPT_RULES,
|
|
10
11
|
CONCEPT_RULES_NEW,
|
|
11
|
-
CONCEPT_VERSION
|
|
12
|
+
CONCEPT_VERSION,
|
|
12
13
|
} from "@truedat/core/routes";
|
|
13
14
|
import ConceptRelationsRoutes from "../relations/components/ConceptRelationsRoutes";
|
|
14
15
|
import ConceptArchive from "./ConceptArchive";
|
|
@@ -39,6 +40,10 @@ export const ConceptTabPane = () => (
|
|
|
39
40
|
path={CONCEPT_LINKS_CONCEPTS}
|
|
40
41
|
render={() => <ConceptRelationsRoutes />}
|
|
41
42
|
/>
|
|
43
|
+
<Route
|
|
44
|
+
path={CONCEPT_LINKS_IMPLEMENTATIONS}
|
|
45
|
+
render={() => <ConceptRelationsRoutes />}
|
|
46
|
+
/>
|
|
42
47
|
<Route
|
|
43
48
|
path={CONCEPT_RULES}
|
|
44
49
|
render={() => (
|
|
@@ -9,22 +9,28 @@ import { useActiveRoute } from "@truedat/core/hooks";
|
|
|
9
9
|
import {
|
|
10
10
|
CONCEPT_ARCHIVE,
|
|
11
11
|
CONCEPT_EVENTS,
|
|
12
|
+
CONCEPT_LINKS_IMPLEMENTATIONS,
|
|
12
13
|
CONCEPT_LINKS_CONCEPTS,
|
|
13
14
|
CONCEPT_LINKS_STRUCTURES,
|
|
14
15
|
CONCEPT_RULES,
|
|
15
16
|
CONCEPT_VERSION,
|
|
16
|
-
linkTo
|
|
17
|
+
linkTo,
|
|
17
18
|
} from "@truedat/core/routes";
|
|
18
19
|
|
|
19
|
-
const ConceptTabs = ({
|
|
20
|
+
export const ConceptTabs = ({
|
|
21
|
+
concept,
|
|
22
|
+
emptyConceptTags,
|
|
23
|
+
emptyImplementationLinks,
|
|
24
|
+
}) => {
|
|
20
25
|
const archiveActive = useActiveRoute(CONCEPT_ARCHIVE);
|
|
21
26
|
const conceptActive = useActiveRoute({
|
|
22
27
|
path: CONCEPT_VERSION,
|
|
23
|
-
exact: true
|
|
28
|
+
exact: true,
|
|
24
29
|
});
|
|
25
30
|
const conceptLinksActive = useActiveRoute(CONCEPT_LINKS_CONCEPTS);
|
|
26
31
|
const eventsActive = useActiveRoute(CONCEPT_EVENTS);
|
|
27
32
|
const rulesActive = useActiveRoute(CONCEPT_RULES);
|
|
33
|
+
const implementationsActive = useActiveRoute(CONCEPT_LINKS_IMPLEMENTATIONS);
|
|
28
34
|
const structureLinksActive = useActiveRoute(CONCEPT_LINKS_STRUCTURES);
|
|
29
35
|
|
|
30
36
|
return _.isEmpty(concept) ? null : (
|
|
@@ -63,6 +69,16 @@ const ConceptTabs = ({ concept, emptyConceptTags }) => {
|
|
|
63
69
|
>
|
|
64
70
|
<FormattedMessage id="tabs.bg.qualityRules" />
|
|
65
71
|
</Menu.Item>
|
|
72
|
+
{!emptyImplementationLinks && (
|
|
73
|
+
<Menu.Item
|
|
74
|
+
active={implementationsActive}
|
|
75
|
+
as={Link}
|
|
76
|
+
to={linkTo.CONCEPT_LINKS_IMPLEMENTATIONS(concept)}
|
|
77
|
+
replace
|
|
78
|
+
>
|
|
79
|
+
<FormattedMessage id="tabs.bg.qualityImplementations" />
|
|
80
|
+
</Menu.Item>
|
|
81
|
+
)}
|
|
66
82
|
<Menu.Item
|
|
67
83
|
active={archiveActive}
|
|
68
84
|
as={Link}
|
|
@@ -71,6 +87,7 @@ const ConceptTabs = ({ concept, emptyConceptTags }) => {
|
|
|
71
87
|
>
|
|
72
88
|
<FormattedMessage id="tabs.bg.history" />
|
|
73
89
|
</Menu.Item>
|
|
90
|
+
|
|
74
91
|
<Menu.Item
|
|
75
92
|
active={eventsActive}
|
|
76
93
|
as={Link}
|
|
@@ -85,15 +102,20 @@ const ConceptTabs = ({ concept, emptyConceptTags }) => {
|
|
|
85
102
|
|
|
86
103
|
ConceptTabs.propTypes = {
|
|
87
104
|
concept: PropTypes.object,
|
|
88
|
-
emptyConceptTags: PropTypes.bool
|
|
105
|
+
emptyConceptTags: PropTypes.bool,
|
|
106
|
+
emptyImplementationLinks: PropTypes.bool,
|
|
89
107
|
};
|
|
90
108
|
|
|
91
|
-
const mapStateToProps = ({ concept, relationTags }) => ({
|
|
109
|
+
const mapStateToProps = ({ concept, relationTags, conceptLinks }) => ({
|
|
92
110
|
emptyConceptTags: _.flow(
|
|
93
111
|
_.filter(_.pathEq("value.target_type", "business_concept")),
|
|
94
112
|
_.isEmpty
|
|
95
113
|
)(relationTags),
|
|
96
|
-
concept
|
|
114
|
+
concept,
|
|
115
|
+
emptyImplementationLinks: _.flow(
|
|
116
|
+
_.filter(_.pathEq("resource_type", "implementation")),
|
|
117
|
+
_.isEmpty
|
|
118
|
+
)(conceptLinks),
|
|
97
119
|
});
|
|
98
120
|
|
|
99
121
|
export default connect(mapStateToProps)(ConceptTabs);
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "@truedat/test/render";
|
|
3
|
+
import { ConceptTabs } from "../ConceptTabs";
|
|
4
|
+
|
|
5
|
+
describe("<ConceptTabs />", () => {
|
|
6
|
+
const renderOpts = {
|
|
7
|
+
messages: {
|
|
8
|
+
en: {
|
|
9
|
+
"tabs.bg.concept": "concept",
|
|
10
|
+
"tabs.bg.relations_data_field": "relations_data_field",
|
|
11
|
+
"tabs.bg.relations_business_concept": "relations_business_concept",
|
|
12
|
+
"tabs.bg.qualityRules": "qualityRules",
|
|
13
|
+
"tabs.bg.qualityImplementations": "qualityImplementations",
|
|
14
|
+
"tabs.bg.history": "history",
|
|
15
|
+
"tabs.bg.audit": "audit",
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const props = {
|
|
21
|
+
concept: {
|
|
22
|
+
id: 1,
|
|
23
|
+
business_concept_id: 8,
|
|
24
|
+
},
|
|
25
|
+
emptyConceptTags: false,
|
|
26
|
+
emptyImplementationLinks: false,
|
|
27
|
+
};
|
|
28
|
+
it("matches the latest snapshot", () => {
|
|
29
|
+
const { container } = render(<ConceptTabs {...props} />, renderOpts);
|
|
30
|
+
expect(container).toMatchSnapshot();
|
|
31
|
+
});
|
|
32
|
+
});
|
|
@@ -16,6 +16,10 @@ exports[`<ConceptTabPane /> matches the latest snapshot 1`] = `
|
|
|
16
16
|
path="/concepts/:business_concept_id/versions/:id/links/concepts"
|
|
17
17
|
render={[Function]}
|
|
18
18
|
/>
|
|
19
|
+
<Route
|
|
20
|
+
path="/concepts/:business_concept_id/versions/:id/links/implementations"
|
|
21
|
+
render={[Function]}
|
|
22
|
+
/>
|
|
19
23
|
<Route
|
|
20
24
|
path="/concepts/:business_concept_id/versions/:id/rules"
|
|
21
25
|
render={[Function]}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`<ConceptTabs /> matches the latest snapshot 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
class="ui pointing secondary top attached tabular menu"
|
|
7
|
+
>
|
|
8
|
+
<a
|
|
9
|
+
class="item"
|
|
10
|
+
href="/concepts/8/versions/1"
|
|
11
|
+
>
|
|
12
|
+
concept
|
|
13
|
+
</a>
|
|
14
|
+
<a
|
|
15
|
+
class="item"
|
|
16
|
+
href="/concepts/8/versions/1/links/structures"
|
|
17
|
+
>
|
|
18
|
+
relations_data_field
|
|
19
|
+
</a>
|
|
20
|
+
<a
|
|
21
|
+
class="item"
|
|
22
|
+
href="/concepts/8/versions/1/links/concepts"
|
|
23
|
+
>
|
|
24
|
+
relations_business_concept
|
|
25
|
+
</a>
|
|
26
|
+
<a
|
|
27
|
+
class="item"
|
|
28
|
+
href="/concepts/8/versions/1/rules"
|
|
29
|
+
>
|
|
30
|
+
qualityRules
|
|
31
|
+
</a>
|
|
32
|
+
<a
|
|
33
|
+
class="item"
|
|
34
|
+
href="/concepts/8/versions/1/links/implementations"
|
|
35
|
+
>
|
|
36
|
+
qualityImplementations
|
|
37
|
+
</a>
|
|
38
|
+
<a
|
|
39
|
+
class="item"
|
|
40
|
+
href="/concepts/8/versions/1/archive"
|
|
41
|
+
>
|
|
42
|
+
history
|
|
43
|
+
</a>
|
|
44
|
+
<a
|
|
45
|
+
class="item"
|
|
46
|
+
href="/concepts/8/versions/1/events"
|
|
47
|
+
>
|
|
48
|
+
audit
|
|
49
|
+
</a>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
`;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import PropTypes from "prop-types";
|
|
4
|
+
import { connect } from "react-redux";
|
|
5
|
+
import { Segment, Header, Table } from "semantic-ui-react";
|
|
6
|
+
import { FormattedMessage } from "react-intl";
|
|
7
|
+
import { getConceptImplementationLinks } from "../selectors";
|
|
8
|
+
import { conceptLinkAction } from "../routines";
|
|
9
|
+
import ImplementationLinksAction from "./ImplementationLinksAction";
|
|
10
|
+
const RuleImplementationsTable = React.lazy(() =>
|
|
11
|
+
import("@truedat/dq/components/RuleImplementationsTable")
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
export const ConceptImplementationLinks = ({ groups, conceptLinkAction }) => {
|
|
15
|
+
const doDelete = (action) => {
|
|
16
|
+
conceptLinkAction(action);
|
|
17
|
+
};
|
|
18
|
+
const [additionalColumns, additionalCells] = [
|
|
19
|
+
[<Table.HeaderCell key={"status"} width={1} />],
|
|
20
|
+
[
|
|
21
|
+
{
|
|
22
|
+
style: { textAlign: "center", padding: "1px" },
|
|
23
|
+
className: "pointer",
|
|
24
|
+
props: { doDelete },
|
|
25
|
+
content: ImplementationLinksAction,
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<Segment attached="bottom">
|
|
32
|
+
{groups.map(([tag, implementations], key) =>
|
|
33
|
+
_.isEmpty(implementations) ? null : (
|
|
34
|
+
<Segment vertical key={key}>
|
|
35
|
+
<Header as="h3">
|
|
36
|
+
{tag === "deleted" ? (
|
|
37
|
+
<FormattedMessage
|
|
38
|
+
id={"implementationDeletedRelation.table.title"}
|
|
39
|
+
/>
|
|
40
|
+
) : tag === "\uffee" ? (
|
|
41
|
+
<FormattedMessage id={"implementationRelation.table.title"} />
|
|
42
|
+
) : (
|
|
43
|
+
tag
|
|
44
|
+
)}
|
|
45
|
+
</Header>
|
|
46
|
+
<RuleImplementationsTable
|
|
47
|
+
ruleImplementations={implementations}
|
|
48
|
+
withoutColumns={["business_concept"]}
|
|
49
|
+
additionalColumns={additionalColumns}
|
|
50
|
+
additionalCells={additionalCells}
|
|
51
|
+
/>
|
|
52
|
+
</Segment>
|
|
53
|
+
)
|
|
54
|
+
)}
|
|
55
|
+
</Segment>
|
|
56
|
+
);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
ConceptImplementationLinks.propTypes = {
|
|
60
|
+
groups: PropTypes.array,
|
|
61
|
+
conceptLinkAction: PropTypes.object,
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const mapStateToProps = (state) => ({
|
|
65
|
+
groups: getConceptImplementationLinks(state),
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
export default connect(mapStateToProps, {
|
|
69
|
+
conceptLinkAction,
|
|
70
|
+
})(ConceptImplementationLinks);
|
|
@@ -33,7 +33,9 @@ export const ConceptRelationRow = ({
|
|
|
33
33
|
return (
|
|
34
34
|
<Table.Row>
|
|
35
35
|
<Table.Cell textAlign="center">
|
|
36
|
-
{canDeleteConceptRelation &&
|
|
36
|
+
{canDeleteConceptRelation && (
|
|
37
|
+
<ConfirmDeleteRelation id={id} resourceType="concept" />
|
|
38
|
+
)}
|
|
37
39
|
</Table.Cell>
|
|
38
40
|
</Table.Row>
|
|
39
41
|
);
|
|
@@ -69,7 +71,9 @@ export const ConceptRelationRow = ({
|
|
|
69
71
|
onClick={() => goToConcept({ history, concept })}
|
|
70
72
|
/>
|
|
71
73
|
<Table.Cell textAlign="center">
|
|
72
|
-
{canDeleteConceptRelation &&
|
|
74
|
+
{canDeleteConceptRelation && (
|
|
75
|
+
<ConfirmDeleteRelation id={id} resourceType="concept" />
|
|
76
|
+
)}
|
|
73
77
|
</Table.Cell>
|
|
74
78
|
</Table.Row>
|
|
75
79
|
);
|
|
@@ -8,10 +8,12 @@ import {
|
|
|
8
8
|
CONCEPT_LINKS_CONCEPTS_NEW,
|
|
9
9
|
CONCEPT_LINKS_STRUCTURES,
|
|
10
10
|
CONCEPT_LINKS_STRUCTURES_NEW,
|
|
11
|
+
CONCEPT_LINKS_IMPLEMENTATIONS,
|
|
11
12
|
} from "@truedat/core/routes";
|
|
12
13
|
import ConceptStructureLinks from "./ConceptStructureLinks";
|
|
13
14
|
import ConceptRelations from "./ConceptRelations";
|
|
14
15
|
import ConceptRelationForm from "./ConceptRelationForm";
|
|
16
|
+
import ConceptImplementationLinks from "./ConceptImplementationLinks";
|
|
15
17
|
|
|
16
18
|
const ConceptStructureLinkForm = React.lazy(() =>
|
|
17
19
|
import("@truedat/lm/components/ConceptStructureLinkForm")
|
|
@@ -52,6 +54,11 @@ export const ConceptRelationsRoutes = ({ conceptLoaded, relationsLoading }) => (
|
|
|
52
54
|
render={() => (conceptLoaded ? <ConceptRelations /> : null)}
|
|
53
55
|
/>
|
|
54
56
|
)}
|
|
57
|
+
<Route
|
|
58
|
+
exact
|
|
59
|
+
path={CONCEPT_LINKS_IMPLEMENTATIONS}
|
|
60
|
+
render={() => (conceptLoaded ? <ConceptImplementationLinks /> : null)}
|
|
61
|
+
/>
|
|
55
62
|
</Switch>
|
|
56
63
|
);
|
|
57
64
|
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import PropTypes from "prop-types";
|
|
4
|
+
import { useIntl } from "react-intl";
|
|
5
|
+
import { Icon } from "semantic-ui-react";
|
|
6
|
+
import { ConfirmModal } from "@truedat/core/components";
|
|
7
|
+
|
|
8
|
+
export const ImplementationLinksAction = ({ _actions: actions, doDelete }) => {
|
|
9
|
+
const { formatMessage } = useIntl();
|
|
10
|
+
const deleteAction = _.prop("delete")(actions);
|
|
11
|
+
return deleteAction ? (
|
|
12
|
+
<>
|
|
13
|
+
<ConfirmModal
|
|
14
|
+
icon="trash"
|
|
15
|
+
trigger={<Icon name="trash alternate outline" color="red" />}
|
|
16
|
+
header={formatMessage({
|
|
17
|
+
id: `conceptRelation.implementation.actions.delete.confirmation.header`,
|
|
18
|
+
})}
|
|
19
|
+
content={formatMessage({
|
|
20
|
+
id: `conceptRelation.implementation.actions.delete.confirmation.content`,
|
|
21
|
+
})}
|
|
22
|
+
onConfirm={() => doDelete(deleteAction)}
|
|
23
|
+
onOpen={(e) => e.stopPropagation()}
|
|
24
|
+
onClose={(e) => e.stopPropagation()}
|
|
25
|
+
/>
|
|
26
|
+
</>
|
|
27
|
+
) : null;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
ImplementationLinksAction.propTypes = {
|
|
31
|
+
doDelete: PropTypes.func,
|
|
32
|
+
_actions: PropTypes.object,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export default ImplementationLinksAction;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import React, { Suspense } from "react";
|
|
3
|
+
import { render } from "@truedat/test/render";
|
|
4
|
+
|
|
5
|
+
import { ConceptImplementationLinks } from "../ConceptImplementationLinks";
|
|
6
|
+
|
|
7
|
+
describe("<ConceptImplementationLinks />", () => {
|
|
8
|
+
const renderOpts = {
|
|
9
|
+
messages: {
|
|
10
|
+
en: {
|
|
11
|
+
"implementationDeletedRelation.table.title": "Deleted Implementations",
|
|
12
|
+
"implementationRelation.table.title": "Link to Implementation",
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const props = {
|
|
18
|
+
groups: [["group", [{ implementation_key: "foo" }]]],
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
it("matches the latest snapshot", () => {
|
|
22
|
+
const { container } = render(
|
|
23
|
+
<Suspense fallback={null}>
|
|
24
|
+
<ConceptImplementationLinks {...props} />
|
|
25
|
+
</Suspense>,
|
|
26
|
+
renderOpts
|
|
27
|
+
);
|
|
28
|
+
expect(container).toMatchSnapshot();
|
|
29
|
+
});
|
|
30
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import React, { Suspense } from "react";
|
|
3
|
+
import { render } from "@truedat/test/render";
|
|
4
|
+
import { ImplementationLinksAction } from "../ImplementationLinksAction";
|
|
5
|
+
|
|
6
|
+
describe("<ImplementationLinksAction />", () => {
|
|
7
|
+
const renderOpts = {
|
|
8
|
+
messages: {
|
|
9
|
+
en: {
|
|
10
|
+
"conceptRelation.implementation.actions.delete.confirmation.header":
|
|
11
|
+
"Delete Link Implementation",
|
|
12
|
+
"conceptRelation.implementation.actions.delete.confirmation.content":
|
|
13
|
+
"You are going to delete this link. Are you sure?",
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
const props = {
|
|
18
|
+
id: 1,
|
|
19
|
+
_actions: { delete: { foo: "bar" } },
|
|
20
|
+
doDelete: jest.fn(),
|
|
21
|
+
};
|
|
22
|
+
it("matches the latest snapshot", () => {
|
|
23
|
+
const { container } = render(
|
|
24
|
+
<Suspense fallback={null}>
|
|
25
|
+
<ImplementationLinksAction {...props} />
|
|
26
|
+
</Suspense>,
|
|
27
|
+
renderOpts
|
|
28
|
+
);
|
|
29
|
+
expect(container).toMatchSnapshot();
|
|
30
|
+
});
|
|
31
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`<ConceptImplementationLinks /> matches the latest snapshot 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
class="ui bottom attached segment"
|
|
7
|
+
style="display: none;"
|
|
8
|
+
>
|
|
9
|
+
<div
|
|
10
|
+
class="ui vertical segment"
|
|
11
|
+
>
|
|
12
|
+
<h3
|
|
13
|
+
class="ui header"
|
|
14
|
+
>
|
|
15
|
+
group
|
|
16
|
+
</h3>
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
`;
|
|
@@ -22,5 +22,10 @@ exports[`<ConceptRelationsRoutes /> matches the latest snapshot 1`] = `
|
|
|
22
22
|
path="/concepts/:business_concept_id/versions/:id/links/concepts"
|
|
23
23
|
render={[Function]}
|
|
24
24
|
/>
|
|
25
|
+
<Route
|
|
26
|
+
exact={true}
|
|
27
|
+
path="/concepts/:business_concept_id/versions/:id/links/implementations"
|
|
28
|
+
render={[Function]}
|
|
29
|
+
/>
|
|
25
30
|
</Switch>
|
|
26
31
|
`;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import { getConceptImplementationLinks } from "..";
|
|
3
|
+
|
|
4
|
+
const foo = {
|
|
5
|
+
deleted_at: "2020-05-29 09:22:24Z",
|
|
6
|
+
id: "11",
|
|
7
|
+
name: "FOO",
|
|
8
|
+
resource_id: 5454,
|
|
9
|
+
resource_type: "implementation",
|
|
10
|
+
tags: [],
|
|
11
|
+
updated_at: "2020-05-20 13:24:33Z",
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const bar = {
|
|
15
|
+
deleted_at: "",
|
|
16
|
+
id: "12",
|
|
17
|
+
name: "BAR",
|
|
18
|
+
resource_id: 5427,
|
|
19
|
+
resource_type: "implementation",
|
|
20
|
+
tags: [],
|
|
21
|
+
updated_at: "2020-05-20 13:24:33Z",
|
|
22
|
+
};
|
|
23
|
+
const baz = {
|
|
24
|
+
deleted_at: "",
|
|
25
|
+
id: "14",
|
|
26
|
+
name: "BAZ",
|
|
27
|
+
resource_id: 5430,
|
|
28
|
+
resource_type: "implementation",
|
|
29
|
+
tags: ["tag"],
|
|
30
|
+
updated_at: "2020-05-20 13:24:33Z",
|
|
31
|
+
};
|
|
32
|
+
const other = {
|
|
33
|
+
deleted_at: "",
|
|
34
|
+
id: "15",
|
|
35
|
+
name: "OTHER",
|
|
36
|
+
resource_id: 5450,
|
|
37
|
+
resource_type: "data_structure",
|
|
38
|
+
tags: ["business_concept_to_field_master"],
|
|
39
|
+
updated_at: "2020-05-20 13:24:33Z",
|
|
40
|
+
};
|
|
41
|
+
const conceptLinks = [foo, bar, baz, other];
|
|
42
|
+
|
|
43
|
+
describe("selectors: getConceptImplementationLinks", () => {
|
|
44
|
+
const state = { conceptLinks };
|
|
45
|
+
|
|
46
|
+
it("should return implementation links with resource_id as id", () => {
|
|
47
|
+
const links = _.flow(getConceptImplementationLinks)(state);
|
|
48
|
+
expect(links).toMatchObject([
|
|
49
|
+
["tag", [{ ...baz, id: baz.resource_id }]],
|
|
50
|
+
["\uffee", [{ ...bar, id: bar.resource_id }]],
|
|
51
|
+
["deleted", [{ ...foo, id: foo.resource_id }]],
|
|
52
|
+
]);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
|
|
3
|
+
import { createSelector } from "reselect";
|
|
4
|
+
import { accentInsensitivePathOrder } from "@truedat/core/services/sort";
|
|
5
|
+
|
|
6
|
+
const getLinks = ({ conceptLinks }) => conceptLinks;
|
|
7
|
+
const orderedLinks = (links) =>
|
|
8
|
+
_.flow(
|
|
9
|
+
_.filter(_.propEq("resource_type", "implementation")),
|
|
10
|
+
_.map((impl) => ({ ...impl, id: impl.resource_id })),
|
|
11
|
+
_.sortBy(accentInsensitivePathOrder("implementation_key"))
|
|
12
|
+
)(links);
|
|
13
|
+
|
|
14
|
+
const implementationLinks = _.flow(
|
|
15
|
+
orderedLinks,
|
|
16
|
+
_.filter(({ deleted_at }) => _.isEmpty(deleted_at)),
|
|
17
|
+
_.groupBy(_.pathOr("\uffee")("tags[0]")),
|
|
18
|
+
_.toPairs,
|
|
19
|
+
_.sortBy(([k]) => k)
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
const deletedImplementationLinks = _.flow(
|
|
23
|
+
orderedLinks,
|
|
24
|
+
_.filter(({ deleted_at }) => _.negate(_.isEmpty)(deleted_at))
|
|
25
|
+
);
|
|
26
|
+
export const getConceptImplementationLinks = createSelector(
|
|
27
|
+
[getLinks],
|
|
28
|
+
(links) => {
|
|
29
|
+
return [
|
|
30
|
+
...implementationLinks(links),
|
|
31
|
+
["deleted", deletedImplementationLinks(links)],
|
|
32
|
+
];
|
|
33
|
+
}
|
|
34
|
+
);
|
|
@@ -19,10 +19,10 @@ export const StructureLink = ({ resource_type, resource_id: id, name }) =>
|
|
|
19
19
|
StructureLink.propTypes = {
|
|
20
20
|
resource_type: PropTypes.string,
|
|
21
21
|
resource_id: PropTypes.number,
|
|
22
|
-
name: PropTypes.string
|
|
22
|
+
name: PropTypes.string,
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
-
const dateDecorator = date => (
|
|
25
|
+
const dateDecorator = (date) => (
|
|
26
26
|
<Label className={"alert warning"}>
|
|
27
27
|
<Icon name="warning circle" color="red" />
|
|
28
28
|
<Moment locale="es" date={date} format="YYYY-MM-DD HH:mm" />
|
|
@@ -33,17 +33,17 @@ const getLinks = ({ conceptLinks }) => conceptLinks;
|
|
|
33
33
|
const getColumns = ({ structuresColumns }) => structuresColumns;
|
|
34
34
|
const getStructureTypes = ({ structureTypes }) => structureTypes;
|
|
35
35
|
|
|
36
|
-
const mapColumn = column =>
|
|
36
|
+
const mapColumn = (column) =>
|
|
37
37
|
_.propEq("name", "name")(column)
|
|
38
38
|
? {
|
|
39
39
|
...column,
|
|
40
40
|
fieldSelector: _.pick(["resource_type", "resource_id", "name"]),
|
|
41
|
-
fieldDecorator: StructureLink
|
|
41
|
+
fieldDecorator: StructureLink,
|
|
42
42
|
}
|
|
43
43
|
: column;
|
|
44
44
|
|
|
45
45
|
const withActions = (conceptLinks, columns) =>
|
|
46
|
-
_.all(c => _.isEmpty(_.prop("_actions")(c)))(conceptLinks)
|
|
46
|
+
_.all((c) => _.isEmpty(_.prop("_actions")(c)))(conceptLinks)
|
|
47
47
|
? _.map(mapColumn)(columns)
|
|
48
48
|
: [
|
|
49
49
|
..._.map(mapColumn)(columns),
|
|
@@ -51,20 +51,20 @@ const withActions = (conceptLinks, columns) =>
|
|
|
51
51
|
textAlign: "center",
|
|
52
52
|
name: "_actions",
|
|
53
53
|
fieldSelector: _.prop("_actions"),
|
|
54
|
-
fieldDecorator: ConceptLinkActions
|
|
55
|
-
}
|
|
54
|
+
fieldDecorator: ConceptLinkActions,
|
|
55
|
+
},
|
|
56
56
|
];
|
|
57
57
|
|
|
58
58
|
const withDeletedAttribute = (conceptLinks, columns) =>
|
|
59
|
-
_.all(c => _.negate(_.isEmpty)(_.prop("deleted_at")(c)))(conceptLinks)
|
|
60
|
-
? _.map(c =>
|
|
59
|
+
_.all((c) => _.negate(_.isEmpty)(_.prop("deleted_at")(c)))(conceptLinks)
|
|
60
|
+
? _.map((c) =>
|
|
61
61
|
_.propEq("name", "updated_at")(c)
|
|
62
62
|
? {
|
|
63
63
|
name: "deleted_at",
|
|
64
64
|
sort: { name: "deleted_at" },
|
|
65
65
|
fieldDecorator: dateDecorator,
|
|
66
66
|
textAlign: "center",
|
|
67
|
-
width: 2
|
|
67
|
+
width: 2,
|
|
68
68
|
}
|
|
69
69
|
: c
|
|
70
70
|
)(columns)
|
|
@@ -72,22 +72,22 @@ const withDeletedAttribute = (conceptLinks, columns) =>
|
|
|
72
72
|
|
|
73
73
|
const mapColumns = (conceptLinks, columns) =>
|
|
74
74
|
_.flow(
|
|
75
|
-
cols => withActions(conceptLinks, cols),
|
|
76
|
-
cols => withDeletedAttribute(conceptLinks, cols)
|
|
75
|
+
(cols) => withActions(conceptLinks, cols),
|
|
76
|
+
(cols) => withDeletedAttribute(conceptLinks, cols)
|
|
77
77
|
)(columns);
|
|
78
78
|
|
|
79
79
|
const withHeaders = (pair, columns) => [
|
|
80
80
|
mapColumns(_.last(pair), columns),
|
|
81
|
-
pair
|
|
81
|
+
pair,
|
|
82
82
|
];
|
|
83
83
|
|
|
84
84
|
const add_structure_type = (link, structureTypes) => ({
|
|
85
85
|
...link,
|
|
86
86
|
data_structure_type:
|
|
87
|
-
_.find(_.propEq("structure_type", link.type))(structureTypes) || {}
|
|
87
|
+
_.find(_.propEq("structure_type", link.type))(structureTypes) || {},
|
|
88
88
|
});
|
|
89
89
|
|
|
90
|
-
const orderedLinks = links =>
|
|
90
|
+
const orderedLinks = (links) =>
|
|
91
91
|
_.flow(
|
|
92
92
|
_.filter(_.propEq("resource_type", "data_structure")),
|
|
93
93
|
_.sortBy(accentInsensitivePathOrder("name"))
|
|
@@ -99,7 +99,7 @@ const conceptLinks = (links, columns) =>
|
|
|
99
99
|
_.groupBy(_.pathOr("\uffee")("tags[0]")),
|
|
100
100
|
_.toPairs,
|
|
101
101
|
_.sortBy(([k]) => k),
|
|
102
|
-
_.map(pair => withHeaders(pair, columns))
|
|
102
|
+
_.map((pair) => withHeaders(pair, columns))
|
|
103
103
|
)(links);
|
|
104
104
|
const conceptDeletedLinks = (links, columns) => {
|
|
105
105
|
const deleted = _.flow(
|
|
@@ -111,12 +111,13 @@ const conceptDeletedLinks = (links, columns) => {
|
|
|
111
111
|
export const getConceptLinks = createSelector(
|
|
112
112
|
[getLinks, getColumns, getStructureTypes],
|
|
113
113
|
(links, columns, structureTypes) => {
|
|
114
|
-
const linksWithDataStructureType = _.map(link =>
|
|
114
|
+
const linksWithDataStructureType = _.map((link) =>
|
|
115
115
|
add_structure_type(link, structureTypes)
|
|
116
116
|
)(links);
|
|
117
|
+
|
|
117
118
|
return [
|
|
118
119
|
...conceptLinks(linksWithDataStructureType, columns),
|
|
119
|
-
...conceptDeletedLinks(linksWithDataStructureType, columns)
|
|
120
|
+
...conceptDeletedLinks(linksWithDataStructureType, columns),
|
|
120
121
|
];
|
|
121
122
|
}
|
|
122
123
|
);
|
|
@@ -2,6 +2,7 @@ export {
|
|
|
2
2
|
getConceptSourceRelations,
|
|
3
3
|
getConceptTargetRelations,
|
|
4
4
|
getConceptRelations,
|
|
5
|
-
getConceptToConceptRelations
|
|
5
|
+
getConceptToConceptRelations,
|
|
6
6
|
} from "./getConceptRelations";
|
|
7
7
|
export { getConceptLinks } from "./getConceptLinks";
|
|
8
|
+
export { getConceptImplementationLinks } from "./getConceptImplementationLinks";
|
package/src/messages/en.js
CHANGED
|
@@ -58,6 +58,8 @@ export default {
|
|
|
58
58
|
"concept.sharedTo.header": "Share in",
|
|
59
59
|
"concept.changeDomain.header": "Edit Domain",
|
|
60
60
|
"concept.changeDomain.label": "Domain",
|
|
61
|
+
"implementationDeletedRelation.table.title": "Deleted Implementations",
|
|
62
|
+
"implementationRelation.table.title": "Link to Implementation",
|
|
61
63
|
"conceptRelation.actions.create": "New Link",
|
|
62
64
|
"conceptRelation.actions.delete.confirmation.content":
|
|
63
65
|
"The Concept will be unlinked from the field. Are you sure?",
|
|
@@ -67,6 +69,10 @@ export default {
|
|
|
67
69
|
"conceptRelation.group": "Group",
|
|
68
70
|
"conceptRelation.group": "Group",
|
|
69
71
|
"conceptRelation.group.placeholder": "Select Group",
|
|
72
|
+
"conceptRelation.implementation.actions.delete.confirmation.header":
|
|
73
|
+
"Delete Link Implementation",
|
|
74
|
+
"conceptRelation.implementation.actions.delete.confirmation.content":
|
|
75
|
+
"You are going to delete this link. Are you sure?",
|
|
70
76
|
"conceptRelation.master": "Master relation",
|
|
71
77
|
"conceptRelation.master.table.title": "Master Link to Structure",
|
|
72
78
|
"conceptDeletedRelation.table.title": "Deleted Structures",
|
|
@@ -242,7 +248,6 @@ export default {
|
|
|
242
248
|
"fields.pairlist.url.value.placeholder": "https://example.com",
|
|
243
249
|
"filters._confidential": "Confidential",
|
|
244
250
|
"filters.domain": "Domain",
|
|
245
|
-
"filters.domain_parents": "Domain",
|
|
246
251
|
"filters.filiacion": "Filiacion",
|
|
247
252
|
"filters.link_count": "Data fields",
|
|
248
253
|
"filters.rule_count": "Quality Rules",
|
|
@@ -262,6 +267,12 @@ export default {
|
|
|
262
267
|
"Link will be deleted. Are you sure?",
|
|
263
268
|
"relations.actions.data_field.delete.confirmation.header": "Delete link",
|
|
264
269
|
"saveConceptFilters.error.name.unique": "Duplicated name",
|
|
270
|
+
"relations.actions.concept.delete.confirmation.header": "Delete link",
|
|
271
|
+
"relations.actions.concept.delete.confirmation.content":
|
|
272
|
+
"Link between concepts will be deleted. Are you sure?",
|
|
273
|
+
"relations.actions.implementation.delete.confirmation.content":
|
|
274
|
+
"Link between implementation and concept will be deleted. Are you sure?",
|
|
275
|
+
"relations.actions.implementation.delete.confirmation.header": "Delete link",
|
|
265
276
|
"source.bc_caculo": "Calculated from",
|
|
266
277
|
"source.bc_padre": "Children",
|
|
267
278
|
"source.bc_parent": "Children",
|
|
@@ -272,6 +283,7 @@ export default {
|
|
|
272
283
|
"tabs.bg.concept": "Concept",
|
|
273
284
|
"tabs.bg.history": "History",
|
|
274
285
|
"tabs.bg.qualityRules": "Quality Rules",
|
|
286
|
+
"tabs.bg.qualityImplementations": "Quality Implementations",
|
|
275
287
|
"tabs.bg.relations_business_concept": "Related Concepts",
|
|
276
288
|
"tabs.bg.relations_data_field": "Linkage",
|
|
277
289
|
"tabs.domains": "Domains",
|
package/src/messages/es.js
CHANGED
|
@@ -60,6 +60,8 @@ export default {
|
|
|
60
60
|
"concept.sharedTo.header": "Compartir en",
|
|
61
61
|
"concept.changeDomain.label": "Dominios",
|
|
62
62
|
"concept.changeDomain.header": "Editar Dominio",
|
|
63
|
+
"implementationDeletedRelation.table.title": "Implementaciones Eliminadas",
|
|
64
|
+
"implementationRelation.table.title": "Relaciones a Implementación",
|
|
63
65
|
"conceptRelation.actions.create": "Crear vínculo",
|
|
64
66
|
"conceptRelation.actions.delete.confirmation.content":
|
|
65
67
|
"Se eliminará esta vinculación. ¿Estás seguro?",
|
|
@@ -68,6 +70,10 @@ export default {
|
|
|
68
70
|
"conceptRelation.field.placeholder": "Seleccionar Campo",
|
|
69
71
|
"conceptRelation.group": "Grupo",
|
|
70
72
|
"conceptRelation.group.placeholder": "Seleccionar Grupo",
|
|
73
|
+
"conceptRelation.implementation.actions.delete.confirmation.header":
|
|
74
|
+
"Borrar relación",
|
|
75
|
+
"conceptRelation.implementation.actions.delete.confirmation.content":
|
|
76
|
+
"Se eliminará la relación con la implementacion. ¿Está seguro?",
|
|
71
77
|
"conceptRelation.master": "Relación master",
|
|
72
78
|
"conceptRelation.master.table.title": "Enlace a Estructura Tipo Master",
|
|
73
79
|
"conceptDeletedRelation.table.title": "Estructuras Eliminadas",
|
|
@@ -244,7 +250,6 @@ export default {
|
|
|
244
250
|
"fields.pairlist.url.value.placeholder": "https://ejemplo.es",
|
|
245
251
|
"filters._confidential": "Confidencial",
|
|
246
252
|
"filters.domain": "Dominio",
|
|
247
|
-
"filters.domain_parents": "Dominio",
|
|
248
253
|
"filters.filiacion": "Filiacion",
|
|
249
254
|
"filters.link_count": "Datos",
|
|
250
255
|
"filters.rule_count": "Reglas de calidad",
|
|
@@ -264,6 +269,13 @@ export default {
|
|
|
264
269
|
"Se eliminará la vinculación entre el concepto y la estructura. ¿Estás seguro?",
|
|
265
270
|
"relations.actions.data_field.delete.confirmation.header":
|
|
266
271
|
"Borrar vínculación",
|
|
272
|
+
"relations.actions.concept.delete.confirmation.header": "Borrar vínculación",
|
|
273
|
+
"relations.actions.concept.delete.confirmation.content":
|
|
274
|
+
"Se eliminará la vinculación entre el conceptos. ¿Estás seguro?",
|
|
275
|
+
"relations.actions.implementation.delete.confirmation.content":
|
|
276
|
+
"Se eliminará la vinculación entre la implementación y el concepto. ¿Estás seguro?",
|
|
277
|
+
"relations.actions.implementation.delete.confirmation.header":
|
|
278
|
+
"Borrar vínculación",
|
|
267
279
|
"saveConceptFilters.error.name.unique": "Nombre duplicado",
|
|
268
280
|
"source.bc_caculo": "Cálculado en base a",
|
|
269
281
|
"source.bc_padre": "Hijos",
|
|
@@ -275,6 +287,7 @@ export default {
|
|
|
275
287
|
"tabs.bg.concept": "Concepto",
|
|
276
288
|
"tabs.bg.history": "Historial",
|
|
277
289
|
"tabs.bg.qualityRules": "Reglas de Calidad",
|
|
290
|
+
"tabs.bg.qualityImplementations": "Implementaciones",
|
|
278
291
|
"tabs.bg.relations_business_concept": "Conceptos relacionados",
|
|
279
292
|
"tabs.bg.relations_data_field": "Vinculación",
|
|
280
293
|
"tabs.domains": "Dominios",
|
|
@@ -37,6 +37,7 @@ export const DomainDropdownSelector = ({
|
|
|
37
37
|
domainOptions: options,
|
|
38
38
|
hideLabel,
|
|
39
39
|
invalid,
|
|
40
|
+
multiple = false,
|
|
40
41
|
onChange,
|
|
41
42
|
value: defaultValue,
|
|
42
43
|
}) => {
|
|
@@ -95,8 +96,9 @@ export const DomainDropdownSelector = ({
|
|
|
95
96
|
|
|
96
97
|
const handleBlur = () => {
|
|
97
98
|
setQuery();
|
|
98
|
-
|
|
99
|
-
|
|
99
|
+
const lastesSelection = _.isNumber(value) ? value : _.last(value);
|
|
100
|
+
if (!_.isNil(lastesSelection)) {
|
|
101
|
+
const domain = _.find({ id: lastesSelection })(options);
|
|
100
102
|
const ancestors = _.map("id")(domain.ancestors);
|
|
101
103
|
const ids = [...ancestors, domain.id];
|
|
102
104
|
setOpen(ancestors);
|
|
@@ -169,6 +171,7 @@ export const DomainDropdownSelector = ({
|
|
|
169
171
|
)(filteredOptions)}
|
|
170
172
|
placeholder={formatMessage({ id: "domain.selector.placeholder" })}
|
|
171
173
|
search={_.identity}
|
|
174
|
+
multiple={multiple}
|
|
172
175
|
selection
|
|
173
176
|
value={value}
|
|
174
177
|
/>
|
|
@@ -182,8 +185,9 @@ DomainDropdownSelector.propTypes = {
|
|
|
182
185
|
domainOptions: PropTypes.array,
|
|
183
186
|
hideLabel: PropTypes.bool,
|
|
184
187
|
invalid: PropTypes.bool,
|
|
188
|
+
multiple: PropTypes.bool,
|
|
185
189
|
onChange: PropTypes.func,
|
|
186
|
-
value: PropTypes.number,
|
|
190
|
+
value: PropTypes.oneOfType([PropTypes.number, PropTypes.array]),
|
|
187
191
|
};
|
|
188
192
|
|
|
189
193
|
const mapStateToProps = (state, props) => ({
|