@truedat/bg 5.2.1 → 5.2.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 +5 -5
- package/src/concepts/components/ConceptRoutes.js +28 -4
- package/src/concepts/components/ConceptsLinksManagement.js +326 -0
- package/src/concepts/components/__tests__/ConceptLinksManagement.spec.js +84 -0
- package/src/concepts/components/__tests__/__snapshots__/ConceptLinksManagement.spec.js.snap +225 -0
- package/src/concepts/relations/components/ConceptSelector.js +13 -2
- package/src/concepts/relations/components/__tests__/ConceptSelector.spec.js +60 -25
- package/src/concepts/relations/components/__tests__/__snapshots__/ConceptSelector.spec.js.snap +156 -88
- package/src/messages/en.js +11 -3
- package/src/messages/es.js +12 -3
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truedat/bg",
|
|
3
|
-
"version": "5.2.
|
|
3
|
+
"version": "5.2.3",
|
|
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.16.5",
|
|
35
35
|
"@testing-library/react": "^12.0.0",
|
|
36
36
|
"@testing-library/user-event": "^13.2.1",
|
|
37
|
-
"@truedat/test": "5.2.
|
|
37
|
+
"@truedat/test": "5.2.3",
|
|
38
38
|
"babel-jest": "^28.1.0",
|
|
39
39
|
"babel-plugin-dynamic-import-node": "^2.3.3",
|
|
40
40
|
"babel-plugin-lodash": "^3.3.4",
|
|
@@ -86,8 +86,8 @@
|
|
|
86
86
|
]
|
|
87
87
|
},
|
|
88
88
|
"dependencies": {
|
|
89
|
-
"@truedat/core": "5.2.
|
|
90
|
-
"@truedat/df": "5.2.
|
|
89
|
+
"@truedat/core": "5.2.3",
|
|
90
|
+
"@truedat/df": "5.2.3",
|
|
91
91
|
"decode-uri-component": "^0.2.2",
|
|
92
92
|
"file-saver": "^2.0.5",
|
|
93
93
|
"moment": "^2.29.4",
|
|
@@ -110,5 +110,5 @@
|
|
|
110
110
|
"react-dom": ">= 16.8.6 < 17",
|
|
111
111
|
"semantic-ui-react": ">= 2.0.3 < 2.2"
|
|
112
112
|
},
|
|
113
|
-
"gitHead": "
|
|
113
|
+
"gitHead": "fecedbbb623fc091ced1eebf41bdcea30f2800fa"
|
|
114
114
|
}
|
|
@@ -6,13 +6,14 @@ import { connect } from "react-redux";
|
|
|
6
6
|
import { Unauthorized } from "@truedat/core/components";
|
|
7
7
|
import { useAuthorized } from "@truedat/core/hooks";
|
|
8
8
|
import {
|
|
9
|
-
|
|
9
|
+
CONCEPT_EDIT,
|
|
10
|
+
CONCEPT_LINKS_MANAGEMENT,
|
|
11
|
+
CONCEPT_VERSION,
|
|
10
12
|
CONCEPTS_BULK_UPDATE,
|
|
11
13
|
CONCEPTS_NEW,
|
|
12
14
|
CONCEPTS_PENDING,
|
|
13
15
|
CONCEPTS_SUBSCOPED,
|
|
14
|
-
|
|
15
|
-
CONCEPT_VERSION,
|
|
16
|
+
CONCEPTS,
|
|
16
17
|
} from "@truedat/core/routes";
|
|
17
18
|
import { useIntl } from "react-intl";
|
|
18
19
|
import Concept from "./Concept";
|
|
@@ -21,6 +22,7 @@ import ConceptEdit from "./ConceptEdit";
|
|
|
21
22
|
import ConceptFiltersLoader from "./ConceptFiltersLoader";
|
|
22
23
|
import ConceptUserFiltersLoader from "./ConceptUserFiltersLoader";
|
|
23
24
|
import ConceptForm from "./ConceptForm";
|
|
25
|
+
import ConceptsLinksManagement from "./ConceptsLinksManagement";
|
|
24
26
|
import ConceptLoader from "./ConceptLoader";
|
|
25
27
|
import Concepts from "./Concepts";
|
|
26
28
|
import ConceptsBulkUpdate from "./ConceptsBulkUpdate";
|
|
@@ -50,6 +52,29 @@ export const ConceptRoutes = ({ concept, conceptLoaded, templatesLoaded }) => {
|
|
|
50
52
|
};
|
|
51
53
|
return (
|
|
52
54
|
<>
|
|
55
|
+
<Route
|
|
56
|
+
exact
|
|
57
|
+
path={CONCEPT_LINKS_MANAGEMENT}
|
|
58
|
+
render={() =>
|
|
59
|
+
authorized ? (
|
|
60
|
+
<>
|
|
61
|
+
<RelationTagsLoader />
|
|
62
|
+
<ConceptsLinksManagement
|
|
63
|
+
header={formatMessage({
|
|
64
|
+
id: "concepts.header.linksManager",
|
|
65
|
+
})}
|
|
66
|
+
subheader={formatMessage({
|
|
67
|
+
id: "concepts.subheader.linksManager",
|
|
68
|
+
})}
|
|
69
|
+
icon="linkify"
|
|
70
|
+
/>
|
|
71
|
+
</>
|
|
72
|
+
) : (
|
|
73
|
+
<Unauthorized />
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
/>
|
|
77
|
+
|
|
53
78
|
<Route
|
|
54
79
|
exact
|
|
55
80
|
path={CONCEPTS_PENDING}
|
|
@@ -74,7 +99,6 @@ export const ConceptRoutes = ({ concept, conceptLoaded, templatesLoaded }) => {
|
|
|
74
99
|
)
|
|
75
100
|
}
|
|
76
101
|
/>
|
|
77
|
-
|
|
78
102
|
<Route
|
|
79
103
|
exact
|
|
80
104
|
path={CONCEPTS_SUBSCOPED}
|
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import React, { useState, useEffect } from "react";
|
|
3
|
+
import PropTypes from "prop-types";
|
|
4
|
+
import { useIntl } from "react-intl";
|
|
5
|
+
import { connect } from "react-redux";
|
|
6
|
+
import { Header, Icon, Segment, Grid, Message } from "semantic-ui-react";
|
|
7
|
+
import {
|
|
8
|
+
makeTagOptionsSelector,
|
|
9
|
+
makeSearchQuerySelector,
|
|
10
|
+
} from "@truedat/core/selectors";
|
|
11
|
+
import {
|
|
12
|
+
clearStructures,
|
|
13
|
+
fetchStructures,
|
|
14
|
+
clearStructureFilters,
|
|
15
|
+
fetchStructureFilters,
|
|
16
|
+
resetStructureFilters,
|
|
17
|
+
} from "@truedat/dd/routines";
|
|
18
|
+
import { createRelation, deleteRelation } from "@truedat/core/routines";
|
|
19
|
+
import ConceptSelector from "../relations/components/ConceptSelector";
|
|
20
|
+
import { fetchConcepts } from "../routines";
|
|
21
|
+
|
|
22
|
+
const TagTypeDropdownSelector = React.lazy(() =>
|
|
23
|
+
import("@truedat/lm/components/TagTypeDropdownSelector")
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
const StructureSelector = React.lazy(() =>
|
|
27
|
+
import("@truedat/dd/components/StructureSelector")
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
const linksDefaultFilters = {
|
|
31
|
+
current: [true],
|
|
32
|
+
status: ["pending_approval", "draft", "rejected", "published"],
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const STATUS_PENDING = "pending";
|
|
36
|
+
const STATUS_CREATED = "created";
|
|
37
|
+
const STATUS_DELETED = "deleted";
|
|
38
|
+
|
|
39
|
+
const LinkedMessage = ({
|
|
40
|
+
selectedConcept,
|
|
41
|
+
selectedStructure,
|
|
42
|
+
selectedTag,
|
|
43
|
+
status,
|
|
44
|
+
}) => {
|
|
45
|
+
const { formatMessage } = useIntl();
|
|
46
|
+
|
|
47
|
+
const messagesMap = {
|
|
48
|
+
[STATUS_PENDING]: formatMessage({ id: "concept.events.relation_creating" }),
|
|
49
|
+
[STATUS_DELETED]: formatMessage({ id: "concept.events.relation_deleted" }),
|
|
50
|
+
[STATUS_CREATED]: formatMessage({ id: "concept.events.relation_created" }),
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<Message success={status !== STATUS_PENDING} floating>
|
|
55
|
+
<Message.Header>{messagesMap[status]}</Message.Header>
|
|
56
|
+
<Message.List>
|
|
57
|
+
{selectedConcept ? (
|
|
58
|
+
<Message.Item>
|
|
59
|
+
{formatMessage({ id: "conceptRelations.concept" })}
|
|
60
|
+
{": "} {selectedConcept.name}
|
|
61
|
+
</Message.Item>
|
|
62
|
+
) : null}
|
|
63
|
+
{selectedStructure ? (
|
|
64
|
+
<Message.Item>
|
|
65
|
+
{formatMessage({ id: "conceptRelations.structure" })}
|
|
66
|
+
{": "}
|
|
67
|
+
{selectedStructure.name}
|
|
68
|
+
</Message.Item>
|
|
69
|
+
) : null}
|
|
70
|
+
{selectedTag ? (
|
|
71
|
+
<Message.Item>
|
|
72
|
+
{formatMessage({ id: "conceptRelations.tag" })}
|
|
73
|
+
{": "}
|
|
74
|
+
{formatMessage({
|
|
75
|
+
id: selectedTag.text,
|
|
76
|
+
defaultMessage: selectedTag.text,
|
|
77
|
+
})}
|
|
78
|
+
</Message.Item>
|
|
79
|
+
) : null}
|
|
80
|
+
</Message.List>
|
|
81
|
+
</Message>
|
|
82
|
+
);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
LinkedMessage.propTypes = {
|
|
86
|
+
selectedConcept: PropTypes.object,
|
|
87
|
+
selectedStructure: PropTypes.object,
|
|
88
|
+
selectedTag: PropTypes.object,
|
|
89
|
+
status: PropTypes.string,
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export const ConceptsLinksManagement = ({
|
|
93
|
+
header,
|
|
94
|
+
subheader,
|
|
95
|
+
icon,
|
|
96
|
+
createRelation,
|
|
97
|
+
deleteRelation,
|
|
98
|
+
creatingRelation,
|
|
99
|
+
deletingRelation,
|
|
100
|
+
fetchConcepts,
|
|
101
|
+
conceptPayload,
|
|
102
|
+
tagOptions,
|
|
103
|
+
selectedRelationTags,
|
|
104
|
+
clearStructures,
|
|
105
|
+
clearStructureFilters,
|
|
106
|
+
fetchStructureFilters,
|
|
107
|
+
resetStructureFilters,
|
|
108
|
+
fetchStructures,
|
|
109
|
+
structurePayload,
|
|
110
|
+
}) => {
|
|
111
|
+
const { formatMessage } = useIntl();
|
|
112
|
+
const [selectedConcept, setSelectedConcept] = useState(null);
|
|
113
|
+
const [selectedStructure, setSelectedStructure] = useState(null);
|
|
114
|
+
|
|
115
|
+
const [selectedTag, setselectedTag] = useState(null);
|
|
116
|
+
const [status, setStatus] = useState(STATUS_PENDING);
|
|
117
|
+
const [links, setLinks] = useState([]);
|
|
118
|
+
|
|
119
|
+
const isStructureLinked = (selectedStructure, links) => {
|
|
120
|
+
return _.find(
|
|
121
|
+
(link) =>
|
|
122
|
+
_.propEq("resource_id", selectedStructure.id.toString())(link) &&
|
|
123
|
+
_.propEq("resource_type", "data_structure")(link)
|
|
124
|
+
)(links);
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const handleConceptSelected = (selectedConcept) => {
|
|
128
|
+
setStatus(STATUS_PENDING);
|
|
129
|
+
setLinks(selectedConcept.links);
|
|
130
|
+
setSelectedStructure(null);
|
|
131
|
+
setSelectedConcept(selectedConcept);
|
|
132
|
+
clearStructures();
|
|
133
|
+
clearStructureFilters();
|
|
134
|
+
fetchStructureFilters();
|
|
135
|
+
resetStructureFilters();
|
|
136
|
+
fetchStructures({ ...structurePayload, size: 7, page: 0 });
|
|
137
|
+
fetchConcepts({
|
|
138
|
+
...conceptPayload,
|
|
139
|
+
filters: { ...conceptPayload.filters, ...linksDefaultFilters },
|
|
140
|
+
size: 7,
|
|
141
|
+
});
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
const handleStructureSelected = (structure) => {
|
|
145
|
+
setSelectedStructure(structure);
|
|
146
|
+
if (selectedConcept && structure) {
|
|
147
|
+
const isLinked = isStructureLinked(structure, links);
|
|
148
|
+
if (isLinked) {
|
|
149
|
+
deleteRelation({ id: isLinked.id });
|
|
150
|
+
} else {
|
|
151
|
+
const structureLink = {
|
|
152
|
+
source_id: selectedConcept.business_concept_id,
|
|
153
|
+
source_type: "business_concept",
|
|
154
|
+
target_id: structure.id,
|
|
155
|
+
target_type: "data_structure",
|
|
156
|
+
tag_ids: selectedRelationTags ? selectedRelationTags : [],
|
|
157
|
+
};
|
|
158
|
+
createRelation(structureLink);
|
|
159
|
+
}
|
|
160
|
+
fetchConcepts({
|
|
161
|
+
...conceptPayload,
|
|
162
|
+
filters: { ...conceptPayload.filters, ...linksDefaultFilters },
|
|
163
|
+
size: 7,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
useEffect(() => {
|
|
169
|
+
if (status !== STATUS_PENDING) setSelectedStructure(null);
|
|
170
|
+
|
|
171
|
+
setStatus(STATUS_PENDING);
|
|
172
|
+
if (selectedRelationTags) {
|
|
173
|
+
const [id] = selectedRelationTags;
|
|
174
|
+
const tag = _.find(_.propEq("value", id))(tagOptions);
|
|
175
|
+
setselectedTag(tag);
|
|
176
|
+
}
|
|
177
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
178
|
+
}, [selectedRelationTags]);
|
|
179
|
+
|
|
180
|
+
useEffect(() => {
|
|
181
|
+
if (deletingRelation?.id) {
|
|
182
|
+
setLinks(_.filter(_.negate(_.propEq("id", deletingRelation.id)))(links));
|
|
183
|
+
setStatus(STATUS_DELETED);
|
|
184
|
+
}
|
|
185
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
186
|
+
}, [deletingRelation]);
|
|
187
|
+
|
|
188
|
+
useEffect(() => {
|
|
189
|
+
if (creatingRelation) {
|
|
190
|
+
setLinks([
|
|
191
|
+
...links,
|
|
192
|
+
{
|
|
193
|
+
id: creatingRelation.id.toString(),
|
|
194
|
+
resource_id: creatingRelation.target_id.toString(),
|
|
195
|
+
resource_type: "data_structure",
|
|
196
|
+
},
|
|
197
|
+
]);
|
|
198
|
+
setStatus(STATUS_CREATED);
|
|
199
|
+
}
|
|
200
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
201
|
+
}, [creatingRelation]);
|
|
202
|
+
|
|
203
|
+
return (
|
|
204
|
+
<>
|
|
205
|
+
<Segment>
|
|
206
|
+
<Header as="h2">
|
|
207
|
+
<Icon circular name={icon} />
|
|
208
|
+
<Header.Content>
|
|
209
|
+
{header}
|
|
210
|
+
<Header.Subheader>{subheader}</Header.Subheader>
|
|
211
|
+
</Header.Content>
|
|
212
|
+
</Header>
|
|
213
|
+
<Segment attached="bottom">
|
|
214
|
+
<Grid>
|
|
215
|
+
<Grid.Row>
|
|
216
|
+
<Grid.Column width={8}>
|
|
217
|
+
{!_.isEmpty(tagOptions) && (
|
|
218
|
+
<TagTypeDropdownSelector options={tagOptions} />
|
|
219
|
+
)}
|
|
220
|
+
</Grid.Column>
|
|
221
|
+
<Grid.Column width={8}>
|
|
222
|
+
{selectedConcept || selectedTag ? (
|
|
223
|
+
<LinkedMessage
|
|
224
|
+
selectedStructure={selectedStructure}
|
|
225
|
+
selectedConcept={selectedConcept}
|
|
226
|
+
selectedTag={selectedTag}
|
|
227
|
+
status={status}
|
|
228
|
+
/>
|
|
229
|
+
) : null}
|
|
230
|
+
</Grid.Column>
|
|
231
|
+
</Grid.Row>
|
|
232
|
+
<Grid.Row>
|
|
233
|
+
<Grid.Column width={8}>
|
|
234
|
+
<Segment>
|
|
235
|
+
<Header as="h4">
|
|
236
|
+
<Header.Content>
|
|
237
|
+
{" "}
|
|
238
|
+
{formatMessage({ id: "conceptRelations.concepts" })}
|
|
239
|
+
</Header.Content>
|
|
240
|
+
</Header>
|
|
241
|
+
<ConceptSelector
|
|
242
|
+
showTitle={false}
|
|
243
|
+
selectedConcept={selectedConcept}
|
|
244
|
+
handleConceptSelected={handleConceptSelected}
|
|
245
|
+
tagOptions={tagOptions}
|
|
246
|
+
/>
|
|
247
|
+
</Segment>
|
|
248
|
+
</Grid.Column>
|
|
249
|
+
<Grid.Column width={8}>
|
|
250
|
+
<Segment>
|
|
251
|
+
<Header as="h4">
|
|
252
|
+
<Header.Content>
|
|
253
|
+
{formatMessage({ id: "conceptRelations.structures" })}
|
|
254
|
+
</Header.Content>
|
|
255
|
+
</Header>
|
|
256
|
+
{selectedConcept ? (
|
|
257
|
+
<StructureSelector
|
|
258
|
+
selectedStructure={selectedStructure}
|
|
259
|
+
onSelect={handleStructureSelected}
|
|
260
|
+
links={links}
|
|
261
|
+
placeToTop={false}
|
|
262
|
+
/>
|
|
263
|
+
) : null}
|
|
264
|
+
</Segment>
|
|
265
|
+
</Grid.Column>
|
|
266
|
+
</Grid.Row>
|
|
267
|
+
</Grid>
|
|
268
|
+
</Segment>
|
|
269
|
+
</Segment>
|
|
270
|
+
</>
|
|
271
|
+
);
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
ConceptsLinksManagement.propTypes = {
|
|
275
|
+
header: PropTypes.string,
|
|
276
|
+
icon: PropTypes.string,
|
|
277
|
+
subheader: PropTypes.string,
|
|
278
|
+
fetchConcepts: PropTypes.func,
|
|
279
|
+
conceptPayload: PropTypes.object,
|
|
280
|
+
structurePayload: PropTypes.object,
|
|
281
|
+
fetchStructures: PropTypes.func,
|
|
282
|
+
clearStructures: PropTypes.func,
|
|
283
|
+
clearStructureFilters: PropTypes.func,
|
|
284
|
+
fetchStructureFilters: PropTypes.func,
|
|
285
|
+
resetStructureFilters: PropTypes.func,
|
|
286
|
+
createRelation: PropTypes.func,
|
|
287
|
+
deleteRelation: PropTypes.func,
|
|
288
|
+
selectedRelationTags: PropTypes.array,
|
|
289
|
+
tagOptions: PropTypes.array,
|
|
290
|
+
creatingRelation: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
|
|
291
|
+
deletingRelation: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
const makeMapStateToProps = () => {
|
|
295
|
+
const getTagOptions = makeTagOptionsSelector("data_field");
|
|
296
|
+
const searchQuerySelector = makeSearchQuerySelector(
|
|
297
|
+
"conceptQuery",
|
|
298
|
+
"conceptActiveFilters"
|
|
299
|
+
);
|
|
300
|
+
const structureSearchQuerySelector = makeSearchQuerySelector(
|
|
301
|
+
"structureQuery",
|
|
302
|
+
"structureActiveFilters",
|
|
303
|
+
"structureDateFilter"
|
|
304
|
+
);
|
|
305
|
+
const mapStateToProps = (state, props) => ({
|
|
306
|
+
conceptPayload: searchQuerySelector(state, props),
|
|
307
|
+
selectedRelationTags: state.selectedRelationTags,
|
|
308
|
+
structurePayload: structureSearchQuerySelector(state, props),
|
|
309
|
+
tagOptions: getTagOptions(state),
|
|
310
|
+
creatingRelation: state.creatingRelation,
|
|
311
|
+
deletingRelation: state.relations,
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
return mapStateToProps;
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
export default connect(makeMapStateToProps, {
|
|
318
|
+
fetchConcepts,
|
|
319
|
+
createRelation,
|
|
320
|
+
deleteRelation,
|
|
321
|
+
fetchStructures,
|
|
322
|
+
clearStructures,
|
|
323
|
+
clearStructureFilters,
|
|
324
|
+
fetchStructureFilters,
|
|
325
|
+
resetStructureFilters,
|
|
326
|
+
})(ConceptsLinksManagement);
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import React, { Suspense } from "react";
|
|
2
|
+
import { render } from "@truedat/test/render";
|
|
3
|
+
import { waitFor } from "@testing-library/react";
|
|
4
|
+
import userEvent from "@testing-library/user-event";
|
|
5
|
+
import ConceptsLinksManagement from "../ConceptsLinksManagement";
|
|
6
|
+
import en from "../../../messages/en";
|
|
7
|
+
|
|
8
|
+
const messages = {
|
|
9
|
+
en: {
|
|
10
|
+
...en,
|
|
11
|
+
"concepts.status.undefined": "undefined",
|
|
12
|
+
"search.save_filters": "save filters",
|
|
13
|
+
"search.clear_filters": "clear filters",
|
|
14
|
+
"search.applied_filters": "apply filters",
|
|
15
|
+
"structures.not_found.body": "",
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const link = {
|
|
20
|
+
id: 745,
|
|
21
|
+
resource_id: 4569480,
|
|
22
|
+
resource_type: "data_structure",
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const concept = {
|
|
26
|
+
_actions: { can_create_structure_link: true },
|
|
27
|
+
id: 1,
|
|
28
|
+
business_concept_id: 1111,
|
|
29
|
+
name: "foo",
|
|
30
|
+
domain: { id: 1, name: "bar" },
|
|
31
|
+
status: "draft",
|
|
32
|
+
business_concept_id: 1,
|
|
33
|
+
links: [link],
|
|
34
|
+
};
|
|
35
|
+
const structure = {
|
|
36
|
+
id: 4569480,
|
|
37
|
+
name: "Contrato",
|
|
38
|
+
path: ["Trabajadores"],
|
|
39
|
+
system: {
|
|
40
|
+
external_id: "micro",
|
|
41
|
+
id: 68,
|
|
42
|
+
name: "System",
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const props = {
|
|
47
|
+
header: "header",
|
|
48
|
+
subheader: "subheader",
|
|
49
|
+
icon: "linkify",
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
describe("<ConceptsLinksManagement />", () => {
|
|
53
|
+
const renderOpts = {
|
|
54
|
+
messages,
|
|
55
|
+
state: {
|
|
56
|
+
loading: false,
|
|
57
|
+
links: [link],
|
|
58
|
+
concepts: [concept],
|
|
59
|
+
structures: [structure],
|
|
60
|
+
structuresRows: [structure],
|
|
61
|
+
conceptActiveFilters: { filter: "some" },
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
it("matches the latest snapshot", () => {
|
|
66
|
+
const { container } = render(
|
|
67
|
+
<ConceptsLinksManagement {...props} />,
|
|
68
|
+
renderOpts
|
|
69
|
+
);
|
|
70
|
+
expect(container).toMatchSnapshot();
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it("select a concept and shows LinkedMessage and structure search table", async () => {
|
|
74
|
+
const { queryByText } = render(
|
|
75
|
+
<Suspense fallback={null}>
|
|
76
|
+
<ConceptsLinksManagement {...props} />
|
|
77
|
+
</Suspense>,
|
|
78
|
+
renderOpts
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
userEvent.click(await queryByText(/foo/));
|
|
82
|
+
expect(queryByText("Adding a link to a structure")).toBeInTheDocument();
|
|
83
|
+
});
|
|
84
|
+
});
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`<ConceptsLinksManagement /> matches the latest snapshot 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
class="ui segment"
|
|
7
|
+
>
|
|
8
|
+
<h2
|
|
9
|
+
class="ui header"
|
|
10
|
+
>
|
|
11
|
+
<i
|
|
12
|
+
aria-hidden="true"
|
|
13
|
+
class="linkify circular icon"
|
|
14
|
+
/>
|
|
15
|
+
<div
|
|
16
|
+
class="content"
|
|
17
|
+
>
|
|
18
|
+
header
|
|
19
|
+
<div
|
|
20
|
+
class="sub header"
|
|
21
|
+
>
|
|
22
|
+
subheader
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
</h2>
|
|
26
|
+
<div
|
|
27
|
+
class="ui bottom attached segment"
|
|
28
|
+
>
|
|
29
|
+
<div
|
|
30
|
+
class="ui grid"
|
|
31
|
+
>
|
|
32
|
+
<div
|
|
33
|
+
class="row"
|
|
34
|
+
>
|
|
35
|
+
<div
|
|
36
|
+
class="eight wide column"
|
|
37
|
+
/>
|
|
38
|
+
<div
|
|
39
|
+
class="eight wide column"
|
|
40
|
+
/>
|
|
41
|
+
</div>
|
|
42
|
+
<div
|
|
43
|
+
class="row"
|
|
44
|
+
>
|
|
45
|
+
<div
|
|
46
|
+
class="eight wide column"
|
|
47
|
+
>
|
|
48
|
+
<div
|
|
49
|
+
class="ui segment"
|
|
50
|
+
>
|
|
51
|
+
<h4
|
|
52
|
+
class="ui header"
|
|
53
|
+
>
|
|
54
|
+
<div
|
|
55
|
+
class="content"
|
|
56
|
+
>
|
|
57
|
+
|
|
58
|
+
Concepts
|
|
59
|
+
</div>
|
|
60
|
+
</h4>
|
|
61
|
+
<div
|
|
62
|
+
class="ui segment"
|
|
63
|
+
>
|
|
64
|
+
<div
|
|
65
|
+
class="ui action left icon input"
|
|
66
|
+
>
|
|
67
|
+
<input
|
|
68
|
+
placeholder="Search concepts..."
|
|
69
|
+
type="text"
|
|
70
|
+
value=""
|
|
71
|
+
/>
|
|
72
|
+
<i
|
|
73
|
+
aria-hidden="true"
|
|
74
|
+
class="search link icon"
|
|
75
|
+
/>
|
|
76
|
+
<div
|
|
77
|
+
aria-expanded="false"
|
|
78
|
+
class="ui button floating labeled scrolling dropdown icon"
|
|
79
|
+
role="listbox"
|
|
80
|
+
tabindex="0"
|
|
81
|
+
>
|
|
82
|
+
<div
|
|
83
|
+
aria-atomic="true"
|
|
84
|
+
aria-live="polite"
|
|
85
|
+
class="divider text"
|
|
86
|
+
role="alert"
|
|
87
|
+
>
|
|
88
|
+
Filters
|
|
89
|
+
</div>
|
|
90
|
+
<i
|
|
91
|
+
aria-hidden="true"
|
|
92
|
+
class="filter icon"
|
|
93
|
+
/>
|
|
94
|
+
<div
|
|
95
|
+
class="menu transition"
|
|
96
|
+
>
|
|
97
|
+
<div
|
|
98
|
+
class="item"
|
|
99
|
+
role="option"
|
|
100
|
+
>
|
|
101
|
+
<em>
|
|
102
|
+
(reset filters)
|
|
103
|
+
</em>
|
|
104
|
+
</div>
|
|
105
|
+
</div>
|
|
106
|
+
</div>
|
|
107
|
+
</div>
|
|
108
|
+
<div
|
|
109
|
+
class="selectedFilters"
|
|
110
|
+
>
|
|
111
|
+
<div
|
|
112
|
+
class="appliedFilters"
|
|
113
|
+
>
|
|
114
|
+
apply filters
|
|
115
|
+
</div>
|
|
116
|
+
<div
|
|
117
|
+
aria-expanded="false"
|
|
118
|
+
class="ui floating item scrolling dropdown"
|
|
119
|
+
role="listbox"
|
|
120
|
+
tabindex="0"
|
|
121
|
+
>
|
|
122
|
+
<div
|
|
123
|
+
class="ui label"
|
|
124
|
+
>
|
|
125
|
+
filter
|
|
126
|
+
<i
|
|
127
|
+
aria-hidden="true"
|
|
128
|
+
class="delete icon"
|
|
129
|
+
/>
|
|
130
|
+
</div>
|
|
131
|
+
<div
|
|
132
|
+
class="menu transition dimmable"
|
|
133
|
+
/>
|
|
134
|
+
</div>
|
|
135
|
+
<a
|
|
136
|
+
class="resetFilters"
|
|
137
|
+
>
|
|
138
|
+
clear filters
|
|
139
|
+
</a>
|
|
140
|
+
<a
|
|
141
|
+
class="resetFilters"
|
|
142
|
+
>
|
|
143
|
+
save filters
|
|
144
|
+
</a>
|
|
145
|
+
</div>
|
|
146
|
+
<table
|
|
147
|
+
class="ui small selectable table"
|
|
148
|
+
>
|
|
149
|
+
<thead
|
|
150
|
+
class=""
|
|
151
|
+
>
|
|
152
|
+
<tr
|
|
153
|
+
class=""
|
|
154
|
+
>
|
|
155
|
+
<th
|
|
156
|
+
class=""
|
|
157
|
+
>
|
|
158
|
+
Term
|
|
159
|
+
</th>
|
|
160
|
+
<th
|
|
161
|
+
class=""
|
|
162
|
+
>
|
|
163
|
+
Domain
|
|
164
|
+
</th>
|
|
165
|
+
<th
|
|
166
|
+
class=""
|
|
167
|
+
>
|
|
168
|
+
Status
|
|
169
|
+
</th>
|
|
170
|
+
</tr>
|
|
171
|
+
</thead>
|
|
172
|
+
<tbody
|
|
173
|
+
class=""
|
|
174
|
+
>
|
|
175
|
+
<tr
|
|
176
|
+
class=""
|
|
177
|
+
>
|
|
178
|
+
<td
|
|
179
|
+
class=""
|
|
180
|
+
>
|
|
181
|
+
foo
|
|
182
|
+
</td>
|
|
183
|
+
<td
|
|
184
|
+
class=""
|
|
185
|
+
>
|
|
186
|
+
bar
|
|
187
|
+
</td>
|
|
188
|
+
<td
|
|
189
|
+
class=""
|
|
190
|
+
>
|
|
191
|
+
<div
|
|
192
|
+
class="ui olive label"
|
|
193
|
+
>
|
|
194
|
+
Draft
|
|
195
|
+
</div>
|
|
196
|
+
</td>
|
|
197
|
+
</tr>
|
|
198
|
+
</tbody>
|
|
199
|
+
</table>
|
|
200
|
+
</div>
|
|
201
|
+
</div>
|
|
202
|
+
</div>
|
|
203
|
+
<div
|
|
204
|
+
class="eight wide column"
|
|
205
|
+
>
|
|
206
|
+
<div
|
|
207
|
+
class="ui segment"
|
|
208
|
+
>
|
|
209
|
+
<h4
|
|
210
|
+
class="ui header"
|
|
211
|
+
>
|
|
212
|
+
<div
|
|
213
|
+
class="content"
|
|
214
|
+
>
|
|
215
|
+
Structures
|
|
216
|
+
</div>
|
|
217
|
+
</h4>
|
|
218
|
+
</div>
|
|
219
|
+
</div>
|
|
220
|
+
</div>
|
|
221
|
+
</div>
|
|
222
|
+
</div>
|
|
223
|
+
</div>
|
|
224
|
+
</div>
|
|
225
|
+
`;
|
|
@@ -26,7 +26,7 @@ const ConceptSelectorRow = ({ concept, active, onClick, disabled }) => {
|
|
|
26
26
|
onClick={() => onClick && onClick(concept)}
|
|
27
27
|
>
|
|
28
28
|
<Table.Cell content={name} />
|
|
29
|
-
<Table.Cell content={domain
|
|
29
|
+
<Table.Cell content={domain?.name} />
|
|
30
30
|
<Table.Cell
|
|
31
31
|
content={
|
|
32
32
|
<Label color={mapStatusColor[status]}>
|
|
@@ -65,6 +65,15 @@ export const ConceptSelector = ({
|
|
|
65
65
|
false
|
|
66
66
|
)(concepts);
|
|
67
67
|
|
|
68
|
+
const isDisabled = (concept) => {
|
|
69
|
+
return concept
|
|
70
|
+
? !_.flow(
|
|
71
|
+
_.pathOr({}, "_actions"),
|
|
72
|
+
_.propOr(true, "can_create_structure_link")
|
|
73
|
+
)(concept)
|
|
74
|
+
: false;
|
|
75
|
+
};
|
|
76
|
+
|
|
68
77
|
return (
|
|
69
78
|
<>
|
|
70
79
|
{loadConcepts && (
|
|
@@ -98,7 +107,9 @@ export const ConceptSelector = ({
|
|
|
98
107
|
<Table.Body>
|
|
99
108
|
{concepts.map((s, i) => (
|
|
100
109
|
<ConceptSelectorRow
|
|
101
|
-
disabled={
|
|
110
|
+
disabled={
|
|
111
|
+
businessConceptId == s.business_concept_id || isDisabled(s)
|
|
112
|
+
}
|
|
102
113
|
key={i}
|
|
103
114
|
concept={s}
|
|
104
115
|
active={selectedConcept && selectedConcept.id == s.id}
|
|
@@ -1,6 +1,25 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { render } from "@truedat/test/render";
|
|
3
|
+
import { waitFor } from "@testing-library/react";
|
|
4
|
+
import userEvent from "@testing-library/user-event";
|
|
3
5
|
import { ConceptSelector } from "../ConceptSelector";
|
|
6
|
+
import en from "../../../../messages/en";
|
|
7
|
+
|
|
8
|
+
const messages = {
|
|
9
|
+
en: {
|
|
10
|
+
...en,
|
|
11
|
+
"concepts.status.undefined": "undefined",
|
|
12
|
+
"search.save_filters": "save filters",
|
|
13
|
+
"search.clear_filters": "clear filters",
|
|
14
|
+
"search.applied_filters": "apply filters",
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
const renderOpts = {
|
|
18
|
+
messages,
|
|
19
|
+
state: {
|
|
20
|
+
conceptActiveFilters: { filter: "some" },
|
|
21
|
+
},
|
|
22
|
+
};
|
|
4
23
|
|
|
5
24
|
describe("<ConceptSelector />", () => {
|
|
6
25
|
const handleConceptSelected = jest.fn();
|
|
@@ -8,46 +27,62 @@ describe("<ConceptSelector />", () => {
|
|
|
8
27
|
id: 1,
|
|
9
28
|
name: "foo",
|
|
10
29
|
domain: { id: 1, name: "bar" },
|
|
11
|
-
status: "draft"
|
|
30
|
+
status: "draft",
|
|
31
|
+
business_concept_id: 1,
|
|
12
32
|
};
|
|
13
33
|
const props = {
|
|
14
34
|
conceptsLoading: false,
|
|
15
35
|
concepts: [concept],
|
|
16
36
|
selectedConcept: {},
|
|
17
|
-
handleConceptSelected
|
|
37
|
+
handleConceptSelected,
|
|
38
|
+
defaultFilters: {},
|
|
18
39
|
};
|
|
19
40
|
it("matches the latest snapshot", () => {
|
|
20
|
-
const
|
|
21
|
-
expect(
|
|
41
|
+
const { container } = render(<ConceptSelector {...props} />, renderOpts);
|
|
42
|
+
expect(container).toMatchSnapshot();
|
|
22
43
|
});
|
|
23
44
|
|
|
24
45
|
it("renders title when specified", () => {
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
46
|
+
const { queryByText } = render(<ConceptSelector {...props} />, renderOpts);
|
|
47
|
+
expect(queryByText("Related concept")).toBeInTheDocument();
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it("renders no title when is not specified", () => {
|
|
51
|
+
const { queryByText } = render(
|
|
52
|
+
<ConceptSelector {...{ ...props, showTitle: false }} />,
|
|
53
|
+
renderOpts
|
|
28
54
|
);
|
|
29
|
-
expect(
|
|
30
|
-
expect(withoutTitle.find("label").length).toBe(0);
|
|
55
|
+
expect(queryByText("Related concept")).not.toBeInTheDocument();
|
|
31
56
|
});
|
|
32
57
|
|
|
33
|
-
it("
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
58
|
+
it("calls handleConceptSelected on concept row click", async () => {
|
|
59
|
+
const { queryByText } = render(
|
|
60
|
+
<ConceptSelector {...{ ...props, selectedConcept: null }} />,
|
|
61
|
+
renderOpts
|
|
62
|
+
);
|
|
63
|
+
userEvent.click(await queryByText(/foo/));
|
|
64
|
+
await waitFor(() => {
|
|
65
|
+
expect(handleConceptSelected.mock.calls.length).toBe(1);
|
|
66
|
+
});
|
|
67
|
+
expect(handleConceptSelected).toHaveBeenCalledWith(
|
|
68
|
+
expect.objectContaining(concept)
|
|
37
69
|
);
|
|
38
|
-
expect(withLoader.find("Connect(ConceptsLoader)").length).toBe(1);
|
|
39
|
-
expect(withoutLoader.find("Connect(ConceptsLoader)").length).toBe(0);
|
|
40
70
|
});
|
|
41
71
|
|
|
42
|
-
it("
|
|
43
|
-
const
|
|
44
|
-
|
|
72
|
+
it("renders disable when cannot create structure link", () => {
|
|
73
|
+
const conceptWithActions = {
|
|
74
|
+
id: 1,
|
|
75
|
+
name: "foo",
|
|
76
|
+
domain: { id: 1, name: "bar" },
|
|
77
|
+
status: "draft",
|
|
78
|
+
business_concept_id: 1,
|
|
79
|
+
_actions: { can_create_structure_link: false },
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const { container } = render(
|
|
83
|
+
<ConceptSelector {...{ ...props, concepts: [conceptWithActions] }} />,
|
|
84
|
+
renderOpts
|
|
45
85
|
);
|
|
46
|
-
|
|
47
|
-
expect(ConceptSelectorRow.length).toBe(1);
|
|
48
|
-
ConceptSelectorRow.dive()
|
|
49
|
-
.find("TableRow")
|
|
50
|
-
.simulate("click");
|
|
51
|
-
expect(handleConceptSelected).toBeCalledWith(concept);
|
|
86
|
+
expect(container.querySelector("tbody > tr")).toHaveClass("disabled");
|
|
52
87
|
});
|
|
53
88
|
});
|
package/src/concepts/relations/components/__tests__/__snapshots__/ConceptSelector.spec.js.snap
CHANGED
|
@@ -1,100 +1,168 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
3
|
exports[`<ConceptSelector /> matches the latest snapshot 1`] = `
|
|
4
|
-
<
|
|
5
|
-
<Connect(ConceptsLoader)
|
|
6
|
-
defaultFilters={
|
|
7
|
-
Object {
|
|
8
|
-
"current": Array [
|
|
9
|
-
true,
|
|
10
|
-
],
|
|
11
|
-
"status": Array [
|
|
12
|
-
"pending_approval",
|
|
13
|
-
"draft",
|
|
14
|
-
"rejected",
|
|
15
|
-
"published",
|
|
16
|
-
],
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
pageSize={7}
|
|
20
|
-
/>
|
|
21
|
-
<Connect(FiltersLoader) />
|
|
22
|
-
<Connect(ConceptUserFiltersLoader) />
|
|
4
|
+
<div>
|
|
23
5
|
<label>
|
|
24
|
-
|
|
25
|
-
id="conceptRelations.relatedConcept"
|
|
26
|
-
/>
|
|
6
|
+
Related concept
|
|
27
7
|
</label>
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
<
|
|
32
|
-
|
|
33
|
-
selectable={true}
|
|
34
|
-
size="small"
|
|
8
|
+
<div
|
|
9
|
+
class="ui segment"
|
|
10
|
+
>
|
|
11
|
+
<div
|
|
12
|
+
class="ui action left icon input"
|
|
35
13
|
>
|
|
36
|
-
<
|
|
37
|
-
|
|
14
|
+
<input
|
|
15
|
+
placeholder="Search concepts..."
|
|
16
|
+
type="text"
|
|
17
|
+
value=""
|
|
18
|
+
/>
|
|
19
|
+
<i
|
|
20
|
+
aria-hidden="true"
|
|
21
|
+
class="search link icon"
|
|
22
|
+
/>
|
|
23
|
+
<div
|
|
24
|
+
aria-expanded="false"
|
|
25
|
+
class="ui button floating labeled scrolling dropdown icon"
|
|
26
|
+
role="listbox"
|
|
27
|
+
tabindex="0"
|
|
38
28
|
>
|
|
39
|
-
<
|
|
40
|
-
|
|
41
|
-
|
|
29
|
+
<div
|
|
30
|
+
aria-atomic="true"
|
|
31
|
+
aria-live="polite"
|
|
32
|
+
class="divider text"
|
|
33
|
+
role="alert"
|
|
42
34
|
>
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
35
|
+
Filters
|
|
36
|
+
</div>
|
|
37
|
+
<i
|
|
38
|
+
aria-hidden="true"
|
|
39
|
+
class="filter icon"
|
|
40
|
+
/>
|
|
41
|
+
<div
|
|
42
|
+
class="menu transition"
|
|
43
|
+
>
|
|
44
|
+
<div
|
|
45
|
+
class="item"
|
|
46
|
+
role="option"
|
|
47
|
+
>
|
|
48
|
+
<em>
|
|
49
|
+
(reset filters)
|
|
50
|
+
</em>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
<div
|
|
56
|
+
class="selectedFilters"
|
|
57
|
+
>
|
|
58
|
+
<div
|
|
59
|
+
class="appliedFilters"
|
|
60
|
+
>
|
|
61
|
+
apply filters
|
|
62
|
+
</div>
|
|
63
|
+
<div
|
|
64
|
+
aria-expanded="false"
|
|
65
|
+
class="ui floating item scrolling dropdown"
|
|
66
|
+
role="listbox"
|
|
67
|
+
tabindex="0"
|
|
68
|
+
>
|
|
69
|
+
<div
|
|
70
|
+
class="ui label"
|
|
71
|
+
>
|
|
72
|
+
filter
|
|
73
|
+
<i
|
|
74
|
+
aria-hidden="true"
|
|
75
|
+
class="delete icon"
|
|
50
76
|
/>
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
77
|
+
</div>
|
|
78
|
+
<div
|
|
79
|
+
class="menu transition dimmable"
|
|
80
|
+
/>
|
|
81
|
+
</div>
|
|
82
|
+
<a
|
|
83
|
+
class="resetFilters"
|
|
84
|
+
>
|
|
85
|
+
clear filters
|
|
86
|
+
</a>
|
|
87
|
+
<a
|
|
88
|
+
class="resetFilters"
|
|
89
|
+
>
|
|
90
|
+
save filters
|
|
91
|
+
</a>
|
|
92
|
+
</div>
|
|
93
|
+
<table
|
|
94
|
+
class="ui small selectable table"
|
|
95
|
+
>
|
|
96
|
+
<thead
|
|
97
|
+
class=""
|
|
98
|
+
>
|
|
99
|
+
<tr
|
|
100
|
+
class=""
|
|
101
|
+
>
|
|
102
|
+
<th
|
|
103
|
+
class=""
|
|
104
|
+
>
|
|
105
|
+
Term
|
|
106
|
+
</th>
|
|
107
|
+
<th
|
|
108
|
+
class=""
|
|
109
|
+
>
|
|
110
|
+
Domain
|
|
111
|
+
</th>
|
|
112
|
+
<th
|
|
113
|
+
class=""
|
|
114
|
+
>
|
|
115
|
+
Status
|
|
116
|
+
</th>
|
|
117
|
+
</tr>
|
|
118
|
+
</thead>
|
|
119
|
+
<tbody
|
|
120
|
+
class=""
|
|
121
|
+
>
|
|
122
|
+
<tr
|
|
123
|
+
class=""
|
|
124
|
+
>
|
|
125
|
+
<td
|
|
126
|
+
class=""
|
|
127
|
+
>
|
|
128
|
+
foo
|
|
129
|
+
</td>
|
|
130
|
+
<td
|
|
131
|
+
class=""
|
|
132
|
+
>
|
|
133
|
+
bar
|
|
134
|
+
</td>
|
|
135
|
+
<td
|
|
136
|
+
class=""
|
|
137
|
+
>
|
|
138
|
+
<div
|
|
139
|
+
class="ui olive label"
|
|
140
|
+
>
|
|
141
|
+
Draft
|
|
142
|
+
</div>
|
|
143
|
+
</td>
|
|
144
|
+
</tr>
|
|
145
|
+
<tr
|
|
146
|
+
class="active"
|
|
147
|
+
>
|
|
148
|
+
<td
|
|
149
|
+
class=""
|
|
58
150
|
/>
|
|
59
|
-
<
|
|
60
|
-
|
|
61
|
-
content={
|
|
62
|
-
<Memo(MemoizedFormattedMessage)
|
|
63
|
-
id="concepts.props.status"
|
|
64
|
-
/>
|
|
65
|
-
}
|
|
151
|
+
<td
|
|
152
|
+
class=""
|
|
66
153
|
/>
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
"name": "foo",
|
|
82
|
-
"status": "draft",
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
disabled={true}
|
|
86
|
-
key="0"
|
|
87
|
-
onClick={[MockFunction]}
|
|
88
|
-
/>
|
|
89
|
-
<ConceptSelectorRow
|
|
90
|
-
active={true}
|
|
91
|
-
concept={Object {}}
|
|
92
|
-
/>
|
|
93
|
-
</TableBody>
|
|
94
|
-
</Table>
|
|
95
|
-
<Connect(Pagination)
|
|
96
|
-
size="small"
|
|
97
|
-
/>
|
|
98
|
-
</Segment>
|
|
99
|
-
</Fragment>
|
|
154
|
+
<td
|
|
155
|
+
class=""
|
|
156
|
+
>
|
|
157
|
+
<div
|
|
158
|
+
class="ui label"
|
|
159
|
+
>
|
|
160
|
+
undefined
|
|
161
|
+
</div>
|
|
162
|
+
</td>
|
|
163
|
+
</tr>
|
|
164
|
+
</tbody>
|
|
165
|
+
</table>
|
|
166
|
+
</div>
|
|
167
|
+
</div>
|
|
100
168
|
`;
|
package/src/messages/en.js
CHANGED
|
@@ -43,9 +43,10 @@ export default {
|
|
|
43
43
|
"concept.events.new_concept_draft":
|
|
44
44
|
"created a new draft form a published concept",
|
|
45
45
|
"concept.events.update_concept_draft": "updated the draft",
|
|
46
|
-
"concept.events.
|
|
47
|
-
"concept.events.
|
|
48
|
-
"concept.events.
|
|
46
|
+
"concept.events.relation_creating": "Adding a link to a structure",
|
|
47
|
+
"concept.events.relation_created": "Added a link to a structure",
|
|
48
|
+
"concept.events.relation_deleted": "Removed a link to a structure",
|
|
49
|
+
"concept.events.relation_deprecated": "Deprecated link to a structure",
|
|
49
50
|
"concept.props.in_progress": "In progress",
|
|
50
51
|
"concept.props.last_update_at": "Update",
|
|
51
52
|
"concept.props.last_update_by": "User",
|
|
@@ -89,6 +90,11 @@ export default {
|
|
|
89
90
|
"This concept is not currently linked to any concept",
|
|
90
91
|
"conceptRelations.relatedConcept": "Related concept",
|
|
91
92
|
"conceptRelations.relationType": "Relation type",
|
|
93
|
+
"conceptRelations.concept": "Concept",
|
|
94
|
+
"conceptRelations.concepts": "Concepts",
|
|
95
|
+
"conceptRelations.structure": "Structure",
|
|
96
|
+
"conceptRelations.structures": "Structures",
|
|
97
|
+
"conceptRelations.tag": "Tag",
|
|
92
98
|
"conceptRelations.tags": "Tags",
|
|
93
99
|
"concepts.actions.bulk_update.popup":
|
|
94
100
|
"You should select only one type in filters",
|
|
@@ -131,6 +137,7 @@ export default {
|
|
|
131
137
|
"concepts.header.edit.bulk.concepts_count":
|
|
132
138
|
'Selected concepts: "{concepts_count}"',
|
|
133
139
|
"concepts.header.edit.bulk.info_message": "Only modify fields to be updated",
|
|
140
|
+
"concepts.header.linksManager": "Concepts link manager",
|
|
134
141
|
"concepts.header.manage": "Concepts Management",
|
|
135
142
|
"concepts.props.completeness": "Completeness",
|
|
136
143
|
"concepts.props.description": "Description",
|
|
@@ -164,6 +171,7 @@ export default {
|
|
|
164
171
|
"concepts.status.published": "Published",
|
|
165
172
|
"concepts.status.rejected": "Rejected",
|
|
166
173
|
"concepts.status.versioned": "Versioned",
|
|
174
|
+
"concepts.subheader.linksManager": "Query links business concepts",
|
|
167
175
|
"concepts.subheader.manage": "Concept Versions in Progress",
|
|
168
176
|
"concepts.subheader.view": "Query business concepts",
|
|
169
177
|
"concepts.summary": "Summary",
|
package/src/messages/es.js
CHANGED
|
@@ -45,9 +45,10 @@ export default {
|
|
|
45
45
|
"concept.events.new_concept_draft":
|
|
46
46
|
"creó un nuevo borrador a partir de la publicación existente",
|
|
47
47
|
"concept.events.update_concept_draft": "actualizó el borrador",
|
|
48
|
-
"concept.events.
|
|
49
|
-
"concept.events.
|
|
50
|
-
"concept.events.
|
|
48
|
+
"concept.events.relation_creating": "Creando un nuevo vínculo",
|
|
49
|
+
"concept.events.relation_created": "Nuevo vínculo creado",
|
|
50
|
+
"concept.events.relation_deleted": "Vínculo eliminado",
|
|
51
|
+
"concept.events.relation_deprecated": "Vínculo deprecado",
|
|
51
52
|
"concept.props.in_progress": "Sin completar",
|
|
52
53
|
"concept.props.last_update_at": "Modificación",
|
|
53
54
|
"concept.props.last_update_by": "Usuario",
|
|
@@ -88,6 +89,11 @@ export default {
|
|
|
88
89
|
"Este concepto no tiene conceptos relacionados actualmente",
|
|
89
90
|
"conceptRelations.relatedConcept": "Concepto relacionado",
|
|
90
91
|
"conceptRelations.relationType": "Tipo de relación",
|
|
92
|
+
"conceptRelations.concept": "Concepto",
|
|
93
|
+
"conceptRelations.concepts": "Conceptos",
|
|
94
|
+
"conceptRelations.structure": "Estructura",
|
|
95
|
+
"conceptRelations.structures": "Estructuras",
|
|
96
|
+
"conceptRelations.tag": "Etiqueta",
|
|
91
97
|
"conceptRelations.tags": "Etiquetas",
|
|
92
98
|
"concepts.actions.bulk_update.popup":
|
|
93
99
|
"Seleccione un único tipo en los filtros",
|
|
@@ -130,6 +136,7 @@ export default {
|
|
|
130
136
|
'Conceptos seleccionados: "{concepts_count}"',
|
|
131
137
|
"concepts.header.edit.bulk.info_message":
|
|
132
138
|
"Rellenar únicamente los campos que se quieran actualizar",
|
|
139
|
+
"concepts.header.linksManager": "Gestion de vínculos para conceptos",
|
|
133
140
|
"concepts.header.manage": "Gestión de Conceptos",
|
|
134
141
|
"concepts.props.completeness": "Completitud",
|
|
135
142
|
"concepts.props.description": "Descripción",
|
|
@@ -164,6 +171,8 @@ export default {
|
|
|
164
171
|
"concepts.status.published": "Publicado",
|
|
165
172
|
"concepts.status.rejected": "Rechazado",
|
|
166
173
|
"concepts.status.versioned": "Versionado",
|
|
174
|
+
"concepts.subheader.linksManager":
|
|
175
|
+
"Consultar vínculos de conceptos de negocio",
|
|
167
176
|
"concepts.subheader.manage": "Versiones de Conceptos en Progreso",
|
|
168
177
|
"concepts.subheader.view": "Consultar conceptos de negocio",
|
|
169
178
|
"concepts.summary": "Resumen",
|