@truedat/dq 4.37.0 → 4.37.4
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 +24 -0
- package/package.json +4 -4
- package/src/components/ImplementationsRoutes.js +4 -0
- package/src/components/RuleEventRow.js +47 -0
- package/src/components/RuleEvents.js +31 -0
- package/src/components/RuleImplementationSelectedFilters.js +23 -1
- package/src/components/RuleImplementationsDownload.js +2 -1
- package/src/components/RuleRoutes.js +24 -0
- package/src/components/RuleSelectedFilters.js +21 -1
- package/src/components/RuleTabs.js +16 -2
- package/src/components/RulesRoutes.js +13 -1
- package/src/components/__tests__/RuleEventRow.spec.js +33 -0
- package/src/components/__tests__/RuleEvents.spec.js +64 -0
- package/src/components/__tests__/__snapshots__/RuleEventRow.spec.js.snap +38 -0
- package/src/components/__tests__/__snapshots__/RuleEvents.spec.js.snap +78 -0
- package/src/messages/en.js +8 -0
- package/src/messages/es.js +11 -0
- package/src/reducers/__tests__/ruleActiveFilters.spec.js +19 -7
- package/src/reducers/__tests__/ruleImplementationActiveFilters.spec.js +19 -7
- package/src/reducers/index.js +2 -0
- package/src/reducers/ruleActiveFilters.js +5 -0
- package/src/reducers/ruleImplementationActiveFilters.js +7 -0
- package/src/reducers/ruleImplementationFilters.js +1 -1
- package/src/reducers/ruleImplementationFiltersLoading.js +14 -0
- package/src/selectors/__tests__/getParsedEvents.spec.js +173 -0
- package/src/selectors/getParsedEvents.js +55 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [4.37.4] 2022-02-04
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- [TD-4424] Disable user filters while rule filters are loading
|
|
8
|
+
|
|
9
|
+
## [4.37.3] 2022-02-03
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- [TD-2929] Added support for `UserSearchFilters` on `Rules` and `RuleImplementations`
|
|
14
|
+
|
|
15
|
+
## [4.37.2] 2022-02-02
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- [TD-4294] Rule audit tab
|
|
20
|
+
|
|
21
|
+
## [4.37.1] 2022-02-02
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- [TD-4152] Include aditional information on implementations download
|
|
26
|
+
|
|
3
27
|
## [4.37.0] 2022-01-25
|
|
4
28
|
|
|
5
29
|
### Changed
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truedat/dq",
|
|
3
|
-
"version": "4.37.
|
|
3
|
+
"version": "4.37.4",
|
|
4
4
|
"description": "Truedat Web Data Quality Module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"jsnext:main": "src/index.js",
|
|
@@ -82,8 +82,8 @@
|
|
|
82
82
|
},
|
|
83
83
|
"dependencies": {
|
|
84
84
|
"@apollo/client": "^3.4.10",
|
|
85
|
-
"@truedat/core": "4.37.
|
|
86
|
-
"@truedat/df": "4.37.
|
|
85
|
+
"@truedat/core": "4.37.4",
|
|
86
|
+
"@truedat/df": "4.37.4",
|
|
87
87
|
"axios": "^0.19.2",
|
|
88
88
|
"graphql": "^15.5.3",
|
|
89
89
|
"path-to-regexp": "^1.7.0",
|
|
@@ -103,5 +103,5 @@
|
|
|
103
103
|
"react-dom": ">= 16.8.6 < 17",
|
|
104
104
|
"semantic-ui-react": ">= 0.88.2 < 2.1"
|
|
105
105
|
},
|
|
106
|
-
"gitHead": "
|
|
106
|
+
"gitHead": "d6a390c1a843d164c28cf7ae174126b6c0e24618"
|
|
107
107
|
}
|
|
@@ -8,6 +8,9 @@ import RuleImplementationsLoader from "./RuleImplementationsLoader";
|
|
|
8
8
|
const TemplatesLoader = React.lazy(() =>
|
|
9
9
|
import("@truedat/df/templates/components/TemplatesLoader")
|
|
10
10
|
);
|
|
11
|
+
const UserSearchFiltersLoader = React.lazy(() =>
|
|
12
|
+
import("@truedat/dd/components/UserSearchFiltersLoader")
|
|
13
|
+
);
|
|
11
14
|
|
|
12
15
|
const ImplementationsRoutes = () => (
|
|
13
16
|
<Route
|
|
@@ -17,6 +20,7 @@ const ImplementationsRoutes = () => (
|
|
|
17
20
|
<RuleImplementationsLoader />
|
|
18
21
|
<ImplementationFiltersLoader />
|
|
19
22
|
<TemplatesLoader scope="qe" />
|
|
23
|
+
<UserSearchFiltersLoader scope="rule_implementation" />
|
|
20
24
|
<RuleImplementations exact />
|
|
21
25
|
</>
|
|
22
26
|
)}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import PropTypes from "prop-types";
|
|
4
|
+
import { Feed } from "semantic-ui-react";
|
|
5
|
+
import { useIntl } from "react-intl";
|
|
6
|
+
import Moment from "react-moment";
|
|
7
|
+
|
|
8
|
+
export const RuleEventRow = ({ user, user_name, ts, payload }) => {
|
|
9
|
+
const { formatMessage, locale } = useIntl();
|
|
10
|
+
const userName = _.propOr(user_name, "user_name")(user);
|
|
11
|
+
|
|
12
|
+
return _.isEmpty(payload) ? null : (
|
|
13
|
+
<Feed.Event>
|
|
14
|
+
<Feed.Content>
|
|
15
|
+
<Feed.Summary>
|
|
16
|
+
<Feed.User>{userName}</Feed.User>{" "}
|
|
17
|
+
<Feed.Date>
|
|
18
|
+
<Moment locale={locale} date={ts} format="YYYY-MM-DD HH:mm" />
|
|
19
|
+
</Feed.Date>
|
|
20
|
+
</Feed.Summary>
|
|
21
|
+
{payload.map(({ field, action, value }, i) => (
|
|
22
|
+
<Feed.Extra
|
|
23
|
+
key={i}
|
|
24
|
+
text
|
|
25
|
+
content={formatMessage(
|
|
26
|
+
{
|
|
27
|
+
id: `rules.events.action_${action}${
|
|
28
|
+
typeof value === "undefined" || _.isObject(value) ? "" : "_to"
|
|
29
|
+
}`,
|
|
30
|
+
},
|
|
31
|
+
[field, JSON.stringify(value)]
|
|
32
|
+
)}
|
|
33
|
+
/>
|
|
34
|
+
))}
|
|
35
|
+
</Feed.Content>
|
|
36
|
+
</Feed.Event>
|
|
37
|
+
);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
RuleEventRow.propTypes = {
|
|
41
|
+
user: PropTypes.object,
|
|
42
|
+
user_name: PropTypes.string,
|
|
43
|
+
ts: PropTypes.string,
|
|
44
|
+
payload: PropTypes.array,
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export default RuleEventRow;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
import { Feed, Segment } from "semantic-ui-react";
|
|
4
|
+
import { connect } from "react-redux";
|
|
5
|
+
import { getParsedEvents } from "../selectors";
|
|
6
|
+
import { RuleEventRow } from "./RuleEventRow";
|
|
7
|
+
|
|
8
|
+
export const RuleEvents = ({ events, eventsLoading }) => {
|
|
9
|
+
return eventsLoading ? null : (
|
|
10
|
+
<Segment attached="bottom">
|
|
11
|
+
<Feed size="small">
|
|
12
|
+
{events.map((e, i) => (
|
|
13
|
+
<RuleEventRow key={i} {...e} />
|
|
14
|
+
))}
|
|
15
|
+
</Feed>
|
|
16
|
+
</Segment>
|
|
17
|
+
);
|
|
18
|
+
};
|
|
19
|
+
RuleEvents.propTypes = {
|
|
20
|
+
events: PropTypes.array.isRequired,
|
|
21
|
+
eventsLoading: PropTypes.bool,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const mapStateToProps = (state) => {
|
|
25
|
+
return {
|
|
26
|
+
events: getParsedEvents(state),
|
|
27
|
+
eventsLoading: state.eventsLoading,
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export default connect(mapStateToProps)(RuleEvents);
|
|
@@ -4,6 +4,11 @@ import { connect } from "react-redux";
|
|
|
4
4
|
import { injectIntl } from "react-intl";
|
|
5
5
|
import { makeOption } from "@truedat/core/services/i18n";
|
|
6
6
|
import { SelectedFilters } from "@truedat/core/components";
|
|
7
|
+
import {
|
|
8
|
+
applyUserSearchFilter,
|
|
9
|
+
deleteUserSearchFilter,
|
|
10
|
+
saveUserSearchFilters,
|
|
11
|
+
} from "@truedat/dd/routines";
|
|
7
12
|
import {
|
|
8
13
|
closeImplementationFilter,
|
|
9
14
|
openImplementationFilter,
|
|
@@ -24,29 +29,46 @@ const translations = (formatMessage) => ({
|
|
|
24
29
|
|
|
25
30
|
export const mapStateToProps = (state, ownProps) => {
|
|
26
31
|
const formatMessage = _.pathOr(_.prop("id"), "intl.formatMessage")(ownProps);
|
|
27
|
-
const {
|
|
32
|
+
const {
|
|
33
|
+
ruleImplementationFiltersLoading: loading,
|
|
34
|
+
ruleImplementationSelectedFilter: selectedFilter,
|
|
35
|
+
} = state;
|
|
28
36
|
const i18nValues = _.flow(
|
|
29
37
|
getRuleImplementationSelectedFilterValues,
|
|
30
38
|
_.map(makeOption(translations(formatMessage), selectedFilter))
|
|
31
39
|
)(state);
|
|
32
40
|
|
|
41
|
+
const {
|
|
42
|
+
selectedUserSearchFilter: selectedUserFilter,
|
|
43
|
+
ruleImplementationActiveFilters: activeFilters,
|
|
44
|
+
userSearchFilters: userFilters,
|
|
45
|
+
} = state;
|
|
46
|
+
|
|
33
47
|
return {
|
|
48
|
+
loading,
|
|
34
49
|
selectedFilter,
|
|
35
50
|
selectedFilters: getRuleImplementationSelectedFilters(state),
|
|
36
51
|
selectedFilterActiveValues:
|
|
37
52
|
getRuleImplementationSelectedFilterActiveValues(state),
|
|
38
53
|
selectedFilterValues: i18nValues,
|
|
54
|
+
selectedUserFilter,
|
|
55
|
+
activeFilters,
|
|
56
|
+
userFilters,
|
|
57
|
+
userFilterScope: "rule_implementation",
|
|
39
58
|
};
|
|
40
59
|
};
|
|
41
60
|
|
|
42
61
|
const mapDispatchToProps = (dispatch) =>
|
|
43
62
|
bindActionCreators(
|
|
44
63
|
{
|
|
64
|
+
applyUserFilter: applyUserSearchFilter,
|
|
45
65
|
closeFilter: closeImplementationFilter,
|
|
66
|
+
deleteUserFilter: deleteUserSearchFilter,
|
|
46
67
|
openFilter: openImplementationFilter,
|
|
47
68
|
removeFilter: removeImplementationFilter,
|
|
48
69
|
resetFilters: resetImplementationFilters,
|
|
49
70
|
toggleFilterValue: toggleImplementationFilterValue,
|
|
71
|
+
saveFilters: saveUserSearchFilters,
|
|
50
72
|
},
|
|
51
73
|
dispatch
|
|
52
74
|
);
|
|
@@ -9,6 +9,7 @@ import { useAuthorized } from "@truedat/core/hooks";
|
|
|
9
9
|
import {
|
|
10
10
|
RULE,
|
|
11
11
|
RULE_EDIT,
|
|
12
|
+
RULE_EVENTS,
|
|
12
13
|
RULE_IMPLEMENTATION_RESULT_DETAILS,
|
|
13
14
|
RULE_IMPLEMENTATION_RESULTS_DETAILS,
|
|
14
15
|
RULE_IMPLEMENTATION,
|
|
@@ -32,6 +33,7 @@ import NewRule from "./NewRule";
|
|
|
32
33
|
import NewRuleImplementation from "./NewRuleImplementation";
|
|
33
34
|
import Rule from "./Rule";
|
|
34
35
|
import RuleCrumbs from "./RuleCrumbs";
|
|
36
|
+
import RuleEvents from "./RuleEvents";
|
|
35
37
|
import RuleImplementation from "./RuleImplementation";
|
|
36
38
|
import RuleImplementationEvents from "./RuleImplementationEvents";
|
|
37
39
|
import RuleImplementationLoader from "./RuleImplementationLoader";
|
|
@@ -61,6 +63,12 @@ const ImplementationStructuresLoader = React.lazy(() =>
|
|
|
61
63
|
const QualityTemplatesLoader = () => <TemplatesLoader scope="dq" />;
|
|
62
64
|
const ImplementationTemplatesLoader = () => <TemplatesLoader scope="ri" />;
|
|
63
65
|
|
|
66
|
+
const RuleEventsLoader = () => {
|
|
67
|
+
const match = useRouteMatch();
|
|
68
|
+
const id = _.path("params.id")(match);
|
|
69
|
+
return <EventsLoader resource_id={id} resource_type="rule" />;
|
|
70
|
+
};
|
|
71
|
+
|
|
64
72
|
const ImplementationEventsLoader = () => {
|
|
65
73
|
const match = useRouteMatch();
|
|
66
74
|
const id = _.path("params.implementation_id")(match);
|
|
@@ -135,6 +143,22 @@ const RuleRoutes = ({
|
|
|
135
143
|
</>
|
|
136
144
|
)}
|
|
137
145
|
/>
|
|
146
|
+
|
|
147
|
+
<Route
|
|
148
|
+
exact
|
|
149
|
+
path={RULE_EVENTS}
|
|
150
|
+
render={() => (
|
|
151
|
+
<>
|
|
152
|
+
<RuleCrumbs />
|
|
153
|
+
<Segment>
|
|
154
|
+
<RuleEventsLoader />
|
|
155
|
+
{ruleLoaded && <Rule />}
|
|
156
|
+
{ruleLoaded && <RuleEvents />}
|
|
157
|
+
</Segment>
|
|
158
|
+
</>
|
|
159
|
+
)}
|
|
160
|
+
/>
|
|
161
|
+
|
|
138
162
|
<Route
|
|
139
163
|
exact
|
|
140
164
|
path={RULE_IMPLEMENTATIONS}
|
|
@@ -4,6 +4,11 @@ import { connect } from "react-redux";
|
|
|
4
4
|
import { injectIntl } from "react-intl";
|
|
5
5
|
import { makeOption } from "@truedat/core/services/i18n";
|
|
6
6
|
import { SelectedFilters } from "@truedat/core/components";
|
|
7
|
+
import {
|
|
8
|
+
applyUserSearchFilter,
|
|
9
|
+
deleteUserSearchFilter,
|
|
10
|
+
saveUserSearchFilters,
|
|
11
|
+
} from "@truedat/dd/routines";
|
|
7
12
|
import {
|
|
8
13
|
closeRuleFilter,
|
|
9
14
|
openRuleFilter,
|
|
@@ -24,28 +29,43 @@ const translations = (formatMessage) => ({
|
|
|
24
29
|
|
|
25
30
|
export const mapStateToProps = (state, ownProps) => {
|
|
26
31
|
const formatMessage = _.pathOr(_.prop("id"), "intl.formatMessage")(ownProps);
|
|
27
|
-
const { ruleSelectedFilter: selectedFilter } =
|
|
32
|
+
const { ruleFiltersLoading: loading, ruleSelectedFilter: selectedFilter } =
|
|
33
|
+
state;
|
|
28
34
|
const i18nValues = _.flow(
|
|
29
35
|
getRuleSelectedFilterValues,
|
|
30
36
|
_.map(makeOption(translations(formatMessage), selectedFilter))
|
|
31
37
|
)(state);
|
|
32
38
|
|
|
39
|
+
const {
|
|
40
|
+
selectedUserSearchFilter: selectedUserFilter,
|
|
41
|
+
ruleActiveFilters: activeFilters,
|
|
42
|
+
userSearchFilters: userFilters,
|
|
43
|
+
} = state;
|
|
44
|
+
|
|
33
45
|
return {
|
|
46
|
+
loading,
|
|
34
47
|
selectedFilter,
|
|
35
48
|
selectedFilters: getRuleSelectedFilters(state),
|
|
36
49
|
selectedFilterActiveValues: getRuleSelectedFilterActiveValues(state),
|
|
37
50
|
selectedFilterValues: i18nValues,
|
|
51
|
+
selectedUserFilter,
|
|
52
|
+
activeFilters,
|
|
53
|
+
userFilters,
|
|
54
|
+
userFilterScope: "rule",
|
|
38
55
|
};
|
|
39
56
|
};
|
|
40
57
|
|
|
41
58
|
const mapDispatchToProps = (dispatch) =>
|
|
42
59
|
bindActionCreators(
|
|
43
60
|
{
|
|
61
|
+
applyUserFilter: applyUserSearchFilter,
|
|
44
62
|
closeFilter: closeRuleFilter,
|
|
63
|
+
deleteUserFilter: deleteUserSearchFilter,
|
|
45
64
|
openFilter: openRuleFilter,
|
|
46
65
|
removeFilter: removeRuleFilter,
|
|
47
66
|
resetFilters: resetRuleFilters,
|
|
48
67
|
toggleFilterValue: toggleRuleFilterValue,
|
|
68
|
+
saveFilters: saveUserSearchFilters,
|
|
49
69
|
},
|
|
50
70
|
dispatch
|
|
51
71
|
);
|
|
@@ -6,7 +6,12 @@ import { Link } from "react-router-dom";
|
|
|
6
6
|
import { connect } from "react-redux";
|
|
7
7
|
import { FormattedMessage } from "react-intl";
|
|
8
8
|
import { usePath } from "@truedat/core/hooks";
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
RULE,
|
|
11
|
+
RULE_IMPLEMENTATIONS,
|
|
12
|
+
RULE_EVENTS,
|
|
13
|
+
linkTo,
|
|
14
|
+
} from "@truedat/core/routes";
|
|
10
15
|
|
|
11
16
|
const RuleTabs = ({ rule }) => {
|
|
12
17
|
const path = usePath();
|
|
@@ -22,12 +27,21 @@ const RuleTabs = ({ rule }) => {
|
|
|
22
27
|
>
|
|
23
28
|
<FormattedMessage id="tabs.dq.ruleImplementations" />
|
|
24
29
|
</Menu.Item>
|
|
30
|
+
<Menu.Item
|
|
31
|
+
active={path === RULE_EVENTS}
|
|
32
|
+
as={Link}
|
|
33
|
+
to={linkTo.RULE_EVENTS({
|
|
34
|
+
id: rule.id,
|
|
35
|
+
})}
|
|
36
|
+
>
|
|
37
|
+
<FormattedMessage id="tabs.dq.rule.audit" />
|
|
38
|
+
</Menu.Item>
|
|
25
39
|
</Menu>
|
|
26
40
|
);
|
|
27
41
|
};
|
|
28
42
|
|
|
29
43
|
RuleTabs.propTypes = {
|
|
30
|
-
rule: PropTypes.object
|
|
44
|
+
rule: PropTypes.object,
|
|
31
45
|
};
|
|
32
46
|
|
|
33
47
|
const mapStateToProps = ({ rule }) => ({ rule });
|
|
@@ -13,13 +13,25 @@ const DomainsLoader = React.lazy(() =>
|
|
|
13
13
|
const TemplatesLoader = React.lazy(() =>
|
|
14
14
|
import("@truedat/df/templates/components/TemplatesLoader")
|
|
15
15
|
);
|
|
16
|
+
const UserSearchFiltersLoader = React.lazy(() =>
|
|
17
|
+
import("@truedat/dd/components/UserSearchFiltersLoader")
|
|
18
|
+
);
|
|
16
19
|
const QualityTemplatesLoader = () => <TemplatesLoader scope="dq" />;
|
|
17
20
|
|
|
18
21
|
const RulesRoutes = () => (
|
|
19
22
|
<>
|
|
20
23
|
<Route path={RULES} component={RulesLoader} />
|
|
21
24
|
<Route path={RULES} component={RuleFiltersLoader} />
|
|
22
|
-
<Route
|
|
25
|
+
<Route
|
|
26
|
+
exact
|
|
27
|
+
path={RULES}
|
|
28
|
+
render={() => (
|
|
29
|
+
<>
|
|
30
|
+
<UserSearchFiltersLoader scope="rule" />
|
|
31
|
+
<Rules />
|
|
32
|
+
</>
|
|
33
|
+
)}
|
|
34
|
+
/>
|
|
23
35
|
<Switch>
|
|
24
36
|
<Route
|
|
25
37
|
exact
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "@truedat/test/render";
|
|
3
|
+
import { RuleEventRow } from "../RuleEventRow";
|
|
4
|
+
|
|
5
|
+
describe("<RuleEventsRow />", () => {
|
|
6
|
+
const props = {
|
|
7
|
+
payload: [
|
|
8
|
+
{
|
|
9
|
+
field: "field1",
|
|
10
|
+
action: "changed",
|
|
11
|
+
value: "new value",
|
|
12
|
+
},
|
|
13
|
+
],
|
|
14
|
+
user_name: "some.user@domain.tld",
|
|
15
|
+
user: {
|
|
16
|
+
email: "some.user@domain.tld",
|
|
17
|
+
full_name: "Some User",
|
|
18
|
+
id: 142,
|
|
19
|
+
user_name: "some.user@domain.tld",
|
|
20
|
+
},
|
|
21
|
+
ts: "2021-09-16T07:36:32.848603Z",
|
|
22
|
+
};
|
|
23
|
+
const renderOpts = {
|
|
24
|
+
messages: {
|
|
25
|
+
en: { "rules.events.action_changed_to": "Field {0} changed to: {1}" },
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
it("matches the latest snapshot", () => {
|
|
30
|
+
const { container } = render(<RuleEventRow {...props} />, renderOpts);
|
|
31
|
+
expect(container).toMatchSnapshot();
|
|
32
|
+
});
|
|
33
|
+
});
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "@truedat/test/render";
|
|
3
|
+
import { RuleEvents } from "../RuleEvents";
|
|
4
|
+
import { getParsedEvents } from "../../selectors/getParsedEvents";
|
|
5
|
+
|
|
6
|
+
describe("<RuleEvents />", () => {
|
|
7
|
+
const events = [
|
|
8
|
+
{
|
|
9
|
+
id: 100217,
|
|
10
|
+
service: "td_dd",
|
|
11
|
+
resource_id: 777,
|
|
12
|
+
resource_type: "rule",
|
|
13
|
+
event: "rule_updated",
|
|
14
|
+
payload: {
|
|
15
|
+
domain_id: 140,
|
|
16
|
+
},
|
|
17
|
+
user_id: 142,
|
|
18
|
+
user_name: null,
|
|
19
|
+
user: {
|
|
20
|
+
email: "some.user@domain.tld",
|
|
21
|
+
full_name: "Some User",
|
|
22
|
+
id: 142,
|
|
23
|
+
user_name: "some.user@domain.tld",
|
|
24
|
+
},
|
|
25
|
+
ts: "2021-09-16T07:36:32.848603Z",
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
id: 100436,
|
|
29
|
+
service: "td_dd",
|
|
30
|
+
resource_id: 777,
|
|
31
|
+
resource_type: "rule",
|
|
32
|
+
event: "rule_updated",
|
|
33
|
+
payload: {
|
|
34
|
+
domain_id: 168,
|
|
35
|
+
},
|
|
36
|
+
user_id: 171,
|
|
37
|
+
user_name: null,
|
|
38
|
+
user: {
|
|
39
|
+
email: "some.user@domain.tld",
|
|
40
|
+
full_name: "Some User",
|
|
41
|
+
id: 171,
|
|
42
|
+
user_name: "some.user",
|
|
43
|
+
},
|
|
44
|
+
ts: "2021-09-16T09:31:03.061864Z",
|
|
45
|
+
},
|
|
46
|
+
];
|
|
47
|
+
const renderOpts = {
|
|
48
|
+
messages: {
|
|
49
|
+
en: {
|
|
50
|
+
"rules.events.action_created": "Rule created",
|
|
51
|
+
"rules.events.action_changed": "Field {0} changed: {1}",
|
|
52
|
+
"rules.events.action_changed_to": "Field {0} changed to: {1}",
|
|
53
|
+
"rules.events.action_updated": "Rule updated",
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const props = { events: getParsedEvents({ events }), eventsLoading: false };
|
|
59
|
+
|
|
60
|
+
it("matches the latest snapshot", () => {
|
|
61
|
+
const { container } = render(<RuleEvents {...props} />, renderOpts);
|
|
62
|
+
expect(container).toMatchSnapshot();
|
|
63
|
+
});
|
|
64
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`<RuleEventsRow /> matches the latest snapshot 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
class="event"
|
|
7
|
+
>
|
|
8
|
+
<div
|
|
9
|
+
class="content"
|
|
10
|
+
>
|
|
11
|
+
<div
|
|
12
|
+
class="summary"
|
|
13
|
+
>
|
|
14
|
+
<a
|
|
15
|
+
class="user"
|
|
16
|
+
>
|
|
17
|
+
some.user@domain.tld
|
|
18
|
+
</a>
|
|
19
|
+
|
|
20
|
+
<div
|
|
21
|
+
class="date"
|
|
22
|
+
>
|
|
23
|
+
<time
|
|
24
|
+
datetime="1631777792848"
|
|
25
|
+
>
|
|
26
|
+
2021-09-16 07:36
|
|
27
|
+
</time>
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
<div
|
|
31
|
+
class="text extra"
|
|
32
|
+
>
|
|
33
|
+
Field field1 changed to: "new value"
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
`;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`<RuleEvents /> matches the latest snapshot 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
class="ui bottom attached segment"
|
|
7
|
+
>
|
|
8
|
+
<div
|
|
9
|
+
class="ui small feed"
|
|
10
|
+
>
|
|
11
|
+
<div
|
|
12
|
+
class="event"
|
|
13
|
+
>
|
|
14
|
+
<div
|
|
15
|
+
class="content"
|
|
16
|
+
>
|
|
17
|
+
<div
|
|
18
|
+
class="summary"
|
|
19
|
+
>
|
|
20
|
+
<a
|
|
21
|
+
class="user"
|
|
22
|
+
>
|
|
23
|
+
some.user@domain.tld
|
|
24
|
+
</a>
|
|
25
|
+
|
|
26
|
+
<div
|
|
27
|
+
class="date"
|
|
28
|
+
>
|
|
29
|
+
<time
|
|
30
|
+
datetime="1631777792848"
|
|
31
|
+
>
|
|
32
|
+
2021-09-16 07:36
|
|
33
|
+
</time>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
<div
|
|
37
|
+
class="text extra"
|
|
38
|
+
>
|
|
39
|
+
Field domain_id changed to: 140
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
<div
|
|
44
|
+
class="event"
|
|
45
|
+
>
|
|
46
|
+
<div
|
|
47
|
+
class="content"
|
|
48
|
+
>
|
|
49
|
+
<div
|
|
50
|
+
class="summary"
|
|
51
|
+
>
|
|
52
|
+
<a
|
|
53
|
+
class="user"
|
|
54
|
+
>
|
|
55
|
+
some.user
|
|
56
|
+
</a>
|
|
57
|
+
|
|
58
|
+
<div
|
|
59
|
+
class="date"
|
|
60
|
+
>
|
|
61
|
+
<time
|
|
62
|
+
datetime="1631784663061"
|
|
63
|
+
>
|
|
64
|
+
2021-09-16 09:31
|
|
65
|
+
</time>
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
<div
|
|
69
|
+
class="text extra"
|
|
70
|
+
>
|
|
71
|
+
Field domain_id changed to: 168
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
`;
|
package/src/messages/en.js
CHANGED
|
@@ -132,6 +132,7 @@ export default {
|
|
|
132
132
|
"All rule implementations should be removed",
|
|
133
133
|
"rule.error.rule_name_bc_id.unique_constraint":
|
|
134
134
|
"Duplicated rule name. Edit name or associated business concept.",
|
|
135
|
+
|
|
135
136
|
"rule.form.accordion.select": "Select",
|
|
136
137
|
"rule.form.concept.label": "Concept",
|
|
137
138
|
"ruleImplementation.form.tooltip.deviation.goal":
|
|
@@ -497,6 +498,8 @@ export default {
|
|
|
497
498
|
"ruleImplementations.props.result": "Quality",
|
|
498
499
|
"ruleImplementations.props.rule": "Rule",
|
|
499
500
|
"ruleImplementations.props.template": "Template",
|
|
501
|
+
"ruleImplementations.props.rule_template": "Rule template",
|
|
502
|
+
"ruleImplementations.props.implementation_template": "Implementation template",
|
|
500
503
|
"ruleImplementations.retrieved.results": "{count} implementations found",
|
|
501
504
|
"ruleImplementations.search.results.empty": "No implementations found",
|
|
502
505
|
"ruleImplementations.searching": "Searching implementations",
|
|
@@ -539,6 +542,10 @@ export default {
|
|
|
539
542
|
"rules.actions.upload.confirmation.header": "Confirm bulk upload",
|
|
540
543
|
"rules.actions.upload.tooltip": "Upload Rules",
|
|
541
544
|
"rules.crumbs.top": "Rules",
|
|
545
|
+
"rules.events.action_created": "Rule created",
|
|
546
|
+
"rules.events.action_changed": "Field {0} changed: {1}",
|
|
547
|
+
"rules.events.action_changed_to": "Field {0} changed to: {1}",
|
|
548
|
+
"rules.events.action_updated": "Rule updated",
|
|
542
549
|
"rules.retrieved.results": "{count} rules found",
|
|
543
550
|
"rules.search.placeholder": "Search rules...",
|
|
544
551
|
"rules.searching": "Searching...",
|
|
@@ -555,6 +562,7 @@ export default {
|
|
|
555
562
|
"structureFields.dropdown.placeholder": "Fields",
|
|
556
563
|
"summary.link.and": "and",
|
|
557
564
|
"tabs.dq.rule": "Rule",
|
|
565
|
+
"tabs.dq.rule.audit": "Audit",
|
|
558
566
|
"tabs.dq.ruleImplementation": "Implementation",
|
|
559
567
|
"tabs.dq.ruleImplementation.audit": "Audit",
|
|
560
568
|
"tabs.dq.ruleImplementation.details": "Details",
|
package/src/messages/es.js
CHANGED
|
@@ -511,6 +511,8 @@ export default {
|
|
|
511
511
|
"ruleImplementations.props.rule": "Regla",
|
|
512
512
|
"ruleImplementations.props.status": "Estado",
|
|
513
513
|
"ruleImplementations.props.template": "Plantilla",
|
|
514
|
+
"ruleImplementations.props.rule_template": "Plantilla de regla",
|
|
515
|
+
"ruleImplementations.props.implementation_template": "Plantilla de implementación",
|
|
514
516
|
"ruleImplementations.retrieved.results":
|
|
515
517
|
"{count} implementaciones encontradas",
|
|
516
518
|
"ruleImplementations.search.results.empty":
|
|
@@ -554,6 +556,14 @@ export default {
|
|
|
554
556
|
"rules.actions.upload.confirmation.header": "Subir ficheros de reglas",
|
|
555
557
|
"rules.actions.upload.tooltip": "Subir reglas",
|
|
556
558
|
"rules.crumbs.top": "Reglas",
|
|
559
|
+
"rules.events.action_created": "Regla creada",
|
|
560
|
+
"rules.events.action_changed": "Campo {0} actualizado: {1}",
|
|
561
|
+
"rules.events.action_changed_to": "Campo {0} actualizado a {1}",
|
|
562
|
+
"rules.events.action_updated": "Regla actualizada",
|
|
563
|
+
"ruleImplementations.events.action_created": "Implementación creada en regla: {0}",
|
|
564
|
+
"ruleImplementations.events.action_changed": "Campo {0} actualizado a {1}",
|
|
565
|
+
"ruleImplementations.events.action_deprecated": "Implementación archivada",
|
|
566
|
+
"ruleImplementations.events.action_moved": "Implementación movida a la regla: {0}",
|
|
557
567
|
"rules.retrieved.results": "{count} reglas encontradas",
|
|
558
568
|
"rules.search.placeholder": "Buscar reglas...",
|
|
559
569
|
"rules.searching": "Buscando...",
|
|
@@ -571,6 +581,7 @@ export default {
|
|
|
571
581
|
"structureFields.dropdown.placeholder": "Campos",
|
|
572
582
|
"summary.link.and": "y",
|
|
573
583
|
"tabs.dq.rule": "Regla",
|
|
584
|
+
"tabs.dq.rule.audit": "Auditoría",
|
|
574
585
|
"tabs.dq.ruleImplementation.audit": "Auditoría",
|
|
575
586
|
"tabs.dq.ruleImplementation.details": "Detalles",
|
|
576
587
|
"tabs.dq.ruleImplementation.results": "Resultados",
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { applyUserSearchFilter } from "@truedat/dd/routines";
|
|
1
2
|
import { initialState } from "../ruleActiveFilters";
|
|
2
3
|
import {
|
|
3
4
|
addRuleFilter,
|
|
4
5
|
closeRuleFilter,
|
|
5
6
|
removeRuleFilter,
|
|
6
7
|
resetRuleFilters,
|
|
7
|
-
toggleRuleFilterValue
|
|
8
|
+
toggleRuleFilterValue,
|
|
8
9
|
} from "../../routines";
|
|
9
10
|
import { ruleActiveFilters } from "..";
|
|
10
11
|
|
|
@@ -21,11 +22,22 @@ describe("reducers: ruleActiveFilters", () => {
|
|
|
21
22
|
expect(
|
|
22
23
|
ruleActiveFilters(fooState, {
|
|
23
24
|
type: addRuleFilter.TRIGGER,
|
|
24
|
-
payload
|
|
25
|
+
payload,
|
|
25
26
|
})
|
|
26
27
|
).toEqual({ ...fooState, baz: [] });
|
|
27
28
|
});
|
|
28
29
|
|
|
30
|
+
it("should handle the applyUserSearchFilter.TRIGGER action", () => {
|
|
31
|
+
const filters = { country: ["Sp"] };
|
|
32
|
+
const payload = { userFilter: { filters }, scope: "rule" };
|
|
33
|
+
expect(
|
|
34
|
+
ruleActiveFilters(fooState, {
|
|
35
|
+
type: applyUserSearchFilter.TRIGGER,
|
|
36
|
+
payload,
|
|
37
|
+
})
|
|
38
|
+
).toEqual({ ...filters });
|
|
39
|
+
});
|
|
40
|
+
|
|
29
41
|
it("should handle the closeRuleFilter.TRIGGER action", () => {
|
|
30
42
|
const foo = ["foo1"];
|
|
31
43
|
const bar = [];
|
|
@@ -34,7 +46,7 @@ describe("reducers: ruleActiveFilters", () => {
|
|
|
34
46
|
expect(
|
|
35
47
|
ruleActiveFilters(state, {
|
|
36
48
|
type: closeRuleFilter.TRIGGER,
|
|
37
|
-
payload
|
|
49
|
+
payload,
|
|
38
50
|
})
|
|
39
51
|
).toEqual({ foo });
|
|
40
52
|
});
|
|
@@ -47,7 +59,7 @@ describe("reducers: ruleActiveFilters", () => {
|
|
|
47
59
|
expect(
|
|
48
60
|
ruleActiveFilters(state, {
|
|
49
61
|
type: removeRuleFilter.TRIGGER,
|
|
50
|
-
payload
|
|
62
|
+
payload,
|
|
51
63
|
})
|
|
52
64
|
).toEqual({ bar });
|
|
53
65
|
});
|
|
@@ -55,7 +67,7 @@ describe("reducers: ruleActiveFilters", () => {
|
|
|
55
67
|
it("should handle the resetRuleFilters.TRIGGER action", () => {
|
|
56
68
|
expect(
|
|
57
69
|
ruleActiveFilters(fooState, {
|
|
58
|
-
type: resetRuleFilters.TRIGGER
|
|
70
|
+
type: resetRuleFilters.TRIGGER,
|
|
59
71
|
})
|
|
60
72
|
).toEqual(initialState);
|
|
61
73
|
});
|
|
@@ -63,7 +75,7 @@ describe("reducers: ruleActiveFilters", () => {
|
|
|
63
75
|
it("should handle the resetRuleFilters.TRIGGER action when execution filter exists", () => {
|
|
64
76
|
expect(
|
|
65
77
|
ruleActiveFilters(fooState, {
|
|
66
|
-
type: resetRuleFilters.TRIGGER
|
|
78
|
+
type: resetRuleFilters.TRIGGER,
|
|
67
79
|
})
|
|
68
80
|
).toEqual(initialState);
|
|
69
81
|
});
|
|
@@ -76,7 +88,7 @@ describe("reducers: ruleActiveFilters", () => {
|
|
|
76
88
|
expect(
|
|
77
89
|
ruleActiveFilters(state, {
|
|
78
90
|
type: toggleRuleFilterValue.TRIGGER,
|
|
79
|
-
payload
|
|
91
|
+
payload,
|
|
80
92
|
})
|
|
81
93
|
).toEqual({ foo: ["foo1", "foo3"], bar });
|
|
82
94
|
});
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { applyUserSearchFilter } from "@truedat/dd/routines";
|
|
1
2
|
import { initialState } from "../ruleImplementationActiveFilters";
|
|
2
3
|
import {
|
|
3
4
|
addImplementationFilter,
|
|
4
5
|
closeImplementationFilter,
|
|
5
6
|
removeImplementationFilter,
|
|
6
7
|
resetImplementationFilters,
|
|
7
|
-
toggleImplementationFilterValue
|
|
8
|
+
toggleImplementationFilterValue,
|
|
8
9
|
} from "../../routines";
|
|
9
10
|
import { ruleImplementationActiveFilters } from "..";
|
|
10
11
|
|
|
@@ -17,13 +18,24 @@ describe("reducers: ruleImplementationActiveFilters", () => {
|
|
|
17
18
|
);
|
|
18
19
|
});
|
|
19
20
|
|
|
21
|
+
it("should handle the applyUserSearchFilter.TRIGGER action", () => {
|
|
22
|
+
const filters = { country: ["Sp"] };
|
|
23
|
+
const payload = { userFilter: { filters }, scope: "rule_implementation" };
|
|
24
|
+
expect(
|
|
25
|
+
ruleImplementationActiveFilters(fooState, {
|
|
26
|
+
type: applyUserSearchFilter.TRIGGER,
|
|
27
|
+
payload,
|
|
28
|
+
})
|
|
29
|
+
).toEqual({ ...filters });
|
|
30
|
+
});
|
|
31
|
+
|
|
20
32
|
it("should handle the addImplementationFilter.TRIGGER action", () => {
|
|
21
33
|
const filter = "baz";
|
|
22
34
|
const payload = { filter };
|
|
23
35
|
expect(
|
|
24
36
|
ruleImplementationActiveFilters(fooState, {
|
|
25
37
|
type: addImplementationFilter.TRIGGER,
|
|
26
|
-
payload
|
|
38
|
+
payload,
|
|
27
39
|
})
|
|
28
40
|
).toEqual({ ...fooState, baz: [] });
|
|
29
41
|
});
|
|
@@ -36,7 +48,7 @@ describe("reducers: ruleImplementationActiveFilters", () => {
|
|
|
36
48
|
expect(
|
|
37
49
|
ruleImplementationActiveFilters(state, {
|
|
38
50
|
type: closeImplementationFilter.TRIGGER,
|
|
39
|
-
payload
|
|
51
|
+
payload,
|
|
40
52
|
})
|
|
41
53
|
).toEqual({ foo });
|
|
42
54
|
});
|
|
@@ -49,7 +61,7 @@ describe("reducers: ruleImplementationActiveFilters", () => {
|
|
|
49
61
|
expect(
|
|
50
62
|
ruleImplementationActiveFilters(state, {
|
|
51
63
|
type: removeImplementationFilter.TRIGGER,
|
|
52
|
-
payload
|
|
64
|
+
payload,
|
|
53
65
|
})
|
|
54
66
|
).toEqual({ bar });
|
|
55
67
|
});
|
|
@@ -57,7 +69,7 @@ describe("reducers: ruleImplementationActiveFilters", () => {
|
|
|
57
69
|
it("should handle the resetImplementationFilters.TRIGGER action", () => {
|
|
58
70
|
expect(
|
|
59
71
|
ruleImplementationActiveFilters(fooState, {
|
|
60
|
-
type: resetImplementationFilters.TRIGGER
|
|
72
|
+
type: resetImplementationFilters.TRIGGER,
|
|
61
73
|
})
|
|
62
74
|
).toEqual(initialState);
|
|
63
75
|
});
|
|
@@ -67,7 +79,7 @@ describe("reducers: ruleImplementationActiveFilters", () => {
|
|
|
67
79
|
ruleImplementationActiveFilters(
|
|
68
80
|
{ ...fooState, executable: [true] },
|
|
69
81
|
{
|
|
70
|
-
type: resetImplementationFilters.TRIGGER
|
|
82
|
+
type: resetImplementationFilters.TRIGGER,
|
|
71
83
|
}
|
|
72
84
|
)
|
|
73
85
|
).toEqual({ executable: [true] });
|
|
@@ -81,7 +93,7 @@ describe("reducers: ruleImplementationActiveFilters", () => {
|
|
|
81
93
|
expect(
|
|
82
94
|
ruleImplementationActiveFilters(state, {
|
|
83
95
|
type: toggleImplementationFilterValue.TRIGGER,
|
|
84
|
-
payload
|
|
96
|
+
payload,
|
|
85
97
|
})
|
|
86
98
|
).toEqual({ foo: ["foo1", "foo3"], bar });
|
|
87
99
|
});
|
package/src/reducers/index.js
CHANGED
|
@@ -17,6 +17,7 @@ import { ruleImplementation } from "./ruleImplementation";
|
|
|
17
17
|
import { ruleImplementationCount } from "./ruleImplementationCount";
|
|
18
18
|
import { ruleImplementationCreating } from "./ruleImplementationCreating";
|
|
19
19
|
import { ruleImplementationFilters } from "./ruleImplementationFilters";
|
|
20
|
+
import { ruleImplementationFiltersLoading } from "./ruleImplementationFiltersLoading";
|
|
20
21
|
import { ruleImplementationLoading } from "./ruleImplementationLoading";
|
|
21
22
|
import { ruleImplementationQuery } from "./ruleImplementationQuery";
|
|
22
23
|
import { ruleImplementationRaw } from "./ruleImplementationRaw";
|
|
@@ -64,6 +65,7 @@ export {
|
|
|
64
65
|
ruleImplementationCount,
|
|
65
66
|
ruleImplementationCreating,
|
|
66
67
|
ruleImplementationFilters,
|
|
68
|
+
ruleImplementationFiltersLoading,
|
|
67
69
|
ruleImplementationLoading,
|
|
68
70
|
ruleImplementationQuery,
|
|
69
71
|
ruleImplementationRaw,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
|
+
import { applyUserSearchFilter } from "@truedat/dd/routines";
|
|
2
3
|
import {
|
|
3
4
|
addRuleFilter,
|
|
4
5
|
closeRuleFilter,
|
|
@@ -15,6 +16,10 @@ export const ruleActiveFilters = (state = initialState, { type, payload }) => {
|
|
|
15
16
|
const { filter } = payload;
|
|
16
17
|
return { ...state, [filter]: [] };
|
|
17
18
|
}
|
|
19
|
+
case applyUserSearchFilter.TRIGGER: {
|
|
20
|
+
const { userFilter, scope } = payload;
|
|
21
|
+
return scope === "rule" ? _.prop("filters")(userFilter) : state;
|
|
22
|
+
}
|
|
18
23
|
case closeRuleFilter.TRIGGER: {
|
|
19
24
|
const { filter } = payload;
|
|
20
25
|
const values = _.propOr([], filter)(state);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
|
+
import { applyUserSearchFilter } from "@truedat/dd/routines";
|
|
2
3
|
import {
|
|
3
4
|
addImplementationFilter,
|
|
4
5
|
closeImplementationFilter,
|
|
@@ -18,6 +19,12 @@ export const ruleImplementationActiveFilters = (
|
|
|
18
19
|
const { filter } = payload;
|
|
19
20
|
return { ...state, [filter]: [] };
|
|
20
21
|
}
|
|
22
|
+
case applyUserSearchFilter.TRIGGER: {
|
|
23
|
+
const { userFilter, scope } = payload;
|
|
24
|
+
return scope === "rule_implementation"
|
|
25
|
+
? _.prop("filters")(userFilter)
|
|
26
|
+
: state;
|
|
27
|
+
}
|
|
21
28
|
case closeImplementationFilter.TRIGGER: {
|
|
22
29
|
const { filter } = payload;
|
|
23
30
|
const values = _.propOr([], filter)(state);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { fetchImplementationFilters } from "../routines";
|
|
2
|
+
|
|
3
|
+
const ruleImplementationFiltersLoading = (state = false, { type }) => {
|
|
4
|
+
switch (type) {
|
|
5
|
+
case fetchImplementationFilters.REQUEST:
|
|
6
|
+
return true;
|
|
7
|
+
case fetchImplementationFilters.FULFILL:
|
|
8
|
+
return false;
|
|
9
|
+
default:
|
|
10
|
+
return state;
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export { ruleImplementationFiltersLoading };
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { getParsedEvents } from "..";
|
|
2
|
+
|
|
3
|
+
describe("selectors: getParsedEvents", () => {
|
|
4
|
+
const events = [
|
|
5
|
+
{
|
|
6
|
+
id: 52351,
|
|
7
|
+
service: "td_dd",
|
|
8
|
+
resource_id: 777,
|
|
9
|
+
resource_type: "rule",
|
|
10
|
+
event: "rule_created",
|
|
11
|
+
payload: {
|
|
12
|
+
active: true,
|
|
13
|
+
content: {
|
|
14
|
+
added: {
|
|
15
|
+
data_owner: null,
|
|
16
|
+
proyecto: ["P1"],
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
description: {},
|
|
20
|
+
df_name: "dq_default_template",
|
|
21
|
+
domain_id: 2,
|
|
22
|
+
goal: 20,
|
|
23
|
+
minimum: 80,
|
|
24
|
+
name: "des01",
|
|
25
|
+
result_type: "deviation",
|
|
26
|
+
updated_by: 398,
|
|
27
|
+
},
|
|
28
|
+
user_id: 398,
|
|
29
|
+
user_name: null,
|
|
30
|
+
user: {
|
|
31
|
+
email: "some.user@domain.tld",
|
|
32
|
+
full_name: "Some User",
|
|
33
|
+
id: 398,
|
|
34
|
+
user_name: "some.user@domain.tld",
|
|
35
|
+
},
|
|
36
|
+
ts: "2021-08-12T12:11:26.908147Z",
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
{
|
|
40
|
+
id: 100217,
|
|
41
|
+
service: "td_dd",
|
|
42
|
+
resource_id: 777,
|
|
43
|
+
resource_type: "rule",
|
|
44
|
+
event: "rule_updated",
|
|
45
|
+
payload: {
|
|
46
|
+
domain_id: 140,
|
|
47
|
+
},
|
|
48
|
+
user_id: 142,
|
|
49
|
+
user_name: null,
|
|
50
|
+
user: {
|
|
51
|
+
email: "some.user@domain.tld",
|
|
52
|
+
full_name: "Some User",
|
|
53
|
+
id: 142,
|
|
54
|
+
user_name: "some.user@domain.tld",
|
|
55
|
+
},
|
|
56
|
+
ts: "2021-09-16T07:36:32.848603Z",
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: 100435,
|
|
60
|
+
service: "td_dd",
|
|
61
|
+
resource_id: 777,
|
|
62
|
+
resource_type: "rule",
|
|
63
|
+
event: "rule_updated",
|
|
64
|
+
payload: {
|
|
65
|
+
description: {
|
|
66
|
+
document: {
|
|
67
|
+
data: {},
|
|
68
|
+
nodes: [
|
|
69
|
+
{
|
|
70
|
+
data: {},
|
|
71
|
+
nodes: [
|
|
72
|
+
{
|
|
73
|
+
marks: [],
|
|
74
|
+
object: "text",
|
|
75
|
+
text: "Añadimos descripción a la regla",
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
object: "block",
|
|
79
|
+
type: "paragraph",
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
object: "document",
|
|
83
|
+
},
|
|
84
|
+
object: "value",
|
|
85
|
+
},
|
|
86
|
+
updated_by: 171,
|
|
87
|
+
},
|
|
88
|
+
user_id: 171,
|
|
89
|
+
user_name: null,
|
|
90
|
+
user: {
|
|
91
|
+
email: "some.user@domain.tld",
|
|
92
|
+
full_name: "Some User",
|
|
93
|
+
id: 171,
|
|
94
|
+
user_name: "some.user",
|
|
95
|
+
},
|
|
96
|
+
ts: "2021-09-16T09:30:52.317357Z",
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
id: 177692,
|
|
100
|
+
service: "td_dd",
|
|
101
|
+
resource_id: 777,
|
|
102
|
+
resource_type: "rule",
|
|
103
|
+
event: "rule_updated",
|
|
104
|
+
payload: {
|
|
105
|
+
content: {
|
|
106
|
+
changed: {
|
|
107
|
+
data_stew: null,
|
|
108
|
+
principle: "Validez",
|
|
109
|
+
scheduler: "",
|
|
110
|
+
tags: "et",
|
|
111
|
+
},
|
|
112
|
+
removed: {
|
|
113
|
+
data_owner: null,
|
|
114
|
+
proyecto: ["P1"],
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
df_name: "quality_template",
|
|
118
|
+
updated_by: 426,
|
|
119
|
+
},
|
|
120
|
+
user_id: 426,
|
|
121
|
+
user_name: null,
|
|
122
|
+
user: {
|
|
123
|
+
email: "some.user@domain.tld",
|
|
124
|
+
full_name: "Some User",
|
|
125
|
+
id: 426,
|
|
126
|
+
user_name: "some.user",
|
|
127
|
+
},
|
|
128
|
+
ts: "2021-10-20T07:56:45.891087Z",
|
|
129
|
+
},
|
|
130
|
+
];
|
|
131
|
+
|
|
132
|
+
const parsed = [
|
|
133
|
+
{
|
|
134
|
+
...events[0],
|
|
135
|
+
payload: [{ field: "des01", action: "created" }],
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
...events[1],
|
|
139
|
+
payload: [{ field: "domain_id", action: "changed", value: 140 }],
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
...events[2],
|
|
143
|
+
payload: [
|
|
144
|
+
{
|
|
145
|
+
field: "description",
|
|
146
|
+
action: "changed",
|
|
147
|
+
value: "Añadimos descripción a la regla",
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
...events[3],
|
|
153
|
+
payload: [
|
|
154
|
+
{ field: "df_name", action: "changed", value: "quality_template" },
|
|
155
|
+
{ action: "changed", field: "data_stew", value: null },
|
|
156
|
+
{ action: "changed", field: "principle", value: "Validez" },
|
|
157
|
+
{ action: "changed", field: "scheduler", value: "" },
|
|
158
|
+
{ action: "changed", field: "tags", value: "et" },
|
|
159
|
+
],
|
|
160
|
+
},
|
|
161
|
+
];
|
|
162
|
+
|
|
163
|
+
it("should return all the events with the new payload", () => {
|
|
164
|
+
const res = getParsedEvents({ events });
|
|
165
|
+
expect(res).toEqual(parsed);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it("should return empty array when we have no elements", () => {
|
|
169
|
+
const res = getParsedEvents({ events: [] });
|
|
170
|
+
expect(res).toHaveLength(0);
|
|
171
|
+
expect(res).toEqual(expect.arrayContaining([]));
|
|
172
|
+
});
|
|
173
|
+
});
|
|
@@ -8,6 +8,24 @@ const getEvents = ({ events }) => {
|
|
|
8
8
|
const transformFieldFormat = (field) =>
|
|
9
9
|
_.isBoolean(field) ? _.toString(field) : field;
|
|
10
10
|
|
|
11
|
+
const findDeep = (obj, key) =>
|
|
12
|
+
_.has(key, obj)
|
|
13
|
+
? obj[key]
|
|
14
|
+
: _.flatten(
|
|
15
|
+
_.map((v) => (typeof v == "object" ? findDeep(v, key) : []), obj)
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
const transformRulePayloadFormat = (payload, field) => {
|
|
19
|
+
switch (field) {
|
|
20
|
+
case "content":
|
|
21
|
+
return payload.content;
|
|
22
|
+
case "description":
|
|
23
|
+
return _.first(findDeep(payload.description, "text"));
|
|
24
|
+
default:
|
|
25
|
+
return payload[field];
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
11
29
|
const getParsedEvents = createSelector([getEvents], (events) => {
|
|
12
30
|
return _.map((d) => {
|
|
13
31
|
switch (d.event) {
|
|
@@ -68,6 +86,43 @@ const getParsedEvents = createSelector([getEvents], (events) => {
|
|
|
68
86
|
}))
|
|
69
87
|
)(d),
|
|
70
88
|
};
|
|
89
|
+
case "rule_created":
|
|
90
|
+
return {
|
|
91
|
+
...d,
|
|
92
|
+
payload: [
|
|
93
|
+
{
|
|
94
|
+
field: _.path("payload.name")(d),
|
|
95
|
+
action: "created",
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
case "rule_updated":
|
|
101
|
+
const content = _.flow(
|
|
102
|
+
_.getOr({}, "payload.content.changed"),
|
|
103
|
+
_.toPairs,
|
|
104
|
+
_.map(([field, value]) => ({
|
|
105
|
+
field,
|
|
106
|
+
value,
|
|
107
|
+
action: "changed",
|
|
108
|
+
}))
|
|
109
|
+
)(d);
|
|
110
|
+
return {
|
|
111
|
+
...d,
|
|
112
|
+
payload: [
|
|
113
|
+
..._.flow(
|
|
114
|
+
_.path("payload"),
|
|
115
|
+
_.omit(["updated_by", "content"]),
|
|
116
|
+
_.keys,
|
|
117
|
+
_.map((field) => ({
|
|
118
|
+
field: field,
|
|
119
|
+
action: "changed",
|
|
120
|
+
value: transformRulePayloadFormat(d.payload, field),
|
|
121
|
+
}))
|
|
122
|
+
)(d),
|
|
123
|
+
...content,
|
|
124
|
+
],
|
|
125
|
+
};
|
|
71
126
|
|
|
72
127
|
default:
|
|
73
128
|
return {
|