@truedat/dq 4.46.4 → 4.46.7
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 +12 -0
- package/package.json +5 -5
- package/src/api/queries.js +16 -0
- package/src/components/ConditionSummary.js +66 -22
- package/src/components/ImplementationsRoutes.js +19 -0
- package/src/components/NewRuleImplementation.js +23 -6
- package/src/components/RuleImplementationHistory.js +84 -0
- package/src/components/RuleImplementationHistoryRow.js +50 -0
- package/src/components/RuleImplementationLoader.js +25 -37
- package/src/components/RuleImplementationTabs.js +15 -4
- package/src/components/__tests__/RuleImplementationHistory.spec.js +54 -0
- package/src/components/__tests__/RuleImplementationLoader.spec.js +32 -42
- package/src/components/__tests__/RuleImplementationTabs.spec.js +1 -0
- package/src/components/__tests__/__snapshots__/RuleImplementation.spec.js.snap +6 -0
- package/src/components/__tests__/__snapshots__/RuleImplementationHistory.spec.js.snap +142 -0
- package/src/components/__tests__/__snapshots__/RuleImplementationLoader.spec.js.snap +15 -1
- package/src/components/__tests__/__snapshots__/RuleImplementationTabs.spec.js.snap +6 -0
- package/src/components/ruleImplementationForm/FiltersField.js +35 -10
- package/src/components/ruleImplementationForm/FiltersFormGroup.js +6 -2
- package/src/components/ruleImplementationForm/FiltersGrid.js +14 -4
- package/src/components/ruleImplementationForm/__tests__/__snapshots__/FiltersFormGroup.spec.js.snap +7 -1
- package/src/components/ruleImplementationForm/__tests__/__snapshots__/FiltersGroup.spec.js.snap +7 -1
- package/src/components/ruleImplementationForm/__tests__/__snapshots__/ValueConditions.spec.js.snap +7 -1
- package/src/messages/en.js +5 -1
- package/src/messages/es.js +6 -1
- package/src/routines.js +3 -0
- package/src/selectors/getRuleImplementationOperators.js +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [4.46.7] 2022-06-20
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- [TD-4919] Add ruleImplementation History
|
|
8
|
+
|
|
9
|
+
## [4.46.5] 2022-06-17
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- [TD-4894] Multiple column operator in implementation creation
|
|
14
|
+
|
|
3
15
|
## [4.46.3] 2022-06-16
|
|
4
16
|
|
|
5
17
|
### Changed
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truedat/dq",
|
|
3
|
-
"version": "4.46.
|
|
3
|
+
"version": "4.46.7",
|
|
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.46.
|
|
37
|
+
"@truedat/test": "4.46.7",
|
|
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.46.
|
|
92
|
-
"@truedat/df": "4.46.
|
|
91
|
+
"@truedat/core": "4.46.7",
|
|
92
|
+
"@truedat/df": "4.46.7",
|
|
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": "2b1c3f0fcf94a7b510f171c06cfb2e1550a14166"
|
|
114
114
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { gql } from "@apollo/client";
|
|
2
|
+
|
|
3
|
+
export const IMPLEMENTATION_WITH_VERSIONS_QUERY = gql`
|
|
4
|
+
query Implementation($id: ID!) {
|
|
5
|
+
implementation(id: $id) {
|
|
6
|
+
id
|
|
7
|
+
versions {
|
|
8
|
+
id
|
|
9
|
+
implementation_key
|
|
10
|
+
version
|
|
11
|
+
status
|
|
12
|
+
updated_at
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
`;
|
|
@@ -8,23 +8,41 @@ import { linkTo } from "@truedat/core/routes";
|
|
|
8
8
|
|
|
9
9
|
const concatValues = (values, link) => _.join(link)(values);
|
|
10
10
|
|
|
11
|
-
const
|
|
12
|
-
|
|
11
|
+
const LinkToStructure = ({ value }) => {
|
|
12
|
+
return value?.id ? (
|
|
13
13
|
<Link to={linkTo.STRUCTURE({ id: value.id })}>
|
|
14
14
|
<span className="highlighted">{`"${
|
|
15
15
|
!_.isEmpty(value.path) ? path(value) : value.name
|
|
16
16
|
}"`}</span>{" "}
|
|
17
17
|
</Link>
|
|
18
|
-
) :
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
18
|
+
) : null;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const FormattedLink = ({ value, operator = {} }) => {
|
|
22
|
+
switch (operator?.value_type) {
|
|
23
|
+
case "field":
|
|
24
|
+
return <LinkToStructure value={value} />;
|
|
25
|
+
case "field_list":
|
|
26
|
+
return (
|
|
27
|
+
<>
|
|
28
|
+
{_.map.convert({ cap: false })((v, i) => (
|
|
29
|
+
<LinkToStructure key={i} value={v} />
|
|
30
|
+
))(value)}
|
|
31
|
+
</>
|
|
32
|
+
);
|
|
33
|
+
default:
|
|
34
|
+
return (
|
|
35
|
+
<span className="highlighted">
|
|
36
|
+
<FormattedMessage
|
|
37
|
+
id={`ruleImplementation.filtersField.${value.raw}`}
|
|
38
|
+
defaultMessage={`"${
|
|
39
|
+
_.isArray(value.raw) ? _.join(", ")(value.raw) : value.raw
|
|
40
|
+
}"`}
|
|
41
|
+
></FormattedMessage>
|
|
42
|
+
</span>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
28
46
|
|
|
29
47
|
FormattedLink.propTypes = {
|
|
30
48
|
value: PropTypes.object,
|
|
@@ -33,26 +51,52 @@ FormattedLink.propTypes = {
|
|
|
33
51
|
|
|
34
52
|
const nilOrEmpty = (v) => _.isNil(v) || v === "";
|
|
35
53
|
|
|
36
|
-
const filterNilOrEmpties = (values, keys) =>
|
|
37
|
-
|
|
54
|
+
const filterNilOrEmpties = (values, keys) => {
|
|
55
|
+
if ("kv" in values) {
|
|
56
|
+
return _.every((k) => !nilOrEmpty(values.kv[k]))(keys) ? values : null;
|
|
57
|
+
}
|
|
38
58
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
_.
|
|
42
|
-
|
|
59
|
+
return _.flow(
|
|
60
|
+
_.map((v) => filterNilOrEmpties(v, keys)),
|
|
61
|
+
_.filter((v) => !!v)
|
|
62
|
+
)(values);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const pick = (value, keys, optionalKeys) => ({
|
|
66
|
+
kv: _.pick(keys)(value),
|
|
67
|
+
optv: _.pick(optionalKeys)(value),
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
const convert = (v, index, value_modifier) => {
|
|
71
|
+
if (_.has("kv")(v)) {
|
|
72
|
+
return { ...v.kv, ...v.optv, modifier: _.nth(index)(value_modifier) };
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return _.map.convert({ cap: false })((v, i) => {
|
|
76
|
+
return convert(v, i, value_modifier);
|
|
77
|
+
})(v);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const valuesFromKeys = (values, keys, optionalKeys, value_modifier) => {
|
|
81
|
+
return _.flow(
|
|
82
|
+
_.map((value) => {
|
|
83
|
+
return Array.isArray(value?.fields)
|
|
84
|
+
? _.map((innerValue) => pick(innerValue, keys, optionalKeys))(
|
|
85
|
+
value?.fields
|
|
86
|
+
)
|
|
87
|
+
: pick(value, keys, optionalKeys);
|
|
43
88
|
}),
|
|
44
89
|
(v) => filterNilOrEmpties(v, keys),
|
|
45
|
-
|
|
46
|
-
return { ...v.kv, ...v.optv, modifier: _.nth(i)(value_modifier) };
|
|
47
|
-
})
|
|
90
|
+
(v) => convert(v, 0, value_modifier)
|
|
48
91
|
)(values);
|
|
92
|
+
};
|
|
49
93
|
|
|
50
94
|
export const empty = (rows) =>
|
|
51
95
|
rows && _.every((r) => _.isEmpty(r) || _.isNil(r))(rows);
|
|
52
96
|
|
|
53
97
|
export const getValues = ({ value = [], operator = {}, value_modifier }) => {
|
|
54
98
|
const defaultOrValue = value || [];
|
|
55
|
-
return
|
|
99
|
+
return ["field", "field_list"].includes(operator?.value_type)
|
|
56
100
|
? valuesFromKeys(defaultOrValue, ["id", "name"], ["path"], value_modifier)
|
|
57
101
|
: valuesFromKeys(defaultOrValue, ["raw"], [], value_modifier);
|
|
58
102
|
};
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
IMPLEMENTATION_CONCEPT_LINKS,
|
|
13
13
|
IMPLEMENTATION_EDIT,
|
|
14
14
|
IMPLEMENTATION_EVENTS,
|
|
15
|
+
IMPLEMENTATION_HISTORY,
|
|
15
16
|
IMPLEMENTATION_MOVE,
|
|
16
17
|
IMPLEMENTATION_NEW,
|
|
17
18
|
IMPLEMENTATION_NEW_RAW,
|
|
@@ -36,6 +37,7 @@ import MoveImplementation from "./MoveImplementation";
|
|
|
36
37
|
import NewRuleImplementation from "./NewRuleImplementation";
|
|
37
38
|
import RuleImplementation from "./RuleImplementation";
|
|
38
39
|
import RuleImplementationEvents from "./RuleImplementationEvents";
|
|
40
|
+
import RuleImplementationHistory from "./RuleImplementationHistory";
|
|
39
41
|
import RuleImplementationLoader from "./RuleImplementationLoader";
|
|
40
42
|
import RuleImplementationProperties from "./RuleImplementationProperties";
|
|
41
43
|
import RuleImplementationResults from "./RuleImplementationResults";
|
|
@@ -312,6 +314,23 @@ export const ImplementationsRoutes = ({
|
|
|
312
314
|
</>
|
|
313
315
|
)}
|
|
314
316
|
/>
|
|
317
|
+
<Route
|
|
318
|
+
exact
|
|
319
|
+
path={IMPLEMENTATION_HISTORY}
|
|
320
|
+
render={() => (
|
|
321
|
+
<>
|
|
322
|
+
<ImplementationCrumbs />
|
|
323
|
+
<Segment>
|
|
324
|
+
{ruleImplementationLoaded ? (
|
|
325
|
+
<RuleImplementation>
|
|
326
|
+
<RuleImplementationHistory />
|
|
327
|
+
</RuleImplementation>
|
|
328
|
+
) : null}
|
|
329
|
+
</Segment>
|
|
330
|
+
</>
|
|
331
|
+
)}
|
|
332
|
+
/>
|
|
333
|
+
|
|
315
334
|
<Route
|
|
316
335
|
exact
|
|
317
336
|
path={IMPLEMENTATION_RESULTS_DETAILS}
|
|
@@ -25,6 +25,24 @@ const updateDatasetKey = (data) =>
|
|
|
25
25
|
{}
|
|
26
26
|
)(data);
|
|
27
27
|
|
|
28
|
+
// https://stackoverflow.com/a/38417085
|
|
29
|
+
const updateValueKeyValue = (object) => {
|
|
30
|
+
if (object?.id || object?.raw || object?.fields) {
|
|
31
|
+
return object?.id
|
|
32
|
+
? _.pick(["id", "parent_index"])(object)
|
|
33
|
+
: _.pick(["raw", "fields"])(object);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return Object.keys(object).reduce(
|
|
37
|
+
(output, key) => {
|
|
38
|
+
// eslint-disable-next-line fp/no-mutation
|
|
39
|
+
output[key] = updateValueKeyValue(object[key]);
|
|
40
|
+
return output;
|
|
41
|
+
},
|
|
42
|
+
Array.isArray(object) ? [] : {}
|
|
43
|
+
);
|
|
44
|
+
};
|
|
45
|
+
|
|
28
46
|
const updateConditionValue = (acc, value, key) => {
|
|
29
47
|
if (key === "structure") {
|
|
30
48
|
return _.set(key, _.pick(["id", "parent_index"])(value))(acc);
|
|
@@ -49,12 +67,10 @@ const updateConditionValue = (acc, value, key) => {
|
|
|
49
67
|
)
|
|
50
68
|
)(acc);
|
|
51
69
|
if (key == "value")
|
|
52
|
-
return
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
)(value)
|
|
57
|
-
)(acc);
|
|
70
|
+
return {
|
|
71
|
+
...acc,
|
|
72
|
+
value: updateValueKeyValue(value),
|
|
73
|
+
};
|
|
58
74
|
if (key === "population") return _.set(key, conditionAttributes(value))(acc);
|
|
59
75
|
|
|
60
76
|
return acc;
|
|
@@ -103,6 +119,7 @@ const fieldTypeFromStructure = (row, structures, operators, scope) => {
|
|
|
103
119
|
field_type,
|
|
104
120
|
_.prop("operator")(row)
|
|
105
121
|
);
|
|
122
|
+
|
|
106
123
|
const updatedRow = {
|
|
107
124
|
...row,
|
|
108
125
|
operator,
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { useParams } from "react-router-dom";
|
|
4
|
+
import { useQuery } from "@apollo/client";
|
|
5
|
+
import PropTypes from "prop-types";
|
|
6
|
+
import { connect } from "react-redux";
|
|
7
|
+
import { Segment, Grid, Table } from "semantic-ui-react";
|
|
8
|
+
import { FormattedMessage } from "react-intl";
|
|
9
|
+
import { Loading } from "@truedat/core/components";
|
|
10
|
+
import { IMPLEMENTATION_WITH_VERSIONS_QUERY } from "../api/queries";
|
|
11
|
+
|
|
12
|
+
import RuleImplementationHistoryRow from "./RuleImplementationHistoryRow";
|
|
13
|
+
|
|
14
|
+
export const RuleImplementationHistory = ({ implementation }) => (
|
|
15
|
+
<Segment attached="bottom">
|
|
16
|
+
<Grid>
|
|
17
|
+
<Grid.Row>
|
|
18
|
+
<Grid.Column>
|
|
19
|
+
{!_.isEmpty(implementation) && (
|
|
20
|
+
<Table selectable>
|
|
21
|
+
<Table.Header>
|
|
22
|
+
<Table.Row>
|
|
23
|
+
<Table.HeaderCell
|
|
24
|
+
content={
|
|
25
|
+
<FormattedMessage id="ruleImplementations.props.implementation_key" />
|
|
26
|
+
}
|
|
27
|
+
/>
|
|
28
|
+
<Table.HeaderCell
|
|
29
|
+
content={
|
|
30
|
+
<FormattedMessage id="ruleImplementations.props.status" />
|
|
31
|
+
}
|
|
32
|
+
/>
|
|
33
|
+
<Table.HeaderCell
|
|
34
|
+
content={
|
|
35
|
+
<FormattedMessage id="ruleImplementations.props.version" />
|
|
36
|
+
}
|
|
37
|
+
/>
|
|
38
|
+
<Table.HeaderCell
|
|
39
|
+
content={
|
|
40
|
+
<FormattedMessage id="ruleImplementations.props.last_change_at" />
|
|
41
|
+
}
|
|
42
|
+
/>
|
|
43
|
+
</Table.Row>
|
|
44
|
+
</Table.Header>
|
|
45
|
+
<Table.Body>
|
|
46
|
+
{implementation?.versions.map((item, i) => (
|
|
47
|
+
<RuleImplementationHistoryRow
|
|
48
|
+
key={i}
|
|
49
|
+
{...item}
|
|
50
|
+
active={item.id == implementation.id}
|
|
51
|
+
/>
|
|
52
|
+
))}
|
|
53
|
+
</Table.Body>
|
|
54
|
+
</Table>
|
|
55
|
+
)}
|
|
56
|
+
</Grid.Column>
|
|
57
|
+
</Grid.Row>
|
|
58
|
+
</Grid>
|
|
59
|
+
</Segment>
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
RuleImplementationHistory.propTypes = {
|
|
63
|
+
implementation: PropTypes.object,
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export const RuleImplementationHistoryLoader = (props) => {
|
|
67
|
+
const { implementation_id: id } = useParams();
|
|
68
|
+
const { loading, error, data } = useQuery(
|
|
69
|
+
IMPLEMENTATION_WITH_VERSIONS_QUERY,
|
|
70
|
+
{
|
|
71
|
+
variables: { id },
|
|
72
|
+
}
|
|
73
|
+
);
|
|
74
|
+
if (error) return null;
|
|
75
|
+
if (loading) return <Loading />;
|
|
76
|
+
const implementation = data?.implementation;
|
|
77
|
+
return (
|
|
78
|
+
<RuleImplementationHistory implementation={implementation} {...props} />
|
|
79
|
+
);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export default connect(null, { RuleImplementationHistory })(
|
|
83
|
+
RuleImplementationHistoryLoader
|
|
84
|
+
);
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import PropTypes from "prop-types";
|
|
4
|
+
import { useHistory } from "react-router-dom";
|
|
5
|
+
import { Table } from "semantic-ui-react";
|
|
6
|
+
import { FormattedMessage } from "react-intl";
|
|
7
|
+
import { DateTime } from "@truedat/core/components";
|
|
8
|
+
import { linkTo } from "@truedat/core/routes";
|
|
9
|
+
|
|
10
|
+
export const RuleImplementationHistoryRow = ({
|
|
11
|
+
id,
|
|
12
|
+
status,
|
|
13
|
+
updated_at,
|
|
14
|
+
version,
|
|
15
|
+
implementation_key,
|
|
16
|
+
active,
|
|
17
|
+
}) => {
|
|
18
|
+
const history = useHistory();
|
|
19
|
+
return (
|
|
20
|
+
<Table.Row
|
|
21
|
+
active={active}
|
|
22
|
+
onClick={() =>
|
|
23
|
+
history.push(linkTo.IMPLEMENTATION({ implementation_id: id }))
|
|
24
|
+
}
|
|
25
|
+
>
|
|
26
|
+
<Table.Cell content={implementation_key} />
|
|
27
|
+
<Table.Cell
|
|
28
|
+
content={
|
|
29
|
+
<FormattedMessage
|
|
30
|
+
id={`concepts.status.${status}`}
|
|
31
|
+
defaultMessage={status}
|
|
32
|
+
/>
|
|
33
|
+
}
|
|
34
|
+
/>
|
|
35
|
+
<Table.Cell content={version} />
|
|
36
|
+
<Table.Cell content={<DateTime value={updated_at} />} />
|
|
37
|
+
</Table.Row>
|
|
38
|
+
);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
RuleImplementationHistoryRow.propTypes = {
|
|
42
|
+
id: PropTypes.number,
|
|
43
|
+
implementation_key: PropTypes.string,
|
|
44
|
+
status: PropTypes.string,
|
|
45
|
+
updated_at: PropTypes.string,
|
|
46
|
+
version: PropTypes.number,
|
|
47
|
+
active: PropTypes.bool,
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export default RuleImplementationHistoryRow;
|
|
@@ -1,48 +1,36 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { withRouter } from "react-router-dom";
|
|
1
|
+
import React, { useEffect } from "react";
|
|
3
2
|
import PropTypes from "prop-types";
|
|
4
|
-
import { compose } from "redux";
|
|
5
3
|
import { connect } from "react-redux";
|
|
4
|
+
import { useParams } from "react-router-dom";
|
|
6
5
|
import { Loading } from "@truedat/core/components";
|
|
7
6
|
import { clearRuleImplementation, fetchRuleImplementation } from "../routines";
|
|
8
7
|
|
|
9
|
-
export
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
8
|
+
export const RuleImplementationLoader = ({
|
|
9
|
+
clearRuleImplementation,
|
|
10
|
+
fetchRuleImplementation,
|
|
11
|
+
ruleImplementationLoading: loading,
|
|
12
|
+
}) => {
|
|
13
|
+
const { implementation_id } = useParams();
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
fetchRuleImplementation({ id: implementation_id });
|
|
16
|
+
return () => {
|
|
17
|
+
clearRuleImplementation();
|
|
18
|
+
};
|
|
19
|
+
}, [implementation_id, clearRuleImplementation, fetchRuleImplementation]);
|
|
20
|
+
return loading ? <Loading /> : null;
|
|
21
|
+
};
|
|
16
22
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
componentWillUnmount() {
|
|
26
|
-
const { clearRuleImplementation } = this.props;
|
|
27
|
-
clearRuleImplementation();
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
render() {
|
|
31
|
-
const { ruleImplementationLoading } = this.props;
|
|
32
|
-
|
|
33
|
-
if (ruleImplementationLoading) {
|
|
34
|
-
return <Loading />;
|
|
35
|
-
} else {
|
|
36
|
-
return null;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
23
|
+
RuleImplementationLoader.propTypes = {
|
|
24
|
+
fetchRuleImplementation: PropTypes.func,
|
|
25
|
+
clearRuleImplementation: PropTypes.func,
|
|
26
|
+
ruleImplementationLoading: PropTypes.bool,
|
|
27
|
+
};
|
|
40
28
|
|
|
41
29
|
const mapStateToProps = ({ ruleImplementationLoading }) => ({
|
|
42
30
|
ruleImplementationLoading,
|
|
43
31
|
});
|
|
44
32
|
|
|
45
|
-
export default
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
)(RuleImplementationLoader);
|
|
33
|
+
export default connect(mapStateToProps, {
|
|
34
|
+
clearRuleImplementation,
|
|
35
|
+
fetchRuleImplementation,
|
|
36
|
+
})(RuleImplementationLoader);
|
|
@@ -7,14 +7,15 @@ import { compose } from "redux";
|
|
|
7
7
|
import { connect } from "react-redux";
|
|
8
8
|
import { FormattedMessage } from "react-intl";
|
|
9
9
|
import {
|
|
10
|
-
IMPLEMENTATION_EVENTS,
|
|
11
|
-
IMPLEMENTATION_CONCEPT_LINKS,
|
|
12
10
|
IMPLEMENTATION_CONCEPT_LINKS_NEW,
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
IMPLEMENTATION_CONCEPT_LINKS,
|
|
12
|
+
IMPLEMENTATION_EVENTS,
|
|
13
|
+
IMPLEMENTATION_HISTORY,
|
|
15
14
|
IMPLEMENTATION_MOVE,
|
|
16
15
|
IMPLEMENTATION_RESULTS_DETAILS,
|
|
17
16
|
IMPLEMENTATION_RESULTS,
|
|
17
|
+
IMPLEMENTATION_STRUCTURES_NEW,
|
|
18
|
+
IMPLEMENTATION_STRUCTURES,
|
|
18
19
|
IMPLEMENTATION,
|
|
19
20
|
linkTo,
|
|
20
21
|
} from "@truedat/core/routes";
|
|
@@ -94,6 +95,16 @@ export const RuleImplementationTabs = ({
|
|
|
94
95
|
<FormattedMessage id="tabs.dq.ruleImplementation.details" />
|
|
95
96
|
</Menu.Item>
|
|
96
97
|
)}
|
|
98
|
+
<Menu.Item
|
|
99
|
+
active={match.path === IMPLEMENTATION_HISTORY}
|
|
100
|
+
as={Link}
|
|
101
|
+
to={linkTo.IMPLEMENTATION_HISTORY({
|
|
102
|
+
implementation_id: ruleImplementation.id,
|
|
103
|
+
})}
|
|
104
|
+
>
|
|
105
|
+
<FormattedMessage id="tabs.dq.ruleImplementation.history" />
|
|
106
|
+
</Menu.Item>
|
|
107
|
+
|
|
97
108
|
<Menu.Item
|
|
98
109
|
active={match.path === IMPLEMENTATION_EVENTS}
|
|
99
110
|
as={Link}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "@truedat/test/render";
|
|
3
|
+
import { RuleImplementationHistory } from "../RuleImplementationHistory";
|
|
4
|
+
|
|
5
|
+
describe("<RuleImplementationHistory", () => {
|
|
6
|
+
const implementation_id = 23;
|
|
7
|
+
const props = {
|
|
8
|
+
implementation: {
|
|
9
|
+
id: implementation_id,
|
|
10
|
+
versions: [
|
|
11
|
+
{
|
|
12
|
+
id: 34,
|
|
13
|
+
implementation_key: "some implementation key 34",
|
|
14
|
+
version: 3,
|
|
15
|
+
status: "draft",
|
|
16
|
+
updated_at: "2022-02-10T15:22:07Z",
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
id: implementation_id,
|
|
20
|
+
implementation_key: "some implementation key " + implementation_id,
|
|
21
|
+
version: 2,
|
|
22
|
+
status: "published",
|
|
23
|
+
updated_at: "2022-02-10T15:22:07Z",
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
id: 22,
|
|
27
|
+
implementation_key: "some implementation key 22",
|
|
28
|
+
version: 1,
|
|
29
|
+
status: "versioned",
|
|
30
|
+
updated_at: "2022-02-10T15:22:07Z",
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const renderOpts = {
|
|
37
|
+
messages: {
|
|
38
|
+
en: {
|
|
39
|
+
"ruleImplementations.props.implementation_key": "key",
|
|
40
|
+
"ruleImplementations.props.status": "status",
|
|
41
|
+
"ruleImplementations.props.version": "version",
|
|
42
|
+
"ruleImplementations.props.last_change_at": "change",
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
it("matches the latest snapshot", () => {
|
|
48
|
+
const { container } = render(
|
|
49
|
+
<RuleImplementationHistory {...props} />,
|
|
50
|
+
renderOpts
|
|
51
|
+
);
|
|
52
|
+
expect(container).toMatchSnapshot();
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -1,67 +1,57 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { render } from "@truedat/test/render";
|
|
3
3
|
import { RuleImplementationLoader } from "../RuleImplementationLoader";
|
|
4
4
|
|
|
5
|
+
const implementation_id = 234;
|
|
6
|
+
jest.mock("react-router-dom", () => ({
|
|
7
|
+
...jest.requireActual("react-router-dom"),
|
|
8
|
+
useParams: () => ({ implementation_id: implementation_id }),
|
|
9
|
+
}));
|
|
10
|
+
|
|
5
11
|
describe("<RuleImplementationLoader />", () => {
|
|
6
|
-
const match = { params: { implementation_id: 1 } };
|
|
7
12
|
const clearRuleImplementation = jest.fn();
|
|
8
13
|
const fetchRuleImplementation = jest.fn();
|
|
14
|
+
const common_props = {
|
|
15
|
+
fetchRuleImplementation,
|
|
16
|
+
clearRuleImplementation,
|
|
17
|
+
};
|
|
9
18
|
|
|
10
19
|
it("matches the latest snapshot", () => {
|
|
11
|
-
const ruleImplementationLoading = true;
|
|
12
20
|
const props = {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
ruleImplementationLoading,
|
|
16
|
-
match
|
|
21
|
+
...common_props,
|
|
22
|
+
ruleImplementationLoading: true,
|
|
17
23
|
};
|
|
18
|
-
const
|
|
19
|
-
expect(
|
|
24
|
+
const { container } = render(<RuleImplementationLoader {...props} />);
|
|
25
|
+
expect(container).toMatchSnapshot();
|
|
20
26
|
});
|
|
21
27
|
|
|
22
28
|
it("renders a loader if rulesLoading is true", () => {
|
|
23
|
-
const ruleImplementationLoading = true;
|
|
24
29
|
const props = {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
match,
|
|
28
|
-
ruleImplementationLoading
|
|
30
|
+
...common_props,
|
|
31
|
+
ruleImplementationLoading: true,
|
|
29
32
|
};
|
|
30
|
-
const
|
|
31
|
-
expect(
|
|
33
|
+
const { container } = render(<RuleImplementationLoader {...props} />);
|
|
34
|
+
expect(container).toMatchSnapshot();
|
|
35
|
+
expect(container.firstChild).not.toBeNull();
|
|
32
36
|
});
|
|
33
37
|
|
|
34
38
|
it("renders null if ruleImplementationLoading is false", () => {
|
|
35
|
-
const ruleImplementationLoading = false;
|
|
36
39
|
const props = {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
match,
|
|
40
|
-
ruleImplementationLoading
|
|
40
|
+
...common_props,
|
|
41
|
+
ruleImplementationLoading: false,
|
|
41
42
|
};
|
|
42
|
-
const
|
|
43
|
-
expect(
|
|
43
|
+
const { container } = render(<RuleImplementationLoader {...props} />);
|
|
44
|
+
expect(container.firstChild).toBeNull();
|
|
44
45
|
});
|
|
45
46
|
|
|
46
47
|
it("calls fetchRuleImplementation when component mounts, clearRuleImplementation when component unmounts", () => {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
};
|
|
56
|
-
jest.spyOn(RuleImplementationLoader.prototype, "componentDidMount");
|
|
57
|
-
const wrapper = shallow(<RuleImplementationLoader {...props} />);
|
|
58
|
-
expect(
|
|
59
|
-
RuleImplementationLoader.prototype.componentDidMount.mock.calls.length
|
|
60
|
-
).toBe(1);
|
|
61
|
-
expect(clearRuleImplementation.mock.calls.length).toBe(0);
|
|
62
|
-
expect(fetchRuleImplementation.mock.calls.length).toBe(1);
|
|
63
|
-
wrapper.unmount();
|
|
64
|
-
expect(clearRuleImplementation.mock.calls.length).toBe(1);
|
|
65
|
-
expect(fetchRuleImplementation.mock.calls.length).toBe(1);
|
|
48
|
+
clearRuleImplementation.mockClear();
|
|
49
|
+
fetchRuleImplementation.mockClear();
|
|
50
|
+
const { unmount } = render(<RuleImplementationLoader {...common_props} />);
|
|
51
|
+
expect(fetchRuleImplementation).toHaveBeenCalledWith({
|
|
52
|
+
id: implementation_id,
|
|
53
|
+
});
|
|
54
|
+
unmount();
|
|
55
|
+
expect(clearRuleImplementation).toHaveBeenCalledTimes(1);
|
|
66
56
|
});
|
|
67
57
|
});
|
|
@@ -12,6 +12,7 @@ describe("<RuleImplementationTabs />", () => {
|
|
|
12
12
|
"tabs.dq.ruleImplementation.results": "results",
|
|
13
13
|
"tabs.dq.ruleImplementation.details": "details",
|
|
14
14
|
"tabs.dq.ruleImplementation.audit": "audit",
|
|
15
|
+
"tabs.dq.ruleImplementation.history": "history",
|
|
15
16
|
},
|
|
16
17
|
},
|
|
17
18
|
};
|
|
@@ -148,6 +148,12 @@ exports[`<RuleImplementation /> matches the latest snapshot 1`] = `
|
|
|
148
148
|
>
|
|
149
149
|
Results
|
|
150
150
|
</a>
|
|
151
|
+
<a
|
|
152
|
+
class="item"
|
|
153
|
+
href="/implementations/1/history"
|
|
154
|
+
>
|
|
155
|
+
History
|
|
156
|
+
</a>
|
|
151
157
|
<a
|
|
152
158
|
class="item"
|
|
153
159
|
href="/implementations/1/events"
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`<RuleImplementationHistory matches the latest snapshot 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
class="ui bottom attached segment"
|
|
7
|
+
>
|
|
8
|
+
<div
|
|
9
|
+
class="ui grid"
|
|
10
|
+
>
|
|
11
|
+
<div
|
|
12
|
+
class="row"
|
|
13
|
+
>
|
|
14
|
+
<div
|
|
15
|
+
class="column"
|
|
16
|
+
>
|
|
17
|
+
<table
|
|
18
|
+
class="ui selectable table"
|
|
19
|
+
>
|
|
20
|
+
<thead
|
|
21
|
+
class=""
|
|
22
|
+
>
|
|
23
|
+
<tr
|
|
24
|
+
class=""
|
|
25
|
+
>
|
|
26
|
+
<th
|
|
27
|
+
class=""
|
|
28
|
+
>
|
|
29
|
+
key
|
|
30
|
+
</th>
|
|
31
|
+
<th
|
|
32
|
+
class=""
|
|
33
|
+
>
|
|
34
|
+
status
|
|
35
|
+
</th>
|
|
36
|
+
<th
|
|
37
|
+
class=""
|
|
38
|
+
>
|
|
39
|
+
version
|
|
40
|
+
</th>
|
|
41
|
+
<th
|
|
42
|
+
class=""
|
|
43
|
+
>
|
|
44
|
+
change
|
|
45
|
+
</th>
|
|
46
|
+
</tr>
|
|
47
|
+
</thead>
|
|
48
|
+
<tbody
|
|
49
|
+
class=""
|
|
50
|
+
>
|
|
51
|
+
<tr
|
|
52
|
+
class=""
|
|
53
|
+
>
|
|
54
|
+
<td
|
|
55
|
+
class=""
|
|
56
|
+
>
|
|
57
|
+
some implementation key 34
|
|
58
|
+
</td>
|
|
59
|
+
<td
|
|
60
|
+
class=""
|
|
61
|
+
>
|
|
62
|
+
draft
|
|
63
|
+
</td>
|
|
64
|
+
<td
|
|
65
|
+
class=""
|
|
66
|
+
>
|
|
67
|
+
3
|
|
68
|
+
</td>
|
|
69
|
+
<td
|
|
70
|
+
class=""
|
|
71
|
+
>
|
|
72
|
+
<time
|
|
73
|
+
datetime="1644506527000"
|
|
74
|
+
>
|
|
75
|
+
2022-02-10 15:22
|
|
76
|
+
</time>
|
|
77
|
+
</td>
|
|
78
|
+
</tr>
|
|
79
|
+
<tr
|
|
80
|
+
class="active"
|
|
81
|
+
>
|
|
82
|
+
<td
|
|
83
|
+
class=""
|
|
84
|
+
>
|
|
85
|
+
some implementation key 23
|
|
86
|
+
</td>
|
|
87
|
+
<td
|
|
88
|
+
class=""
|
|
89
|
+
>
|
|
90
|
+
published
|
|
91
|
+
</td>
|
|
92
|
+
<td
|
|
93
|
+
class=""
|
|
94
|
+
>
|
|
95
|
+
2
|
|
96
|
+
</td>
|
|
97
|
+
<td
|
|
98
|
+
class=""
|
|
99
|
+
>
|
|
100
|
+
<time
|
|
101
|
+
datetime="1644506527000"
|
|
102
|
+
>
|
|
103
|
+
2022-02-10 15:22
|
|
104
|
+
</time>
|
|
105
|
+
</td>
|
|
106
|
+
</tr>
|
|
107
|
+
<tr
|
|
108
|
+
class=""
|
|
109
|
+
>
|
|
110
|
+
<td
|
|
111
|
+
class=""
|
|
112
|
+
>
|
|
113
|
+
some implementation key 22
|
|
114
|
+
</td>
|
|
115
|
+
<td
|
|
116
|
+
class=""
|
|
117
|
+
>
|
|
118
|
+
versioned
|
|
119
|
+
</td>
|
|
120
|
+
<td
|
|
121
|
+
class=""
|
|
122
|
+
>
|
|
123
|
+
1
|
|
124
|
+
</td>
|
|
125
|
+
<td
|
|
126
|
+
class=""
|
|
127
|
+
>
|
|
128
|
+
<time
|
|
129
|
+
datetime="1644506527000"
|
|
130
|
+
>
|
|
131
|
+
2022-02-10 15:22
|
|
132
|
+
</time>
|
|
133
|
+
</td>
|
|
134
|
+
</tr>
|
|
135
|
+
</tbody>
|
|
136
|
+
</table>
|
|
137
|
+
</div>
|
|
138
|
+
</div>
|
|
139
|
+
</div>
|
|
140
|
+
</div>
|
|
141
|
+
</div>
|
|
142
|
+
`;
|
|
@@ -1,3 +1,17 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
|
-
exports[`<RuleImplementationLoader /> matches the latest snapshot 1`] =
|
|
3
|
+
exports[`<RuleImplementationLoader /> matches the latest snapshot 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
class="ui active loader"
|
|
7
|
+
/>
|
|
8
|
+
</div>
|
|
9
|
+
`;
|
|
10
|
+
|
|
11
|
+
exports[`<RuleImplementationLoader /> renders a loader if rulesLoading is true 1`] = `
|
|
12
|
+
<div>
|
|
13
|
+
<div
|
|
14
|
+
class="ui active loader"
|
|
15
|
+
/>
|
|
16
|
+
</div>
|
|
17
|
+
`;
|
|
@@ -48,6 +48,24 @@ export const FiltersField = ({
|
|
|
48
48
|
const { value_type, value_type_filter, fixed_values } = operator;
|
|
49
49
|
|
|
50
50
|
const modifierDef = _.find({ name: modifier?.name })(typeCastModifiers);
|
|
51
|
+
const pickFromValue = _.pick(["data_structure_id", "name", "parent_index"]);
|
|
52
|
+
|
|
53
|
+
const getVal = (value) => {
|
|
54
|
+
return _.isNil(_.prop("parent_index")(value))
|
|
55
|
+
? _.prop("id")(value)
|
|
56
|
+
: `${_.prop("id")(value)}/${_.prop("parent_index")(value)}`;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const getValue = (valueOrValues, operator) => {
|
|
60
|
+
const getValueResultado =
|
|
61
|
+
operator?.value_type === "field_list"
|
|
62
|
+
? (valueOrValues?.fields || []).map((v) => {
|
|
63
|
+
return getVal(v);
|
|
64
|
+
})
|
|
65
|
+
: getVal(valueOrValues);
|
|
66
|
+
|
|
67
|
+
return getValueResultado;
|
|
68
|
+
};
|
|
51
69
|
|
|
52
70
|
switch (value_type) {
|
|
53
71
|
case "string":
|
|
@@ -89,6 +107,7 @@ export const FiltersField = ({
|
|
|
89
107
|
case "timestamp":
|
|
90
108
|
return <DateTimeField label={label} value={value} onChange={onChange} />;
|
|
91
109
|
case "field":
|
|
110
|
+
case "field_list":
|
|
92
111
|
const structureFields = getStructureFields(parentStructures);
|
|
93
112
|
return value_type_filter == "any" ? (
|
|
94
113
|
<StructureSelectorInputField
|
|
@@ -111,24 +130,30 @@ export const FiltersField = ({
|
|
|
111
130
|
) : (
|
|
112
131
|
<>
|
|
113
132
|
<StructureFieldsDropdown
|
|
133
|
+
multiple={value_type === "field_list"}
|
|
114
134
|
label={label}
|
|
115
135
|
inline={false}
|
|
116
136
|
parentStructures={parentStructures}
|
|
117
137
|
structureFields={structureFields}
|
|
118
138
|
typeCastModifiers={typeCastModifiers}
|
|
119
|
-
filters={
|
|
120
|
-
|
|
139
|
+
filters={
|
|
140
|
+
value_type === "field_list" ? null : { field_type: [fieldType] }
|
|
141
|
+
}
|
|
142
|
+
onSelectField={(value, modifier) => {
|
|
121
143
|
onChange(
|
|
122
144
|
null,
|
|
123
|
-
|
|
145
|
+
pickFromValue(value),
|
|
124
146
|
modifier ? { name: modifier.name } : null
|
|
125
|
-
)
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
147
|
+
);
|
|
148
|
+
}}
|
|
149
|
+
onSelectFields={(values) => {
|
|
150
|
+
onChange(
|
|
151
|
+
null,
|
|
152
|
+
values.map((value) => pickFromValue(value)),
|
|
153
|
+
null
|
|
154
|
+
);
|
|
155
|
+
}}
|
|
156
|
+
value={getValue(value, operator)}
|
|
132
157
|
/>
|
|
133
158
|
{modifier && (
|
|
134
159
|
<FieldModifier
|
|
@@ -65,7 +65,9 @@ export const FiltersFormGroup = ({
|
|
|
65
65
|
inline={false}
|
|
66
66
|
parentStructures={parentStructures}
|
|
67
67
|
structureFields={structureFields}
|
|
68
|
-
onSelectField={(value) =>
|
|
68
|
+
onSelectField={(value) => {
|
|
69
|
+
return onStructureChange(index, value /*[0]*/);
|
|
70
|
+
}}
|
|
69
71
|
value={
|
|
70
72
|
_.isNil(_.prop("parent_index")(clause?.structure))
|
|
71
73
|
? _.prop("id")(clause?.structure)
|
|
@@ -122,7 +124,9 @@ export const FiltersFormGroup = ({
|
|
|
122
124
|
})}
|
|
123
125
|
options={operatorsOptions}
|
|
124
126
|
value={getOperatorValue(clause)}
|
|
125
|
-
onClick={(
|
|
127
|
+
onClick={(whatever) => {
|
|
128
|
+
onOperatorChange(index, whatever.id);
|
|
129
|
+
}}
|
|
126
130
|
placeholder={formatMessage({
|
|
127
131
|
id: "operator.dropdown.placeholder",
|
|
128
132
|
})}
|
|
@@ -56,13 +56,23 @@ export const FiltersGrid = ({
|
|
|
56
56
|
});
|
|
57
57
|
};
|
|
58
58
|
|
|
59
|
+
const composeFieldValue = (value) => {
|
|
60
|
+
return {
|
|
61
|
+
id: value.data_structure_id || value.id,
|
|
62
|
+
name: value.name,
|
|
63
|
+
path: value.path,
|
|
64
|
+
parent_index: value.parent_index,
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
|
|
59
68
|
const composeValue = (value_type, value) => {
|
|
60
69
|
if (value_type == "field") {
|
|
70
|
+
return composeFieldValue(value);
|
|
71
|
+
} else if (value_type === "field_list") {
|
|
61
72
|
return {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
parent_index: value.parent_index,
|
|
73
|
+
fields: _.map((v) => {
|
|
74
|
+
return composeFieldValue(v);
|
|
75
|
+
})(value),
|
|
66
76
|
};
|
|
67
77
|
} else {
|
|
68
78
|
return { raw: value };
|
package/src/messages/en.js
CHANGED
|
@@ -423,7 +423,8 @@ export default {
|
|
|
423
423
|
"matches regular expression",
|
|
424
424
|
"ruleImplementation.operator.starts_with": "starts with",
|
|
425
425
|
"ruleImplementation.operator.starts_with.string": "starts with",
|
|
426
|
-
"ruleImplementation.operator.unique": "
|
|
426
|
+
"ruleImplementation.operator.unique": "unique",
|
|
427
|
+
"ruleImplementation.operator.unique.field_list": "unique across fields",
|
|
427
428
|
"ruleImplementation.operator.variation_on_count": "count variation",
|
|
428
429
|
"ruleImplementation.operator.variation_on_count.string": "count variation",
|
|
429
430
|
"ruleImplementation.props.esquema": "Structure",
|
|
@@ -501,6 +502,7 @@ export default {
|
|
|
501
502
|
"ruleImplementations.events.action_restored": "Implementation restored",
|
|
502
503
|
"ruleImplementations.events.action_updated": "Implementation updated",
|
|
503
504
|
"ruleImplementations.props.business_concept": "Concept",
|
|
505
|
+
"ruleImplementations.props.last_change_at": "Last change at",
|
|
504
506
|
"ruleImplementations.props.status": "Status",
|
|
505
507
|
"ruleImplementations.props.executable": "Executable",
|
|
506
508
|
"ruleImplementations.props.executable.true": "Executable",
|
|
@@ -527,6 +529,7 @@ export default {
|
|
|
527
529
|
"ruleImplementations.props.template": "Template",
|
|
528
530
|
"ruleImplementations.props.rule_template": "Rule template",
|
|
529
531
|
"ruleImplementations.props.implementation_template": "Implementation template",
|
|
532
|
+
"ruleImplementations.props.version": "Version",
|
|
530
533
|
"ruleImplementations.retrieved.results": "{count} implementations found",
|
|
531
534
|
"ruleImplementations.search.results.empty": "No implementations found",
|
|
532
535
|
"ruleImplementations.searching": "Searching implementations",
|
|
@@ -599,6 +602,7 @@ export default {
|
|
|
599
602
|
"tabs.dq.ruleImplementation": "Implementation",
|
|
600
603
|
"tabs.dq.ruleImplementation.audit": "Audit",
|
|
601
604
|
"tabs.dq.ruleImplementation.details": "Details",
|
|
605
|
+
"tabs.dq.ruleImplementation.history": "History",
|
|
602
606
|
"tabs.dq.ruleImplementation.results": "Results",
|
|
603
607
|
"tabs.dq.ruleImplementations": "Implementations",
|
|
604
608
|
"tabs.dq.ruleImplementationResult.info": "Information",
|
package/src/messages/es.js
CHANGED
|
@@ -435,7 +435,8 @@ export default {
|
|
|
435
435
|
"ruleImplementation.operator.regex_format": "cumple la expresión regular",
|
|
436
436
|
"ruleImplementation.operator.starts_with.string": "empieza por",
|
|
437
437
|
"ruleImplementation.operator.starts_with": "empieza por",
|
|
438
|
-
"ruleImplementation.operator.unique": "
|
|
438
|
+
"ruleImplementation.operator.unique": "único",
|
|
439
|
+
"ruleImplementation.operator.unique.field_list": "único en conjunto",
|
|
439
440
|
"ruleImplementation.operator.variation_on_count.string": "variación conteo",
|
|
440
441
|
"ruleImplementation.operator.variation_on_count": "variación conteo",
|
|
441
442
|
"ruleImplementation.props.esquema.placeholder": "añade una estructura",
|
|
@@ -516,6 +517,7 @@ export default {
|
|
|
516
517
|
"ruleImplementations.events.action_restored": "Implementación restaurada",
|
|
517
518
|
"ruleImplementations.events.action_updated": "Implementación actualizada",
|
|
518
519
|
"ruleImplementations.props.business_concept": "Concepto",
|
|
520
|
+
"ruleImplementations.props.last_change_at": "Fecha de última modificación",
|
|
519
521
|
"ruleImplementations.props.executable.false": "Interna",
|
|
520
522
|
"ruleImplementations.props.executable.true": "Ejecutable",
|
|
521
523
|
"ruleImplementations.props.executable": "Ejecutable",
|
|
@@ -545,6 +547,8 @@ export default {
|
|
|
545
547
|
"ruleImplementations.props.rule_template": "Plantilla de regla",
|
|
546
548
|
"ruleImplementations.props.implementation_template":
|
|
547
549
|
"Plantilla de implementación",
|
|
550
|
+
|
|
551
|
+
"ruleImplementations.props.version": "Versión",
|
|
548
552
|
"ruleImplementations.retrieved.results":
|
|
549
553
|
"{count} implementaciones encontradas",
|
|
550
554
|
"ruleImplementations.search.results.empty":
|
|
@@ -623,6 +627,7 @@ export default {
|
|
|
623
627
|
"tabs.dq.rule.audit": "Auditoría",
|
|
624
628
|
"tabs.dq.ruleImplementation.audit": "Auditoría",
|
|
625
629
|
"tabs.dq.ruleImplementation.details": "Detalles",
|
|
630
|
+
"tabs.dq.ruleImplementation.history": "Historial",
|
|
626
631
|
"tabs.dq.ruleImplementation.results": "Resultados",
|
|
627
632
|
"tabs.dq.ruleImplementation": "Implementación",
|
|
628
633
|
"tabs.dq.ruleImplementations": "Implementaciones",
|
package/src/routines.js
CHANGED
|
@@ -61,6 +61,9 @@ export const fetchRuleImplementation = createRoutine(
|
|
|
61
61
|
export const fetchRuleImplementations = createRoutine(
|
|
62
62
|
"FETCH_RULE_IMPLEMENTATIONS"
|
|
63
63
|
);
|
|
64
|
+
export const fetchRuleImplementationV2 = createRoutine(
|
|
65
|
+
"FETCH_RULE_IMPLEMENTATION_V2"
|
|
66
|
+
);
|
|
64
67
|
export const fetchRules = createRoutine("FETCH_RULES");
|
|
65
68
|
export const fetchSegmentResults = createRoutine("FETCH_SEGMENT_RESULTS");
|
|
66
69
|
export const openImplementationFilter = createRoutine(
|