@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
|
@@ -6,189 +6,224 @@ import DataViewEditor, { DataViewDetailEditor } from "../DataViewEditor";
|
|
|
6
6
|
|
|
7
7
|
const mockFormatMessage = jest.fn(({ id }) => id);
|
|
8
8
|
jest.mock("react-intl", () => ({
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
...jest.requireActual("react-intl"),
|
|
10
|
+
useIntl: () => ({ formatMessage: mockFormatMessage }),
|
|
11
11
|
}));
|
|
12
12
|
|
|
13
13
|
jest.mock("@truedat/core/routes", () => ({
|
|
14
|
-
|
|
14
|
+
DATA_VIEWS: "/dataviews",
|
|
15
15
|
}));
|
|
16
16
|
|
|
17
17
|
jest.mock("react-router", () => ({
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
...jest.requireActual("react-router"),
|
|
19
|
+
useParams: jest.fn(),
|
|
20
20
|
}));
|
|
21
21
|
|
|
22
22
|
jest.mock("@apollo/client", () => ({
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
23
|
+
...jest.requireActual("@apollo/client"),
|
|
24
|
+
useQuery: jest.fn(() => ({
|
|
25
|
+
data: {
|
|
26
|
+
referenceDatasets: [
|
|
27
|
+
{ id: "10", name: "Álpha" },
|
|
28
|
+
{ id: "2", name: "Beta" },
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
loading: false,
|
|
32
|
+
})),
|
|
33
33
|
}));
|
|
34
34
|
|
|
35
35
|
const mockUseDataViews = jest.fn();
|
|
36
36
|
const mockUseDataViewFetch = jest.fn();
|
|
37
37
|
|
|
38
38
|
jest.mock("@truedat/qx/hooks/useDataViews", () => ({
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
39
|
+
useDataViews: () => mockUseDataViews(),
|
|
40
|
+
useDataViewFetch: (...args) => mockUseDataViewFetch(...args),
|
|
41
|
+
// mutation hooks are irrelevant here; don’t assert on them
|
|
42
|
+
useDataViewCreate: () => ({ trigger: jest.fn(), isMutating: false }),
|
|
43
|
+
useDataViewUpdate: () => ({ trigger: jest.fn(), isMutating: false }),
|
|
44
|
+
useDataViewDelete: () => ({ trigger: jest.fn(), isMutating: false }),
|
|
45
45
|
}));
|
|
46
46
|
|
|
47
|
-
const mockUseFunctions = jest.fn(() => ({
|
|
47
|
+
const mockUseFunctions = jest.fn(() => ({
|
|
48
|
+
data: { data: [] },
|
|
49
|
+
loading: false,
|
|
50
|
+
}));
|
|
48
51
|
|
|
49
52
|
jest.mock("@truedat/qx/hooks/useFunctions", () => ({
|
|
50
|
-
|
|
53
|
+
useFunctions: () => mockUseFunctions(),
|
|
51
54
|
}));
|
|
52
55
|
|
|
53
56
|
jest.mock("@truedat/core/components", () => ({
|
|
54
|
-
|
|
55
|
-
|
|
57
|
+
Loading: () => <div data-testid="loading">loading…</div>,
|
|
58
|
+
ConfirmModal: ({ trigger, onConfirm }) => (
|
|
59
|
+
<div data-testid="confirm-trigger" onClick={onConfirm}>
|
|
60
|
+
{trigger}
|
|
61
|
+
</div>
|
|
62
|
+
),
|
|
56
63
|
}));
|
|
57
64
|
|
|
58
65
|
jest.mock("../advancedForm/AdvancedDataViewEditor", () => () => (
|
|
59
|
-
|
|
66
|
+
<div data-testid="advanced-editor" />
|
|
60
67
|
));
|
|
61
68
|
jest.mock("../simpleForm/SimpleDataViewEditor", () => () => (
|
|
62
|
-
|
|
69
|
+
<div data-testid="simple-editor" />
|
|
63
70
|
));
|
|
64
71
|
jest.mock("../BreadCrumb", () => ({ text }) => (
|
|
65
|
-
|
|
72
|
+
<div data-testid="breadcrumb">{text}</div>
|
|
66
73
|
));
|
|
67
74
|
|
|
68
75
|
beforeEach(() => {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
76
|
+
jest.clearAllMocks();
|
|
77
|
+
useParams.mockReturnValue({});
|
|
78
|
+
require("@apollo/client").useQuery.mockImplementation(() => ({
|
|
79
|
+
data: {
|
|
80
|
+
referenceDatasets: [
|
|
81
|
+
{ id: "10", name: "Álpha" },
|
|
82
|
+
{ id: "2", name: "Beta" },
|
|
83
|
+
],
|
|
84
|
+
},
|
|
85
|
+
loading: false,
|
|
86
|
+
}));
|
|
87
|
+
mockUseDataViews.mockReturnValue({ data: { data: [] }, loading: false });
|
|
88
|
+
mockUseDataViewFetch.mockReset();
|
|
82
89
|
});
|
|
83
90
|
|
|
84
91
|
describe("<DataViewDetailEditor /> (render behavior only)", () => {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
expect(rendered.getByTestId("simple-editor")).toBeInTheDocument();
|
|
90
|
-
expect(rendered.queryByTestId("advanced-editor")).not.toBeInTheDocument();
|
|
91
|
-
expect(rendered.container.querySelector(".ui.segment.loading")).toBeNull();
|
|
92
|
+
it("renders Simple editor by default (guided)", async () => {
|
|
93
|
+
const rendered = render(<DataViewDetailEditor dataView={undefined} />);
|
|
94
|
+
await waitForLoad(rendered);
|
|
92
95
|
|
|
93
|
-
|
|
94
|
-
|
|
96
|
+
expect(rendered.getByTestId("simple-editor")).toBeInTheDocument();
|
|
97
|
+
expect(rendered.queryByTestId("advanced-editor")).not.toBeInTheDocument();
|
|
98
|
+
expect(rendered.container.querySelector(".ui.segment.loading")).toBeNull();
|
|
95
99
|
|
|
96
|
-
|
|
97
|
-
|
|
100
|
+
const guidedBtn = rendered.getByRole("button", {
|
|
101
|
+
name: /actions.mode.guided/i,
|
|
98
102
|
});
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
const user = userEvent.setup({ delay: null });
|
|
102
|
-
const rendered = render(<DataViewDetailEditor dataView={undefined} />);
|
|
103
|
-
await waitForLoad(rendered);
|
|
104
|
-
|
|
105
|
-
const advancedBtn = rendered.getByRole("button", { name: /actions.mode.advanced/i });
|
|
106
|
-
expect(advancedBtn).not.toBeDisabled();
|
|
107
|
-
await user.click(advancedBtn);
|
|
108
|
-
|
|
109
|
-
expect(rendered.getByTestId("advanced-editor")).toBeInTheDocument();
|
|
110
|
-
expect(rendered.queryByTestId("simple-editor")).not.toBeInTheDocument();
|
|
111
|
-
|
|
112
|
-
expect(rendered.getByRole("button", { name: /actions.mode.advanced/i })).toBeDisabled();
|
|
113
|
-
expect(rendered.getByRole("button", { name: /actions.mode.guided/i })).not.toBeDisabled();
|
|
103
|
+
const advancedBtn = rendered.getByRole("button", {
|
|
104
|
+
name: /actions.mode.advanced/i,
|
|
114
105
|
});
|
|
115
106
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
name: "Adv View",
|
|
120
|
-
description: "",
|
|
121
|
-
mode: "advanced",
|
|
122
|
-
queryables: [],
|
|
123
|
-
select: { type: "select" },
|
|
124
|
-
};
|
|
125
|
-
const rendered = render(<DataViewDetailEditor dataView={dataView} />);
|
|
126
|
-
await waitForLoad(rendered);
|
|
127
|
-
|
|
128
|
-
expect(rendered.getByTestId("advanced-editor")).toBeInTheDocument();
|
|
129
|
-
expect(rendered.queryByTestId("simple-editor")).not.toBeInTheDocument();
|
|
130
|
-
|
|
131
|
-
expect(rendered.getByRole("button", { name: /actions.mode.advanced/i })).toBeDisabled();
|
|
132
|
-
expect(rendered.getByRole("button", { name: /actions.mode.guided/i })).toBeDisabled();
|
|
133
|
-
});
|
|
107
|
+
expect(guidedBtn).toBeDisabled();
|
|
108
|
+
expect(advancedBtn).not.toBeDisabled();
|
|
109
|
+
});
|
|
134
110
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
111
|
+
it("switches to Advanced editor when advanced toggle is confirmed (state managed here)", async () => {
|
|
112
|
+
const user = userEvent.setup({ delay: null });
|
|
113
|
+
const rendered = render(<DataViewDetailEditor dataView={undefined} />);
|
|
114
|
+
await waitForLoad(rendered);
|
|
138
115
|
|
|
139
|
-
|
|
116
|
+
const advancedBtn = rendered.getByRole("button", {
|
|
117
|
+
name: /actions.mode.advanced/i,
|
|
140
118
|
});
|
|
119
|
+
expect(advancedBtn).not.toBeDisabled();
|
|
120
|
+
await user.click(advancedBtn);
|
|
121
|
+
|
|
122
|
+
expect(rendered.getByTestId("advanced-editor")).toBeInTheDocument();
|
|
123
|
+
expect(rendered.queryByTestId("simple-editor")).not.toBeInTheDocument();
|
|
124
|
+
|
|
125
|
+
expect(
|
|
126
|
+
rendered.getByRole("button", { name: /actions.mode.advanced/i })
|
|
127
|
+
).toBeDisabled();
|
|
128
|
+
expect(
|
|
129
|
+
rendered.getByRole("button", { name: /actions.mode.guided/i })
|
|
130
|
+
).not.toBeDisabled();
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it("when incoming dataView is advanced, shows Advanced editor and disables switching back to guided", async () => {
|
|
134
|
+
const dataView = {
|
|
135
|
+
id: 7,
|
|
136
|
+
name: "Adv View",
|
|
137
|
+
description: "",
|
|
138
|
+
mode: "advanced",
|
|
139
|
+
queryables: [],
|
|
140
|
+
select: { type: "select" },
|
|
141
|
+
};
|
|
142
|
+
const rendered = render(<DataViewDetailEditor dataView={dataView} />);
|
|
143
|
+
await waitForLoad(rendered);
|
|
144
|
+
|
|
145
|
+
expect(rendered.getByTestId("advanced-editor")).toBeInTheDocument();
|
|
146
|
+
expect(rendered.queryByTestId("simple-editor")).not.toBeInTheDocument();
|
|
147
|
+
|
|
148
|
+
expect(
|
|
149
|
+
rendered.getByRole("button", { name: /actions.mode.advanced/i })
|
|
150
|
+
).toBeDisabled();
|
|
151
|
+
expect(
|
|
152
|
+
rendered.getByRole("button", { name: /actions.mode.guided/i })
|
|
153
|
+
).toBeDisabled();
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it("shows loading state when any dependency is loading", () => {
|
|
157
|
+
mockUseDataViews.mockReturnValue({ data: { data: [] }, loading: true });
|
|
158
|
+
const rendered = render(<DataViewDetailEditor dataView={undefined} />);
|
|
159
|
+
|
|
160
|
+
expect(
|
|
161
|
+
rendered.container.querySelector(".ui.segment.loading")
|
|
162
|
+
).not.toBeNull();
|
|
163
|
+
});
|
|
141
164
|
});
|
|
142
165
|
|
|
143
166
|
describe("<DataViewEditor /> (render branches only)", () => {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
167
|
+
it("renders 'new' breadcrumb and detail editor when there is no id param", async () => {
|
|
168
|
+
const rendered = render(<DataViewEditor />);
|
|
169
|
+
await waitForLoad(rendered);
|
|
170
|
+
|
|
171
|
+
expect(rendered.getByTestId("breadcrumb")).toHaveTextContent(
|
|
172
|
+
"dataViews.new"
|
|
173
|
+
);
|
|
174
|
+
expect(rendered.getByTestId("simple-editor")).toBeInTheDocument();
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it("shows Loading while fetching an existing dataview", async () => {
|
|
178
|
+
useParams.mockReturnValue({ id: 1 });
|
|
179
|
+
mockUseDataViewFetch.mockReturnValue({
|
|
180
|
+
dataView: null,
|
|
181
|
+
loading: true,
|
|
182
|
+
error: undefined,
|
|
150
183
|
});
|
|
184
|
+
const rendered = render(<DataViewEditor />);
|
|
151
185
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
mockUseDataViewFetch.mockReturnValue({ dataView: null, loading: true, error: undefined });
|
|
155
|
-
const rendered = render(<DataViewEditor />);
|
|
186
|
+
expect(rendered.getByTestId("loading")).toBeInTheDocument();
|
|
187
|
+
});
|
|
156
188
|
|
|
157
|
-
|
|
189
|
+
it("renders nothing when fetch returns error", async () => {
|
|
190
|
+
useParams.mockReturnValue({ id: 1 });
|
|
191
|
+
mockUseDataViewFetch.mockReturnValue({
|
|
192
|
+
dataView: null,
|
|
193
|
+
loading: false,
|
|
194
|
+
error: { foo: "bar" },
|
|
158
195
|
});
|
|
159
196
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
197
|
+
const rendered = render(<DataViewEditor />);
|
|
198
|
+
await waitForLoad(rendered);
|
|
199
|
+
|
|
200
|
+
expect(rendered.queryByTestId("breadcrumb")).toBeNull();
|
|
201
|
+
expect(rendered.queryByTestId("simple-editor")).toBeNull();
|
|
202
|
+
expect(rendered.queryByTestId("advanced-editor")).toBeNull();
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
it("renders breadcrumb with existing name and advanced editor when mode is advanced", async () => {
|
|
206
|
+
useParams.mockReturnValue({ id: 42 });
|
|
207
|
+
mockUseDataViewFetch.mockReturnValue({
|
|
208
|
+
dataView: {
|
|
209
|
+
id: 42,
|
|
210
|
+
name: "Existing View Name",
|
|
211
|
+
description: "desc",
|
|
212
|
+
mode: "advanced",
|
|
213
|
+
queryables: [],
|
|
214
|
+
select: { type: "select" },
|
|
215
|
+
},
|
|
216
|
+
loading: false,
|
|
217
|
+
error: undefined,
|
|
170
218
|
});
|
|
171
219
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
select: { type: "select" },
|
|
182
|
-
},
|
|
183
|
-
loading: false,
|
|
184
|
-
error: undefined,
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
const rendered = render(<DataViewEditor />);
|
|
188
|
-
await waitForLoad(rendered);
|
|
189
|
-
|
|
190
|
-
expect(rendered.getByTestId("breadcrumb")).toHaveTextContent("Existing View Name");
|
|
191
|
-
expect(rendered.getByTestId("advanced-editor")).toBeInTheDocument();
|
|
192
|
-
expect(rendered.queryByTestId("simple-editor")).toBeNull();
|
|
193
|
-
});
|
|
220
|
+
const rendered = render(<DataViewEditor />);
|
|
221
|
+
await waitForLoad(rendered);
|
|
222
|
+
|
|
223
|
+
expect(rendered.getByTestId("breadcrumb")).toHaveTextContent(
|
|
224
|
+
"Existing View Name"
|
|
225
|
+
);
|
|
226
|
+
expect(rendered.getByTestId("advanced-editor")).toBeInTheDocument();
|
|
227
|
+
expect(rendered.queryByTestId("simple-editor")).toBeNull();
|
|
228
|
+
});
|
|
194
229
|
});
|