@truedat/dq 4.38.7 → 4.40.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## [4.39.0] 2022-03-01
4
+
5
+ ### Changed
6
+
7
+ - [TD-4528] Restyle quality results table
8
+
3
9
  ## [4.38.7] 2022-02-22
4
10
 
5
11
  ### Added
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@truedat/dq",
3
- "version": "4.38.7",
3
+ "version": "4.40.0",
4
4
  "description": "Truedat Web Data Quality Module",
5
5
  "sideEffects": false,
6
6
  "jsnext:main": "src/index.js",
@@ -31,7 +31,7 @@
31
31
  "@babel/plugin-transform-modules-commonjs": "^7.15.0",
32
32
  "@babel/preset-env": "^7.15.0",
33
33
  "@babel/preset-react": "^7.14.5",
34
- "@truedat/test": "4.38.7",
34
+ "@truedat/test": "4.39.0",
35
35
  "babel-jest": "^27.0.6",
36
36
  "babel-plugin-dynamic-import-node": "^2.3.3",
37
37
  "babel-plugin-lodash": "^3.3.4",
@@ -82,8 +82,8 @@
82
82
  },
83
83
  "dependencies": {
84
84
  "@apollo/client": "^3.4.10",
85
- "@truedat/core": "4.38.7",
86
- "@truedat/df": "4.38.7",
85
+ "@truedat/core": "4.40.0",
86
+ "@truedat/df": "4.40.0",
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": "840c799ecdd6b8440112ac803119482e688142ed"
106
+ "gitHead": "0bd677584da73a5021a5c96f2e5525fde9a1958a"
107
107
  }
@@ -91,14 +91,7 @@ export const ExecutionDetails = ({ ruleImplementation, ruleResultId }) => {
91
91
  ruleImplementation.results
92
92
  );
93
93
 
94
- return _.isEmpty(ruleResult.details) ? (
95
- <Message
96
- style={{ marginTop: "14px" }}
97
- header={formatMessage({
98
- id: "rule.ruleImplementation.results.details.empty",
99
- })}
100
- />
101
- ) : (
94
+ return (
102
95
  <Table className="implementation-results medium">
103
96
  <Table.Header>
104
97
  <Table.Row>
@@ -116,20 +109,23 @@ export const ExecutionDetails = ({ ruleImplementation, ruleResultId }) => {
116
109
  ruleResult={ruleResult}
117
110
  />
118
111
  </Table.Body>
119
-
120
- <Table.Header>
121
- <Table.Row>
122
- <Table.HeaderCell
123
- colSpan={2}
124
- content={formatMessage({
125
- id: "ruleResult.props.header.details",
126
- })}
127
- />
128
- </Table.Row>
129
- </Table.Header>
130
- <Table.Body>
131
- <DetailRow details={ruleResult.details} />
132
- </Table.Body>
112
+ {!_.isEmpty(ruleResult.details) ? (
113
+ <>
114
+ <Table.Header>
115
+ <Table.Row>
116
+ <Table.HeaderCell
117
+ colSpan={2}
118
+ content={formatMessage({
119
+ id: "ruleResult.props.header.details",
120
+ })}
121
+ />
122
+ </Table.Row>
123
+ </Table.Header>
124
+ <Table.Body>
125
+ <DetailRow details={ruleResult?.details} />
126
+ </Table.Body>
127
+ </>
128
+ ) : null}
133
129
  </Table>
134
130
  );
135
131
  };
@@ -35,7 +35,7 @@ export const RuleImplementationResults = ({
35
35
 
36
36
  return (
37
37
  <>
38
- {ruleImplementation.event_type === "FAILED" && (
38
+ {ruleImplementation.event_type === "FAILED" ? (
39
39
  <Message negative style={{ marginTop: "14px" }}>
40
40
  <Message.Header>
41
41
  {formatMessage({
@@ -61,7 +61,7 @@ export const RuleImplementationResults = ({
61
61
  {ruleImplementation.event_message}
62
62
  </p>
63
63
  </Message>
64
- )}
64
+ ) : null}
65
65
  {_.isEmpty(ruleResults) ? (
66
66
  <Message
67
67
  style={{ marginTop: "14px" }}
@@ -70,25 +70,25 @@ export const RuleImplementationResults = ({
70
70
  })}
71
71
  />
72
72
  ) : (
73
- <Table className="implementation-results small" selectable>
73
+ <Table className="implementation-results small">
74
74
  <Table.Header>
75
75
  <Table.Row>
76
76
  <Table.HeaderCell
77
- content={formatMessage({ id: "ruleResult.props.quality" })}
77
+ content={formatMessage({ id: "ruleResult.props.date" })}
78
78
  />
79
79
  <Table.HeaderCell
80
- content={formatMessage({ id: "ruleResult.props.date" })}
80
+ content={formatMessage({ id: "ruleResult.props.quality" })}
81
81
  />
82
- {_.includes("records")(optionalColumns) && (
82
+ {_.includes("records")(optionalColumns) ? (
83
83
  <Table.HeaderCell
84
84
  content={formatMessage({ id: "ruleResult.props.records" })}
85
85
  />
86
- )}
87
- {_.includes("errors")(optionalColumns) && (
86
+ ) : null}
87
+ {_.includes("errors")(optionalColumns) ? (
88
88
  <Table.HeaderCell
89
89
  content={formatMessage({ id: "ruleResult.props.errors" })}
90
90
  />
91
- )}
91
+ ) : null}
92
92
  {customColumns.map((column, index) => (
93
93
  <Table.HeaderCell
94
94
  key={index}
@@ -99,7 +99,7 @@ export const RuleImplementationResults = ({
99
99
  />
100
100
  ))}
101
101
  {<Table.HeaderCell />}
102
- {isAdmin && <Table.HeaderCell />}
102
+ {isAdmin ? <Table.HeaderCell /> : null}
103
103
  </Table.Row>
104
104
  </Table.Header>
105
105
  <Table.Body>
@@ -3,13 +3,14 @@ import React from "react";
3
3
  import PropTypes from "prop-types";
4
4
  import { connect } from "react-redux";
5
5
  import { useIntl } from "react-intl";
6
- import { useHistory } from "react-router-dom";
6
+ import { Link } from "react-router-dom";
7
7
  import { Table, Icon } from "semantic-ui-react";
8
8
  import { ConfirmModal, DateTime } from "@truedat/core/components";
9
9
  import { columnDecorator } from "@truedat/core/services";
10
10
  import { linkTo } from "@truedat/core/routes";
11
11
  import { selectColor } from "../functions/selectors";
12
12
  import { deleteRuleResult } from "../routines";
13
+ import "../styles/ruleResultRow.less";
13
14
 
14
15
  export const RuleResultRow = ({
15
16
  deleteRuleResult,
@@ -22,24 +23,25 @@ export const RuleResultRow = ({
22
23
  }) => {
23
24
  const { formatMessage, formatNumber: _formatNumber } = useIntl();
24
25
  const formatNumber = (num) => (_.isNil(num) ? num : _formatNumber(num));
25
- const history = useHistory();
26
26
 
27
27
  return (
28
- <Table.Row
29
- onClick={() =>
30
- !_.isEmpty(ruleResult.details)
31
- ? history.push(
32
- linkTo.RULE_IMPLEMENTATION_RESULT_DETAILS({
33
- id: rule.id,
34
- implementation_id: ruleImplementation.id,
35
- rule,
36
- ruleImplementation,
37
- rule_result_id: ruleResult.id,
38
- })
39
- )
40
- : null
41
- }
42
- >
28
+ <Table.Row>
29
+ <Table.Cell>
30
+ <Link
31
+ to={linkTo.RULE_IMPLEMENTATION_RESULT_DETAILS({
32
+ id: rule.id,
33
+ implementation_id: ruleImplementation.id,
34
+ rule,
35
+ ruleImplementation,
36
+ rule_result_id: ruleResult.id,
37
+ })}
38
+ >
39
+ <DateTime className="rule-result-date" value={ruleResult.date} />
40
+ {!_.isEmpty(ruleResult.details) ? (
41
+ <Icon name="info circle" color="blue" />
42
+ ) : null}
43
+ </Link>
44
+ </Table.Cell>
43
45
  <Table.Cell>
44
46
  <Icon
45
47
  name="circle"
@@ -47,28 +49,18 @@ export const RuleResultRow = ({
47
49
  />
48
50
  {`${parseFloat(ruleResult.result)} %`}
49
51
  </Table.Cell>
50
- <Table.Cell>
51
- <DateTime value={ruleResult.date} />
52
- </Table.Cell>
53
- {_.includes("records")(optionalColumns) && (
52
+ {_.includes("records")(optionalColumns) ? (
54
53
  <Table.Cell>{formatNumber(ruleResult.records)}</Table.Cell>
55
- )}
56
- {_.includes("errors")(optionalColumns) && (
54
+ ) : null}
55
+ {_.includes("errors")(optionalColumns) ? (
57
56
  <Table.Cell>{formatNumber(ruleResult.errors)}</Table.Cell>
58
- )}
59
- {_.includes("details")(optionalColumns) && (
60
- <Table.Cell>
61
- {!_.isEmpty(ruleResult.details) && (
62
- <Icon name="info circle" color="blue" />
63
- )}
64
- </Table.Cell>
65
- )}
57
+ ) : null}
66
58
  {customColumns?.map((column, index) => (
67
59
  <Table.Cell key={index}>
68
60
  {columnDecorator(column)(ruleResult)}
69
61
  </Table.Cell>
70
62
  ))}
71
- {isAdmin && (
63
+ {isAdmin ? (
72
64
  <Table.Cell onClick={(e) => e.stopPropagation()}>
73
65
  <ConfirmModal
74
66
  icon="trash"
@@ -88,7 +80,7 @@ export const RuleResultRow = ({
88
80
  }
89
81
  />
90
82
  </Table.Cell>
91
- )}
83
+ ) : null}
92
84
  </Table.Row>
93
85
  );
94
86
  };
@@ -11,8 +11,12 @@ jest.spyOn(React, "useContext").mockImplementation(() => intl);
11
11
  describe("<RuleResultRow />", () => {
12
12
  it("renders customColumns values when passed", () => {
13
13
  const ruleResultRowProps = {
14
- id: 10,
15
- ruleResult: { result: 80, params: { p1: "1", p2: "2", p3: "no" } },
14
+ rule: { id: 10 },
15
+ ruleResult: {
16
+ id: 54,
17
+ result: 80,
18
+ params: { p1: "1", p2: "2", p3: "no" },
19
+ },
16
20
  customColumns: [
17
21
  {
18
22
  name: "m_parm1",
@@ -24,7 +28,12 @@ describe("<RuleResultRow />", () => {
24
28
  },
25
29
  ],
26
30
  date: "2019-08-12T02:00:00Z",
27
- ruleImplementation: { minimum: 1, goal: 10, result_type: "percentage" },
31
+ ruleImplementation: {
32
+ id: 23,
33
+ minimum: 1,
34
+ goal: 10,
35
+ result_type: "percentage",
36
+ },
28
37
  };
29
38
 
30
39
  const wrapper = shallow(<RuleResultRow {...ruleResultRowProps} />);
@@ -50,10 +59,11 @@ describe("<RuleResultRow />", () => {
50
59
 
51
60
  it("green icon when result is over goal", () => {
52
61
  const ruleResultRowProps = {
53
- id: 10,
54
- ruleResult: { result: 80 },
62
+ rule: { id: 10 },
63
+ ruleResult: { id: 54, result: 80 },
55
64
  date: "2019-08-12T02:00:00Z",
56
65
  ruleImplementation: {
66
+ id: 23,
57
67
  minimum: 1,
58
68
  goal: 10,
59
69
  result_type: "percentage",
@@ -61,7 +71,7 @@ describe("<RuleResultRow />", () => {
61
71
  };
62
72
 
63
73
  const wrapper = shallow(<RuleResultRow {...ruleResultRowProps} />);
64
- const cell = wrapper.find("TableRow").find("TableCell").at(0).dive();
74
+ const cell = wrapper.find("TableRow").find("TableCell").at(1).dive();
65
75
 
66
76
  expect(cell.find("td").find("Icon")).toHaveLength(1);
67
77
 
@@ -72,10 +82,11 @@ describe("<RuleResultRow />", () => {
72
82
 
73
83
  it("red icon when result is under minimum", () => {
74
84
  const ruleResultRowProps = {
75
- id: 10,
76
- ruleResult: { result: 80 },
85
+ rule: { id: 10 },
86
+ ruleResult: { id: 54, result: 80 },
77
87
  date: "2019-08-12T02:00:00Z",
78
88
  ruleImplementation: {
89
+ id: 23,
79
90
  minimum: 81,
80
91
  goal: 90,
81
92
  result_type: "percentage",
@@ -83,7 +94,7 @@ describe("<RuleResultRow />", () => {
83
94
  };
84
95
 
85
96
  const wrapper = shallow(<RuleResultRow {...ruleResultRowProps} />);
86
- const cell = wrapper.find("TableRow").find("TableCell").at(0).dive();
97
+ const cell = wrapper.find("TableRow").find("TableCell").at(1).dive();
87
98
 
88
99
  expect(cell.find("td").find("Icon")).toHaveLength(1);
89
100
 
@@ -94,18 +105,19 @@ describe("<RuleResultRow />", () => {
94
105
 
95
106
  it("yellow icon when result is between minimum and goal", () => {
96
107
  const ruleResultRowProps = {
97
- id: 10,
108
+ rule: { id: 10 },
98
109
  ruleImplementation: {
110
+ id: 23,
99
111
  minimum: 81,
100
112
  goal: 90,
101
113
  result_type: "percentage",
102
114
  },
103
- ruleResult: { result: 82 },
115
+ ruleResult: { id: 54, result: 82 },
104
116
  date: "2019-08-12T02:00:00Z",
105
117
  };
106
118
 
107
119
  const wrapper = shallow(<RuleResultRow {...ruleResultRowProps} />);
108
- const cell = wrapper.find("TableRow").find("TableCell").at(0).dive();
120
+ const cell = wrapper.find("TableRow").find("TableCell").at(1).dive();
109
121
 
110
122
  expect(cell.find("td").find("Icon")).toHaveLength(1);
111
123
 
@@ -116,13 +128,14 @@ describe("<RuleResultRow />", () => {
116
128
 
117
129
  it("renders delete cell in RuleResultRow when user isAdmin is true", () => {
118
130
  const ruleResultRowProps = {
119
- id: 10,
131
+ rule: { id: 10 },
120
132
  ruleImplementation: {
133
+ id: 23,
121
134
  minimum: 81,
122
135
  goal: 90,
123
136
  result_type: "percentage",
124
137
  },
125
- ruleResult: { result: 82 },
138
+ ruleResult: { id: 54, result: 82 },
126
139
  date: "2019-08-12T02:00:00Z",
127
140
  isAdmin: true,
128
141
  deleteRuleResult: jest.fn(),
@@ -138,13 +151,14 @@ describe("<RuleResultRow />", () => {
138
151
 
139
152
  it("does not render delete cell in RuleResultRow when user isAdmin is false", () => {
140
153
  const ruleResultRowProps = {
141
- id: 10,
154
+ rule: { id: 10 },
142
155
  ruleImplementation: {
156
+ id: 23,
143
157
  minimum: 81,
144
158
  goal: 90,
145
159
  result_type: "percentage",
146
160
  },
147
- ruleResult: { result: 82 },
161
+ ruleResult: { id: 54, result: 82 },
148
162
  date: "2019-08-12T02:00:00Z",
149
163
  isAdmin: false,
150
164
  deleteRuleResult: jest.fn(),
@@ -115,19 +115,81 @@ exports[`<ExecutionDetails> matches the lastest snapshot 1`] = `
115
115
 
116
116
  exports[`<ExecutionDetails> without details 1`] = `
117
117
  <div>
118
- <div
119
- class="ui message"
120
- style="margin-top: 14px;"
118
+ <table
119
+ class="ui table implementation-results medium"
121
120
  >
122
- <div
123
- class="content"
121
+ <thead
122
+ class=""
124
123
  >
125
- <div
126
- class="header"
124
+ <tr
125
+ class=""
127
126
  >
128
- No details found for current result
129
- </div>
130
- </div>
131
- </div>
127
+ <th
128
+ class=""
129
+ colspan="2"
130
+ >
131
+ Information
132
+ </th>
133
+ </tr>
134
+ </thead>
135
+ <tbody
136
+ class=""
137
+ >
138
+ <tr
139
+ class=""
140
+ >
141
+ <td
142
+ class=""
143
+ >
144
+ Quality
145
+ </td>
146
+ <td
147
+ class=""
148
+ >
149
+ <i
150
+ aria-hidden="true"
151
+ class="grey circle icon"
152
+ />
153
+ NaN %
154
+ </td>
155
+ </tr>
156
+ <tr
157
+ class=""
158
+ >
159
+ <td
160
+ class=""
161
+ >
162
+ Date
163
+ </td>
164
+ <td
165
+ class=""
166
+ />
167
+ </tr>
168
+ <tr
169
+ class=""
170
+ >
171
+ <td
172
+ class=""
173
+ >
174
+ Records
175
+ </td>
176
+ <td
177
+ class=""
178
+ />
179
+ </tr>
180
+ <tr
181
+ class=""
182
+ >
183
+ <td
184
+ class=""
185
+ >
186
+ Errors
187
+ </td>
188
+ <td
189
+ class=""
190
+ />
191
+ </tr>
192
+ </tbody>
193
+ </table>
132
194
  </div>
133
195
  `;
@@ -5,7 +5,6 @@ exports[`<RuleImplementationResults /> matches the latest snapshot 1`] = `
5
5
  <Table
6
6
  as="table"
7
7
  className="implementation-results small"
8
- selectable={true}
9
8
  >
10
9
  <TableHeader
11
10
  as="thead"
@@ -16,11 +15,11 @@ exports[`<RuleImplementationResults /> matches the latest snapshot 1`] = `
16
15
  >
17
16
  <TableHeaderCell
18
17
  as="th"
19
- content="ruleResult.props.quality"
18
+ content="ruleResult.props.date"
20
19
  />
21
20
  <TableHeaderCell
22
21
  as="th"
23
- content="ruleResult.props.date"
22
+ content="ruleResult.props.quality"
24
23
  />
25
24
  <TableHeaderCell
26
25
  as="th"
@@ -0,0 +1,3 @@
1
+ .rule-result-date {
2
+ margin-right: 5px;
3
+ }