@truedat/dq 6.16.1 → 6.16.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@truedat/dq",
3
- "version": "6.16.1",
3
+ "version": "6.16.3",
4
4
  "description": "Truedat Web Data Quality Module",
5
5
  "sideEffects": false,
6
6
  "jsnext:main": "src/index.js",
@@ -93,7 +93,7 @@
93
93
  "dependencies": {
94
94
  "@apollo/client": "^3.7.1",
95
95
  "@truedat/core": "6.15.2",
96
- "@truedat/df": "6.16.1",
96
+ "@truedat/df": "6.15.2",
97
97
  "decode-uri-component": "^0.2.2",
98
98
  "graphql": "^15.5.3",
99
99
  "moment": "^2.29.4",
@@ -118,5 +118,5 @@
118
118
  "react-dom": ">= 16.8.6 < 17",
119
119
  "semantic-ui-react": ">= 2.0.3 < 2.2"
120
120
  },
121
- "gitHead": "717d91b523c2e29e373791fef9c12b3a561449b7"
121
+ "gitHead": "9ac7bd2ddab3f16be28269b3203e568c269cbd0e"
122
122
  }
@@ -3,28 +3,57 @@ import React from "react";
3
3
  import PropTypes from "prop-types";
4
4
  import { FormattedMessage, useIntl } from "react-intl";
5
5
  import { Link } from "react-router-dom";
6
- import { Table, Button, Message, Segment } from "semantic-ui-react";
6
+ import { Table, Button, Message, Segment, TableCell } from "semantic-ui-react";
7
7
  import { connect } from "react-redux";
8
8
  import { linkTo } from "@truedat/core/routes";
9
9
 
10
- const ConceptRuleRow = ({ active, name, id }) => (
11
- <Table.Row>
12
- <Table.Cell>
13
- <Link to={linkTo.RULE({ id })}>{name}</Link>
14
- </Table.Cell>
15
- <Table.Cell>
16
- <FormattedMessage id={`rule.props.active.${active}`} />
17
- </Table.Cell>
18
- </Table.Row>
19
- );
10
+ const ConceptRuleRow = ({
11
+ rule: { active, name, id, business_concept_id, business_concept_name },
12
+ showExpandableColumn,
13
+ }) => {
14
+ return (
15
+ <Table.Row>
16
+ <Table.Cell>
17
+ <Link to={linkTo.RULE({ id })}>{name}</Link>
18
+ </Table.Cell>
19
+ <Table.Cell>
20
+ <FormattedMessage id={`rule.props.active.${active}`} />
21
+ </Table.Cell>
22
+ {showExpandableColumn ? (
23
+ <TableCell>
24
+ {business_concept_id ? (
25
+ <Link
26
+ to={linkTo.CONCEPT_VERSION({
27
+ business_concept_id: business_concept_id,
28
+ id: "current",
29
+ })}
30
+ >
31
+ {business_concept_name}
32
+ </Link>
33
+ ) : null}
34
+ </TableCell>
35
+ ) : null}
36
+ </Table.Row>
37
+ );
38
+ };
20
39
 
21
40
  ConceptRuleRow.propTypes = {
22
- name: PropTypes.string,
23
- active: PropTypes.bool,
24
- id: PropTypes.number,
41
+ rule: PropTypes.shape({
42
+ name: PropTypes.string,
43
+ active: PropTypes.bool,
44
+ id: PropTypes.number,
45
+ business_concept_id: PropTypes.number,
46
+ business_concept_name: PropTypes.string,
47
+ }),
48
+ showExpandableColumn: PropTypes.bool,
25
49
  };
26
50
 
27
- export const ConceptRules = ({ conceptRules, visible, createRuleUrl }) => {
51
+ export const ConceptRules = ({
52
+ conceptRules,
53
+ visible,
54
+ createRuleUrl,
55
+ showExpandableColumn,
56
+ }) => {
28
57
  const { formatMessage } = useIntl();
29
58
 
30
59
  return (
@@ -56,12 +85,23 @@ export const ConceptRules = ({ conceptRules, visible, createRuleUrl }) => {
56
85
  <Table.HeaderCell
57
86
  content={formatMessage({ id: "concepts.rules.status" })}
58
87
  />
88
+ {showExpandableColumn ? (
89
+ <Table.HeaderCell
90
+ content={formatMessage({
91
+ id: "concepts.rules.expandable",
92
+ })}
93
+ />
94
+ ) : null}
59
95
  </Table.Row>
60
96
  </Table.Header>
61
97
  <Table.Body>
62
- {_.map((rule) => <ConceptRuleRow key={rule.id} {...rule} />)(
63
- conceptRules
64
- )}
98
+ {_.map((rule) => (
99
+ <ConceptRuleRow
100
+ key={rule.id}
101
+ rule={rule}
102
+ showExpandableColumn={showExpandableColumn}
103
+ />
104
+ ))(conceptRules)}
65
105
  </Table.Body>
66
106
  </Table>
67
107
  )}
@@ -73,11 +113,13 @@ ConceptRules.propTypes = {
73
113
  conceptRules: PropTypes.array,
74
114
  createRuleUrl: PropTypes.string,
75
115
  visible: PropTypes.bool,
116
+ showExpandableColumn: PropTypes.bool,
76
117
  };
77
118
 
78
119
  const mapStateToProps = ({ conceptRules, concept, conceptRulesActions }) => ({
79
120
  concept,
80
121
  conceptRules: _.reject("deleted_at")(conceptRules),
122
+ showExpandableColumn: _.some("business_concept_name")(conceptRules),
81
123
  createRuleUrl: conceptRulesActions?.create
82
124
  ? linkTo.CONCEPT_RULES_NEW(concept)
83
125
  : null,
@@ -91,7 +91,7 @@ export const RuleForm = ({
91
91
  domain_id: null,
92
92
  business_concept_id: null,
93
93
  name: "",
94
- description: {},
94
+ description: ruleData ? ruleData.description : {},
95
95
  df_content: {},
96
96
  template: null,
97
97
  });
@@ -6,7 +6,10 @@ import { getSortInfo, sortColumn } from "@truedat/core/services/sort";
6
6
  import { Checkbox, Table, Header, Icon } from "semantic-ui-react";
7
7
  import { useIntl } from "react-intl";
8
8
  import { sortImplementations } from "../routines";
9
- import { getRuleImplementationColumns } from "../selectors";
9
+ import {
10
+ getRuleImplementationColumns,
11
+ getRuleImplementationExpandableColumns,
12
+ } from "../selectors";
10
13
  import RuleImplementationRow from "./RuleImplementationRow";
11
14
 
12
15
  export const RuleImplementationsTable = ({
@@ -23,9 +26,9 @@ export const RuleImplementationsTable = ({
23
26
  withoutColumns,
24
27
  }) => {
25
28
  const { formatMessage } = useIntl();
26
- const effectiveColumns = _.filter(({ name }) =>
27
- _.negate(_.includes(name))(withoutColumns)
28
- )(columns);
29
+ const effectiveColumns = _.filter(({ name }) => {
30
+ return _.negate(_.includes(name))(withoutColumns);
31
+ })(columns);
29
32
  const [sortedColumn, setColumn] = useState(
30
33
  _.prop("column")(getSortInfo(implementationsSort))
31
34
  );
@@ -127,7 +130,7 @@ RuleImplementationsTable.propTypes = {
127
130
  };
128
131
 
129
132
  const mapStateToProps = (state, props) => ({
130
- columns: getRuleImplementationColumns(state),
133
+ columns: _.propOr(getRuleImplementationColumns(state), "columns")(props),
131
134
  ruleImplementations: props.ruleImplementations || state.ruleImplementations,
132
135
  ruleImplementationsLoading: state.ruleImplementationsLoading,
133
136
  implementationsSort: _.path("ruleImplementationQuery.sort")(state),
@@ -158,23 +158,23 @@ exports[`<EditRule /> matches the latest snapshot 1`] = `
158
158
  autocorrect="on"
159
159
  contenteditable="true"
160
160
  data-gramm="false"
161
- data-key="7"
161
+ data-key="0"
162
162
  data-slate-editor="true"
163
163
  role="textbox"
164
164
  spellcheck="true"
165
165
  style="outline: none; white-space: pre-wrap; word-wrap: break-word;"
166
166
  >
167
167
  <div
168
- data-key="8"
168
+ data-key="1"
169
169
  data-slate-object="block"
170
170
  style="position: relative;"
171
171
  >
172
172
  <span
173
- data-key="9"
173
+ data-key="2"
174
174
  data-slate-object="text"
175
175
  >
176
176
  <span
177
- data-offset-key="9:0"
177
+ data-offset-key="2:0"
178
178
  data-slate-leaf="true"
179
179
  >
180
180
  <span
@@ -0,0 +1,23 @@
1
+ import {
2
+ getBusinessConceptsLinksToImplementationsColumns,
3
+ defaultBusinessConceptsLinksToImplementationsColumns,
4
+ } from "..";
5
+
6
+ describe("selectors: getBusinessConceptsLinksToImplementationsColumns", () => {
7
+ it("should return custom businessConceptsLinksToImplementationsColumns when present", () => {
8
+ const businessConceptsLinksToImplementationsColumns = [{ name: "test" }];
9
+ const res = getBusinessConceptsLinksToImplementationsColumns({
10
+ businessConceptsLinksToImplementationsColumns,
11
+ });
12
+ expect(res).toHaveLength(1);
13
+ expect(res).toEqual(businessConceptsLinksToImplementationsColumns);
14
+ });
15
+
16
+ it("should return default getBusinessConceptsLinksToImplementationsColumns when no customized", () => {
17
+ const res = getBusinessConceptsLinksToImplementationsColumns({});
18
+
19
+ expect(res).toHaveLength(
20
+ defaultBusinessConceptsLinksToImplementationsColumns.length
21
+ );
22
+ });
23
+ });
@@ -0,0 +1,116 @@
1
+ import _ from "lodash/fp";
2
+ import React from "react";
3
+ import { createSelector } from "reselect";
4
+ import { FormattedMessage } from "react-intl";
5
+ import DateTime from "@truedat/core/components/DateTime";
6
+ import { formatNumber } from "@truedat/core/services/format";
7
+ import ArrayDecorator from "@truedat/core/components/ArrayDecorator";
8
+ import { linkTo } from "@truedat/core/routes";
9
+ import { Link } from "react-router-dom";
10
+ import RuleResultDecorator from "../components/RuleResultDecorator";
11
+ import RuleImplementationLink from "../components/RuleImplementationLink";
12
+ import RuleLink from "../components/RuleLink";
13
+
14
+ const translateDecorator = (id) =>
15
+ id ? <FormattedMessage id={id} defaultMessage={id} /> : null;
16
+
17
+ const resultTypeDecorator = (result, result_type, resultType) =>
18
+ _.defaultTo(result_type)(resultType) === "errors_number"
19
+ ? formatNumber(result)
20
+ : `${result}%`;
21
+
22
+ export const defaultBusinessConceptsLinksToImplementationsColumns = [
23
+ {
24
+ name: "implementation_key",
25
+ fieldSelector: _.pick(["id", "implementation_key", "rule_id"]),
26
+ fieldDecorator: RuleImplementationLink,
27
+ width: 2,
28
+ },
29
+ {
30
+ name: "rule",
31
+ fieldSelector: ({ rule, rule_id: id }) => ({ id, name: rule?.name }),
32
+ fieldDecorator: RuleLink,
33
+ width: 2,
34
+ },
35
+ {
36
+ name: "status",
37
+ fieldSelector: ({ status }) =>
38
+ translateDecorator(`ruleImplementation.status.${status}`),
39
+ width: 2,
40
+ },
41
+ {
42
+ name: "last_execution_at",
43
+ fieldSelector: ({ execution_result_info }) => ({
44
+ value: execution_result_info?.date,
45
+ }),
46
+ fieldDecorator: DateTime,
47
+ width: 2,
48
+ },
49
+ {
50
+ name: "result_type",
51
+ fieldDecorator: (value) =>
52
+ _.isNil(value)
53
+ ? null
54
+ : translateDecorator(`ruleImplementations.props.result_type.${value}`),
55
+ width: 2,
56
+ },
57
+ {
58
+ name: "minimum",
59
+ fieldSelector: _.pick(["minimum", "result_type"]),
60
+ fieldDecorator: (field) =>
61
+ resultTypeDecorator(field.minimum, field.result_type),
62
+ textAlign: "right",
63
+ width: 1,
64
+ },
65
+ {
66
+ name: "goal",
67
+ fieldSelector: _.pick(["goal", "result_type"]),
68
+ fieldDecorator: (field) =>
69
+ resultTypeDecorator(field.goal, field.result_type),
70
+ textAlign: "right",
71
+ width: 1,
72
+ },
73
+ {
74
+ name: "result",
75
+ fieldSelector: (ruleImplementation) => ({
76
+ ruleResult: ruleImplementation?.execution_result_info,
77
+ ruleImplementation,
78
+ }),
79
+ fieldDecorator: RuleResultDecorator,
80
+ textAlign: "center",
81
+ width: 2,
82
+ },
83
+ {
84
+ name: "inserted_at",
85
+ fieldSelector: ({ inserted_at }) => ({ value: inserted_at }),
86
+ fieldDecorator: DateTime,
87
+ },
88
+ {
89
+ name: "updated_at",
90
+ fieldSelector: ({ updated_at }) => ({ value: updated_at }),
91
+ fieldDecorator: DateTime,
92
+ },
93
+ {
94
+ name: "related_by",
95
+ fieldSelector: _.pick(["business_concept_id", "business_concept_name"]),
96
+ fieldDecorator: ({ business_concept_id, business_concept_name }) => {
97
+ return _.isEmpty(business_concept_id) ? (
98
+ <></>
99
+ ) : (
100
+ <Link
101
+ to={linkTo.CONCEPT_VERSION({
102
+ business_concept_id: business_concept_id,
103
+ id: "current",
104
+ })}
105
+ >
106
+ {business_concept_name}
107
+ </Link>
108
+ );
109
+ },
110
+ },
111
+ ];
112
+
113
+ export const getBusinessConceptsLinksToImplementationsColumns = createSelector(
114
+ _.prop("businessConceptsLinksToImplementationsColumns"),
115
+ _.defaultTo(defaultBusinessConceptsLinksToImplementationsColumns)
116
+ );
@@ -27,6 +27,10 @@ export {
27
27
  getRuleImplementationColumns,
28
28
  defaultImplementationColumns,
29
29
  } from "./getRuleImplementationColumns";
30
+ export {
31
+ getBusinessConceptsLinksToImplementationsColumns,
32
+ defaultBusinessConceptsLinksToImplementationsColumns,
33
+ } from "./getBusinessConceptsLinksToImplementationsColumns";
30
34
  export { getPreviousRuleImplementationQuery } from "./getPreviousRuleImplementationQuery";
31
35
  export { getRuleImplementationAvailableFilters } from "./getRuleImplementationAvailableFilters";
32
36
  export { getRuleImplementationFilterTypes } from "./getRuleImplementationFilterTypes";