@truedat/dq 4.33.10 → 4.35.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 +26 -0
- package/package.json +5 -5
- package/src/api.js +7 -1
- package/src/components/ConditionSummary.js +23 -21
- package/src/components/ExecutionDetails.js +11 -14
- package/src/components/ExecutionGroup.js +24 -15
- package/src/components/ImplementationResultBar.js +80 -0
- package/src/components/ImplementationSummary.js +33 -72
- package/src/components/ImplementationsUploadButton.js +61 -0
- package/src/components/InformationSummary.js +68 -0
- package/src/components/NewRuleImplementation.js +12 -0
- package/src/components/RuleForm.js +0 -178
- package/src/components/RuleImplementation.js +10 -6
- package/src/components/RuleImplementationProperties.js +31 -64
- package/src/components/RuleImplementationResults.js +87 -53
- package/src/components/RuleImplementationsActions.js +3 -59
- package/src/components/RuleImplementationsDownload.js +86 -0
- package/src/components/RuleImplementationsOptions.js +28 -0
- package/src/components/RuleProperties.js +1 -10
- package/src/components/RuleResultDecorator.js +43 -26
- package/src/components/RuleResultRow.js +4 -1
- package/src/components/RuleResultsUpload.js +47 -0
- package/src/components/RuleRoutes.js +0 -13
- package/src/components/RuleSummary.js +15 -2
- package/src/components/RulesActions.js +17 -10
- package/src/components/RulesUploadButton.js +58 -0
- package/src/components/__tests__/ExecutionGroup.spec.js +11 -7
- package/src/components/__tests__/ImplementationResultBar.spec.js +98 -0
- package/src/components/__tests__/ImplementationSummary.spec.js +9 -26
- package/src/components/__tests__/InformationSummary.spec.js +35 -0
- package/src/components/__tests__/NewRuleImplementation.spec.js +1 -1
- package/src/components/__tests__/RuleForm.spec.js +0 -191
- package/src/components/__tests__/RuleImplementation.spec.js +1 -0
- package/src/components/__tests__/RuleImplementationProperties.spec.js +23 -33
- package/src/components/__tests__/RuleImplementationsActions.spec.js +0 -9
- package/src/components/__tests__/RuleImplementationsOptions.spec.js +18 -0
- package/src/components/__tests__/RuleProperties.spec.js +7 -9
- package/src/components/__tests__/RuleResultDecorator.spec.js +17 -11
- package/src/components/__tests__/RuleResultRow.spec.js +25 -46
- package/src/components/__tests__/RuleResultsUpload.spec.js +18 -0
- package/src/components/__tests__/RuleRow.spec.js +0 -4
- package/src/components/__tests__/RuleSummary.spec.js +6 -6
- package/src/components/__tests__/Rules.spec.js +15 -39
- package/src/components/__tests__/__snapshots__/ConditionSummary.spec.js.snap +55 -51
- package/src/components/__tests__/__snapshots__/ExecutionGroup.spec.js.snap +5 -4
- package/src/components/__tests__/__snapshots__/ImplementationResultBar.spec.js.snap +141 -0
- package/src/components/__tests__/__snapshots__/ImplementationSummary.spec.js.snap +194 -457
- package/src/components/__tests__/__snapshots__/InformationSummary.spec.js.snap +185 -0
- package/src/components/__tests__/__snapshots__/NewRuleImplementation.spec.js.snap +6 -0
- package/src/components/__tests__/__snapshots__/RuleForm.spec.js.snap +0 -148
- package/src/components/__tests__/__snapshots__/RuleImplementation.spec.js.snap +20 -0
- package/src/components/__tests__/__snapshots__/RuleImplementationProperties.spec.js.snap +43 -49
- package/src/components/__tests__/__snapshots__/RuleImplementationResults.spec.js.snap +63 -61
- 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__/RuleProperties.spec.js.snap +0 -1
- package/src/components/__tests__/__snapshots__/RuleResultsUpload.spec.js.snap +18 -0
- package/src/components/__tests__/__snapshots__/RuleRow.spec.js.snap +0 -28
- package/src/components/__tests__/__snapshots__/Rules.spec.js.snap +0 -101
- package/src/components/ruleImplementationForm/FiltersGroup.js +1 -0
- package/src/components/ruleImplementationForm/InformationForm.js +5 -5
- package/src/components/ruleImplementationForm/LimitsForm.js +142 -0
- package/src/components/ruleImplementationForm/RuleImplementationForm.js +14 -4
- package/src/components/ruleImplementationForm/RuleImplementationRawForm.js +16 -6
- package/src/components/ruleImplementationForm/ValueConditions.js +11 -0
- package/src/components/ruleImplementationForm/__tests__/LimitsForm.spec.js +186 -0
- package/src/components/ruleImplementationForm/__tests__/RuleImplementationRawForm.spec.js +42 -35
- package/src/components/ruleImplementationForm/__tests__/__snapshots__/LimitsForm.spec.js.snap +1104 -0
- package/src/components/ruleImplementationForm/__tests__/__snapshots__/RuleImplementationForm.spec.js.snap +4 -1
- package/src/components/ruleImplementationForm/__tests__/__snapshots__/RuleImplementationRawForm.spec.js.snap +12 -1
- package/src/components/ruleImplementationForm/limitsValidation.js +72 -0
- package/src/messages/en.js +167 -76
- package/src/messages/es.js +292 -185
- package/src/reducers/__tests__/rule.spec.js +2 -4
- package/src/reducers/__tests__/ruleImplementation.spec.js +2 -0
- package/src/reducers/__tests__/ruleImplementations.spec.js +12 -8
- 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/rule.js +0 -3
- package/src/reducers/ruleImplementation.js +3 -0
- package/src/reducers/ruleImplementationRedirect.js +6 -1
- package/src/reducers/ruleImplementations.js +3 -0
- 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/src/selectors/getRuleImplementationColumns.js +38 -3
- package/src/selectors/ruleColumnsSelector.js +0 -31
- package/src/styles/ruleSummary.less +17 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
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
|
+
|
|
22
|
+
## [4.34.0] 2021-12-02
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- [TD-4270] Move goal and threshold from Rule to Implementation
|
|
27
|
+
- [TD-4295] Changed how implementation Information section is displayed
|
|
28
|
+
|
|
3
29
|
## [4.33.10] 2021-11-30
|
|
4
30
|
|
|
5
31
|
- [TD-4306] Fix popups inside execution popup
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truedat/dq",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.35.2",
|
|
4
4
|
"description": "Truedat Web Data Quality Module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"jsnext:main": "src/index.js",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"@babel/plugin-transform-modules-commonjs": "^7.15.0",
|
|
32
32
|
"@babel/preset-env": "^7.15.0",
|
|
33
33
|
"@babel/preset-react": "^7.14.5",
|
|
34
|
-
"@truedat/test": "4.
|
|
34
|
+
"@truedat/test": "4.34.0",
|
|
35
35
|
"babel-jest": "^27.0.6",
|
|
36
36
|
"babel-plugin-dynamic-import-node": "^2.3.3",
|
|
37
37
|
"babel-plugin-lodash": "^3.3.4",
|
|
@@ -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.2",
|
|
86
|
+
"@truedat/df": "4.35.2",
|
|
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": "2d5ffbb16aaf62db662165ccd8088c65fcb6ec74"
|
|
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
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
2
|
import React, { Fragment } from "react";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
|
-
import { Header, Icon, Table } from "semantic-ui-react";
|
|
4
|
+
import { Header, Icon, Segment, Table } from "semantic-ui-react";
|
|
5
5
|
import { Link } from "react-router-dom";
|
|
6
6
|
import { FormattedMessage } from "react-intl";
|
|
7
7
|
import { linkTo } from "@truedat/core/routes";
|
|
@@ -168,26 +168,28 @@ export const ConditionSummary = ({ rows, type, icon }) =>
|
|
|
168
168
|
/>
|
|
169
169
|
</Header.Content>
|
|
170
170
|
</Header>
|
|
171
|
-
<
|
|
172
|
-
<Table
|
|
173
|
-
<Table.
|
|
174
|
-
<Table.
|
|
175
|
-
<
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
<
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
<
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
171
|
+
<Segment>
|
|
172
|
+
<Table basic="very">
|
|
173
|
+
<Table.Header>
|
|
174
|
+
<Table.Row>
|
|
175
|
+
<Table.HeaderCell>
|
|
176
|
+
<FormattedMessage id={`ruleImplementation.summary.field`} />
|
|
177
|
+
</Table.HeaderCell>
|
|
178
|
+
<Table.HeaderCell>
|
|
179
|
+
<FormattedMessage id={`ruleImplementation.summary.operator`} />
|
|
180
|
+
</Table.HeaderCell>
|
|
181
|
+
<Table.HeaderCell>
|
|
182
|
+
<FormattedMessage id={`ruleImplementation.summary.values`} />
|
|
183
|
+
</Table.HeaderCell>
|
|
184
|
+
</Table.Row>
|
|
185
|
+
</Table.Header>
|
|
186
|
+
<Table.Body>
|
|
187
|
+
{rows.map((row, i) => (
|
|
188
|
+
<ConditionCell key={i} row={row} />
|
|
189
|
+
))}
|
|
190
|
+
</Table.Body>
|
|
191
|
+
</Table>
|
|
192
|
+
</Segment>
|
|
191
193
|
</>
|
|
192
194
|
);
|
|
193
195
|
|
|
@@ -8,7 +8,7 @@ import { Table, Message, Icon } from "semantic-ui-react";
|
|
|
8
8
|
import { DateTime } from "@truedat/core/components";
|
|
9
9
|
import { selectColor } from "../functions/selectors";
|
|
10
10
|
|
|
11
|
-
const GeneralInformation = ({
|
|
11
|
+
const GeneralInformation = ({ ruleImplementation, ruleResult }) => {
|
|
12
12
|
const { formatMessage, formatNumber: _formatNumber } = useIntl();
|
|
13
13
|
const formatNumber = (num) => (_.isNil(num) ? num : _formatNumber(num));
|
|
14
14
|
return (
|
|
@@ -18,7 +18,10 @@ const GeneralInformation = ({ rule, ruleResult }) => {
|
|
|
18
18
|
{formatMessage({ id: "ruleResult.props.quality" })}
|
|
19
19
|
</Table.Cell>
|
|
20
20
|
<Table.Cell>
|
|
21
|
-
<Icon
|
|
21
|
+
<Icon
|
|
22
|
+
name="circle"
|
|
23
|
+
color={selectColor({ ...ruleImplementation, ...ruleResult })}
|
|
24
|
+
/>
|
|
22
25
|
{`${parseFloat(ruleResult.result)} %`}
|
|
23
26
|
</Table.Cell>
|
|
24
27
|
</Table.Row>
|
|
@@ -50,7 +53,7 @@ const GeneralInformation = ({ rule, ruleResult }) => {
|
|
|
50
53
|
};
|
|
51
54
|
|
|
52
55
|
GeneralInformation.propTypes = {
|
|
53
|
-
|
|
56
|
+
ruleImplementation: PropTypes.object,
|
|
54
57
|
ruleResult: PropTypes.object,
|
|
55
58
|
};
|
|
56
59
|
|
|
@@ -70,11 +73,7 @@ const DetailRow = ({ details }) => {
|
|
|
70
73
|
)(details);
|
|
71
74
|
};
|
|
72
75
|
|
|
73
|
-
export const ExecutionDetails = ({
|
|
74
|
-
rule,
|
|
75
|
-
ruleImplementation,
|
|
76
|
-
rule_result_id,
|
|
77
|
-
}) => {
|
|
76
|
+
export const ExecutionDetails = ({ ruleImplementation, rule_result_id }) => {
|
|
78
77
|
const { formatMessage } = useIntl();
|
|
79
78
|
const { rule_result_id: id } = useParams();
|
|
80
79
|
|
|
@@ -104,7 +103,10 @@ export const ExecutionDetails = ({
|
|
|
104
103
|
</Table.Row>
|
|
105
104
|
</Table.Header>
|
|
106
105
|
<Table.Body>
|
|
107
|
-
<GeneralInformation
|
|
106
|
+
<GeneralInformation
|
|
107
|
+
ruleImplementation={ruleImplementation}
|
|
108
|
+
ruleResult={ruleResult}
|
|
109
|
+
/>
|
|
108
110
|
</Table.Body>
|
|
109
111
|
|
|
110
112
|
<Table.Header>
|
|
@@ -126,16 +128,11 @@ export const ExecutionDetails = ({
|
|
|
126
128
|
|
|
127
129
|
ExecutionDetails.propTypes = {
|
|
128
130
|
ruleImplementation: PropTypes.object,
|
|
129
|
-
rule: PropTypes.object,
|
|
130
|
-
customColumns: PropTypes.array,
|
|
131
|
-
isAdmin: PropTypes.bool,
|
|
132
131
|
rule_result_id: PropTypes.number,
|
|
133
132
|
};
|
|
134
133
|
|
|
135
134
|
const mapStateToProps = (state) => ({
|
|
136
|
-
rule: state.rule,
|
|
137
135
|
ruleImplementation: state.ruleImplementation,
|
|
138
|
-
isAdmin: state.authentication.role === "admin",
|
|
139
136
|
});
|
|
140
137
|
|
|
141
138
|
export default connect(mapStateToProps)(ExecutionDetails);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { flow, pick, reject, size, sortBy } from "lodash/fp";
|
|
1
|
+
import { flow, pick, filter, reject, size, prop, sortBy } from "lodash/fp";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
4
|
import { connect } from "react-redux";
|
|
@@ -15,41 +15,41 @@ const columns = [
|
|
|
15
15
|
{
|
|
16
16
|
name: "ruleImplementations.props.status",
|
|
17
17
|
fieldDecorator: RuleEventDecorator,
|
|
18
|
-
fieldSelector: pick(["_embedded.quality_events"])
|
|
18
|
+
fieldSelector: pick(["_embedded.quality_events"]),
|
|
19
19
|
},
|
|
20
20
|
{
|
|
21
21
|
name: "ruleImplementations.props.implementation_key",
|
|
22
22
|
fieldSelector: "_embedded.implementation",
|
|
23
|
-
fieldDecorator: RuleImplementationResultsLink
|
|
23
|
+
fieldDecorator: RuleImplementationResultsLink,
|
|
24
24
|
},
|
|
25
25
|
{
|
|
26
26
|
name: "rule.props.name",
|
|
27
|
-
fieldSelector: "_embedded.rule.name"
|
|
27
|
+
fieldSelector: "_embedded.rule.name",
|
|
28
28
|
},
|
|
29
29
|
{
|
|
30
30
|
name: "ruleResult.props.date",
|
|
31
31
|
fieldDecorator: DateTime,
|
|
32
32
|
textAlign: "center",
|
|
33
|
-
fieldSelector: ({ _embedded }) => ({ value: _embedded?.result?.date })
|
|
33
|
+
fieldSelector: ({ _embedded }) => ({ value: _embedded?.result?.date }),
|
|
34
34
|
},
|
|
35
35
|
{
|
|
36
36
|
name: "ruleResult.props.records",
|
|
37
37
|
textAlign: "right",
|
|
38
|
-
fieldSelector: "_embedded.result.records"
|
|
38
|
+
fieldSelector: "_embedded.result.records",
|
|
39
39
|
},
|
|
40
40
|
{
|
|
41
41
|
name: "ruleResult.props.errors",
|
|
42
42
|
textAlign: "right",
|
|
43
|
-
fieldSelector: "_embedded.result.errors"
|
|
43
|
+
fieldSelector: "_embedded.result.errors",
|
|
44
44
|
},
|
|
45
45
|
{
|
|
46
46
|
name: "ruleResult.props.quality",
|
|
47
47
|
fieldSelector: ({ _embedded }) => ({
|
|
48
48
|
ruleResult: _embedded?.result,
|
|
49
|
-
|
|
49
|
+
ruleImplementation: _embedded?.implementation,
|
|
50
50
|
}),
|
|
51
|
-
fieldDecorator: RuleResultDecorator
|
|
52
|
-
}
|
|
51
|
+
fieldDecorator: RuleResultDecorator,
|
|
52
|
+
},
|
|
53
53
|
];
|
|
54
54
|
|
|
55
55
|
export const ExecutionRow = ({ execution }) => (
|
|
@@ -65,7 +65,7 @@ export const ExecutionRow = ({ execution }) => (
|
|
|
65
65
|
);
|
|
66
66
|
|
|
67
67
|
ExecutionRow.propTypes = {
|
|
68
|
-
execution: PropTypes.object
|
|
68
|
+
execution: PropTypes.object,
|
|
69
69
|
};
|
|
70
70
|
|
|
71
71
|
export const ExecutionGroup = ({ executionGroup, executionGroupLoading }) => {
|
|
@@ -74,10 +74,19 @@ export const ExecutionGroup = ({ executionGroup, executionGroupLoading }) => {
|
|
|
74
74
|
executionGroup?._embedded?.executions
|
|
75
75
|
);
|
|
76
76
|
const count = size(executions);
|
|
77
|
-
const
|
|
77
|
+
const missingResultCount = flow(reject("_embedded.result"), size)(executions);
|
|
78
|
+
const errorCount = flow(
|
|
79
|
+
filter(flow(prop("_embedded.quality_events"), size)),
|
|
80
|
+
size
|
|
81
|
+
)(executions);
|
|
82
|
+
|
|
78
83
|
return executionGroupLoading ? null : (
|
|
79
84
|
<>
|
|
80
|
-
<ExecutionGroupMessage
|
|
85
|
+
<ExecutionGroupMessage
|
|
86
|
+
count={count}
|
|
87
|
+
pending={missingResultCount - errorCount}
|
|
88
|
+
error={errorCount}
|
|
89
|
+
/>
|
|
81
90
|
<Table>
|
|
82
91
|
<Table.Header>
|
|
83
92
|
<Table.Row>
|
|
@@ -102,12 +111,12 @@ export const ExecutionGroup = ({ executionGroup, executionGroupLoading }) => {
|
|
|
102
111
|
|
|
103
112
|
ExecutionGroup.propTypes = {
|
|
104
113
|
executionGroup: PropTypes.object,
|
|
105
|
-
executionGroupLoading: PropTypes.bool
|
|
114
|
+
executionGroupLoading: PropTypes.bool,
|
|
106
115
|
};
|
|
107
116
|
|
|
108
117
|
export const mapStateToProps = ({ executionGroup, executionGroupLoading }) => ({
|
|
109
118
|
executionGroup,
|
|
110
|
-
executionGroupLoading
|
|
119
|
+
executionGroupLoading,
|
|
111
120
|
});
|
|
112
121
|
|
|
113
122
|
export default connect(mapStateToProps)(ExecutionGroup);
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import PropTypes from "prop-types";
|
|
4
|
+
import { Popup } from "semantic-ui-react";
|
|
5
|
+
import { Link } from "react-router-dom";
|
|
6
|
+
import { FormattedMessage, useIntl } from "react-intl";
|
|
7
|
+
import { linkTo } from "@truedat/core/routes";
|
|
8
|
+
import { calculateResultDecoration } from "./RuleResultDecorator";
|
|
9
|
+
import "../styles/ruleSummary.less";
|
|
10
|
+
|
|
11
|
+
export default function ImplementationResultBar({ implementation }) {
|
|
12
|
+
const intl = useIntl();
|
|
13
|
+
const ruleResult = _.head(implementation?.results);
|
|
14
|
+
const { color, resultText } =
|
|
15
|
+
implementation.event_type === "FAILED"
|
|
16
|
+
? {
|
|
17
|
+
color: "failed",
|
|
18
|
+
resultText: intl.formatMessage({ id: "quality.error" }),
|
|
19
|
+
}
|
|
20
|
+
: calculateResultDecoration({
|
|
21
|
+
ruleResult,
|
|
22
|
+
ruleImplementation: implementation,
|
|
23
|
+
date: ruleResult?.date,
|
|
24
|
+
intl,
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const propsByColor = {
|
|
28
|
+
red: {
|
|
29
|
+
className: "under-minimum-color",
|
|
30
|
+
tooltip: "under_minimum",
|
|
31
|
+
},
|
|
32
|
+
yellow: {
|
|
33
|
+
className: "under-goal-color",
|
|
34
|
+
tooltip: "under_goal",
|
|
35
|
+
},
|
|
36
|
+
green: {
|
|
37
|
+
className: "over-goal-color",
|
|
38
|
+
tooltip: "over_goal",
|
|
39
|
+
},
|
|
40
|
+
grey: {
|
|
41
|
+
className: "not-executed-color",
|
|
42
|
+
tooltip: "no_execution",
|
|
43
|
+
},
|
|
44
|
+
failed: {
|
|
45
|
+
className: "failed-color",
|
|
46
|
+
tooltip: "failed",
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
const summaryProps = propsByColor[color];
|
|
50
|
+
return (
|
|
51
|
+
<div className="rule-summary-wrapper">
|
|
52
|
+
<Link
|
|
53
|
+
as="div"
|
|
54
|
+
className="rule-summary pointer"
|
|
55
|
+
to={linkTo.RULE_IMPLEMENTATION_RESULTS({
|
|
56
|
+
id: implementation.rule_id,
|
|
57
|
+
implementation_id: implementation.id,
|
|
58
|
+
})}
|
|
59
|
+
>
|
|
60
|
+
<Popup
|
|
61
|
+
position="bottom center"
|
|
62
|
+
basic
|
|
63
|
+
on="hover"
|
|
64
|
+
content={
|
|
65
|
+
<FormattedMessage id={`quality_result.${summaryProps.tooltip}`} />
|
|
66
|
+
}
|
|
67
|
+
trigger={
|
|
68
|
+
<span className={summaryProps.className} style={{ width: "100%" }}>
|
|
69
|
+
<span className="value">{resultText}</span>
|
|
70
|
+
</span>
|
|
71
|
+
}
|
|
72
|
+
/>
|
|
73
|
+
</Link>
|
|
74
|
+
</div>
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
ImplementationResultBar.propTypes = {
|
|
79
|
+
implementation: PropTypes.object.isRequired,
|
|
80
|
+
};
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
|
-
import { Header, Icon,
|
|
4
|
+
import { Header, Icon, Table, Segment } from "semantic-ui-react";
|
|
5
5
|
import { Link } from "react-router-dom";
|
|
6
6
|
import { FormattedMessage } from "react-intl";
|
|
7
7
|
import { linkTo } from "@truedat/core/routes";
|
|
8
8
|
import ConditionSummary, { empty, path } from "./ConditionSummary";
|
|
9
|
+
import InformationSummary from "./InformationSummary";
|
|
9
10
|
|
|
10
11
|
const defaults = [
|
|
11
12
|
"executable",
|
|
@@ -38,45 +39,6 @@ FormattedLink.propTypes = {
|
|
|
38
39
|
operator: PropTypes.object,
|
|
39
40
|
};
|
|
40
41
|
|
|
41
|
-
const GeneralSummary = ({ executable, implementationKey }) => (
|
|
42
|
-
<>
|
|
43
|
-
<Header as="h3">
|
|
44
|
-
<Icon name="database" size="small" />
|
|
45
|
-
<Header.Content>
|
|
46
|
-
<FormattedMessage id="ruleImplementations.summary.headers.implementation" />
|
|
47
|
-
</Header.Content>
|
|
48
|
-
</Header>
|
|
49
|
-
<Grid>
|
|
50
|
-
<Grid.Row>
|
|
51
|
-
<Grid.Column>
|
|
52
|
-
<Label color={executable ? "olive" : "teal"}>
|
|
53
|
-
<FormattedMessage
|
|
54
|
-
id={`ruleImplementation.props.executable.${executable}`}
|
|
55
|
-
/>
|
|
56
|
-
</Label>
|
|
57
|
-
</Grid.Column>
|
|
58
|
-
</Grid.Row>
|
|
59
|
-
{implementationKey && (
|
|
60
|
-
<Grid.Row columns={2}>
|
|
61
|
-
<Grid.Column width={4}>
|
|
62
|
-
<FormattedMessage
|
|
63
|
-
id={`ruleImplementation.summary.implementation_key`}
|
|
64
|
-
/>
|
|
65
|
-
</Grid.Column>
|
|
66
|
-
<Grid.Column width={12}>
|
|
67
|
-
<span className="highlighted">{`"${implementationKey}"`}</span>
|
|
68
|
-
</Grid.Column>
|
|
69
|
-
</Grid.Row>
|
|
70
|
-
)}
|
|
71
|
-
</Grid>
|
|
72
|
-
</>
|
|
73
|
-
);
|
|
74
|
-
|
|
75
|
-
GeneralSummary.propTypes = {
|
|
76
|
-
executable: PropTypes.bool,
|
|
77
|
-
implementationKey: PropTypes.string,
|
|
78
|
-
};
|
|
79
|
-
|
|
80
42
|
const DatasetSummary = ({ rows }) =>
|
|
81
43
|
empty(rows) ? null : (
|
|
82
44
|
<>
|
|
@@ -86,34 +48,36 @@ const DatasetSummary = ({ rows }) =>
|
|
|
86
48
|
<FormattedMessage id="ruleImplementations.summary.headers.dataset" />
|
|
87
49
|
</Header.Content>
|
|
88
50
|
</Header>
|
|
89
|
-
<
|
|
90
|
-
<Table
|
|
91
|
-
<Table.
|
|
92
|
-
<Table.
|
|
93
|
-
<
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
</Table.Header>
|
|
97
|
-
<Table.Body>
|
|
98
|
-
{rows.map((row, i) => (
|
|
99
|
-
<Table.Row key={i}>
|
|
100
|
-
{_.has("structure")(row) && (
|
|
101
|
-
<Table.Cell key={i}>
|
|
102
|
-
<Link
|
|
103
|
-
to={linkTo.STRUCTURE({
|
|
104
|
-
id: _.pathOr("", "structure.id")(row),
|
|
105
|
-
})}
|
|
106
|
-
>
|
|
107
|
-
<span key={i} className="highlighted">{`"${path(
|
|
108
|
-
_.propOr({}, "structure")(row)
|
|
109
|
-
)}"`}</span>
|
|
110
|
-
</Link>
|
|
111
|
-
</Table.Cell>
|
|
112
|
-
)}
|
|
51
|
+
<Segment>
|
|
52
|
+
<Table basic="very">
|
|
53
|
+
<Table.Header>
|
|
54
|
+
<Table.Row>
|
|
55
|
+
<Table.HeaderCell>
|
|
56
|
+
<FormattedMessage id={`ruleImplementation.summary.structure`} />
|
|
57
|
+
</Table.HeaderCell>
|
|
113
58
|
</Table.Row>
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
59
|
+
</Table.Header>
|
|
60
|
+
<Table.Body>
|
|
61
|
+
{rows.map((row, i) => (
|
|
62
|
+
<Table.Row key={i}>
|
|
63
|
+
{_.has("structure")(row) && (
|
|
64
|
+
<Table.Cell key={i}>
|
|
65
|
+
<Link
|
|
66
|
+
to={linkTo.STRUCTURE({
|
|
67
|
+
id: _.pathOr("", "structure.id")(row),
|
|
68
|
+
})}
|
|
69
|
+
>
|
|
70
|
+
<span key={i} className="highlighted">{`"${path(
|
|
71
|
+
_.propOr({}, "structure")(row)
|
|
72
|
+
)}"`}</span>
|
|
73
|
+
</Link>
|
|
74
|
+
</Table.Cell>
|
|
75
|
+
)}
|
|
76
|
+
</Table.Row>
|
|
77
|
+
))}
|
|
78
|
+
</Table.Body>
|
|
79
|
+
</Table>
|
|
80
|
+
</Segment>
|
|
117
81
|
</>
|
|
118
82
|
);
|
|
119
83
|
|
|
@@ -123,16 +87,13 @@ DatasetSummary.propTypes = {
|
|
|
123
87
|
|
|
124
88
|
export const ImplementationSummary = ({ ruleImplementation, activeSteps }) => {
|
|
125
89
|
const steps = _.isEmpty(activeSteps) ? defaults : activeSteps;
|
|
126
|
-
const {
|
|
90
|
+
const { dataset, population, validations } =
|
|
127
91
|
_.pick(steps)(ruleImplementation);
|
|
128
92
|
return (
|
|
129
93
|
<>
|
|
130
94
|
{(_.includes("implementationKey")(steps) ||
|
|
131
95
|
_.includes("executable")(steps)) && (
|
|
132
|
-
<
|
|
133
|
-
executable={executable}
|
|
134
|
-
implementationKey={implementationKey}
|
|
135
|
-
/>
|
|
96
|
+
<InformationSummary ruleImplementation={ruleImplementation} />
|
|
136
97
|
)}
|
|
137
98
|
{dataset && _.includes("dataset")(steps) && (
|
|
138
99
|
<DatasetSummary rows={dataset} />
|
|
@@ -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
|
+
);
|