@truedat/dq 4.33.10 → 4.34.0

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 (66) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/package.json +5 -5
  3. package/src/components/ConditionSummary.js +23 -21
  4. package/src/components/ExecutionDetails.js +11 -14
  5. package/src/components/ExecutionGroup.js +24 -15
  6. package/src/components/ImplementationResultBar.js +80 -0
  7. package/src/components/ImplementationSummary.js +33 -72
  8. package/src/components/InformationSummary.js +68 -0
  9. package/src/components/NewRuleImplementation.js +12 -0
  10. package/src/components/RuleForm.js +0 -178
  11. package/src/components/RuleImplementation.js +10 -6
  12. package/src/components/RuleImplementationProperties.js +31 -64
  13. package/src/components/RuleImplementationResults.js +87 -53
  14. package/src/components/RuleProperties.js +1 -10
  15. package/src/components/RuleResultDecorator.js +43 -26
  16. package/src/components/RuleResultRow.js +4 -1
  17. package/src/components/RuleRoutes.js +0 -13
  18. package/src/components/RuleSummary.js +15 -2
  19. package/src/components/__tests__/ExecutionGroup.spec.js +11 -7
  20. package/src/components/__tests__/ImplementationResultBar.spec.js +98 -0
  21. package/src/components/__tests__/ImplementationSummary.spec.js +9 -26
  22. package/src/components/__tests__/InformationSummary.spec.js +35 -0
  23. package/src/components/__tests__/NewRuleImplementation.spec.js +1 -1
  24. package/src/components/__tests__/RuleForm.spec.js +0 -191
  25. package/src/components/__tests__/RuleImplementation.spec.js +1 -0
  26. package/src/components/__tests__/RuleImplementationProperties.spec.js +23 -33
  27. package/src/components/__tests__/RuleProperties.spec.js +7 -9
  28. package/src/components/__tests__/RuleResultDecorator.spec.js +17 -11
  29. package/src/components/__tests__/RuleResultRow.spec.js +25 -46
  30. package/src/components/__tests__/RuleRow.spec.js +0 -4
  31. package/src/components/__tests__/RuleSummary.spec.js +6 -6
  32. package/src/components/__tests__/Rules.spec.js +15 -39
  33. package/src/components/__tests__/__snapshots__/ConditionSummary.spec.js.snap +55 -51
  34. package/src/components/__tests__/__snapshots__/ExecutionGroup.spec.js.snap +5 -4
  35. package/src/components/__tests__/__snapshots__/ImplementationResultBar.spec.js.snap +141 -0
  36. package/src/components/__tests__/__snapshots__/ImplementationSummary.spec.js.snap +194 -457
  37. package/src/components/__tests__/__snapshots__/InformationSummary.spec.js.snap +185 -0
  38. package/src/components/__tests__/__snapshots__/NewRuleImplementation.spec.js.snap +6 -0
  39. package/src/components/__tests__/__snapshots__/RuleForm.spec.js.snap +0 -148
  40. package/src/components/__tests__/__snapshots__/RuleImplementation.spec.js.snap +20 -0
  41. package/src/components/__tests__/__snapshots__/RuleImplementationProperties.spec.js.snap +43 -49
  42. package/src/components/__tests__/__snapshots__/RuleImplementationResults.spec.js.snap +63 -61
  43. package/src/components/__tests__/__snapshots__/RuleProperties.spec.js.snap +0 -1
  44. package/src/components/__tests__/__snapshots__/RuleRow.spec.js.snap +0 -28
  45. package/src/components/__tests__/__snapshots__/Rules.spec.js.snap +0 -101
  46. package/src/components/ruleImplementationForm/InformationForm.js +5 -5
  47. package/src/components/ruleImplementationForm/LimitsForm.js +142 -0
  48. package/src/components/ruleImplementationForm/RuleImplementationForm.js +14 -4
  49. package/src/components/ruleImplementationForm/RuleImplementationRawForm.js +16 -6
  50. package/src/components/ruleImplementationForm/__tests__/LimitsForm.spec.js +186 -0
  51. package/src/components/ruleImplementationForm/__tests__/RuleImplementationRawForm.spec.js +42 -35
  52. package/src/components/ruleImplementationForm/__tests__/__snapshots__/LimitsForm.spec.js.snap +1104 -0
  53. package/src/components/ruleImplementationForm/__tests__/__snapshots__/RuleImplementationForm.spec.js.snap +4 -1
  54. package/src/components/ruleImplementationForm/__tests__/__snapshots__/RuleImplementationRawForm.spec.js.snap +12 -1
  55. package/src/components/ruleImplementationForm/limitsValidation.js +72 -0
  56. package/src/messages/en.js +130 -71
  57. package/src/messages/es.js +253 -180
  58. package/src/reducers/__tests__/rule.spec.js +2 -4
  59. package/src/reducers/__tests__/ruleImplementation.spec.js +2 -0
  60. package/src/reducers/__tests__/ruleImplementations.spec.js +12 -8
  61. package/src/reducers/rule.js +0 -3
  62. package/src/reducers/ruleImplementation.js +3 -0
  63. package/src/reducers/ruleImplementations.js +3 -0
  64. package/src/selectors/getRuleImplementationColumns.js +38 -3
  65. package/src/selectors/ruleColumnsSelector.js +0 -31
  66. package/src/styles/ruleSummary.less +17 -10
@@ -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
- as="h2"
182
- content={ruleImplementation.implementation_key}
183
- icon={{ name: "clipboard check", circular: true }}
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 { 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
 
@@ -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;