@truedat/qx 5.12.2 → 5.12.7

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 (52) hide show
  1. package/package.json +8 -3
  2. package/src/api.js +3 -1
  3. package/src/components/QxContext.js +3 -0
  4. package/src/components/QxRoutes.js +6 -1
  5. package/src/components/common/DescriptionInput.js +47 -0
  6. package/src/components/common/TestFormWrapper.js +33 -0
  7. package/src/components/common/TypeSelector.js +33 -0
  8. package/src/components/common/index.js +4 -0
  9. package/src/components/functions/FunctionEditor.js +200 -0
  10. package/src/components/functions/FunctionParams.js +122 -0
  11. package/src/components/functions/Functions.js +152 -0
  12. package/src/components/functions/__tests__/FunctionEditor.spec.js +195 -0
  13. package/src/components/functions/__tests__/FunctionParams.spec.js +108 -0
  14. package/src/components/functions/__tests__/Functions.spec.js +95 -0
  15. package/src/components/functions/__tests__/__snapshots__/FunctionEditor.spec.js.snap +1563 -0
  16. package/src/components/functions/__tests__/__snapshots__/FunctionParams.spec.js.snap +228 -0
  17. package/src/components/functions/__tests__/__snapshots__/Functions.spec.js.snap +86 -0
  18. package/src/components/functions/__tests__/useWatchParams.spec.js +23 -0
  19. package/src/components/functions/expressions/ConstantSelector.js +26 -0
  20. package/src/components/functions/expressions/Expression.js +40 -0
  21. package/src/components/functions/expressions/FieldSelector.js +56 -0
  22. package/src/components/functions/expressions/FunctionArgs.js +49 -0
  23. package/src/components/functions/expressions/FunctionSelector.js +95 -0
  24. package/src/components/functions/expressions/ParamSelector.js +51 -0
  25. package/src/components/functions/expressions/ShapeSelector.js +74 -0
  26. package/src/components/functions/expressions/__tests__/ConstantSelector.spec.js +64 -0
  27. package/src/components/functions/expressions/__tests__/Expression.spec.js +131 -0
  28. package/src/components/functions/expressions/__tests__/FunctionArgs.spec.js +86 -0
  29. package/src/components/functions/expressions/__tests__/FunctionSelector.spec.js +69 -0
  30. package/src/components/functions/expressions/__tests__/ParamSelector.spec.js +115 -0
  31. package/src/components/functions/expressions/__tests__/ShapeSelector.spec.js +107 -0
  32. package/src/components/functions/expressions/__tests__/__snapshots__/ConstantSelector.spec.js.snap +149 -0
  33. package/src/components/functions/expressions/__tests__/__snapshots__/Expression.spec.js.snap +904 -0
  34. package/src/components/functions/expressions/__tests__/__snapshots__/FunctionArgs.spec.js.snap +392 -0
  35. package/src/components/functions/expressions/__tests__/__snapshots__/FunctionSelector.spec.js.snap +377 -0
  36. package/src/components/functions/expressions/__tests__/__snapshots__/ParamSelector.spec.js.snap +95 -0
  37. package/src/components/functions/expressions/__tests__/__snapshots__/ShapeSelector.spec.js.snap +290 -0
  38. package/src/components/functions/expressions/constantInputs/AnySelector.js +29 -0
  39. package/src/components/functions/expressions/constantInputs/BooleanSelector.js +37 -0
  40. package/src/components/functions/expressions/constantInputs/DefaultSelector.js +34 -0
  41. package/src/components/functions/expressions/constantInputs/__tests__/AnySelector.spec.js +63 -0
  42. package/src/components/functions/expressions/constantInputs/__tests__/BooleanSelector.spec.js +51 -0
  43. package/src/components/functions/expressions/constantInputs/__tests__/DefaultSelector.spec.js +56 -0
  44. package/src/components/functions/expressions/constantInputs/__tests__/__snapshots__/AnySelector.spec.js.snap +236 -0
  45. package/src/components/functions/expressions/constantInputs/__tests__/__snapshots__/BooleanSelector.spec.js.snap +101 -0
  46. package/src/components/functions/expressions/constantInputs/__tests__/__snapshots__/DefaultSelector.spec.js.snap +39 -0
  47. package/src/components/functions/expressions/constantInputs/index.js +5 -0
  48. package/src/components/functions/useWatchParams.js +13 -0
  49. package/src/hooks/__tests__/useFunctions.spec.js +101 -0
  50. package/src/hooks/useFunctions.js +33 -0
  51. package/src/styles/Expression.less +102 -0
  52. package/src/types.js +38 -0
@@ -0,0 +1,290 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`<ShapeSelector /> matches the latest snapshot 1`] = `
4
+ <div>
5
+ <div
6
+ aria-expanded="false"
7
+ class="ui top left pointing dropdown"
8
+ role="listbox"
9
+ tabindex="0"
10
+ >
11
+ <div
12
+ class="shape-selector-trigger"
13
+ />
14
+ <div
15
+ class="menu transition"
16
+ >
17
+ <div
18
+ aria-checked="false"
19
+ aria-selected="true"
20
+ class="selected item"
21
+ role="option"
22
+ style="pointer-events: all;"
23
+ >
24
+ <div
25
+ class="text"
26
+ style="display: flex; align-items: center;"
27
+ >
28
+ <small
29
+ style="margin-right: 5px;"
30
+ >
31
+ <b>
32
+ <code>
33
+ [π]
34
+ </code>
35
+ </b>
36
+ </small>
37
+ constant
38
+ </div>
39
+ </div>
40
+ <div
41
+ aria-checked="false"
42
+ aria-selected="false"
43
+ class="item"
44
+ role="option"
45
+ style="pointer-events: all;"
46
+ >
47
+ <div
48
+ class="text"
49
+ style="display: flex; align-items: center;"
50
+ >
51
+ <small
52
+ style="margin-right: 5px;"
53
+ >
54
+ <b>
55
+ <code>
56
+ f(x)
57
+ </code>
58
+ </b>
59
+ </small>
60
+ function
61
+ </div>
62
+ </div>
63
+ </div>
64
+ </div>
65
+ </div>
66
+ `;
67
+
68
+ exports[`<ShapeSelector /> user interaction select constant 1`] = `
69
+ <div>
70
+ <div
71
+ aria-expanded="false"
72
+ class="ui top left pointing dropdown"
73
+ role="listbox"
74
+ tabindex="0"
75
+ >
76
+ <div
77
+ class="shape-selector-trigger"
78
+ >
79
+ [π]
80
+ </div>
81
+ <div
82
+ class="menu transition"
83
+ >
84
+ <div
85
+ aria-checked="true"
86
+ aria-selected="true"
87
+ class="active selected item"
88
+ role="option"
89
+ style="pointer-events: all;"
90
+ >
91
+ <div
92
+ class="text"
93
+ style="display: flex; align-items: center;"
94
+ >
95
+ <small
96
+ style="margin-right: 5px;"
97
+ >
98
+ <b>
99
+ <code>
100
+ [π]
101
+ </code>
102
+ </b>
103
+ </small>
104
+ constant
105
+ </div>
106
+ </div>
107
+ <div
108
+ aria-checked="false"
109
+ aria-selected="false"
110
+ class="item"
111
+ role="option"
112
+ style="pointer-events: all;"
113
+ >
114
+ <div
115
+ class="text"
116
+ style="display: flex; align-items: center;"
117
+ >
118
+ <small
119
+ style="margin-right: 5px;"
120
+ >
121
+ <b>
122
+ <code>
123
+ f(x)
124
+ </code>
125
+ </b>
126
+ </small>
127
+ function
128
+ </div>
129
+ </div>
130
+ </div>
131
+ </div>
132
+ </div>
133
+ `;
134
+
135
+ exports[`<ShapeSelector /> user interaction select function 1`] = `
136
+ <div>
137
+ <div
138
+ aria-expanded="false"
139
+ class="ui top left pointing dropdown"
140
+ role="listbox"
141
+ tabindex="0"
142
+ >
143
+ <div
144
+ class="shape-selector-trigger"
145
+ >
146
+ f(x)
147
+ </div>
148
+ <div
149
+ class="menu transition"
150
+ >
151
+ <div
152
+ aria-checked="false"
153
+ aria-selected="false"
154
+ class="item"
155
+ role="option"
156
+ style="pointer-events: all;"
157
+ >
158
+ <div
159
+ class="text"
160
+ style="display: flex; align-items: center;"
161
+ >
162
+ <small
163
+ style="margin-right: 5px;"
164
+ >
165
+ <b>
166
+ <code>
167
+ [π]
168
+ </code>
169
+ </b>
170
+ </small>
171
+ constant
172
+ </div>
173
+ </div>
174
+ <div
175
+ aria-checked="true"
176
+ aria-selected="true"
177
+ class="active selected item"
178
+ role="option"
179
+ style="pointer-events: all;"
180
+ >
181
+ <div
182
+ class="text"
183
+ style="display: flex; align-items: center;"
184
+ >
185
+ <small
186
+ style="margin-right: 5px;"
187
+ >
188
+ <b>
189
+ <code>
190
+ f(x)
191
+ </code>
192
+ </b>
193
+ </small>
194
+ function
195
+ </div>
196
+ </div>
197
+ </div>
198
+ </div>
199
+ </div>
200
+ `;
201
+
202
+ exports[`<ShapeSelector /> user interaction select param 1`] = `
203
+ <div>
204
+ <div
205
+ aria-expanded="false"
206
+ class="ui top left pointing dropdown"
207
+ role="listbox"
208
+ tabindex="0"
209
+ >
210
+ <div
211
+ class="shape-selector-trigger"
212
+ >
213
+ [P]
214
+ </div>
215
+ <div
216
+ class="menu transition"
217
+ >
218
+ <div
219
+ aria-checked="false"
220
+ aria-selected="false"
221
+ class="item"
222
+ role="option"
223
+ style="pointer-events: all;"
224
+ >
225
+ <div
226
+ class="text"
227
+ style="display: flex; align-items: center;"
228
+ >
229
+ <small
230
+ style="margin-right: 5px;"
231
+ >
232
+ <b>
233
+ <code>
234
+ [π]
235
+ </code>
236
+ </b>
237
+ </small>
238
+ constant
239
+ </div>
240
+ </div>
241
+ <div
242
+ aria-checked="false"
243
+ aria-selected="false"
244
+ class="item"
245
+ role="option"
246
+ style="pointer-events: all;"
247
+ >
248
+ <div
249
+ class="text"
250
+ style="display: flex; align-items: center;"
251
+ >
252
+ <small
253
+ style="margin-right: 5px;"
254
+ >
255
+ <b>
256
+ <code>
257
+ f(x)
258
+ </code>
259
+ </b>
260
+ </small>
261
+ function
262
+ </div>
263
+ </div>
264
+ <div
265
+ aria-checked="true"
266
+ aria-selected="true"
267
+ class="active selected item"
268
+ role="option"
269
+ style="pointer-events: all;"
270
+ >
271
+ <div
272
+ class="text"
273
+ style="display: flex; align-items: center;"
274
+ >
275
+ <small
276
+ style="margin-right: 5px;"
277
+ >
278
+ <b>
279
+ <code>
280
+ [P]
281
+ </code>
282
+ </b>
283
+ </small>
284
+ param
285
+ </div>
286
+ </div>
287
+ </div>
288
+ </div>
289
+ </div>
290
+ `;
@@ -0,0 +1,29 @@
1
+ import React, { useContext, useState } from "react";
2
+ import { useFormContext } from "react-hook-form";
3
+ import { TypeSelector } from "@truedat/qx/components/common";
4
+ import QxContext from "@truedat/qx/components/QxContext";
5
+ const ConstantSelector = React.lazy(() => import("../ConstantSelector"));
6
+
7
+ export default function AnySelector() {
8
+ const context = useContext(QxContext);
9
+ const { watch, setValue } = useFormContext();
10
+ const [type, setType] = useState(watch(`${context.field}.value.type`));
11
+
12
+ return (
13
+ <>
14
+ <TypeSelector
15
+ value={type}
16
+ onChange={(_e, { value }) => {
17
+ setType(value);
18
+ setValue(`${context.field}.value.value`, "");
19
+ }}
20
+ withoutTypeAny
21
+ />
22
+ {type ? (
23
+ <QxContext.Provider value={{ ...context, type }}>
24
+ <ConstantSelector />
25
+ </QxContext.Provider>
26
+ ) : null}
27
+ </>
28
+ );
29
+ }
@@ -0,0 +1,37 @@
1
+ import React, { useContext } from "react";
2
+ import { useIntl } from "react-intl";
3
+ import { Controller, useFormContext } from "react-hook-form";
4
+ import { Dropdown } from "semantic-ui-react";
5
+ import QxContext from "@truedat/qx/components/QxContext";
6
+
7
+ export default function BooleanSelector() {
8
+ const { formatMessage } = useIntl();
9
+ const { field } = useContext(QxContext);
10
+ const { control } = useFormContext();
11
+
12
+ return (
13
+ <Controller
14
+ control={control}
15
+ name={`${field}.value.value`}
16
+ rules={{ required: true }}
17
+ render={({
18
+ field: { onBlur, onChange, value },
19
+ fieldState: { error },
20
+ }) => (
21
+ <Dropdown
22
+ fluid
23
+ selection
24
+ error={!!error}
25
+ onBlur={onBlur}
26
+ options={["true", "false"].map((v) => ({
27
+ key: v,
28
+ value: v,
29
+ text: formatMessage({ id: `functions.expression.constant.${v}` }),
30
+ }))}
31
+ value={value}
32
+ onChange={(_e, { value }) => onChange(value)}
33
+ />
34
+ )}
35
+ />
36
+ );
37
+ }
@@ -0,0 +1,34 @@
1
+ import React, { useContext } from "react";
2
+ import { useIntl } from "react-intl";
3
+ import { Form } from "semantic-ui-react";
4
+ import { Controller, useFormContext } from "react-hook-form";
5
+ import QxContext from "@truedat/qx/components/QxContext";
6
+
7
+ export default function DefaultSelector() {
8
+ const { formatMessage } = useIntl();
9
+ const { field } = useContext(QxContext);
10
+ const { control } = useFormContext();
11
+
12
+ return (
13
+ <Controller
14
+ control={control}
15
+ name={`${field}.value.value`}
16
+ rules={{
17
+ required: formatMessage({ id: "functions.form.required" }),
18
+ }}
19
+ render={({
20
+ field: { onBlur, onChange, value },
21
+ fieldState: { error },
22
+ }) => (
23
+ <Form.Input
24
+ autoComplete="off"
25
+ error={error?.message}
26
+ onBlur={onBlur}
27
+ onChange={(_e, { value }) => onChange(value)}
28
+ value={value}
29
+ required
30
+ />
31
+ )}
32
+ />
33
+ );
34
+ }
@@ -0,0 +1,63 @@
1
+ import React from "react";
2
+ import { render } from "@truedat/test/render";
3
+ import userEvent from "@testing-library/user-event";
4
+ import TestFormWrapper from "@truedat/qx/components/common/TestFormWrapper";
5
+ import AnySelector from "../AnySelector";
6
+
7
+ describe("<AnySelector />", () => {
8
+ it("matches the latest snapshot", () => {
9
+ const { container } = render(
10
+ <TestFormWrapper>
11
+ <AnySelector />
12
+ </TestFormWrapper>
13
+ );
14
+ expect(container).toMatchSnapshot();
15
+ });
16
+
17
+ it("user interaction", async () => {
18
+ const renderOpts = {
19
+ messages: {
20
+ en: {
21
+ "functions.expression.constant.false": "false",
22
+ "functions.expression.constant.true": "true",
23
+ "functions.form.required": "required",
24
+ },
25
+ },
26
+ fallback: "lazy",
27
+ };
28
+
29
+ const watcher = jest.fn();
30
+
31
+ const { container, findByText } = render(
32
+ <TestFormWrapper watcher={watcher}>
33
+ <AnySelector />
34
+ </TestFormWrapper>,
35
+ renderOpts
36
+ );
37
+
38
+ userEvent.click(await findByText("boolean"));
39
+ userEvent.click(await findByText("true"));
40
+
41
+ expect(watcher).lastCalledWith({
42
+ test: {
43
+ value: {
44
+ type: "boolean",
45
+ value: "true",
46
+ },
47
+ },
48
+ });
49
+
50
+ userEvent.click(await findByText("string"));
51
+
52
+ expect(watcher).lastCalledWith({
53
+ test: {
54
+ value: {
55
+ type: "string",
56
+ value: "",
57
+ },
58
+ },
59
+ });
60
+
61
+ expect(container).toMatchSnapshot();
62
+ });
63
+ });
@@ -0,0 +1,51 @@
1
+ import React from "react";
2
+ import { render } from "@truedat/test/render";
3
+ import userEvent from "@testing-library/user-event";
4
+ import TestFormWrapper from "@truedat/qx/components/common/TestFormWrapper";
5
+ import BooleanSelector from "../BooleanSelector";
6
+
7
+ describe("<BooleanSelector />", () => {
8
+ const renderOpts = {
9
+ messages: {
10
+ en: {
11
+ "functions.expression.constant.false": "false",
12
+ "functions.expression.constant.true": "true",
13
+ "functions.form.required": "required",
14
+ },
15
+ },
16
+ fallback: "lazy",
17
+ };
18
+
19
+ it("matches the latest snapshot", () => {
20
+ const { container } = render(
21
+ <TestFormWrapper>
22
+ <BooleanSelector />
23
+ </TestFormWrapper>,
24
+ renderOpts
25
+ );
26
+ expect(container).toMatchSnapshot();
27
+ });
28
+
29
+ it("user interaction", () => {
30
+ const watcher = jest.fn();
31
+ const { container, getByRole } = render(
32
+ <TestFormWrapper watcher={watcher}>
33
+ <BooleanSelector />
34
+ </TestFormWrapper>,
35
+ renderOpts
36
+ );
37
+
38
+ userEvent.click(getByRole("listbox"));
39
+ userEvent.click(getByRole("option", { name: /true/i }));
40
+
41
+ expect(watcher).lastCalledWith({
42
+ test: {
43
+ value: {
44
+ value: "true",
45
+ },
46
+ },
47
+ });
48
+
49
+ expect(container).toMatchSnapshot();
50
+ });
51
+ });
@@ -0,0 +1,56 @@
1
+ import React from "react";
2
+ import { render } from "@truedat/test/render";
3
+ import userEvent from "@testing-library/user-event";
4
+ import TestFormWrapper from "@truedat/qx/components/common/TestFormWrapper";
5
+ import DefaultSelector from "../DefaultSelector";
6
+
7
+ describe("<DefaultSelector />", () => {
8
+ const renderOpts = {
9
+ messages: {
10
+ en: {
11
+ "functions.form.required": "required",
12
+ },
13
+ },
14
+ fallback: "lazy",
15
+ };
16
+
17
+ it("matches the latest snapshot", () => {
18
+ const { container } = render(
19
+ <TestFormWrapper>
20
+ <DefaultSelector />
21
+ </TestFormWrapper>,
22
+ renderOpts
23
+ );
24
+ expect(container).toMatchSnapshot();
25
+ });
26
+
27
+ it("user interaction", async () => {
28
+ const watcher = jest.fn();
29
+ const field = "test";
30
+ const defaultValues = {
31
+ [field]: { value: { value: "" } },
32
+ };
33
+ const { container, findByRole } = render(
34
+ <TestFormWrapper
35
+ watcher={watcher}
36
+ defaultValues={defaultValues}
37
+ field={field}
38
+ >
39
+ <DefaultSelector />
40
+ </TestFormWrapper>,
41
+ renderOpts
42
+ );
43
+
44
+ userEvent.type(await findByRole("textbox"), "text");
45
+
46
+ expect(watcher).lastCalledWith({
47
+ test: {
48
+ value: {
49
+ value: "text",
50
+ },
51
+ },
52
+ });
53
+
54
+ expect(container).toMatchSnapshot();
55
+ });
56
+ });