@truedat/dq 4.33.8 → 4.34.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.
Files changed (90) hide show
  1. package/CHANGELOG.md +21 -1
  2. package/package.json +5 -5
  3. package/src/api.js +5 -1
  4. package/src/components/ConditionSummary.js +23 -21
  5. package/src/components/ExecutionDetails.js +11 -14
  6. package/src/components/ExecutionForm.js +116 -0
  7. package/src/components/ExecutionGroup.js +24 -15
  8. package/src/components/ExecutionPopup.js +58 -0
  9. package/src/components/ImplementationResultBar.js +80 -0
  10. package/src/components/ImplementationSummary.js +33 -72
  11. package/src/components/ImplementationsRoutes.js +15 -5
  12. package/src/components/ImplementationsUploadButton.js +63 -0
  13. package/src/components/InformationSummary.js +68 -0
  14. package/src/components/NewRuleImplementation.js +12 -0
  15. package/src/components/RuleForm.js +0 -178
  16. package/src/components/RuleImplementation.js +10 -6
  17. package/src/components/RuleImplementationProperties.js +31 -64
  18. package/src/components/RuleImplementationResults.js +87 -53
  19. package/src/components/RuleImplementationsActions.js +18 -48
  20. package/src/components/RuleProperties.js +1 -10
  21. package/src/components/RuleResultDecorator.js +43 -26
  22. package/src/components/RuleResultRow.js +4 -1
  23. package/src/components/RuleRoutes.js +0 -13
  24. package/src/components/RuleSummary.js +15 -2
  25. package/src/components/RulesActions.js +17 -10
  26. package/src/components/RulesUploadButton.js +58 -0
  27. package/src/components/__tests__/ExecutionForm.spec.js +25 -0
  28. package/src/components/__tests__/ExecutionGroup.spec.js +11 -7
  29. package/src/components/__tests__/ExecutionPopup.spec.js +20 -0
  30. package/src/components/__tests__/ImplementationResultBar.spec.js +98 -0
  31. package/src/components/__tests__/ImplementationSummary.spec.js +9 -26
  32. package/src/components/__tests__/InformationSummary.spec.js +35 -0
  33. package/src/components/__tests__/NewRuleImplementation.spec.js +1 -1
  34. package/src/components/__tests__/RuleForm.spec.js +0 -191
  35. package/src/components/__tests__/RuleImplementation.spec.js +1 -0
  36. package/src/components/__tests__/RuleImplementationProperties.spec.js +23 -33
  37. package/src/components/__tests__/RuleImplementationsActions.spec.js +10 -32
  38. package/src/components/__tests__/RuleProperties.spec.js +7 -9
  39. package/src/components/__tests__/RuleResultDecorator.spec.js +17 -11
  40. package/src/components/__tests__/RuleResultRow.spec.js +25 -46
  41. package/src/components/__tests__/RuleRow.spec.js +0 -4
  42. package/src/components/__tests__/RuleSummary.spec.js +6 -6
  43. package/src/components/__tests__/Rules.spec.js +15 -39
  44. package/src/components/__tests__/__snapshots__/ConditionSummary.spec.js.snap +55 -51
  45. package/src/components/__tests__/__snapshots__/ExecutionForm.spec.js.snap +33 -0
  46. package/src/components/__tests__/__snapshots__/ExecutionGroup.spec.js.snap +5 -4
  47. package/src/components/__tests__/__snapshots__/ExecutionPopup.spec.js.snap +11 -0
  48. package/src/components/__tests__/__snapshots__/ImplementationResultBar.spec.js.snap +141 -0
  49. package/src/components/__tests__/__snapshots__/ImplementationSummary.spec.js.snap +194 -457
  50. package/src/components/__tests__/__snapshots__/InformationSummary.spec.js.snap +185 -0
  51. package/src/components/__tests__/__snapshots__/NewRuleImplementation.spec.js.snap +6 -0
  52. package/src/components/__tests__/__snapshots__/RuleForm.spec.js.snap +0 -148
  53. package/src/components/__tests__/__snapshots__/RuleImplementation.spec.js.snap +20 -0
  54. package/src/components/__tests__/__snapshots__/RuleImplementationProperties.spec.js.snap +43 -49
  55. package/src/components/__tests__/__snapshots__/RuleImplementationResults.spec.js.snap +63 -61
  56. package/src/components/__tests__/__snapshots__/RuleImplementationsActions.spec.js.snap +5 -49
  57. package/src/components/__tests__/__snapshots__/RuleProperties.spec.js.snap +0 -1
  58. package/src/components/__tests__/__snapshots__/RuleRow.spec.js.snap +0 -28
  59. package/src/components/__tests__/__snapshots__/Rules.spec.js.snap +0 -101
  60. package/src/components/ruleImplementationForm/InformationForm.js +5 -5
  61. package/src/components/ruleImplementationForm/LimitsForm.js +142 -0
  62. package/src/components/ruleImplementationForm/RuleImplementationForm.js +14 -4
  63. package/src/components/ruleImplementationForm/RuleImplementationRawForm.js +16 -6
  64. package/src/components/ruleImplementationForm/__tests__/LimitsForm.spec.js +186 -0
  65. package/src/components/ruleImplementationForm/__tests__/RuleImplementationRawForm.spec.js +42 -35
  66. package/src/components/ruleImplementationForm/__tests__/__snapshots__/LimitsForm.spec.js.snap +1104 -0
  67. package/src/components/ruleImplementationForm/__tests__/__snapshots__/RuleImplementationForm.spec.js.snap +4 -1
  68. package/src/components/ruleImplementationForm/__tests__/__snapshots__/RuleImplementationRawForm.spec.js.snap +12 -1
  69. package/src/components/ruleImplementationForm/limitsValidation.js +72 -0
  70. package/src/messages/en.js +145 -71
  71. package/src/messages/es.js +270 -180
  72. package/src/reducers/__tests__/rule.spec.js +2 -4
  73. package/src/reducers/__tests__/ruleImplementation.spec.js +2 -0
  74. package/src/reducers/__tests__/ruleImplementations.spec.js +12 -8
  75. package/src/reducers/dqMessage.js +100 -1
  76. package/src/reducers/index.js +4 -0
  77. package/src/reducers/rule.js +0 -3
  78. package/src/reducers/ruleImplementation.js +3 -0
  79. package/src/reducers/ruleImplementationRedirect.js +6 -1
  80. package/src/reducers/ruleImplementations.js +3 -0
  81. package/src/reducers/ruleRedirect.js +5 -0
  82. package/src/reducers/uploadImplementationsFile.js +28 -0
  83. package/src/reducers/uploadRulesFile.js +25 -0
  84. package/src/routines.js +2 -0
  85. package/src/sagas/index.js +6 -0
  86. package/src/sagas/uploadImplementations.js +28 -0
  87. package/src/sagas/uploadRules.js +28 -0
  88. package/src/selectors/getRuleImplementationColumns.js +38 -3
  89. package/src/selectors/ruleColumnsSelector.js +0 -31
  90. package/src/styles/ruleSummary.less +17 -10
@@ -3,19 +3,22 @@ import React from "react";
3
3
  import PropTypes from "prop-types";
4
4
  import { FormattedMessage } from "react-intl";
5
5
  import { connect } from "react-redux";
6
- import { Header, Grid, Icon, Label, Segment, List } from "semantic-ui-react";
6
+ import { Grid, Label, Segment } from "semantic-ui-react";
7
+ import InformationSummary from "./InformationSummary";
7
8
  import ImplementationSummary from "./ImplementationSummary";
8
9
  import RawContent from "./RawContent";
9
- import RuleResultDecorator from "./RuleResultDecorator";
10
- import QualityEventError from "./QualityEventError";
10
+
11
+ const DynamicFormViewer = React.lazy(() =>
12
+ import("@truedat/df/components/DynamicFormViewer")
13
+ );
11
14
 
12
15
  const summarySteps = ["dataset", "population", "validations"];
13
16
 
14
17
  export const RuleImplementationProperties = ({
15
- rule,
16
18
  ruleImplementation,
17
19
  ruleImplementationRaw,
18
- ruleResult,
20
+ templateImpl,
21
+ ruleImplementationLoaded,
19
22
  }) => {
20
23
  return _.isEmpty(ruleImplementation) &&
21
24
  _.isEmpty(ruleImplementationRaw) ? null : (
@@ -30,6 +33,18 @@ export const RuleImplementationProperties = ({
30
33
  </Label>
31
34
  </Grid.Column>
32
35
  </Grid.Row>
36
+ <Grid.Row>
37
+ <Grid.Column width={10}>
38
+ <InformationSummary ruleImplementation={ruleImplementation} />
39
+ {!_.isEmpty(templateImpl) && ruleImplementationLoaded && (
40
+ <DynamicFormViewer
41
+ boxLayout
42
+ template={templateImpl}
43
+ content={ruleImplementation.df_content}
44
+ />
45
+ )}
46
+ </Grid.Column>
47
+ </Grid.Row>
33
48
  <Grid.Column width={10}>
34
49
  {_.isEmpty(ruleImplementationRaw) ? (
35
50
  <ImplementationSummary
@@ -41,85 +56,37 @@ export const RuleImplementationProperties = ({
41
56
  )}
42
57
  </Grid.Column>
43
58
  </Grid>
44
- <Header as="h3">
45
- <FormattedMessage id={`rule.props.result_type.${rule.result_type}`} />
46
- </Header>
47
- <List>
48
- <List.Item>
49
- <Icon name="circle" color="yellow" />
50
- <List.Content>
51
- <List.Description>
52
- <FormattedMessage id="quality.threshold" />
53
- {`: ${rule.minimum} ${
54
- rule.result_type !== "errors_number" ? "%" : ""
55
- }`}
56
- </List.Description>
57
- </List.Content>
58
- </List.Item>
59
- <List.Item>
60
- <Icon name="circle" color="green" />
61
- <List.Content>
62
- <List.Description>
63
- <FormattedMessage id="quality.goal" />
64
- {`: ${rule.goal} ${
65
- rule.result_type !== "errors_number" ? "%" : ""
66
- }`}
67
- </List.Description>
68
- </List.Content>
69
- </List.Item>
70
- </List>
71
- <Header as="h3">
72
- <FormattedMessage id="quality.rule.quality" />
73
- </Header>
74
- {ruleResult ? (
75
- <p>
76
- <RuleResultDecorator
77
- ruleResult={ruleResult}
78
- date={ruleResult?.date}
79
- rule={rule}
80
- />
81
- </p>
82
- ) : (
83
- <FormattedMessage id="quality.result.no.data" />
84
- )}
85
- {ruleImplementation.event_type !== "FAILED" ? null : (
86
- <>
87
- <Header as="h3">
88
- <Icon name="warning circle" color="red" size="small" />
89
- <FormattedMessage id="quality.error" />
90
- </Header>
91
- <QualityEventError
92
- inserted_at={ruleImplementation.event_inserted_at}
93
- message={ruleImplementation.event_message}
94
- type={ruleImplementation.event_type}
95
- />
96
- </>
97
- )}
98
59
  </Segment>
99
60
  );
100
61
  };
101
62
  RuleImplementationProperties.propTypes = {
102
- rule: PropTypes.object,
103
63
  ruleImplementation: PropTypes.object.isRequired,
104
64
  ruleImplementationRaw: PropTypes.object,
105
- ruleResult: PropTypes.array,
65
+ templateImpl: PropTypes.object,
66
+ ruleImplementationLoaded: PropTypes.bool,
106
67
  };
107
68
 
108
69
  const mapStateToProps = ({
109
- rule,
110
70
  ruleImplementation,
111
71
  ruleImplementationRaw,
72
+ templates,
73
+ ruleImplementationLoading,
112
74
  }) => ({
113
- rule,
114
75
  ruleImplementation: _.pick([
115
76
  ...summarySteps,
116
77
  "executable",
117
78
  "event_type",
118
79
  "event_message",
119
80
  "event_inserted_at",
81
+ "result_type",
82
+ "minimum",
83
+ "goal",
84
+ "df_content",
120
85
  ])(ruleImplementation),
121
86
  ruleImplementationRaw,
122
- ruleResult: _.head(ruleImplementation?.results),
87
+ templateImpl: _.find(_.propEq("name", ruleImplementation.df_name))(templates),
88
+ ruleImplementationLoaded:
89
+ !ruleImplementationLoading && !_.isEmpty(ruleImplementation),
123
90
  });
124
91
 
125
92
  export default connect(mapStateToProps)(RuleImplementationProperties);
@@ -3,8 +3,9 @@ import React from "react";
3
3
  import PropTypes from "prop-types";
4
4
  import { useIntl } from "react-intl";
5
5
  import { connect } from "react-redux";
6
- import { Table, Message } from "semantic-ui-react";
6
+ import { Table, Message, Divider } from "semantic-ui-react";
7
7
  import { columnDecorator } from "@truedat/core/services";
8
+ import Moment from "react-moment";
8
9
  import { getRuleResultsColumns } from "../selectors";
9
10
  import RuleResultRow from "./RuleResultRow";
10
11
 
@@ -25,65 +26,98 @@ export const RuleImplementationResults = ({
25
26
  customColumns,
26
27
  isAdmin,
27
28
  }) => {
28
- const { formatMessage } = useIntl();
29
+ const { formatMessage, locale } = useIntl();
29
30
 
30
31
  if (_.isEmpty(rule) || _.isEmpty(ruleImplementation)) return null;
31
32
 
32
33
  const ruleResults = ruleImplementation.results;
33
34
  const optionalColumns = getOptionalColumnsWithData(ruleResults);
34
35
 
35
- return _.isEmpty(ruleResults) ? (
36
- <Message
37
- style={{ marginTop: "14px" }}
38
- header={formatMessage({ id: "rule.ruleImplementation.results.empty" })}
39
- />
40
- ) : (
41
- <Table className="implementation-results small" selectable>
42
- <Table.Header>
43
- <Table.Row>
44
- <Table.HeaderCell
45
- content={formatMessage({ id: "ruleResult.props.quality" })}
36
+ return (
37
+ <>
38
+ {ruleImplementation.event_type === "FAILED" && (
39
+ <Message negative style={{ marginTop: "14px" }}>
40
+ <Message.Header>
41
+ {formatMessage({
42
+ id: "quality.error",
43
+ })}
44
+ </Message.Header>
45
+ <Divider />
46
+ <Moment
47
+ style={{
48
+ position: "absolute",
49
+ top: "14px",
50
+ right: "21px",
51
+ }}
52
+ locale={locale}
53
+ date={ruleImplementation.event_inserted_at}
54
+ format="YYYY-MM-DD HH:mm"
46
55
  />
47
- <Table.HeaderCell
48
- content={formatMessage({ id: "ruleResult.props.date" })}
49
- />
50
- {_.includes("records")(optionalColumns) && (
51
- <Table.HeaderCell
52
- content={formatMessage({ id: "ruleResult.props.records" })}
53
- />
54
- )}
55
- {_.includes("errors")(optionalColumns) && (
56
- <Table.HeaderCell
57
- content={formatMessage({ id: "ruleResult.props.errors" })}
58
- />
59
- )}
60
- {customColumns.map((column, index) => (
61
- <Table.HeaderCell
62
- key={index}
63
- content={formatMessage({
64
- id: `ruleResult.props.${column.name}`,
65
- defaultMessage: column.name,
66
- })}
67
- />
68
- ))}
69
- {<Table.HeaderCell />}
70
- {isAdmin && <Table.HeaderCell />}
71
- </Table.Row>
72
- </Table.Header>
73
- <Table.Body>
74
- {ruleResults.map((result, i) => (
75
- <RuleResultRow
76
- key={i}
77
- optionalColumns={optionalColumns}
78
- ruleResult={result}
79
- customColumns={customColumns}
80
- isAdmin={isAdmin}
81
- ruleImplementation={ruleImplementation}
82
- rule={rule}
83
- />
84
- ))}
85
- </Table.Body>
86
- </Table>
56
+ <p
57
+ style={{
58
+ whiteSpace: "pre-wrap",
59
+ }}
60
+ >
61
+ {ruleImplementation.event_message}
62
+ </p>
63
+ </Message>
64
+ )}
65
+ {_.isEmpty(ruleResults) ? (
66
+ <Message
67
+ style={{ marginTop: "14px" }}
68
+ header={formatMessage({
69
+ id: "rule.ruleImplementation.results.empty",
70
+ })}
71
+ />
72
+ ) : (
73
+ <Table className="implementation-results small" selectable>
74
+ <Table.Header>
75
+ <Table.Row>
76
+ <Table.HeaderCell
77
+ content={formatMessage({ id: "ruleResult.props.quality" })}
78
+ />
79
+ <Table.HeaderCell
80
+ content={formatMessage({ id: "ruleResult.props.date" })}
81
+ />
82
+ {_.includes("records")(optionalColumns) && (
83
+ <Table.HeaderCell
84
+ content={formatMessage({ id: "ruleResult.props.records" })}
85
+ />
86
+ )}
87
+ {_.includes("errors")(optionalColumns) && (
88
+ <Table.HeaderCell
89
+ content={formatMessage({ id: "ruleResult.props.errors" })}
90
+ />
91
+ )}
92
+ {customColumns.map((column, index) => (
93
+ <Table.HeaderCell
94
+ key={index}
95
+ content={formatMessage({
96
+ id: `ruleResult.props.${column.name}`,
97
+ defaultMessage: column.name,
98
+ })}
99
+ />
100
+ ))}
101
+ {<Table.HeaderCell />}
102
+ {isAdmin && <Table.HeaderCell />}
103
+ </Table.Row>
104
+ </Table.Header>
105
+ <Table.Body>
106
+ {ruleResults.map((result, i) => (
107
+ <RuleResultRow
108
+ key={i}
109
+ optionalColumns={optionalColumns}
110
+ ruleResult={result}
111
+ customColumns={customColumns}
112
+ isAdmin={isAdmin}
113
+ ruleImplementation={ruleImplementation}
114
+ rule={rule}
115
+ />
116
+ ))}
117
+ </Table.Body>
118
+ </Table>
119
+ )}
120
+ </>
87
121
  );
88
122
  };
89
123
 
@@ -4,9 +4,7 @@ import PropTypes from "prop-types";
4
4
  import { connect } from "react-redux";
5
5
  import { Button, Checkbox } from "semantic-ui-react";
6
6
  import { useIntl } from "react-intl";
7
- import { FormattedMessage } from "react-intl";
8
- import { ConfirmModal } from "@truedat/core/components";
9
- import { downloadImplementations } from "../routines";
7
+ import { downloadImplementations, uploadImplementations } from "../routines";
10
8
  import { getImplementationsExecution } from "../selectors";
11
9
  import {
12
10
  addImplementationFilter,
@@ -14,6 +12,9 @@ import {
14
12
  removeImplementationFilter,
15
13
  createExecutionGroup,
16
14
  } from "../routines";
15
+ import ImplementationsUploadButton from "./ImplementationsUploadButton";
16
+
17
+ import ExecutionPopup from "./ExecutionPopup";
17
18
 
18
19
  const staticHeaderLabels = [
19
20
  "implementation_key",
@@ -39,20 +40,6 @@ const staticContentLabels = [
39
40
  "executable.false",
40
41
  ];
41
42
 
42
- const actions = (handleSubmit) => [
43
- {
44
- key: "no",
45
- secondary: true,
46
- content: <FormattedMessage id="confirmation.no" />,
47
- },
48
- {
49
- key: "yes",
50
- primary: true,
51
- content: <FormattedMessage id="confirmation.yes" />,
52
- onClick: handleSubmit,
53
- },
54
- ];
55
-
56
43
  export const RuleImplementationsActions = ({
57
44
  addImplementationFilter,
58
45
  canExecute,
@@ -60,7 +47,6 @@ export const RuleImplementationsActions = ({
60
47
  executeImplementationsOn,
61
48
  toggleImplementationFilterValue,
62
49
  removeImplementationFilter,
63
- executionGroupLoading,
64
50
  createExecutionGroup,
65
51
  selectedImplementations,
66
52
  implementationQuery,
@@ -69,6 +55,7 @@ export const RuleImplementationsActions = ({
69
55
  ruleImplementationCount,
70
56
  ruleImplementationsDownloading,
71
57
  ruleImplementationsLoading,
58
+ upload,
72
59
  }) => {
73
60
  const { formatMessage } = useIntl();
74
61
 
@@ -99,11 +86,11 @@ export const RuleImplementationsActions = ({
99
86
  checked ? showExecutableInfo() : hideExecutableInfo();
100
87
  };
101
88
 
102
- const handleSubmit = () => {
89
+ const handleSubmit = (df_content) => {
103
90
  const query = _.isEmpty(selectedImplementations)
104
91
  ? implementationQuery
105
92
  : { filters: { id: selectedImplementations } };
106
- createExecutionGroup({ ...query });
93
+ createExecutionGroup({ ...query, df_content });
107
94
  };
108
95
  return (
109
96
  <div style={{ float: "right" }}>
@@ -117,32 +104,14 @@ export const RuleImplementationsActions = ({
117
104
  checked={executeImplementationsOn}
118
105
  style={{ top: "6px", marginRight: "7.5px" }}
119
106
  />
120
- <ConfirmModal
121
- actions={actions(handleSubmit)}
122
- trigger={
123
- <Button
124
- id="execute_button"
125
- secondary
126
- disabled={!executeImplementationsOn}
127
- loading={executionGroupLoading}
128
- content={
129
- <FormattedMessage id="implementations.actions.do_execution" />
130
- }
131
- />
132
- }
133
- header={
134
- <FormattedMessage id="implementations.actions.execution.confirmation.header" />
135
- }
136
- content={
137
- <FormattedMessage
138
- id="implementations.actions.execution.confirmation.content"
139
- values={{
140
- implementations_count: _.isEmpty(selectedImplementations)
141
- ? ruleImplementationCount
142
- : selectedImplementations.length,
143
- }}
144
- />
107
+ <ExecutionPopup
108
+ disabled={!executeImplementationsOn}
109
+ count={
110
+ _.isEmpty(selectedImplementations)
111
+ ? ruleImplementationCount
112
+ : selectedImplementations.length
145
113
  }
114
+ handleSubmit={handleSubmit}
146
115
  />
147
116
  </>
148
117
  )}
@@ -160,6 +129,8 @@ export const RuleImplementationsActions = ({
160
129
  loading={ruleImplementationsDownloading}
161
130
  />
162
131
  )}
132
+ {upload && <ImplementationsUploadButton />}
133
+ <ImplementationsUploadButton />
163
134
  </div>
164
135
  );
165
136
  };
@@ -170,7 +141,6 @@ RuleImplementationsActions.propTypes = {
170
141
  canExecute: PropTypes.bool,
171
142
  createExecutionGroup: PropTypes.func,
172
143
  executeImplementationsOn: PropTypes.bool,
173
- executionGroupLoading: PropTypes.bool,
174
144
  implementationsExecution: PropTypes.bool,
175
145
  implementationQuery: PropTypes.object,
176
146
  removeImplementationFilter: PropTypes.func,
@@ -180,11 +150,11 @@ RuleImplementationsActions.propTypes = {
180
150
  toggleImplementationFilterValue: PropTypes.func,
181
151
  ruleImplementationsDownloading: PropTypes.bool,
182
152
  ruleImplementationsLoading: PropTypes.bool,
153
+ upload: PropTypes.bool,
183
154
  };
184
155
 
185
156
  const mapStateToProps = (state) => ({
186
157
  canExecute: _.propOr(false, "userImplementationsPermissions.execute")(state),
187
- executionGroupLoading: state.executionGroupLoading,
188
158
  ruleImplementationCount: state.ruleImplementationCount,
189
159
  implementationsExecution: getImplementationsExecution(state),
190
160
  ruleImplementationsDownloading: state.ruleImplementationsDownloading,
@@ -197,4 +167,4 @@ export default connect(mapStateToProps, {
197
167
  toggleImplementationFilterValue,
198
168
  removeImplementationFilter,
199
169
  createExecutionGroup,
200
- })(RuleImplementationsActions);
170
+ })(RuleImplementationsActions, uploadImplementations);
@@ -3,12 +3,10 @@ import React from "react";
3
3
  import PropTypes from "prop-types";
4
4
  import { FormattedMessage } from "react-intl";
5
5
  import { connect } from "react-redux";
6
- import { useHistory, Link } from "react-router-dom";
6
+ import { Link } from "react-router-dom";
7
7
  import { List, Label } from "semantic-ui-react";
8
8
  import "rc-slider/assets/index.css";
9
9
  import { linkTo } from "@truedat/core/routes";
10
- import RuleRangeNumber from "./RuleRangeNumber";
11
- import RuleRangePercentage from "./RuleRangePercentage";
12
10
 
13
11
  const RichTextEditor = React.lazy(() =>
14
12
  import("@truedat/core/components/RichTextEditor")
@@ -27,7 +25,6 @@ export const RuleProperties = ({
27
25
  domain,
28
26
  domain_id,
29
27
  active,
30
- result_type,
31
28
  }) => {
32
29
  return (
33
30
  <List size="big" relaxed>
@@ -67,11 +64,6 @@ export const RuleProperties = ({
67
64
  </Link>
68
65
  </List.Item>
69
66
  )}
70
- {["percentage", "deviation"].includes(result_type) ? (
71
- <RuleRangePercentage />
72
- ) : (
73
- <RuleRangeNumber />
74
- )}
75
67
  </List>
76
68
  );
77
69
  };
@@ -83,7 +75,6 @@ RuleProperties.propTypes = {
83
75
  description: PropTypes.object,
84
76
  domain: PropTypes.object,
85
77
  domain_id: PropTypes.number,
86
- result_type: PropTypes.string,
87
78
  };
88
79
 
89
80
  const mapStateToProps = ({ rule }) => rule;
@@ -10,31 +10,30 @@ const nilResult = (ruleResult) =>
10
10
  isNil(ruleResult) ||
11
11
  (has("result_text")(ruleResult) && isNil(ruleResult?.result_text));
12
12
 
13
- export const RuleResultDecorator = ({ ruleResult, rule, date }) => {
14
- const { formatMessage, formatNumber: _formatNumber } = useIntl();
13
+ export const calculateResultDecoration = ({
14
+ ruleResult,
15
+ ruleImplementation,
16
+ date,
17
+ intl: { formatMessage, formatNumber: _formatNumber },
18
+ }) => {
15
19
  const formatNumber = (num) => (isNil(num) ? num : _formatNumber(num));
16
- if (nilResult(ruleResult) && isNil(date)) {
17
- return null;
18
- }
20
+
19
21
  if (ruleResult?.result_text === "quality_result.failed") {
20
- return (
21
- <>
22
- <Icon
23
- name="warning circle"
24
- color="red"
25
- title={formatMessage({ id: "quality_result.failed" })}
26
- />
27
- {formatMessage({ id: "quality_result.failed" })}
28
- </>
29
- );
22
+ const resultText = formatMessage({ id: "quality_result.failed" });
23
+ return {
24
+ iconName: "warning circle",
25
+ resultText: resultText,
26
+ color: "red",
27
+ resultText,
28
+ };
30
29
  }
31
- const resultText = ruleResult?.result_text;
32
- const resultType = rule?.result_type;
30
+
31
+ const resultType = ruleImplementation?.result_type;
33
32
  const result =
34
33
  resultType === "errors_number"
35
34
  ? formatNumber(ruleResult?.errors)
36
35
  : ruleResult?.result;
37
- const resultTitle = isNil(result)
36
+ const resultText = isNil(result)
38
37
  ? formatMessage({ id: "quality.result.no.data" })
39
38
  : date
40
39
  ? formatMessage(
@@ -45,23 +44,41 @@ export const RuleResultDecorator = ({ ruleResult, rule, date }) => {
45
44
  { id: `quality.result.${resultType}.description` },
46
45
  { result }
47
46
  );
48
- const color = selectColor({ ...rule, ...ruleResult });
47
+ const color = selectColor({ ...ruleImplementation, ...ruleResult });
48
+ const iconTitle = ruleResult?.result_text
49
+ ? formatMessage({ id: ruleResult?.result_text })
50
+ : null;
51
+
52
+ return { iconName: "circle", color, resultText, iconTitle };
53
+ };
54
+
55
+ export const RuleResultDecorator = ({
56
+ ruleResult,
57
+ ruleImplementation,
58
+ date,
59
+ }) => {
60
+ const intl = useIntl();
61
+ if (nilResult(ruleResult) && isNil(date)) {
62
+ return null;
63
+ }
64
+ const { iconName, color, resultText, iconTitle } = calculateResultDecoration({
65
+ ruleResult,
66
+ ruleImplementation,
67
+ date,
68
+ intl,
69
+ });
49
70
 
50
71
  return (
51
72
  <>
52
- <Icon
53
- name="circle"
54
- title={resultText ? formatMessage({ id: resultText }) : null}
55
- color={color}
56
- />
57
- {resultTitle}
73
+ <Icon name={iconName} title={iconTitle} color={color} />
74
+ {resultText}
58
75
  </>
59
76
  );
60
77
  };
61
78
 
62
79
  RuleResultDecorator.propTypes = {
63
80
  ruleResult: PropTypes.object,
64
- rule: PropTypes.object,
81
+ ruleImplementation: PropTypes.object,
65
82
  date: PropTypes.string,
66
83
  };
67
84
 
@@ -41,7 +41,10 @@ export const RuleResultRow = ({
41
41
  }
42
42
  >
43
43
  <Table.Cell>
44
- <Icon name="circle" color={selectColor({ ...rule, ...ruleResult })} />
44
+ <Icon
45
+ name="circle"
46
+ color={selectColor({ ...ruleImplementation, ...ruleResult })}
47
+ />
45
48
  {`${parseFloat(ruleResult.result)} %`}
46
49
  </Table.Cell>
47
50
  <Table.Cell>
@@ -66,7 +66,6 @@ const RuleRoutes = ({
66
66
  templatesLoaded,
67
67
  template,
68
68
  structuresAliasesLoading,
69
- templateImpl,
70
69
  ruleImplementation,
71
70
  }) => {
72
71
  const latest = _.head(ruleImplementation.results);
@@ -227,14 +226,6 @@ const RuleRoutes = ({
227
226
  <RuleImplementationProperties />
228
227
  </RuleImplementation>
229
228
  )}
230
- {!_.isEmpty(templateImpl) && ruleImplementationLoaded && (
231
- <Segment attached="bottom">
232
- <DynamicFormViewer
233
- template={templateImpl}
234
- content={ruleImplementation.df_content}
235
- />
236
- </Segment>
237
- )}
238
229
  </Segment>
239
230
  </>
240
231
  )}
@@ -305,7 +296,6 @@ RuleRoutes.propTypes = {
305
296
  implementationStructures: PropTypes.array,
306
297
  ruleLoaded: PropTypes.bool,
307
298
  template: PropTypes.object,
308
- templateImpl: PropTypes.object,
309
299
  ruleImplementation: PropTypes.object,
310
300
  ruleImplementationLoaded: PropTypes.bool,
311
301
  implementationStructuresLoaded: PropTypes.bool,
@@ -325,9 +315,6 @@ const mapStateToProps = (state) => ({
325
315
  templatesLoaded: !state.templatesLoading && !_.isEmpty(state.templates),
326
316
  template: _.find(_.propEq("name", state.rule.df_name))(state.templates),
327
317
  structuresAliasesLoading: state.structuresAliasesLoading,
328
- templateImpl: _.find(_.propEq("name", state.ruleImplementation.df_name))(
329
- state.templates
330
- ),
331
318
  ruleImplementation: state.ruleImplementation,
332
319
  });
333
320
 
@@ -22,8 +22,12 @@ const mapSummary = (implementations) => {
22
22
  const failed = _.size(failedImplementations);
23
23
  const quality = _.reduce(
24
24
  (summary, implementation) => {
25
- const { errors, result } = implementation.execution_result_info;
26
- const { goal, minimum, result_type } = implementation.rule;
25
+ const {
26
+ goal,
27
+ minimum,
28
+ result_type,
29
+ execution_result_info: { errors, result },
30
+ } = implementation;
27
31
  const color = selectColor({ errors, result, minimum, goal, result_type });
28
32
  return _.set(color, summary[color] + 1)(summary);
29
33
  },
@@ -71,6 +75,15 @@ const SummaryBar = ({
71
75
  </>
72
76
  );
73
77
 
78
+ SummaryBar.propTypes = {
79
+ key: PropTypes.string,
80
+ className: PropTypes.string,
81
+ summary: PropTypes.object,
82
+ percentages: PropTypes.array,
83
+ showPercentages: PropTypes.bool,
84
+ tooltip: PropTypes.string,
85
+ };
86
+
74
87
  const SummaryBars = (props) => {
75
88
  return (
76
89
  <div className="rule-summary">