@truedat/lm 4.40.0 → 4.40.3
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 +6 -0
- package/package.json +4 -4
- package/src/components/ConceptImplementationLink.js +25 -0
- package/src/components/ConfirmDeleteRelation.js +13 -5
- package/src/components/ImplementationLinkRow.js +24 -0
- package/src/components/ImplementationLinks.js +114 -0
- package/src/components/ImplementationRelationForm.js +147 -0
- package/src/components/LinksPane.js +13 -0
- package/src/components/RelationTagForm.js +17 -13
- package/src/components/__tests__/ConceptImplementationLink.spec.js +23 -0
- package/src/components/__tests__/ConfirmDeleteRelation.spec.js +27 -0
- package/src/components/__tests__/ImplementationLinkRow.spec.js +25 -0
- package/src/components/__tests__/ImplementationLinks.spec.js +31 -0
- package/src/components/__tests__/ImplementationRelationForm.spec.js +33 -0
- package/src/components/__tests__/LinksPane.spec.js +35 -0
- package/src/components/__tests__/RelationTagForm.spec.js +6 -5
- package/src/components/__tests__/__snapshots__/ConceptImplementationLink.spec.js.snap +11 -0
- package/src/components/__tests__/__snapshots__/ConfirmDeleteRelation.spec.js.snap +10 -0
- package/src/components/__tests__/__snapshots__/ImplementationLinkRow.spec.js.snap +21 -0
- package/src/components/__tests__/__snapshots__/ImplementationLinks.spec.js.snap +96 -0
- package/src/components/__tests__/__snapshots__/ImplementationRelationForm.spec.js.snap +70 -0
- package/src/components/__tests__/__snapshots__/LinksPane.spec.js.snap +52 -0
- package/src/components/__tests__/__snapshots__/RelationTagForm.spec.js.snap +13 -0
- package/src/components/index.js +3 -1
- package/src/messages/en.js +3 -2
- package/src/messages/es.js +4 -1
- package/src/sagas/__tests__/deleteRelation.spec.js +2 -2
- package/src/sagas/deleteRelation.js +2 -2
- package/src/selectors/__tests__/getImplementationToConceptLinks.js +11 -0
- package/src/selectors/getImplementationToConceptLinks.js +9 -0
- package/src/selectors/index.js +1 -0
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truedat/lm",
|
|
3
|
-
"version": "4.40.
|
|
3
|
+
"version": "4.40.3",
|
|
4
4
|
"description": "Truedat Link Manager",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"jsnext:main": "src/index.js",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"@testing-library/jest-dom": "^5.14.1",
|
|
34
34
|
"@testing-library/react": "^12.0.0",
|
|
35
35
|
"@testing-library/user-event": "^13.2.1",
|
|
36
|
-
"@truedat/test": "4.
|
|
36
|
+
"@truedat/test": "4.40.3",
|
|
37
37
|
"babel-jest": "^27.0.6",
|
|
38
38
|
"babel-plugin-dynamic-import-node": "^2.3.3",
|
|
39
39
|
"babel-plugin-lodash": "^3.3.4",
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
]
|
|
84
84
|
},
|
|
85
85
|
"dependencies": {
|
|
86
|
-
"@truedat/core": "4.40.
|
|
86
|
+
"@truedat/core": "4.40.3",
|
|
87
87
|
"path-to-regexp": "^1.7.0",
|
|
88
88
|
"prop-types": "^15.7.2",
|
|
89
89
|
"react-graph-vis": "1.0.5",
|
|
@@ -100,5 +100,5 @@
|
|
|
100
100
|
"react-dom": ">= 16.8.6 < 17",
|
|
101
101
|
"semantic-ui-react": ">= 0.88.2 < 2.1"
|
|
102
102
|
},
|
|
103
|
-
"gitHead": "
|
|
103
|
+
"gitHead": "03104a28941b568007ad53b85874ff58225eaa6a"
|
|
104
104
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Link } from "react-router-dom";
|
|
3
|
+
import PropTypes from "prop-types";
|
|
4
|
+
import { linkTo } from "@truedat/core/routes";
|
|
5
|
+
|
|
6
|
+
export const ConceptImplementationLink = ({
|
|
7
|
+
resource_id: business_concept_id,
|
|
8
|
+
name,
|
|
9
|
+
}) => (
|
|
10
|
+
<Link
|
|
11
|
+
to={linkTo.CONCEPT_LINKS_IMPLEMENTATIONS({
|
|
12
|
+
business_concept_id,
|
|
13
|
+
id: "current",
|
|
14
|
+
})}
|
|
15
|
+
>
|
|
16
|
+
{name}
|
|
17
|
+
</Link>
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
ConceptImplementationLink.propTypes = {
|
|
21
|
+
resource_id: PropTypes.number,
|
|
22
|
+
name: PropTypes.string,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export default ConceptImplementationLink;
|
|
@@ -6,15 +6,19 @@ import { FormattedMessage } from "react-intl";
|
|
|
6
6
|
import { ConfirmModal } from "@truedat/core/components";
|
|
7
7
|
import { deleteRelation } from "../routines";
|
|
8
8
|
|
|
9
|
-
export const ConfirmDeleteRelation = ({ id, deleteRelation }) => (
|
|
9
|
+
export const ConfirmDeleteRelation = ({ id, deleteRelation, resourceType }) => (
|
|
10
10
|
<ConfirmModal
|
|
11
11
|
icon="trash"
|
|
12
|
-
trigger={<Icon name="trash alternate outline" />}
|
|
12
|
+
trigger={<Icon name="trash alternate outline" color="red" />}
|
|
13
13
|
header={
|
|
14
|
-
<FormattedMessage
|
|
14
|
+
<FormattedMessage
|
|
15
|
+
id={`relations.actions.${resourceType}.delete.confirmation.header`}
|
|
16
|
+
/>
|
|
15
17
|
}
|
|
16
18
|
content={
|
|
17
|
-
<FormattedMessage
|
|
19
|
+
<FormattedMessage
|
|
20
|
+
id={`relations.actions.${resourceType}.delete.confirmation.content`}
|
|
21
|
+
/>
|
|
18
22
|
}
|
|
19
23
|
onConfirm={() => deleteRelation({ id })}
|
|
20
24
|
onOpen={(e) => e.stopPropagation()}
|
|
@@ -22,6 +26,10 @@ export const ConfirmDeleteRelation = ({ id, deleteRelation }) => (
|
|
|
22
26
|
/>
|
|
23
27
|
);
|
|
24
28
|
|
|
25
|
-
ConfirmDeleteRelation.propTypes = {
|
|
29
|
+
ConfirmDeleteRelation.propTypes = {
|
|
30
|
+
id: PropTypes.number,
|
|
31
|
+
deleteRelation: PropTypes.func,
|
|
32
|
+
resourceType: PropTypes.string,
|
|
33
|
+
};
|
|
26
34
|
|
|
27
35
|
export default connect(null, { deleteRelation })(ConfirmDeleteRelation);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import PropTypes from "prop-types";
|
|
4
|
+
import { Table } from "semantic-ui-react";
|
|
5
|
+
import { columnDecorator } from "@truedat/core/services";
|
|
6
|
+
|
|
7
|
+
export const ImplementationLinkRow = ({ link, columns }) => (
|
|
8
|
+
<Table.Row>
|
|
9
|
+
{columns.map((column, i) => (
|
|
10
|
+
<Table.Cell
|
|
11
|
+
key={i}
|
|
12
|
+
textAlign={_.prop("textAlign")(column)}
|
|
13
|
+
content={columnDecorator(column)(link)}
|
|
14
|
+
/>
|
|
15
|
+
))}
|
|
16
|
+
</Table.Row>
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
ImplementationLinkRow.propTypes = {
|
|
20
|
+
link: PropTypes.object,
|
|
21
|
+
columns: PropTypes.array,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export default ImplementationLinkRow;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import PropTypes from "prop-types";
|
|
4
|
+
import { connect } from "react-redux";
|
|
5
|
+
import { Table, Button, Grid, Segment } from "semantic-ui-react";
|
|
6
|
+
import { FormattedMessage } from "react-intl";
|
|
7
|
+
import { Link } from "react-router-dom";
|
|
8
|
+
import { linkTo } from "@truedat/core/routes";
|
|
9
|
+
import { accentInsensitivePathOrder } from "@truedat/core/services/sort";
|
|
10
|
+
import { getImplementationToConceptLinks } from "../selectors/getImplementationToConceptLinks";
|
|
11
|
+
import ConceptImplementationLink from "./ConceptImplementationLink";
|
|
12
|
+
import ConceptLinkTags from "./ConceptLinkTags";
|
|
13
|
+
import ImplementationLinkRow from "./ImplementationLinkRow";
|
|
14
|
+
import ConfirmDeleteRelation from "./ConfirmDeleteRelation";
|
|
15
|
+
|
|
16
|
+
const ConfirmDeleteImplementationRelation = ({ id }) => (
|
|
17
|
+
<ConfirmDeleteRelation id={id} resourceType="implementation" />
|
|
18
|
+
);
|
|
19
|
+
ConfirmDeleteImplementationRelation.propTypes = {
|
|
20
|
+
id: PropTypes.number,
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const ImplementationLinks = ({
|
|
24
|
+
implementation,
|
|
25
|
+
implementationLinks,
|
|
26
|
+
canCreateLink,
|
|
27
|
+
}) => {
|
|
28
|
+
const deleteColumn = canCreateLink
|
|
29
|
+
? [
|
|
30
|
+
{
|
|
31
|
+
fieldSelector: _.identity,
|
|
32
|
+
fieldDecorator: ConfirmDeleteImplementationRelation,
|
|
33
|
+
},
|
|
34
|
+
]
|
|
35
|
+
: [];
|
|
36
|
+
|
|
37
|
+
const columns = [
|
|
38
|
+
{
|
|
39
|
+
header: "concepts.props.name",
|
|
40
|
+
fieldSelector: _.identity,
|
|
41
|
+
fieldDecorator: ConceptImplementationLink,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
header: "concepts.props.tags",
|
|
45
|
+
fieldSelector: _.identity,
|
|
46
|
+
fieldDecorator: ConceptLinkTags,
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
header: "concepts.props.domain",
|
|
50
|
+
fieldSelector: _.path("domain.name"),
|
|
51
|
+
},
|
|
52
|
+
...deleteColumn,
|
|
53
|
+
];
|
|
54
|
+
|
|
55
|
+
const headerRow = columns.map(({ header }, key) => (
|
|
56
|
+
<Table.HeaderCell
|
|
57
|
+
key={key}
|
|
58
|
+
content={header ? <FormattedMessage id={header} /> : null}
|
|
59
|
+
/>
|
|
60
|
+
));
|
|
61
|
+
|
|
62
|
+
const id = _.prop("rule_id")(implementation);
|
|
63
|
+
const implementation_id = _.prop("id")(implementation);
|
|
64
|
+
|
|
65
|
+
const renderBodyRow = (link, i) => (
|
|
66
|
+
<ImplementationLinkRow key={i} link={link} columns={columns} />
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<Segment attached="bottom">
|
|
71
|
+
<Grid>
|
|
72
|
+
{id && canCreateLink && (
|
|
73
|
+
<Grid.Column width={16}>
|
|
74
|
+
<Button
|
|
75
|
+
floated="right"
|
|
76
|
+
primary
|
|
77
|
+
as={Link}
|
|
78
|
+
to={linkTo.IMPLEMENTATION_CONCEPT_LINKS_NEW({
|
|
79
|
+
id: id,
|
|
80
|
+
implementation_id: implementation_id,
|
|
81
|
+
})}
|
|
82
|
+
content={<FormattedMessage id="links.actions.create" />}
|
|
83
|
+
/>
|
|
84
|
+
</Grid.Column>
|
|
85
|
+
)}
|
|
86
|
+
{!_.isEmpty(implementationLinks) ? (
|
|
87
|
+
<Grid.Column width={16}>
|
|
88
|
+
<Table
|
|
89
|
+
headerRow={headerRow}
|
|
90
|
+
renderBodyRow={renderBodyRow}
|
|
91
|
+
tableData={implementationLinks}
|
|
92
|
+
/>
|
|
93
|
+
</Grid.Column>
|
|
94
|
+
) : null}
|
|
95
|
+
</Grid>
|
|
96
|
+
</Segment>
|
|
97
|
+
);
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
ImplementationLinks.propTypes = {
|
|
101
|
+
implementation: PropTypes.object,
|
|
102
|
+
canCreateLink: PropTypes.bool,
|
|
103
|
+
implementationLinks: PropTypes.array,
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const mapStateToProps = (state) => ({
|
|
107
|
+
implementation: state.ruleImplementation,
|
|
108
|
+
implementationLinks: _.sortBy(accentInsensitivePathOrder("name"))(
|
|
109
|
+
getImplementationToConceptLinks(state)
|
|
110
|
+
),
|
|
111
|
+
canCreateLink: _.propOr(false, "link_concept")(state.implementationActions),
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
export default connect(mapStateToProps)(ImplementationLinks);
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import React, { useState } from "react";
|
|
3
|
+
import PropTypes from "prop-types";
|
|
4
|
+
import { connect } from "react-redux";
|
|
5
|
+
import { useIntl } from "react-intl";
|
|
6
|
+
import {
|
|
7
|
+
Button,
|
|
8
|
+
Checkbox,
|
|
9
|
+
Form,
|
|
10
|
+
Grid,
|
|
11
|
+
Header,
|
|
12
|
+
Segment,
|
|
13
|
+
} from "semantic-ui-react";
|
|
14
|
+
import { HistoryBackButton } from "@truedat/core/components";
|
|
15
|
+
import { linkTo } from "@truedat/core/routes";
|
|
16
|
+
import { linkConcept } from "../routines";
|
|
17
|
+
import RelationTagsLoader from "./RelationTagsLoader";
|
|
18
|
+
|
|
19
|
+
const ConceptSelector = React.lazy(() =>
|
|
20
|
+
import("@truedat/bg/concepts/relations/components/ConceptSelector")
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
export const ImplementationRelationForm = ({
|
|
24
|
+
conceptLinking,
|
|
25
|
+
implementation,
|
|
26
|
+
tagOptions,
|
|
27
|
+
linkConcept,
|
|
28
|
+
}) => {
|
|
29
|
+
const { formatMessage } = useIntl();
|
|
30
|
+
const [selectedTag, setSelectedTag] = useState([]);
|
|
31
|
+
const [selectedConcept, setSelectedConcept] = useState(null);
|
|
32
|
+
const submitDisabled = conceptLinking || !selectedConcept;
|
|
33
|
+
|
|
34
|
+
const handleTagOnChange = (e, { value }) => {
|
|
35
|
+
const newSelectedTag = _.cond([
|
|
36
|
+
[_.includes(value), _.without([value])],
|
|
37
|
+
[_.stubTrue, _.concat(value)],
|
|
38
|
+
])(selectedTag);
|
|
39
|
+
setSelectedTag(newSelectedTag);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const handleConceptSelected = (selectedConcept) =>
|
|
43
|
+
setSelectedConcept(selectedConcept);
|
|
44
|
+
|
|
45
|
+
const handleSubmit = () => {
|
|
46
|
+
const redirectUrl = linkTo.IMPLEMENTATION_CONCEPT_LINKS({
|
|
47
|
+
id: implementation.rule_id,
|
|
48
|
+
implementation_id: implementation.id,
|
|
49
|
+
});
|
|
50
|
+
const conceptLink = {
|
|
51
|
+
redirectUrl,
|
|
52
|
+
source_id: implementation.id,
|
|
53
|
+
source_type: "implementation",
|
|
54
|
+
target_id: selectedConcept.business_concept_id,
|
|
55
|
+
target_type: "business_concept",
|
|
56
|
+
tag_ids: selectedTag ? selectedTag : [],
|
|
57
|
+
context: {},
|
|
58
|
+
};
|
|
59
|
+
linkConcept(conceptLink);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
<Segment attached="bottom">
|
|
64
|
+
<Grid>
|
|
65
|
+
<Grid.Column with={16}>
|
|
66
|
+
<RelationTagsLoader />
|
|
67
|
+
<Header
|
|
68
|
+
as="h4"
|
|
69
|
+
content={formatMessage({
|
|
70
|
+
id: "implementations.relation.new.header",
|
|
71
|
+
})}
|
|
72
|
+
/>
|
|
73
|
+
|
|
74
|
+
{!_.isEmpty(tagOptions) ? (
|
|
75
|
+
<Form.Field style={{ marginBottom: "10px" }}>
|
|
76
|
+
<label>
|
|
77
|
+
{formatMessage({ id: "conceptRelations.relationType" })}
|
|
78
|
+
</label>
|
|
79
|
+
{tagOptions.map((tagOption, key) => (
|
|
80
|
+
<div key={key} style={{ margin: "6px 0" }}>
|
|
81
|
+
<Checkbox
|
|
82
|
+
toggle
|
|
83
|
+
label={formatMessage({
|
|
84
|
+
id: `conceptRelations.relationType.${tagOption.text}`,
|
|
85
|
+
defaultMessage: tagOption.text,
|
|
86
|
+
})}
|
|
87
|
+
name={tagOption.text}
|
|
88
|
+
value={tagOption.id}
|
|
89
|
+
onChange={handleTagOnChange}
|
|
90
|
+
/>
|
|
91
|
+
</div>
|
|
92
|
+
))}
|
|
93
|
+
</Form.Field>
|
|
94
|
+
) : null}
|
|
95
|
+
<ConceptSelector
|
|
96
|
+
selectedConcept={selectedConcept}
|
|
97
|
+
handleConceptSelected={handleConceptSelected}
|
|
98
|
+
/>
|
|
99
|
+
|
|
100
|
+
<div className="actions">
|
|
101
|
+
<HistoryBackButton
|
|
102
|
+
content={formatMessage({ id: "actions.cancel" })}
|
|
103
|
+
disabled={conceptLinking}
|
|
104
|
+
/>
|
|
105
|
+
|
|
106
|
+
<Button
|
|
107
|
+
primary
|
|
108
|
+
content={formatMessage({ id: "actions.create" })}
|
|
109
|
+
disabled={submitDisabled}
|
|
110
|
+
loading={conceptLinking}
|
|
111
|
+
onClick={handleSubmit}
|
|
112
|
+
/>
|
|
113
|
+
</div>
|
|
114
|
+
</Grid.Column>
|
|
115
|
+
</Grid>
|
|
116
|
+
</Segment>
|
|
117
|
+
);
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
ImplementationRelationForm.propTypes = {
|
|
121
|
+
implementation: PropTypes.object,
|
|
122
|
+
tagOptions: PropTypes.array,
|
|
123
|
+
conceptLinking: PropTypes.bool,
|
|
124
|
+
linkConcept: PropTypes.func,
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const tagsToOptions = _.map(({ id: id, value: { type } }) => ({
|
|
128
|
+
id,
|
|
129
|
+
text: type,
|
|
130
|
+
}));
|
|
131
|
+
|
|
132
|
+
const mapStateToProps = (state) => ({
|
|
133
|
+
conceptLinking: state.conceptLinking,
|
|
134
|
+
implementation: state.ruleImplementation,
|
|
135
|
+
tagOptions: _.flow(
|
|
136
|
+
_.filter(
|
|
137
|
+
(tag) =>
|
|
138
|
+
_.path("value.target_type")(tag) == "rule_implementations" ||
|
|
139
|
+
!_.path("value.target_type")
|
|
140
|
+
),
|
|
141
|
+
tagsToOptions
|
|
142
|
+
)(state.relationTags),
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
export default connect(mapStateToProps, { linkConcept })(
|
|
146
|
+
ImplementationRelationForm
|
|
147
|
+
);
|
|
@@ -18,6 +18,11 @@ const Row = ({ columns, link }) => (
|
|
|
18
18
|
</Table.Row>
|
|
19
19
|
);
|
|
20
20
|
|
|
21
|
+
Row.propTypes = {
|
|
22
|
+
columns: PropTypes.array,
|
|
23
|
+
link: PropTypes.object,
|
|
24
|
+
};
|
|
25
|
+
|
|
21
26
|
export const Links = ({ tag, sourceType, targetType, columns, links }) => {
|
|
22
27
|
const headerRow = columns.map(({ name }, key) => (
|
|
23
28
|
<Table.HeaderCell
|
|
@@ -50,6 +55,14 @@ export const Links = ({ tag, sourceType, targetType, columns, links }) => {
|
|
|
50
55
|
);
|
|
51
56
|
};
|
|
52
57
|
|
|
58
|
+
Links.propTypes = {
|
|
59
|
+
tag: PropTypes.string,
|
|
60
|
+
sourceType: PropTypes.string,
|
|
61
|
+
targetType: PropTypes.string,
|
|
62
|
+
columns: PropTypes.array,
|
|
63
|
+
links: PropTypes.array,
|
|
64
|
+
};
|
|
65
|
+
|
|
53
66
|
const columnPredicate = (column) => {
|
|
54
67
|
const { fieldSelector, name } = column || {};
|
|
55
68
|
return _.isFunction(fieldSelector)
|
|
@@ -13,20 +13,24 @@ export const RelationTagForm = ({ relationTag, isSubmitting, onSubmit }) => {
|
|
|
13
13
|
defaultValues: {
|
|
14
14
|
type: "",
|
|
15
15
|
target_type: "",
|
|
16
|
-
...relationTag
|
|
17
|
-
}
|
|
16
|
+
...relationTag,
|
|
17
|
+
},
|
|
18
18
|
});
|
|
19
19
|
const { isDirty, isValid } = formState;
|
|
20
20
|
const targetTypeOptions = [
|
|
21
21
|
{
|
|
22
22
|
value: "business_concept",
|
|
23
|
-
text: formatMessage({ id: "target_type.business_concept" })
|
|
23
|
+
text: formatMessage({ id: "target_type.business_concept" }),
|
|
24
24
|
},
|
|
25
25
|
{ value: "ingest", text: formatMessage({ id: "target_type.ingest" }) },
|
|
26
|
+
{
|
|
27
|
+
value: "implementations",
|
|
28
|
+
text: formatMessage({ id: "target_type.implementations" }),
|
|
29
|
+
},
|
|
26
30
|
{
|
|
27
31
|
value: "data_field",
|
|
28
|
-
text: formatMessage({ id: "target_type.data_field" })
|
|
29
|
-
}
|
|
32
|
+
text: formatMessage({ id: "target_type.data_field" }),
|
|
33
|
+
},
|
|
30
34
|
];
|
|
31
35
|
return (
|
|
32
36
|
<Form onSubmit={handleSubmit(onSubmit)}>
|
|
@@ -37,7 +41,7 @@ export const RelationTagForm = ({ relationTag, isSubmitting, onSubmit }) => {
|
|
|
37
41
|
required: formatMessage(
|
|
38
42
|
{ id: "form.validation.required" },
|
|
39
43
|
{ prop: formatMessage({ id: "relationTags.props.type" }) }
|
|
40
|
-
)
|
|
44
|
+
),
|
|
41
45
|
}}
|
|
42
46
|
render={({ onBlur, onChange, value }) => (
|
|
43
47
|
<Form.Input
|
|
@@ -46,12 +50,12 @@ export const RelationTagForm = ({ relationTag, isSubmitting, onSubmit }) => {
|
|
|
46
50
|
error={errors.type?.message}
|
|
47
51
|
label={{
|
|
48
52
|
children: formatMessage({ id: "relationTags.props.type" }),
|
|
49
|
-
htmlFor: "type"
|
|
53
|
+
htmlFor: "type",
|
|
50
54
|
}}
|
|
51
55
|
onBlur={onBlur}
|
|
52
56
|
onChange={(_e, { value }) => onChange(value)}
|
|
53
57
|
placeholder={formatMessage({
|
|
54
|
-
id: "relationTags.props.type.placeholder"
|
|
58
|
+
id: "relationTags.props.type.placeholder",
|
|
55
59
|
})}
|
|
56
60
|
value={value || ""}
|
|
57
61
|
required
|
|
@@ -65,7 +69,7 @@ export const RelationTagForm = ({ relationTag, isSubmitting, onSubmit }) => {
|
|
|
65
69
|
required: formatMessage(
|
|
66
70
|
{ id: "form.validation.required" },
|
|
67
71
|
{ prop: formatMessage({ id: "relationTags.props.target_type" }) }
|
|
68
|
-
)
|
|
72
|
+
),
|
|
69
73
|
}}
|
|
70
74
|
render={({ onBlur, onChange, value }) => (
|
|
71
75
|
<Form.Dropdown
|
|
@@ -74,12 +78,12 @@ export const RelationTagForm = ({ relationTag, isSubmitting, onSubmit }) => {
|
|
|
74
78
|
error={errors.target_type?.message}
|
|
75
79
|
label={{
|
|
76
80
|
children: formatMessage({ id: "relationTags.props.target_type" }),
|
|
77
|
-
htmlFor: "target_type"
|
|
81
|
+
htmlFor: "target_type",
|
|
78
82
|
}}
|
|
79
83
|
onBlur={onBlur}
|
|
80
84
|
onChange={(_e, { value }) => onChange(value)}
|
|
81
85
|
placeholder={formatMessage({
|
|
82
|
-
id: "relationTags.props.target_type.placeholder"
|
|
86
|
+
id: "relationTags.props.target_type.placeholder",
|
|
83
87
|
})}
|
|
84
88
|
value={value || ""}
|
|
85
89
|
selection
|
|
@@ -109,11 +113,11 @@ export const RelationTagForm = ({ relationTag, isSubmitting, onSubmit }) => {
|
|
|
109
113
|
RelationTagForm.propTypes = {
|
|
110
114
|
relationTag: PropTypes.object,
|
|
111
115
|
isSubmitting: PropTypes.bool,
|
|
112
|
-
onSubmit: PropTypes.func
|
|
116
|
+
onSubmit: PropTypes.func,
|
|
113
117
|
};
|
|
114
118
|
|
|
115
119
|
const mapStateToProps = ({ relationTagCreating }) => ({
|
|
116
|
-
isSubmitting: relationTagCreating
|
|
120
|
+
isSubmitting: relationTagCreating,
|
|
117
121
|
});
|
|
118
122
|
|
|
119
123
|
export default connect(mapStateToProps)(RelationTagForm);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "@truedat/test/render";
|
|
3
|
+
import { ConceptImplementationLink } from "../ConceptImplementationLink";
|
|
4
|
+
|
|
5
|
+
describe("<ConceptImplementationLink />", () => {
|
|
6
|
+
const renderOpts = {
|
|
7
|
+
messages: {
|
|
8
|
+
en: {},
|
|
9
|
+
},
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const props = {
|
|
13
|
+
resource_id: 8,
|
|
14
|
+
name: "ConceptImplementationLink",
|
|
15
|
+
};
|
|
16
|
+
it("matches the latest snapshot", () => {
|
|
17
|
+
const { container } = render(
|
|
18
|
+
<ConceptImplementationLink {...props} />,
|
|
19
|
+
renderOpts
|
|
20
|
+
);
|
|
21
|
+
expect(container).toMatchSnapshot();
|
|
22
|
+
});
|
|
23
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "@truedat/test/render";
|
|
3
|
+
import { ConfirmDeleteRelation } from "../ConfirmDeleteRelation";
|
|
4
|
+
|
|
5
|
+
describe("<ConfirmDeleteRelation />", () => {
|
|
6
|
+
const renderOpts = {
|
|
7
|
+
messages: {
|
|
8
|
+
en: {
|
|
9
|
+
"relations.actions.resourceType.delete.confirmation.header": "header",
|
|
10
|
+
"relations.actions.resourceType.delete.confirmation.content": "content",
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const props = {
|
|
16
|
+
id: 10,
|
|
17
|
+
deleteRelation: () => {},
|
|
18
|
+
resourceType: "resourceType",
|
|
19
|
+
};
|
|
20
|
+
it("matches the latest snapshot", () => {
|
|
21
|
+
const { container } = render(
|
|
22
|
+
<ConfirmDeleteRelation {...props} />,
|
|
23
|
+
renderOpts
|
|
24
|
+
);
|
|
25
|
+
expect(container).toMatchSnapshot();
|
|
26
|
+
});
|
|
27
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "@truedat/test/render";
|
|
3
|
+
import { Table } from "semantic-ui-react";
|
|
4
|
+
import { ImplementationLinkRow } from "../ImplementationLinkRow";
|
|
5
|
+
|
|
6
|
+
describe("<ImplementationLinkRow />", () => {
|
|
7
|
+
const renderOpts = {
|
|
8
|
+
messages: {
|
|
9
|
+
en: { "props.name": "name" },
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
it("matches the latest snapshot", () => {
|
|
14
|
+
const columns = [{ header: "props.name" }];
|
|
15
|
+
const renderBodyRow = (link, i) => (
|
|
16
|
+
<ImplementationLinkRow key={i} link={link} columns={columns} />
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
const { container } = render(
|
|
20
|
+
<Table renderBodyRow={renderBodyRow} tableData={[{ id: 1 }]} />,
|
|
21
|
+
renderOpts
|
|
22
|
+
);
|
|
23
|
+
expect(container).toMatchSnapshot();
|
|
24
|
+
});
|
|
25
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "@truedat/test/render";
|
|
3
|
+
import { ImplementationLinks } from "../ImplementationLinks";
|
|
4
|
+
|
|
5
|
+
describe("<ImplementationLinks />", () => {
|
|
6
|
+
const renderOpts = {
|
|
7
|
+
messages: {
|
|
8
|
+
en: {
|
|
9
|
+
"links.actions.create": "create",
|
|
10
|
+
"concepts.props.name": "name",
|
|
11
|
+
"concepts.props.tags": "tags",
|
|
12
|
+
"concepts.props.domain": "domain",
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const props = {
|
|
18
|
+
implementation: { rule_id: 2, id: 4 },
|
|
19
|
+
canCreateLink: true,
|
|
20
|
+
implementationLinks: [
|
|
21
|
+
{ name: "name", tags: [], domain: { name: "domain" }, resource_id: 2 },
|
|
22
|
+
],
|
|
23
|
+
};
|
|
24
|
+
it("matches the latest snapshot", () => {
|
|
25
|
+
const { container } = render(
|
|
26
|
+
<ImplementationLinks {...props} />,
|
|
27
|
+
renderOpts
|
|
28
|
+
);
|
|
29
|
+
expect(container).toMatchSnapshot();
|
|
30
|
+
});
|
|
31
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React, { Suspense } from "react";
|
|
2
|
+
import { render } from "@truedat/test/render";
|
|
3
|
+
import { ImplementationRelationForm } from "../ImplementationRelationForm";
|
|
4
|
+
|
|
5
|
+
describe("<ImplementationRelationForm />", () => {
|
|
6
|
+
const renderOpts = {
|
|
7
|
+
messages: {
|
|
8
|
+
en: {
|
|
9
|
+
"implementations.relation.new.header": "header",
|
|
10
|
+
"conceptRelations.relationType": "relationType",
|
|
11
|
+
"actions.cancel": "cancel",
|
|
12
|
+
"actions.create": "create",
|
|
13
|
+
"conceptRelations.relationType.text": "text",
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const props = {
|
|
19
|
+
implementation: { rule_id: 2, id: 4 },
|
|
20
|
+
tagOptions: [{ id: 2, text: "text" }],
|
|
21
|
+
conceptLinking: false,
|
|
22
|
+
linkConcept: () => {},
|
|
23
|
+
};
|
|
24
|
+
it("matches the latest snapshot", () => {
|
|
25
|
+
const { container } = render(
|
|
26
|
+
<Suspense fallback={null}>
|
|
27
|
+
<ImplementationRelationForm {...props} />
|
|
28
|
+
</Suspense>,
|
|
29
|
+
renderOpts
|
|
30
|
+
);
|
|
31
|
+
expect(container).toMatchSnapshot();
|
|
32
|
+
});
|
|
33
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "@truedat/test/render";
|
|
3
|
+
import { LinksPane } from "../LinksPane";
|
|
4
|
+
|
|
5
|
+
describe("<LinksPane />", () => {
|
|
6
|
+
const renderOpts = {
|
|
7
|
+
messages: {
|
|
8
|
+
en: {
|
|
9
|
+
"column.header": "header",
|
|
10
|
+
"implementationDeletedRelation.table.title": "Delete title",
|
|
11
|
+
"implementationRelation.table.title": "Relation Title",
|
|
12
|
+
"implementationRelation.master.table.title": "Master title",
|
|
13
|
+
"concept.column": "column",
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const columns = [
|
|
19
|
+
{
|
|
20
|
+
name: "column",
|
|
21
|
+
header: "column.header",
|
|
22
|
+
},
|
|
23
|
+
];
|
|
24
|
+
const links = [{ id: 4 }];
|
|
25
|
+
const props = {
|
|
26
|
+
groups: [[columns, ["tag", links]]],
|
|
27
|
+
sourceType: "implementation",
|
|
28
|
+
targetType: "concept",
|
|
29
|
+
linksActions: <button>action</button>,
|
|
30
|
+
};
|
|
31
|
+
it("matches the latest snapshot", () => {
|
|
32
|
+
const { container } = render(<LinksPane {...props} />, renderOpts);
|
|
33
|
+
expect(container).toMatchSnapshot();
|
|
34
|
+
});
|
|
35
|
+
});
|
|
@@ -16,9 +16,10 @@ const renderOpts = {
|
|
|
16
16
|
"relationTags.props.type.placeholder": "...",
|
|
17
17
|
"target_type.business_concept": "concept",
|
|
18
18
|
"target_type.data_field": "structure",
|
|
19
|
-
"target_type.ingest": "ingest"
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
"target_type.ingest": "ingest",
|
|
20
|
+
"target_type.implementations": "implementations",
|
|
21
|
+
},
|
|
22
|
+
},
|
|
22
23
|
};
|
|
23
24
|
|
|
24
25
|
describe("<RelationTagForm />", () => {
|
|
@@ -32,7 +33,7 @@ describe("<RelationTagForm />", () => {
|
|
|
32
33
|
const onSubmit = jest.fn();
|
|
33
34
|
|
|
34
35
|
const { findByRole, getByRole, findByText } = render(
|
|
35
|
-
<RelationTagForm onSubmit={props => onSubmit(props)} />,
|
|
36
|
+
<RelationTagForm onSubmit={(props) => onSubmit(props)} />,
|
|
36
37
|
renderOpts
|
|
37
38
|
);
|
|
38
39
|
|
|
@@ -59,7 +60,7 @@ describe("<RelationTagForm />", () => {
|
|
|
59
60
|
await waitFor(() =>
|
|
60
61
|
expect(onSubmit).toHaveBeenCalledWith({
|
|
61
62
|
type: "foo",
|
|
62
|
-
target_type: "business_concept"
|
|
63
|
+
target_type: "business_concept",
|
|
63
64
|
})
|
|
64
65
|
);
|
|
65
66
|
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`<ImplementationLinkRow /> matches the latest snapshot 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<table
|
|
6
|
+
class="ui table"
|
|
7
|
+
>
|
|
8
|
+
<tbody
|
|
9
|
+
class=""
|
|
10
|
+
>
|
|
11
|
+
<tr
|
|
12
|
+
class=""
|
|
13
|
+
>
|
|
14
|
+
<td
|
|
15
|
+
class=""
|
|
16
|
+
/>
|
|
17
|
+
</tr>
|
|
18
|
+
</tbody>
|
|
19
|
+
</table>
|
|
20
|
+
</div>
|
|
21
|
+
`;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`<ImplementationLinks /> matches the latest snapshot 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
class="ui bottom attached segment"
|
|
7
|
+
>
|
|
8
|
+
<div
|
|
9
|
+
class="ui grid"
|
|
10
|
+
>
|
|
11
|
+
<div
|
|
12
|
+
class="sixteen wide column"
|
|
13
|
+
>
|
|
14
|
+
<a
|
|
15
|
+
class="ui primary right floated button"
|
|
16
|
+
href="/rules/2/implementations/4/links/new"
|
|
17
|
+
role="button"
|
|
18
|
+
>
|
|
19
|
+
create
|
|
20
|
+
</a>
|
|
21
|
+
</div>
|
|
22
|
+
<div
|
|
23
|
+
class="sixteen wide column"
|
|
24
|
+
>
|
|
25
|
+
<table
|
|
26
|
+
class="ui table"
|
|
27
|
+
>
|
|
28
|
+
<thead
|
|
29
|
+
class=""
|
|
30
|
+
>
|
|
31
|
+
<tr
|
|
32
|
+
class=""
|
|
33
|
+
>
|
|
34
|
+
<th
|
|
35
|
+
class=""
|
|
36
|
+
>
|
|
37
|
+
name
|
|
38
|
+
</th>
|
|
39
|
+
<th
|
|
40
|
+
class=""
|
|
41
|
+
>
|
|
42
|
+
tags
|
|
43
|
+
</th>
|
|
44
|
+
<th
|
|
45
|
+
class=""
|
|
46
|
+
>
|
|
47
|
+
domain
|
|
48
|
+
</th>
|
|
49
|
+
<th
|
|
50
|
+
class=""
|
|
51
|
+
/>
|
|
52
|
+
</tr>
|
|
53
|
+
</thead>
|
|
54
|
+
<tbody
|
|
55
|
+
class=""
|
|
56
|
+
>
|
|
57
|
+
<tr
|
|
58
|
+
class=""
|
|
59
|
+
>
|
|
60
|
+
<td
|
|
61
|
+
class=""
|
|
62
|
+
>
|
|
63
|
+
<a
|
|
64
|
+
href="/concepts/2/versions/current/links/implementations"
|
|
65
|
+
>
|
|
66
|
+
name
|
|
67
|
+
</a>
|
|
68
|
+
</td>
|
|
69
|
+
<td
|
|
70
|
+
class=""
|
|
71
|
+
>
|
|
72
|
+
<ul
|
|
73
|
+
class="concept-link-tags"
|
|
74
|
+
/>
|
|
75
|
+
</td>
|
|
76
|
+
<td
|
|
77
|
+
class=""
|
|
78
|
+
>
|
|
79
|
+
domain
|
|
80
|
+
</td>
|
|
81
|
+
<td
|
|
82
|
+
class=""
|
|
83
|
+
>
|
|
84
|
+
<i
|
|
85
|
+
aria-hidden="true"
|
|
86
|
+
class="red trash alternate outline icon"
|
|
87
|
+
/>
|
|
88
|
+
</td>
|
|
89
|
+
</tr>
|
|
90
|
+
</tbody>
|
|
91
|
+
</table>
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
`;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`<ImplementationRelationForm /> 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 grid"
|
|
11
|
+
>
|
|
12
|
+
<div
|
|
13
|
+
class="column"
|
|
14
|
+
with="16"
|
|
15
|
+
>
|
|
16
|
+
<h4
|
|
17
|
+
class="ui header"
|
|
18
|
+
>
|
|
19
|
+
header
|
|
20
|
+
</h4>
|
|
21
|
+
<div
|
|
22
|
+
class="field"
|
|
23
|
+
style="margin-bottom: 10px;"
|
|
24
|
+
>
|
|
25
|
+
<label>
|
|
26
|
+
relationType
|
|
27
|
+
</label>
|
|
28
|
+
<div
|
|
29
|
+
style="margin: 6px 0px;"
|
|
30
|
+
>
|
|
31
|
+
<div
|
|
32
|
+
class="ui toggle checkbox"
|
|
33
|
+
>
|
|
34
|
+
<input
|
|
35
|
+
class="hidden"
|
|
36
|
+
name="text"
|
|
37
|
+
readonly=""
|
|
38
|
+
tabindex="0"
|
|
39
|
+
type="checkbox"
|
|
40
|
+
value="2"
|
|
41
|
+
/>
|
|
42
|
+
<label>
|
|
43
|
+
text
|
|
44
|
+
</label>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
<div
|
|
49
|
+
class="actions"
|
|
50
|
+
>
|
|
51
|
+
<a
|
|
52
|
+
class="ui secondary button"
|
|
53
|
+
href="/"
|
|
54
|
+
role="button"
|
|
55
|
+
>
|
|
56
|
+
cancel
|
|
57
|
+
</a>
|
|
58
|
+
<button
|
|
59
|
+
class="ui primary disabled button"
|
|
60
|
+
disabled=""
|
|
61
|
+
tabindex="-1"
|
|
62
|
+
>
|
|
63
|
+
create
|
|
64
|
+
</button>
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
`;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`<LinksPane /> matches the latest snapshot 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
class="ui grid"
|
|
7
|
+
>
|
|
8
|
+
<div
|
|
9
|
+
class="row"
|
|
10
|
+
>
|
|
11
|
+
<div
|
|
12
|
+
class="column"
|
|
13
|
+
>
|
|
14
|
+
<button>
|
|
15
|
+
action
|
|
16
|
+
</button>
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
<div
|
|
20
|
+
class="row"
|
|
21
|
+
>
|
|
22
|
+
<div
|
|
23
|
+
class="column"
|
|
24
|
+
>
|
|
25
|
+
<h3
|
|
26
|
+
class="ui header"
|
|
27
|
+
>
|
|
28
|
+
Master title
|
|
29
|
+
</h3>
|
|
30
|
+
<table
|
|
31
|
+
class="ui table"
|
|
32
|
+
>
|
|
33
|
+
<thead
|
|
34
|
+
class=""
|
|
35
|
+
>
|
|
36
|
+
<tr
|
|
37
|
+
class=""
|
|
38
|
+
/>
|
|
39
|
+
</thead>
|
|
40
|
+
<tbody
|
|
41
|
+
class=""
|
|
42
|
+
>
|
|
43
|
+
<tr
|
|
44
|
+
class=""
|
|
45
|
+
/>
|
|
46
|
+
</tbody>
|
|
47
|
+
</table>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
`;
|
|
@@ -84,6 +84,19 @@ exports[`<RelationTagForm /> matches the latest snapshot 1`] = `
|
|
|
84
84
|
ingest
|
|
85
85
|
</span>
|
|
86
86
|
</div>
|
|
87
|
+
<div
|
|
88
|
+
aria-checked="false"
|
|
89
|
+
aria-selected="false"
|
|
90
|
+
class="item"
|
|
91
|
+
role="option"
|
|
92
|
+
style="pointer-events: all;"
|
|
93
|
+
>
|
|
94
|
+
<span
|
|
95
|
+
class="text"
|
|
96
|
+
>
|
|
97
|
+
implementations
|
|
98
|
+
</span>
|
|
99
|
+
</div>
|
|
87
100
|
<div
|
|
88
101
|
aria-checked="false"
|
|
89
102
|
aria-selected="false"
|
package/src/components/index.js
CHANGED
|
@@ -7,6 +7,7 @@ import RelationTagsLoader from "./RelationTagsLoader";
|
|
|
7
7
|
import Relations from "./Relations";
|
|
8
8
|
import RelationsLoader from "./RelationsLoader";
|
|
9
9
|
import RelationsGraphLoader from "./RelationsGraphLoader";
|
|
10
|
+
import ImplementationRelationForm from "./ImplementationRelationForm";
|
|
10
11
|
import StructureLinks from "./StructureLinks";
|
|
11
12
|
import StructureRelationForm from "./StructureRelationForm";
|
|
12
13
|
import TagTypeSelector from "./TagTypeSelector";
|
|
@@ -26,6 +27,7 @@ export {
|
|
|
26
27
|
Relations,
|
|
27
28
|
RelationsLoader,
|
|
28
29
|
RelationsGraphLoader,
|
|
30
|
+
ImplementationRelationForm,
|
|
29
31
|
StructureLinks,
|
|
30
32
|
StructureRelationForm,
|
|
31
33
|
TagTypeSelector,
|
|
@@ -33,5 +35,5 @@ export {
|
|
|
33
35
|
RelationRoutes,
|
|
34
36
|
RelationTags,
|
|
35
37
|
RelationTagCards,
|
|
36
|
-
NewRelationTag
|
|
38
|
+
NewRelationTag,
|
|
37
39
|
};
|
package/src/messages/en.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export default {
|
|
2
|
+
"implementations.relation.new.header": "Link to Concept",
|
|
2
3
|
"links.actions.create": "Add Link",
|
|
3
4
|
"relations.actions.create": "Add relation",
|
|
4
5
|
"relations.empty": "Not found relations",
|
|
5
|
-
|
|
6
6
|
"relations.relationType": "Relation types",
|
|
7
7
|
"relation.actions.delete.confirmation.header": "Delete Relation",
|
|
8
8
|
"relation.actions.delete.confirmation.content":
|
|
@@ -19,6 +19,7 @@ export default {
|
|
|
19
19
|
"relationTags.props.type.placeholder": "Type",
|
|
20
20
|
"relationTags.props.target_type.placeholder": "Target type",
|
|
21
21
|
"target_type.business_concept": "Concept",
|
|
22
|
+
"target_type.implementations": "Implementations",
|
|
22
23
|
"target_type.ingest": "Ingest",
|
|
23
|
-
"target_type.data_field": "Structure"
|
|
24
|
+
"target_type.data_field": "Structure",
|
|
24
25
|
};
|
package/src/messages/es.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export default {
|
|
2
|
+
"implementations.relation.new.header":
|
|
3
|
+
"Vas a vincular esta implementación a un término del glosario",
|
|
2
4
|
"links.actions.create": "Añadir vinculación",
|
|
3
5
|
"relations.actions.create": "Añadir relación",
|
|
4
6
|
"relations.empty": "No se han encontrado relaciones",
|
|
@@ -19,6 +21,7 @@ export default {
|
|
|
19
21
|
"relationTags.props.type.placeholder": "Código",
|
|
20
22
|
"relationTags.props.target_type.placeholder": "Destino",
|
|
21
23
|
"target_type.business_concept": "Concepto",
|
|
24
|
+
"target_type.implementations": "Implementaciones",
|
|
22
25
|
"target_type.ingest": "Ingesta",
|
|
23
|
-
"target_type.data_field": "Estructura"
|
|
26
|
+
"target_type.data_field": "Estructura",
|
|
24
27
|
};
|
|
@@ -3,7 +3,7 @@ import { testSaga } from "redux-saga-test-plan";
|
|
|
3
3
|
import { apiJsonDelete, JSON_OPTS } from "@truedat/core/services/api";
|
|
4
4
|
import {
|
|
5
5
|
deleteRelationSaga,
|
|
6
|
-
deleteRelationRequestSaga
|
|
6
|
+
deleteRelationRequestSaga,
|
|
7
7
|
} from "../deleteRelation";
|
|
8
8
|
import { deleteRelation } from "../../routines";
|
|
9
9
|
import { API_RELATIONS_ID } from "../../api";
|
|
@@ -41,7 +41,7 @@ describe("sagas: deleteRelationSaga", () => {
|
|
|
41
41
|
.put({ meta, ...deleteRelation.request() })
|
|
42
42
|
.next()
|
|
43
43
|
.call(apiJsonDelete, url, JSON_OPTS)
|
|
44
|
-
.next({ data:
|
|
44
|
+
.next({ data: "" })
|
|
45
45
|
.put({ meta, ...deleteRelation.success(payload) })
|
|
46
46
|
.next()
|
|
47
47
|
.put(deleteRelation.fulfill())
|
|
@@ -12,8 +12,8 @@ export function* deleteRelationSaga({ payload }) {
|
|
|
12
12
|
const meta = { id };
|
|
13
13
|
const url = toApiPath(payload);
|
|
14
14
|
yield put({ meta, ...deleteRelation.request() });
|
|
15
|
-
|
|
16
|
-
yield put({ meta, ...deleteRelation.success(
|
|
15
|
+
yield call(apiJsonDelete, url, JSON_OPTS);
|
|
16
|
+
yield put({ meta, ...deleteRelation.success(payload) });
|
|
17
17
|
} catch (error) {
|
|
18
18
|
if (error.response) {
|
|
19
19
|
const { status, data } = error.response;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { getImplementationToConceptLinks } from "..";
|
|
2
|
+
|
|
3
|
+
const conceptLink = { resource_type: "concept" };
|
|
4
|
+
describe("selectors: getGrantAvailableFilters", () => {
|
|
5
|
+
const implementationLinks = [conceptLink, { resource_type: "other" }];
|
|
6
|
+
const state = { implementationLinks };
|
|
7
|
+
|
|
8
|
+
it("should return implementation links with 'concept' resource_type", () => {
|
|
9
|
+
expect(getImplementationToConceptLinks(state)).toEqual([conceptLink]);
|
|
10
|
+
});
|
|
11
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import { createSelector } from "reselect";
|
|
3
|
+
|
|
4
|
+
const getImplementationLinks = (state) => state.implementationLinks;
|
|
5
|
+
|
|
6
|
+
export const getImplementationToConceptLinks = createSelector(
|
|
7
|
+
getImplementationLinks,
|
|
8
|
+
_.filter(_.propEq("resource_type", "concept"))
|
|
9
|
+
);
|
package/src/selectors/index.js
CHANGED