@truedat/qx 8.10.2 → 8.10.4

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 (61) hide show
  1. package/package.json +3 -3
  2. package/src/components/QxRoutes.js +8 -7
  3. package/src/components/__tests__/QxRoutes.spec.js +2 -1
  4. package/src/components/__tests__/__fixtures__/helper.js +13 -0
  5. package/src/components/__tests__/__snapshots__/QxRoutes.spec.js.snap +1 -1
  6. package/src/components/common/ClauseViewer.js +52 -8
  7. package/src/components/common/DescriptionInput.js +9 -34
  8. package/src/components/common/TypeSelector.js +20 -10
  9. package/src/components/common/__tests__/ClauseViewer.spec.js +150 -0
  10. package/src/components/common/__tests__/DescriptionInput.spec.js +2 -5
  11. package/src/components/common/__tests__/__snapshots__/DescriptionInput.spec.js.snap +7 -10
  12. package/src/components/common/expressions/Clauses.js +22 -17
  13. package/src/components/common/expressions/Condition.js +201 -102
  14. package/src/components/common/expressions/Expression.js +17 -23
  15. package/src/components/common/expressions/FunctionSelector.js +3 -3
  16. package/src/components/common/expressions/ShapeSelector.js +1 -1
  17. package/src/components/common/expressions/__tests__/Clauses.spec.js +1 -1
  18. package/src/components/common/expressions/__tests__/Condition.spec.js +83 -26
  19. package/src/components/common/expressions/__tests__/ParamSelector.spec.js +1 -1
  20. package/src/components/common/expressions/__tests__/__snapshots__/Clauses.spec.js.snap +18 -22
  21. package/src/components/common/expressions/__tests__/__snapshots__/Condition.spec.js.snap +215 -216
  22. package/src/components/common/expressions/__tests__/__snapshots__/ConstantSelector.spec.js.snap +6 -10
  23. package/src/components/common/expressions/__tests__/__snapshots__/Expression.spec.js.snap +630 -654
  24. package/src/components/common/expressions/__tests__/__snapshots__/FunctionArgs.spec.js.snap +193 -201
  25. package/src/components/common/expressions/__tests__/__snapshots__/FunctionSelector.spec.js.snap +450 -466
  26. package/src/components/common/expressions/__tests__/__snapshots__/ShapeSelector.spec.js.snap +34 -34
  27. package/src/components/common/expressions/constantInputs/AnySelector.js +1 -0
  28. package/src/components/common/expressions/constantInputs/__tests__/__snapshots__/AnySelector.spec.js.snap +15 -15
  29. package/src/components/dataViews/__tests__/__snapshots__/AdvancedDataViewEditor.spec.js.snap +378 -406
  30. package/src/components/dataViews/__tests__/__snapshots__/DataViewSummary.spec.js.snap +6 -6
  31. package/src/components/dataViews/__tests__/__snapshots__/Queryable.spec.js.snap +489 -577
  32. package/src/components/dataViews/__tests__/__snapshots__/Queryables.spec.js.snap +400 -476
  33. package/src/components/dataViews/advancedForm/Queryable.js +56 -64
  34. package/src/components/dataViews/advancedForm/Queryables.js +11 -2
  35. package/src/components/dataViews/queryableProperties/Join.js +16 -6
  36. package/src/components/dataViews/queryableProperties/__tests__/__snapshots__/Join.spec.js.snap +0 -28
  37. package/src/components/dataViews/queryableProperties/__tests__/__snapshots__/Select.spec.js.snap +270 -282
  38. package/src/components/dataViews/queryableProperties/__tests__/__snapshots__/SelectField.spec.js.snap +172 -180
  39. package/src/components/dataViews/simpleForm/DatasetForm.js +4 -0
  40. package/src/components/dataViews/simpleForm/FormQueryable.js +49 -53
  41. package/src/components/dataViews/summary/Where.js +3 -2
  42. package/src/components/functions/FunctionEdit.js +92 -0
  43. package/src/components/functions/FunctionEditor.js +32 -10
  44. package/src/components/functions/FunctionParams.js +54 -61
  45. package/src/components/functions/FunctionsList.js +213 -0
  46. package/src/components/functions/__tests__/FunctionEdit.spec.js +168 -0
  47. package/src/components/functions/__tests__/FunctionParams.spec.js +1 -8
  48. package/src/components/functions/__tests__/FunctionsList.spec.js +62 -0
  49. package/src/components/functions/__tests__/__snapshots__/FunctionEditor.spec.js.snap +553 -469
  50. package/src/components/functions/__tests__/__snapshots__/FunctionParams.spec.js.snap +139 -161
  51. package/src/components/functions/__tests__/__snapshots__/FunctionsList.spec.js.snap +588 -0
  52. package/src/components/qualityControls/__tests__/NewQualityControl.spec.js +4 -0
  53. package/src/components/qualityControls/__tests__/QualityControlEditor.spec.js +8 -1
  54. package/src/components/qualityControls/__tests__/__snapshots__/EditQualityControl.spec.js.snap +109 -118
  55. package/src/components/qualityControls/__tests__/__snapshots__/NewDraftQualityControl.spec.js.snap +109 -118
  56. package/src/components/qualityControls/__tests__/__snapshots__/QualityControlEditor.spec.js.snap +471 -468
  57. package/src/hooks/useFunctions.js +6 -0
  58. package/src/styles/Expression.less +39 -6
  59. package/src/components/functions/Functions.js +0 -143
  60. package/src/components/functions/__tests__/Functions.spec.js +0 -56
  61. package/src/components/functions/__tests__/__snapshots__/Functions.spec.js.snap +0 -85
@@ -31,3 +31,9 @@ export const useFunctionDelete = (func) => {
31
31
  const url = compile(API_FUNCTION)({ id: `${id}` });
32
32
  return useSWRMutations(url, (url, { arg }) => apiJsonDelete(url, arg));
33
33
  };
34
+
35
+ export const useFunctionFetch = (id) => {
36
+ const url = id ? compile(API_FUNCTION)({ id: `${id}` }) : null;
37
+ const { data, error } = useSWR(url, apiJson);
38
+ return { data: data?.data, error, loading: !error && !data };
39
+ };
@@ -30,21 +30,33 @@
30
30
  display: flex;
31
31
  flex-direction: row;
32
32
  align-items: flex-start;
33
+
34
+ .expression-content {
35
+ flex: 1;
36
+ min-width: 0;
37
+ display: flex;
38
+ flex-direction: row;
39
+ align-items: flex-start;
40
+ }
33
41
  }
34
42
 
35
- .shape-selector-trigger {
43
+ .shape-selector-trigger,
44
+ .type-selector-trigger {
36
45
  width: 38px;
37
46
  height: 38px;
38
47
  border: 1px solid rgba(34, 36, 38, 0.15);
39
48
  border-radius: 4px;
40
- font-size: 12px;
41
- font-weight: bold;
42
- font-family: monospace;
43
49
  display: flex;
44
50
  align-items: center;
45
51
  justify-content: center;
46
52
  }
47
53
 
54
+ .shape-selector-trigger {
55
+ font-size: 12px;
56
+ font-weight: bold;
57
+ font-family: monospace;
58
+ }
59
+
48
60
  .shape-icon {
49
61
  font-size: 12px;
50
62
  font-weight: bold;
@@ -127,8 +139,26 @@ ul.function-tree {
127
139
 
128
140
  .condition-row {
129
141
  display: flex;
130
- justify-content: space-evenly;
131
- align-items: center;
142
+ align-items: flex-start;
143
+ gap: 4px;
144
+
145
+ .condition-fields {
146
+ flex: 1;
147
+ display: flex;
148
+ flex-direction: row;
149
+ gap: 4px;
150
+ min-width: 0;
151
+ }
152
+
153
+ .condition-arg-field {
154
+ flex: 1 1 0;
155
+ min-width: 0;
156
+ }
157
+
158
+ .condition-operator-field {
159
+ flex: 0 0 12%;
160
+ min-width: 0;
161
+ }
132
162
  }
133
163
 
134
164
  .condition-operator-trigger {
@@ -156,6 +186,9 @@ ul.function-tree {
156
186
  display: flex;
157
187
  align-items: center;
158
188
  justify-content: flex-end;
189
+ flex-shrink: 0;
190
+ width: 2rem;
191
+ padding-top: 2px;
159
192
  }
160
193
 
161
194
  .join_type {
@@ -1,143 +0,0 @@
1
- import _ from "lodash/fp";
2
- import { useState } from "react";
3
- import { useIntl, FormattedMessage } from "react-intl";
4
- import {
5
- Button,
6
- Grid,
7
- GridColumn,
8
- Header,
9
- Icon,
10
- List,
11
- Segment,
12
- } from "semantic-ui-react";
13
-
14
- import { typeLabel } from "@truedat/qx/types";
15
- import {
16
- useFunctions,
17
- useFunctionCreate,
18
- useFunctionDelete,
19
- useFunctionUpdate,
20
- } from "@truedat/qx/hooks/useFunctions";
21
- import FunctionEditor from "./FunctionEditor";
22
-
23
- const NEW_FUNCTION = {
24
- name: "",
25
- description: "",
26
- type: "boolean",
27
- params: [],
28
- expression: { shape: "function", value: null },
29
- };
30
-
31
- export default function Functions() {
32
- const { formatMessage } = useIntl();
33
- const { data, loading, mutate } = useFunctions();
34
- const [selectedFunction, setSelectedFunction] = useState();
35
- const [isDirty, setDirty] = useState(false);
36
-
37
- const functions = data?.data;
38
- const userFunctions = _.reject(({ expression }) => _.isNil(expression))(
39
- functions,
40
- );
41
-
42
- const changeSelectedFunction = (selection) => {
43
- setSelectedFunction(null);
44
- setSelectedFunction(selection);
45
- };
46
- const setStateNewFunction = () => changeSelectedFunction(NEW_FUNCTION);
47
- const clearForm = () => {
48
- setSelectedFunction(null);
49
- setDirty(false);
50
- };
51
-
52
- const { trigger: createFunction, isMutating: isCreating } =
53
- useFunctionCreate();
54
-
55
- const { trigger: updateFunction, isMutating: isUpdating } =
56
- useFunctionUpdate(selectedFunction);
57
-
58
- const { trigger: deleteFunction, isMutating: isDeleting } =
59
- useFunctionDelete(selectedFunction);
60
-
61
- const isSubmitting = isCreating || isUpdating || isDeleting;
62
- const onFunctionCreate = (func) => {
63
- const mutateFunction = selectedFunction?.id
64
- ? updateFunction
65
- : createFunction;
66
- mutateFunction({ function: func }).then(() => {
67
- clearForm();
68
- mutate();
69
- });
70
- };
71
- const onFunctionDelete = (func) => {
72
- deleteFunction({ function: func }).then(() => {
73
- clearForm();
74
- mutate();
75
- });
76
- };
77
- return (
78
- <Segment loading={loading}>
79
- <Header as="h2">
80
- <Icon circular name="archive" />
81
- <Header.Content>
82
- <FormattedMessage id="functions.header" />
83
- <Header.Subheader>
84
- <FormattedMessage id="functions.subheader" />
85
- </Header.Subheader>
86
- </Header.Content>
87
- </Header>
88
- <Grid>
89
- <GridColumn width={4}>
90
- <Button fluid onClick={setStateNewFunction} disabled={isDirty}>
91
- {formatMessage({ id: "functions.action.new" })}
92
- </Button>
93
- <List divided selection={!isDirty}>
94
- {!_.isEmpty(userFunctions) ? (
95
- userFunctions.map((func, key) => (
96
- <List.Item
97
- key={key}
98
- onClick={() => !isDirty && changeSelectedFunction(func)}
99
- >
100
- <List.Content>
101
- <List.Header>
102
- {typeLabel(func.type)}
103
- {func.name || "Function"}/{func.params.length}
104
- </List.Header>
105
- </List.Content>
106
- </List.Item>
107
- ))
108
- ) : (
109
- <List.Item>
110
- <List.Content>
111
- <List.Header>
112
- {formatMessage({ id: "functions.empty_list" })}
113
- </List.Header>
114
- </List.Content>
115
- </List.Item>
116
- )}
117
- </List>
118
- </GridColumn>
119
- <GridColumn width={11}>
120
- {selectedFunction ? (
121
- <FunctionEditor
122
- key={selectedFunction?.id || "new"}
123
- selectedFunction={selectedFunction}
124
- functions={functions}
125
- onCancel={clearForm}
126
- onSubmit={onFunctionCreate}
127
- onDelete={selectedFunction?.id ? onFunctionDelete : null}
128
- isSubmitting={isSubmitting}
129
- setDirty={setDirty}
130
- />
131
- ) : (
132
- <Header as="h2" icon textAlign="center">
133
- <Icon name="hand pointer outline" />
134
- <Header.Subheader>
135
- {formatMessage({ id: "functions.no_selection" })}
136
- </Header.Subheader>
137
- </Header>
138
- )}
139
- </GridColumn>
140
- </Grid>
141
- </Segment>
142
- );
143
- }
@@ -1,56 +0,0 @@
1
- import userEvent from "@testing-library/user-event";
2
- import { render, waitForLoad } from "@truedat/test/render";
3
- import Functions from "../Functions";
4
-
5
- jest.mock("@truedat/qx/hooks/useFunctions", () => {
6
- const originalModule = jest.requireActual("@truedat/qx/hooks/useFunctions");
7
-
8
- return {
9
- __esModule: true,
10
- ...originalModule,
11
- useFunctions: jest.fn(() => ({
12
- data: {
13
- data: [
14
- {
15
- name: "eq",
16
- type: "boolean",
17
- params: [
18
- { name: "arg1", type: "any" },
19
- { name: "arg2", type: "any" },
20
- ],
21
- },
22
- {
23
- name: "user_false",
24
- type: "boolean",
25
- params: [],
26
- expression: {
27
- shape: "constant",
28
- value: { type: "boolean", value: "false" },
29
- },
30
- },
31
- ],
32
- },
33
- loading: false,
34
- })),
35
- useFunctionCreate: jest.fn(() => ({
36
- trigger: jest.fn(() => new Promise(() => {})),
37
- isMutating: false,
38
- })),
39
- useFunctionDelete: jest.fn(() => ({
40
- trigger: jest.fn(() => new Promise(() => {})),
41
- isMutating: false,
42
- })),
43
- useFunctionUpdate: jest.fn(() => ({
44
- trigger: jest.fn(() => new Promise(() => {})),
45
- isMutating: false,
46
- })),
47
- };
48
- });
49
-
50
- describe("<Functions />", () => {
51
- it("matches the latest snapshot", async () => {
52
- const rendered = render(<Functions />);
53
- await waitForLoad(rendered);
54
- expect(rendered.container).toMatchSnapshot();
55
- });
56
- });
@@ -1,85 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`<Functions /> matches the latest snapshot 1`] = `
4
- <div>
5
- <div
6
- class="ui segment"
7
- >
8
- <h2
9
- class="ui header"
10
- >
11
- <i
12
- aria-hidden="true"
13
- class="archive circular icon"
14
- />
15
- <div
16
- class="content"
17
- >
18
- functions.header
19
- <div
20
- class="sub header"
21
- >
22
- functions.subheader
23
- </div>
24
- </div>
25
- </h2>
26
- <div
27
- class="ui grid"
28
- >
29
- <div
30
- class="four wide column"
31
- >
32
- <button
33
- class="ui fluid button"
34
- >
35
- functions.action.new
36
- </button>
37
- <div
38
- class="ui divided selection list"
39
- role="list"
40
- >
41
- <div
42
- class="item"
43
- role="listitem"
44
- >
45
- <div
46
- class="content"
47
- >
48
- <div
49
- class="header"
50
- >
51
- <div
52
- class="ui teal tiny circular label"
53
- width="100px"
54
- >
55
- b
56
- </div>
57
- user_false
58
- /
59
- 0
60
- </div>
61
- </div>
62
- </div>
63
- </div>
64
- </div>
65
- <div
66
- class="eleven wide column"
67
- >
68
- <h2
69
- class="ui icon center aligned header"
70
- >
71
- <i
72
- aria-hidden="true"
73
- class="hand pointer outline icon"
74
- />
75
- <div
76
- class="sub header"
77
- >
78
- functions.no_selection
79
- </div>
80
- </h2>
81
- </div>
82
- </div>
83
- </div>
84
- </div>
85
- `;