@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
|
@@ -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 = ({
|
|
@@ -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 {
|
|
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
|
-
|
|
10
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
<
|
|
45
|
-
|
|
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
|
-
<
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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
|
|