@truedat/dq 4.44.4 → 4.44.5

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 (29) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/package.json +24 -17
  3. package/src/components/NewRuleImplementation.js +6 -29
  4. package/src/components/RemediationForm.js +20 -47
  5. package/src/components/RemediationPlan.js +1 -1
  6. package/src/components/RuleFilters.js +1 -5
  7. package/src/components/RuleForm.js +20 -59
  8. package/src/components/RuleImplementationFilters.js +1 -5
  9. package/src/components/__tests__/ExecutionForm.spec.js +14 -12
  10. package/src/components/__tests__/NewRuleImplementation.spec.js +27 -15
  11. package/src/components/__tests__/RemediationForm.spec.js +11 -46
  12. package/src/components/__tests__/RemediationPlan.spec.js +49 -73
  13. package/src/components/__tests__/RuleForm.spec.js +22 -52
  14. package/src/components/__tests__/RuleProperties.spec.js +39 -27
  15. package/src/components/__tests__/__snapshots__/ExecutionForm.spec.js.snap +75 -5
  16. package/src/components/__tests__/__snapshots__/NewRuleImplementation.spec.js.snap +202 -2
  17. package/src/components/__tests__/__snapshots__/RemediationForm.spec.js.snap +77 -3
  18. package/src/components/__tests__/__snapshots__/RemediationPlan.spec.js.snap +40 -1
  19. package/src/components/__tests__/__snapshots__/RuleForm.spec.js.snap +156 -6
  20. package/src/components/__tests__/__snapshots__/RuleImplementationsSearch.spec.js.snap +1 -1
  21. package/src/components/__tests__/__snapshots__/RuleProperties.spec.js.snap +68 -56
  22. package/src/components/__tests__/__snapshots__/RuleSearch.spec.js.snap +1 -1
  23. package/src/components/ruleImplementationForm/InformationForm.js +14 -33
  24. package/src/components/ruleImplementationForm/RuleImplementationForm.js +7 -11
  25. package/src/components/ruleImplementationForm/RuleImplementationRawForm.js +20 -39
  26. package/src/components/ruleImplementationForm/__tests__/RuleImplementationForm.spec.js +11 -7
  27. package/src/components/ruleImplementationForm/__tests__/RuleImplementationRawForm.spec.js +175 -156
  28. package/src/components/ruleImplementationForm/__tests__/__snapshots__/RuleImplementationForm.spec.js.snap +75 -0
  29. package/src/components/ruleImplementationForm/__tests__/__snapshots__/RuleImplementationRawForm.spec.js.snap +412 -165
@@ -1,62 +1,74 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
3
  exports[`<RuleProperties /> matches the latest snapshot 1`] = `
4
- <List
5
- relaxed={true}
6
- size="big"
7
- >
8
- <Label
9
- color="grey"
4
+ <div>
5
+ <div
6
+ class="ui big relaxed list"
7
+ role="list"
8
+ style=""
10
9
  >
11
- <MemoizedFormattedMessage
12
- id="rule.props.active.undefined"
13
- />
14
- </Label>
15
- <ListItem>
16
- <ListHeader
17
- as="h3"
10
+ <div
11
+ class="ui olive label"
18
12
  >
19
- <MemoizedFormattedMessage
20
- id="concepts.props.description"
21
- />
22
- </ListHeader>
23
- <lazy
24
- readOnly={true}
25
- value={
26
- Object {
27
- "document": Object {
28
- "data": Object {},
29
- "nodes": Array [
30
- Object {
31
- "data": Object {},
32
- "nodes": Array [
33
- Object {
34
- "marks": Array [
35
- Object {
36
- "data": Object {},
37
- "object": "text",
38
- "text": "desc1",
39
- },
40
- ],
41
- },
42
- ],
43
- },
44
- ],
45
- "object": "document",
46
- },
47
- }
48
- }
49
- />
50
- </ListItem>
51
- <ListItem>
52
- <ListHeader>
53
- <MemoizedFormattedMessage
54
- id="quality.domain"
55
- />
56
- </ListHeader>
57
- <ListContent>
58
- foo
59
- </ListContent>
60
- </ListItem>
61
- </List>
13
+ Active
14
+ </div>
15
+ <div
16
+ class="item"
17
+ role="listitem"
18
+ >
19
+ <h3
20
+ class="header"
21
+ >
22
+ Description
23
+ </h3>
24
+ <div>
25
+ <div
26
+ autocorrect="on"
27
+ data-gramm="false"
28
+ data-key="0"
29
+ data-slate-editor="true"
30
+ spellcheck="true"
31
+ style="outline: none; white-space: pre-wrap; word-wrap: break-word;"
32
+ >
33
+ <div
34
+ data-key="1"
35
+ data-slate-object="block"
36
+ style="position: relative;"
37
+ >
38
+ <span
39
+ data-key="2"
40
+ data-slate-object="text"
41
+ >
42
+ <span
43
+ data-offset-key="2:0"
44
+ data-slate-leaf="true"
45
+ >
46
+ <span
47
+ data-slate-string="true"
48
+ >
49
+ desc
50
+ </span>
51
+ </span>
52
+ </span>
53
+ </div>
54
+ </div>
55
+ </div>
56
+ </div>
57
+ <div
58
+ class="item"
59
+ role="listitem"
60
+ >
61
+ <div
62
+ class="header"
63
+ >
64
+ Domain
65
+ </div>
66
+ <div
67
+ class="content"
68
+ >
69
+ foo
70
+ </div>
71
+ </div>
72
+ </div>
73
+ </div>
62
74
  `;
@@ -2,7 +2,7 @@
2
2
 
3
3
  exports[`<RulesSearch /> matches the latest snapshot 1`] = `
4
4
  <Input
5
- action={<Memo(Connect(Component)) />}
5
+ action={<Memo(Connect(AvailableFilters)) />}
6
6
  icon={
7
7
  Object {
8
8
  "link": true,
@@ -4,43 +4,30 @@ import { connect } from "react-redux";
4
4
  import PropTypes from "prop-types";
5
5
  import { useIntl, FormattedMessage } from "react-intl";
6
6
  import { Form, Icon, Popup } from "semantic-ui-react";
7
- import { TemplateSelector } from "@truedat/core/components";
8
7
  import LimitsForm from "./LimitsForm";
9
8
 
10
9
  const DomainDropdownSelector = React.lazy(() =>
11
10
  import("@truedat/bg/taxonomy/components/DomainDropdownSelector")
12
11
  );
13
12
 
14
- const DynamicForm = React.lazy(() =>
15
- import("@truedat/df/components/DynamicForm")
13
+ const SelectableDynamicForm = React.lazy(() =>
14
+ import("@truedat/df/components/SelectableDynamicForm")
16
15
  );
17
16
 
18
17
  export const InformationForm = ({
19
18
  setImplementationKey,
20
19
  onChange,
21
20
  ruleImplementation,
22
- template,
23
- setTemplate,
21
+ setIsValid,
24
22
  rule,
25
23
  }) => {
26
24
  const { formatMessage } = useIntl();
27
25
 
28
- const handleTemplatesLoaded = ({ templates }) => {
29
- const name = ruleImplementation?.dfName;
30
- const template = name
31
- ? _.find(_.propEq("name", name))(templates)
32
- : _.size(templates) == 1
33
- ? templates[0]
34
- : null;
35
- setTemplate(template);
26
+ const handleContentChange = ({ content, valid }) => {
27
+ onChange("dfContent", content);
28
+ setIsValid(_.isEmpty(valid));
36
29
  };
37
-
38
- const handleTemplateSelected = (e, { template }) => {
39
- setTemplate(template);
40
- };
41
-
42
- const handleContentChange = (content) => onChange("dfContent", content);
43
-
30
+ const domainId = ruleImplementation?.domain_id || rule?.domain_id;
44
31
  return (
45
32
  <>
46
33
  <Form.Radio
@@ -86,20 +73,15 @@ export const InformationForm = ({
86
73
  </Form.Field>
87
74
  ) : null}
88
75
  <LimitsForm onChange={onChange} ruleImplementation={ruleImplementation} />
89
- <TemplateSelector
76
+ <SelectableDynamicForm
90
77
  scope="ri"
91
- selectedValue={template?.id}
92
- onChange={handleTemplateSelected}
93
- onLoad={handleTemplatesLoaded}
78
+ domainIds={_.isNil(domainId) ? null : [domainId]}
94
79
  required
80
+ content={ruleImplementation?.dfContent}
81
+ name={ruleImplementation?.dfName}
82
+ onChange={handleContentChange}
83
+ onNameChange={(dfName) => onChange("dfName", dfName)}
95
84
  />
96
- {template === null ? null : (
97
- <DynamicForm
98
- template={template}
99
- content={ruleImplementation?.dfContent}
100
- onChange={handleContentChange}
101
- />
102
- )}
103
85
  </>
104
86
  );
105
87
  };
@@ -109,8 +91,7 @@ InformationForm.propTypes = {
109
91
  rule: PropTypes.object,
110
92
  ruleImplementation: PropTypes.object,
111
93
  setImplementationKey: PropTypes.func,
112
- setTemplate: PropTypes.func,
113
- template: PropTypes.object,
94
+ setIsValid: PropTypes.func,
114
95
  };
115
96
 
116
97
  const mapStateToProps = ({ rule }) => ({ rule });
@@ -13,7 +13,6 @@ import {
13
13
  Step,
14
14
  Segment,
15
15
  } from "semantic-ui-react";
16
- import { validateContent } from "@truedat/df/utils";
17
16
  import PopulationForm from "./PopulationForm";
18
17
  import DatasetForm from "./DatasetForm";
19
18
  import ValidationsForm from "./ValidationsForm";
@@ -52,9 +51,7 @@ export const RuleImplementationForm = ({
52
51
  setPopulations,
53
52
  setSegments,
54
53
  setStructures,
55
- setTemplate,
56
54
  setValidations,
57
- template,
58
55
  }) => {
59
56
  const { formatMessage } = useIntl();
60
57
  const history = useHistory();
@@ -76,18 +73,20 @@ export const RuleImplementationForm = ({
76
73
 
77
74
  const [activeStep, setActiveStep] = useState("information");
78
75
  const [selector, setSelector] = useState();
76
+ const [isContentValid, setContentIsValid] = useState();
79
77
 
80
78
  const {
81
79
  dataset: structures,
82
80
  populations,
83
81
  validations,
84
- dfContent,
82
+ dfName,
85
83
  segments,
86
84
  } = ruleImplementation || {};
87
85
 
88
86
  const validInformation = () =>
89
- template &&
90
- _.size(validateContent(template)(dfContent)) == 0 &&
87
+ dfName &&
88
+ !_.isEmpty(dfName) &&
89
+ isContentValid &&
91
90
  (!_.isEmpty(rule) || _.isNumber(_.prop("domain_id")(ruleImplementation))) &&
92
91
  areLimitsValid(ruleImplementation);
93
92
 
@@ -242,8 +241,7 @@ export const RuleImplementationForm = ({
242
241
  onChange,
243
242
  ruleImplementation,
244
243
  setImplementationKey,
245
- setTemplate,
246
- template,
244
+ setIsValid: setContentIsValid,
247
245
  }}
248
246
  />
249
247
  )}
@@ -358,9 +356,7 @@ RuleImplementationForm.propTypes = {
358
356
  setPopulations: PropTypes.func,
359
357
  setSegments: PropTypes.func,
360
358
  setStructures: PropTypes.func,
361
- setTemplate: PropTypes.func,
362
359
  setValidations: PropTypes.func,
363
- template: PropTypes.object,
364
360
  rule: PropTypes.object,
365
361
  };
366
362
 
@@ -370,7 +366,7 @@ const mapStateToProps = ({
370
366
  userRulePermissions,
371
367
  implementationActions,
372
368
  }) => ({
373
- rule: rule,
369
+ rule,
374
370
  isSubmitting: ruleImplementationCreating,
375
371
  authManageSegments:
376
372
  !!userRulePermissions?.manage_segments ||
@@ -1,18 +1,16 @@
1
1
  import _ from "lodash/fp";
2
- import React from "react";
2
+ import React, { useState } from "react";
3
3
  import PropTypes from "prop-types";
4
4
  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 { TemplateSelector } from "@truedat/core/components";
9
8
  import { accentInsensitivePathOrder } from "@truedat/core/services/sort";
10
- import { validateContent as validDfContent } from "@truedat/df/utils";
11
9
  import LimitsForm from "./LimitsForm";
12
10
  import { areLimitsValid } from "./limitsValidation";
13
11
 
14
- const DynamicForm = React.lazy(() =>
15
- import("@truedat/df/components/DynamicForm")
12
+ const SelectableDynamicForm = React.lazy(() =>
13
+ import("@truedat/df/components/SelectableDynamicForm")
16
14
  );
17
15
 
18
16
  const DomainDropdownSelector = React.lazy(() =>
@@ -47,30 +45,18 @@ export const RuleImplementationRawForm = ({
47
45
  ruleImplementation,
48
46
  setImplementationKey,
49
47
  setImplementationRawContent,
50
- setTemplate,
51
48
  sources,
52
49
  sourcesLoading,
53
- template = {},
54
50
  }) => {
55
51
  const { formatMessage } = useIntl();
56
52
  const history = useHistory();
53
+ const [isContentValid, setIsContentValid] = useState();
57
54
 
58
- const handleTemplatesLoaded = ({ templates }) => {
59
- const name = ruleImplementation?.dfName;
60
- const template = name
61
- ? _.find(_.propEq("name", name))(templates)
62
- : _.size(templates) == 1
63
- ? templates[0]
64
- : null;
65
- setTemplate(template);
55
+ const handleContentChange = ({ content, valid }) => {
56
+ onChange("dfContent", content);
57
+ setIsContentValid(_.isEmpty(valid));
66
58
  };
67
59
 
68
- const handleTemplateSelected = (e, { template }) => {
69
- setTemplate(template);
70
- };
71
-
72
- const handleContentChange = (content) => onChange("dfContent", content);
73
-
74
60
  const isNilOrEmpty = (propName) =>
75
61
  _.isNil(_.prop(propName)(rawContent)) ||
76
62
  _.prop(propName)(rawContent) === "";
@@ -119,9 +105,9 @@ export const RuleImplementationRawForm = ({
119
105
  return text ? text.match(re) : [];
120
106
  };
121
107
  const validInformation = () =>
122
- template &&
123
- !_.isEmpty(template) &&
124
- _.size(validDfContent(template)(ruleImplementation?.dfContent)) == 0 &&
108
+ ruleImplementation?.dfName &&
109
+ !_.isEmpty(ruleImplementation?.dfName) &&
110
+ isContentValid &&
125
111
  (!_.isEmpty(rule) || _.isNumber(_.prop("domain_id")(ruleImplementation))) &&
126
112
  areLimitsValid(ruleImplementation);
127
113
 
@@ -157,6 +143,7 @@ export const RuleImplementationRawForm = ({
157
143
  const doCancel = () => history.goBack();
158
144
  const errors = getErrors();
159
145
 
146
+ const domainId = ruleImplementation?.domain_id || rule?.domain_id;
160
147
  return (
161
148
  <Form className="rule">
162
149
  <Form.Radio
@@ -185,26 +172,21 @@ export const RuleImplementationRawForm = ({
185
172
  {_.isEmpty(rule) && !ruleImplementation?.rule_id && (
186
173
  <Form.Field>
187
174
  <DomainDropdownSelector
188
- value={ruleImplementation.domain_id}
175
+ value={domainId}
189
176
  onChange={(_e, { value }) => onChange("domain_id", value)}
190
177
  />
191
178
  </Form.Field>
192
179
  )}
193
180
  <LimitsForm onChange={onChange} ruleImplementation={ruleImplementation} />
194
- <TemplateSelector
181
+ <SelectableDynamicForm
195
182
  scope="ri"
196
- selectedValue={template?.id}
197
- onChange={handleTemplateSelected}
198
- onLoad={handleTemplatesLoaded}
183
+ domainIds={_.isNil(domainId) ? null : [domainId]}
199
184
  required
185
+ content={ruleImplementation?.dfContent}
186
+ name={ruleImplementation?.dfName}
187
+ onChange={handleContentChange}
188
+ onNameChange={(dfName) => onChange("dfName", dfName)}
200
189
  />
201
- {template?.id ? (
202
- <DynamicForm
203
- template={template}
204
- content={_.prop("dfContent")(ruleImplementation)}
205
- onChange={handleContentChange}
206
- />
207
- ) : null}
208
190
  <Form.Dropdown
209
191
  label={
210
192
  <label>
@@ -252,11 +234,12 @@ export const RuleImplementationRawForm = ({
252
234
  }
253
235
  }
254
236
  label={
255
- <label>
237
+ <label htmlFor="dataset">
256
238
  <FormattedMessage id="ruleImplementationRawForm.props.dataset" />
257
239
  <Help message="ruleImplementationRawForm.props.dataset.help"></Help>
258
240
  </label>
259
241
  }
242
+ id="dataset"
260
243
  name="dataset"
261
244
  onChange={(e, { value }) => onChangeImplementation("dataset", value)}
262
245
  placeholder={formatMessage({
@@ -343,10 +326,8 @@ RuleImplementationRawForm.propTypes = {
343
326
  ruleImplementation: PropTypes.object,
344
327
  setImplementationKey: PropTypes.func,
345
328
  setImplementationRawContent: PropTypes.func,
346
- setTemplate: PropTypes.func,
347
329
  sources: PropTypes.array,
348
330
  sourcesLoading: PropTypes.bool,
349
- template: PropTypes.object,
350
331
  };
351
332
 
352
333
  const mapStateToProps = ({ rule, ruleImplementationCreating }) => ({
@@ -1,19 +1,23 @@
1
- import React, { Suspense } from "react";
1
+ import React from "react";
2
2
  import { waitFor } from "@testing-library/react";
3
3
  import { render } from "@truedat/test/render";
4
+ import { multipleTemplatesMock } from "@truedat/test/mocks";
4
5
  import RuleImplementationForm from "../RuleImplementationForm";
5
6
 
6
7
  const renderOpts = {
8
+ mocks: [multipleTemplatesMock({ scope: "ri", domainIds: null })],
7
9
  state: {
8
10
  rule: {},
9
11
  implementationActions: { manage_segments: {} },
10
12
  ruleImplementationCreating: true,
11
13
  },
14
+ fallback: "lazy",
12
15
  };
13
16
 
14
17
  describe("<RuleImplementationForm />", () => {
15
18
  const props = {
16
19
  onSubmit: jest.fn(),
20
+ onChange: jest.fn(),
17
21
  ruleImplementation: {
18
22
  implementationKey: "foo",
19
23
  executable: true,
@@ -25,14 +29,14 @@ describe("<RuleImplementationForm />", () => {
25
29
 
26
30
  it("matches the latest snapshot", async () => {
27
31
  const { container, queryByText } = render(
28
- <Suspense fallback="loading...">
29
- <RuleImplementationForm {...props} />
30
- </Suspense>,
32
+ <RuleImplementationForm {...props} />,
31
33
  renderOpts
32
34
  );
33
- await waitFor(() => {
34
- expect(queryByText(/loading/i)).not.toBeInTheDocument();
35
- });
35
+
36
+ await waitFor(() =>
37
+ expect(queryByText(/loading/i)).not.toBeInTheDocument()
38
+ );
39
+ await waitFor(() => expect(queryByText(/lazy/i)).not.toBeInTheDocument());
36
40
  expect(container).toMatchSnapshot();
37
41
  });
38
42
  });