@truedat/dd 4.40.12 → 4.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/package.json +6 -6
- package/src/api.js +3 -0
- package/src/components/DictionaryRoutes.js +17 -1
- package/src/components/PendingStructureNoteRow.js +45 -0
- package/src/components/PendingStructureNotes.js +149 -0
- package/src/components/PendingStructureNotesTable.js +73 -0
- package/src/components/StructuresDomainsUploadOption.js +52 -0
- package/src/components/StructuresOptions.js +4 -0
- package/src/components/__tests__/PendingStructureNoteRow.spec.js +48 -0
- package/src/components/__tests__/PendingStructureNotes.spec.js +102 -0
- package/src/components/__tests__/PendingStructureNotesTable.spec.js +83 -0
- package/src/components/__tests__/StructuresOptions.spec.js +6 -1
- package/src/components/__tests__/__snapshots__/DictionaryRoutes.spec.js.snap +4 -0
- package/src/components/__tests__/__snapshots__/PendingStructureNoteRow.spec.js.snap +35 -0
- package/src/components/__tests__/__snapshots__/PendingStructureNotes.spec.js.snap +126 -0
- package/src/components/__tests__/__snapshots__/PendingStructureNotesTable.spec.js.snap +123 -0
- package/src/components/__tests__/__snapshots__/StructuresOptions.spec.js.snap +14 -0
- package/src/messages/en.js +27 -0
- package/src/messages/es.js +30 -0
- package/src/reducers/__tests__/ddMessage.spec.js +76 -0
- package/src/reducers/ddMessage.js +51 -8
- package/src/routines.js +1 -0
- package/src/sagas/__tests__/uploadStructuresDomains.spec.js +81 -0
- package/src/sagas/index.js +3 -0
- package/src/sagas/uploadStructuresDomains.js +35 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [4.41.0] 2022-03-25
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- [TD-4535] Structures domains CSV upload bulk update
|
|
8
|
+
|
|
9
|
+
## [4.40.14] 2022-03-22
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- [TD-4577] View for Pending `StructureNotes`
|
|
14
|
+
|
|
3
15
|
## [4.40.10] 2022-03-21
|
|
4
16
|
|
|
5
17
|
### Changed
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truedat/dd",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.41.0",
|
|
4
4
|
"description": "Truedat Web Data Dictionary",
|
|
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.41.0",
|
|
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",
|
|
@@ -84,9 +84,9 @@
|
|
|
84
84
|
]
|
|
85
85
|
},
|
|
86
86
|
"dependencies": {
|
|
87
|
-
"@truedat/auth": "4.
|
|
88
|
-
"@truedat/core": "4.
|
|
89
|
-
"@truedat/df": "4.
|
|
87
|
+
"@truedat/auth": "4.41.0",
|
|
88
|
+
"@truedat/core": "4.41.0",
|
|
89
|
+
"@truedat/df": "4.41.0",
|
|
90
90
|
"lodash": "^4.17.21",
|
|
91
91
|
"path-to-regexp": "^1.7.0",
|
|
92
92
|
"prop-types": "^15.7.2",
|
|
@@ -107,5 +107,5 @@
|
|
|
107
107
|
"react-dom": ">= 16.8.6 < 17",
|
|
108
108
|
"semantic-ui-react": ">= 0.88.2 < 2.1"
|
|
109
109
|
},
|
|
110
|
-
"gitHead": "
|
|
110
|
+
"gitHead": "f4d8bc5e536b847c7b562a84bfa70955a93166ea"
|
|
111
111
|
}
|
package/src/api.js
CHANGED
|
@@ -31,6 +31,8 @@ const API_STRUCTURE_TAG = "/api/data_structure_tags/:id";
|
|
|
31
31
|
const API_STRUCTURE_TAGS = "/api/data_structure_tags";
|
|
32
32
|
const API_STRUCTURE_TYPE = "/api/data_structure_types/:id";
|
|
33
33
|
const API_STRUCTURE_TYPES = "/api/data_structure_types";
|
|
34
|
+
const API_STRUCTURES_DOMAINS_UPLOAD =
|
|
35
|
+
"/api/data_structures/bulk_upload_domains";
|
|
34
36
|
const API_STRUCTURES_TAG = "/api/data_structures/:data_structure_id/tags/:id";
|
|
35
37
|
const API_STRUCTURES_TAGS = "/api/data_structures/:data_structure_id/tags";
|
|
36
38
|
const API_USER_SEARCH_FILTERS = "/api/user_search_filters";
|
|
@@ -79,6 +81,7 @@ export {
|
|
|
79
81
|
API_USER_SEARCH_FILTERS,
|
|
80
82
|
API_USER_SEARCH_FILTER,
|
|
81
83
|
API_GET_USER_SEARCH_FILTERS,
|
|
84
|
+
API_STRUCTURES_DOMAINS_UPLOAD,
|
|
82
85
|
API_STRUCTURES_TAG,
|
|
83
86
|
API_STRUCTURES_TAGS,
|
|
84
87
|
API_STRUCTURES_UPLOAD,
|
|
@@ -2,13 +2,15 @@ import React from "react";
|
|
|
2
2
|
import { Route, Switch } from "react-router-dom";
|
|
3
3
|
import { useActiveRoute } from "@truedat/core/hooks";
|
|
4
4
|
import {
|
|
5
|
+
PENDING_STRUCTURE_NOTES,
|
|
5
6
|
PROFILE_EXECUTION,
|
|
6
7
|
PROFILE_GROUP,
|
|
7
|
-
STRUCTURES,
|
|
8
8
|
STRUCTURE_TAGS,
|
|
9
9
|
STRUCTURE_TYPES,
|
|
10
|
+
STRUCTURES,
|
|
10
11
|
SYSTEMS,
|
|
11
12
|
} from "@truedat/core/routes";
|
|
13
|
+
import PendingStructureNotes from "./PendingStructureNotes";
|
|
12
14
|
import ProfileExecution from "./ProfileExecution";
|
|
13
15
|
import ProfileExecutionBreadcrumbs from "./ProfileExecutionBreadcrumbs";
|
|
14
16
|
import ProfileExecutionLoader from "./ProfileExecutionLoader";
|
|
@@ -27,6 +29,10 @@ const TemplatesLoader = React.lazy(() =>
|
|
|
27
29
|
import("@truedat/df/templates/components/TemplatesLoader")
|
|
28
30
|
);
|
|
29
31
|
|
|
32
|
+
const DomainsLoader = React.lazy(() =>
|
|
33
|
+
import("@truedat/bg/taxonomy/components/DomainsLoader")
|
|
34
|
+
);
|
|
35
|
+
|
|
30
36
|
const Loaders = () => (
|
|
31
37
|
<>
|
|
32
38
|
<StructuresLoader />
|
|
@@ -82,6 +88,16 @@ export const DictionaryRoutes = () => {
|
|
|
82
88
|
</>
|
|
83
89
|
)}
|
|
84
90
|
/>
|
|
91
|
+
<Route
|
|
92
|
+
path={PENDING_STRUCTURE_NOTES}
|
|
93
|
+
render={() => (
|
|
94
|
+
<>
|
|
95
|
+
<SystemsLoader />
|
|
96
|
+
<DomainsLoader />
|
|
97
|
+
<PendingStructureNotes />
|
|
98
|
+
</>
|
|
99
|
+
)}
|
|
100
|
+
/>
|
|
85
101
|
<Route
|
|
86
102
|
path={PROFILE_GROUP}
|
|
87
103
|
render={() => (
|
|
@@ -0,0 +1,45 @@
|
|
|
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 { useIntl } from "react-intl";
|
|
6
|
+
import { useHistory } from "react-router-dom";
|
|
7
|
+
import { linkTo } from "@truedat/core/routes";
|
|
8
|
+
|
|
9
|
+
const PendingStructureNoteRow = ({ structureNote }) => {
|
|
10
|
+
const { formatMessage } = useIntl();
|
|
11
|
+
const history = useHistory();
|
|
12
|
+
const dataStructure = _.prop("data_structure")(structureNote);
|
|
13
|
+
const path = _.propOr(
|
|
14
|
+
[],
|
|
15
|
+
"data_structure.current_version.path"
|
|
16
|
+
)(structureNote);
|
|
17
|
+
const name = _.prop("data_structure.current_version.name")(structureNote);
|
|
18
|
+
const system = _.prop("data_structure.system.name")(structureNote);
|
|
19
|
+
const domainsNames = _.flow(
|
|
20
|
+
_.prop("data_structure.domains"),
|
|
21
|
+
_.map("name")
|
|
22
|
+
)(structureNote);
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<Table.Row
|
|
26
|
+
onClick={() => history.push(linkTo.STRUCTURE_NOTES(dataStructure))}
|
|
27
|
+
>
|
|
28
|
+
<Table.Cell content={name} />
|
|
29
|
+
<Table.Cell
|
|
30
|
+
content={formatMessage({
|
|
31
|
+
id: `structure.notes.status.${structureNote.status}`,
|
|
32
|
+
})}
|
|
33
|
+
/>
|
|
34
|
+
<Table.Cell content={system} />
|
|
35
|
+
<Table.Cell content={domainsNames.join(", ")} />
|
|
36
|
+
<Table.Cell content={path.join(" > ")} />
|
|
37
|
+
</Table.Row>
|
|
38
|
+
);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
PendingStructureNoteRow.propTypes = {
|
|
42
|
+
structureNote: PropTypes.object,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export default PendingStructureNoteRow;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import React, { useState } from "react";
|
|
3
|
+
import { useSelector } from "react-redux";
|
|
4
|
+
import { FormattedMessage, useIntl } from "react-intl";
|
|
5
|
+
import { gql, useQuery } from "@apollo/client";
|
|
6
|
+
import { Checkbox, Form, Header, Icon, Segment } from "semantic-ui-react";
|
|
7
|
+
import { useForm, Controller } from "react-hook-form";
|
|
8
|
+
import PendingStructureNotesTable from "./PendingStructureNotesTable";
|
|
9
|
+
|
|
10
|
+
const DomainDropdownSelector = React.lazy(() =>
|
|
11
|
+
import("@truedat/bg/taxonomy/components/DomainDropdownSelector")
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
export const STRUCTURE_NOTES = gql`
|
|
15
|
+
query STRUCTURE_NOTES($filter: StructureNotesFilter) {
|
|
16
|
+
structure_notes(filter: $filter) {
|
|
17
|
+
id
|
|
18
|
+
status
|
|
19
|
+
data_structure {
|
|
20
|
+
id
|
|
21
|
+
current_version {
|
|
22
|
+
id
|
|
23
|
+
name
|
|
24
|
+
path
|
|
25
|
+
version
|
|
26
|
+
}
|
|
27
|
+
system {
|
|
28
|
+
name
|
|
29
|
+
}
|
|
30
|
+
domains {
|
|
31
|
+
name
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
`;
|
|
37
|
+
|
|
38
|
+
const STATUS = ["pending_approval", "draft", "rejected"];
|
|
39
|
+
|
|
40
|
+
export const PendingStructureNotes = () => {
|
|
41
|
+
const { formatMessage } = useIntl();
|
|
42
|
+
const { systems } = useSelector(_.pick(["systems"]));
|
|
43
|
+
const [filter, setFilter] = useState({
|
|
44
|
+
statuses: STATUS,
|
|
45
|
+
});
|
|
46
|
+
const { loading, error, data } = useQuery(STRUCTURE_NOTES, {
|
|
47
|
+
variables: { filter },
|
|
48
|
+
fetchPolicy: "network-only",
|
|
49
|
+
});
|
|
50
|
+
const items = loading || error ? [] : data?.structure_notes;
|
|
51
|
+
const { control } = useForm({
|
|
52
|
+
mode: "all",
|
|
53
|
+
defaultValues: {
|
|
54
|
+
status: STATUS,
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
return (
|
|
59
|
+
<Segment>
|
|
60
|
+
<Header as="h2">
|
|
61
|
+
<Icon name="sticky note outline" circular />
|
|
62
|
+
<Header.Content>
|
|
63
|
+
<FormattedMessage id="pendingStructureNotes.header" />
|
|
64
|
+
<Header.Subheader>
|
|
65
|
+
<FormattedMessage id="pendingStructureNotes.subheader" />
|
|
66
|
+
</Header.Subheader>
|
|
67
|
+
</Header.Content>
|
|
68
|
+
</Header>
|
|
69
|
+
<Form>
|
|
70
|
+
<Header
|
|
71
|
+
as="h5"
|
|
72
|
+
content={formatMessage({ id: "pendingStructureNotes.filters" })}
|
|
73
|
+
/>
|
|
74
|
+
<Controller
|
|
75
|
+
control={control}
|
|
76
|
+
name="status"
|
|
77
|
+
render={({ onBlur, onChange, value }) => (
|
|
78
|
+
<Form.Field className="subscriptions-checkbox-filters">
|
|
79
|
+
<label>
|
|
80
|
+
{formatMessage({ id: "pendingStructureNotes.props.status" })}
|
|
81
|
+
</label>
|
|
82
|
+
{STATUS.map((type, idx) => (
|
|
83
|
+
<Checkbox
|
|
84
|
+
onBlur={onBlur}
|
|
85
|
+
key={idx}
|
|
86
|
+
label={
|
|
87
|
+
<label>
|
|
88
|
+
{formatMessage({ id: `structure.notes.status.${type}` })}
|
|
89
|
+
</label>
|
|
90
|
+
}
|
|
91
|
+
onChange={() => {
|
|
92
|
+
const statuses = _.includes(type)(value)
|
|
93
|
+
? _.filter((t) => t !== type)(value)
|
|
94
|
+
: [...value, type];
|
|
95
|
+
setFilter({ ...filter, statuses });
|
|
96
|
+
onChange(statuses);
|
|
97
|
+
}}
|
|
98
|
+
checked={_.includes(type)(value)}
|
|
99
|
+
/>
|
|
100
|
+
))}
|
|
101
|
+
</Form.Field>
|
|
102
|
+
)}
|
|
103
|
+
/>
|
|
104
|
+
<Controller
|
|
105
|
+
control={control}
|
|
106
|
+
name="system_ids"
|
|
107
|
+
render={({ onBlur, onChange, value }) => (
|
|
108
|
+
<Form.Dropdown
|
|
109
|
+
label={formatMessage({
|
|
110
|
+
id: "pendingStructureNotes.props.system",
|
|
111
|
+
})}
|
|
112
|
+
onBlur={onBlur}
|
|
113
|
+
onChange={(e, { value }) => {
|
|
114
|
+
setFilter({ ...filter, system_ids: value });
|
|
115
|
+
onChange(value);
|
|
116
|
+
}}
|
|
117
|
+
options={systems.map(({ name, id }) => ({
|
|
118
|
+
text: name,
|
|
119
|
+
key: id,
|
|
120
|
+
value: id,
|
|
121
|
+
}))}
|
|
122
|
+
selection
|
|
123
|
+
clearable
|
|
124
|
+
multiple
|
|
125
|
+
value={value || []}
|
|
126
|
+
/>
|
|
127
|
+
)}
|
|
128
|
+
/>
|
|
129
|
+
<Controller
|
|
130
|
+
control={control}
|
|
131
|
+
name="domain_ids"
|
|
132
|
+
render={({ onChange, value }) => (
|
|
133
|
+
<DomainDropdownSelector
|
|
134
|
+
value={value}
|
|
135
|
+
onChange={(_e, { value }) => {
|
|
136
|
+
const domain_ids = _.isNumber(value) ? [value] : [];
|
|
137
|
+
setFilter({ ...filter, domain_ids });
|
|
138
|
+
onChange(value);
|
|
139
|
+
}}
|
|
140
|
+
/>
|
|
141
|
+
)}
|
|
142
|
+
/>
|
|
143
|
+
</Form>
|
|
144
|
+
<PendingStructureNotesTable structureNotes={items} loading={loading} />
|
|
145
|
+
</Segment>
|
|
146
|
+
);
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
export default PendingStructureNotes;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import PropTypes from "prop-types";
|
|
4
|
+
import { FormattedMessage } from "react-intl";
|
|
5
|
+
import { Table, Header, Icon } from "semantic-ui-react";
|
|
6
|
+
import PendingStructureNoteRow from "./PendingStructureNoteRow";
|
|
7
|
+
|
|
8
|
+
const PendingStructureNotesTable = ({ structureNotes, loading }) => {
|
|
9
|
+
return (
|
|
10
|
+
<>
|
|
11
|
+
{!_.isEmpty(structureNotes) && (
|
|
12
|
+
<Table selectable>
|
|
13
|
+
<Table.Header>
|
|
14
|
+
<Table.Row>
|
|
15
|
+
<Table.HeaderCell
|
|
16
|
+
content={
|
|
17
|
+
<FormattedMessage
|
|
18
|
+
id={"pendingStructureNotes.props.structure"}
|
|
19
|
+
/>
|
|
20
|
+
}
|
|
21
|
+
/>
|
|
22
|
+
<Table.HeaderCell
|
|
23
|
+
content={
|
|
24
|
+
<FormattedMessage id={"pendingStructureNotes.props.status"} />
|
|
25
|
+
}
|
|
26
|
+
/>
|
|
27
|
+
<Table.HeaderCell
|
|
28
|
+
content={
|
|
29
|
+
<FormattedMessage id={"pendingStructureNotes.props.system"} />
|
|
30
|
+
}
|
|
31
|
+
/>
|
|
32
|
+
<Table.HeaderCell
|
|
33
|
+
content={
|
|
34
|
+
<FormattedMessage
|
|
35
|
+
id={"pendingStructureNotes.props.domains"}
|
|
36
|
+
/>
|
|
37
|
+
}
|
|
38
|
+
/>
|
|
39
|
+
<Table.HeaderCell
|
|
40
|
+
content={
|
|
41
|
+
<FormattedMessage id={"pendingStructureNotes.props.path"} />
|
|
42
|
+
}
|
|
43
|
+
/>
|
|
44
|
+
</Table.Row>
|
|
45
|
+
</Table.Header>
|
|
46
|
+
<Table.Body>
|
|
47
|
+
{structureNotes.map((structureNote, key) => (
|
|
48
|
+
<PendingStructureNoteRow
|
|
49
|
+
key={key}
|
|
50
|
+
structureNote={structureNote}
|
|
51
|
+
/>
|
|
52
|
+
))}
|
|
53
|
+
</Table.Body>
|
|
54
|
+
</Table>
|
|
55
|
+
)}
|
|
56
|
+
{_.isEmpty(structureNotes) && !loading && (
|
|
57
|
+
<Header as="h4">
|
|
58
|
+
<Icon name="search" />
|
|
59
|
+
<Header.Content>
|
|
60
|
+
<FormattedMessage id="pendingStructureNotes.search.results.empty" />
|
|
61
|
+
</Header.Content>
|
|
62
|
+
</Header>
|
|
63
|
+
)}
|
|
64
|
+
</>
|
|
65
|
+
);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
PendingStructureNotesTable.propTypes = {
|
|
69
|
+
structureNotes: PropTypes.array,
|
|
70
|
+
loading: PropTypes.bool,
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export default PendingStructureNotesTable;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
import { connect } from "react-redux";
|
|
4
|
+
import { Dropdown } from "semantic-ui-react";
|
|
5
|
+
import { useIntl } from "react-intl";
|
|
6
|
+
import { UploadModal } from "@truedat/core/components";
|
|
7
|
+
import { uploadStructuresDomains } from "../routines";
|
|
8
|
+
|
|
9
|
+
export const StructuresDomainsUploadOption = ({
|
|
10
|
+
uploadStructuresDomains,
|
|
11
|
+
loading,
|
|
12
|
+
}) => {
|
|
13
|
+
const { formatMessage } = useIntl();
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<UploadModal
|
|
17
|
+
icon="upload"
|
|
18
|
+
trigger={
|
|
19
|
+
<Dropdown.Item
|
|
20
|
+
icon="upload"
|
|
21
|
+
text={formatMessage({ id: "structures.actions.uploadDomains.tooltip" })}
|
|
22
|
+
disabled={loading}
|
|
23
|
+
/>
|
|
24
|
+
}
|
|
25
|
+
header={formatMessage({
|
|
26
|
+
id: "structures.actions.uploadDomains.confirmation.header",
|
|
27
|
+
})}
|
|
28
|
+
content={formatMessage({
|
|
29
|
+
id: "structures.actions.uploadDomains.confirmation.content",
|
|
30
|
+
})}
|
|
31
|
+
param={"structures_domains"}
|
|
32
|
+
handleSubmit={(data) =>
|
|
33
|
+
uploadStructuresDomains({
|
|
34
|
+
data,
|
|
35
|
+
})
|
|
36
|
+
}
|
|
37
|
+
/>
|
|
38
|
+
);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
StructuresDomainsUploadOption.propTypes = {
|
|
42
|
+
uploadStructuresDomains: PropTypes.func,
|
|
43
|
+
loading: PropTypes.bool,
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const mapStateToProps = ({ uploadingStructuresDomainsFile }) => ({
|
|
47
|
+
loading: uploadingStructuresDomainsFile,
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
export default connect(mapStateToProps, { uploadStructuresDomains })(
|
|
51
|
+
StructuresDomainsUploadOption
|
|
52
|
+
);
|
|
@@ -6,10 +6,12 @@ import StructuresDownloadOption from "./StructuresDownloadOption";
|
|
|
6
6
|
import StructuresEditableDownloadOption from "./StructuresEditableDownloadOption";
|
|
7
7
|
import StructuresUpdateOption from "./StructuresUpdateOption";
|
|
8
8
|
import StructuresUploadOption from "./StructuresUploadOption";
|
|
9
|
+
import StructuresDomainsUploadOption from "./StructuresDomainsUploadOption";
|
|
9
10
|
|
|
10
11
|
export const StructuresOptions = ({
|
|
11
12
|
autoPublish,
|
|
12
13
|
bulkUpload,
|
|
14
|
+
bulkUploadDomains,
|
|
13
15
|
hasFilterApplied,
|
|
14
16
|
}) => (
|
|
15
17
|
<Dropdown
|
|
@@ -26,6 +28,7 @@ export const StructuresOptions = ({
|
|
|
26
28
|
{bulkUpload ? (
|
|
27
29
|
<StructuresUploadOption canAutoPublish={!!autoPublish} />
|
|
28
30
|
) : null}
|
|
31
|
+
{bulkUploadDomains ? <StructuresDomainsUploadOption /> : null}
|
|
29
32
|
<Dropdown.Divider />
|
|
30
33
|
<StructuresUpdateOption />
|
|
31
34
|
</Dropdown.Menu>
|
|
@@ -35,6 +38,7 @@ export const StructuresOptions = ({
|
|
|
35
38
|
StructuresOptions.propTypes = {
|
|
36
39
|
autoPublish: PropTypes.object,
|
|
37
40
|
bulkUpload: PropTypes.object,
|
|
41
|
+
bulkUploadDomains: PropTypes.object,
|
|
38
42
|
hasFilterApplied: PropTypes.bool,
|
|
39
43
|
};
|
|
40
44
|
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { waitFor } from "@testing-library/react";
|
|
3
|
+
import { render } from "@truedat/test/render";
|
|
4
|
+
import PendingStructureNoteRow from "../PendingStructureNoteRow";
|
|
5
|
+
|
|
6
|
+
const renderOpts = {
|
|
7
|
+
messages: {
|
|
8
|
+
en: {
|
|
9
|
+
"pendingStructureNotes.search.results.empty": "Empty",
|
|
10
|
+
"pendingStructureNotes.props.structure": "Structure",
|
|
11
|
+
"pendingStructureNotes.props.status": "Status",
|
|
12
|
+
"pendingStructureNotes.props.system": "System",
|
|
13
|
+
"pendingStructureNotes.props.domains": "Domains",
|
|
14
|
+
"structure.notes.status.deprecated": "Deprecated",
|
|
15
|
+
"structure.notes.status.draft": "Draft",
|
|
16
|
+
"structure.notes.status.rejected": "Rejected",
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const props = {
|
|
22
|
+
structureNote: {
|
|
23
|
+
id: "7207",
|
|
24
|
+
status: "draft",
|
|
25
|
+
data_structure: {
|
|
26
|
+
current_version: {
|
|
27
|
+
name: "bar",
|
|
28
|
+
path: ["bar rute"],
|
|
29
|
+
},
|
|
30
|
+
domains: [{ name: "bar domain" }],
|
|
31
|
+
system: { name: "bar system" },
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
describe("<PendingStructureNoteRow />", () => {
|
|
37
|
+
it("matches the latest snapshot", async () => {
|
|
38
|
+
const { container, queryByText } = render(
|
|
39
|
+
<PendingStructureNoteRow {...props} />,
|
|
40
|
+
renderOpts
|
|
41
|
+
);
|
|
42
|
+
expect(container).toMatchSnapshot();
|
|
43
|
+
|
|
44
|
+
await waitFor(() => {
|
|
45
|
+
expect(queryByText(/bar system/)).toBeTruthy();
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
});
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import React, { Suspense } from "react";
|
|
2
|
+
import { waitFor } from "@testing-library/react";
|
|
3
|
+
import { render } from "@truedat/test/render";
|
|
4
|
+
import {
|
|
5
|
+
PendingStructureNotes,
|
|
6
|
+
STRUCTURE_NOTES,
|
|
7
|
+
} from "../PendingStructureNotes";
|
|
8
|
+
|
|
9
|
+
jest.mock("react-redux", () => ({
|
|
10
|
+
...jest.requireActual("react-redux"),
|
|
11
|
+
useSelector: jest.fn((selector) =>
|
|
12
|
+
selector({
|
|
13
|
+
systems: [
|
|
14
|
+
{ external_id: "some_external_id", id: 10, name: "some system" },
|
|
15
|
+
],
|
|
16
|
+
})
|
|
17
|
+
),
|
|
18
|
+
}));
|
|
19
|
+
|
|
20
|
+
const domains = [
|
|
21
|
+
{ id: 1, name: "Domain 1", level: 0 },
|
|
22
|
+
{ id: 2, name: "Domain 2", level: 0 },
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
const messages = {
|
|
26
|
+
en: {
|
|
27
|
+
"structure.notes.status.pending_approval": "Empty",
|
|
28
|
+
"pendingStructureNotes.filters": "Filters",
|
|
29
|
+
"pendingStructureNotes.props.status": "Status",
|
|
30
|
+
"pendingStructureNotes.props.system": "System",
|
|
31
|
+
"pendingStructureNotes.props.domains": "Domains",
|
|
32
|
+
"structure.notes.status.draft": "Draft",
|
|
33
|
+
"structure.notes.status.rejected": "Rejected",
|
|
34
|
+
"pendingStructureNotes.header": "Header",
|
|
35
|
+
"pendingStructureNotes.subheader": "Sub header",
|
|
36
|
+
"pendingStructureNotes.search.results.empty": "Serch Empty",
|
|
37
|
+
"domain.selector.placeholder": "Place Holder",
|
|
38
|
+
"domain.selector.label": "label",
|
|
39
|
+
"template.form.validation.empty_required": "empty required",
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const structureNotes = {
|
|
44
|
+
loading: false,
|
|
45
|
+
structureNotes: [
|
|
46
|
+
{
|
|
47
|
+
id: "7207",
|
|
48
|
+
status: "draft",
|
|
49
|
+
data_structure: {
|
|
50
|
+
current_version: {
|
|
51
|
+
name: "bar",
|
|
52
|
+
path: ["bar rute"],
|
|
53
|
+
},
|
|
54
|
+
domains: [{ name: "bar domain" }],
|
|
55
|
+
system: { name: "bar system" },
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: "665214",
|
|
60
|
+
status: "rejected",
|
|
61
|
+
data_structure: {
|
|
62
|
+
current_version: {
|
|
63
|
+
name: "foo",
|
|
64
|
+
path: ["foo rute", "other route"],
|
|
65
|
+
},
|
|
66
|
+
domains: [{ name: "foo domain 1" }, { name: "foo domain 2" }],
|
|
67
|
+
system: { name: "foo system" },
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const StructureNotesMock = {
|
|
74
|
+
request: { query: STRUCTURE_NOTES },
|
|
75
|
+
result: { data: { structureNotes } },
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const renderOpts = {
|
|
79
|
+
mocks: [StructureNotesMock],
|
|
80
|
+
messages,
|
|
81
|
+
state: { domains },
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
describe("<PendingStructureNotes />", () => {
|
|
85
|
+
it("matches the latest snapshot", async () => {
|
|
86
|
+
const { container, queryByText } = render(
|
|
87
|
+
<Suspense fallback={null}>
|
|
88
|
+
<PendingStructureNotes />
|
|
89
|
+
</Suspense>,
|
|
90
|
+
renderOpts
|
|
91
|
+
);
|
|
92
|
+
expect(container).toMatchSnapshot();
|
|
93
|
+
|
|
94
|
+
await waitFor(() => {
|
|
95
|
+
expect(queryByText(/some system/)).toBeTruthy();
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
await waitFor(() => {
|
|
99
|
+
expect(queryByText(/Domain 1/)).toBeTruthy();
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
});
|