@truedat/qx 7.13.8 → 7.14.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.
Files changed (46) hide show
  1. package/package.json +3 -3
  2. package/src/components/common/ClauseViewer.js +183 -21
  3. package/src/components/common/expressions/Condition.js +13 -6
  4. package/src/components/dataViews/DataViewEditor.js +0 -2
  5. package/src/components/dataViews/DataViewSummary.js +73 -0
  6. package/src/components/dataViews/__tests__/AdvancedDataViewEditor.spec.js +4 -1
  7. package/src/components/dataViews/__tests__/DataViewEditor.spec.js +167 -132
  8. package/src/components/dataViews/__tests__/DataViewSummary.spec.js +820 -0
  9. package/src/components/dataViews/__tests__/DataViews.spec.js +57 -17
  10. package/src/components/dataViews/__tests__/SimpleDataViewEditor.spec.js +140 -141
  11. package/src/components/dataViews/__tests__/__snapshots__/AdvancedDataViewEditor.spec.js.snap +963 -759
  12. package/src/components/dataViews/__tests__/__snapshots__/DataViewSelect.spec.js.snap +17 -13
  13. package/src/components/dataViews/__tests__/__snapshots__/DataViewSummary.spec.js.snap +1786 -0
  14. package/src/components/dataViews/__tests__/__snapshots__/Queryable.spec.js.snap +18 -14
  15. package/src/components/dataViews/__tests__/__snapshots__/Queryables.spec.js.snap +18 -14
  16. package/src/components/dataViews/advancedForm/AdvancedDataViewEditor.js +59 -48
  17. package/src/components/dataViews/queryableProperties/Join.js +2 -1
  18. package/src/components/dataViews/queryableProperties/Select.js +22 -30
  19. package/src/components/dataViews/queryableProperties/__tests__/__snapshots__/Join.spec.js.snap +1 -1
  20. package/src/components/dataViews/queryableProperties/__tests__/__snapshots__/Select.spec.js.snap +37 -25
  21. package/src/components/dataViews/queryableSummaryHelpers.js +101 -0
  22. package/src/components/dataViews/simpleForm/SimpleDataViewEditor.js +9 -4
  23. package/src/components/dataViews/summary/From.js +45 -0
  24. package/src/components/dataViews/summary/GroupBy.js +82 -0
  25. package/src/components/dataViews/summary/Join.js +60 -0
  26. package/src/components/dataViews/summary/Select.js +31 -0
  27. package/src/components/dataViews/summary/Where.js +37 -0
  28. package/src/components/qualityControls/ControlPropertiesView.js +115 -63
  29. package/src/components/qualityControls/EditQualityControl.js +5 -3
  30. package/src/components/qualityControls/NewDraftQualityControl.js +8 -3
  31. package/src/components/qualityControls/NewQualityControl.js +5 -3
  32. package/src/components/qualityControls/QualityControlCrumbs.js +46 -5
  33. package/src/components/qualityControls/QualityControlRoutes.js +3 -1
  34. package/src/components/qualityControls/QualityControls.js +9 -18
  35. package/src/components/qualityControls/QualityControlsLabelResults.js +2 -2
  36. package/src/components/qualityControls/__tests__/__snapshots__/ControlPropertiesView.spec.js.snap +12 -9
  37. package/src/components/qualityControls/__tests__/__snapshots__/EditQualityControl.spec.js.snap +536 -493
  38. package/src/components/qualityControls/__tests__/__snapshots__/NewDraftQualityControl.spec.js.snap +510 -483
  39. package/src/components/qualityControls/__tests__/__snapshots__/NewQualityControl.spec.js.snap +261 -245
  40. package/src/components/qualityControls/__tests__/__snapshots__/QualityControl.spec.js.snap +11 -8
  41. package/src/components/qualityControls/__tests__/__snapshots__/QualityControlCrumbs.spec.js.snap +1 -1
  42. package/src/components/qualityControls/__tests__/__snapshots__/QualityControlHeader.spec.js.snap +1 -1
  43. package/src/components/qualityControls/__tests__/__snapshots__/QualityControls.spec.js.snap +87 -87
  44. package/src/components/qualityControls/__tests__/__snapshots__/QualityControlsLabelResults.spec.js.snap +6 -2
  45. package/src/hooks/useDataViews.js +1 -1
  46. package/src/styles/Expression.less +25 -1
@@ -0,0 +1,82 @@
1
+ import _ from "lodash/fp";
2
+ import { useIntl } from "react-intl";
3
+ import { List, Header, Icon, Label, Segment } from "semantic-ui-react";
4
+ import {
5
+ getAggregateFields,
6
+ getGroupByFields,
7
+ } from "../queryableSummaryHelpers";
8
+ import { getColorById } from "../queryableFunctions";
9
+ import { ExpressionViewer } from "@truedat/qx/components/common/ClauseViewer";
10
+
11
+ export default function GroupBy({ queryable }) {
12
+ const { formatMessage } = useIntl();
13
+ const groupByFields = getGroupByFields(queryable);
14
+ const aggregateFields = getAggregateFields(queryable);
15
+ const color = getColorById(queryable.id);
16
+ const hasGroupByFields = _.size(groupByFields) > 0;
17
+ const hasAggregateFields = _.size(aggregateFields) > 0;
18
+
19
+ return (
20
+ <List.Item>
21
+ <List.Header style={{ marginBottom: 4 }}>
22
+ <Icon name="calculator" />
23
+ {formatMessage({ id: "dataViews.form.queryable.group_by" })}
24
+ </List.Header>
25
+ <List.Content>
26
+ {queryable.alias && (
27
+ <div style={{ marginBottom: 4 }}>
28
+ <b style={{ marginRight: 4 }}>as</b>
29
+ <Label color={color}>{queryable.alias}</Label>
30
+ </div>
31
+ )}
32
+ {hasGroupByFields && (
33
+ <Segment>
34
+ <List.Description>
35
+ <div style={{ marginBottom: 8 }}>
36
+ <Header as="h5">
37
+ <Icon name="group" size="small" />
38
+ {formatMessage({
39
+ id: "queryables.group_by.form.group_fields",
40
+ })}
41
+ </Header>
42
+ </div>
43
+ <div>
44
+ {groupByFields.map((field, idx) => (
45
+ <ExpressionViewer
46
+ key={idx}
47
+ expression={field.expression}
48
+ alias={field.alias}
49
+ />
50
+ ))}
51
+ </div>
52
+ </List.Description>
53
+ </Segment>
54
+ )}
55
+
56
+ {hasAggregateFields && (
57
+ <Segment>
58
+ <List.Description>
59
+ <div style={{ marginBottom: 8 }}>
60
+ <Header as="h5">
61
+ <Icon name="chart bar" size="small" />
62
+ {formatMessage({
63
+ id: "queryables.group_by.form.aggregate_fields",
64
+ })}
65
+ </Header>
66
+ </div>
67
+ <div>
68
+ {aggregateFields.map((field, idx) => (
69
+ <ExpressionViewer
70
+ key={idx}
71
+ expression={field.expression}
72
+ alias={field.alias}
73
+ />
74
+ ))}
75
+ </div>
76
+ </List.Description>
77
+ </Segment>
78
+ )}
79
+ </List.Content>
80
+ </List.Item>
81
+ );
82
+ }
@@ -0,0 +1,60 @@
1
+ import _ from "lodash/fp";
2
+ import { useIntl } from "react-intl";
3
+ import { List, Icon, Label } from "semantic-ui-react";
4
+ import { getJoinInfo } from "../queryableSummaryHelpers";
5
+ import ClauseViewer from "@truedat/qx/components/common/ClauseViewer";
6
+ import JoinTypeIcon from "../queryableProperties/JoinTypeIcon";
7
+ import { getColorById } from "../queryableFunctions";
8
+ import "@truedat/qx/styles/Expression.less";
9
+
10
+ export default function Join({ queryable }) {
11
+ const { formatMessage } = useIntl();
12
+ const joinResource = getJoinInfo(queryable);
13
+ const color = getColorById(queryable.id);
14
+
15
+ return (
16
+ <List.Item>
17
+ <List.Header style={{ marginBottom: 4 }}>
18
+ <Icon name="linkify" />
19
+ {formatMessage({ id: "dataViews.form.queryable.join" })}
20
+ </List.Header>
21
+ {joinResource && (
22
+ <List.Content>
23
+ <List.Description className="description-flex-wrap text-break-word">
24
+ <div style={{ display: "flex", rowGap: 5, flexWrap: "wrap" }}>
25
+ <div
26
+ style={{
27
+ display: "flex",
28
+ alignItems: "center",
29
+ }}
30
+ >
31
+ <JoinTypeIcon type={joinResource.joinType} />
32
+ <Label horizontal>
33
+ {formatMessage({
34
+ id: `queryables.resource.selector.${joinResource.type}`,
35
+ })}
36
+ </Label>
37
+ </div>
38
+ <Label color={color} className="text-break-word">
39
+ {joinResource.name}
40
+ </Label>
41
+ </div>
42
+ {joinResource.alias && (
43
+ <>
44
+ <b style={{ marginRight: 4, marginLeft: 4 }}>as</b>
45
+ <Label color={color} className="text-break-word">
46
+ {joinResource.alias}
47
+ </Label>
48
+ </>
49
+ )}
50
+ {joinResource.clauses && _.size(joinResource.clauses) > 0 && (
51
+ <div style={{ marginTop: 4, width: "100%" }}>
52
+ <ClauseViewer clause={joinResource.clauses} />
53
+ </div>
54
+ )}
55
+ </List.Description>
56
+ </List.Content>
57
+ )}
58
+ </List.Item>
59
+ );
60
+ }
@@ -0,0 +1,31 @@
1
+ import { useIntl } from "react-intl";
2
+ import { List, Icon } from "semantic-ui-react";
3
+ import { getSelectFields } from "../queryableSummaryHelpers";
4
+ import { ExpressionViewer } from "@truedat/qx/components/common/ClauseViewer";
5
+
6
+ export default function Select({ queryable }) {
7
+ const { formatMessage } = useIntl();
8
+ const selectFields = getSelectFields(queryable);
9
+
10
+ return (
11
+ <List.Item>
12
+ <List.Header style={{ marginBottom: 8 }}>
13
+ <Icon name="columns" />
14
+ {formatMessage({ id: "dataViews.form.queryable.select" })}
15
+ </List.Header>
16
+ <List.Content>
17
+ <List.List>
18
+ {selectFields.map((field, idx) => (
19
+ <List.Item key={idx}>
20
+ <ExpressionViewer
21
+ key={idx}
22
+ expression={field.expression}
23
+ alias={field.alias}
24
+ />
25
+ </List.Item>
26
+ ))}
27
+ </List.List>
28
+ </List.Content>
29
+ </List.Item>
30
+ );
31
+ }
@@ -0,0 +1,37 @@
1
+ import _ from "lodash/fp";
2
+ import { useIntl } from "react-intl";
3
+ import { List, Icon, Label } from "semantic-ui-react";
4
+ import ClauseViewer from "@truedat/qx/components/common/ClauseViewer";
5
+ import { getColorById } from "../queryableFunctions";
6
+
7
+ export default function Where({
8
+ queryable: whereResource,
9
+ clauseType = "where",
10
+ }) {
11
+ const { formatMessage } = useIntl();
12
+ const color = getColorById(whereResource.id);
13
+
14
+ return (
15
+ <List.Item>
16
+ <List.Header style={{ marginBottom: 4 }}>
17
+ <Icon name="filter" />
18
+ {formatMessage({ id: `dataViews.form.queryable.${clauseType}` })}
19
+ </List.Header>
20
+ <List.Content>
21
+ <List.Description>
22
+ {whereResource.alias && (
23
+ <div>
24
+ <b style={{ marginRight: 4 }}>as</b>
25
+ <Label color={color}>{whereResource.alias}</Label>
26
+ </div>
27
+ )}
28
+ {whereResource.properties?.clauses ? (
29
+ <ClauseViewer clause={whereResource.properties.clauses} />
30
+ ) : (
31
+ <>{formatMessage({ id: "dataViews.summary.where.empty" })}</>
32
+ )}
33
+ </List.Description>
34
+ </List.Content>
35
+ </List.Item>
36
+ );
37
+ }
@@ -2,7 +2,11 @@ import _ from "lodash/fp";
2
2
  import PropTypes from "prop-types";
3
3
  import { FormattedMessage } from "react-intl";
4
4
  import { Header, Icon, Segment, List, Label } from "semantic-ui-react";
5
+ import { Loading } from "@truedat/core/components";
5
6
  import ClauseViewer from "@truedat/qx/components/common/ClauseViewer";
7
+ import DataViewSummary from "../dataViews/DataViewSummary";
8
+ import { useDataViewFetch } from "@truedat/qx/hooks/useDataViews";
9
+ import { getColorById } from "../dataViews/queryableFunctions";
6
10
 
7
11
  export default function ControlPropertiesView({ qualityControl }) {
8
12
  const { control_properties, control_mode } = qualityControl;
@@ -38,71 +42,119 @@ export default function ControlPropertiesView({ qualityControl }) {
38
42
  );
39
43
  }
40
44
 
41
- const ControlPropertiesRatio = ({ controlProperties }) => (
42
- <List>
43
- <List.Item>
44
- <List.Header>
45
- <FormattedMessage id="quality_control.ratio.resource" />
46
- </List.Header>
47
- <List.Content>
48
- {controlProperties.resource ? (
49
- <List.Description>
50
- <Label horizontal>
51
- <FormattedMessage
52
- id={`queryables.resource.selector.${controlProperties.resource?.type}`}
53
- />
54
- </Label>
55
- <Label color="blue">
56
- {_.prop("resource.embedded.name")(controlProperties)}
57
- </Label>
58
- </List.Description>
59
- ) : (
60
- <FormattedMessage id="quality_control.ratio.resource.empty" />
61
- )}
62
- </List.Content>
63
- </List.Item>
64
- <List.Item>
65
- <List.Header>
66
- <FormattedMessage id="quality_control.ratio.validation" />
67
- </List.Header>
68
- <List.Content>
69
- {controlProperties.validation ? (
70
- <List.Description>
71
- <ClauseViewer clause={controlProperties.validation} />
72
- </List.Description>
73
- ) : (
74
- <FormattedMessage id="quality_control.ratio.validation.empty" />
75
- )}
76
- </List.Content>
77
- </List.Item>
78
- </List>
79
- );
45
+ const ControlPropertiesRatio = ({ controlProperties }) => {
46
+ const isDataViewResource = controlProperties.resource?.type === "data_view";
47
+ const dataViewId = isDataViewResource ? controlProperties.resource?.id : null;
48
+ const { dataView, loading: dataViewLoading } = useDataViewFetch(dataViewId);
80
49
 
81
- const ControlPropertiesCount = ({ controlProperties }) => (
82
- <List>
83
- <List.Item>
84
- <List.Header>
85
- <FormattedMessage id="quality_control.count.errors_resource" />
86
- </List.Header>
87
- <List.Content>
88
- {controlProperties.errors_resource ? (
89
- <List.Description>
90
- <Label horizontal>
91
- <FormattedMessage
92
- id={`queryables.resource.selector.${controlProperties.errors_resource?.type}`}
50
+ return (
51
+ <List>
52
+ <List.Item>
53
+ <List.Header>
54
+ <FormattedMessage id="quality_control.ratio.resource" />
55
+ </List.Header>
56
+ <List.Content>
57
+ {controlProperties.resource ? (
58
+ <List.Description>
59
+ <Label horizontal>
60
+ <FormattedMessage
61
+ id={`queryables.resource.selector.${controlProperties.resource?.type}`}
62
+ />
63
+ </Label>
64
+ <Label color={getColorById(controlProperties.resource?.id)}>
65
+ {_.prop("resource.embedded.name")(controlProperties)}
66
+ </Label>
67
+ </List.Description>
68
+ ) : (
69
+ <FormattedMessage id="quality_control.ratio.resource.empty" />
70
+ )}
71
+ </List.Content>
72
+ </List.Item>
73
+ {isDataViewResource && (
74
+ <List.Item>
75
+ <List.Header style={{ marginBottom: 8 }}>
76
+ <FormattedMessage id="quality_control.data_view_summary" />
77
+ </List.Header>
78
+ <List.Content>
79
+ {dataViewLoading ? (
80
+ <Loading />
81
+ ) : dataView ? (
82
+ <DataViewSummary dataView={dataView} />
83
+ ) : null}
84
+ </List.Content>
85
+ </List.Item>
86
+ )}
87
+ <List.Item>
88
+ <List.Header>
89
+ <FormattedMessage id="quality_control.ratio.validation" />
90
+ </List.Header>
91
+ <List.Content>
92
+ {controlProperties.validation ? (
93
+ <List.Description>
94
+ <ClauseViewer
95
+ clause={controlProperties.validation}
96
+ parentResource={controlProperties.resource}
93
97
  />
94
- </Label>
95
- <Label color="blue">
96
- {_.prop("errors_resource.embedded.name")(controlProperties)}
97
- </Label>
98
- </List.Description>
99
- ) : (
100
- <FormattedMessage id="quality_control.count.errors_resource.empty" />
101
- )}
102
- </List.Content>
103
- </List.Item>
104
- </List>
105
- );
98
+ </List.Description>
99
+ ) : (
100
+ <FormattedMessage id="quality_control.ratio.validation.empty" />
101
+ )}
102
+ </List.Content>
103
+ </List.Item>
104
+ </List>
105
+ );
106
+ };
107
+
108
+ const ControlPropertiesCount = ({ controlProperties }) => {
109
+ const isDataViewResource =
110
+ controlProperties.errors_resource?.type === "data_view";
111
+ const dataViewId = isDataViewResource
112
+ ? controlProperties.errors_resource?.id
113
+ : null;
114
+ const { dataView, loading: dataViewLoading } = useDataViewFetch(dataViewId);
115
+
116
+ return (
117
+ <List>
118
+ <List.Item>
119
+ <List.Header>
120
+ <FormattedMessage id="quality_control.count.errors_resource" />
121
+ </List.Header>
122
+ <List.Content>
123
+ {controlProperties.errors_resource ? (
124
+ <List.Description>
125
+ <Label horizontal>
126
+ <FormattedMessage
127
+ id={`queryables.resource.selector.${controlProperties.errors_resource?.type}`}
128
+ />
129
+ </Label>
130
+ <Label
131
+ color={getColorById(controlProperties.errors_resource?.id)}
132
+ >
133
+ {_.prop("errors_resource.embedded.name")(controlProperties)}
134
+ </Label>
135
+ </List.Description>
136
+ ) : (
137
+ <FormattedMessage id="quality_control.count.errors_resource.empty" />
138
+ )}
139
+ </List.Content>
140
+ </List.Item>
141
+ {isDataViewResource && (
142
+ <List.Item>
143
+ <List.Header style={{ marginBottom: 8 }}>
144
+ <FormattedMessage id="quality_control.data_view_summary" />
145
+ </List.Header>
146
+ <List.Content>
147
+ {dataViewLoading ? (
148
+ <Loading />
149
+ ) : dataView ? (
150
+ <DataViewSummary dataView={dataView} />
151
+ ) : null}
152
+ </List.Content>
153
+ </List.Item>
154
+ )}
155
+ </List>
156
+ );
157
+ };
106
158
 
107
159
  ControlPropertiesView.propTypes = {
108
160
  qualityControl: PropTypes.object,
@@ -7,6 +7,7 @@ import {
7
7
  useQualityControl,
8
8
  } from "../../hooks/useQualityControls";
9
9
  import QualityControlEditor from "./QualityControlEditor";
10
+ import QualityControlCrumbs from "./QualityControlCrumbs";
10
11
 
11
12
  export default function EditQualityControl() {
12
13
  const { id, version } = useParams();
@@ -33,8 +34,9 @@ export default function EditQualityControl() {
33
34
  });
34
35
  };
35
36
  return (
36
- <Segment floated="left" loading={loading}>
37
- <Container text>
37
+ <>
38
+ <QualityControlCrumbs qualityControl={qualityControl} action="Edit" />
39
+ <Container as={Segment} loading={loading} text>
38
40
  <Header as="h2">
39
41
  <Icon circular name="archive" />
40
42
  <Header.Content>
@@ -54,6 +56,6 @@ export default function EditQualityControl() {
54
56
  />
55
57
  ) : null}
56
58
  </Container>
57
- </Segment>
59
+ </>
58
60
  );
59
61
  }
@@ -8,6 +8,7 @@ import {
8
8
  useQualityControl,
9
9
  } from "../../hooks/useQualityControls";
10
10
  import QualityControlEditor from "./QualityControlEditor";
11
+ import QualityControlCrumbs from "./QualityControlCrumbs";
11
12
 
12
13
  export default function NewDraftQualityControl() {
13
14
  const { id, version } = useParams();
@@ -48,8 +49,12 @@ export default function NewDraftQualityControl() {
48
49
  };
49
50
 
50
51
  return (
51
- <Segment floated="left" loading={loading}>
52
- <Container text>
52
+ <>
53
+ <QualityControlCrumbs
54
+ qualityControl={qualityControl}
55
+ action="New Draft"
56
+ />
57
+ <Container as={Segment} text loading={loading}>
53
58
  <Header as="h2">
54
59
  <Icon circular name="archive" />
55
60
  <Header.Content>
@@ -70,6 +75,6 @@ export default function NewDraftQualityControl() {
70
75
  />
71
76
  ) : null}
72
77
  </Container>
73
- </Segment>
78
+ </>
74
79
  );
75
80
  }
@@ -5,6 +5,7 @@ import { Container, Header, Icon, Segment } from "semantic-ui-react";
5
5
  import { QUALITY_CONTROLS, linkTo } from "@truedat/core/routes";
6
6
  import { useQualityControlCreate } from "../../hooks/useQualityControls";
7
7
  import QualityControlEditor from "./QualityControlEditor";
8
+ import QualityControlCrumbs from "./QualityControlCrumbs";
8
9
 
9
10
  export const defaultQualityControl = {
10
11
  name: "",
@@ -42,8 +43,9 @@ export default function NewQualityControl() {
42
43
  };
43
44
 
44
45
  return (
45
- <Segment floated="left" loading={isMutating}>
46
- <Container text>
46
+ <>
47
+ <QualityControlCrumbs action="New" />
48
+ <Container as={Segment} text loading={isMutating}>
47
49
  <Header as="h2">
48
50
  <Icon circular name="archive" />
49
51
  <Header.Content>
@@ -62,6 +64,6 @@ export default function NewQualityControl() {
62
64
  isSubmitting={isMutating}
63
65
  />
64
66
  </Container>
65
- </Segment>
67
+ </>
66
68
  );
67
69
  }
@@ -1,21 +1,62 @@
1
+ import { Fragment } from "react";
1
2
  import PropTypes from "prop-types";
2
3
  import { Breadcrumb } from "semantic-ui-react";
3
4
  import { Link } from "react-router";
4
5
  import { FormattedMessage } from "react-intl";
5
- import { QUALITY_CONTROLS } from "@truedat/core/routes";
6
+ import {
7
+ QUALITY_CONTROLS,
8
+ QUALITY_CONTROLS_DRAFTS,
9
+ QUALITY_CONTROLS_DEPRECATED,
10
+ linkTo,
11
+ } from "@truedat/core/routes";
12
+
13
+ const QualityControlSection = ({ qualityControl, active }) => {
14
+ const to = linkTo.QUALITY_CONTROL({
15
+ id: qualityControl.id,
16
+ version: qualityControl.version,
17
+ });
18
+ const props = active ? { active } : { as: Link, to };
19
+ return (
20
+ <Breadcrumb.Section {...props}>{qualityControl.name}</Breadcrumb.Section>
21
+ );
22
+ };
23
+
24
+ QualityControlSection.propTypes = {
25
+ qualityControl: PropTypes.object.isRequired,
26
+ active: PropTypes.bool,
27
+ };
28
+
29
+ export default function QualityControlCrumbs({ qualityControl, action }) {
30
+ const listRoute =
31
+ qualityControl?.status === "draft"
32
+ ? QUALITY_CONTROLS_DRAFTS
33
+ : qualityControl?.status === "deprecated"
34
+ ? QUALITY_CONTROLS_DEPRECATED
35
+ : QUALITY_CONTROLS;
36
+
37
+ const sections = [
38
+ qualityControl && (
39
+ <QualityControlSection qualityControl={qualityControl} active={!action} />
40
+ ),
41
+ action && <Breadcrumb.Section active>{action}</Breadcrumb.Section>,
42
+ ].filter(Boolean);
6
43
 
7
- export default function QualityControlCrumbs({ qualityControl }) {
8
44
  return (
9
45
  <Breadcrumb>
10
- <Breadcrumb.Section as={Link} to={QUALITY_CONTROLS} active={false}>
46
+ <Breadcrumb.Section as={Link} to={listRoute}>
11
47
  <FormattedMessage id="quality_controls.header" />
12
48
  </Breadcrumb.Section>
13
- <Breadcrumb.Divider icon="right angle" />
14
- <Breadcrumb.Section active>{qualityControl.name}</Breadcrumb.Section>
49
+ {sections.map((section, index) => (
50
+ <Fragment key={index}>
51
+ <Breadcrumb.Divider icon="right angle" />
52
+ {section}
53
+ </Fragment>
54
+ ))}
15
55
  </Breadcrumb>
16
56
  );
17
57
  }
18
58
 
19
59
  QualityControlCrumbs.propTypes = {
20
60
  qualityControl: PropTypes.object,
61
+ action: PropTypes.string,
21
62
  };
@@ -1,4 +1,6 @@
1
1
  import { Route, Routes, useParams } from "react-router";
2
+ import { SearchContextProvider } from "@truedat/core/search/SearchContext";
3
+ // This is only for information purposes, we are not using these routes in the code
2
4
  import {
3
5
  QUALITY_CONTROLS_DEPRECATED,
4
6
  QUALITY_CONTROLS_DRAFTS,
@@ -10,7 +12,7 @@ import {
10
12
  QUALITY_CONTROL_HISTORY,
11
13
  QUALITY_CONTROL_SCORES,
12
14
  } from "@truedat/core/routes";
13
- import { SearchContextProvider } from "@truedat/core/search/SearchContext";
15
+
14
16
  import {
15
17
  useQualityControlsSearch,
16
18
  useQualityControlsFilters,
@@ -11,8 +11,6 @@ import {
11
11
  Icon,
12
12
  Segment,
13
13
  Grid,
14
- Dimmer,
15
- Loader,
16
14
  } from "semantic-ui-react";
17
15
  import { linkTo, QUALITY_CONTROL_NEW } from "@truedat/core/routes";
18
16
  import useAuthorizedAction from "@truedat/core/hooks/useAuthorizedAction";
@@ -138,7 +136,7 @@ export const QualityControls = () => {
138
136
  };
139
137
 
140
138
  return (
141
- <Segment>
139
+ <Segment loading={loading}>
142
140
  <Header as="h2">
143
141
  <Icon circular name="archive" />
144
142
  <Header.Content>
@@ -195,21 +193,14 @@ export const QualityControls = () => {
195
193
  executeQualityControlOn={executeQualityControlOn}
196
194
  qualityControlsToExecute={_.size(selectedQualityControls)}
197
195
  />
198
- <Dimmer.Dimmable dimmed={loading}>
199
- {loading ? (
200
- <Dimmer active inverted>
201
- <Loader />
202
- </Dimmer>
203
- ) : null}
204
- <QualityControlsTable
205
- addAll={addAll}
206
- checkedAll={allChecked()}
207
- checkRow={checkRow}
208
- executeQualityControlOn={executeQualityControlOn}
209
- isRowChecked={isRowChecked}
210
- />
211
- <QualityControlsPagination />
212
- </Dimmer.Dimmable>
196
+ <QualityControlsTable
197
+ addAll={addAll}
198
+ checkedAll={allChecked()}
199
+ checkRow={checkRow}
200
+ executeQualityControlOn={executeQualityControlOn}
201
+ isRowChecked={isRowChecked}
202
+ />
203
+ <QualityControlsPagination />
213
204
  </Segment>
214
205
  );
215
206
  };
@@ -10,7 +10,7 @@ export const QualityControlsLabelResults = ({
10
10
  const { loading, count } = useSearchContext();
11
11
 
12
12
  return (
13
- <>
13
+ <div style={{ marginBottom: 8 }}>
14
14
  <Label className="quality-controls-label-results">
15
15
  {loading ? (
16
16
  <FormattedMessage id="quality_controls.searching" />
@@ -34,7 +34,7 @@ export const QualityControlsLabelResults = ({
34
34
  />
35
35
  </Label>
36
36
  ) : null}
37
- </>
37
+ </div>
38
38
  );
39
39
  };
40
40