@truedat/dd 4.40.14 → 4.41.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/package.json +6 -6
- package/src/api.js +3 -0
- package/src/components/EditDomainForm.js +37 -24
- package/src/components/StructuresDomainsUploadOption.js +54 -0
- package/src/components/StructuresOptions.js +4 -0
- package/src/components/__tests__/EditDomainForm.spec.js +2 -0
- package/src/components/__tests__/PendingStructureNotesTable.spec.js +1 -0
- package/src/components/__tests__/StructuresOptions.spec.js +6 -1
- package/src/components/__tests__/__snapshots__/EditDomainForm.spec.js.snap +66 -77
- package/src/components/__tests__/__snapshots__/PendingStructureNotesTable.spec.js.snap +1 -1
- package/src/components/__tests__/__snapshots__/StructuresOptions.spec.js.snap +14 -0
- package/src/messages/en.js +18 -0
- package/src/messages/es.js +20 -0
- package/src/reducers/__tests__/ddMessage.spec.js +73 -0
- package/src/reducers/ddMessage.js +52 -8
- package/src/routines.js +3 -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,23 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [4.41.2] 2022-03-30
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- [TD-4535] "Show more" on long Alert errors
|
|
8
|
+
|
|
9
|
+
## [4.41.1] 2022-03-25
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- [TD-4617] Use domainMenuSelector on editDomainForm
|
|
14
|
+
|
|
15
|
+
## [4.41.0] 2022-03-25
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- [TD-4535] Structures domains CSV upload bulk update
|
|
20
|
+
|
|
3
21
|
## [4.40.14] 2022-03-22
|
|
4
22
|
|
|
5
23
|
### Added
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truedat/dd",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.41.2",
|
|
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.2",
|
|
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.2",
|
|
88
|
+
"@truedat/core": "4.41.2",
|
|
89
|
+
"@truedat/df": "4.41.2",
|
|
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": "de1e8cd9c744c0dae85be4585fccc1c50fdf6a07"
|
|
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,
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
2
|
import React, { useState } from "react";
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import {
|
|
4
|
+
Button,
|
|
5
|
+
Checkbox,
|
|
6
|
+
Container,
|
|
7
|
+
Form,
|
|
8
|
+
Header,
|
|
9
|
+
Segment,
|
|
10
|
+
} from "semantic-ui-react";
|
|
5
11
|
import { linkTo } from "@truedat/core/routes";
|
|
6
12
|
import PropTypes from "prop-types";
|
|
7
13
|
import { useIntl } from "react-intl";
|
|
8
14
|
import { connect } from "react-redux";
|
|
15
|
+
import { DomainMenuSelector } from "@truedat/bg/taxonomy/components/DomainMenuSelector";
|
|
16
|
+
import { getDomainSelectorOptions } from "@truedat/bg/taxonomy/selectors";
|
|
9
17
|
import { updateStructure } from "../routines";
|
|
10
18
|
|
|
11
19
|
export const EditDomainForm = ({
|
|
@@ -13,6 +21,7 @@ export const EditDomainForm = ({
|
|
|
13
21
|
title,
|
|
14
22
|
updateStructure,
|
|
15
23
|
structure,
|
|
24
|
+
domainOptions,
|
|
16
25
|
}) => {
|
|
17
26
|
const { formatMessage } = useIntl();
|
|
18
27
|
const [domainIds, setDomainIds] = useState(structure?.domain_ids || []);
|
|
@@ -32,26 +41,26 @@ export const EditDomainForm = ({
|
|
|
32
41
|
return (
|
|
33
42
|
<Container style={{ width: "400px" }}>
|
|
34
43
|
<Header as="h2" content={title} />
|
|
35
|
-
<DomainDropdownSelector
|
|
36
|
-
clearable={false}
|
|
37
|
-
multiple={true}
|
|
38
|
-
onChange={handleDomainSelected}
|
|
39
|
-
name="domain"
|
|
40
|
-
value={domainIds}
|
|
41
|
-
/>
|
|
42
|
-
|
|
43
|
-
<Checkbox
|
|
44
|
-
label={formatMessage({
|
|
45
|
-
id: "structureDomain.actions.update.inherit",
|
|
46
|
-
})}
|
|
47
|
-
checked={inherit}
|
|
48
|
-
onChange={(e) => {
|
|
49
|
-
setInherit(!inherit);
|
|
50
|
-
e.preventDefault();
|
|
51
|
-
}}
|
|
52
|
-
/>
|
|
53
44
|
|
|
54
45
|
<Form onSubmit={saving ? null : onSubmit}>
|
|
46
|
+
<Segment>
|
|
47
|
+
<DomainMenuSelector
|
|
48
|
+
domainOptions={domainOptions}
|
|
49
|
+
onChange={handleDomainSelected}
|
|
50
|
+
value={domainIds}
|
|
51
|
+
/>
|
|
52
|
+
</Segment>
|
|
53
|
+
|
|
54
|
+
<Checkbox
|
|
55
|
+
label={formatMessage({
|
|
56
|
+
id: "structureDomain.actions.update.inherit",
|
|
57
|
+
})}
|
|
58
|
+
checked={inherit}
|
|
59
|
+
onChange={(e) => {
|
|
60
|
+
setInherit(!inherit);
|
|
61
|
+
e.preventDefault();
|
|
62
|
+
}}
|
|
63
|
+
/>
|
|
55
64
|
<div className="actions">
|
|
56
65
|
<Button
|
|
57
66
|
type="submit"
|
|
@@ -71,15 +80,19 @@ export const EditDomainForm = ({
|
|
|
71
80
|
};
|
|
72
81
|
|
|
73
82
|
EditDomainForm.propTypes = {
|
|
83
|
+
domainOptions: PropTypes.array,
|
|
74
84
|
structure: PropTypes.object,
|
|
75
85
|
updateStructure: PropTypes.func,
|
|
76
86
|
title: PropTypes.string,
|
|
77
87
|
saving: PropTypes.bool,
|
|
78
88
|
};
|
|
79
89
|
|
|
80
|
-
const mapStateToProps = (state) =>
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
90
|
+
const mapStateToProps = (state) => {
|
|
91
|
+
return {
|
|
92
|
+
structure: _.pick(["id", "domain_ids"])(state.structure),
|
|
93
|
+
saving: state.structureUpdating,
|
|
94
|
+
domainOptions: getDomainSelectorOptions(state),
|
|
95
|
+
};
|
|
96
|
+
};
|
|
84
97
|
|
|
85
98
|
export default connect(mapStateToProps, { updateStructure })(EditDomainForm);
|
|
@@ -0,0 +1,54 @@
|
|
|
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({
|
|
22
|
+
id: "structures.actions.uploadDomains.tooltip",
|
|
23
|
+
})}
|
|
24
|
+
disabled={loading}
|
|
25
|
+
/>
|
|
26
|
+
}
|
|
27
|
+
header={formatMessage({
|
|
28
|
+
id: "structures.actions.uploadDomains.confirmation.header",
|
|
29
|
+
})}
|
|
30
|
+
content={formatMessage({
|
|
31
|
+
id: "structures.actions.uploadDomains.confirmation.content",
|
|
32
|
+
})}
|
|
33
|
+
param={"structures_domains"}
|
|
34
|
+
handleSubmit={(data) =>
|
|
35
|
+
uploadStructuresDomains({
|
|
36
|
+
data,
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
/>
|
|
40
|
+
);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
StructuresDomainsUploadOption.propTypes = {
|
|
44
|
+
uploadStructuresDomains: PropTypes.func,
|
|
45
|
+
loading: PropTypes.bool,
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const mapStateToProps = ({ uploadingStructuresDomainsFile }) => ({
|
|
49
|
+
loading: uploadingStructuresDomainsFile,
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
export default connect(mapStateToProps, { uploadStructuresDomains })(
|
|
53
|
+
StructuresDomainsUploadOption
|
|
54
|
+
);
|
|
@@ -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
|
|
|
@@ -20,6 +20,7 @@ describe("<EditDomainForm />", () => {
|
|
|
20
20
|
title: "title",
|
|
21
21
|
updateStructure,
|
|
22
22
|
structure,
|
|
23
|
+
domainOptions: domains,
|
|
23
24
|
};
|
|
24
25
|
|
|
25
26
|
const messages = {
|
|
@@ -29,6 +30,7 @@ describe("<EditDomainForm />", () => {
|
|
|
29
30
|
"structureDomain.actions.update.inherit": "Apply on children",
|
|
30
31
|
"domain.selector.label": "Domain",
|
|
31
32
|
"domain.selector.placeholder": "Select a domain...",
|
|
33
|
+
"domain.multiple.placeholder": "Select domains ...",
|
|
32
34
|
},
|
|
33
35
|
};
|
|
34
36
|
|
|
@@ -10,7 +10,12 @@ const renderOpts = {
|
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
describe("<StructuresOptions />", () => {
|
|
13
|
-
const props = {
|
|
13
|
+
const props = {
|
|
14
|
+
bulkUpload: {},
|
|
15
|
+
bulkUpdate: {},
|
|
16
|
+
bulkUploadDomains: {},
|
|
17
|
+
autoPublish: {},
|
|
18
|
+
};
|
|
14
19
|
|
|
15
20
|
it("matches the latest snapshot", async () => {
|
|
16
21
|
const { container } = render(<StructuresOptions {...props} />, renderOpts);
|
|
@@ -11,107 +11,96 @@ exports[`<EditDomainForm /> matches the latest snapshot 1`] = `
|
|
|
11
11
|
>
|
|
12
12
|
title
|
|
13
13
|
</h2>
|
|
14
|
-
<
|
|
15
|
-
class="
|
|
14
|
+
<form
|
|
15
|
+
class="ui form"
|
|
16
16
|
>
|
|
17
|
-
<label>
|
|
18
|
-
Domain
|
|
19
|
-
</label>
|
|
20
17
|
<div
|
|
21
|
-
class="
|
|
18
|
+
class="ui segment"
|
|
22
19
|
>
|
|
23
20
|
<div
|
|
24
|
-
|
|
25
|
-
class="ui fluid multiple search selection dropdown"
|
|
26
|
-
name="domain"
|
|
27
|
-
role="combobox"
|
|
21
|
+
class="field"
|
|
28
22
|
>
|
|
29
|
-
<input
|
|
30
|
-
aria-autocomplete="list"
|
|
31
|
-
autocomplete="off"
|
|
32
|
-
class="search"
|
|
33
|
-
tabindex="0"
|
|
34
|
-
type="text"
|
|
35
|
-
value=""
|
|
36
|
-
/>
|
|
37
|
-
<span
|
|
38
|
-
class="sizer"
|
|
39
|
-
/>
|
|
40
|
-
<div
|
|
41
|
-
aria-atomic="true"
|
|
42
|
-
aria-live="polite"
|
|
43
|
-
class="divider default text"
|
|
44
|
-
role="alert"
|
|
45
|
-
>
|
|
46
|
-
Select a domain...
|
|
47
|
-
</div>
|
|
48
|
-
<i
|
|
49
|
-
aria-hidden="true"
|
|
50
|
-
class="dropdown icon"
|
|
51
|
-
/>
|
|
52
23
|
<div
|
|
24
|
+
aria-expanded="false"
|
|
53
25
|
aria-multiselectable="true"
|
|
54
|
-
class="
|
|
26
|
+
class="ui floating multiple dropdown"
|
|
55
27
|
role="listbox"
|
|
28
|
+
tabindex="0"
|
|
56
29
|
>
|
|
30
|
+
<label>
|
|
31
|
+
Select domains ...
|
|
32
|
+
</label>
|
|
33
|
+
<i
|
|
34
|
+
aria-hidden="true"
|
|
35
|
+
class="dropdown icon"
|
|
36
|
+
/>
|
|
57
37
|
<div
|
|
58
|
-
|
|
59
|
-
aria-selected="true"
|
|
60
|
-
class="selected item"
|
|
61
|
-
role="option"
|
|
62
|
-
style="pointer-events: all;"
|
|
38
|
+
class="menu transition"
|
|
63
39
|
>
|
|
64
40
|
<div
|
|
65
|
-
class="
|
|
66
|
-
style="margin-left: 0px;"
|
|
41
|
+
class="ui left icon input search"
|
|
67
42
|
>
|
|
43
|
+
<input
|
|
44
|
+
type="text"
|
|
45
|
+
/>
|
|
68
46
|
<i
|
|
69
47
|
aria-hidden="true"
|
|
70
|
-
class="icon"
|
|
48
|
+
class="search icon"
|
|
71
49
|
/>
|
|
72
|
-
Domain 1
|
|
73
50
|
</div>
|
|
74
|
-
</div>
|
|
75
|
-
<div
|
|
76
|
-
aria-checked="false"
|
|
77
|
-
aria-selected="false"
|
|
78
|
-
class="item"
|
|
79
|
-
role="option"
|
|
80
|
-
style="pointer-events: all;"
|
|
81
|
-
>
|
|
82
51
|
<div
|
|
83
|
-
class="
|
|
84
|
-
style="margin-left: 0px;"
|
|
52
|
+
class="scrolling menu transition"
|
|
85
53
|
>
|
|
86
|
-
<
|
|
87
|
-
aria-
|
|
88
|
-
class="
|
|
89
|
-
|
|
90
|
-
|
|
54
|
+
<div
|
|
55
|
+
aria-selected="false"
|
|
56
|
+
class="item"
|
|
57
|
+
role="option"
|
|
58
|
+
>
|
|
59
|
+
<div
|
|
60
|
+
style="margin-left: 0px;"
|
|
61
|
+
>
|
|
62
|
+
<i
|
|
63
|
+
aria-hidden="true"
|
|
64
|
+
class="icon"
|
|
65
|
+
/>
|
|
66
|
+
Domain 1
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
<div
|
|
70
|
+
aria-selected="false"
|
|
71
|
+
class="item"
|
|
72
|
+
role="option"
|
|
73
|
+
>
|
|
74
|
+
<div
|
|
75
|
+
style="margin-left: 0px;"
|
|
76
|
+
>
|
|
77
|
+
<i
|
|
78
|
+
aria-hidden="true"
|
|
79
|
+
class="icon"
|
|
80
|
+
/>
|
|
81
|
+
Domain 2
|
|
82
|
+
</div>
|
|
83
|
+
</div>
|
|
91
84
|
</div>
|
|
92
85
|
</div>
|
|
93
86
|
</div>
|
|
94
87
|
</div>
|
|
95
88
|
</div>
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
</
|
|
111
|
-
</div>
|
|
112
|
-
<form
|
|
113
|
-
class="ui form"
|
|
114
|
-
>
|
|
89
|
+
<div
|
|
90
|
+
class="ui checked checkbox"
|
|
91
|
+
>
|
|
92
|
+
<input
|
|
93
|
+
checked=""
|
|
94
|
+
class="hidden"
|
|
95
|
+
readonly=""
|
|
96
|
+
tabindex="0"
|
|
97
|
+
type="checkbox"
|
|
98
|
+
value=""
|
|
99
|
+
/>
|
|
100
|
+
<label>
|
|
101
|
+
Apply on children
|
|
102
|
+
</label>
|
|
103
|
+
</div>
|
|
115
104
|
<div
|
|
116
105
|
class="actions"
|
|
117
106
|
>
|
|
@@ -68,6 +68,20 @@ exports[`<StructuresOptions /> matches the latest snapshot 1`] = `
|
|
|
68
68
|
Upload structure notes
|
|
69
69
|
</span>
|
|
70
70
|
</div>
|
|
71
|
+
<div
|
|
72
|
+
class="item"
|
|
73
|
+
role="option"
|
|
74
|
+
>
|
|
75
|
+
<i
|
|
76
|
+
aria-hidden="true"
|
|
77
|
+
class="upload icon"
|
|
78
|
+
/>
|
|
79
|
+
<span
|
|
80
|
+
class="text"
|
|
81
|
+
>
|
|
82
|
+
Update structure domains
|
|
83
|
+
</span>
|
|
84
|
+
</div>
|
|
71
85
|
<div
|
|
72
86
|
class="divider"
|
|
73
87
|
/>
|
package/src/messages/en.js
CHANGED
|
@@ -371,9 +371,13 @@ export default {
|
|
|
371
371
|
"structures.actions.new_system": "New system",
|
|
372
372
|
"structures.actions.upload": "Upload file",
|
|
373
373
|
"structures.actions.upload.confirmation.content": "Notes",
|
|
374
|
+
"structures.actions.uploadDomains.confirmation.content": "Structure domains",
|
|
374
375
|
"structures.actions.upload.confirmation.header":
|
|
375
376
|
"Upload notes file of structures",
|
|
377
|
+
"structures.actions.uploadDomains.confirmation.header":
|
|
378
|
+
"Upload structures domains file",
|
|
376
379
|
"structures.actions.upload.tooltip": "Upload structure notes",
|
|
380
|
+
"structures.actions.uploadDomains.tooltip": "Update structure domains",
|
|
377
381
|
"structures.bulkUpdate.crumbs.top": "Bulk update",
|
|
378
382
|
"structures.bulkUpdate.success.content":
|
|
379
383
|
"Updated {count} structures successfully",
|
|
@@ -391,12 +395,25 @@ export default {
|
|
|
391
395
|
"Bulk update completed. Loaded {count_ids} errors {count_errors}",
|
|
392
396
|
"structures.bulkUpdateStructures.success.errors":
|
|
393
397
|
"Error in external id {externalId}, message: {message}",
|
|
398
|
+
"structures.bulkUploadStructuresDomains.success.errors.domain: not_exist":
|
|
399
|
+
"Error in line {row}, in external id {externalId}, domain does not exist",
|
|
400
|
+
"structures.bulkUploadStructuresDomains.success.errors.update_domain: forbbiden":
|
|
401
|
+
"Error in line {row}, in external id {externalId}, update forbbiden",
|
|
402
|
+
"structures.bulkUploadStructuresDomains.success.errors.domain_ids: must be a non-empty list":
|
|
403
|
+
"Error in line {row}, in external id {externalId}, domain_ids must be a non-empty list",
|
|
404
|
+
"structures.bulkUploadStructuresDomains.success.errors.structure: not_exist":
|
|
405
|
+
"Error in line {row}, in external id {externalId}, data structure does not exist",
|
|
394
406
|
"structures.bulkUploadStructures.success.errors":
|
|
395
407
|
"Error in line {row}, in external id {externalId}, message: {message}",
|
|
408
|
+
"structures.bulkUploadStructuresDomains.success.errors":
|
|
409
|
+
"Error in line {row}, in external id {externalId}, message: {message}",
|
|
396
410
|
"structures.bulkUpdateStructures.success.unchanged":
|
|
397
411
|
"{unchanged} structures remained unchanged.",
|
|
398
412
|
"structures.bulkUpdateStructures.success.updated":
|
|
399
413
|
"Updated {changed} structures successfully.",
|
|
414
|
+
"structures.bulkUploadStructuresDomains.success.header":
|
|
415
|
+
"Bulk update completed. Loaded {count_ids} errors {count_errors}",
|
|
416
|
+
|
|
400
417
|
"structures.crumbs.top": "Structures",
|
|
401
418
|
"structures.edit.bulk.confirmation.content":
|
|
402
419
|
"{structures_count} structures will be updated. Are you sure?",
|
|
@@ -445,6 +462,7 @@ export default {
|
|
|
445
462
|
"structures.uploadStructures.failed.external_id_not_exist":
|
|
446
463
|
"Invalid External Id",
|
|
447
464
|
"structures.uploadStructures.failed.header": "Upload Failed!",
|
|
465
|
+
"structures.uploadStructuresDomains.failed.header": "Upload Failed!",
|
|
448
466
|
"structures.uploadStructures.failed.invalid_file_format":
|
|
449
467
|
"Invalid file format",
|
|
450
468
|
"structures.uploadStructures.failed.note.df_content.default":
|
package/src/messages/es.js
CHANGED
|
@@ -375,9 +375,15 @@ export default {
|
|
|
375
375
|
"structures.actions.new_system": "Nuevo sistema",
|
|
376
376
|
"structures.actions.upload": "Subir fichero",
|
|
377
377
|
"structures.actions.upload.confirmation.content": "Notas",
|
|
378
|
+
"structures.actions.uploadDomains.confirmation.content":
|
|
379
|
+
"Dominios de estructuras",
|
|
378
380
|
"structures.actions.upload.confirmation.header":
|
|
379
381
|
"Subir fichero de notas de estructuras",
|
|
382
|
+
"structures.actions.uploadDomains.confirmation.header":
|
|
383
|
+
"Subir fichero de dominios de estructuras",
|
|
380
384
|
"structures.actions.upload.tooltip": "Subir notas de estructuras",
|
|
385
|
+
"structures.actions.uploadDomains.tooltip":
|
|
386
|
+
"Actualizar dominios de estructuras",
|
|
381
387
|
"structures.bulkUpdate.crumbs.top": "Actualización masiva",
|
|
382
388
|
"structures.bulkUpdate.success.content":
|
|
383
389
|
"Se han actualizado {count} estructuras",
|
|
@@ -395,12 +401,24 @@ export default {
|
|
|
395
401
|
"¡Actualización finalizada! subidos {count_ids} errores {count_errors}",
|
|
396
402
|
"structures.bulkUpdateStructures.success.errors":
|
|
397
403
|
"Error en external id {externalId}, mensaje: {message}",
|
|
404
|
+
"structures.bulkUploadStructuresDomains.success.errors.domain: not_exist":
|
|
405
|
+
"Error en linea {row}, en external id {externalId}, el dominio no existe",
|
|
406
|
+
"structures.bulkUploadStructuresDomains.success.errors.structure: not_exist":
|
|
407
|
+
"Error en linea {row}, en external id {externalId}, la estructura no existe",
|
|
408
|
+
"structures.bulkUploadStructuresDomains.success.errors.update_domain: forbbiden":
|
|
409
|
+
"Error en linea {row}, en external id {externalId}, no tiene permisos para actualizar",
|
|
410
|
+
"structures.bulkUploadStructuresDomains.success.errors.domain_ids: must be a non-empty list":
|
|
411
|
+
"Error en linea {row}, en external id {externalId}, domain_ids no puede ser una lista vacia",
|
|
398
412
|
"structures.bulkUploadStructures.success.errors":
|
|
399
413
|
"Error en linea {row}, en external id {externalId} mensaje: {message}",
|
|
414
|
+
"structures.bulkUploadStructuresDomains.success.errors":
|
|
415
|
+
"Error en linea {row}, en external id {externalId} mensaje: {message}",
|
|
400
416
|
"structures.bulkUpdateStructures.success.unchanged":
|
|
401
417
|
"{unchanged} se han mantenido sin cambios.",
|
|
402
418
|
"structures.bulkUpdateStructures.success.updated":
|
|
403
419
|
"Se han actualizado {changed} estructuras.",
|
|
420
|
+
"structures.bulkUploadStructuresDomains.success.header":
|
|
421
|
+
"¡Actualización finalizada! subidos {count_ids} errores {count_errors}",
|
|
404
422
|
"structures.crumbs.top": "Estructuras",
|
|
405
423
|
"structures.edit.bulk.confirmation.content":
|
|
406
424
|
"Se van a actualizar {structures_count} estructuras. ¿Estás seguro?",
|
|
@@ -453,6 +471,8 @@ export default {
|
|
|
453
471
|
"External Id Inválido",
|
|
454
472
|
"structures.uploadStructures.failed.header":
|
|
455
473
|
"Error al subir el fichero. El contenido no se ha actualizado",
|
|
474
|
+
"structures.uploadStructuresDomains.failed.header":
|
|
475
|
+
"Error al subir el fichero. El contenido no se ha actualizado",
|
|
456
476
|
"structures.uploadStructures.failed.invalid_file_format":
|
|
457
477
|
"Formato de fichero inválido",
|
|
458
478
|
"structures.uploadStructures.failed.note.df_content.default":
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { uploadStructuresDomains } from "../../routines";
|
|
2
|
+
import { ddMessage } from "..";
|
|
3
|
+
|
|
4
|
+
const fooState = { foo: "bar" };
|
|
5
|
+
|
|
6
|
+
describe("reducers: ddMessage", () => {
|
|
7
|
+
const initialState = null;
|
|
8
|
+
|
|
9
|
+
it("should provide the initial state", () => {
|
|
10
|
+
expect(ddMessage(undefined, {})).toEqual(initialState);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it("should handle the uploadStructuresDomains.SUCCESS action returning some errored rows", () => {
|
|
14
|
+
const ddMsg = ddMessage(fooState, {
|
|
15
|
+
type: uploadStructuresDomains.SUCCESS,
|
|
16
|
+
payload: {
|
|
17
|
+
data: {
|
|
18
|
+
errors: [
|
|
19
|
+
{
|
|
20
|
+
external_id:
|
|
21
|
+
"postgres://Postgres-Test/postgres/public/city/city_id",
|
|
22
|
+
message: {
|
|
23
|
+
external_domain_ids: ["must exist: UEUEUEU"],
|
|
24
|
+
},
|
|
25
|
+
row: 3,
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
external_id:
|
|
29
|
+
"postgres://Postgres-Test/postgres/public/city/city_name",
|
|
30
|
+
message: {
|
|
31
|
+
external_domain_ids: ["must exist: NANDAKA, JAJAJA"],
|
|
32
|
+
},
|
|
33
|
+
row: 4,
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
ids: [5375339],
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
expect(ddMsg).toMatchObject({
|
|
42
|
+
error: false,
|
|
43
|
+
header: "structures.bulkUploadStructuresDomains.success.header",
|
|
44
|
+
icon: "check",
|
|
45
|
+
color: "orange",
|
|
46
|
+
fields: { count_errors: 2, count_ids: 1 },
|
|
47
|
+
});
|
|
48
|
+
const { messages: errors } = ddMsg;
|
|
49
|
+
expect(errors.length).toEqual(2);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it("should handle the uploadStructuresDomains.FAILURE action", () => {
|
|
53
|
+
const ddMsg = ddMessage(fooState, {
|
|
54
|
+
type: uploadStructuresDomains.FAILURE,
|
|
55
|
+
payload: {
|
|
56
|
+
status: 422,
|
|
57
|
+
data: {
|
|
58
|
+
error: {
|
|
59
|
+
message:
|
|
60
|
+
"invalid_headers, must be: external_id, domain_external_ids",
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
expect(ddMsg).toMatchObject({
|
|
67
|
+
error: true,
|
|
68
|
+
header: "structures.uploadStructuresDomains.failed.header",
|
|
69
|
+
icon: "attention",
|
|
70
|
+
content: "invalid_headers, must be: external_id, domain_external_ids",
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
});
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
bulkUpdateStructures,
|
|
5
5
|
uploadStructures,
|
|
6
6
|
updateStructureType,
|
|
7
|
+
uploadStructuresDomains,
|
|
7
8
|
} from "../routines";
|
|
8
9
|
|
|
9
10
|
const initialState = null;
|
|
@@ -18,10 +19,7 @@ const ddMessage = (state = initialState, { type, payload }) => {
|
|
|
18
19
|
? _.flow(
|
|
19
20
|
_.propOr([], "errors"),
|
|
20
21
|
_.map((error) => ({
|
|
21
|
-
id:
|
|
22
|
-
type == bulkUpdateStructures.SUCCESS
|
|
23
|
-
? `structures.bulkUpdateStructures.failed.note.${error.message}`
|
|
24
|
-
: `structures.uploadStructures.failed.note.${error.message}`,
|
|
22
|
+
id: `structures.bulkUpdateStructures.failed.note.${error.message}`,
|
|
25
23
|
fields: {
|
|
26
24
|
row: error.row,
|
|
27
25
|
id: error.id,
|
|
@@ -29,10 +27,7 @@ const ddMessage = (state = initialState, { type, payload }) => {
|
|
|
29
27
|
externalId: error.external_id,
|
|
30
28
|
message: error.message,
|
|
31
29
|
},
|
|
32
|
-
defaultMessage:
|
|
33
|
-
type == bulkUpdateStructures.SUCCESS
|
|
34
|
-
? "structures.bulkUpdateStructures.success.errors"
|
|
35
|
-
: "structures.bulkUploadStructures.success.errors",
|
|
30
|
+
defaultMessage: "structures.bulkUploadStructures.success.errors",
|
|
36
31
|
}))
|
|
37
32
|
)(payload.data)
|
|
38
33
|
: "";
|
|
@@ -51,6 +46,55 @@ const ddMessage = (state = initialState, { type, payload }) => {
|
|
|
51
46
|
initialMaxListItems: 5,
|
|
52
47
|
};
|
|
53
48
|
}
|
|
49
|
+
|
|
50
|
+
case uploadStructuresDomains.SUCCESS: {
|
|
51
|
+
const messagesImp = _.has("errors")(payload.data)
|
|
52
|
+
? _.flow(
|
|
53
|
+
_.propOr([], "errors"),
|
|
54
|
+
_.map((error) => {
|
|
55
|
+
const errorMessage = Object.entries(error.message)
|
|
56
|
+
.map(([field, messages]) => `${field}: ${messages.join(", ")}`)
|
|
57
|
+
.join(" | ");
|
|
58
|
+
return {
|
|
59
|
+
id: `structures.bulkUploadStructuresDomains.success.errors.${errorMessage}`,
|
|
60
|
+
fields: {
|
|
61
|
+
row: error.row,
|
|
62
|
+
id: error.id,
|
|
63
|
+
field: error.field,
|
|
64
|
+
externalId: error.external_id,
|
|
65
|
+
message: errorMessage,
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
})
|
|
69
|
+
)(payload.data)
|
|
70
|
+
: "";
|
|
71
|
+
return {
|
|
72
|
+
error: false,
|
|
73
|
+
header: "structures.bulkUploadStructuresDomains.success.header",
|
|
74
|
+
icon: "check",
|
|
75
|
+
color: payload.data.errors.length >= 1 ? "orange" : "green",
|
|
76
|
+
text: "",
|
|
77
|
+
messages: messagesImp,
|
|
78
|
+
fields: {
|
|
79
|
+
count_ids: payload.data.ids.length,
|
|
80
|
+
count_errors: payload.data.errors.length,
|
|
81
|
+
},
|
|
82
|
+
downloadable: true,
|
|
83
|
+
initialMaxListItems: 5,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
case uploadStructuresDomains.FAILURE:
|
|
88
|
+
return payload.status !== 422
|
|
89
|
+
? state
|
|
90
|
+
: {
|
|
91
|
+
error: true,
|
|
92
|
+
header: "structures.uploadStructuresDomains.failed.header",
|
|
93
|
+
icon: "attention",
|
|
94
|
+
content: payload?.data?.error?.message,
|
|
95
|
+
initialMaxListItems: 5,
|
|
96
|
+
};
|
|
97
|
+
|
|
54
98
|
case updateStructureType.SUCCESS:
|
|
55
99
|
return {
|
|
56
100
|
error: false,
|
package/src/routines.js
CHANGED
|
@@ -132,6 +132,9 @@ export const updateStructureTag = createRoutine("UPDATE_STRUCTURE_TAG");
|
|
|
132
132
|
export const updateStructureType = createRoutine("UPDATE_STRUCTURE_TYPE");
|
|
133
133
|
export const updateSystem = createRoutine("UPDATE_SYSTEM");
|
|
134
134
|
export const uploadStructures = createRoutine("UPLOAD_STRUCTURES");
|
|
135
|
+
export const uploadStructuresDomains = createRoutine(
|
|
136
|
+
"UPLOAD_STRUCTURES_DOMAINS"
|
|
137
|
+
);
|
|
135
138
|
export const addGrantRequestToCart = createRoutine("ADD_GRANT_REQUEST_TO_CART");
|
|
136
139
|
export const removeGrantRequestFromCart = createRoutine(
|
|
137
140
|
"REMOVE_GRANT_REQUEST_FROM_CART"
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { testSaga } from "redux-saga-test-plan";
|
|
2
|
+
import { apiJsonPost, UPLOAD_JSON_OPTS } from "@truedat/core/services/api";
|
|
3
|
+
import {
|
|
4
|
+
uploadStructuresDomainsRequestSaga,
|
|
5
|
+
uploadStructuresDomainsSaga,
|
|
6
|
+
} from "../uploadStructuresDomains";
|
|
7
|
+
import { uploadStructuresDomains } from "../../routines";
|
|
8
|
+
import { API_STRUCTURES_DOMAINS_UPLOAD } from "../../api";
|
|
9
|
+
|
|
10
|
+
describe("sagas: uploadStructuresDomainsRequestSaga", () => {
|
|
11
|
+
it("should invoke uploadStructuresDomainsSaga on trigger", () => {
|
|
12
|
+
expect(() => {
|
|
13
|
+
testSaga(uploadStructuresDomainsRequestSaga)
|
|
14
|
+
.next()
|
|
15
|
+
.takeLatest(
|
|
16
|
+
uploadStructuresDomains.TRIGGER,
|
|
17
|
+
uploadStructuresDomainsSaga
|
|
18
|
+
)
|
|
19
|
+
.finish()
|
|
20
|
+
.isDone();
|
|
21
|
+
}).not.toThrow();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("should throw exception if an unhandled action is received", () => {
|
|
25
|
+
expect(() => {
|
|
26
|
+
testSaga(uploadStructuresDomainsRequestSaga)
|
|
27
|
+
.next()
|
|
28
|
+
.takeLatest("FOO", uploadStructuresDomainsSaga);
|
|
29
|
+
}).toThrow();
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
describe("sagas: uploadStructuresDomainsSaga", () => {
|
|
34
|
+
const body = { structures_domains: "content" };
|
|
35
|
+
const payload = { data: body };
|
|
36
|
+
const data = { message: [1, 2] };
|
|
37
|
+
it("should put a success action when a response is returned", () => {
|
|
38
|
+
expect(() => {
|
|
39
|
+
testSaga(uploadStructuresDomainsSaga, { payload })
|
|
40
|
+
.next()
|
|
41
|
+
.put(uploadStructuresDomains.request())
|
|
42
|
+
.next()
|
|
43
|
+
.call(
|
|
44
|
+
apiJsonPost,
|
|
45
|
+
API_STRUCTURES_DOMAINS_UPLOAD,
|
|
46
|
+
body,
|
|
47
|
+
UPLOAD_JSON_OPTS
|
|
48
|
+
)
|
|
49
|
+
.next({ data })
|
|
50
|
+
.put(uploadStructuresDomains.success({ data }))
|
|
51
|
+
.next()
|
|
52
|
+
.put(uploadStructuresDomains.fulfill())
|
|
53
|
+
.next()
|
|
54
|
+
.isDone();
|
|
55
|
+
}).not.toThrow();
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it("should put a failure action when the call returns an error", () => {
|
|
59
|
+
const message = "Request failed";
|
|
60
|
+
const error = { message };
|
|
61
|
+
|
|
62
|
+
expect(() => {
|
|
63
|
+
testSaga(uploadStructuresDomainsSaga, { payload })
|
|
64
|
+
.next()
|
|
65
|
+
.put(uploadStructuresDomains.request())
|
|
66
|
+
.next()
|
|
67
|
+
.call(
|
|
68
|
+
apiJsonPost,
|
|
69
|
+
API_STRUCTURES_DOMAINS_UPLOAD,
|
|
70
|
+
body,
|
|
71
|
+
UPLOAD_JSON_OPTS
|
|
72
|
+
)
|
|
73
|
+
.throw(error)
|
|
74
|
+
.put(uploadStructuresDomains.failure(message))
|
|
75
|
+
.next()
|
|
76
|
+
.put(uploadStructuresDomains.fulfill())
|
|
77
|
+
.next()
|
|
78
|
+
.isDone();
|
|
79
|
+
}).not.toThrow();
|
|
80
|
+
});
|
|
81
|
+
});
|
package/src/sagas/index.js
CHANGED
|
@@ -46,6 +46,7 @@ import { updateStructureTagRequestSaga } from "./updateStructureTag";
|
|
|
46
46
|
import { updateStructureTypeRequestSaga } from "./updateStructureType";
|
|
47
47
|
import { updateSystemRequestSaga } from "./updateSystem";
|
|
48
48
|
import { uploadStructuresRequestSaga } from "./uploadStructures";
|
|
49
|
+
import { uploadStructuresDomainsRequestSaga } from "./uploadStructuresDomains";
|
|
49
50
|
import { operateGrantRequestToCartRequestSaga } from "./operateGrantRequestCart";
|
|
50
51
|
|
|
51
52
|
export {
|
|
@@ -97,6 +98,7 @@ export {
|
|
|
97
98
|
updateStructureTypeRequestSaga,
|
|
98
99
|
updateSystemRequestSaga,
|
|
99
100
|
uploadStructuresRequestSaga,
|
|
101
|
+
uploadStructuresDomainsRequestSaga,
|
|
100
102
|
operateGrantRequestToCartRequestSaga,
|
|
101
103
|
};
|
|
102
104
|
|
|
@@ -149,5 +151,6 @@ export default [
|
|
|
149
151
|
updateStructureTypeRequestSaga(),
|
|
150
152
|
updateSystemRequestSaga(),
|
|
151
153
|
uploadStructuresRequestSaga(),
|
|
154
|
+
uploadStructuresDomainsRequestSaga(),
|
|
152
155
|
operateGrantRequestToCartRequestSaga(),
|
|
153
156
|
];
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { call, put, takeLatest } from "redux-saga/effects";
|
|
2
|
+
import { apiJsonPost, UPLOAD_JSON_OPTS } from "@truedat/core/services/api";
|
|
3
|
+
import { uploadStructuresDomains } from "../routines";
|
|
4
|
+
import { API_STRUCTURES_DOMAINS_UPLOAD } from "../api";
|
|
5
|
+
|
|
6
|
+
export function* uploadStructuresDomainsSaga({ payload }) {
|
|
7
|
+
try {
|
|
8
|
+
const { data: body } = payload;
|
|
9
|
+
yield put(uploadStructuresDomains.request());
|
|
10
|
+
const { data } = yield call(
|
|
11
|
+
apiJsonPost,
|
|
12
|
+
API_STRUCTURES_DOMAINS_UPLOAD,
|
|
13
|
+
body,
|
|
14
|
+
UPLOAD_JSON_OPTS
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
yield put(uploadStructuresDomains.success({ data }));
|
|
18
|
+
} catch (error) {
|
|
19
|
+
if (error.response) {
|
|
20
|
+
const { status, data } = error.response;
|
|
21
|
+
yield put(uploadStructuresDomains.failure({ status, data }));
|
|
22
|
+
} else {
|
|
23
|
+
yield put(uploadStructuresDomains.failure(error.message));
|
|
24
|
+
}
|
|
25
|
+
} finally {
|
|
26
|
+
yield put(uploadStructuresDomains.fulfill());
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function* uploadStructuresDomainsRequestSaga() {
|
|
31
|
+
yield takeLatest(
|
|
32
|
+
uploadStructuresDomains.TRIGGER,
|
|
33
|
+
uploadStructuresDomainsSaga
|
|
34
|
+
);
|
|
35
|
+
}
|