@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
@@ -22,55 +22,10 @@ exports[`<RuleImplementationsActions /> matches the latest snapshot 1`] = `
22
22
  toggle={true}
23
23
  type="checkbox"
24
24
  />
25
- <ConfirmModal
26
- actions={
27
- Array [
28
- Object {
29
- "content": <Memo(MemoizedFormattedMessage)
30
- id="confirmation.no"
31
- />,
32
- "key": "no",
33
- "secondary": true,
34
- },
35
- Object {
36
- "content": <Memo(MemoizedFormattedMessage)
37
- id="confirmation.yes"
38
- />,
39
- "key": "yes",
40
- "onClick": [Function],
41
- "primary": true,
42
- },
43
- ]
44
- }
45
- content={
46
- <Memo(MemoizedFormattedMessage)
47
- id="implementations.actions.execution.confirmation.content"
48
- values={
49
- Object {
50
- "implementations_count": 12,
51
- }
52
- }
53
- />
54
- }
55
- header={
56
- <Memo(MemoizedFormattedMessage)
57
- id="implementations.actions.execution.confirmation.header"
58
- />
59
- }
60
- trigger={
61
- <Button
62
- as="button"
63
- content={
64
- <Memo(MemoizedFormattedMessage)
65
- id="implementations.actions.do_execution"
66
- />
67
- }
68
- disabled={true}
69
- id="execute_button"
70
- loading={false}
71
- secondary={true}
72
- />
73
- }
25
+ <Connect(ExecutionPopup)
26
+ count={12}
27
+ disabled={true}
28
+ handleSubmit={[Function]}
74
29
  />
75
30
  <Button
76
31
  as="button"
@@ -81,5 +36,6 @@ exports[`<RuleImplementationsActions /> matches the latest snapshot 1`] = `
81
36
  onClick={[Function]}
82
37
  secondary={true}
83
38
  />
39
+ <Connect(ImplementationsUploadButton) />
84
40
  </div>
85
41
  `;
@@ -58,6 +58,5 @@ exports[`<RuleProperties /> matches the latest snapshot 1`] = `
58
58
  foo
59
59
  </ListContent>
60
60
  </ListItem>
61
- <Connect(RuleRangeNumber) />
62
61
  </List>
63
62
  `;
@@ -24,19 +24,6 @@ exports[`<RuleRow /> matches the latest snapshot 1`] = `
24
24
  >
25
25
 
26
26
  </td>
27
- <td
28
- class=""
29
- />
30
- <td
31
- class="right aligned"
32
- >
33
- 1%
34
- </td>
35
- <td
36
- class="right aligned"
37
- >
38
- 22%
39
- </td>
40
27
  </tr>
41
28
  </tbody>
42
29
  </table>
@@ -66,21 +53,6 @@ exports[`<RuleRow /> row prints column fields 1`] = `
66
53
  class=""
67
54
  >
68
55
 
69
- </td>
70
- <td
71
- class=""
72
- >
73
- Percentage
74
- </td>
75
- <td
76
- class="right aligned"
77
- >
78
- 1%
79
- </td>
80
- <td
81
- class="right aligned"
82
- >
83
- 22%
84
56
  </td>
85
57
  <td
86
58
  class=""
@@ -57,47 +57,6 @@ exports[`<Rules /> matches the latest snapshot 1`] = `
57
57
  sorted={null}
58
58
  width={3}
59
59
  />
60
- <TableHeaderCell
61
- as="th"
62
- className=""
63
- content={
64
- <Memo(MemoizedFormattedMessage)
65
- id="quality.result_type"
66
- />
67
- }
68
- key="3"
69
- onClick={[Function]}
70
- sorted={null}
71
- width={2}
72
- />
73
- <TableHeaderCell
74
- as="th"
75
- className=""
76
- content={
77
- <Memo(MemoizedFormattedMessage)
78
- id="quality.minimum"
79
- />
80
- }
81
- key="4"
82
- onClick={[Function]}
83
- sorted={null}
84
- textAlign="right"
85
- width={1}
86
- />
87
- <TableHeaderCell
88
- as="th"
89
- className=""
90
- content={
91
- <Memo(MemoizedFormattedMessage)
92
- id="quality.goal.list"
93
- />
94
- }
95
- key="5"
96
- onClick={[Function]}
97
- sorted={null}
98
- textAlign="right"
99
- width={1}
100
- />
101
60
  </TableRow>
102
61
  </TableHeader>
103
62
  <TableBody
@@ -131,34 +90,6 @@ exports[`<Rules /> matches the latest snapshot 1`] = `
131
90
  },
132
91
  "width": 3,
133
92
  },
134
- Object {
135
- "fieldDecorator": [Function],
136
- "name": "result_type",
137
- "sort": Object {
138
- "name": "result_type.raw",
139
- },
140
- "width": 2,
141
- },
142
- Object {
143
- "fieldDecorator": [Function],
144
- "fieldSelector": [Function],
145
- "name": "minimum",
146
- "sort": Object {
147
- "name": "minimum",
148
- },
149
- "textAlign": "right",
150
- "width": 1,
151
- },
152
- Object {
153
- "fieldDecorator": [Function],
154
- "fieldSelector": [Function],
155
- "name": "goal.list",
156
- "sort": Object {
157
- "name": "goal",
158
- },
159
- "textAlign": "right",
160
- "width": 1,
161
- },
162
93
  ]
163
94
  }
164
95
  key="0"
@@ -166,9 +97,7 @@ exports[`<Rules /> matches the latest snapshot 1`] = `
166
97
  Object {
167
98
  "business_concept_id": "2D2B3",
168
99
  "description": "desc1",
169
- "goal": 10,
170
100
  "id": 123,
171
- "minimum": 1,
172
101
  "name": "control1",
173
102
  "status": "status1",
174
103
  "type": "type1",
@@ -204,34 +133,6 @@ exports[`<Rules /> matches the latest snapshot 1`] = `
204
133
  },
205
134
  "width": 3,
206
135
  },
207
- Object {
208
- "fieldDecorator": [Function],
209
- "name": "result_type",
210
- "sort": Object {
211
- "name": "result_type.raw",
212
- },
213
- "width": 2,
214
- },
215
- Object {
216
- "fieldDecorator": [Function],
217
- "fieldSelector": [Function],
218
- "name": "minimum",
219
- "sort": Object {
220
- "name": "minimum",
221
- },
222
- "textAlign": "right",
223
- "width": 1,
224
- },
225
- Object {
226
- "fieldDecorator": [Function],
227
- "fieldSelector": [Function],
228
- "name": "goal.list",
229
- "sort": Object {
230
- "name": "goal",
231
- },
232
- "textAlign": "right",
233
- "width": 1,
234
- },
235
136
  ]
236
137
  }
237
138
  key="1"
@@ -239,9 +140,7 @@ exports[`<Rules /> matches the latest snapshot 1`] = `
239
140
  Object {
240
141
  "business_concept_id": "2D2B4",
241
142
  "description": "desc2",
242
- "goal": 10,
243
143
  "id": 122,
244
- "minimum": 1,
245
144
  "name": "control2",
246
145
  "status": "status2",
247
146
  "type": "type2",
@@ -6,6 +6,8 @@ import { useIntl } from "react-intl";
6
6
  import { Form, Icon, Popup } from "semantic-ui-react";
7
7
  import { selectTemplate } from "@truedat/df/routines";
8
8
 
9
+ import LimitsForm from "./LimitsForm";
10
+
9
11
  const TemplateSelector = React.lazy(() =>
10
12
  import("@truedat/df/templates/components/TemplateSelector")
11
13
  );
@@ -33,12 +35,11 @@ const ImplementationDynamicForm = ({
33
35
  ? firstTemplate
34
36
  : {}
35
37
  );
36
-
37
- selectTemplate({ id: templateId });
38
+ if (templateId !== undefined) selectTemplate({ id: templateId });
38
39
  }, [ruleImplementation, selectTemplate, templates]);
39
40
 
40
41
  const handleContentChange = (content) => onChange("dfContent", content);
41
- const handleTemplateSelected = (e, { value }) =>
42
+ const handleTemplateSelected = (_e, { value }) =>
42
43
  selectTemplate({ id: value });
43
44
 
44
45
  return (
@@ -47,7 +48,6 @@ const ImplementationDynamicForm = ({
47
48
  name="template"
48
49
  selectedValue={_.prop("id")(template)}
49
50
  onChange={handleTemplateSelected}
50
- isOptional={true}
51
51
  />
52
52
  {template && template.id && (
53
53
  <DynamicForm
@@ -113,7 +113,7 @@ export const InformationForm = ({
113
113
  autoComplete="off"
114
114
  />
115
115
  </Form.Field>
116
-
116
+ <LimitsForm onChange={onChange} ruleImplementation={ruleImplementation} />
117
117
  {!_.isEmpty(templates) && (
118
118
  <ImplementationDynamicForm
119
119
  selectTemplate={selectTemplate}
@@ -0,0 +1,142 @@
1
+ import _ from "lodash/fp";
2
+ import React from "react";
3
+ import PropTypes from "prop-types";
4
+ import { useIntl } from "react-intl";
5
+ import { Form, Icon, Popup, Label, Segment } from "semantic-ui-react";
6
+
7
+ import generateValidationMessages from "./limitsValidation";
8
+
9
+ export const FieldLabelWrapping = ({
10
+ children,
11
+ label,
12
+ required,
13
+ tooltip,
14
+ message,
15
+ }) => (
16
+ <Form.Field>
17
+ <label className="rule-form-label">
18
+ {label}
19
+ {required && <span>*</span>}
20
+ {tooltip && (
21
+ <Popup
22
+ trigger={
23
+ <Icon className="rule-form-popup" name="question circle outline" />
24
+ }
25
+ content={tooltip}
26
+ on="click"
27
+ hideOnScroll
28
+ />
29
+ )}
30
+ {message && <Label pointing="left">{message}</Label>}
31
+ </label>
32
+ {children}
33
+ </Form.Field>
34
+ );
35
+
36
+ FieldLabelWrapping.propTypes = {
37
+ children: PropTypes.node,
38
+ label: PropTypes.string,
39
+ required: PropTypes.bool,
40
+ tooltip: PropTypes.string,
41
+ message: PropTypes.string,
42
+ };
43
+
44
+ export default function LimitsForm({ onChange, ruleImplementation }) {
45
+ const { formatMessage } = useIntl();
46
+ const handleChange = (e, { name, value }) => {
47
+ e && e.preventDefault();
48
+ onChange(name, value);
49
+ };
50
+
51
+ const { minimum: minimumMessage, goal: goalMessage } =
52
+ generateValidationMessages(ruleImplementation);
53
+
54
+ return (
55
+ <Segment>
56
+ <FieldLabelWrapping
57
+ label={formatMessage({ id: "ruleImplementations.props.result_type" })}
58
+ required
59
+ tooltip={formatMessage({
60
+ id: "ruleImplementation.form.tooltip.result_type",
61
+ })}
62
+ >
63
+ <Form.Group inline>
64
+ <Form.Radio
65
+ name={"result_type"}
66
+ label={formatMessage({
67
+ id: "ruleImplementations.props.result_type.percentage",
68
+ })}
69
+ value={"percentage"}
70
+ checked={ruleImplementation.result_type == "percentage"}
71
+ onChange={handleChange}
72
+ />
73
+ <Form.Radio
74
+ name={"result_type"}
75
+ label={formatMessage({
76
+ id: "ruleImplementations.props.result_type.deviation",
77
+ })}
78
+ value={"deviation"}
79
+ checked={ruleImplementation.result_type == "deviation"}
80
+ onChange={handleChange}
81
+ />
82
+ <Form.Radio
83
+ name={"result_type"}
84
+ label={formatMessage({
85
+ id: "ruleImplementations.props.result_type.errors_number",
86
+ })}
87
+ value={"errors_number"}
88
+ checked={ruleImplementation.result_type == "errors_number"}
89
+ onChange={handleChange}
90
+ />
91
+ </Form.Group>
92
+ </FieldLabelWrapping>
93
+ <FieldLabelWrapping
94
+ label={formatMessage({ id: "ruleImplementations.props.minimum" })}
95
+ message={minimumMessage && formatMessage({ id: minimumMessage })}
96
+ required
97
+ tooltip={formatMessage({
98
+ id: `ruleImplementation.form.tooltip.${ruleImplementation.result_type}.minimum`,
99
+ })}
100
+ >
101
+ <Form.Input
102
+ name="minimum"
103
+ onChange={handleChange}
104
+ value={
105
+ _.isNil(ruleImplementation.minimum)
106
+ ? ""
107
+ : ruleImplementation.minimum
108
+ }
109
+ placeholder={formatMessage({
110
+ id: "ruleImplementations.props.minimum.placeholder",
111
+ })}
112
+ autoComplete="off"
113
+ />
114
+ </FieldLabelWrapping>
115
+ <FieldLabelWrapping
116
+ label={formatMessage({ id: "ruleImplementations.props.goal" })}
117
+ message={goalMessage && formatMessage({ id: goalMessage })}
118
+ required
119
+ tooltip={formatMessage({
120
+ id: `ruleImplementation.form.tooltip.${ruleImplementation.result_type}.goal`,
121
+ })}
122
+ >
123
+ <Form.Input
124
+ name="goal"
125
+ onChange={handleChange}
126
+ value={
127
+ _.isNil(ruleImplementation.goal) ? "" : ruleImplementation.goal
128
+ }
129
+ placeholder={formatMessage({
130
+ id: "ruleImplementations.props.goal.placeholder",
131
+ })}
132
+ autoComplete="off"
133
+ />
134
+ </FieldLabelWrapping>
135
+ </Segment>
136
+ );
137
+ }
138
+
139
+ LimitsForm.propTypes = {
140
+ ruleImplementation: PropTypes.object,
141
+ onChange: PropTypes.func,
142
+ };
@@ -5,10 +5,12 @@ import { connect } from "react-redux";
5
5
  import { useHistory } from "react-router-dom";
6
6
  import { FormattedMessage, useIntl } from "react-intl";
7
7
  import { Button, Divider, Form, Grid, Icon, Step } from "semantic-ui-react";
8
+ import { validateContent } from "@truedat/df/utils";
8
9
  import PopulationForm from "./PopulationForm";
9
10
  import DatasetForm from "./DatasetForm";
10
11
  import ValidationsForm from "./ValidationsForm";
11
12
  import InformationForm from "./InformationForm";
13
+ import { areLimitsValid } from "./limitsValidation";
12
14
 
13
15
  const RuleImplementationStep = ({ activeStep, name, icon }) => (
14
16
  <Step active={activeStep == name}>
@@ -37,12 +39,12 @@ export const RuleImplementationForm = ({
37
39
  handleSubmit,
38
40
  operators,
39
41
  onChange,
40
- applyTemplate,
42
+ template,
41
43
  }) => {
42
44
  const { formatMessage } = useIntl();
43
45
  const history = useHistory();
44
46
  const steps = [
45
- { name: "information", icon: "info", isValid: () => true },
47
+ { name: "information", icon: "info", isValid: () => validInformation() },
46
48
  { name: "dataset", icon: "database", isValid: () => validDataSet() },
47
49
  { name: "population", icon: "user", isValid: () => validPopulation() },
48
50
  { name: "validations", icon: "setting", isValid: () => validValidations() },
@@ -55,8 +57,15 @@ export const RuleImplementationForm = ({
55
57
  dataset: structures,
56
58
  population,
57
59
  validations,
60
+ dfContent,
58
61
  } = ruleImplementation || {};
59
62
 
63
+ const validInformation = () =>
64
+ template &&
65
+ !_.isEmpty(template) &&
66
+ _.size(validateContent(template)(dfContent)) == 0 &&
67
+ areLimitsValid(ruleImplementation);
68
+
60
69
  const validPopulation = () =>
61
70
  _.every(_.isEmpty)(population) || populationComplete();
62
71
 
@@ -208,7 +217,6 @@ export const RuleImplementationForm = ({
208
217
  setImplementationKey,
209
218
  ruleImplementation,
210
219
  onChange,
211
- applyTemplate,
212
220
  }}
213
221
  />
214
222
  )}
@@ -241,6 +249,7 @@ export const RuleImplementationForm = ({
241
249
  )}
242
250
  </Form>
243
251
  </Grid.Row>
252
+ <Divider hidden />
244
253
  <Grid.Row stretched>
245
254
  <Button
246
255
  floated="right"
@@ -287,11 +296,12 @@ RuleImplementationForm.propTypes = {
287
296
  setValidations: PropTypes.func,
288
297
  operators: PropTypes.object,
289
298
  onChange: PropTypes.func,
290
- applyTemplate: PropTypes.func,
299
+ template: PropTypes.object,
291
300
  };
292
301
 
293
302
  const mapStateToProps = (state) => ({
294
303
  isSubmitting: state.ruleImplementationCreating,
304
+ template: state.template,
295
305
  });
296
306
 
297
307
  export default connect(mapStateToProps)(RuleImplementationForm);
@@ -5,7 +5,10 @@ import { connect } from "react-redux";
5
5
  import { useHistory } from "react-router-dom";
6
6
  import { FormattedMessage, useIntl } from "react-intl";
7
7
  import { Button, Form, Icon, Popup } from "semantic-ui-react";
8
+ import { validateContent as validDfContent } from "@truedat/df/utils";
8
9
  import { selectTemplate } from "@truedat/df/routines";
10
+ import LimitsForm from "./LimitsForm";
11
+ import { areLimitsValid } from "./limitsValidation";
9
12
 
10
13
  const Help = ({ message }) => {
11
14
  const { formatMessage } = useIntl();
@@ -60,7 +63,6 @@ const ImplementationDynamicForm = ({
60
63
  name="template"
61
64
  selectedValue={_.prop("id")(template)}
62
65
  onChange={handleTemplateSelected}
63
- isOptional={true}
64
66
  />
65
67
  {template && template.id && (
66
68
  <DynamicForm
@@ -84,7 +86,6 @@ export const RuleImplementationRawForm = ({
84
86
  handleSubmit,
85
87
  isSubmitting,
86
88
  implementationKey,
87
- mode,
88
89
  rawContent,
89
90
  setImplementationKey,
90
91
  setImplementationRawContent,
@@ -148,9 +149,15 @@ export const RuleImplementationRawForm = ({
148
149
  /\b(DROP|DELETE|INSERT|UPDATE|CALL|EXEC|EXECUTE|ALTER)\b|;|--|#/gi;
149
150
  return text ? text.match(re) : [];
150
151
  };
152
+ const validInformation = () =>
153
+ template &&
154
+ !_.isEmpty(template) &&
155
+ _.size(validDfContent(template)(ruleImplementation?.dfContent)) == 0 &&
156
+ areLimitsValid(ruleImplementation);
151
157
 
152
158
  const isValidForm = () => {
153
159
  return (
160
+ validInformation() &&
154
161
  isNotEmptyProp("source_id") &&
155
162
  (_.isEmpty(databasesOptions) || isNotEmptyProp("database")) &&
156
163
  _.every(isNotEmptyProp)(["dataset", "validations"]) &&
@@ -208,11 +215,14 @@ export const RuleImplementationRawForm = ({
208
215
  placeholder={formatMessage({
209
216
  id: "ruleImplementation.props.name.placeholder",
210
217
  })}
211
- readOnly={mode == "edition"}
212
218
  required
213
219
  value={implementationKey}
214
220
  />
215
221
  </Form.Field>
222
+ <LimitsForm
223
+ onChange={onChange}
224
+ ruleImplementation={ruleImplementation}
225
+ />
216
226
  {!_.isEmpty(templates) && (
217
227
  <ImplementationDynamicForm
218
228
  selectTemplate={selectTemplate}
@@ -279,7 +289,7 @@ export const RuleImplementationRawForm = ({
279
289
  required
280
290
  rows={4}
281
291
  size="small"
282
- value={_.prop("dataset")(rawContent)}
292
+ value={_.prop("dataset")(rawContent) || ""}
283
293
  />
284
294
  <Form.TextArea
285
295
  className="raw"
@@ -303,7 +313,7 @@ export const RuleImplementationRawForm = ({
303
313
  })}
304
314
  rows={4}
305
315
  size="small"
306
- value={_.prop("population")(rawContent)}
316
+ value={_.prop("population")(rawContent) || ""}
307
317
  />
308
318
  <Form.TextArea
309
319
  className="raw"
@@ -328,7 +338,7 @@ export const RuleImplementationRawForm = ({
328
338
  required
329
339
  rows={4}
330
340
  size="small"
331
- value={_.prop("validations")(rawContent)}
341
+ value={_.prop("validations")(rawContent) || ""}
332
342
  />
333
343
  <Form.Button
334
344
  floated="right"