@truedat/dq 4.34.0 → 4.35.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 +19 -0
- package/package.json +4 -4
- package/src/api.js +7 -1
- package/src/components/ImplementationsUploadButton.js +61 -0
- package/src/components/RuleImplementationsActions.js +3 -59
- package/src/components/RuleImplementationsDownload.js +86 -0
- package/src/components/RuleImplementationsOptions.js +28 -0
- package/src/components/RuleResultsUpload.js +47 -0
- package/src/components/RulesActions.js +17 -10
- package/src/components/RulesUploadButton.js +58 -0
- package/src/components/__tests__/RuleImplementationsActions.spec.js +0 -9
- package/src/components/__tests__/RuleImplementationsOptions.spec.js +18 -0
- package/src/components/__tests__/RuleResultsUpload.spec.js +18 -0
- package/src/components/__tests__/__snapshots__/RuleImplementationsActions.spec.js.snap +1 -7
- package/src/components/__tests__/__snapshots__/RuleImplementationsOptions.spec.js.snap +58 -0
- package/src/components/__tests__/__snapshots__/RuleResultsUpload.spec.js.snap +18 -0
- package/src/components/ruleImplementationForm/FiltersGroup.js +1 -0
- package/src/components/ruleImplementationForm/ValueConditions.js +11 -0
- package/src/messages/en.js +38 -6
- package/src/messages/es.js +41 -7
- package/src/reducers/__tests__/uploadingResults.spec.js +28 -0
- package/src/reducers/dqMessage.js +121 -1
- package/src/reducers/index.js +6 -0
- package/src/reducers/ruleImplementationRedirect.js +6 -1
- package/src/reducers/ruleRedirect.js +5 -0
- package/src/reducers/uploadImplementationsFile.js +28 -0
- package/src/reducers/uploadRulesFile.js +25 -0
- package/src/reducers/uploadingResults.js +16 -0
- package/src/routines.js +3 -0
- package/src/sagas/__tests__/uploadResults.spec.js +65 -0
- package/src/sagas/index.js +9 -0
- package/src/sagas/uploadImplementations.js +28 -0
- package/src/sagas/uploadResults.js +32 -0
- package/src/sagas/uploadRules.js +28 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [4.35.2] 2021-12-20
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- [TD-4380] Allow modifier in operator filter
|
|
8
|
+
|
|
9
|
+
## [4.34.3] 2021-12-15
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- [TD-4273] Upload `RuleResults`
|
|
14
|
+
|
|
15
|
+
## [4.34.2] 2021-12-14
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- [TD-4314] Add BulkLoad for `rules`
|
|
20
|
+
- [TD-4301] Add BulkLoad for `implementations`
|
|
21
|
+
|
|
3
22
|
## [4.34.0] 2021-12-02
|
|
4
23
|
|
|
5
24
|
### Changed
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truedat/dq",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.35.3",
|
|
4
4
|
"description": "Truedat Web Data Quality Module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"jsnext:main": "src/index.js",
|
|
@@ -82,8 +82,8 @@
|
|
|
82
82
|
},
|
|
83
83
|
"dependencies": {
|
|
84
84
|
"@apollo/client": "^3.4.10",
|
|
85
|
-
"@truedat/core": "4.
|
|
86
|
-
"@truedat/df": "4.
|
|
85
|
+
"@truedat/core": "4.35.3",
|
|
86
|
+
"@truedat/df": "4.35.3",
|
|
87
87
|
"axios": "^0.19.2",
|
|
88
88
|
"graphql": "^15.5.3",
|
|
89
89
|
"path-to-regexp": "^1.7.0",
|
|
@@ -103,5 +103,5 @@
|
|
|
103
103
|
"react-dom": ">= 16.8.6 < 17",
|
|
104
104
|
"semantic-ui-react": ">= 0.88.2 < 2.1"
|
|
105
105
|
},
|
|
106
|
-
"gitHead": "
|
|
106
|
+
"gitHead": "10cfa24ea2c47fe56e640e16cecaa51f302aaad3"
|
|
107
107
|
}
|
package/src/api.js
CHANGED
|
@@ -4,6 +4,7 @@ const API_EXECUTION_GROUPS = "/api/execution_groups";
|
|
|
4
4
|
const API_RULE = "/api/rules/:id";
|
|
5
5
|
const API_RULES = "/api/rules";
|
|
6
6
|
const API_RULES_SEARCH = "/api/rules/search";
|
|
7
|
+
const API_RULES_UPLOAD = "/api/rules/upload";
|
|
7
8
|
const API_RULE_FILTERS_SEARCH = "/api/rule_filters/search";
|
|
8
9
|
const API_RULE_IMPLEMENTATION = "/api/rule_implementations/:id";
|
|
9
10
|
const API_RULE_IMPLEMENTATIONS = "/api/rule_implementations";
|
|
@@ -13,7 +14,9 @@ const API_RULE_IMPLEMENTATIONS_FROM_RULE =
|
|
|
13
14
|
const API_RULE_IMPLEMENTATIONS_SEARCH = "/api/rule_implementations/search";
|
|
14
15
|
const API_RULE_IMPLEMENTATION_FILTERS_SEARCH =
|
|
15
16
|
"/api/rule_implementation_filters/search";
|
|
17
|
+
const API_RULE_IMPLEMENTATIONS_UPLOAD = "/api/rule_implementations/upload";
|
|
16
18
|
const API_RULE_RESULT = "/api/rule_results/:id";
|
|
19
|
+
const API_RULE_RESULTS = "/api/rule_results";
|
|
17
20
|
const API_SUBSCRIPTIONS_SEARCH = "/api/subscriptions/user/me/search";
|
|
18
21
|
const API_SUBSCRIPTION = "/api/subscriptions/:id";
|
|
19
22
|
const API_SUBSCRIPTIONS = "/api/subscriptions";
|
|
@@ -25,6 +28,7 @@ export {
|
|
|
25
28
|
API_RULE,
|
|
26
29
|
API_RULES,
|
|
27
30
|
API_RULES_SEARCH,
|
|
31
|
+
API_RULES_UPLOAD,
|
|
28
32
|
API_RULE_FILTERS_SEARCH,
|
|
29
33
|
API_RULE_IMPLEMENTATION,
|
|
30
34
|
API_RULE_IMPLEMENTATIONS,
|
|
@@ -32,8 +36,10 @@ export {
|
|
|
32
36
|
API_RULE_IMPLEMENTATIONS_FROM_RULE,
|
|
33
37
|
API_RULE_IMPLEMENTATIONS_SEARCH,
|
|
34
38
|
API_RULE_IMPLEMENTATION_FILTERS_SEARCH,
|
|
39
|
+
API_RULE_IMPLEMENTATIONS_UPLOAD,
|
|
35
40
|
API_RULE_RESULT,
|
|
41
|
+
API_RULE_RESULTS,
|
|
36
42
|
API_SUBSCRIPTIONS_SEARCH,
|
|
37
43
|
API_SUBSCRIPTION,
|
|
38
|
-
API_SUBSCRIPTIONS
|
|
44
|
+
API_SUBSCRIPTIONS,
|
|
39
45
|
};
|
|
@@ -0,0 +1,61 @@
|
|
|
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 { FormattedMessage, useIntl } from "react-intl";
|
|
6
|
+
import { UploadModal } from "@truedat/core/components";
|
|
7
|
+
import { API_RULE_IMPLEMENTATIONS_UPLOAD } from "../api";
|
|
8
|
+
import { uploadImplementations } from "../routines";
|
|
9
|
+
|
|
10
|
+
const uploadAction = {
|
|
11
|
+
method: "POST",
|
|
12
|
+
href: API_RULE_IMPLEMENTATIONS_UPLOAD,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const ImplementationsUploadButton = ({
|
|
16
|
+
uploadImplementations,
|
|
17
|
+
loading,
|
|
18
|
+
}) => {
|
|
19
|
+
const { formatMessage } = useIntl();
|
|
20
|
+
return (
|
|
21
|
+
<UploadModal
|
|
22
|
+
icon="upload"
|
|
23
|
+
trigger={
|
|
24
|
+
<Dropdown.Item
|
|
25
|
+
icon="upload"
|
|
26
|
+
text={formatMessage({
|
|
27
|
+
id: "ruleImplementations.actions.upload.tooltip",
|
|
28
|
+
})}
|
|
29
|
+
disabled={loading}
|
|
30
|
+
/>
|
|
31
|
+
}
|
|
32
|
+
header={
|
|
33
|
+
<FormattedMessage id="ruleImplementations.actions.upload.confirmation.header" />
|
|
34
|
+
}
|
|
35
|
+
content={
|
|
36
|
+
<FormattedMessage id="ruleImplementations.actions.upload.confirmation.content" />
|
|
37
|
+
}
|
|
38
|
+
param={"implementations"}
|
|
39
|
+
handleSubmit={(data) =>
|
|
40
|
+
uploadImplementations({
|
|
41
|
+
action: "upload",
|
|
42
|
+
data,
|
|
43
|
+
...uploadAction,
|
|
44
|
+
})
|
|
45
|
+
}
|
|
46
|
+
/>
|
|
47
|
+
);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
ImplementationsUploadButton.propTypes = {
|
|
51
|
+
uploadImplementations: PropTypes.func,
|
|
52
|
+
loading: PropTypes.bool,
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const mapStateToProps = ({ uploadImplementationsFile: { loading } }) => ({
|
|
56
|
+
loading,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
export default connect(mapStateToProps, { uploadImplementations })(
|
|
60
|
+
ImplementationsUploadButton
|
|
61
|
+
);
|
|
@@ -2,9 +2,7 @@ import _ from "lodash/fp";
|
|
|
2
2
|
import React from "react";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
4
|
import { connect } from "react-redux";
|
|
5
|
-
import {
|
|
6
|
-
import { useIntl } from "react-intl";
|
|
7
|
-
import { downloadImplementations } from "../routines";
|
|
5
|
+
import { Checkbox } from "semantic-ui-react";
|
|
8
6
|
import { getImplementationsExecution } from "../selectors";
|
|
9
7
|
import {
|
|
10
8
|
addImplementationFilter,
|
|
@@ -13,35 +11,11 @@ import {
|
|
|
13
11
|
createExecutionGroup,
|
|
14
12
|
} from "../routines";
|
|
15
13
|
import ExecutionPopup from "./ExecutionPopup";
|
|
16
|
-
|
|
17
|
-
const staticHeaderLabels = [
|
|
18
|
-
"implementation_key",
|
|
19
|
-
"implementation_type",
|
|
20
|
-
"rule",
|
|
21
|
-
"template",
|
|
22
|
-
"goal",
|
|
23
|
-
"minimum",
|
|
24
|
-
"business_concept",
|
|
25
|
-
"last_execution_at",
|
|
26
|
-
"result",
|
|
27
|
-
"execution",
|
|
28
|
-
"inserted_at",
|
|
29
|
-
"executable",
|
|
30
|
-
];
|
|
31
|
-
|
|
32
|
-
const staticContentLabels = [
|
|
33
|
-
"quality_result.under_minimum",
|
|
34
|
-
"quality_result.under_goal",
|
|
35
|
-
"quality_result.over_goal",
|
|
36
|
-
"quality_result.no_execution",
|
|
37
|
-
"executable.true",
|
|
38
|
-
"executable.false",
|
|
39
|
-
];
|
|
14
|
+
import RuleImplementationsOptions from "./RuleImplementationsOptions";
|
|
40
15
|
|
|
41
16
|
export const RuleImplementationsActions = ({
|
|
42
17
|
addImplementationFilter,
|
|
43
18
|
canExecute,
|
|
44
|
-
downloadImplementations,
|
|
45
19
|
executeImplementationsOn,
|
|
46
20
|
toggleImplementationFilterValue,
|
|
47
21
|
removeImplementationFilter,
|
|
@@ -51,21 +25,8 @@ export const RuleImplementationsActions = ({
|
|
|
51
25
|
setMode,
|
|
52
26
|
implementationsExecution,
|
|
53
27
|
ruleImplementationCount,
|
|
54
|
-
ruleImplementationsDownloading,
|
|
55
28
|
ruleImplementationsLoading,
|
|
56
29
|
}) => {
|
|
57
|
-
const { formatMessage } = useIntl();
|
|
58
|
-
|
|
59
|
-
const headerLabels = _.flow(
|
|
60
|
-
_.map((l) => [l, formatMessage({ id: `ruleImplementations.props.${l}` })]),
|
|
61
|
-
_.fromPairs
|
|
62
|
-
)(staticHeaderLabels);
|
|
63
|
-
|
|
64
|
-
const contentLabels = _.flow(
|
|
65
|
-
_.map((l) => [l, formatMessage({ id: `ruleImplementations.props.${l}` })]),
|
|
66
|
-
_.fromPairs
|
|
67
|
-
)(staticContentLabels);
|
|
68
|
-
|
|
69
30
|
const showExecutableInfo = () => {
|
|
70
31
|
addImplementationFilter({ filter: "executable" });
|
|
71
32
|
toggleImplementationFilterValue({
|
|
@@ -112,27 +73,13 @@ export const RuleImplementationsActions = ({
|
|
|
112
73
|
/>
|
|
113
74
|
</>
|
|
114
75
|
)}
|
|
115
|
-
{
|
|
116
|
-
<Button
|
|
117
|
-
floated="right"
|
|
118
|
-
secondary
|
|
119
|
-
icon="download"
|
|
120
|
-
data-tooltip={formatMessage({
|
|
121
|
-
id: "implementations.actions.download.tooltip",
|
|
122
|
-
})}
|
|
123
|
-
onClick={() =>
|
|
124
|
-
downloadImplementations({ contentLabels, headerLabels })
|
|
125
|
-
}
|
|
126
|
-
loading={ruleImplementationsDownloading}
|
|
127
|
-
/>
|
|
128
|
-
)}
|
|
76
|
+
<RuleImplementationsOptions loading={ruleImplementationsLoading} />
|
|
129
77
|
</div>
|
|
130
78
|
);
|
|
131
79
|
};
|
|
132
80
|
|
|
133
81
|
RuleImplementationsActions.propTypes = {
|
|
134
82
|
addImplementationFilter: PropTypes.func,
|
|
135
|
-
downloadImplementations: PropTypes.func,
|
|
136
83
|
canExecute: PropTypes.bool,
|
|
137
84
|
createExecutionGroup: PropTypes.func,
|
|
138
85
|
executeImplementationsOn: PropTypes.bool,
|
|
@@ -143,7 +90,6 @@ RuleImplementationsActions.propTypes = {
|
|
|
143
90
|
selectedImplementations: PropTypes.array,
|
|
144
91
|
setMode: PropTypes.func,
|
|
145
92
|
toggleImplementationFilterValue: PropTypes.func,
|
|
146
|
-
ruleImplementationsDownloading: PropTypes.bool,
|
|
147
93
|
ruleImplementationsLoading: PropTypes.bool,
|
|
148
94
|
};
|
|
149
95
|
|
|
@@ -151,13 +97,11 @@ const mapStateToProps = (state) => ({
|
|
|
151
97
|
canExecute: _.propOr(false, "userImplementationsPermissions.execute")(state),
|
|
152
98
|
ruleImplementationCount: state.ruleImplementationCount,
|
|
153
99
|
implementationsExecution: getImplementationsExecution(state),
|
|
154
|
-
ruleImplementationsDownloading: state.ruleImplementationsDownloading,
|
|
155
100
|
ruleImplementationsLoading: state.ruleImplementationsLoading,
|
|
156
101
|
});
|
|
157
102
|
|
|
158
103
|
export default connect(mapStateToProps, {
|
|
159
104
|
addImplementationFilter,
|
|
160
|
-
downloadImplementations,
|
|
161
105
|
toggleImplementationFilterValue,
|
|
162
106
|
removeImplementationFilter,
|
|
163
107
|
createExecutionGroup,
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import PropTypes from "prop-types";
|
|
4
|
+
import { connect } from "react-redux";
|
|
5
|
+
import { Dropdown } from "semantic-ui-react";
|
|
6
|
+
import { useIntl } from "react-intl";
|
|
7
|
+
import { downloadImplementations } from "../routines";
|
|
8
|
+
|
|
9
|
+
const staticHeaderLabels = [
|
|
10
|
+
"implementation_key",
|
|
11
|
+
"implementation_type",
|
|
12
|
+
"rule",
|
|
13
|
+
"template",
|
|
14
|
+
"goal",
|
|
15
|
+
"minimum",
|
|
16
|
+
"business_concept",
|
|
17
|
+
"last_execution_at",
|
|
18
|
+
"result",
|
|
19
|
+
"execution",
|
|
20
|
+
"inserted_at",
|
|
21
|
+
"executable",
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
const staticContentLabels = [
|
|
25
|
+
"quality_result.under_minimum",
|
|
26
|
+
"quality_result.under_goal",
|
|
27
|
+
"quality_result.over_goal",
|
|
28
|
+
"quality_result.no_execution",
|
|
29
|
+
"executable.true",
|
|
30
|
+
"executable.false",
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
export const RuleImplementationsDownload = ({
|
|
34
|
+
downloadImplementations,
|
|
35
|
+
ruleImplementationsDownloading,
|
|
36
|
+
ruleImplementations,
|
|
37
|
+
}) => {
|
|
38
|
+
const { formatMessage } = useIntl();
|
|
39
|
+
|
|
40
|
+
const headerLabels = _.flow(
|
|
41
|
+
_.map((l) => [l, formatMessage({ id: `ruleImplementations.props.${l}` })]),
|
|
42
|
+
_.fromPairs
|
|
43
|
+
)(staticHeaderLabels);
|
|
44
|
+
|
|
45
|
+
const contentLabels = _.flow(
|
|
46
|
+
_.map((l) => [l, formatMessage({ id: `ruleImplementations.props.${l}` })]),
|
|
47
|
+
_.fromPairs
|
|
48
|
+
)(staticContentLabels);
|
|
49
|
+
|
|
50
|
+
const isDisabled = _.isEmpty(ruleImplementations);
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
<Dropdown.Item
|
|
54
|
+
icon="download"
|
|
55
|
+
content={
|
|
56
|
+
<>
|
|
57
|
+
<span>
|
|
58
|
+
{formatMessage({ id: "implementations.actions.download.tooltip" })}
|
|
59
|
+
</span>
|
|
60
|
+
{isDisabled && (
|
|
61
|
+
<p className="menu-item-description">
|
|
62
|
+
{formatMessage({ id: "implementations.actions.download.empty" })}
|
|
63
|
+
</p>
|
|
64
|
+
)}
|
|
65
|
+
</>
|
|
66
|
+
}
|
|
67
|
+
onClick={() => downloadImplementations({ contentLabels, headerLabels })}
|
|
68
|
+
disabled={isDisabled || ruleImplementationsDownloading}
|
|
69
|
+
/>
|
|
70
|
+
);
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
RuleImplementationsDownload.propTypes = {
|
|
74
|
+
downloadImplementations: PropTypes.func,
|
|
75
|
+
ruleImplementationsDownloading: PropTypes.bool,
|
|
76
|
+
ruleImplementations: PropTypes.array,
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const mapStateToProps = _.pick([
|
|
80
|
+
"ruleImplementationsDownloading",
|
|
81
|
+
"ruleImplementations",
|
|
82
|
+
]);
|
|
83
|
+
|
|
84
|
+
export default connect(mapStateToProps, {
|
|
85
|
+
downloadImplementations,
|
|
86
|
+
})(RuleImplementationsDownload);
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
import { Dropdown } from "semantic-ui-react";
|
|
4
|
+
import RuleImplementationsDownload from "./RuleImplementationsDownload";
|
|
5
|
+
import RuleResultsUpload from "./RuleResultsUpload";
|
|
6
|
+
import ImplementationsUploadButton from "./ImplementationsUploadButton";
|
|
7
|
+
|
|
8
|
+
export const RuleImplementationsOptions = ({ loading }) => (
|
|
9
|
+
<Dropdown
|
|
10
|
+
icon="ellipsis vertical"
|
|
11
|
+
className="button icon group-actions button-update"
|
|
12
|
+
direction="left"
|
|
13
|
+
floating
|
|
14
|
+
disabled={loading}
|
|
15
|
+
>
|
|
16
|
+
<Dropdown.Menu>
|
|
17
|
+
<RuleImplementationsDownload />
|
|
18
|
+
<ImplementationsUploadButton />
|
|
19
|
+
<RuleResultsUpload />
|
|
20
|
+
</Dropdown.Menu>
|
|
21
|
+
</Dropdown>
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
RuleImplementationsOptions.propTypes = {
|
|
25
|
+
loading: PropTypes.bool,
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export default RuleImplementationsOptions;
|
|
@@ -0,0 +1,47 @@
|
|
|
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 { uploadResults } from "../routines";
|
|
8
|
+
|
|
9
|
+
export const RuleResultsUpload = ({ uploadResults, loading }) => {
|
|
10
|
+
const { formatMessage } = useIntl();
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<UploadModal
|
|
14
|
+
icon="upload"
|
|
15
|
+
trigger={
|
|
16
|
+
<Dropdown.Item
|
|
17
|
+
icon="upload"
|
|
18
|
+
text={formatMessage({ id: "ruleResults.actions.upload.tooltip" })}
|
|
19
|
+
disabled={loading}
|
|
20
|
+
/>
|
|
21
|
+
}
|
|
22
|
+
header={formatMessage({
|
|
23
|
+
id: "ruleResults.actions.upload.confirmation.header",
|
|
24
|
+
})}
|
|
25
|
+
content={formatMessage({
|
|
26
|
+
id: "uploadModal.actions.upload.confirmation.content",
|
|
27
|
+
})}
|
|
28
|
+
param={"rule_results"}
|
|
29
|
+
handleSubmit={(data) =>
|
|
30
|
+
uploadResults({
|
|
31
|
+
data,
|
|
32
|
+
})
|
|
33
|
+
}
|
|
34
|
+
/>
|
|
35
|
+
);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
RuleResultsUpload.propTypes = {
|
|
39
|
+
uploadResults: PropTypes.func,
|
|
40
|
+
loading: PropTypes.bool,
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const mapStateToProps = ({ uploadingResults }) => ({
|
|
44
|
+
loading: uploadingResults,
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
export default connect(mapStateToProps, { uploadResults })(RuleResultsUpload);
|
|
@@ -5,26 +5,33 @@ import { Link } from "react-router-dom";
|
|
|
5
5
|
import { Button } from "semantic-ui-react";
|
|
6
6
|
import { FormattedMessage } from "react-intl";
|
|
7
7
|
import { RULE_NEW } from "@truedat/core/routes";
|
|
8
|
+
import { uploadRules } from "../routines";
|
|
9
|
+
import RulesUploadButton from "./RulesUploadButton";
|
|
8
10
|
|
|
9
|
-
export const RulesActions = ({ userRulesPermissions }) => (
|
|
11
|
+
export const RulesActions = ({ userRulesPermissions, upload }) => (
|
|
10
12
|
<div style={{ float: "right" }}>
|
|
11
13
|
{userRulesPermissions.manage_quality_rules && (
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
<>
|
|
15
|
+
<Button
|
|
16
|
+
primary
|
|
17
|
+
as={Link}
|
|
18
|
+
to={RULE_NEW}
|
|
19
|
+
content={<FormattedMessage id="quality.actions.create" />}
|
|
20
|
+
/>
|
|
21
|
+
{upload && <RulesUploadButton />}
|
|
22
|
+
<RulesUploadButton />
|
|
23
|
+
</>
|
|
18
24
|
)}
|
|
19
25
|
</div>
|
|
20
26
|
);
|
|
21
27
|
|
|
22
28
|
RulesActions.propTypes = {
|
|
23
|
-
userRulesPermissions: PropTypes.object
|
|
29
|
+
userRulesPermissions: PropTypes.object,
|
|
30
|
+
upload: PropTypes.bool,
|
|
24
31
|
};
|
|
25
32
|
|
|
26
33
|
const mapStateToProps = ({ userRulesPermissions }) => ({
|
|
27
|
-
userRulesPermissions
|
|
34
|
+
userRulesPermissions,
|
|
28
35
|
});
|
|
29
36
|
|
|
30
|
-
export default connect(mapStateToProps)(RulesActions);
|
|
37
|
+
export default connect(mapStateToProps)(RulesActions, uploadRules);
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
import { connect } from "react-redux";
|
|
4
|
+
import { Button } from "semantic-ui-react";
|
|
5
|
+
import { FormattedMessage, useIntl } from "react-intl";
|
|
6
|
+
import { UploadModal } from "@truedat/core/components";
|
|
7
|
+
import { API_RULES_UPLOAD } from "../api";
|
|
8
|
+
import { uploadRules } from "../routines";
|
|
9
|
+
|
|
10
|
+
const uploadAction = {
|
|
11
|
+
method: "POST",
|
|
12
|
+
href: API_RULES_UPLOAD,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const RulesUploadButton = ({ uploadRules, loading }) => {
|
|
16
|
+
const { formatMessage } = useIntl();
|
|
17
|
+
return (
|
|
18
|
+
<UploadModal
|
|
19
|
+
icon="upload"
|
|
20
|
+
trigger={
|
|
21
|
+
<Button
|
|
22
|
+
secondary
|
|
23
|
+
floated="right"
|
|
24
|
+
icon="upload"
|
|
25
|
+
loading={loading}
|
|
26
|
+
data-tooltip={formatMessage({
|
|
27
|
+
id: "rules.actions.upload.tooltip",
|
|
28
|
+
})}
|
|
29
|
+
/>
|
|
30
|
+
}
|
|
31
|
+
header={
|
|
32
|
+
<FormattedMessage id="rules.actions.upload.confirmation.header" />
|
|
33
|
+
}
|
|
34
|
+
content={
|
|
35
|
+
<FormattedMessage id="rules.actions.upload.confirmation.content" />
|
|
36
|
+
}
|
|
37
|
+
param={"rules"}
|
|
38
|
+
handleSubmit={(data) =>
|
|
39
|
+
uploadRules({
|
|
40
|
+
action: "upload",
|
|
41
|
+
data,
|
|
42
|
+
...uploadAction,
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
/>
|
|
46
|
+
);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
RulesUploadButton.propTypes = {
|
|
50
|
+
uploadRules: PropTypes.func,
|
|
51
|
+
loading: PropTypes.bool,
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const mapStateToProps = ({ uploadRulesFile: { loading } }) => ({
|
|
55
|
+
loading,
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
export default connect(mapStateToProps, { uploadRules })(RulesUploadButton);
|
|
@@ -8,7 +8,6 @@ jest.spyOn(React, "useContext").mockImplementation(() => intl);
|
|
|
8
8
|
|
|
9
9
|
describe("<RuleImplementationsActions />", () => {
|
|
10
10
|
const addImplementationFilter = jest.fn();
|
|
11
|
-
const downloadImplementations = jest.fn();
|
|
12
11
|
const toggleImplementationFilterValue = jest.fn();
|
|
13
12
|
const setMode = jest.fn();
|
|
14
13
|
const removeImplementationFilter = jest.fn();
|
|
@@ -17,9 +16,7 @@ describe("<RuleImplementationsActions />", () => {
|
|
|
17
16
|
executionGroupLoading: false,
|
|
18
17
|
ruleImplementationCount: 12,
|
|
19
18
|
implementationsExecution: true,
|
|
20
|
-
ruleImplementationsDownloading: false,
|
|
21
19
|
ruleImplementationsLoading: false,
|
|
22
|
-
downloadImplementations,
|
|
23
20
|
toggleImplementationFilterValue,
|
|
24
21
|
addImplementationFilter,
|
|
25
22
|
executeImplementationsOn: false,
|
|
@@ -31,12 +28,6 @@ describe("<RuleImplementationsActions />", () => {
|
|
|
31
28
|
expect(wrapper).toMatchSnapshot();
|
|
32
29
|
});
|
|
33
30
|
|
|
34
|
-
it("calls downloadImplementations on button click", () => {
|
|
35
|
-
const wrapper = shallow(<RuleImplementationsActions {...props} />);
|
|
36
|
-
wrapper.find("Button").simulate("click");
|
|
37
|
-
expect(downloadImplementations.mock.calls.length).toBe(1);
|
|
38
|
-
});
|
|
39
|
-
|
|
40
31
|
it("as user with permissions I see execute implementations button and checkbox", () => {
|
|
41
32
|
const props = {
|
|
42
33
|
canExecute: true,
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { shallow } from "enzyme";
|
|
4
|
+
import { intl } from "@truedat/test/intl-stub";
|
|
5
|
+
import { RuleImplementationsOptions } from "../RuleImplementationsOptions";
|
|
6
|
+
|
|
7
|
+
jest.spyOn(React, "useContext").mockImplementation(() => intl);
|
|
8
|
+
|
|
9
|
+
describe("<RuleImplementationsOptions />", () => {
|
|
10
|
+
it("matches the latest snapshot", () => {
|
|
11
|
+
const wrapper = shallow(<RuleImplementationsOptions />);
|
|
12
|
+
expect(wrapper).toMatchSnapshot();
|
|
13
|
+
});
|
|
14
|
+
it("matches the latest loading snapshot", () => {
|
|
15
|
+
const wrapper = shallow(<RuleImplementationsOptions loading />);
|
|
16
|
+
expect(wrapper).toMatchSnapshot();
|
|
17
|
+
});
|
|
18
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { shallow } from "enzyme";
|
|
4
|
+
import { intl } from "@truedat/test/intl-stub";
|
|
5
|
+
import { RuleResultsUpload } from "../RuleResultsUpload";
|
|
6
|
+
|
|
7
|
+
jest.spyOn(React, "useContext").mockImplementation(() => intl);
|
|
8
|
+
|
|
9
|
+
describe("<RuleResultsUpload />", () => {
|
|
10
|
+
it("matches the latest snapshot", () => {
|
|
11
|
+
const props = {
|
|
12
|
+
uploadResults: jest.fn(),
|
|
13
|
+
loading: false,
|
|
14
|
+
};
|
|
15
|
+
const wrapper = shallow(<RuleResultsUpload {...props} />);
|
|
16
|
+
expect(wrapper).toMatchSnapshot();
|
|
17
|
+
});
|
|
18
|
+
});
|
|
@@ -27,14 +27,8 @@ exports[`<RuleImplementationsActions /> matches the latest snapshot 1`] = `
|
|
|
27
27
|
disabled={true}
|
|
28
28
|
handleSubmit={[Function]}
|
|
29
29
|
/>
|
|
30
|
-
<
|
|
31
|
-
as="button"
|
|
32
|
-
data-tooltip="implementations.actions.download.tooltip"
|
|
33
|
-
floated="right"
|
|
34
|
-
icon="download"
|
|
30
|
+
<RuleImplementationsOptions
|
|
35
31
|
loading={false}
|
|
36
|
-
onClick={[Function]}
|
|
37
|
-
secondary={true}
|
|
38
32
|
/>
|
|
39
33
|
</div>
|
|
40
34
|
`;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`<RuleImplementationsOptions /> matches the latest loading snapshot 1`] = `
|
|
4
|
+
<Dropdown
|
|
5
|
+
additionLabel="Add "
|
|
6
|
+
additionPosition="top"
|
|
7
|
+
className="button icon group-actions button-update"
|
|
8
|
+
closeOnBlur={true}
|
|
9
|
+
closeOnEscape={true}
|
|
10
|
+
deburr={false}
|
|
11
|
+
direction="left"
|
|
12
|
+
disabled={true}
|
|
13
|
+
floating={true}
|
|
14
|
+
icon="ellipsis vertical"
|
|
15
|
+
minCharacters={1}
|
|
16
|
+
noResultsMessage="No results found."
|
|
17
|
+
openOnFocus={true}
|
|
18
|
+
renderLabel={[Function]}
|
|
19
|
+
searchInput="text"
|
|
20
|
+
selectOnBlur={true}
|
|
21
|
+
selectOnNavigation={true}
|
|
22
|
+
wrapSelection={true}
|
|
23
|
+
>
|
|
24
|
+
<DropdownMenu>
|
|
25
|
+
<Connect(RuleImplementationsDownload) />
|
|
26
|
+
<Connect(ImplementationsUploadButton) />
|
|
27
|
+
<Connect(RuleResultsUpload) />
|
|
28
|
+
</DropdownMenu>
|
|
29
|
+
</Dropdown>
|
|
30
|
+
`;
|
|
31
|
+
|
|
32
|
+
exports[`<RuleImplementationsOptions /> matches the latest snapshot 1`] = `
|
|
33
|
+
<Dropdown
|
|
34
|
+
additionLabel="Add "
|
|
35
|
+
additionPosition="top"
|
|
36
|
+
className="button icon group-actions button-update"
|
|
37
|
+
closeOnBlur={true}
|
|
38
|
+
closeOnEscape={true}
|
|
39
|
+
deburr={false}
|
|
40
|
+
direction="left"
|
|
41
|
+
floating={true}
|
|
42
|
+
icon="ellipsis vertical"
|
|
43
|
+
minCharacters={1}
|
|
44
|
+
noResultsMessage="No results found."
|
|
45
|
+
openOnFocus={true}
|
|
46
|
+
renderLabel={[Function]}
|
|
47
|
+
searchInput="text"
|
|
48
|
+
selectOnBlur={true}
|
|
49
|
+
selectOnNavigation={true}
|
|
50
|
+
wrapSelection={true}
|
|
51
|
+
>
|
|
52
|
+
<DropdownMenu>
|
|
53
|
+
<Connect(RuleImplementationsDownload) />
|
|
54
|
+
<Connect(ImplementationsUploadButton) />
|
|
55
|
+
<Connect(RuleResultsUpload) />
|
|
56
|
+
</DropdownMenu>
|
|
57
|
+
</Dropdown>
|
|
58
|
+
`;
|