@truedat/qx 7.4.0 → 7.4.2

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 (47) hide show
  1. package/package.json +4 -4
  2. package/src/api.js +3 -2
  3. package/src/components/qualityControls/EditQualityControl.js +9 -7
  4. package/src/components/qualityControls/NewDraftQualityControl.js +13 -8
  5. package/src/components/qualityControls/NewQualityControl.js +8 -6
  6. package/src/components/qualityControls/QualityBadge.js +85 -2
  7. package/src/components/qualityControls/QualityControlActions.js +53 -4
  8. package/src/components/qualityControls/QualityControlHeader.js +2 -2
  9. package/src/components/qualityControls/QualityControlHistory.js +6 -0
  10. package/src/components/qualityControls/QualityControlRoutes.js +3 -1
  11. package/src/components/qualityControls/QualityControlScores.js +4 -4
  12. package/src/components/qualityControls/QualityControls.js +4 -4
  13. package/src/components/qualityControls/QualityControlsTable.js +17 -4
  14. package/src/components/qualityControls/__tests__/EditQualityControl.spec.js +2 -2
  15. package/src/components/qualityControls/__tests__/NewDraftQualityControl.spec.js +3 -3
  16. package/src/components/qualityControls/__tests__/NewQualityControl.spec.js +2 -2
  17. package/src/components/qualityControls/__tests__/QualityBadge.spec.js +173 -2
  18. package/src/components/qualityControls/__tests__/QualityControlActions.spec.js +7 -2
  19. package/src/components/qualityControls/__tests__/QualityControlHeader.spec.js +7 -1
  20. package/src/components/qualityControls/__tests__/QualityControlRow.spec.js +1 -3
  21. package/src/components/qualityControls/__tests__/QualityControlScores.spec.js +1 -1
  22. package/src/components/qualityControls/__tests__/QualityControlTabs.spec.js +2 -2
  23. package/src/components/qualityControls/__tests__/QualityControls.spec.js +8 -8
  24. package/src/components/qualityControls/__tests__/QualityControlsTable.spec.js +4 -1
  25. package/src/components/qualityControls/__tests__/__fixtures__/qualityControlHelper.js +16 -11
  26. package/src/components/qualityControls/__tests__/__snapshots__/QualityBadge.spec.js.snap +32 -0
  27. package/src/components/qualityControls/__tests__/__snapshots__/QualityControlActions.spec.js.snap +1 -3
  28. package/src/components/qualityControls/__tests__/__snapshots__/QualityControlHeader.spec.js.snap +13 -4
  29. package/src/components/qualityControls/__tests__/__snapshots__/QualityControlHistory.spec.js.snap +10 -2
  30. package/src/components/qualityControls/__tests__/__snapshots__/QualityControlRow.spec.js.snap +20 -2
  31. package/src/components/qualityControls/__tests__/__snapshots__/QualityControlScores.spec.js.snap +3 -3
  32. package/src/components/qualityControls/__tests__/__snapshots__/QualityControlTabs.spec.js.snap +3 -3
  33. package/src/components/qualityControls/__tests__/__snapshots__/QualityControls.spec.js.snap +15 -1
  34. package/src/components/qualityControls/__tests__/__snapshots__/QualityControlsTable.spec.js.snap +25 -2
  35. package/src/components/qualityControls/qualityByControlMode.js +24 -7
  36. package/src/components/qualityControls/qualityControlScoresColumns.js +11 -4
  37. package/src/components/scores/QualityBar.js +23 -1
  38. package/src/components/scores/ScoreCrumbs.js +4 -1
  39. package/src/components/scores/ScoreGroup.js +2 -2
  40. package/src/components/scores/__tests__/QualityBar.spec.js +1 -1
  41. package/src/components/scores/__tests__/Score.spec.js +2 -2
  42. package/src/components/scores/__tests__/ScoreGroup.spec.js +1 -1
  43. package/src/components/scores/__tests__/__fixtures__/scoreHelper.js +1 -0
  44. package/src/components/scores/__tests__/__snapshots__/Score.spec.js.snap +1 -1
  45. package/src/components/scores/__tests__/__snapshots__/ScoreCrumbs.spec.js.snap +1 -1
  46. package/src/components/scores/__tests__/__snapshots__/ScoreGroup.spec.js.snap +1 -1
  47. package/src/hooks/useQualityControls.js +8 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@truedat/qx",
3
- "version": "7.4.0",
3
+ "version": "7.4.2",
4
4
  "description": "Truedat Web Quality Experience package",
5
5
  "sideEffects": false,
6
6
  "jsnext:main": "src/index.js",
@@ -35,7 +35,7 @@
35
35
  "@testing-library/react": "^12.0.0",
36
36
  "@testing-library/react-hooks": "^8.0.1",
37
37
  "@testing-library/user-event": "^13.2.1",
38
- "@truedat/test": "7.4.0",
38
+ "@truedat/test": "7.4.2",
39
39
  "babel-jest": "^28.1.0",
40
40
  "babel-plugin-dynamic-import-node": "^2.3.3",
41
41
  "babel-plugin-lodash": "^3.3.4",
@@ -90,7 +90,7 @@
90
90
  ]
91
91
  },
92
92
  "dependencies": {
93
- "@truedat/core": "7.4.0",
93
+ "@truedat/core": "7.4.2",
94
94
  "prop-types": "^15.8.1",
95
95
  "react-hook-form": "^7.45.4",
96
96
  "react-intl": "^5.20.10",
@@ -106,5 +106,5 @@
106
106
  "overrides": {
107
107
  "jsdom": "26.0.0"
108
108
  },
109
- "gitHead": "65eb6322cc8478fd4c35f2268c8ac1a41e8f129d"
109
+ "gitHead": "bfc4801642aec7b29767605d30866b52f67aacce"
110
110
  }
package/src/api.js CHANGED
@@ -2,7 +2,6 @@ const API_DATA_VIEW = "/api/data_views/:id";
2
2
  const API_DATA_VIEWS = "/api/data_views";
3
3
  const API_FUNCTION = "/api/quality_functions/:id";
4
4
  const API_FUNCTIONS = "/api/quality_functions";
5
- const API_QUALITY_CONTROL = "/api/quality_controls/:id";
6
5
  const API_QUALITY_CONTROL_DRAFT = "/api/quality_controls/:id/draft";
7
6
  const API_QUALITY_CONTROL_FILTERS = "/api/quality_controls/filters";
8
7
  const API_QUALITY_CONTROL_MAIN = "/api/quality_controls/:id/main";
@@ -10,6 +9,8 @@ const API_QUALITY_CONTROL_PUBLISHED = "/api/quality_controls/:id/published";
10
9
  const API_QUALITY_CONTROL_QUERIES = "/api/quality_controls/:id/queries";
11
10
  const API_QUALITY_CONTROL_SEARCH = "/api/quality_controls/search";
12
11
  const API_QUALITY_CONTROL_STATUS = "/api/quality_controls/:id/status";
12
+ const API_QUALITY_CONTROL_VERSION =
13
+ "/api/quality_controls/:id/versions/:version";
13
14
  const API_QUALITY_CONTROL_VERSIONS = "/api/quality_controls/:id/versions";
14
15
  const API_QUALITY_CONTROLS = "/api/quality_controls";
15
16
  const API_SCORE_GROUPS_SEARCH = "/api/score_groups/search";
@@ -36,8 +37,8 @@ export {
36
37
  API_QUALITY_CONTROL_QUERIES,
37
38
  API_QUALITY_CONTROL_SEARCH,
38
39
  API_QUALITY_CONTROL_STATUS,
40
+ API_QUALITY_CONTROL_VERSION,
39
41
  API_QUALITY_CONTROL_VERSIONS,
40
- API_QUALITY_CONTROL,
41
42
  API_QUALITY_CONTROLS,
42
43
  API_SCORE_GROUPS,
43
44
  API_SCORE_GROUP,
@@ -1,4 +1,3 @@
1
- import _ from "lodash/fp";
2
1
  import React from "react";
3
2
  import { FormattedMessage } from "react-intl";
4
3
  import { useParams, useHistory } from "react-router-dom";
@@ -11,11 +10,13 @@ import {
11
10
  import QualityControlEditor from "./QualityControlEditor";
12
11
 
13
12
  export default function EditQualityControl() {
14
- const { id } = useParams();
13
+ const { id, version } = useParams();
15
14
  const history = useHistory();
16
-
17
15
  const { trigger, isMutating } = useQualityControlUpdateDraft(id);
18
- const { data, loading: qualityControlLoading } = useQualityControl(id);
16
+ const { data, loading: qualityControlLoading } = useQualityControl(
17
+ id,
18
+ version
19
+ );
19
20
  const qualityControl = data?.data;
20
21
  const loading = qualityControlLoading || isMutating;
21
22
 
@@ -25,9 +26,10 @@ export default function EditQualityControl() {
25
26
  ...qualityControl,
26
27
  status: "draft",
27
28
  },
28
- }).then((data) => {
29
- const id = _.prop("data.data.id")(data);
30
- history.push(linkTo.QUALITY_CONTROL({ id }));
29
+ }).then(({ data }) => {
30
+ const id = data?.data?.id;
31
+ const version = data?.data?.version;
32
+ history.push(linkTo.QUALITY_CONTROL({ id, version }));
31
33
  });
32
34
  };
33
35
  return (
@@ -11,11 +11,14 @@ import {
11
11
  import QualityControlEditor from "./QualityControlEditor";
12
12
 
13
13
  export default function NewDraftQualityControl() {
14
- const { id } = useParams();
14
+ const { id, version } = useParams();
15
15
  const history = useHistory();
16
16
  const { trigger, isMutating } = useQualityControlCreateDraft(id);
17
17
 
18
- const { data, loading: qualityControlLoading } = useQualityControl(id);
18
+ const { data, loading: qualityControlLoading } = useQualityControl(
19
+ id,
20
+ version
21
+ );
19
22
  const qualityControl = data?.data;
20
23
  const loading = qualityControlLoading || isMutating;
21
24
 
@@ -25,9 +28,10 @@ export default function NewDraftQualityControl() {
25
28
  ...qualityControl,
26
29
  status: "published",
27
30
  },
28
- }).then((data) => {
29
- const id = _.prop("data.data.id")(data);
30
- history.push(linkTo.QUALITY_CONTROL({ id }));
31
+ }).then(({ data }) => {
32
+ const id = data?.data?.id;
33
+ const version = data?.data?.version;
34
+ history.push(linkTo.QUALITY_CONTROL({ id, version }));
31
35
  });
32
36
  const handleSave = (qualityControl) => {
33
37
  trigger({
@@ -35,9 +39,10 @@ export default function NewDraftQualityControl() {
35
39
  ...qualityControl,
36
40
  status: "draft",
37
41
  },
38
- }).then((data) => {
39
- const id = _.prop("data.data.id")(data);
40
- history.push(linkTo.QUALITY_CONTROL({ id }));
42
+ }).then(({ data }) => {
43
+ const id = data?.data?.id;
44
+ const version = data?.data?.version;
45
+ history.push(linkTo.QUALITY_CONTROL({ id, version }));
41
46
  });
42
47
  };
43
48
  return (
@@ -23,9 +23,10 @@ export default function NewQualityControl() {
23
23
  ...qualityControl,
24
24
  status: "published",
25
25
  },
26
- }).then((data) => {
27
- const id = _.prop("data.data.id")(data);
28
- history.push(linkTo.QUALITY_CONTROL({ id }));
26
+ }).then(({ data }) => {
27
+ const id = data?.data?.id;
28
+ const version = data?.data?.version;
29
+ history.push(linkTo.QUALITY_CONTROL({ id, version }));
29
30
  });
30
31
  };
31
32
  const handleSave = (qualityControl) => {
@@ -34,9 +35,10 @@ export default function NewQualityControl() {
34
35
  ...qualityControl,
35
36
  status: "draft",
36
37
  },
37
- }).then((data) => {
38
- const id = _.prop("data.data.id")(data);
39
- history.push(linkTo.QUALITY_CONTROL({ id }));
38
+ }).then(({ data }) => {
39
+ const id = data?.data?.id;
40
+ const version = data?.data?.version;
41
+ history.push(linkTo.QUALITY_CONTROL({ id, version }));
40
42
  });
41
43
  };
42
44
 
@@ -1,12 +1,15 @@
1
1
  import _ from "lodash/fp";
2
2
  import React from "react";
3
- import { FormattedMessage } from "react-intl";
3
+ import PropTypes from "prop-types";
4
+ import { FormattedMessage, useIntl } from "react-intl";
4
5
  import { Icon } from "semantic-ui-react";
5
6
  import IconPopup from "./IconPopup";
6
7
  import qualityByControlMode from "./qualityByControlMode";
7
8
 
8
9
  export default function QualityBadge({ score }) {
9
- const quality = qualityByControlMode(score);
10
+ const { formatMessage } = useIntl();
11
+ const noResultsMessage = formatMessage({ id: "score.no_results" });
12
+ const quality = qualityByControlMode({ ...score, noResultsMessage });
10
13
 
11
14
  return quality.isFailed ? (
12
15
  <>
@@ -14,6 +17,11 @@ export default function QualityBadge({ score }) {
14
17
  <FormattedMessage id={"score.status.failed"} />
15
18
  </>
16
19
  ) : quality.isEmpty ? (
20
+ <>
21
+ <Icon inverted color="grey" />
22
+ <FormattedMessage id={"score.not_executed"} />
23
+ </>
24
+ ) : score.score_content.total_count == 0 ? (
17
25
  <>
18
26
  <Icon inverted color="grey" name="warning circle" />
19
27
  <FormattedMessage id={"score.no_results"} />
@@ -31,3 +39,78 @@ export default function QualityBadge({ score }) {
31
39
  </>
32
40
  );
33
41
  }
42
+ QualityBadge.propTypes = {
43
+ score: PropTypes.object,
44
+ };
45
+
46
+ export const QualityBadgeForSearch = ({
47
+ latestScore,
48
+ criteria,
49
+ controlMode,
50
+ }) => {
51
+ const color =
52
+ latestScore?.result_message === "meets_goal"
53
+ ? "green"
54
+ : latestScore?.result_message === "under_goal"
55
+ ? "yellow"
56
+ : latestScore?.result_message === "no_results"
57
+ ? "grey"
58
+ : "red";
59
+
60
+ const attrs =
61
+ controlMode == "percentage"
62
+ ? {
63
+ color: color,
64
+ label1: "quality_control.score_criteria.percentage.minimum",
65
+ value1: criteria.minimum,
66
+ label2: "quality_control.score_criteria.percentage.goal",
67
+ value2: criteria.goal,
68
+ text: `${latestScore.result}%`,
69
+ }
70
+ : controlMode == "deviation"
71
+ ? {
72
+ color: color,
73
+ label1: "quality_control.score_criteria.deviation.goal",
74
+ value1: criteria.goal,
75
+ label2: "quality_control.score_criteria.deviation.maximum",
76
+ value2: criteria.maximum,
77
+ text: `${latestScore.result}%`,
78
+ }
79
+ : {
80
+ color: color,
81
+ label1: "quality_control.score_criteria.error_count.goal",
82
+ value1: criteria?.goal,
83
+ label2: "quality_control.score_criteria.error_count.maximum",
84
+ value2: criteria?.maximum,
85
+ text: latestScore?.result,
86
+ };
87
+ return latestScore?.status === "failed" ? (
88
+ <>
89
+ <Icon color="red" name="warning circle" />
90
+ <FormattedMessage id={"score.status.failed"} />
91
+ </>
92
+ ) : _.prop("result_message")(latestScore) == "no_results" &&
93
+ _.isNil(latestScore?.result) ? (
94
+ <>
95
+ <Icon inverted color="grey" name="warning circle" />
96
+ <FormattedMessage id={"score.no_results"} />
97
+ </>
98
+ ) : !_.has("result")(latestScore) ? null : (
99
+ <>
100
+ <IconPopup
101
+ color={attrs.color}
102
+ label1={attrs.label1}
103
+ value1={attrs.value1}
104
+ label2={attrs.label2}
105
+ value2={attrs.value2}
106
+ />
107
+ {attrs.text}
108
+ </>
109
+ );
110
+ };
111
+
112
+ QualityBadgeForSearch.propTypes = {
113
+ controlMode: PropTypes.string,
114
+ latestScore: PropTypes.object,
115
+ criteria: PropTypes.object,
116
+ };
@@ -4,7 +4,7 @@ import PropTypes from "prop-types";
4
4
  import { useIntl } from "react-intl";
5
5
  import { Link, useHistory } from "react-router-dom";
6
6
  import { Button, Container } from "semantic-ui-react";
7
- import { linkTo } from "@truedat/core/routes";
7
+ import { linkTo, QUALITY_CONTROLS } from "@truedat/core/routes";
8
8
  import { useAuthorized } from "@truedat/core/hooks";
9
9
  import { ConfirmModal, GroupActions } from "@truedat/core/components";
10
10
  import { useScoreGroupCreate } from "../../hooks/useScoreGroups";
@@ -13,10 +13,11 @@ import { ScoreGroupPopup } from "../scores";
13
13
  import {
14
14
  useQualityControlUpdateStatus,
15
15
  useQualityControlUpdateMain,
16
+ useQualityControlDelete,
16
17
  } from "../../hooks/useQualityControls";
17
18
  import QualityControlQueryModal from "./QualityControlQueryModal";
18
19
 
19
- export const ConfirmToggleActiveModal = ({ onConfirm, qualityControl }) => {
20
+ const ConfirmToggleActiveModal = ({ onConfirm, qualityControl }) => {
20
21
  const { formatMessage } = useIntl();
21
22
  const { active, name } = qualityControl || {};
22
23
  const action = active ? "disable" : "enable";
@@ -48,6 +49,38 @@ ConfirmToggleActiveModal.propTypes = {
48
49
  onConfirm: PropTypes.func,
49
50
  };
50
51
 
52
+ const ConfirmDeletionModal = ({ qualityControl, onConfirm }) => {
53
+ const icon = "trash alternate outline";
54
+ const { formatMessage } = useIntl();
55
+ const { name } = qualityControl || {};
56
+
57
+ return (
58
+ <ConfirmModal
59
+ icon={icon}
60
+ trigger={
61
+ <Button
62
+ icon={icon}
63
+ content={formatMessage({ id: `quality_controls.actions.delete` })}
64
+ />
65
+ }
66
+ header={formatMessage({
67
+ id: `quality_controls.actions.delete.confirmation.header`,
68
+ })}
69
+ size="small"
70
+ content={formatMessage(
71
+ { id: `quality_controls.actions.delete.confirmation.content` },
72
+ { name: <i>{name}</i> }
73
+ )}
74
+ onConfirm={() => onConfirm()}
75
+ />
76
+ );
77
+ };
78
+
79
+ ConfirmDeletionModal.propTypes = {
80
+ qualityControl: PropTypes.object,
81
+ onConfirm: PropTypes.func,
82
+ };
83
+
51
84
  export default function QualityControlActions() {
52
85
  const history = useHistory();
53
86
  const { formatMessage } = useIntl();
@@ -62,6 +95,9 @@ export default function QualityControlActions() {
62
95
  const { trigger: triggerCreateScoreGroup, loading: groupCreating } =
63
96
  useScoreGroupCreate();
64
97
 
98
+ const { trigger: triggerDeleteQualityControl, isMutating: isDeleting } =
99
+ useQualityControlDelete(qualityControl);
100
+
65
101
  const updateStatus = (action) =>
66
102
  updateQualityControlStatus({ action }).then(() => mutate());
67
103
 
@@ -70,6 +106,9 @@ export default function QualityControlActions() {
70
106
  quality_control: { active: !qualityControl.active },
71
107
  }).then(() => mutate());
72
108
 
109
+ const confirmQualityControlDeletion = () =>
110
+ triggerDeleteQualityControl().then(() => history.push(QUALITY_CONTROLS));
111
+
73
112
  const canExecute = _.includes("execute")(actions);
74
113
 
75
114
  const availableActions = _.flow(
@@ -89,7 +128,7 @@ export default function QualityControlActions() {
89
128
  };
90
129
  const base = {
91
130
  key: action,
92
- disabled: isMutating || isMutatingMain,
131
+ disabled: isMutating || isMutatingMain || isDeleting,
93
132
  icon: _.prop(action)(actionIcon),
94
133
  };
95
134
  switch (action) {
@@ -114,6 +153,13 @@ export default function QualityControlActions() {
114
153
  onConfirm: toggleActive,
115
154
  qualityControl: qualityControl,
116
155
  };
156
+ case "delete":
157
+ return {
158
+ ...base,
159
+ as: ConfirmDeletionModal,
160
+ onConfirm: confirmQualityControlDeletion,
161
+ qualityControl: qualityControl,
162
+ };
117
163
  default:
118
164
  return {
119
165
  ...base,
@@ -153,7 +199,10 @@ export default function QualityControlActions() {
153
199
  onSubmit={onCreateScoreGroup}
154
200
  />
155
201
  ) : null}
156
- <GroupActions availableActions={availableActions} />
202
+ <GroupActions
203
+ availableActions={availableActions}
204
+ disabled={_.isEmpty(availableActions)}
205
+ />
157
206
  </Container>
158
207
  );
159
208
  }
@@ -13,8 +13,8 @@ import QualityControlActions from "./QualityControlActions";
13
13
  import QualityControlTabs from "./QualityControlTabs";
14
14
 
15
15
  export default function QualityControlHeader({ children }) {
16
- const { id } = useParams();
17
- const { data, loading, mutate } = useQualityControl(id);
16
+ const { id, version } = useParams();
17
+ const { data, loading, mutate } = useQualityControl(id, version);
18
18
 
19
19
  const qualityControl = _.propOr({}, "data")(data);
20
20
  const actions = _.propOr([], "_actions")(data);
@@ -5,6 +5,8 @@ import { Table } from "semantic-ui-react";
5
5
  import { useIntl } from "react-intl";
6
6
  import { columnDecorator } from "@truedat/core/services";
7
7
  import { Loading } from "@truedat/core/components";
8
+ import { Link } from "react-router-dom";
9
+ import { linkTo } from "@truedat/core/routes";
8
10
  import QxContext from "../QxContext";
9
11
 
10
12
  const translateDecorator = (id) =>
@@ -17,6 +19,10 @@ export default function QualityControlsHistory() {
17
19
  const columns = [
18
20
  {
19
21
  name: "name",
22
+ fieldSelector: _.pick(["quality_control_id", "version", "name"]),
23
+ fieldDecorator: ({ quality_control_id: id, version, name }) => (
24
+ <Link to={linkTo.QUALITY_CONTROL({ id, version })}>{name}</Link>
25
+ ),
20
26
  },
21
27
  {
22
28
  name: "version",
@@ -65,7 +65,9 @@ export default function QualityControlRoutes() {
65
65
  render={() => (
66
66
  <SearchContextProvider
67
67
  {...searchProps}
68
- defaultFilters={{ status: "draft" }}
68
+ defaultFilters={{
69
+ status: ["draft", "pending_approval", "rejected"],
70
+ }}
69
71
  >
70
72
  <QualityControls />
71
73
  </SearchContextProvider>
@@ -77,12 +77,12 @@ export default function QualityControlScores() {
77
77
  </Table.Header>
78
78
  <Table.Body>
79
79
  {scoreRows.map((score, key) => {
80
- const active =
81
- score.quality_control.version === qualityControl.version;
80
+ const version = score.quality_control.version;
81
+ const active = version === qualityControl.version;
82
82
  const tagLabel = score.firstInVersion
83
83
  ? `${formatMessage({
84
84
  id: "quality_control.props.version",
85
- })}: ${score.quality_control.version}`
85
+ })}: ${version}`
86
86
  : null;
87
87
  return (
88
88
  <React.Fragment key={key}>
@@ -91,7 +91,7 @@ export default function QualityControlScores() {
91
91
  <Table.Cell>
92
92
  <Label
93
93
  as={Link}
94
- to={linkTo.QUALITY_CONTROL_HISTORY({ id })}
94
+ to={linkTo.QUALITY_CONTROL_HISTORY({ id, version })}
95
95
  active={active}
96
96
  ribbon
97
97
  >
@@ -54,7 +54,7 @@ export const QualityControls = () => {
54
54
  const status = _.prop("status")(defaultFilters);
55
55
 
56
56
  const allChecked = () => {
57
- const ids = _.map(_.prop("version_id"))(qualityControls);
57
+ const ids = _.map(_.prop("id"))(qualityControls);
58
58
  return (
59
59
  _.negate(_.isEmpty)(selectedQualityControls) &&
60
60
  _.every((id) => _.includes(id)(selectedQualityControls))(ids)
@@ -63,7 +63,7 @@ export const QualityControls = () => {
63
63
 
64
64
  const addAll = (_e, target) => {
65
65
  const checkedAll = _.prop("checked")(target);
66
- const ids = _.map(_.prop("version_id"))(qualityControls);
66
+ const ids = _.map(_.prop("id"))(qualityControls);
67
67
  checkedAll
68
68
  ? setSelectedQualityControls(
69
69
  _.flow(_.concat(ids), _.uniq)(selectedQualityControls)
@@ -73,14 +73,14 @@ export const QualityControls = () => {
73
73
  );
74
74
  };
75
75
  const isRowChecked = (qualityControl) => {
76
- const id = _.prop("version_id")(qualityControl);
76
+ const id = _.prop("id")(qualityControl);
77
77
  return _.some((selectedId) => _.eq(id, selectedId))(
78
78
  selectedQualityControls
79
79
  );
80
80
  };
81
81
 
82
82
  const checkRow = (qualityControl) => {
83
- const id = _.prop("version_id")(qualityControl);
83
+ const id = _.prop("id")(qualityControl);
84
84
  const exists = _.some((selectedId) => _.eq(id, selectedId))(
85
85
  selectedQualityControls
86
86
  );
@@ -8,6 +8,7 @@ import { linkTo } from "@truedat/core/routes";
8
8
  import Moment from "react-moment";
9
9
 
10
10
  import { useSearchContext } from "@truedat/core/search/SearchContext";
11
+ import { QualityBadgeForSearch } from "./QualityBadge";
11
12
  import QualityControlRow from "./QualityControlRow";
12
13
 
13
14
  const translateDecorator = (id) =>
@@ -27,10 +28,10 @@ DateDecorator.propTypes = {
27
28
  export const columns = [
28
29
  {
29
30
  name: "name",
30
- sort: { name: "name.raw" },
31
- fieldSelector: _.pick(["id", "name"]),
32
- fieldDecorator: ({ id, name }) => (
33
- <Link to={linkTo.QUALITY_CONTROL({ id })}>{name}</Link>
31
+ sort: { name: "name.sort" },
32
+ fieldSelector: _.pick(["quality_control_id", "version", "name"]),
33
+ fieldDecorator: ({ quality_control_id: id, version, name }) => (
34
+ <Link to={linkTo.QUALITY_CONTROL({ id, version })}>{name}</Link>
34
35
  ),
35
36
  },
36
37
  {
@@ -54,6 +55,18 @@ export const columns = [
54
55
  translateDecorator(`quality_control.status.${status}`),
55
56
  width: 2,
56
57
  },
58
+ {
59
+ name: "latest_score",
60
+ width: 2,
61
+ fieldSelector: _.pick(["latest_score", "score_criteria", "control_mode"]),
62
+ fieldDecorator: ({ latest_score, score_criteria, control_mode }) => (
63
+ <QualityBadgeForSearch
64
+ controlMode={control_mode}
65
+ latestScore={latest_score}
66
+ criteria={score_criteria}
67
+ />
68
+ ),
69
+ },
57
70
  {
58
71
  name: "updated_at",
59
72
  sort: { name: "updated_at" },
@@ -22,7 +22,7 @@ const mockHistory = { push: jest.fn() };
22
22
 
23
23
  jest.mock("react-router-dom", () => ({
24
24
  ...jest.requireActual("react-router-dom"),
25
- useParams: () => ({ id: "8" }),
25
+ useParams: () => ({ id: "8", version: "1" }),
26
26
  useHistory: () => mockHistory,
27
27
  }));
28
28
 
@@ -181,7 +181,7 @@ describe("<EditQualityControl />", () => {
181
181
 
182
182
  it("test save submit ", async () => {
183
183
  const trigger = jest.fn(() =>
184
- Promise.resolve({ data: { data: { id: "9" } } })
184
+ Promise.resolve({ data: { data: { id: "9", version: "1" } } })
185
185
  );
186
186
 
187
187
  useQualityControlUpdateDraft.mockImplementation(() => ({
@@ -23,7 +23,7 @@ const mockHistory = { push: jest.fn() };
23
23
 
24
24
  jest.mock("react-router-dom", () => ({
25
25
  ...jest.requireActual("react-router-dom"),
26
- useParams: () => ({ id: "8" }),
26
+ useParams: () => ({ id: "8", version: "1" }),
27
27
  useHistory: () => mockHistory,
28
28
  }));
29
29
 
@@ -165,7 +165,7 @@ describe("<NewDraftQualityControl />", () => {
165
165
 
166
166
  it("test save submit ", async () => {
167
167
  const trigger = jest.fn(() =>
168
- Promise.resolve({ data: { data: { id: "9" } } })
168
+ Promise.resolve({ data: { data: { id: "9", version: "1" } } })
169
169
  );
170
170
 
171
171
  useQualityControlCreateDraft.mockImplementation(() => ({
@@ -203,7 +203,7 @@ describe("<NewDraftQualityControl />", () => {
203
203
 
204
204
  it("test publish submit ", async () => {
205
205
  const trigger = jest.fn(() =>
206
- Promise.resolve({ data: { data: { id: "9" } } })
206
+ Promise.resolve({ data: { data: { id: "9", version: "1" } } })
207
207
  );
208
208
 
209
209
  useQualityControlCreateDraft.mockImplementation(() => ({
@@ -135,7 +135,7 @@ describe("<NewQualityControl />", () => {
135
135
 
136
136
  it("test save submit ", async () => {
137
137
  const trigger = jest.fn(() =>
138
- Promise.resolve({ data: { data: { id: "9" } } })
138
+ Promise.resolve({ data: { data: { id: "9", version: "1" } } })
139
139
  );
140
140
 
141
141
  useQualityControlCreate.mockImplementation(() => ({
@@ -283,7 +283,7 @@ describe("<NewQualityControl />", () => {
283
283
 
284
284
  it("test publish submit ", async () => {
285
285
  const trigger = jest.fn(() =>
286
- Promise.resolve({ data: { data: { id: "9" } } })
286
+ Promise.resolve({ data: { data: { id: "9", version: "1" } } })
287
287
  );
288
288
 
289
289
  useQualityControlCreate.mockImplementation(() => ({