@truedat/qx 7.13.9 → 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.
- package/package.json +3 -3
- package/src/components/common/ClauseViewer.js +183 -21
- package/src/components/common/expressions/Condition.js +13 -6
- package/src/components/dataViews/DataViewEditor.js +0 -2
- package/src/components/dataViews/DataViewSummary.js +73 -0
- package/src/components/dataViews/__tests__/AdvancedDataViewEditor.spec.js +4 -1
- package/src/components/dataViews/__tests__/DataViewEditor.spec.js +167 -132
- package/src/components/dataViews/__tests__/DataViewSummary.spec.js +820 -0
- package/src/components/dataViews/__tests__/DataViews.spec.js +57 -17
- package/src/components/dataViews/__tests__/SimpleDataViewEditor.spec.js +140 -141
- package/src/components/dataViews/__tests__/__snapshots__/AdvancedDataViewEditor.spec.js.snap +963 -759
- package/src/components/dataViews/__tests__/__snapshots__/DataViewSelect.spec.js.snap +17 -13
- package/src/components/dataViews/__tests__/__snapshots__/DataViewSummary.spec.js.snap +1786 -0
- package/src/components/dataViews/__tests__/__snapshots__/Queryable.spec.js.snap +18 -14
- package/src/components/dataViews/__tests__/__snapshots__/Queryables.spec.js.snap +18 -14
- package/src/components/dataViews/advancedForm/AdvancedDataViewEditor.js +59 -48
- package/src/components/dataViews/queryableProperties/Join.js +2 -1
- package/src/components/dataViews/queryableProperties/Select.js +22 -30
- package/src/components/dataViews/queryableProperties/__tests__/__snapshots__/Join.spec.js.snap +1 -1
- package/src/components/dataViews/queryableProperties/__tests__/__snapshots__/Select.spec.js.snap +37 -25
- package/src/components/dataViews/queryableSummaryHelpers.js +101 -0
- package/src/components/dataViews/simpleForm/SimpleDataViewEditor.js +9 -4
- package/src/components/dataViews/summary/From.js +45 -0
- package/src/components/dataViews/summary/GroupBy.js +82 -0
- package/src/components/dataViews/summary/Join.js +60 -0
- package/src/components/dataViews/summary/Select.js +31 -0
- package/src/components/dataViews/summary/Where.js +37 -0
- package/src/components/qualityControls/ControlPropertiesView.js +115 -63
- package/src/components/qualityControls/EditQualityControl.js +5 -3
- package/src/components/qualityControls/NewDraftQualityControl.js +8 -3
- package/src/components/qualityControls/NewQualityControl.js +5 -3
- package/src/components/qualityControls/QualityControlCrumbs.js +46 -5
- package/src/components/qualityControls/QualityControlRoutes.js +3 -1
- package/src/components/qualityControls/QualityControls.js +9 -18
- package/src/components/qualityControls/QualityControlsLabelResults.js +2 -2
- package/src/components/qualityControls/__tests__/__snapshots__/ControlPropertiesView.spec.js.snap +12 -9
- package/src/components/qualityControls/__tests__/__snapshots__/EditQualityControl.spec.js.snap +536 -493
- package/src/components/qualityControls/__tests__/__snapshots__/NewDraftQualityControl.spec.js.snap +510 -483
- package/src/components/qualityControls/__tests__/__snapshots__/NewQualityControl.spec.js.snap +261 -245
- package/src/components/qualityControls/__tests__/__snapshots__/QualityControl.spec.js.snap +11 -8
- package/src/components/qualityControls/__tests__/__snapshots__/QualityControlCrumbs.spec.js.snap +1 -1
- package/src/components/qualityControls/__tests__/__snapshots__/QualityControlHeader.spec.js.snap +1 -1
- package/src/components/qualityControls/__tests__/__snapshots__/QualityControls.spec.js.snap +87 -87
- package/src/components/qualityControls/__tests__/__snapshots__/QualityControlsLabelResults.spec.js.snap +6 -2
- package/src/hooks/useDataViews.js +1 -1
- 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
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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
|
-
</
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
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
|
-
|
|
37
|
-
<
|
|
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
|
-
|
|
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
|
-
|
|
52
|
-
<
|
|
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
|
-
|
|
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
|
-
|
|
46
|
-
<
|
|
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
|
-
|
|
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 {
|
|
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={
|
|
46
|
+
<Breadcrumb.Section as={Link} to={listRoute}>
|
|
11
47
|
<FormattedMessage id="quality_controls.header" />
|
|
12
48
|
</Breadcrumb.Section>
|
|
13
|
-
|
|
14
|
-
|
|
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
|
-
|
|
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
|
-
<
|
|
199
|
-
{
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
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
|
|