@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.
- package/CHANGELOG.md +21 -1
- package/package.json +5 -5
- package/src/api.js +5 -1
- package/src/components/ConditionSummary.js +23 -21
- package/src/components/ExecutionDetails.js +11 -14
- package/src/components/ExecutionForm.js +116 -0
- package/src/components/ExecutionGroup.js +24 -15
- package/src/components/ExecutionPopup.js +58 -0
- package/src/components/ImplementationResultBar.js +80 -0
- package/src/components/ImplementationSummary.js +33 -72
- package/src/components/ImplementationsRoutes.js +15 -5
- package/src/components/ImplementationsUploadButton.js +63 -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 +18 -48
- package/src/components/RuleProperties.js +1 -10
- package/src/components/RuleResultDecorator.js +43 -26
- package/src/components/RuleResultRow.js +4 -1
- 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__/ExecutionForm.spec.js +25 -0
- package/src/components/__tests__/ExecutionGroup.spec.js +11 -7
- package/src/components/__tests__/ExecutionPopup.spec.js +20 -0
- 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 +10 -32
- 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__/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__/ExecutionForm.spec.js.snap +33 -0
- package/src/components/__tests__/__snapshots__/ExecutionGroup.spec.js.snap +5 -4
- package/src/components/__tests__/__snapshots__/ExecutionPopup.spec.js.snap +11 -0
- 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 +5 -49
- package/src/components/__tests__/__snapshots__/RuleProperties.spec.js.snap +0 -1
- 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/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/__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 +145 -71
- package/src/messages/es.js +270 -180
- 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/dqMessage.js +100 -1
- package/src/reducers/index.js +4 -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/routines.js +2 -0
- package/src/sagas/index.js +6 -0
- package/src/sagas/uploadImplementations.js +28 -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
|
@@ -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} />
|
|
@@ -5,12 +5,22 @@ import ImplementationFiltersLoader from "./ImplementationFiltersLoader";
|
|
|
5
5
|
import RuleImplementations from "./RuleImplementations";
|
|
6
6
|
import RuleImplementationsLoader from "./RuleImplementationsLoader";
|
|
7
7
|
|
|
8
|
+
const TemplatesLoader = React.lazy(() =>
|
|
9
|
+
import("@truedat/df/templates/components/TemplatesLoader")
|
|
10
|
+
);
|
|
11
|
+
|
|
8
12
|
const ImplementationsRoutes = () => (
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
<Route
|
|
14
|
+
path={IMPLEMENTATIONS}
|
|
15
|
+
render={() => (
|
|
16
|
+
<>
|
|
17
|
+
<RuleImplementationsLoader />
|
|
18
|
+
<ImplementationFiltersLoader />
|
|
19
|
+
<TemplatesLoader scope="qe" />
|
|
20
|
+
<RuleImplementations exact />
|
|
21
|
+
</>
|
|
22
|
+
)}
|
|
23
|
+
/>
|
|
14
24
|
);
|
|
15
25
|
|
|
16
26
|
export default ImplementationsRoutes;
|
|
@@ -0,0 +1,63 @@
|
|
|
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_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
|
+
<Button
|
|
25
|
+
secondary
|
|
26
|
+
floated="right"
|
|
27
|
+
icon="upload"
|
|
28
|
+
loading={loading}
|
|
29
|
+
data-tooltip={formatMessage({
|
|
30
|
+
id: "ruleImplementations.actions.upload.tooltip",
|
|
31
|
+
})}
|
|
32
|
+
/>
|
|
33
|
+
}
|
|
34
|
+
header={
|
|
35
|
+
<FormattedMessage id="ruleImplementations.actions.upload.confirmation.header" />
|
|
36
|
+
}
|
|
37
|
+
content={
|
|
38
|
+
<FormattedMessage id="ruleImplementations.actions.upload.confirmation.content" />
|
|
39
|
+
}
|
|
40
|
+
param={"implementations"}
|
|
41
|
+
handleSubmit={(data) =>
|
|
42
|
+
uploadImplementations({
|
|
43
|
+
action: "upload",
|
|
44
|
+
data,
|
|
45
|
+
...uploadAction,
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
/>
|
|
49
|
+
);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
ImplementationsUploadButton.propTypes = {
|
|
53
|
+
uploadImplementations: PropTypes.func,
|
|
54
|
+
loading: PropTypes.bool,
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const mapStateToProps = ({ uploadImplementationsFile: { loading } }) => ({
|
|
58
|
+
loading,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
export default connect(mapStateToProps, { uploadImplementations })(
|
|
62
|
+
ImplementationsUploadButton
|
|
63
|
+
);
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
import { FormattedMessage } from "react-intl";
|
|
4
|
+
import { Header, Icon, Segment, List } from "semantic-ui-react";
|
|
5
|
+
|
|
6
|
+
export default function InformationSummary({ ruleImplementation }) {
|
|
7
|
+
return (
|
|
8
|
+
<>
|
|
9
|
+
<Header as="h3">
|
|
10
|
+
<Icon name="info" size="small" />
|
|
11
|
+
<Header.Content>
|
|
12
|
+
<FormattedMessage id="ruleImplementationForm.step.information" />
|
|
13
|
+
</Header.Content>
|
|
14
|
+
</Header>
|
|
15
|
+
<Segment>
|
|
16
|
+
<List>
|
|
17
|
+
<List.Item>
|
|
18
|
+
<List.Header>
|
|
19
|
+
<FormattedMessage id="quality.thresholds" />
|
|
20
|
+
</List.Header>
|
|
21
|
+
<List.Content>
|
|
22
|
+
<List.Description>
|
|
23
|
+
<FormattedMessage
|
|
24
|
+
id={`ruleImplementations.props.result_type.${ruleImplementation.result_type}`}
|
|
25
|
+
/>
|
|
26
|
+
</List.Description>
|
|
27
|
+
</List.Content>
|
|
28
|
+
</List.Item>
|
|
29
|
+
<List.Item>
|
|
30
|
+
<Icon name="circle" color="yellow" />
|
|
31
|
+
<List.Content>
|
|
32
|
+
<List.Header>
|
|
33
|
+
<FormattedMessage id="quality.threshold" />
|
|
34
|
+
</List.Header>
|
|
35
|
+
<List.Description>
|
|
36
|
+
{ruleImplementation.minimum &&
|
|
37
|
+
`${ruleImplementation.minimum} ${
|
|
38
|
+
ruleImplementation.result_type !== "errors_number"
|
|
39
|
+
? "%"
|
|
40
|
+
: ""
|
|
41
|
+
}`}
|
|
42
|
+
</List.Description>
|
|
43
|
+
</List.Content>
|
|
44
|
+
</List.Item>
|
|
45
|
+
<List.Item>
|
|
46
|
+
<Icon name="circle" color="green" />
|
|
47
|
+
<List.Content>
|
|
48
|
+
<List.Header>
|
|
49
|
+
<FormattedMessage id="quality.goal" />
|
|
50
|
+
</List.Header>
|
|
51
|
+
<List.Description>
|
|
52
|
+
{ruleImplementation.goal &&
|
|
53
|
+
`${ruleImplementation.goal} ${
|
|
54
|
+
ruleImplementation.result_type !== "errors_number"
|
|
55
|
+
? "%"
|
|
56
|
+
: ""
|
|
57
|
+
}`}
|
|
58
|
+
</List.Description>
|
|
59
|
+
</List.Content>
|
|
60
|
+
</List.Item>
|
|
61
|
+
</List>
|
|
62
|
+
</Segment>
|
|
63
|
+
</>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
InformationSummary.propTypes = {
|
|
67
|
+
ruleImplementation: PropTypes.object.isRequired,
|
|
68
|
+
};
|
|
@@ -220,6 +220,9 @@ export const NewRuleImplementation = ({
|
|
|
220
220
|
},
|
|
221
221
|
dfName: _.prop("df_name")(ruleImplementationProps),
|
|
222
222
|
dfContent: ruleImplementationProps.df_content,
|
|
223
|
+
result_type: ruleImplementationProps.result_type,
|
|
224
|
+
minimum: ruleImplementationProps.minimum,
|
|
225
|
+
goal: ruleImplementationProps.goal,
|
|
223
226
|
}
|
|
224
227
|
: {
|
|
225
228
|
executable: true,
|
|
@@ -237,6 +240,9 @@ export const NewRuleImplementation = ({
|
|
|
237
240
|
},
|
|
238
241
|
dfName: "",
|
|
239
242
|
dfContent: {},
|
|
243
|
+
result_type: "percentage",
|
|
244
|
+
minimum: null,
|
|
245
|
+
goal: null,
|
|
240
246
|
}
|
|
241
247
|
);
|
|
242
248
|
|
|
@@ -343,6 +349,9 @@ export const NewRuleImplementation = ({
|
|
|
343
349
|
df_content: dfContent,
|
|
344
350
|
rule_id: rule.id,
|
|
345
351
|
raw_content: { ...raw_content, source },
|
|
352
|
+
result_type: ruleImplementation.result_type,
|
|
353
|
+
minimum: ruleImplementation.minimum,
|
|
354
|
+
goal: ruleImplementation.goal,
|
|
346
355
|
}
|
|
347
356
|
: {
|
|
348
357
|
executable: ruleImplementation.executable,
|
|
@@ -355,6 +364,9 @@ export const NewRuleImplementation = ({
|
|
|
355
364
|
df_name,
|
|
356
365
|
df_content: dfContent,
|
|
357
366
|
rule_id: rule.id,
|
|
367
|
+
result_type: ruleImplementation.result_type,
|
|
368
|
+
minimum: ruleImplementation.minimum,
|
|
369
|
+
goal: ruleImplementation.goal,
|
|
358
370
|
};
|
|
359
371
|
|
|
360
372
|
clone || !edition
|
|
@@ -85,12 +85,9 @@ export class RuleForm extends React.Component {
|
|
|
85
85
|
domain_id: null,
|
|
86
86
|
name: "",
|
|
87
87
|
description: null,
|
|
88
|
-
minimum: null,
|
|
89
|
-
goal: null,
|
|
90
88
|
type_params: {},
|
|
91
89
|
df_name: "",
|
|
92
90
|
df_content: {},
|
|
93
|
-
result_type: "percentage",
|
|
94
91
|
};
|
|
95
92
|
|
|
96
93
|
componentDidMount() {
|
|
@@ -218,86 +215,6 @@ export class RuleForm extends React.Component {
|
|
|
218
215
|
this.setState({ activeSelection: !activeSelection });
|
|
219
216
|
};
|
|
220
217
|
|
|
221
|
-
percentageResultValidationMessages = () => {
|
|
222
|
-
const rule = this.state;
|
|
223
|
-
const {
|
|
224
|
-
intl: { formatMessage },
|
|
225
|
-
} = this.props;
|
|
226
|
-
const minimumMessages = [];
|
|
227
|
-
const goalMessages = [];
|
|
228
|
-
if (rule.goal > 100)
|
|
229
|
-
goalMessages.push(formatMessage({ id: "rule.form.validation.max_goal" }));
|
|
230
|
-
|
|
231
|
-
if (
|
|
232
|
-
!_.isNil(rule.minimum) &&
|
|
233
|
-
!_.isNil(rule.goal) &&
|
|
234
|
-
rule.minimum > rule.goal
|
|
235
|
-
) {
|
|
236
|
-
minimumMessages.push(
|
|
237
|
-
formatMessage({ id: "rule.form.validation.minimum_greater" })
|
|
238
|
-
);
|
|
239
|
-
goalMessages.push(
|
|
240
|
-
formatMessage({ id: "rule.form.validation.goal_less" })
|
|
241
|
-
);
|
|
242
|
-
}
|
|
243
|
-
return { minimumMessages, goalMessages };
|
|
244
|
-
};
|
|
245
|
-
|
|
246
|
-
errorsNumberResultValidationMessages = () => {
|
|
247
|
-
const rule = this.state;
|
|
248
|
-
const {
|
|
249
|
-
intl: { formatMessage },
|
|
250
|
-
} = this.props;
|
|
251
|
-
const minimumMessages = [];
|
|
252
|
-
const goalMessages = [];
|
|
253
|
-
|
|
254
|
-
if (
|
|
255
|
-
!_.isNil(rule.minimum) &&
|
|
256
|
-
!_.isNil(rule.goal) &&
|
|
257
|
-
rule.minimum < rule.goal
|
|
258
|
-
) {
|
|
259
|
-
minimumMessages.push(
|
|
260
|
-
formatMessage({
|
|
261
|
-
id: "rule.form.validation.minimum.greater_eq.goal",
|
|
262
|
-
})
|
|
263
|
-
);
|
|
264
|
-
goalMessages.push(
|
|
265
|
-
formatMessage({ id: "rule.form.validation.goal.less_eq.minimum" })
|
|
266
|
-
);
|
|
267
|
-
}
|
|
268
|
-
return { minimumMessages, goalMessages };
|
|
269
|
-
};
|
|
270
|
-
|
|
271
|
-
deviationResultValidationMessages = () => {
|
|
272
|
-
const rule = this.state;
|
|
273
|
-
const {
|
|
274
|
-
intl: { formatMessage },
|
|
275
|
-
} = this.props;
|
|
276
|
-
const minimumMessages = [];
|
|
277
|
-
const goalMessages = [];
|
|
278
|
-
|
|
279
|
-
if (rule.minimum > 100)
|
|
280
|
-
minimumMessages.push(
|
|
281
|
-
formatMessage({ id: "rule.form.validation.max_minimum" })
|
|
282
|
-
);
|
|
283
|
-
|
|
284
|
-
if (
|
|
285
|
-
!_.isNil(rule.minimum) &&
|
|
286
|
-
!_.isNil(rule.goal) &&
|
|
287
|
-
rule.minimum < rule.goal
|
|
288
|
-
) {
|
|
289
|
-
minimumMessages.push(
|
|
290
|
-
formatMessage({
|
|
291
|
-
id: "rule.form.validation.minimum.greater_eq.goal",
|
|
292
|
-
})
|
|
293
|
-
);
|
|
294
|
-
goalMessages.push(
|
|
295
|
-
formatMessage({ id: "rule.form.validation.goal.less_eq.minimum" })
|
|
296
|
-
);
|
|
297
|
-
}
|
|
298
|
-
return { minimumMessages, goalMessages };
|
|
299
|
-
};
|
|
300
|
-
|
|
301
218
|
generateValidationMessages = () => {
|
|
302
219
|
const rule = this.state;
|
|
303
220
|
const {
|
|
@@ -311,30 +228,9 @@ export class RuleForm extends React.Component {
|
|
|
311
228
|
: undefined;
|
|
312
229
|
const domain = _.isNil(rule.domain_id) ? [requiredMessage] : undefined;
|
|
313
230
|
|
|
314
|
-
const { minimumMessages, goalMessages } = (() => {
|
|
315
|
-
switch (rule.result_type) {
|
|
316
|
-
case "percentage":
|
|
317
|
-
return this.percentageResultValidationMessages();
|
|
318
|
-
case "errors_number":
|
|
319
|
-
return this.errorsNumberResultValidationMessages();
|
|
320
|
-
case "deviation":
|
|
321
|
-
return this.deviationResultValidationMessages();
|
|
322
|
-
}
|
|
323
|
-
})();
|
|
324
|
-
|
|
325
|
-
if (_.isNil(rule.minimum)) minimumMessages.push(requiredMessage);
|
|
326
|
-
if (_.isNil(rule.goal)) goalMessages.push(requiredMessage);
|
|
327
|
-
|
|
328
|
-
const minimum_validation = !_.isEmpty(minimumMessages)
|
|
329
|
-
? minimumMessages
|
|
330
|
-
: undefined;
|
|
331
|
-
const goal_validation = !_.isEmpty(goalMessages) ? goalMessages : undefined;
|
|
332
|
-
|
|
333
231
|
return {
|
|
334
232
|
domain,
|
|
335
233
|
name: name_validation,
|
|
336
|
-
minimum: minimum_validation,
|
|
337
|
-
goal: goal_validation,
|
|
338
234
|
};
|
|
339
235
|
};
|
|
340
236
|
|
|
@@ -454,80 +350,6 @@ export class RuleForm extends React.Component {
|
|
|
454
350
|
</Accordion>
|
|
455
351
|
</Segment>
|
|
456
352
|
)}
|
|
457
|
-
<Segment>
|
|
458
|
-
<FieldLabelWrapping
|
|
459
|
-
label={formatMessage({ id: "rule.props.result_type" })}
|
|
460
|
-
messages={_.prop("result_type")(messages)}
|
|
461
|
-
required
|
|
462
|
-
tooltip={formatMessage({ id: "rule.form.tooltip.result_type" })}
|
|
463
|
-
>
|
|
464
|
-
<Form.Group inline>
|
|
465
|
-
<Form.Radio
|
|
466
|
-
name={"result_type"}
|
|
467
|
-
label={formatMessage({
|
|
468
|
-
id: "rule.props.result_type.percentage",
|
|
469
|
-
})}
|
|
470
|
-
value={"percentage"}
|
|
471
|
-
checked={rule.result_type == "percentage"}
|
|
472
|
-
onChange={this.handleChange}
|
|
473
|
-
/>
|
|
474
|
-
<Form.Radio
|
|
475
|
-
name={"result_type"}
|
|
476
|
-
label={formatMessage({
|
|
477
|
-
id: "rule.props.result_type.deviation",
|
|
478
|
-
})}
|
|
479
|
-
value={"deviation"}
|
|
480
|
-
checked={rule.result_type == "deviation"}
|
|
481
|
-
onChange={this.handleChange}
|
|
482
|
-
/>
|
|
483
|
-
<Form.Radio
|
|
484
|
-
name={"result_type"}
|
|
485
|
-
label={formatMessage({
|
|
486
|
-
id: "rule.props.result_type.errors_number",
|
|
487
|
-
})}
|
|
488
|
-
value={"errors_number"}
|
|
489
|
-
checked={rule.result_type == "errors_number"}
|
|
490
|
-
onChange={this.handleChange}
|
|
491
|
-
/>
|
|
492
|
-
</Form.Group>
|
|
493
|
-
</FieldLabelWrapping>
|
|
494
|
-
<FieldLabelWrapping
|
|
495
|
-
label={formatMessage({ id: "rule.props.minimum" })}
|
|
496
|
-
messages={_.prop("minimum")(messages)}
|
|
497
|
-
required
|
|
498
|
-
tooltip={formatMessage({
|
|
499
|
-
id: `rule.form.tooltip.${rule.result_type}.minimum`,
|
|
500
|
-
})}
|
|
501
|
-
>
|
|
502
|
-
<Form.Input
|
|
503
|
-
name="minimum"
|
|
504
|
-
onChange={this.handleChangeInteger}
|
|
505
|
-
value={_.isNil(rule.minimum) ? "" : rule.minimum}
|
|
506
|
-
placeholder={formatMessage({
|
|
507
|
-
id: "rule.props.minimum.placeholder",
|
|
508
|
-
})}
|
|
509
|
-
autoComplete="off"
|
|
510
|
-
/>
|
|
511
|
-
</FieldLabelWrapping>
|
|
512
|
-
<FieldLabelWrapping
|
|
513
|
-
label={formatMessage({ id: "rule.props.goal" })}
|
|
514
|
-
messages={_.prop("goal")(messages)}
|
|
515
|
-
required
|
|
516
|
-
tooltip={formatMessage({
|
|
517
|
-
id: `rule.form.tooltip.${rule.result_type}.goal`,
|
|
518
|
-
})}
|
|
519
|
-
>
|
|
520
|
-
<Form.Input
|
|
521
|
-
name="goal"
|
|
522
|
-
onChange={this.handleChangeInteger}
|
|
523
|
-
value={_.isNil(rule.goal) ? "" : rule.goal}
|
|
524
|
-
placeholder={formatMessage({
|
|
525
|
-
id: "rule.props.goal.placeholder",
|
|
526
|
-
})}
|
|
527
|
-
autoComplete="off"
|
|
528
|
-
/>
|
|
529
|
-
</FieldLabelWrapping>
|
|
530
|
-
</Segment>
|
|
531
353
|
{!_.isNil(rule.df_content) && templatesLoaded && (
|
|
532
354
|
<DynamicRuleForm
|
|
533
355
|
name="dynamicForm"
|
|
@@ -4,12 +4,13 @@ import { Link } from "react-router-dom";
|
|
|
4
4
|
import PropTypes from "prop-types";
|
|
5
5
|
import { useIntl } from "react-intl";
|
|
6
6
|
import { connect } from "react-redux";
|
|
7
|
-
import { Header, Label, Menu, Grid } from "semantic-ui-react";
|
|
7
|
+
import { Header, Label, Menu, Grid, Icon } from "semantic-ui-react";
|
|
8
8
|
import { ConfirmModal, GroupActions } from "@truedat/core/components";
|
|
9
9
|
import { useAuthorized } from "@truedat/core/hooks";
|
|
10
10
|
import { linkTo } from "@truedat/core/routes";
|
|
11
11
|
import { setRuleImplementationStatus } from "../routines";
|
|
12
12
|
import RuleImplementationTabs from "./RuleImplementationTabs";
|
|
13
|
+
import ImplementationResultBar from "./ImplementationResultBar";
|
|
13
14
|
|
|
14
15
|
const getAvailableActions = (props, formatMessage) => {
|
|
15
16
|
const contentActions = [
|
|
@@ -177,11 +178,13 @@ export const RuleImplementation = ({
|
|
|
177
178
|
<>
|
|
178
179
|
<Grid>
|
|
179
180
|
<Grid.Column width={8}>
|
|
180
|
-
<Header
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
181
|
+
<Header as="h2">
|
|
182
|
+
<Icon circular name="clipboard check" />
|
|
183
|
+
<Header.Content>
|
|
184
|
+
{ruleImplementation.implementation_key}
|
|
185
|
+
<ImplementationResultBar implementation={ruleImplementation} />
|
|
186
|
+
</Header.Content>
|
|
187
|
+
</Header>
|
|
185
188
|
</Grid.Column>
|
|
186
189
|
<Grid.Column width={8} textAlign="right">
|
|
187
190
|
<>
|
|
@@ -215,6 +218,7 @@ RuleImplementation.propTypes = {
|
|
|
215
218
|
rule: PropTypes.object,
|
|
216
219
|
ruleImplementation: PropTypes.object,
|
|
217
220
|
userRulePermissions: PropTypes.object,
|
|
221
|
+
children: PropTypes.node,
|
|
218
222
|
};
|
|
219
223
|
|
|
220
224
|
const mapStateToProps = ({
|