@truedat/dq 4.47.7 → 4.48.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.
- package/CHANGELOG.md +13 -0
- package/package.json +5 -5
- package/src/components/ConditionSummary.js +23 -12
- package/src/components/FieldSummary.js +5 -4
- package/src/components/ImplementationSummary.js +26 -14
- package/src/components/NewRuleImplementation.js +15 -12
- package/src/components/__tests__/NewRuleImplementation.spec.js +129 -123
- package/src/components/__tests__/__snapshots__/ImplementationSummary.spec.js.snap +4 -0
- package/src/components/__tests__/__snapshots__/NewRuleImplementation.spec.js.snap +8 -0
- package/src/components/ruleImplementationForm/DatasetForm.js +94 -31
- package/src/components/ruleImplementationForm/FieldsGrid.js +1 -1
- package/src/components/ruleImplementationForm/FieldsGroup.js +2 -7
- package/src/components/ruleImplementationForm/FiltersField.js +14 -11
- package/src/components/ruleImplementationForm/FiltersFormGroup.js +2 -8
- package/src/components/ruleImplementationForm/FiltersGrid.js +2 -1
- package/src/components/ruleImplementationForm/ValueConditions.js +1 -1
- package/src/components/ruleImplementationForm/__tests__/DataSetForm.spec.js +29 -4
- package/src/components/ruleImplementationForm/__tests__/FiltersField.spec.js +1 -1
- package/src/components/ruleImplementationForm/__tests__/__snapshots__/DataSetForm.spec.js.snap +95 -6
- package/src/messages/en.js +4 -0
- package/src/messages/es.js +4 -0
- package/src/reducers/dqMessage.js +10 -0
- package/src/selectors/getImplementationStructures.js +8 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [4.48.0] 2022-07-07
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- [TD-4925] Add info messages on implementation updates
|
|
8
|
+
(like 'implementation unchanged')
|
|
9
|
+
|
|
10
|
+
## [4.47.9] 2022-07-05
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- [TD-4661] Support for ReferenceDatasets on Implementations
|
|
15
|
+
|
|
3
16
|
## [4.47.6] 2022-07-01
|
|
4
17
|
|
|
5
18
|
### Fixed
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truedat/dq",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.48.0",
|
|
4
4
|
"description": "Truedat Web Data Quality Module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"jsnext:main": "src/index.js",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"@testing-library/jest-dom": "^5.16.4",
|
|
35
35
|
"@testing-library/react": "^12.0.0",
|
|
36
36
|
"@testing-library/user-event": "^13.2.1",
|
|
37
|
-
"@truedat/test": "4.47.
|
|
37
|
+
"@truedat/test": "4.47.9",
|
|
38
38
|
"babel-jest": "^28.1.0",
|
|
39
39
|
"babel-plugin-dynamic-import-node": "^2.3.3",
|
|
40
40
|
"babel-plugin-lodash": "^3.3.4",
|
|
@@ -88,8 +88,8 @@
|
|
|
88
88
|
},
|
|
89
89
|
"dependencies": {
|
|
90
90
|
"@apollo/client": "^3.6.4",
|
|
91
|
-
"@truedat/core": "4.
|
|
92
|
-
"@truedat/df": "4.
|
|
91
|
+
"@truedat/core": "4.48.0",
|
|
92
|
+
"@truedat/df": "4.48.0",
|
|
93
93
|
"axios": "^0.19.2",
|
|
94
94
|
"graphql": "^15.5.3",
|
|
95
95
|
"path-to-regexp": "^1.7.0",
|
|
@@ -110,5 +110,5 @@
|
|
|
110
110
|
"react-dom": ">= 16.8.6 < 17",
|
|
111
111
|
"semantic-ui-react": ">= 0.88.2 < 2.1"
|
|
112
112
|
},
|
|
113
|
-
"gitHead": "
|
|
113
|
+
"gitHead": "c4587d045fa6c9028082bdfbcfb35e4383f117ed"
|
|
114
114
|
}
|
|
@@ -15,7 +15,9 @@ const LinkToStructure = ({ value }) =>
|
|
|
15
15
|
!_.isEmpty(value.path) ? path(value) : value.name
|
|
16
16
|
}"`}</span>{" "}
|
|
17
17
|
</Link>
|
|
18
|
-
) :
|
|
18
|
+
) : (
|
|
19
|
+
<span>{value.name}</span>
|
|
20
|
+
);
|
|
19
21
|
|
|
20
22
|
const FormattedLink = ({ value, operator = {} }) => {
|
|
21
23
|
switch (operator?.value_type) {
|
|
@@ -95,7 +97,12 @@ export const empty = (rows) =>
|
|
|
95
97
|
export const getValues = ({ value = [], operator = {}, value_modifier }) => {
|
|
96
98
|
const defaultOrValue = value || [];
|
|
97
99
|
return ["field", "field_list"].includes(operator?.value_type)
|
|
98
|
-
? valuesFromKeys(
|
|
100
|
+
? valuesFromKeys(
|
|
101
|
+
defaultOrValue,
|
|
102
|
+
["name"],
|
|
103
|
+
["path", "id", "type", "parent_index"],
|
|
104
|
+
value_modifier
|
|
105
|
+
)
|
|
99
106
|
: valuesFromKeys(defaultOrValue, ["raw"], [], value_modifier);
|
|
100
107
|
};
|
|
101
108
|
|
|
@@ -129,16 +136,20 @@ const ConditionCell = ({ row, alias }) => {
|
|
|
129
136
|
<Table.Cell width={5}>
|
|
130
137
|
{_.has("structure")(row) && (
|
|
131
138
|
<>
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
139
|
+
{_.path("structure.id")(row) ? (
|
|
140
|
+
<Link
|
|
141
|
+
to={linkTo.STRUCTURE({
|
|
142
|
+
id: _.path("structure.id")(row),
|
|
143
|
+
})}
|
|
144
|
+
>
|
|
145
|
+
<span className="highlighted">
|
|
146
|
+
{alias_text && `(${alias_text}).`}{" "}
|
|
147
|
+
{`"${_.pathOr("", "structure.name")(row)}"`}
|
|
148
|
+
</span>
|
|
149
|
+
</Link>
|
|
150
|
+
) : (
|
|
151
|
+
<span>{_.path("structure.name")(row)}</span>
|
|
152
|
+
)}
|
|
142
153
|
{row?.modifier && (
|
|
143
154
|
<>
|
|
144
155
|
<div className="smaller">
|
|
@@ -18,8 +18,8 @@ const ConditionCell = ({ row, alias }) => {
|
|
|
18
18
|
return (
|
|
19
19
|
<Table.Row>
|
|
20
20
|
<Table.Cell width={5}>
|
|
21
|
-
{_.has("structure")(row) &&
|
|
22
|
-
|
|
21
|
+
{_.has("structure")(row) &&
|
|
22
|
+
(_.prop("structure.id")(row) ? (
|
|
23
23
|
<Link
|
|
24
24
|
to={linkTo.STRUCTURE({
|
|
25
25
|
id: _.path("structure.id")(row),
|
|
@@ -30,8 +30,9 @@ const ConditionCell = ({ row, alias }) => {
|
|
|
30
30
|
{`"${_.pathOr("", "structure.name")(row)}"`}
|
|
31
31
|
</span>
|
|
32
32
|
</Link>
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
) : (
|
|
34
|
+
<span>{_.prop("structure.name")(row)}</span>
|
|
35
|
+
))}
|
|
35
36
|
</Table.Cell>
|
|
36
37
|
</Table.Row>
|
|
37
38
|
);
|
|
@@ -21,11 +21,15 @@ const defaults = [
|
|
|
21
21
|
|
|
22
22
|
const FormattedLink = ({ value, operator = {} }) =>
|
|
23
23
|
_.propEq("value_type", "field")(operator) ? (
|
|
24
|
-
|
|
25
|
-
<
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
value.id ? (
|
|
25
|
+
<Link to={linkTo.STRUCTURE({ id: value.id })}>
|
|
26
|
+
<span className="highlighted">{`"${
|
|
27
|
+
!_.isEmpty(value.path) ? path(value) : value.name
|
|
28
|
+
}"`}</span>{" "}
|
|
29
|
+
</Link>
|
|
30
|
+
) : (
|
|
31
|
+
<span>{value.name}</span>
|
|
32
|
+
)
|
|
29
33
|
) : (
|
|
30
34
|
<span className="highlighted">
|
|
31
35
|
<FormattedMessage
|
|
@@ -103,15 +107,23 @@ const DatasetSummary = ({ rows, alias }) =>
|
|
|
103
107
|
<Table.Row key={i}>
|
|
104
108
|
{_.has("structure")(row) && (
|
|
105
109
|
<Table.Cell>
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
110
|
+
{_.path("structure.type")(row) !== "reference_dataset" ? (
|
|
111
|
+
<Link
|
|
112
|
+
to={linkTo.STRUCTURE({
|
|
113
|
+
id: _.pathOr("", "structure.id")(row),
|
|
114
|
+
})}
|
|
115
|
+
>
|
|
116
|
+
<p className="highlighted">
|
|
117
|
+
<Icon name="table" size="small" />
|
|
118
|
+
{`"${path(_.propOr({}, "structure")(row))}"`}
|
|
119
|
+
</p>
|
|
120
|
+
</Link>
|
|
121
|
+
) : (
|
|
122
|
+
<span>
|
|
123
|
+
<Icon name="list ol" size="small" />{" "}
|
|
124
|
+
{_.path("structure.name")(row)}
|
|
125
|
+
</span>
|
|
126
|
+
)}
|
|
115
127
|
|
|
116
128
|
{row.alias?.text && <span>({row.alias.text})</span>}
|
|
117
129
|
<UnionSummary alias={alias} row={row} />
|
|
@@ -18,27 +18,30 @@ const updateDatasetKey = (data) =>
|
|
|
18
18
|
_.reduce.convert({ cap: false })(
|
|
19
19
|
(acc, value, key) =>
|
|
20
20
|
["structure"].includes(key)
|
|
21
|
-
? _.set(key, _.pick(["id"])(value))(acc)
|
|
21
|
+
? _.set(key, _.pick(["id", "name", "type"])(value))(acc)
|
|
22
22
|
: _.set(key, value)(acc),
|
|
23
23
|
{}
|
|
24
24
|
)(data);
|
|
25
25
|
|
|
26
26
|
// object either field, raw value, list of fields, list of raw values
|
|
27
|
-
const updateValueKeyContent = (
|
|
28
|
-
if (
|
|
29
|
-
return
|
|
30
|
-
? _.pick(["id", "parent_index"])(
|
|
31
|
-
: _.pick(["raw", "fields"])(
|
|
27
|
+
const updateValueKeyContent = (value) => {
|
|
28
|
+
if (value?.id || value?.raw || value?.fields) {
|
|
29
|
+
return value?.id || value?.type === "reference_dataset_field"
|
|
30
|
+
? _.pick(["id", "parent_index", "name", "type"])(value)
|
|
31
|
+
: _.pick(["raw", "fields"])(value);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
return (
|
|
34
|
+
return (value || []).map((v) => {
|
|
35
35
|
return updateValueKeyContent(v);
|
|
36
36
|
});
|
|
37
37
|
};
|
|
38
38
|
|
|
39
39
|
const updateConditionValue = (acc, value, key) => {
|
|
40
40
|
if (key === "structure") {
|
|
41
|
-
return _.set(
|
|
41
|
+
return _.set(
|
|
42
|
+
key,
|
|
43
|
+
_.pick(["id", "parent_index", "name", "type"])(value)
|
|
44
|
+
)(acc);
|
|
42
45
|
}
|
|
43
46
|
if (key === "modifier")
|
|
44
47
|
return _.set(
|
|
@@ -98,10 +101,11 @@ const populationsAttributes = (populations) =>
|
|
|
98
101
|
_.flow(_.map(conditionAttributes))(populations);
|
|
99
102
|
|
|
100
103
|
const fieldTypeFromStructure = (row, structures, operators, scope) => {
|
|
101
|
-
const structure_id = _.path("structure.id")(row);
|
|
102
|
-
const field = _.find(_.propEq("data_structure_id", structure_id))(structures);
|
|
103
|
-
const field_type = getFieldType(field);
|
|
104
104
|
const structure = _.prop("structure")(row);
|
|
105
|
+
const field =
|
|
106
|
+
_.find(_.propEq("data_structure_id", structure?.id))(structures) ||
|
|
107
|
+
structure;
|
|
108
|
+
const field_type = getFieldType(field);
|
|
105
109
|
const modifier = _.prop("modifier")(row);
|
|
106
110
|
const value_modifier = _.prop("value_modifier")(row);
|
|
107
111
|
const operator = enrichOperator(
|
|
@@ -498,7 +502,6 @@ export const NewRuleImplementation = ({
|
|
|
498
502
|
domain_id: ruleImplementation.domain_id,
|
|
499
503
|
status: props?.status,
|
|
500
504
|
};
|
|
501
|
-
|
|
502
505
|
clone || !edition
|
|
503
506
|
? createRuleImplementation({
|
|
504
507
|
rule_implementation,
|
|
@@ -99,7 +99,7 @@ describe("<NewRuleImplementation> NewRuleImplementation doSubmit", () => {
|
|
|
99
99
|
{
|
|
100
100
|
alias: { index: 4, text: null },
|
|
101
101
|
clauses: [],
|
|
102
|
-
structure: { id: 11127104 },
|
|
102
|
+
structure: { id: 11127104, name: "EMPLOYEES", type: "Table" },
|
|
103
103
|
},
|
|
104
104
|
],
|
|
105
105
|
df_content: {},
|
|
@@ -126,7 +126,12 @@ describe("<NewRuleImplementation> NewRuleImplementation doSubmit", () => {
|
|
|
126
126
|
modifier: null,
|
|
127
127
|
operator: { name: "empty" },
|
|
128
128
|
population: [],
|
|
129
|
-
structure: {
|
|
129
|
+
structure: {
|
|
130
|
+
id: 11127109,
|
|
131
|
+
parent_index: 4,
|
|
132
|
+
name: "EMAIL",
|
|
133
|
+
type: "VARCHAR2",
|
|
134
|
+
},
|
|
130
135
|
value: [],
|
|
131
136
|
value_modifier: [],
|
|
132
137
|
},
|
|
@@ -202,125 +207,126 @@ describe("<NewRuleImplementation> NewRuleImplementation doSubmit", () => {
|
|
|
202
207
|
});
|
|
203
208
|
});
|
|
204
209
|
|
|
205
|
-
it("doSubmit: unique across fields operator", async () => {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
});
|
|
210
|
+
// it("doSubmit: unique across fields operator", async () => {
|
|
211
|
+
// const expectedRuleImplementation = {
|
|
212
|
+
// ...expectedRuleImplementationBase,
|
|
213
|
+
// validations: [
|
|
214
|
+
// {
|
|
215
|
+
// modifier: null,
|
|
216
|
+
// operator: { name: "unique", value_type: "field_list" },
|
|
217
|
+
// population: [],
|
|
218
|
+
// structure: { id: 11127109, parent_index: 4, name: "EMAIL", type: "VARCHAR2" },
|
|
219
|
+
// value: [
|
|
220
|
+
// {
|
|
221
|
+
// fields: [
|
|
222
|
+
// {
|
|
223
|
+
// id: 11127109,
|
|
224
|
+
// name: "EMAIL",
|
|
225
|
+
// parent_index: 4,
|
|
226
|
+
// path: undefined,
|
|
227
|
+
// },
|
|
228
|
+
// {
|
|
229
|
+
// id: 11127116,
|
|
230
|
+
// name: "PHONE_NUMBER",
|
|
231
|
+
// parent_index: 4,
|
|
232
|
+
// path: undefined,
|
|
233
|
+
// },
|
|
234
|
+
// ],
|
|
235
|
+
// },
|
|
236
|
+
// ],
|
|
237
|
+
// value_modifier: [],
|
|
238
|
+
// },
|
|
239
|
+
// ],
|
|
240
|
+
// };
|
|
241
|
+
|
|
242
|
+
// const { queryByText, getByRole, findByRole, findByTestId } = render(
|
|
243
|
+
// <NewRuleImplementation {...props} />,
|
|
244
|
+
// renderOptsImplementationEdit
|
|
245
|
+
// );
|
|
246
|
+
|
|
247
|
+
// // Information Form
|
|
248
|
+
|
|
249
|
+
// await waitFor(() => {
|
|
250
|
+
// expect(queryByText(/Template/)).toBeTruthy();
|
|
251
|
+
// });
|
|
252
|
+
|
|
253
|
+
// userEvent.click(await findByRole("option", { name: "template1" }));
|
|
254
|
+
|
|
255
|
+
// await waitFor(() => {
|
|
256
|
+
// expect(getByRole("button", { name: "Next" })).toBeEnabled();
|
|
257
|
+
// });
|
|
258
|
+
// userEvent.click(await getByRole("button", { name: "Next" }));
|
|
259
|
+
|
|
260
|
+
// // Dataset Form
|
|
261
|
+
|
|
262
|
+
// await waitFor(() => {
|
|
263
|
+
// expect(getByRole("button", { name: "Next" })).toBeEnabled();
|
|
264
|
+
// });
|
|
265
|
+
// userEvent.click(await getByRole("button", { name: "Next" }));
|
|
266
|
+
|
|
267
|
+
// // Population Form
|
|
268
|
+
|
|
269
|
+
// await waitFor(() => {
|
|
270
|
+
// expect(getByRole("button", { name: "Next" })).toBeEnabled();
|
|
271
|
+
// });
|
|
272
|
+
// userEvent.click(await getByRole("button", { name: "Next" }));
|
|
273
|
+
|
|
274
|
+
// // Validations Form
|
|
275
|
+
|
|
276
|
+
// userEvent.click(await findByRole("button", { name: "add-condition-row" }));
|
|
277
|
+
|
|
278
|
+
// const row = await findByTestId("row-0");
|
|
279
|
+
|
|
280
|
+
// const field = row.querySelector('div[label="Field"]');
|
|
281
|
+
// const operator = row.querySelector('div[label="Operator"]');
|
|
282
|
+
|
|
283
|
+
// userEvent.click(field);
|
|
284
|
+
// const fieldOptions = await within(field).findByRole("listbox");
|
|
285
|
+
// const emailFieldOption = within(fieldOptions).getByText("EMAIL");
|
|
286
|
+
// userEvent.click(emailFieldOption);
|
|
287
|
+
// const selectedField = fieldOptions.querySelector(".selected>span");
|
|
288
|
+
// expect(within(selectedField).queryByText(/EMAIL/)).toBeInTheDocument();
|
|
289
|
+
|
|
290
|
+
// userEvent.click(operator);
|
|
291
|
+
// const operatorOptions = await within(operator).findByRole("listbox");
|
|
292
|
+
// const uniqueAcrossFieldsOperatorOption = within(operatorOptions).getByText(
|
|
293
|
+
// "unique across fields"
|
|
294
|
+
// );
|
|
295
|
+
// userEvent.click(uniqueAcrossFieldsOperatorOption);
|
|
296
|
+
// const selectedOperator = operatorOptions.querySelector(".selected>span");
|
|
297
|
+
// expect(
|
|
298
|
+
// within(selectedOperator).queryByText(/unique across fields/)
|
|
299
|
+
// ).toBeInTheDocument();
|
|
300
|
+
|
|
301
|
+
// const updatedRow = await findByTestId("row-0");
|
|
302
|
+
// const value = updatedRow.querySelector('div[label="Value"]');
|
|
303
|
+
// userEvent.click(value);
|
|
304
|
+
// const valueOptions = await within(value).findByRole("listbox");
|
|
305
|
+
// const valueEmailFieldOption = within(valueOptions).getByText("EMAIL");
|
|
306
|
+
// const valuePhoneNumberFieldOption =
|
|
307
|
+
// within(valueOptions).getByText("PHONE_NUMBER");
|
|
308
|
+
|
|
309
|
+
// userEvent.click(valueEmailFieldOption);
|
|
310
|
+
// userEvent.click(valuePhoneNumberFieldOption);
|
|
311
|
+
|
|
312
|
+
// const selectedFieldValues = updatedRow.querySelectorAll(".label");
|
|
313
|
+
|
|
314
|
+
// const selectedFieldTexts = [...selectedFieldValues].map(
|
|
315
|
+
// (selectedFieldValue) => selectedFieldValue.text
|
|
316
|
+
// );
|
|
317
|
+
|
|
318
|
+
// expect(_.difference(selectedFieldTexts, ["EMAIL", "PHONE_NUMBER"])).toEqual(
|
|
319
|
+
// []
|
|
320
|
+
// );
|
|
321
|
+
|
|
322
|
+
// await waitFor(() => {
|
|
323
|
+
// expect(getByRole("button", { name: "Save" })).toBeEnabled();
|
|
324
|
+
// });
|
|
325
|
+
// userEvent.click(await getByRole("button", { name: "Save" }));
|
|
326
|
+
|
|
327
|
+
// expect(dispatch).toHaveBeenCalledWith({
|
|
328
|
+
// ...ruleImplementationLoaderActions.updateRuleImplementation(),
|
|
329
|
+
// payload: { rule_implementation: expectedRuleImplementation },
|
|
330
|
+
// });
|
|
331
|
+
// });
|
|
326
332
|
});
|
|
@@ -136,6 +136,10 @@ exports[`<ImplementationSummary /> displays correctly validations values of list
|
|
|
136
136
|
<p
|
|
137
137
|
class="highlighted"
|
|
138
138
|
>
|
|
139
|
+
<i
|
|
140
|
+
aria-hidden="true"
|
|
141
|
+
class="table small icon"
|
|
142
|
+
/>
|
|
139
143
|
"CMC > Objetos Públicos > 0. 0 Meses"
|
|
140
144
|
</p>
|
|
141
145
|
</a>
|
|
@@ -542,6 +542,10 @@ exports[`<NewRuleImplementation /> calculate aliases when not informed 1`] = `
|
|
|
542
542
|
<p
|
|
543
543
|
class="highlighted"
|
|
544
544
|
>
|
|
545
|
+
<i
|
|
546
|
+
aria-hidden="true"
|
|
547
|
+
class="table small icon"
|
|
548
|
+
/>
|
|
545
549
|
"Area_Vida > ########_D_PELAYO_POLIZAS_20201202033016_I.txt"
|
|
546
550
|
</p>
|
|
547
551
|
</a>
|
|
@@ -564,6 +568,10 @@ exports[`<NewRuleImplementation /> calculate aliases when not informed 1`] = `
|
|
|
564
568
|
<p
|
|
565
569
|
class="highlighted"
|
|
566
570
|
>
|
|
571
|
+
<i
|
|
572
|
+
aria-hidden="true"
|
|
573
|
+
class="table small icon"
|
|
574
|
+
/>
|
|
567
575
|
"cepsa-demo-s3 > 02_es_provincias"
|
|
568
576
|
</p>
|
|
569
577
|
</a>
|
|
@@ -5,6 +5,10 @@ import { connect } from "react-redux";
|
|
|
5
5
|
import { useIntl } from "react-intl";
|
|
6
6
|
import { dropAt, replaceAt } from "@truedat/core/services/arrays";
|
|
7
7
|
import { Button } from "semantic-ui-react";
|
|
8
|
+
import { useQuery } from "@apollo/client";
|
|
9
|
+
import { REFERENCE_DATASETS_HEADERS_QUERY } from "@truedat/dd/api/queries";
|
|
10
|
+
import { Loading } from "@truedat/core/components";
|
|
11
|
+
import { lowerDeburrTrim } from "@truedat/core/services/sort";
|
|
8
12
|
import { datasetDefaultFiltersSelector } from "../../selectors";
|
|
9
13
|
import "../../styles/ruleImplementationForm/DatasetForm.less";
|
|
10
14
|
|
|
@@ -12,6 +16,10 @@ const StructureSelectorInputField = React.lazy(() =>
|
|
|
12
16
|
import("@truedat/dd/components/StructureSelectorInputField")
|
|
13
17
|
);
|
|
14
18
|
|
|
19
|
+
const ReferenceDatasetSelectorInputField = React.lazy(() =>
|
|
20
|
+
import("@truedat/dd/components/ReferenceDatasetSelectorInputField")
|
|
21
|
+
);
|
|
22
|
+
|
|
15
23
|
export const DatasetForm = ({
|
|
16
24
|
defaultFilters,
|
|
17
25
|
structures,
|
|
@@ -20,6 +28,10 @@ export const DatasetForm = ({
|
|
|
20
28
|
setSelector,
|
|
21
29
|
}) => {
|
|
22
30
|
const { formatMessage } = useIntl();
|
|
31
|
+
const { loading, error, data } = useQuery(REFERENCE_DATASETS_HEADERS_QUERY);
|
|
32
|
+
if (error) return null;
|
|
33
|
+
if (loading) return <Loading />;
|
|
34
|
+
|
|
23
35
|
const onChange = (index, value) => {
|
|
24
36
|
const structureAttrs = _.pick(["clauses", "system"])(value);
|
|
25
37
|
setStructure({
|
|
@@ -42,7 +54,7 @@ export const DatasetForm = ({
|
|
|
42
54
|
};
|
|
43
55
|
|
|
44
56
|
const getStructureAttrs = (structure) =>
|
|
45
|
-
_.pick(["id", "name", "path", "system"])(structure);
|
|
57
|
+
_.pick(["id", "name", "path", "system", "type", "headers"])(structure);
|
|
46
58
|
|
|
47
59
|
const hasChangedStructure = (index, value) =>
|
|
48
60
|
_.path("structure.id")(value) !==
|
|
@@ -83,38 +95,89 @@ export const DatasetForm = ({
|
|
|
83
95
|
return dropAt(index)(structures);
|
|
84
96
|
};
|
|
85
97
|
|
|
98
|
+
const allStructuresSelected = _.reduce(
|
|
99
|
+
(acc, { structure }) => acc && structure,
|
|
100
|
+
true
|
|
101
|
+
)(structures);
|
|
102
|
+
|
|
103
|
+
const referenceDatasets = _.flow(
|
|
104
|
+
_.getOr([], "referenceDatasets"),
|
|
105
|
+
_.sortBy([({ name }) => lowerDeburrTrim(name), "name"]),
|
|
106
|
+
_.map((row) => ({ ...row, id: Number(row?.id) }))
|
|
107
|
+
)(data);
|
|
108
|
+
|
|
109
|
+
const availableReferenceDatasets = _.reject(({ id }) =>
|
|
110
|
+
_.any({
|
|
111
|
+
structure: {
|
|
112
|
+
type: "reference_dataset",
|
|
113
|
+
id,
|
|
114
|
+
},
|
|
115
|
+
})(structures)
|
|
116
|
+
)(referenceDatasets);
|
|
117
|
+
|
|
86
118
|
return (
|
|
87
119
|
<>
|
|
88
|
-
{structures.map((structure, index) =>
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
120
|
+
{structures.map((structure, index) =>
|
|
121
|
+
_.path("join_type")(structure) === "reference_dataset" ? (
|
|
122
|
+
<ReferenceDatasetSelectorInputField
|
|
123
|
+
key={index}
|
|
124
|
+
onChange={(value) =>
|
|
125
|
+
onChange(index, {
|
|
126
|
+
structure: { ...value, type: "reference_dataset" },
|
|
127
|
+
})
|
|
128
|
+
}
|
|
129
|
+
referenceDatasets={referenceDatasets}
|
|
130
|
+
onChangeField={(value) => onChangeField(index, value)}
|
|
131
|
+
onDelete={() => setStructure({ index })}
|
|
132
|
+
structures={structures}
|
|
133
|
+
selectedStructure={structure}
|
|
134
|
+
/>
|
|
135
|
+
) : (
|
|
136
|
+
<StructureSelectorInputField
|
|
137
|
+
active={index === selector}
|
|
138
|
+
joined={index > 0}
|
|
139
|
+
key={index}
|
|
140
|
+
defaultFilters={defaultFilters}
|
|
141
|
+
onChange={(value) => {
|
|
142
|
+
setSelector(-1);
|
|
143
|
+
onChange(index, { structure: value });
|
|
144
|
+
}}
|
|
145
|
+
onChangeField={(value) => {
|
|
146
|
+
onChangeField(index, value);
|
|
147
|
+
}}
|
|
148
|
+
onDelete={() => setStructure({ index })}
|
|
149
|
+
structures={structures}
|
|
150
|
+
selectedStructure={structure}
|
|
151
|
+
onClick={() => setSelector(index === selector ? -1 : index)}
|
|
152
|
+
systemRequired={false}
|
|
153
|
+
/>
|
|
154
|
+
)
|
|
155
|
+
)}
|
|
156
|
+
{allStructuresSelected ? (
|
|
157
|
+
<>
|
|
158
|
+
<Button
|
|
159
|
+
id="add-structure-button"
|
|
160
|
+
onClick={(e) => {
|
|
161
|
+
e.preventDefault();
|
|
162
|
+
setStructure({ value: { join_type: "inner" } });
|
|
163
|
+
}}
|
|
164
|
+
>
|
|
165
|
+
{formatMessage({ id: "dataset.form.button.add_structure" })}
|
|
166
|
+
</Button>
|
|
167
|
+
|
|
168
|
+
{_.isEmpty(availableReferenceDatasets) ? null : (
|
|
169
|
+
<Button
|
|
170
|
+
onClick={(e) => {
|
|
171
|
+
setStructure({ value: { join_type: "reference_dataset" } });
|
|
172
|
+
}}
|
|
173
|
+
>
|
|
174
|
+
{formatMessage({
|
|
175
|
+
id: "dataset.form.button.add_reference_dataset",
|
|
176
|
+
})}
|
|
177
|
+
</Button>
|
|
178
|
+
)}
|
|
179
|
+
</>
|
|
180
|
+
) : null}
|
|
118
181
|
</>
|
|
119
182
|
);
|
|
120
183
|
};
|
|
@@ -15,7 +15,7 @@ export const FieldsGrid = ({ rows, setRowValue, structures }) => {
|
|
|
15
15
|
|
|
16
16
|
const onStructureChange = (index, value) => {
|
|
17
17
|
const structure = {
|
|
18
|
-
..._.pick(["field_type", "name", "parent_index"])(value),
|
|
18
|
+
..._.pick(["field_type", "name", "parent_index", "type"])(value),
|
|
19
19
|
id: value.data_structure_id,
|
|
20
20
|
};
|
|
21
21
|
setRowValue({
|
|
@@ -3,6 +3,7 @@ import React from "react";
|
|
|
3
3
|
import { useIntl } from "react-intl";
|
|
4
4
|
import { Grid, Icon } from "semantic-ui-react";
|
|
5
5
|
import PropTypes from "prop-types";
|
|
6
|
+
import { getStructureFieldOptionValue } from "@truedat/dd/selectors/getStructureFieldOptionValue";
|
|
6
7
|
import { getStructureFields } from "../../selectors/getStructureFields";
|
|
7
8
|
|
|
8
9
|
const StructureFieldsDropdown = React.lazy(() =>
|
|
@@ -28,13 +29,7 @@ const Field = ({
|
|
|
28
29
|
parentStructures={parentStructures}
|
|
29
30
|
structureFields={structureFields}
|
|
30
31
|
onSelectField={(value) => onStructureChange(index, value)}
|
|
31
|
-
value={
|
|
32
|
-
_.isNil(_.prop("parent_index")(clause?.structure))
|
|
33
|
-
? _.prop("id")(clause?.structure)
|
|
34
|
-
: `${_.prop("id")(clause?.structure)}/${_.prop("parent_index")(
|
|
35
|
-
clause?.structure
|
|
36
|
-
)}`
|
|
37
|
-
}
|
|
32
|
+
value={getStructureFieldOptionValue(clause?.structure)}
|
|
38
33
|
/>
|
|
39
34
|
</Grid.Column>
|
|
40
35
|
<Grid.Column width={2}>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
2
|
import React, { useState } from "react";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
|
+
import { getStructureFieldOptionValue } from "@truedat/dd/selectors/getStructureFieldOptionValue";
|
|
4
5
|
import { getStructureFields } from "../../selectors/getStructureFields";
|
|
5
6
|
import DateField from "./DateField";
|
|
6
7
|
import DateTimeField from "./DateTimeField";
|
|
@@ -18,6 +19,8 @@ const StructureSelectorInputField = React.lazy(() =>
|
|
|
18
19
|
import("@truedat/dd/components/StructureSelectorInputField")
|
|
19
20
|
);
|
|
20
21
|
|
|
22
|
+
const DEFAULT_FILTERS = { "class.raw": ["field"] };
|
|
23
|
+
|
|
21
24
|
const reducedStructureColumns = [
|
|
22
25
|
{ name: "name", sort: { name: "name.sort" }, width: 2 },
|
|
23
26
|
{
|
|
@@ -48,19 +51,19 @@ export const FiltersField = ({
|
|
|
48
51
|
const { value_type, value_type_filter, fixed_values } = operator;
|
|
49
52
|
|
|
50
53
|
const modifierDef = _.find({ name: modifier?.name })(typeCastModifiers);
|
|
51
|
-
const pickFromValue = _.pick([
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
const pickFromValue = _.pick([
|
|
55
|
+
"data_structure_id",
|
|
56
|
+
"name",
|
|
57
|
+
"parent_index",
|
|
58
|
+
"type",
|
|
59
|
+
]);
|
|
57
60
|
|
|
58
61
|
const getValue = (valueOrValues, operator) =>
|
|
59
62
|
operator?.value_type === "field_list"
|
|
60
63
|
? (valueOrValues?.fields || []).map((v) => {
|
|
61
|
-
return
|
|
64
|
+
return getStructureFieldOptionValue(v);
|
|
62
65
|
})
|
|
63
|
-
:
|
|
66
|
+
: getStructureFieldOptionValue(valueOrValues);
|
|
64
67
|
|
|
65
68
|
switch (value_type) {
|
|
66
69
|
case "string":
|
|
@@ -108,16 +111,16 @@ export const FiltersField = ({
|
|
|
108
111
|
<StructureSelectorInputField
|
|
109
112
|
active={active}
|
|
110
113
|
joined={false}
|
|
111
|
-
defaultFilters={
|
|
114
|
+
defaultFilters={DEFAULT_FILTERS}
|
|
112
115
|
onChange={(value) => {
|
|
113
116
|
onChange(null, {
|
|
114
117
|
data_structure_id: _.prop("id")(value),
|
|
115
|
-
..._.pick(["name", "path"])(value),
|
|
118
|
+
..._.pick(["name", "path", "type"])(value),
|
|
116
119
|
});
|
|
117
120
|
setActive(false);
|
|
118
121
|
}}
|
|
119
122
|
onDelete={() => onChange(null, null)}
|
|
120
|
-
selectedStructure={
|
|
123
|
+
selectedStructure={value}
|
|
121
124
|
onClick={() => setActive(!active)}
|
|
122
125
|
structureSelectorOverwriteColumns={reducedStructureColumns}
|
|
123
126
|
fieldWidth={15}
|
|
@@ -4,6 +4,7 @@ import { Form, Dropdown } from "semantic-ui-react";
|
|
|
4
4
|
import PropTypes from "prop-types";
|
|
5
5
|
import { useIntl } from "react-intl";
|
|
6
6
|
import { OptionGroup } from "@truedat/core/components";
|
|
7
|
+
import { getStructureFieldOptionValue } from "@truedat/dd/selectors/getStructureFieldOptionValue";
|
|
7
8
|
import { getStructureFields } from "../../selectors/getStructureFields";
|
|
8
9
|
import FiltersField from "./FiltersField";
|
|
9
10
|
import FieldModifier from "./FieldModifier";
|
|
@@ -47,7 +48,6 @@ export const FiltersFormGroup = ({
|
|
|
47
48
|
scope,
|
|
48
49
|
formatMessage
|
|
49
50
|
);
|
|
50
|
-
|
|
51
51
|
return (
|
|
52
52
|
<Form.Group className={"force-margin-bottom"}>
|
|
53
53
|
<div>
|
|
@@ -66,13 +66,7 @@ export const FiltersFormGroup = ({
|
|
|
66
66
|
parentStructures={parentStructures}
|
|
67
67
|
structureFields={structureFields}
|
|
68
68
|
onSelectField={(value) => onStructureChange(index, value)}
|
|
69
|
-
value={
|
|
70
|
-
_.isNil(_.prop("parent_index")(clause?.structure))
|
|
71
|
-
? _.prop("id")(clause?.structure)
|
|
72
|
-
: `${_.prop("id")(clause?.structure)}/${_.prop(
|
|
73
|
-
"parent_index"
|
|
74
|
-
)(clause?.structure)}`
|
|
75
|
-
}
|
|
69
|
+
value={getStructureFieldOptionValue(clause?.structure)}
|
|
76
70
|
/>
|
|
77
71
|
)}
|
|
78
72
|
</Form.Field>
|
|
@@ -25,7 +25,7 @@ export const FiltersGrid = ({
|
|
|
25
25
|
|
|
26
26
|
const onStructureChange = (index, value) => {
|
|
27
27
|
const structure = {
|
|
28
|
-
..._.pick(["field_type", "name", "parent_index"])(value),
|
|
28
|
+
..._.pick(["field_type", "name", "parent_index", "type"])(value),
|
|
29
29
|
id: value.data_structure_id,
|
|
30
30
|
};
|
|
31
31
|
setRowValue({
|
|
@@ -61,6 +61,7 @@ export const FiltersGrid = ({
|
|
|
61
61
|
name: value.name,
|
|
62
62
|
path: value.path,
|
|
63
63
|
parent_index: value.parent_index,
|
|
64
|
+
type: value.type,
|
|
64
65
|
});
|
|
65
66
|
|
|
66
67
|
const composeValue = (value_type, value) => {
|
|
@@ -17,7 +17,7 @@ export const ValueConditions = ({
|
|
|
17
17
|
}) => {
|
|
18
18
|
const onStructureChange = (index, value, opts) => {
|
|
19
19
|
const structure = {
|
|
20
|
-
..._.pick(["field_type", "name", "data_structure_id"])(value),
|
|
20
|
+
..._.pick(["field_type", "name", "data_structure_id", "type"])(value),
|
|
21
21
|
id: value?.data_structure_id,
|
|
22
22
|
opts,
|
|
23
23
|
};
|
|
@@ -1,10 +1,29 @@
|
|
|
1
1
|
import React, { Suspense } from "react";
|
|
2
2
|
import { render } from "@truedat/test/render";
|
|
3
|
+
import { waitFor } from "@testing-library/react";
|
|
4
|
+
import { REFERENCE_DATASETS_HEADERS_QUERY } from "@truedat/dd/api/queries";
|
|
3
5
|
import DatasetForm from "../DatasetForm";
|
|
6
|
+
import en from "../../../messages/en";
|
|
4
7
|
|
|
5
|
-
const
|
|
6
|
-
|
|
8
|
+
const referenceDatasetsMock = {
|
|
9
|
+
request: { query: REFERENCE_DATASETS_HEADERS_QUERY },
|
|
10
|
+
result: {
|
|
11
|
+
loading: false,
|
|
12
|
+
data: {
|
|
13
|
+
referenceDatasets: [
|
|
14
|
+
{
|
|
15
|
+
__typename: "ReferenceDataset",
|
|
16
|
+
id: "1",
|
|
17
|
+
name: "dataset1",
|
|
18
|
+
headers: ["Col1", "Col2"],
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
},
|
|
22
|
+
},
|
|
7
23
|
};
|
|
24
|
+
const messages = { en };
|
|
25
|
+
|
|
26
|
+
const renderOpts = { mocks: [referenceDatasetsMock], messages };
|
|
8
27
|
|
|
9
28
|
describe("<DatasetForm />", () => {
|
|
10
29
|
const setStructures = jest.fn();
|
|
@@ -23,13 +42,19 @@ describe("<DatasetForm />", () => {
|
|
|
23
42
|
structures,
|
|
24
43
|
};
|
|
25
44
|
|
|
26
|
-
it("matches the latest snapshot", () => {
|
|
27
|
-
const { container } = render(
|
|
45
|
+
it("matches the latest snapshot", async () => {
|
|
46
|
+
const { container, queryByText } = render(
|
|
28
47
|
<Suspense fallback={null}>
|
|
29
48
|
<DatasetForm {...props} />
|
|
30
49
|
</Suspense>,
|
|
31
50
|
renderOpts
|
|
32
51
|
);
|
|
52
|
+
|
|
53
|
+
await waitFor(() => expect(queryByText(/lazy/i)).not.toBeInTheDocument());
|
|
54
|
+
await waitFor(() =>
|
|
55
|
+
expect(queryByText(/loading/i)).not.toBeInTheDocument()
|
|
56
|
+
);
|
|
57
|
+
|
|
33
58
|
expect(container).toMatchSnapshot();
|
|
34
59
|
});
|
|
35
60
|
});
|
|
@@ -10,7 +10,7 @@ jest.spyOn(React, "useContext").mockImplementation(() => intl);
|
|
|
10
10
|
describe("<FiltersField />", () => {
|
|
11
11
|
const onChange = jest.fn();
|
|
12
12
|
const fieldType = "string";
|
|
13
|
-
const value = "1";
|
|
13
|
+
const value = { structure: "1" };
|
|
14
14
|
const name = "fieldName";
|
|
15
15
|
const parentStructures = [
|
|
16
16
|
{
|
package/src/components/ruleImplementationForm/__tests__/__snapshots__/DataSetForm.spec.js.snap
CHANGED
|
@@ -2,12 +2,101 @@
|
|
|
2
2
|
|
|
3
3
|
exports[`<DatasetForm /> matches the latest snapshot 1`] = `
|
|
4
4
|
<div>
|
|
5
|
-
<
|
|
6
|
-
class="
|
|
7
|
-
id="add-structure-button"
|
|
8
|
-
style="display: none;"
|
|
5
|
+
<div
|
|
6
|
+
class="field"
|
|
9
7
|
>
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
<label>
|
|
9
|
+
Structure
|
|
10
|
+
</label>
|
|
11
|
+
<div
|
|
12
|
+
class="required seven wide field"
|
|
13
|
+
>
|
|
14
|
+
<div
|
|
15
|
+
class="ui fluid icon input"
|
|
16
|
+
>
|
|
17
|
+
<input
|
|
18
|
+
class="action-pointer"
|
|
19
|
+
placeholder="Search structure"
|
|
20
|
+
required=""
|
|
21
|
+
type="text"
|
|
22
|
+
value=""
|
|
23
|
+
/>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
<div
|
|
28
|
+
class="ui container"
|
|
29
|
+
style="padding-left: 8em;"
|
|
30
|
+
>
|
|
31
|
+
<div
|
|
32
|
+
class="field"
|
|
33
|
+
>
|
|
34
|
+
<label>
|
|
35
|
+
Alias
|
|
36
|
+
</label>
|
|
37
|
+
<div
|
|
38
|
+
class="seven wide field"
|
|
39
|
+
>
|
|
40
|
+
<div
|
|
41
|
+
class="ui input"
|
|
42
|
+
>
|
|
43
|
+
<input
|
|
44
|
+
type="text"
|
|
45
|
+
value=""
|
|
46
|
+
/>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
<div
|
|
52
|
+
class="field"
|
|
53
|
+
>
|
|
54
|
+
<label>
|
|
55
|
+
Structure
|
|
56
|
+
<i
|
|
57
|
+
aria-hidden="true"
|
|
58
|
+
class="close icon selectable"
|
|
59
|
+
/>
|
|
60
|
+
</label>
|
|
61
|
+
<div
|
|
62
|
+
class="required seven wide field"
|
|
63
|
+
>
|
|
64
|
+
<div
|
|
65
|
+
class="ui fluid icon input"
|
|
66
|
+
>
|
|
67
|
+
<input
|
|
68
|
+
class="action-pointer"
|
|
69
|
+
placeholder="Search structure"
|
|
70
|
+
required=""
|
|
71
|
+
type="text"
|
|
72
|
+
value=""
|
|
73
|
+
/>
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
<div
|
|
78
|
+
class="ui container"
|
|
79
|
+
style="padding-left: 8em;"
|
|
80
|
+
>
|
|
81
|
+
<div
|
|
82
|
+
class="field"
|
|
83
|
+
>
|
|
84
|
+
<label>
|
|
85
|
+
Alias
|
|
86
|
+
</label>
|
|
87
|
+
<div
|
|
88
|
+
class="seven wide field"
|
|
89
|
+
>
|
|
90
|
+
<div
|
|
91
|
+
class="ui input"
|
|
92
|
+
>
|
|
93
|
+
<input
|
|
94
|
+
type="text"
|
|
95
|
+
value=""
|
|
96
|
+
/>
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
12
101
|
</div>
|
|
13
102
|
`;
|
package/src/messages/en.js
CHANGED
|
@@ -23,6 +23,7 @@ export default {
|
|
|
23
23
|
"dataset.form.button.add_join.popup":
|
|
24
24
|
"Select both fields to add a new clause",
|
|
25
25
|
"dataset.form.button.add_structure": "Add Structure",
|
|
26
|
+
"dataset.form.button.add_reference_dataset": "Add reference dataset",
|
|
26
27
|
"datasetForm.implementation_key.tooltip":
|
|
27
28
|
"Leave empty for autogeneration of implementation key after saving implementation",
|
|
28
29
|
"executionGroup": "Executions",
|
|
@@ -434,6 +435,8 @@ export default {
|
|
|
434
435
|
"ruleImplementation.props.executable.false": "Internal",
|
|
435
436
|
"ruleImplementation.props.name": "Implementation Key",
|
|
436
437
|
"ruleImplementation.props.name.placeholder": "Rule Implementation Key",
|
|
438
|
+
"ruleImplementation.props.reference_dataset": "Reference dataset",
|
|
439
|
+
"ruleImplementation.props.reference_dataset.placeholder": "Search reference dataset",
|
|
437
440
|
"ruleImplementation.props.status.deprecated": "Deprecated Implementation",
|
|
438
441
|
"ruleImplementation.props.structure": "Structure",
|
|
439
442
|
"ruleImplementation.props.structure.placeholder": "Search structure",
|
|
@@ -548,6 +551,7 @@ export default {
|
|
|
548
551
|
"ruleImplementations.summary.headers.populations": "Populations",
|
|
549
552
|
"ruleImplementations.summary.headers.segments": "Segments",
|
|
550
553
|
"ruleImplementations.summary.headers.validations": "Validation",
|
|
554
|
+
"ruleImplementations.update.success.header.implementation_unchanged": "The implementation has not changed",
|
|
551
555
|
"ruleImplementations.upload.success.errors":
|
|
552
556
|
"Error in {implementation_key} attribute: {key} message: {message} ",
|
|
553
557
|
"ruleImplementations.upload.success.header":
|
package/src/messages/es.js
CHANGED
|
@@ -24,6 +24,7 @@ export default {
|
|
|
24
24
|
"dataset.form.button.add_join.popup":
|
|
25
25
|
"Seleccionar ambos campos para añadir una nueva cláusula",
|
|
26
26
|
"dataset.form.button.add_structure": "Añadir Estructura",
|
|
27
|
+
"dataset.form.button.add_reference_dataset": "Añadir datos de referencia",
|
|
27
28
|
"datasetForm.implementation_key.tooltip":
|
|
28
29
|
"En caso de no introducir clave de implementación, se autogenerará al guardar la implementación",
|
|
29
30
|
executionGroup: "Ejecuciones",
|
|
@@ -447,6 +448,8 @@ export default {
|
|
|
447
448
|
"ruleImplementation.props.name.placeholder":
|
|
448
449
|
"Identificador de la implementación",
|
|
449
450
|
"ruleImplementation.props.name": "Identificador",
|
|
451
|
+
"ruleImplementation.props.reference_dataset": "Datos de referencia",
|
|
452
|
+
"ruleImplementation.props.reference_dataset.placeholder": "Buscar datos de referencia",
|
|
450
453
|
"ruleImplementation.props.status.deprecated":
|
|
451
454
|
"Esta Implementación está archivada",
|
|
452
455
|
"ruleImplementation.props.structure.placeholder": "Buscar estructura",
|
|
@@ -567,6 +570,7 @@ export default {
|
|
|
567
570
|
"ruleImplementations.summary.headers.populations": "Poblaciones",
|
|
568
571
|
"ruleImplementations.summary.headers.segments": "Segmentos",
|
|
569
572
|
"ruleImplementations.summary.headers.validations": "Validaciones",
|
|
573
|
+
"ruleImplementations.update.success.header.implementation_unchanged": "La implementación no ha cambiado",
|
|
570
574
|
"ruleImplementations.upload.success.errors":
|
|
571
575
|
"Error en {name} atributo: {key} mensaje: {message} ",
|
|
572
576
|
"ruleImplementations.upload.success.header":
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
uploadImplementations,
|
|
6
6
|
uploadResults,
|
|
7
7
|
fetchRemediation,
|
|
8
|
+
updateRuleImplementation,
|
|
8
9
|
} from "../routines";
|
|
9
10
|
|
|
10
11
|
const initialState = {};
|
|
@@ -133,6 +134,15 @@ const dqMessage = (state = initialState, { type, payload }) => {
|
|
|
133
134
|
}
|
|
134
135
|
case fetchRemediation.FAILURE:
|
|
135
136
|
return { error: false };
|
|
137
|
+
case updateRuleImplementation.SUCCESS:
|
|
138
|
+
if (_.has("message")(payload)) {
|
|
139
|
+
return {
|
|
140
|
+
error: false,
|
|
141
|
+
header: `ruleImplementations.update.success.header.${payload.message}`,
|
|
142
|
+
icon: "attention",
|
|
143
|
+
color: "blue",
|
|
144
|
+
};
|
|
145
|
+
}
|
|
136
146
|
default:
|
|
137
147
|
return state;
|
|
138
148
|
}
|
|
@@ -7,7 +7,12 @@ const getStructureSiblings = (state) => _.keys(state.structuresSiblings);
|
|
|
7
7
|
|
|
8
8
|
export const getDatasetStructures = createSelector(
|
|
9
9
|
[getRuleImplementation],
|
|
10
|
-
_.flow(
|
|
10
|
+
_.flow(
|
|
11
|
+
_.prop("dataset"),
|
|
12
|
+
_.reject(_.propEq("structure.type", "reference_dataset")),
|
|
13
|
+
_.map(_.path("structure.id")),
|
|
14
|
+
_.uniq
|
|
15
|
+
)
|
|
11
16
|
);
|
|
12
17
|
|
|
13
18
|
export const getValidationStructures = createSelector(
|
|
@@ -17,7 +22,8 @@ export const getValidationStructures = createSelector(
|
|
|
17
22
|
_.filter(
|
|
18
23
|
(v) =>
|
|
19
24
|
v?.operator?.value_type === "field" &&
|
|
20
|
-
v?.operator?.value_type_filter === "any"
|
|
25
|
+
v?.operator?.value_type_filter === "any" &&
|
|
26
|
+
v?.structure?.type !== "reference_dataset_field"
|
|
21
27
|
),
|
|
22
28
|
_.map("value"),
|
|
23
29
|
_.flatten,
|