@truedat/qx 7.0.8 → 7.1.1

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.
Files changed (169) hide show
  1. package/package.json +13 -4
  2. package/src/api.js +29 -20
  3. package/src/components/QxRoutes.js +18 -16
  4. package/src/components/__tests__/__fixtures__/helper.js +189 -0
  5. package/src/components/common/TestFormWrapper.js +38 -0
  6. package/src/components/common/__tests__/ResourceSelector.spec.js +18 -7
  7. package/src/components/common/__tests__/__snapshots__/ResourceSelector.spec.js.snap +0 -12
  8. package/src/components/common/expressions/__tests__/Condition.spec.js +4 -1
  9. package/src/components/common/expressions/__tests__/FunctionArgs.spec.js +18 -5
  10. package/src/components/common/expressions/__tests__/ShapeSelector.spec.js +10 -4
  11. package/src/components/common/expressions/__tests__/__snapshots__/FunctionArgs.spec.js.snap +10 -2
  12. package/src/components/common/resourceSelectors/__tests__/DataStructureSelector.spec.js +6 -3
  13. package/src/components/common/resourceSelectors/__tests__/__snapshots__/DataStructureSelector.spec.js.snap +0 -12
  14. package/src/components/dataViews/__tests__/DataViewEditor.spec.js +83 -53
  15. package/src/components/dataViews/__tests__/DataViews.spec.js +14 -1
  16. package/src/components/dataViews/__tests__/__snapshots__/DataViewEditor.spec.js.snap +93 -4
  17. package/src/components/dataViews/queryableProperties/__tests__/SelectField.spec.js +13 -6
  18. package/src/components/functions/__tests__/FunctionEditor.spec.js +2 -34
  19. package/src/components/functions/__tests__/FunctionParams.spec.js +4 -17
  20. package/src/components/functions/__tests__/Functions.spec.js +2 -34
  21. package/src/components/functions/__tests__/__snapshots__/FunctionEditor.spec.js.snap +48 -48
  22. package/src/components/functions/__tests__/__snapshots__/FunctionParams.spec.js.snap +4 -4
  23. package/src/components/functions/__tests__/__snapshots__/Functions.spec.js.snap +4 -4
  24. package/src/components/qualityControls/ControlProperties.js +43 -0
  25. package/src/components/qualityControls/ControlPropertiesView.js +109 -0
  26. package/src/components/qualityControls/EditQualityControl.js +5 -21
  27. package/src/components/qualityControls/IconPopup.js +28 -0
  28. package/src/components/qualityControls/NewDraftQualityControl.js +4 -13
  29. package/src/components/qualityControls/NewQualityControl.js +10 -25
  30. package/src/components/qualityControls/QualityBadge.js +33 -0
  31. package/src/components/qualityControls/QualityControl.js +11 -53
  32. package/src/components/qualityControls/QualityControlActions.js +133 -46
  33. package/src/components/qualityControls/QualityControlEditor.js +113 -134
  34. package/src/components/qualityControls/QualityControlHeader.js +29 -7
  35. package/src/components/qualityControls/QualityControlHistory.js +6 -12
  36. package/src/components/qualityControls/QualityControlQueryModal.js +8 -5
  37. package/src/components/qualityControls/QualityControlRoutes.js +51 -96
  38. package/src/components/qualityControls/QualityControlRow.js +21 -2
  39. package/src/components/qualityControls/QualityControlScores.js +140 -0
  40. package/src/components/qualityControls/QualityControlTabs.js +24 -23
  41. package/src/components/qualityControls/QualityControls.js +142 -59
  42. package/src/components/qualityControls/QualityControlsLabelResults.js +51 -0
  43. package/src/components/qualityControls/QualityControlsTable.js +69 -43
  44. package/src/components/qualityControls/ScoreCriteria.js +40 -0
  45. package/src/components/qualityControls/{ResultCriteria.js → ScoreCriteriaView.js} +26 -42
  46. package/src/components/qualityControls/__tests__/ControlProperties.spec.js +86 -0
  47. package/src/components/qualityControls/__tests__/ControlPropertiesView.spec.js +86 -0
  48. package/src/components/qualityControls/__tests__/EditQualityControl.spec.js +219 -0
  49. package/src/components/qualityControls/__tests__/IconPopup.spec.js +33 -0
  50. package/src/components/qualityControls/__tests__/NewDraftQualityControl.spec.js +253 -0
  51. package/src/components/qualityControls/__tests__/NewQualityControl.spec.js +384 -0
  52. package/src/components/qualityControls/__tests__/QualityBadge.spec.js +30 -0
  53. package/src/components/qualityControls/__tests__/QualityControl.spec.js +47 -0
  54. package/src/components/qualityControls/__tests__/QualityControlActions.spec.js +192 -0
  55. package/src/components/qualityControls/__tests__/QualityControlCrumbs.spec.js +18 -0
  56. package/src/components/qualityControls/__tests__/QualityControlEditor.spec.js +296 -0
  57. package/src/components/qualityControls/__tests__/QualityControlHeader.spec.js +68 -0
  58. package/src/components/qualityControls/__tests__/QualityControlHistory.spec.js +21 -0
  59. package/src/components/qualityControls/__tests__/QualityControlQueryModal.spec.js +77 -0
  60. package/src/components/qualityControls/__tests__/QualityControlRow.spec.js +91 -0
  61. package/src/components/qualityControls/__tests__/QualityControlScores.spec.js +139 -0
  62. package/src/components/qualityControls/__tests__/QualityControlTabs.spec.js +20 -0
  63. package/src/components/qualityControls/__tests__/QualityControls.spec.js +202 -0
  64. package/src/components/qualityControls/__tests__/QualityControlsLabelResults.spec.js +83 -0
  65. package/src/components/qualityControls/__tests__/QualityControlsTable.spec.js +38 -0
  66. package/src/components/qualityControls/__tests__/ScoreCriteria.spec.js +77 -0
  67. package/src/components/qualityControls/__tests__/ScoreCriteriaView.spec.js +62 -0
  68. package/src/components/qualityControls/__tests__/__fixtures__/qualityControlHelper.js +281 -0
  69. package/src/components/qualityControls/__tests__/__snapshots__/ControlProperties.spec.js.snap +151 -0
  70. package/src/components/qualityControls/__tests__/__snapshots__/ControlPropertiesView.spec.js.snap +290 -0
  71. package/src/components/qualityControls/__tests__/__snapshots__/EditQualityControl.spec.js.snap +672 -0
  72. package/src/components/qualityControls/__tests__/__snapshots__/IconPopup.spec.js.snap +10 -0
  73. package/src/components/qualityControls/__tests__/__snapshots__/NewDraftQualityControl.spec.js.snap +648 -0
  74. package/src/components/qualityControls/__tests__/__snapshots__/NewQualityControl.spec.js.snap +336 -0
  75. package/src/components/qualityControls/__tests__/__snapshots__/QualityBadge.spec.js.snap +11 -0
  76. package/src/components/qualityControls/__tests__/__snapshots__/QualityControl.spec.js.snap +255 -0
  77. package/src/components/qualityControls/__tests__/__snapshots__/QualityControlActions.spec.js.snap +85 -0
  78. package/src/components/qualityControls/__tests__/__snapshots__/QualityControlCrumbs.spec.js.snap +25 -0
  79. package/src/components/qualityControls/__tests__/__snapshots__/QualityControlEditor.spec.js.snap +930 -0
  80. package/src/components/qualityControls/__tests__/__snapshots__/QualityControlHeader.spec.js.snap +127 -0
  81. package/src/components/qualityControls/__tests__/__snapshots__/QualityControlHistory.spec.js.snap +75 -0
  82. package/src/components/qualityControls/__tests__/__snapshots__/QualityControlQueryModal.spec.js.snap +27 -0
  83. package/src/components/qualityControls/__tests__/__snapshots__/QualityControlRow.spec.js.snap +113 -0
  84. package/src/components/qualityControls/__tests__/__snapshots__/QualityControlScores.spec.js.snap +161 -0
  85. package/src/components/qualityControls/__tests__/__snapshots__/QualityControlTabs.spec.js.snap +28 -0
  86. package/src/components/qualityControls/__tests__/__snapshots__/QualityControls.spec.js.snap +219 -0
  87. package/src/components/qualityControls/__tests__/__snapshots__/QualityControlsLabelResults.spec.js.snap +11 -0
  88. package/src/components/qualityControls/__tests__/__snapshots__/QualityControlsTable.spec.js.snap +121 -0
  89. package/src/components/qualityControls/__tests__/__snapshots__/ScoreCriteria.spec.js.snap +186 -0
  90. package/src/components/qualityControls/__tests__/__snapshots__/ScoreCriteriaView.spec.js.snap +76 -0
  91. package/src/components/qualityControls/__tests__/qualityByControlMode.spec.js +248 -0
  92. package/src/components/qualityControls/controlProperties/ErrorCount.js +56 -0
  93. package/src/components/qualityControls/controlProperties/Ratio.js +79 -0
  94. package/src/components/qualityControls/controlProperties/__tests__/ErrorCount.spec.js +82 -0
  95. package/src/components/qualityControls/controlProperties/__tests__/Ratio.spec.js +115 -0
  96. package/src/components/qualityControls/controlProperties/__tests__/__snapshots__/ErrorCount.spec.js.snap +62 -0
  97. package/src/components/qualityControls/controlProperties/__tests__/__snapshots__/Ratio.spec.js.snap +143 -0
  98. package/src/components/qualityControls/qualityByControlMode.js +62 -0
  99. package/src/components/qualityControls/qualityControlScoresColumns.js +52 -0
  100. package/src/components/qualityControls/{resultCriterias → scoreCriterias}/Deviation.js +6 -6
  101. package/src/components/qualityControls/{resultCriterias/ErrorsNumber.js → scoreCriterias/ErrorCount.js} +7 -7
  102. package/src/components/qualityControls/{resultCriterias → scoreCriterias}/Percentage.js +6 -6
  103. package/src/components/qualityControls/scoreCriterias/__tests__/Deviation.spec.js +75 -0
  104. package/src/components/qualityControls/scoreCriterias/__tests__/ErrorCount.spec.js +63 -0
  105. package/src/components/qualityControls/scoreCriterias/__tests__/Percentage.spec.js +61 -0
  106. package/src/components/qualityControls/scoreCriterias/__tests__/__snapshots__/Deviation.spec.js.snap +58 -0
  107. package/src/components/qualityControls/scoreCriterias/__tests__/__snapshots__/ErrorCount.spec.js.snap +58 -0
  108. package/src/components/qualityControls/scoreCriterias/__tests__/__snapshots__/Percentage.spec.js.snap +58 -0
  109. package/src/components/{executions/ExecutionGroupsHeader.js → scores/MyScoreGroups.js} +5 -3
  110. package/src/components/scores/QualityBar.js +73 -0
  111. package/src/components/scores/Score.js +32 -0
  112. package/src/components/scores/ScoreContext.js +3 -0
  113. package/src/components/scores/ScoreCrumbs.js +40 -0
  114. package/src/components/scores/ScoreDetails.js +67 -0
  115. package/src/components/scores/ScoreEvents.js +59 -0
  116. package/src/components/scores/ScoreGroup.js +83 -0
  117. package/src/components/scores/ScoreGroupBreadcrumbs.js +25 -0
  118. package/src/components/{qualityControls/ExecutionForm.js → scores/ScoreGroupForm.js} +11 -13
  119. package/src/components/scores/ScoreGroupLink.js +18 -0
  120. package/src/components/scores/ScoreGroupMessage.js +25 -0
  121. package/src/components/{qualityControls/ExecutionPopup.js → scores/ScoreGroupPopup.js} +13 -22
  122. package/src/components/scores/ScoreGroupsTable.js +113 -0
  123. package/src/components/scores/ScoreRoutes.js +32 -0
  124. package/src/components/{executions/ExecutionStatusDecorator.js → scores/ScoreStatusDecorator.js} +10 -8
  125. package/src/components/scores/ScoreTabs.js +32 -0
  126. package/src/components/scores/__tests__/MyScoreGroups.spec.js +31 -0
  127. package/src/components/scores/__tests__/QualityBar.spec.js +55 -0
  128. package/src/components/scores/__tests__/Score.spec.js +41 -0
  129. package/src/components/scores/__tests__/ScoreCrumbs.spec.js +39 -0
  130. package/src/components/scores/__tests__/ScoreDetails.spec.js +38 -0
  131. package/src/components/scores/__tests__/ScoreEvents.spec.js +24 -0
  132. package/src/components/scores/__tests__/ScoreGroup.spec.js +43 -0
  133. package/src/components/scores/__tests__/ScoreGroupBreadcrumbs.spec.js +16 -0
  134. package/src/components/scores/__tests__/ScoreGroupForm.spec.js +78 -0
  135. package/src/components/scores/__tests__/ScoreGroupLink.spec.js +16 -0
  136. package/src/components/scores/__tests__/ScoreGroupMessage.spec.js +20 -0
  137. package/src/components/scores/__tests__/ScoreGroupPopup.spec.js +59 -0
  138. package/src/components/scores/__tests__/ScoreGroupsTable.spec.js +40 -0
  139. package/src/components/scores/__tests__/ScoreStatusDecorator.spec.js +21 -0
  140. package/src/components/scores/__tests__/ScoreTabs.spec.js +27 -0
  141. package/src/components/scores/__tests__/__fixtures__/scoreHelper.js +182 -0
  142. package/src/components/scores/__tests__/__snapshots__/MyScoreGroups.spec.js.snap +154 -0
  143. package/src/components/scores/__tests__/__snapshots__/QualityBar.spec.js.snap +24 -0
  144. package/src/components/scores/__tests__/__snapshots__/Score.spec.js.snap +92 -0
  145. package/src/components/scores/__tests__/__snapshots__/ScoreCrumbs.spec.js.snap +39 -0
  146. package/src/components/scores/__tests__/__snapshots__/ScoreDetails.spec.js.snap +156 -0
  147. package/src/components/scores/__tests__/__snapshots__/ScoreEvents.spec.js.snap +167 -0
  148. package/src/components/scores/__tests__/__snapshots__/ScoreGroup.spec.js.snap +103 -0
  149. package/src/components/scores/__tests__/__snapshots__/ScoreGroupBreadcrumbs.spec.js.snap +29 -0
  150. package/src/components/scores/__tests__/__snapshots__/ScoreGroupForm.spec.js.snap +145 -0
  151. package/src/components/scores/__tests__/__snapshots__/ScoreGroupLink.spec.js.snap +15 -0
  152. package/src/components/scores/__tests__/__snapshots__/ScoreGroupMessage.spec.js.snap +43 -0
  153. package/src/components/scores/__tests__/__snapshots__/ScoreGroupPopup.spec.js.snap +11 -0
  154. package/src/components/scores/__tests__/__snapshots__/ScoreGroupsTable.spec.js.snap +147 -0
  155. package/src/components/scores/__tests__/__snapshots__/ScoreStatusDecorator.spec.js.snap +71 -0
  156. package/src/components/scores/__tests__/__snapshots__/ScoreTabs.spec.js.snap +43 -0
  157. package/src/components/scores/index.js +15 -0
  158. package/src/hooks/useQualityControls.js +3 -9
  159. package/src/hooks/useScoreGroups.js +23 -0
  160. package/src/hooks/useScores.js +22 -0
  161. package/src/styles/Expression.less +16 -0
  162. package/src/styles/scores.less +63 -0
  163. package/src/components/executions/ExecutionGroupBreadcrumbs.js +0 -25
  164. package/src/components/executions/ExecutionGroupContent.js +0 -42
  165. package/src/components/executions/ExecutionGroupLink.js +0 -18
  166. package/src/components/executions/ExecutionGroupMessage.js +0 -27
  167. package/src/components/executions/ExecutionGroupsTable.js +0 -101
  168. package/src/components/executions/executionGroupDetail.js +0 -87
  169. package/src/components/qualityControls/ResultType.js +0 -57
@@ -1,17 +1,15 @@
1
1
  import React, { useState } from "react";
2
2
  import PropTypes from "prop-types";
3
- import { connect } from "react-redux";
4
3
  import { useIntl } from "react-intl";
5
4
  import { Button, Popup } from "semantic-ui-react";
6
- import ExecutionForm from "./ExecutionForm";
5
+ import ScoreGroupForm from "./ScoreGroupForm";
7
6
 
8
- export const ExecutionPopup = ({
9
- disabled,
10
- executionGroupLoading,
11
- count,
7
+ export default function ScoreGroupPopup({
8
+ disabled = false,
9
+ loading,
10
+ count = 1,
12
11
  onSubmit,
13
- executionGroupType = "implementation",
14
- }) => {
12
+ }) {
15
13
  const { formatMessage } = useIntl();
16
14
  const [open, setOpen] = useState(false);
17
15
 
@@ -29,35 +27,28 @@ export const ExecutionPopup = ({
29
27
  <Button
30
28
  secondary
31
29
  disabled={disabled}
32
- loading={executionGroupLoading}
30
+ loading={loading}
33
31
  content={formatMessage({
34
32
  id:
35
33
  count === 1
36
- ? executionGroupType + ".actions.do_execution"
37
- : executionGroupType + "s.actions.do_execution",
34
+ ? "quality_control.actions.do_execution"
35
+ : "quality_controls.actions.do_execution",
38
36
  })}
39
37
  />
40
38
  }
41
39
  >
42
- <ExecutionForm
40
+ <ScoreGroupForm
43
41
  count={count}
44
42
  onSubmit={onSubmit}
45
43
  onCancel={() => setOpen(false)}
46
44
  />
47
45
  </Popup>
48
46
  );
49
- };
47
+ }
50
48
 
51
- ExecutionPopup.propTypes = {
49
+ ScoreGroupPopup.propTypes = {
52
50
  count: PropTypes.number,
53
51
  disabled: PropTypes.bool,
54
- executionGroupLoading: PropTypes.bool,
52
+ loading: PropTypes.bool,
55
53
  onSubmit: PropTypes.func,
56
- executionGroupType: PropTypes.string,
57
54
  };
58
-
59
- const mapStateToProps = ({ executionGroupLoading }) => ({
60
- executionGroupLoading,
61
- });
62
-
63
- export default connect(mapStateToProps)(ExecutionPopup);
@@ -0,0 +1,113 @@
1
+ import _ from "lodash/fp";
2
+ import React from "react";
3
+ import PropTypes from "prop-types";
4
+ import { FormattedMessage } from "react-intl";
5
+ import { Table, Header, Icon, Label } from "semantic-ui-react";
6
+ import { columnDecorator } from "@truedat/core/services";
7
+ import { useMyScoreGroupsIndex } from "../../hooks/useScoreGroups";
8
+
9
+ import ScoreGroupLink from "./ScoreGroupLink";
10
+
11
+ export const HeaderRow = ({ columns }) => (
12
+ <Table.Row>
13
+ {columns.map(({ name: id, textAlign }, i) => (
14
+ <Table.HeaderCell key={i} textAlign={textAlign}>
15
+ <FormattedMessage id={id} defaultMessage={id} />
16
+ </Table.HeaderCell>
17
+ ))}
18
+ </Table.Row>
19
+ );
20
+
21
+ HeaderRow.propTypes = {
22
+ columns: PropTypes.arrayOf(PropTypes.object),
23
+ };
24
+
25
+ export const ScoreGroupRow = ({ columns, ...props }) => (
26
+ <Table.Row>
27
+ {columns.map((col, i) => (
28
+ <Table.Cell
29
+ key={i}
30
+ textAlign={col.textAlign}
31
+ content={columnDecorator(col)(props)}
32
+ />
33
+ ))}
34
+ </Table.Row>
35
+ );
36
+
37
+ ScoreGroupRow.propTypes = {
38
+ columns: PropTypes.arrayOf(PropTypes.object),
39
+ };
40
+
41
+ export default function ScoreGroupsTable() {
42
+ const { data } = useMyScoreGroupsIndex();
43
+ const scoreGroups = data?.data;
44
+
45
+ const presentStatuses = _.flow(
46
+ _.flatMap(_.flow(_.prop("status_summary"), _.keys)),
47
+ _.uniq
48
+ )(scoreGroups);
49
+
50
+ const statusColumns = _.flow(
51
+ _.filter((status) => _.includes(status)(presentStatuses)),
52
+ _.map((status) => ({
53
+ name: `score.status.${status}`,
54
+ fieldSelector: `status_summary.${status}`,
55
+ fieldDecorator: (count) =>
56
+ count ? (
57
+ <Label
58
+ circular
59
+ color={
60
+ {
61
+ PENDING: "yellow",
62
+ QUEUED: "yellow",
63
+ STARTED: "yellow",
64
+ SUCCEEDED: "green",
65
+ FAILED: "red",
66
+ TIMEOUT: "red",
67
+ }[status]
68
+ }
69
+ >
70
+ {count}
71
+ </Label>
72
+ ) : null,
73
+ textAlign: "center",
74
+ width: 2,
75
+ }))
76
+ )(["PENDING", "QUEUED", "STARTED", "SUCCEEDED", "FAILED", "TIMEOUT"]);
77
+
78
+ const columns = [
79
+ {
80
+ name: "score_groups.table.header.created",
81
+ width: 4,
82
+ fieldSelector: _.identity,
83
+ fieldDecorator: ScoreGroupLink,
84
+ },
85
+ ...statusColumns,
86
+ ];
87
+
88
+ return (
89
+ <>
90
+ {!_.isEmpty(scoreGroups) && (
91
+ <Table collapsing striped celled>
92
+ <Table.Header>
93
+ <HeaderRow columns={columns} />
94
+ </Table.Header>
95
+ <Table.Body>
96
+ {scoreGroups &&
97
+ scoreGroups.map((props, key) => (
98
+ <ScoreGroupRow key={key} columns={columns} {...props} />
99
+ ))}
100
+ </Table.Body>
101
+ </Table>
102
+ )}
103
+ {_.isEmpty(scoreGroups) && (
104
+ <Header as="h4">
105
+ <Icon name="search" />
106
+ <Header.Content>
107
+ <FormattedMessage id="score_groups.search.results.empty" />
108
+ </Header.Content>
109
+ </Header>
110
+ )}
111
+ </>
112
+ );
113
+ }
@@ -0,0 +1,32 @@
1
+ import React from "react";
2
+ import { Route, Switch } from "react-router-dom";
3
+ import {
4
+ MY_SCORE_GROUPS,
5
+ SCORE_GROUPS,
6
+ SCORE_GROUP,
7
+ SCORE,
8
+ SCORE_EVENTS,
9
+ } from "@truedat/core/routes";
10
+
11
+ import { MyScoreGroups, ScoreGroup, Score, ScoreDetails, ScoreEvents } from ".";
12
+ import "../../styles/scores.less";
13
+
14
+ export default function ScoreRoutes() {
15
+ return (
16
+ <Switch>
17
+ <Route exact path={MY_SCORE_GROUPS} render={() => <MyScoreGroups />} />
18
+ <Route exact path={SCORE_GROUP} render={() => <ScoreGroup />} />
19
+ <Route
20
+ path={SCORE}
21
+ render={() => (
22
+ <Score>
23
+ <Switch>
24
+ <Route exact path={SCORE} render={() => <ScoreDetails />} />
25
+ <Route exact path={SCORE_EVENTS} render={() => <ScoreEvents />} />
26
+ </Switch>
27
+ </Score>
28
+ )}
29
+ />
30
+ </Switch>
31
+ );
32
+ }
@@ -2,30 +2,32 @@ import _ from "lodash/fp";
2
2
  import { FormattedMessage } from "react-intl";
3
3
  import React from "react";
4
4
  import PropTypes from "prop-types";
5
+ import { Link } from "react-router-dom";
5
6
  import { Icon } from "semantic-ui-react";
7
+ import { linkTo } from "@truedat/core/routes";
6
8
 
7
9
  const PENDING = { name: "info circle", color: "grey" };
8
10
 
9
11
  export const icons = {
10
12
  PENDING,
13
+ QUEUED: { name: "play circle outline", color: "green" },
11
14
  STARTED: { name: "play circle outline", color: "green" },
12
15
  SUCCEEDED: { name: "check circle outline", color: "green" },
13
16
  FAILED: { name: "warning circle", color: "red" },
14
17
  };
15
18
 
16
- export const ExecutionStatusDecorator = (status) => {
19
+ export default function ScoreStatusDecorator({ id, status }) {
17
20
  const icon = _.propOr(PENDING, _.toUpper(status))(icons);
18
- const messageId = "quality_control_execution_group.status." + status;
21
+ const messageId = "score.status." + status;
19
22
  return (
20
- <>
23
+ <Link to={linkTo.SCORE({ id })}>
21
24
  <Icon size="large" {...icon} />
22
25
  <FormattedMessage id={messageId} />
23
- </>
26
+ </Link>
24
27
  );
25
- };
28
+ }
26
29
 
27
- ExecutionStatusDecorator.propTypes = {
30
+ ScoreStatusDecorator.propTypes = {
31
+ id: PropTypes.number,
28
32
  status: PropTypes.string,
29
33
  };
30
-
31
- export default ExecutionStatusDecorator;
@@ -0,0 +1,32 @@
1
+ import _ from "lodash/fp";
2
+ import React from "react";
3
+ import { Menu } from "semantic-ui-react";
4
+ import { Link, useLocation, useParams } from "react-router-dom";
5
+ import { FormattedMessage } from "react-intl";
6
+ import { linkTo } from "@truedat/core/routes";
7
+
8
+ export default function ScoreTabs() {
9
+ const { pathname } = useLocation();
10
+ const urlParams = useParams();
11
+
12
+ const tabs = [
13
+ {
14
+ url: linkTo.SCORE(urlParams),
15
+ text: "tabs.qx.score.details",
16
+ },
17
+ {
18
+ url: linkTo.SCORE_EVENTS(urlParams),
19
+ text: "tabs.qx.score.score_events",
20
+ },
21
+ ];
22
+
23
+ return (
24
+ <Menu attached="top" pointing secondary tabular>
25
+ {tabs.map(({ url, text }, key) => (
26
+ <Menu.Item key={key} active={pathname === url} as={Link} to={url}>
27
+ <FormattedMessage id={text} />
28
+ </Menu.Item>
29
+ ))}
30
+ </Menu>
31
+ );
32
+ }
@@ -0,0 +1,31 @@
1
+ import React from "react";
2
+ import { render } from "@truedat/test/render";
3
+ import { messages } from "@truedat/qx/components/__tests__/__fixtures__/helper";
4
+ import MyScoreGroups from "../MyScoreGroups";
5
+
6
+ const renderOpts = { messages };
7
+
8
+ jest.mock("@truedat/qx/hooks/useScoreGroups", () => {
9
+ const { scoreGroupData } = jest.requireActual(
10
+ "@truedat/qx/components/scores/__tests__/__fixtures__/scoreHelper"
11
+ );
12
+
13
+ return {
14
+ useMyScoreGroupsIndex: jest.fn(() => ({
15
+ data: {
16
+ data: [
17
+ scoreGroupData({ status_summary: { PENDING: 1, QUEUED: 2 } }),
18
+ scoreGroupData({ status_summary: { SUCCEEDED: 1, FAILED: 3 } }),
19
+ ],
20
+ },
21
+ loading: false,
22
+ })),
23
+ };
24
+ });
25
+
26
+ describe("<MyScoreGroups />", () => {
27
+ it("matches the latest snapshot", () => {
28
+ const { container } = render(<MyScoreGroups />, renderOpts);
29
+ expect(container).toMatchSnapshot();
30
+ });
31
+ });
@@ -0,0 +1,55 @@
1
+ import React from "react";
2
+ import { render } from "@truedat/test/render";
3
+ import { messages } from "@truedat/qx/components/__tests__/__fixtures__/helper";
4
+ import { scoreData } from "@truedat/qx/components/scores/__tests__/__fixtures__/scoreHelper";
5
+ import ScoreContext from "../ScoreContext";
6
+ import QualityBar from "../QualityBar";
7
+
8
+ const renderOpts = { messages };
9
+
10
+ describe("<QualityBar />", () => {
11
+ it("matches the latest snapshot", () => {
12
+ const context = {
13
+ score: scoreData(),
14
+ };
15
+
16
+ const { container } = render(
17
+ <ScoreContext.Provider value={context}>
18
+ <QualityBar />
19
+ </ScoreContext.Provider>,
20
+ renderOpts
21
+ );
22
+
23
+ expect(container).toMatchSnapshot();
24
+ });
25
+
26
+ it("when score is failed", () => {
27
+ const context = {
28
+ score: scoreData({ status: "FAILED" }),
29
+ };
30
+
31
+ const { queryByText } = render(
32
+ <ScoreContext.Provider value={context}>
33
+ <QualityBar />
34
+ </ScoreContext.Provider>,
35
+ renderOpts
36
+ );
37
+
38
+ expect(queryByText(/Failed/i)).toBeInTheDocument();
39
+ });
40
+
41
+ it("when score is empty", () => {
42
+ const context = {
43
+ score: scoreData({ score_content: undefined }),
44
+ };
45
+
46
+ const { queryByText } = render(
47
+ <ScoreContext.Provider value={context}>
48
+ <QualityBar />
49
+ </ScoreContext.Provider>,
50
+ renderOpts
51
+ );
52
+
53
+ expect(queryByText(/No results/i)).toBeInTheDocument();
54
+ });
55
+ });
@@ -0,0 +1,41 @@
1
+ import _ from "lodash/fp";
2
+ import React from "react";
3
+ import { render } from "@truedat/test/render";
4
+ import { messages } from "@truedat/qx/components/__tests__/__fixtures__/helper";
5
+ import { useScoreShow } from "@truedat/qx/hooks/useScores";
6
+ import Score from "../Score";
7
+
8
+ jest.mock("react-router-dom", () => ({
9
+ ...jest.requireActual("react-router-dom"),
10
+ useParams: () => ({ id: "8" }),
11
+ }));
12
+
13
+ jest.mock("@truedat/qx/hooks/useScores", () => {
14
+ const { scoreData } = jest.requireActual(
15
+ "@truedat/qx/components/scores/__tests__/__fixtures__/scoreHelper"
16
+ );
17
+
18
+ return {
19
+ useScoreShow: jest.fn(() => ({
20
+ data: scoreData(),
21
+ loading: false,
22
+ })),
23
+ };
24
+ });
25
+
26
+ const renderOpts = { messages };
27
+
28
+ describe("<Score />", () => {
29
+ it("matches the latest snapshot", () => {
30
+ const { container } = render(<Score />, renderOpts);
31
+ expect(container).toMatchSnapshot();
32
+ });
33
+
34
+ it("matches the latest snapshot when has no score", () => {
35
+ useScoreShow.mockImplementation(() => ({
36
+ data: undefined,
37
+ }));
38
+ const { container } = render(<Score />, renderOpts);
39
+ expect(container).toMatchSnapshot();
40
+ });
41
+ });
@@ -0,0 +1,39 @@
1
+ import _ from "lodash/fp";
2
+ import React from "react";
3
+ import { render } from "@truedat/test/render";
4
+ import { scoreData } from "@truedat/qx/components/scores/__tests__/__fixtures__/scoreHelper";
5
+ import { messages } from "@truedat/qx/components/__tests__/__fixtures__/helper";
6
+ import ScoreContext from "../ScoreContext";
7
+ import ScoreCrumbs from "../ScoreCrumbs";
8
+
9
+ const renderOpts = { messages };
10
+
11
+ describe("<ScoreCrumbs />", () => {
12
+ it("matches the latest snapshot", () => {
13
+ const context = {
14
+ score: scoreData(),
15
+ };
16
+ const { container } = render(
17
+ <ScoreContext.Provider value={context}>
18
+ <ScoreCrumbs />
19
+ </ScoreContext.Provider>,
20
+ renderOpts
21
+ );
22
+
23
+ expect(container).toMatchSnapshot();
24
+ });
25
+
26
+ it("show message if is not executed", () => {
27
+ const context = {
28
+ score: scoreData({ execution_timestamp: undefined }),
29
+ };
30
+ const { queryByText } = render(
31
+ <ScoreContext.Provider value={context}>
32
+ <ScoreCrumbs />
33
+ </ScoreContext.Provider>,
34
+ renderOpts
35
+ );
36
+
37
+ expect(queryByText(/Not executed/i)).toBeInTheDocument();
38
+ });
39
+ });
@@ -0,0 +1,38 @@
1
+ import _ from "lodash/fp";
2
+ import React from "react";
3
+ import { render } from "@truedat/test/render";
4
+ import { messages } from "@truedat/qx/components/__tests__/__fixtures__/helper";
5
+ import ScoreContext from "../ScoreContext";
6
+ import ScoreDetails from "../ScoreDetails";
7
+ import { scoreData } from "./__fixtures__/scoreHelper";
8
+
9
+ const renderOpts = { messages };
10
+
11
+ describe("<ScoreDetails />", () => {
12
+ it("matches the latest snapshot", () => {
13
+ const context = {
14
+ score: scoreData(),
15
+ };
16
+ const { container } = render(
17
+ <ScoreContext.Provider value={context}>
18
+ <ScoreDetails />
19
+ </ScoreContext.Provider>,
20
+ renderOpts
21
+ );
22
+
23
+ expect(container).toMatchSnapshot();
24
+ });
25
+
26
+ it("do not display details if not available.", () => {
27
+ const context = {
28
+ score: scoreData({ details: undefined }),
29
+ };
30
+ const { queryByText } = render(
31
+ <ScoreContext.Provider value={context}>
32
+ <ScoreDetails />
33
+ </ScoreContext.Provider>,
34
+ renderOpts
35
+ );
36
+ expect(queryByText(/Details/i)).not.toBeInTheDocument();
37
+ });
38
+ });
@@ -0,0 +1,24 @@
1
+ import React from "react";
2
+ import { render } from "@truedat/test/render";
3
+ import { scoreData } from "@truedat/qx/components/scores/__tests__/__fixtures__/scoreHelper";
4
+ import { messages } from "@truedat/qx/components/__tests__/__fixtures__/helper";
5
+ import ScoreContext from "../ScoreContext";
6
+ import ScoreEvents from "../ScoreEvents";
7
+
8
+ const renderOpts = { messages };
9
+
10
+ describe("<ScoreEvents />", () => {
11
+ it("matches the latest snapshot", () => {
12
+ const context = {
13
+ score: scoreData(),
14
+ };
15
+ const { container } = render(
16
+ <ScoreContext.Provider value={context}>
17
+ <ScoreEvents />
18
+ </ScoreContext.Provider>,
19
+ renderOpts
20
+ );
21
+
22
+ expect(container).toMatchSnapshot();
23
+ });
24
+ });
@@ -0,0 +1,43 @@
1
+ import React from "react";
2
+ import { render } from "@truedat/test/render";
3
+ import { messages } from "@truedat/qx/components/__tests__/__fixtures__/helper";
4
+ import { useScoreGroupShow } from "@truedat/qx/hooks/useScoreGroups";
5
+ import ScoreGroup from "../ScoreGroup";
6
+
7
+ jest.mock("react-router-dom", () => ({
8
+ ...jest.requireActual("react-router-dom"),
9
+ useParams: () => ({ id: "8" }),
10
+ }));
11
+
12
+ jest.mock("@truedat/qx/hooks/useScoreGroups", () => {
13
+ const { scoreGroup } = jest.requireActual(
14
+ "@truedat/qx/components/scores/__tests__/__fixtures__/scoreHelper"
15
+ );
16
+
17
+ return {
18
+ useScoreGroupShow: jest.fn(() => ({
19
+ data: { data: scoreGroup },
20
+ loading: false,
21
+ })),
22
+ };
23
+ });
24
+
25
+ const renderOpts = { messages, fallback: "lazy" };
26
+
27
+ describe("<ScoreGroup />", () => {
28
+ it("matches the latest snapshot", () => {
29
+ const { container } = render(<ScoreGroup />, renderOpts);
30
+
31
+ expect(container).toMatchSnapshot();
32
+ });
33
+
34
+ it("matches the latest snapshot when scoreGroup is empty", () => {
35
+ useScoreGroupShow.mockImplementation(() => ({
36
+ data: { data: [] },
37
+ loading: false,
38
+ }));
39
+ const { container } = render(<ScoreGroup />, renderOpts);
40
+
41
+ expect(container).toMatchSnapshot();
42
+ });
43
+ });
@@ -0,0 +1,16 @@
1
+ import React from "react";
2
+ import { render } from "@truedat/test/render";
3
+ import { messages } from "@truedat/qx/components/__tests__/__fixtures__/helper";
4
+ import ScoreGroupBreadcrumbs from "../ScoreGroupBreadcrumbs";
5
+
6
+ const renderOpts = { messages };
7
+
8
+ describe("<ScoreGroupBreadcrumbs />", () => {
9
+ it("matches the latest snapshot", () => {
10
+ const { container } = render(
11
+ <ScoreGroupBreadcrumbs timestamp="2025-01-23T10:10:00Z" />,
12
+ renderOpts
13
+ );
14
+ expect(container).toMatchSnapshot();
15
+ });
16
+ });
@@ -0,0 +1,78 @@
1
+ import React from "react";
2
+ import { render } from "@truedat/test/render";
3
+ import { waitFor } from "@testing-library/react";
4
+ import userEvent from "@testing-library/user-event";
5
+ import { singleTemplateMock } from "@truedat/test/mocks";
6
+ import { messages } from "@truedat/qx/components/__tests__/__fixtures__/helper";
7
+ import ScoreGroupForm from "../ScoreGroupForm";
8
+
9
+ const renderOpts = {
10
+ mocks: [
11
+ singleTemplateMock({
12
+ scope: "qe",
13
+ domainIds: undefined,
14
+ }),
15
+ ],
16
+ messages,
17
+ fallback: "lazy",
18
+ };
19
+
20
+ const props = {
21
+ count: 10,
22
+ onSubmit: jest.fn(),
23
+ onCancel: jest.fn(),
24
+ };
25
+ describe("<ScoreGroupForm />", () => {
26
+ it("matches the latest snapshot", async () => {
27
+ const { container, queryByText } = render(
28
+ <ScoreGroupForm {...props} />,
29
+ renderOpts
30
+ );
31
+
32
+ await waitFor(() => {
33
+ expect(queryByText(/lazy/i)).not.toBeInTheDocument();
34
+ expect(container.querySelector(".loading")).not.toBeInTheDocument();
35
+ });
36
+
37
+ expect(container).toMatchSnapshot();
38
+ });
39
+ it("matches the latest snapshot for count 1", async () => {
40
+ const { container, queryByText } = render(
41
+ <ScoreGroupForm {...props} count={1} />,
42
+ renderOpts
43
+ );
44
+
45
+ await waitFor(() => {
46
+ expect(queryByText(/lazy/i)).not.toBeInTheDocument();
47
+ expect(container.querySelector(".loading")).not.toBeInTheDocument();
48
+ });
49
+
50
+ expect(container).toMatchSnapshot();
51
+ });
52
+
53
+ it("writes to form, submit and confirm", async () => {
54
+ const onSubmit = jest.fn();
55
+ const { container, queryByText, findByText, findByPlaceholderText } =
56
+ render(<ScoreGroupForm {...props} onSubmit={onSubmit} />, renderOpts);
57
+
58
+ await waitFor(() => {
59
+ expect(queryByText(/lazy/i)).not.toBeInTheDocument();
60
+ expect(container.querySelector(".loading")).not.toBeInTheDocument();
61
+ });
62
+
63
+ userEvent.type(await findByPlaceholderText("field1"), "foo");
64
+ userEvent.click(await findByText(/Create/i));
65
+
66
+ await waitFor(() =>
67
+ expect(onSubmit).toHaveBeenCalledWith({
68
+ content: {
69
+ field1: {
70
+ origin: "user",
71
+ value: "foo",
72
+ },
73
+ },
74
+ df_type: "template1",
75
+ })
76
+ );
77
+ });
78
+ });
@@ -0,0 +1,16 @@
1
+ import React from "react";
2
+ import { render } from "@truedat/test/render";
3
+ import { messages } from "@truedat/qx/components/__tests__/__fixtures__/helper";
4
+ import ScoreGroupLink from "../ScoreGroupLink";
5
+
6
+ const renderOpts = { messages };
7
+
8
+ describe("<ScoreGroupLink />", () => {
9
+ it("matches the latest snapshot", () => {
10
+ const { container } = render(
11
+ <ScoreGroupLink id="8" inserted_at="2025-01-23T10:10:00Z" />,
12
+ renderOpts
13
+ );
14
+ expect(container).toMatchSnapshot();
15
+ });
16
+ });