@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.
- 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
|
@@ -556,7 +556,7 @@ exports[`<Queryable /> matches the latest snapshot with join queryable 1`] = `
|
|
|
556
556
|
</label>
|
|
557
557
|
<div
|
|
558
558
|
aria-expanded="false"
|
|
559
|
-
class="ui selection dropdown select-field-dropdown"
|
|
559
|
+
class="ui selection dropdown select-field-dropdown join-type-selector"
|
|
560
560
|
role="listbox"
|
|
561
561
|
tabindex="0"
|
|
562
562
|
>
|
|
@@ -787,21 +787,25 @@ exports[`<Queryable /> matches the latest snapshot with select queryable 1`] = `
|
|
|
787
787
|
role="list"
|
|
788
788
|
>
|
|
789
789
|
<div
|
|
790
|
-
class="
|
|
791
|
-
role="listitem"
|
|
790
|
+
class="field"
|
|
792
791
|
>
|
|
793
|
-
<
|
|
794
|
-
class="
|
|
795
|
-
|
|
796
|
-
add_select_field
|
|
797
|
-
</button>
|
|
798
|
-
<button
|
|
799
|
-
class="ui disabled button"
|
|
800
|
-
disabled=""
|
|
801
|
-
tabindex="-1"
|
|
792
|
+
<div
|
|
793
|
+
class="item"
|
|
794
|
+
role="listitem"
|
|
802
795
|
>
|
|
803
|
-
|
|
804
|
-
|
|
796
|
+
<button
|
|
797
|
+
class="ui button"
|
|
798
|
+
>
|
|
799
|
+
add_select_field
|
|
800
|
+
</button>
|
|
801
|
+
<button
|
|
802
|
+
class="ui disabled button"
|
|
803
|
+
disabled=""
|
|
804
|
+
tabindex="-1"
|
|
805
|
+
>
|
|
806
|
+
add_all_select_fields
|
|
807
|
+
</button>
|
|
808
|
+
</div>
|
|
805
809
|
</div>
|
|
806
810
|
</div>
|
|
807
811
|
</div>
|
|
@@ -402,7 +402,7 @@ exports[`<Queryables /> matches the latest snapshot with join queryable 1`] = `
|
|
|
402
402
|
</label>
|
|
403
403
|
<div
|
|
404
404
|
aria-expanded="false"
|
|
405
|
-
class="ui selection dropdown select-field-dropdown"
|
|
405
|
+
class="ui selection dropdown select-field-dropdown join-type-selector"
|
|
406
406
|
role="listbox"
|
|
407
407
|
tabindex="0"
|
|
408
408
|
>
|
|
@@ -672,21 +672,25 @@ exports[`<Queryables /> matches the latest snapshot with select queryable 1`] =
|
|
|
672
672
|
role="list"
|
|
673
673
|
>
|
|
674
674
|
<div
|
|
675
|
-
class="
|
|
676
|
-
role="listitem"
|
|
675
|
+
class="field"
|
|
677
676
|
>
|
|
678
|
-
<
|
|
679
|
-
class="
|
|
680
|
-
|
|
681
|
-
queryables.select.form.add_select_field
|
|
682
|
-
</button>
|
|
683
|
-
<button
|
|
684
|
-
class="ui disabled button"
|
|
685
|
-
disabled=""
|
|
686
|
-
tabindex="-1"
|
|
677
|
+
<div
|
|
678
|
+
class="item"
|
|
679
|
+
role="listitem"
|
|
687
680
|
>
|
|
688
|
-
|
|
689
|
-
|
|
681
|
+
<button
|
|
682
|
+
class="ui button"
|
|
683
|
+
>
|
|
684
|
+
queryables.select.form.add_select_field
|
|
685
|
+
</button>
|
|
686
|
+
<button
|
|
687
|
+
class="ui disabled button"
|
|
688
|
+
disabled=""
|
|
689
|
+
tabindex="-1"
|
|
690
|
+
>
|
|
691
|
+
queryables.select.form.add_all_select_fields
|
|
692
|
+
</button>
|
|
693
|
+
</div>
|
|
690
694
|
</div>
|
|
691
695
|
</div>
|
|
692
696
|
</div>
|
|
@@ -14,6 +14,7 @@ import { FormProvider, useForm, Controller } from "react-hook-form";
|
|
|
14
14
|
import QxContext from "@truedat/qx/components/QxContext";
|
|
15
15
|
import DataViewSelect from "./DataViewSelect";
|
|
16
16
|
import Queryables from "./Queryables";
|
|
17
|
+
import DataViewSummary from "../DataViewSummary";
|
|
17
18
|
|
|
18
19
|
const SourceSelector = lazy(
|
|
19
20
|
() => import("@truedat/cx/sources/components/SourceSelector")
|
|
@@ -37,18 +38,21 @@ export default function AdvancedDataViewEditor({
|
|
|
37
38
|
|
|
38
39
|
const isEditForm = !_.isNil(selectedDataView?.id);
|
|
39
40
|
const sourceId = watch("source_id");
|
|
41
|
+
const currentDataView = watch();
|
|
42
|
+
|
|
40
43
|
if (!selectedDataView) return null;
|
|
41
44
|
|
|
42
45
|
return (
|
|
43
46
|
<Fragment>
|
|
44
|
-
<
|
|
45
|
-
<
|
|
46
|
-
<
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
47
|
+
<Grid>
|
|
48
|
+
<Grid.Column width="11">
|
|
49
|
+
<FormProvider {...form}>
|
|
50
|
+
<Form>
|
|
51
|
+
<Header as="h3" dividing>
|
|
52
|
+
{watch("name") || formatMessage({ id: "dataViews.action.new" })}
|
|
53
|
+
</Header>
|
|
54
|
+
|
|
55
|
+
<Grid.Row>
|
|
52
56
|
<Controller
|
|
53
57
|
control={control}
|
|
54
58
|
name="name"
|
|
@@ -78,7 +82,7 @@ export default function AdvancedDataViewEditor({
|
|
|
78
82
|
)}
|
|
79
83
|
/>
|
|
80
84
|
</Grid.Row>
|
|
81
|
-
<Grid.Row
|
|
85
|
+
<Grid.Row>
|
|
82
86
|
<Controller
|
|
83
87
|
control={control}
|
|
84
88
|
name="description"
|
|
@@ -104,47 +108,54 @@ export default function AdvancedDataViewEditor({
|
|
|
104
108
|
)}
|
|
105
109
|
/>
|
|
106
110
|
</Grid.Row>
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
111
|
+
<Controller
|
|
112
|
+
control={control}
|
|
113
|
+
name="source_id"
|
|
114
|
+
rules={{ required: true }}
|
|
115
|
+
render={({ field: { onChange, value } }) => (
|
|
116
|
+
<Form.Field required>
|
|
117
|
+
<label>
|
|
118
|
+
{formatMessage({ id: "dataViews.form.source" })}
|
|
119
|
+
</label>
|
|
120
|
+
<SourceSelector
|
|
121
|
+
disabled={isEditForm}
|
|
122
|
+
value={value + ""}
|
|
123
|
+
onChange={(_e, { value }) => onChange(value)}
|
|
124
|
+
/>
|
|
125
|
+
</Form.Field>
|
|
126
|
+
)}
|
|
127
|
+
/>
|
|
128
|
+
{!_.isNil(sourceId) ? (
|
|
129
|
+
<QxContext value={{ ...context, sourceId }}>
|
|
130
|
+
<Queryables />
|
|
131
|
+
<DataViewSelect />
|
|
132
|
+
</QxContext>
|
|
133
|
+
) : null}
|
|
134
|
+
<Divider hidden />
|
|
135
|
+
<Container textAlign="right">
|
|
136
|
+
<Button
|
|
137
|
+
content={formatMessage({ id: "actions.cancel" })}
|
|
138
|
+
disabled={isSubmitting}
|
|
139
|
+
onClick={onCancel}
|
|
120
140
|
/>
|
|
121
|
-
</Form.Field>
|
|
122
|
-
)}
|
|
123
|
-
/>
|
|
124
|
-
{!_.isNil(sourceId) ? (
|
|
125
|
-
<QxContext value={{ ...context, sourceId }}>
|
|
126
|
-
<Queryables />
|
|
127
|
-
<DataViewSelect />
|
|
128
|
-
</QxContext>
|
|
129
|
-
) : null}
|
|
130
|
-
<Divider hidden />
|
|
131
|
-
<Container textAlign="right">
|
|
132
|
-
<Button
|
|
133
|
-
content={formatMessage({ id: "actions.cancel" })}
|
|
134
|
-
disabled={isSubmitting}
|
|
135
|
-
onClick={onCancel}
|
|
136
|
-
/>
|
|
137
141
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
142
|
+
<Button
|
|
143
|
+
onClick={handleSubmit((data) => onSubmit({ ...data, mode }))}
|
|
144
|
+
primary
|
|
145
|
+
loading={isSubmitting}
|
|
146
|
+
disabled={!isValid || !isDirty}
|
|
147
|
+
content={formatMessage({ id: "actions.save" })}
|
|
148
|
+
/>
|
|
149
|
+
</Container>
|
|
150
|
+
</Form>
|
|
151
|
+
</FormProvider>
|
|
152
|
+
</Grid.Column>
|
|
153
|
+
{!_.isNil(sourceId) && (
|
|
154
|
+
<Grid.Column width="5">
|
|
155
|
+
<DataViewSummary dataView={currentDataView} />
|
|
156
|
+
</Grid.Column>
|
|
157
|
+
)}
|
|
158
|
+
</Grid>
|
|
148
159
|
</Fragment>
|
|
149
160
|
);
|
|
150
161
|
}
|
|
@@ -7,6 +7,7 @@ import { Dropdown, Form } from "semantic-ui-react";
|
|
|
7
7
|
import ResourceSelector from "@truedat/qx/components/common/ResourceSelector";
|
|
8
8
|
import QxContext from "@truedat/qx/components/QxContext";
|
|
9
9
|
import JoinTypeIcon from "./JoinTypeIcon";
|
|
10
|
+
import "@truedat/qx/styles/Expression.less";
|
|
10
11
|
|
|
11
12
|
export default function Join() {
|
|
12
13
|
const { formatMessage } = useIntl();
|
|
@@ -38,7 +39,7 @@ export default function Join() {
|
|
|
38
39
|
{formatMessage({ id: "queryables.form.join.type" })}
|
|
39
40
|
</label>
|
|
40
41
|
<Dropdown
|
|
41
|
-
className="select-field-dropdown"
|
|
42
|
+
className="select-field-dropdown join-type-selector"
|
|
42
43
|
selection
|
|
43
44
|
value={value}
|
|
44
45
|
options={joinTypeOptions}
|
|
@@ -2,7 +2,7 @@ import _ from "lodash/fp";
|
|
|
2
2
|
import { use } from "react";
|
|
3
3
|
import { useIntl } from "react-intl";
|
|
4
4
|
import { useFieldArray, useFormState } from "react-hook-form";
|
|
5
|
-
import { Button,
|
|
5
|
+
import { Button, Form, Label, List } from "semantic-ui-react";
|
|
6
6
|
import QxContext from "@truedat/qx/components/QxContext";
|
|
7
7
|
import SelectField, { newSelectField } from "./SelectField";
|
|
8
8
|
|
|
@@ -29,12 +29,6 @@ export default function Select() {
|
|
|
29
29
|
)(ctxFields);
|
|
30
30
|
const maxId = _.flow(_.map("id"), _.max)(fields) || 0;
|
|
31
31
|
|
|
32
|
-
const addFieldButton = (
|
|
33
|
-
<Button onClick={() => append(newSelectField(maxId + 1))}>
|
|
34
|
-
{formatMessage({ id: "queryables.select.form.add_select_field" })}
|
|
35
|
-
</Button>
|
|
36
|
-
);
|
|
37
|
-
|
|
38
32
|
return (
|
|
39
33
|
<List>
|
|
40
34
|
{fields.map((selectField, index) => (
|
|
@@ -46,30 +40,28 @@ export default function Select() {
|
|
|
46
40
|
</QxContext>
|
|
47
41
|
</List.Item>
|
|
48
42
|
))}
|
|
49
|
-
<
|
|
50
|
-
|
|
51
|
-
<
|
|
52
|
-
|
|
53
|
-
content={requiredError}
|
|
54
|
-
open
|
|
55
|
-
pinned
|
|
56
|
-
position="bottom center"
|
|
57
|
-
trigger={addFieldButton}
|
|
58
|
-
/>
|
|
59
|
-
) : (
|
|
60
|
-
addFieldButton
|
|
61
|
-
)}
|
|
62
|
-
{_.size(fields) == 0 ? (
|
|
63
|
-
<Button
|
|
64
|
-
onClick={() => append(allFields)}
|
|
65
|
-
disabled={_.isEmpty(allFields)}
|
|
66
|
-
>
|
|
67
|
-
{formatMessage({
|
|
68
|
-
id: "queryables.select.form.add_all_select_fields",
|
|
69
|
-
})}
|
|
43
|
+
<Form.Field error={!!requiredError}>
|
|
44
|
+
<List.Item>
|
|
45
|
+
<Button onClick={() => append(newSelectField(maxId + 1))}>
|
|
46
|
+
{formatMessage({ id: "queryables.select.form.add_select_field" })}
|
|
70
47
|
</Button>
|
|
71
|
-
|
|
72
|
-
|
|
48
|
+
{_.size(fields) == 0 ? (
|
|
49
|
+
<Button
|
|
50
|
+
onClick={() => append(allFields)}
|
|
51
|
+
disabled={_.isEmpty(allFields)}
|
|
52
|
+
>
|
|
53
|
+
{formatMessage({
|
|
54
|
+
id: "queryables.select.form.add_all_select_fields",
|
|
55
|
+
})}
|
|
56
|
+
</Button>
|
|
57
|
+
) : null}
|
|
58
|
+
</List.Item>
|
|
59
|
+
{requiredError && (
|
|
60
|
+
<List.Item>
|
|
61
|
+
<Label content={requiredError} prompt pointing="above" />
|
|
62
|
+
</List.Item>
|
|
63
|
+
)}
|
|
64
|
+
</Form.Field>
|
|
73
65
|
</List>
|
|
74
66
|
);
|
|
75
67
|
}
|
package/src/components/dataViews/queryableProperties/__tests__/__snapshots__/Join.spec.js.snap
CHANGED
|
@@ -60,7 +60,7 @@ exports[`<Join /> matches the latest snapshot 1`] = `
|
|
|
60
60
|
</label>
|
|
61
61
|
<div
|
|
62
62
|
aria-expanded="false"
|
|
63
|
-
class="ui selection dropdown select-field-dropdown"
|
|
63
|
+
class="ui selection dropdown select-field-dropdown join-type-selector"
|
|
64
64
|
role="listbox"
|
|
65
65
|
tabindex="0"
|
|
66
66
|
>
|
package/src/components/dataViews/queryableProperties/__tests__/__snapshots__/Select.spec.js.snap
CHANGED
|
@@ -191,14 +191,18 @@ exports[`<Select /> handles add all fields 1`] = `
|
|
|
191
191
|
</div>
|
|
192
192
|
</div>
|
|
193
193
|
<div
|
|
194
|
-
class="
|
|
195
|
-
role="listitem"
|
|
194
|
+
class="field"
|
|
196
195
|
>
|
|
197
|
-
<
|
|
198
|
-
class="
|
|
196
|
+
<div
|
|
197
|
+
class="item"
|
|
198
|
+
role="listitem"
|
|
199
199
|
>
|
|
200
|
-
|
|
201
|
-
|
|
200
|
+
<button
|
|
201
|
+
class="ui button"
|
|
202
|
+
>
|
|
203
|
+
queryables.select.form.add_select_field
|
|
204
|
+
</button>
|
|
205
|
+
</div>
|
|
202
206
|
</div>
|
|
203
207
|
</div>
|
|
204
208
|
</div>
|
|
@@ -211,21 +215,25 @@ exports[`<Select /> matches the latest snapshot 1`] = `
|
|
|
211
215
|
role="list"
|
|
212
216
|
>
|
|
213
217
|
<div
|
|
214
|
-
class="
|
|
215
|
-
role="listitem"
|
|
218
|
+
class="field"
|
|
216
219
|
>
|
|
217
|
-
<
|
|
218
|
-
class="
|
|
219
|
-
|
|
220
|
-
queryables.select.form.add_select_field
|
|
221
|
-
</button>
|
|
222
|
-
<button
|
|
223
|
-
class="ui disabled button"
|
|
224
|
-
disabled=""
|
|
225
|
-
tabindex="-1"
|
|
220
|
+
<div
|
|
221
|
+
class="item"
|
|
222
|
+
role="listitem"
|
|
226
223
|
>
|
|
227
|
-
|
|
228
|
-
|
|
224
|
+
<button
|
|
225
|
+
class="ui button"
|
|
226
|
+
>
|
|
227
|
+
queryables.select.form.add_select_field
|
|
228
|
+
</button>
|
|
229
|
+
<button
|
|
230
|
+
class="ui disabled button"
|
|
231
|
+
disabled=""
|
|
232
|
+
tabindex="-1"
|
|
233
|
+
>
|
|
234
|
+
queryables.select.form.add_all_select_fields
|
|
235
|
+
</button>
|
|
236
|
+
</div>
|
|
229
237
|
</div>
|
|
230
238
|
</div>
|
|
231
239
|
</div>
|
|
@@ -583,14 +591,18 @@ exports[`<Select /> matches the latest snapshot with content 1`] = `
|
|
|
583
591
|
</div>
|
|
584
592
|
</div>
|
|
585
593
|
<div
|
|
586
|
-
class="
|
|
587
|
-
role="listitem"
|
|
594
|
+
class="field"
|
|
588
595
|
>
|
|
589
|
-
<
|
|
590
|
-
class="
|
|
596
|
+
<div
|
|
597
|
+
class="item"
|
|
598
|
+
role="listitem"
|
|
591
599
|
>
|
|
592
|
-
|
|
593
|
-
|
|
600
|
+
<button
|
|
601
|
+
class="ui button"
|
|
602
|
+
>
|
|
603
|
+
queryables.select.form.add_select_field
|
|
604
|
+
</button>
|
|
605
|
+
</div>
|
|
594
606
|
</div>
|
|
595
607
|
</div>
|
|
596
608
|
</div>
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
|
|
3
|
+
const labelForQueryable = (queryable) => {
|
|
4
|
+
if (queryable.type === "from")
|
|
5
|
+
return queryable.alias || queryable.properties?.resource?.embedded?.name;
|
|
6
|
+
if (queryable.type === "join")
|
|
7
|
+
return queryable.alias || queryable.properties?.resource?.embedded?.name;
|
|
8
|
+
if (queryable.type === "group_by") return queryable.alias || "Group By";
|
|
9
|
+
return null;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const validResource = (queryable) => {
|
|
13
|
+
return !_.isNil(queryable?.properties?.resource?.id);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Extracts resource information from a queryable
|
|
18
|
+
*/
|
|
19
|
+
export const getResourceInfo = (queryable) => {
|
|
20
|
+
if (!queryable?.properties?.resource?.id) return null;
|
|
21
|
+
|
|
22
|
+
const resource = queryable.properties.resource;
|
|
23
|
+
return {
|
|
24
|
+
id: resource.id,
|
|
25
|
+
type: resource.type,
|
|
26
|
+
name: resource.embedded?.name || resource.name,
|
|
27
|
+
alias: queryable.alias,
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Extracts join information including join type
|
|
33
|
+
*/
|
|
34
|
+
export const getJoinInfo = (queryable) => {
|
|
35
|
+
if (!queryable?.properties?.resource?.id) return null;
|
|
36
|
+
|
|
37
|
+
const resource = queryable.properties.resource;
|
|
38
|
+
const joinType = queryable.properties.type || "inner";
|
|
39
|
+
|
|
40
|
+
return {
|
|
41
|
+
id: resource.id,
|
|
42
|
+
type: resource.type,
|
|
43
|
+
name: resource.embedded?.name || resource.name,
|
|
44
|
+
alias: queryable.alias,
|
|
45
|
+
joinType,
|
|
46
|
+
clauses: queryable.properties.clauses,
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Extracts group by fields
|
|
52
|
+
*/
|
|
53
|
+
export const getGroupByFields = (queryable) => {
|
|
54
|
+
if (!queryable?.properties?.group_fields) return [];
|
|
55
|
+
|
|
56
|
+
return _.map((field) => ({
|
|
57
|
+
alias: field.alias,
|
|
58
|
+
expression: field.expression,
|
|
59
|
+
}))(queryable.properties.group_fields);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Extracts aggregate fields
|
|
64
|
+
*/
|
|
65
|
+
export const getAggregateFields = (queryable) => {
|
|
66
|
+
if (!queryable?.properties?.aggregate_fields) return [];
|
|
67
|
+
|
|
68
|
+
return _.map((field) => ({
|
|
69
|
+
alias: field.alias,
|
|
70
|
+
expression: field.expression,
|
|
71
|
+
}))(queryable.properties.aggregate_fields);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Extracts select fields
|
|
76
|
+
*/
|
|
77
|
+
export const getSelectFields = (queryable) => {
|
|
78
|
+
if (!queryable?.properties?.fields) return [];
|
|
79
|
+
|
|
80
|
+
return _.map((field) => ({
|
|
81
|
+
alias: field.alias,
|
|
82
|
+
expression: field.expression,
|
|
83
|
+
}))(queryable.properties.fields);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Checks if queryables array has valid structure
|
|
88
|
+
*/
|
|
89
|
+
export const hasValidStructure = (queryables = []) => {
|
|
90
|
+
return (
|
|
91
|
+
_.size(queryables) > 0 &&
|
|
92
|
+
_.some((q) => q.type === "from" && validResource(q))(queryables)
|
|
93
|
+
);
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
export const buildParentResourceMap = (queryables = []) =>
|
|
97
|
+
_.flow(
|
|
98
|
+
_.filter((q) => ["from", "join", "group_by"].includes(q.type)),
|
|
99
|
+
_.map((q) => [q.id, { ...q, label: labelForQueryable(q) }]),
|
|
100
|
+
_.fromPairs
|
|
101
|
+
)(queryables);
|
|
@@ -10,6 +10,7 @@ import DatasetForm from "./DatasetForm";
|
|
|
10
10
|
import AggregationForm from "./AggregationForm";
|
|
11
11
|
import SelectionForm from "./SelectionForm";
|
|
12
12
|
import CancelButton from "../actions/CancelButton";
|
|
13
|
+
import DataViewSummary from "../DataViewSummary";
|
|
13
14
|
|
|
14
15
|
export default function SimpleDataViewEditor({
|
|
15
16
|
selectedDataView,
|
|
@@ -34,6 +35,7 @@ export default function SimpleDataViewEditor({
|
|
|
34
35
|
|
|
35
36
|
const isEditForm = !_.isNil(selectedDataView?.id);
|
|
36
37
|
const sourceId = watch("source_id");
|
|
38
|
+
const currentDataView = watch();
|
|
37
39
|
|
|
38
40
|
const doSubmit = async (data) => {
|
|
39
41
|
const ok = await trigger();
|
|
@@ -49,9 +51,7 @@ export default function SimpleDataViewEditor({
|
|
|
49
51
|
const updateStatusState = async (steps) => {
|
|
50
52
|
const validations = await Promise.all(
|
|
51
53
|
_.map.convert({ cap: false })(async (step) => {
|
|
52
|
-
const ok = await trigger(stepInformation[step]["fieldNames"]
|
|
53
|
-
shouldFocus: true,
|
|
54
|
-
});
|
|
54
|
+
const ok = await trigger(stepInformation[step]["fieldNames"]);
|
|
55
55
|
const content = ok ? { status: "valid" } : { status: "error" };
|
|
56
56
|
return [step, content];
|
|
57
57
|
})(steps)
|
|
@@ -102,7 +102,7 @@ export default function SimpleDataViewEditor({
|
|
|
102
102
|
return (
|
|
103
103
|
<Fragment>
|
|
104
104
|
<Grid>
|
|
105
|
-
<Grid.Column width="
|
|
105
|
+
<Grid.Column width="11">
|
|
106
106
|
<Grid.Row textAlign="center">
|
|
107
107
|
<Step.Group>
|
|
108
108
|
<Step active={activeStep == 0} {...stepProps(0)}>
|
|
@@ -250,6 +250,11 @@ export default function SimpleDataViewEditor({
|
|
|
250
250
|
</FormProvider>
|
|
251
251
|
</Grid.Row>
|
|
252
252
|
</Grid.Column>
|
|
253
|
+
{!_.isNil(sourceId) && (
|
|
254
|
+
<Grid.Column width="5">
|
|
255
|
+
<DataViewSummary dataView={currentDataView} />
|
|
256
|
+
</Grid.Column>
|
|
257
|
+
)}
|
|
253
258
|
</Grid>
|
|
254
259
|
</Fragment>
|
|
255
260
|
);
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import { useIntl } from "react-intl";
|
|
3
|
+
import { List, Icon, Label } from "semantic-ui-react";
|
|
4
|
+
import { getResourceInfo } from "../queryableSummaryHelpers";
|
|
5
|
+
import { getColorById } from "../queryableFunctions";
|
|
6
|
+
import "@truedat/qx/styles/Expression.less";
|
|
7
|
+
|
|
8
|
+
export default function From({ queryable }) {
|
|
9
|
+
const { formatMessage } = useIntl();
|
|
10
|
+
const fromResource = getResourceInfo(queryable);
|
|
11
|
+
const color = getColorById(queryable.id);
|
|
12
|
+
|
|
13
|
+
if (_.isNil(fromResource)) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<List.Item>
|
|
19
|
+
<List.Header style={{ marginBottom: 8 }}>
|
|
20
|
+
<Icon name="database" />
|
|
21
|
+
{formatMessage({ id: "dataViews.form.queryable.from" })}
|
|
22
|
+
</List.Header>
|
|
23
|
+
<List.Content>
|
|
24
|
+
<List.Description className="description-flex-wrap text-break-word">
|
|
25
|
+
<Label horizontal>
|
|
26
|
+
{formatMessage({
|
|
27
|
+
id: `queryables.resource.selector.${fromResource.type}`,
|
|
28
|
+
})}
|
|
29
|
+
</Label>
|
|
30
|
+
<Label color={color} className="text-break-word">
|
|
31
|
+
{fromResource.name}
|
|
32
|
+
</Label>
|
|
33
|
+
{fromResource.alias && (
|
|
34
|
+
<>
|
|
35
|
+
<b style={{ marginRight: 4, marginLeft: 4 }}>as</b>
|
|
36
|
+
<Label color={color} className="text-break-word">
|
|
37
|
+
{fromResource.alias}
|
|
38
|
+
</Label>
|
|
39
|
+
</>
|
|
40
|
+
)}
|
|
41
|
+
</List.Description>
|
|
42
|
+
</List.Content>
|
|
43
|
+
</List.Item>
|
|
44
|
+
);
|
|
45
|
+
}
|