@cubejs-client/playground 1.1.12 → 1.1.17

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 (193) hide show
  1. package/build/assets/{index-wSty61qr.js → index-DgSEz9T1.js} +613 -779
  2. package/build/index.html +1 -1
  3. package/build/vizard/download/react-typescript-antd-table.zip +0 -0
  4. package/build/vizard/download/react-typescript-chartjs-area+bar+doughnut+line+pie.zip +0 -0
  5. package/lib/.tsbuildinfo +1 -1
  6. package/lib/App.js +1 -1
  7. package/lib/App.js.map +1 -1
  8. package/lib/QueryBuilderV2/QueryBuilder.d.ts +4 -0
  9. package/lib/QueryBuilderV2/QueryBuilder.js +12 -9
  10. package/lib/QueryBuilderV2/QueryBuilder.js.map +1 -1
  11. package/lib/QueryBuilderV2/QueryBuilderChart.js +2 -2
  12. package/lib/QueryBuilderV2/QueryBuilderChart.js.map +1 -1
  13. package/lib/QueryBuilderV2/QueryBuilderChartResults.js +4 -4
  14. package/lib/QueryBuilderV2/QueryBuilderChartResults.js.map +1 -1
  15. package/lib/QueryBuilderV2/QueryBuilderError.js +1 -3
  16. package/lib/QueryBuilderV2/QueryBuilderError.js.map +1 -1
  17. package/lib/QueryBuilderV2/QueryBuilderExtras.d.ts +1 -0
  18. package/lib/QueryBuilderV2/QueryBuilderExtras.js +39 -18
  19. package/lib/QueryBuilderV2/QueryBuilderExtras.js.map +1 -1
  20. package/lib/QueryBuilderV2/QueryBuilderFilters.js +88 -84
  21. package/lib/QueryBuilderV2/QueryBuilderFilters.js.map +1 -1
  22. package/lib/QueryBuilderV2/QueryBuilderGraphQL.js +1 -1
  23. package/lib/QueryBuilderV2/QueryBuilderGraphQL.js.map +1 -1
  24. package/lib/QueryBuilderV2/QueryBuilderInternals.js +7 -10
  25. package/lib/QueryBuilderV2/QueryBuilderInternals.js.map +1 -1
  26. package/lib/QueryBuilderV2/QueryBuilderResults.js +87 -45
  27. package/lib/QueryBuilderV2/QueryBuilderResults.js.map +1 -1
  28. package/lib/QueryBuilderV2/QueryBuilderSidePanel.d.ts +4 -3
  29. package/lib/QueryBuilderV2/QueryBuilderSidePanel.js +95 -54
  30. package/lib/QueryBuilderV2/QueryBuilderSidePanel.js.map +1 -1
  31. package/lib/QueryBuilderV2/components/Accordion/AccordionItemTitle.js +1 -1
  32. package/lib/QueryBuilderV2/components/Accordion/AccordionItemTitle.js.map +1 -1
  33. package/lib/QueryBuilderV2/components/AddFilterInput.d.ts +10 -0
  34. package/lib/QueryBuilderV2/components/AddFilterInput.js +195 -0
  35. package/lib/QueryBuilderV2/components/AddFilterInput.js.map +1 -0
  36. package/lib/QueryBuilderV2/components/Badge.d.ts +3 -2
  37. package/lib/QueryBuilderV2/components/Badge.js +4 -3
  38. package/lib/QueryBuilderV2/components/Badge.js.map +1 -1
  39. package/lib/QueryBuilderV2/components/ChartRenderer.js +0 -1
  40. package/lib/QueryBuilderV2/components/ChartRenderer.js.map +1 -1
  41. package/lib/QueryBuilderV2/components/DateRangeFilter.d.ts +7 -0
  42. package/lib/QueryBuilderV2/components/DateRangeFilter.js +25 -4
  43. package/lib/QueryBuilderV2/components/DateRangeFilter.js.map +1 -1
  44. package/lib/QueryBuilderV2/components/EditQueryDialogForm.js +18 -20
  45. package/lib/QueryBuilderV2/components/EditQueryDialogForm.js.map +1 -1
  46. package/lib/QueryBuilderV2/components/FilterByMemberButton.d.ts +6 -1
  47. package/lib/QueryBuilderV2/components/FilterByMemberButton.js +16 -6
  48. package/lib/QueryBuilderV2/components/FilterByMemberButton.js.map +1 -1
  49. package/lib/QueryBuilderV2/components/FilterLabel.d.ts +9 -0
  50. package/lib/QueryBuilderV2/components/FilterLabel.js +18 -4
  51. package/lib/QueryBuilderV2/components/FilterLabel.js.map +1 -1
  52. package/lib/QueryBuilderV2/components/FilterMember.d.ts +19 -0
  53. package/lib/QueryBuilderV2/components/FilterMember.js +137 -0
  54. package/lib/QueryBuilderV2/components/FilterMember.js.map +1 -0
  55. package/lib/QueryBuilderV2/components/FilterOptionsButton.d.ts +8 -0
  56. package/lib/QueryBuilderV2/components/FilterOptionsButton.js +54 -0
  57. package/lib/QueryBuilderV2/components/FilterOptionsButton.js.map +1 -0
  58. package/lib/QueryBuilderV2/components/FilteredLabel.js +10 -2
  59. package/lib/QueryBuilderV2/components/FilteredLabel.js.map +1 -1
  60. package/lib/QueryBuilderV2/components/Folder.d.ts +9 -0
  61. package/lib/QueryBuilderV2/components/Folder.js +47 -0
  62. package/lib/QueryBuilderV2/components/Folder.js.map +1 -0
  63. package/lib/QueryBuilderV2/components/GranularityListMember.d.ts +3 -0
  64. package/lib/QueryBuilderV2/components/GranularityListMember.js +5 -14
  65. package/lib/QueryBuilderV2/components/GranularityListMember.js.map +1 -1
  66. package/lib/QueryBuilderV2/components/HierarchyMember.d.ts +14 -0
  67. package/lib/QueryBuilderV2/components/HierarchyMember.js +47 -0
  68. package/lib/QueryBuilderV2/components/HierarchyMember.js.map +1 -0
  69. package/lib/QueryBuilderV2/components/InstanceTooltipProvider.d.ts +15 -0
  70. package/lib/QueryBuilderV2/components/InstanceTooltipProvider.js +36 -0
  71. package/lib/QueryBuilderV2/components/InstanceTooltipProvider.js.map +1 -0
  72. package/lib/QueryBuilderV2/components/ListButton.d.ts +341 -11
  73. package/lib/QueryBuilderV2/components/ListButton.js +2 -1
  74. package/lib/QueryBuilderV2/components/ListButton.js.map +1 -1
  75. package/lib/QueryBuilderV2/components/ListCube.js +2 -2
  76. package/lib/QueryBuilderV2/components/ListCube.js.map +1 -1
  77. package/lib/QueryBuilderV2/components/ListMember.d.ts +11 -2
  78. package/lib/QueryBuilderV2/components/ListMember.js +39 -29
  79. package/lib/QueryBuilderV2/components/ListMember.js.map +1 -1
  80. package/lib/QueryBuilderV2/components/ListMemberButton.d.ts +341 -11
  81. package/lib/QueryBuilderV2/components/ListMemberButton.js +8 -1
  82. package/lib/QueryBuilderV2/components/ListMemberButton.js.map +1 -1
  83. package/lib/QueryBuilderV2/components/LogicalFilter.d.ts +12 -0
  84. package/lib/QueryBuilderV2/components/LogicalFilter.js +152 -0
  85. package/lib/QueryBuilderV2/components/LogicalFilter.js.map +1 -0
  86. package/lib/QueryBuilderV2/components/MemberLabel.d.ts +11 -1
  87. package/lib/QueryBuilderV2/components/MemberLabel.js +14 -6
  88. package/lib/QueryBuilderV2/components/MemberLabel.js.map +1 -1
  89. package/lib/QueryBuilderV2/components/MemberLabelText.js +11 -4
  90. package/lib/QueryBuilderV2/components/MemberLabelText.js.map +1 -1
  91. package/lib/QueryBuilderV2/components/ReorderableList.d.ts +20 -0
  92. package/lib/QueryBuilderV2/components/ReorderableList.js +173 -0
  93. package/lib/QueryBuilderV2/components/ReorderableList.js.map +1 -0
  94. package/lib/QueryBuilderV2/components/ScrollableArea.d.ts +354 -1
  95. package/lib/QueryBuilderV2/components/SegmentFilter.d.ts +7 -0
  96. package/lib/QueryBuilderV2/components/SegmentFilter.js +30 -4
  97. package/lib/QueryBuilderV2/components/SegmentFilter.js.map +1 -1
  98. package/lib/QueryBuilderV2/components/SidePanelCubeItem.d.ts +4 -5
  99. package/lib/QueryBuilderV2/components/SidePanelCubeItem.js +380 -130
  100. package/lib/QueryBuilderV2/components/SidePanelCubeItem.js.map +1 -1
  101. package/lib/QueryBuilderV2/components/TimeListMember.d.ts +20 -5
  102. package/lib/QueryBuilderV2/components/TimeListMember.js +95 -49
  103. package/lib/QueryBuilderV2/components/TimeListMember.js.map +1 -1
  104. package/lib/QueryBuilderV2/components/ValuesInput.d.ts +4 -0
  105. package/lib/QueryBuilderV2/components/ValuesInput.js +65 -41
  106. package/lib/QueryBuilderV2/components/ValuesInput.js.map +1 -1
  107. package/lib/QueryBuilderV2/hooks/dimension-values.d.ts +13 -0
  108. package/lib/QueryBuilderV2/hooks/dimension-values.js +62 -0
  109. package/lib/QueryBuilderV2/hooks/dimension-values.js.map +1 -0
  110. package/lib/QueryBuilderV2/hooks/filtered-cubes.d.ts +6 -2
  111. package/lib/QueryBuilderV2/hooks/filtered-cubes.js +26 -8
  112. package/lib/QueryBuilderV2/hooks/filtered-cubes.js.map +1 -1
  113. package/lib/QueryBuilderV2/hooks/filtered-members.d.ts +10 -4
  114. package/lib/QueryBuilderV2/hooks/filtered-members.js +57 -20
  115. package/lib/QueryBuilderV2/hooks/filtered-members.js.map +1 -1
  116. package/lib/QueryBuilderV2/hooks/has-overflow.d.ts +1 -1
  117. package/lib/QueryBuilderV2/hooks/has-overflow.js +3 -0
  118. package/lib/QueryBuilderV2/hooks/has-overflow.js.map +1 -1
  119. package/lib/QueryBuilderV2/hooks/index.d.ts +2 -1
  120. package/lib/QueryBuilderV2/hooks/index.js +2 -1
  121. package/lib/QueryBuilderV2/hooks/index.js.map +1 -1
  122. package/lib/QueryBuilderV2/hooks/local-storage.js +1 -1
  123. package/lib/QueryBuilderV2/hooks/local-storage.js.map +1 -1
  124. package/lib/QueryBuilderV2/hooks/query-builder.d.ts +36 -13
  125. package/lib/QueryBuilderV2/hooks/query-builder.js +258 -36
  126. package/lib/QueryBuilderV2/hooks/query-builder.js.map +1 -1
  127. package/lib/QueryBuilderV2/hooks/shown-member-name.d.ts +16 -0
  128. package/lib/QueryBuilderV2/hooks/shown-member-name.js +20 -0
  129. package/lib/QueryBuilderV2/hooks/shown-member-name.js.map +1 -0
  130. package/lib/QueryBuilderV2/icons/{ArrowIcon.d.ts → ChevronIcon.d.ts} +5 -5
  131. package/lib/QueryBuilderV2/icons/ChevronIcon.js +49 -0
  132. package/lib/QueryBuilderV2/icons/ChevronIcon.js.map +1 -0
  133. package/lib/QueryBuilderV2/icons/ItemInfoIcon.d.ts +7 -6
  134. package/lib/QueryBuilderV2/icons/ItemInfoIcon.js +7 -4
  135. package/lib/QueryBuilderV2/icons/ItemInfoIcon.js.map +1 -1
  136. package/lib/QueryBuilderV2/icons/PrimaryKeyIcon.js +1 -1
  137. package/lib/QueryBuilderV2/icons/PrimaryKeyIcon.js.map +1 -1
  138. package/lib/QueryBuilderV2/types.d.ts +38 -4
  139. package/lib/QueryBuilderV2/utils/cube-sql-converter.d.ts +5 -5
  140. package/lib/QueryBuilderV2/utils/cube-sql-converter.js +48 -25
  141. package/lib/QueryBuilderV2/utils/cube-sql-converter.js.map +1 -1
  142. package/lib/QueryBuilderV2/utils/get-member-search-name.d.ts +3 -0
  143. package/lib/QueryBuilderV2/utils/get-member-search-name.js +11 -0
  144. package/lib/QueryBuilderV2/utils/get-member-search-name.js.map +1 -0
  145. package/lib/QueryBuilderV2/utils/get-query-hash.js +2 -29
  146. package/lib/QueryBuilderV2/utils/get-query-hash.js.map +1 -1
  147. package/lib/QueryBuilderV2/utils/get-type-icon.d.ts +1 -1
  148. package/lib/QueryBuilderV2/utils/get-type-icon.js +1 -1
  149. package/lib/QueryBuilderV2/utils/get-type-icon.js.map +1 -1
  150. package/lib/QueryBuilderV2/utils/get-used-cubes-and-members.d.ts +7 -1
  151. package/lib/QueryBuilderV2/utils/get-used-cubes-and-members.js +48 -8
  152. package/lib/QueryBuilderV2/utils/get-used-cubes-and-members.js.map +1 -1
  153. package/lib/QueryBuilderV2/utils/graphql-converters.js +9 -12
  154. package/lib/QueryBuilderV2/utils/graphql-converters.js.map +1 -1
  155. package/lib/QueryBuilderV2/utils/index.d.ts +2 -0
  156. package/lib/QueryBuilderV2/utils/index.js +2 -0
  157. package/lib/QueryBuilderV2/utils/index.js.map +1 -1
  158. package/lib/QueryBuilderV2/utils/validate-query.d.ts +2 -0
  159. package/lib/QueryBuilderV2/utils/validate-query.js +109 -0
  160. package/lib/QueryBuilderV2/utils/validate-query.js.map +1 -0
  161. package/lib/QueryBuilderV2/values.d.ts +2 -2
  162. package/lib/QueryBuilderV2/values.js +8 -7
  163. package/lib/QueryBuilderV2/values.js.map +1 -1
  164. package/lib/components/Header/Header.js +2 -2
  165. package/lib/components/Header/Header.js.map +1 -1
  166. package/lib/components/PlaygroundQueryBuilder/QueryBuilderContainer.js +1 -2
  167. package/lib/components/PlaygroundQueryBuilder/QueryBuilderContainer.js.map +1 -1
  168. package/lib/components/QueryTabs/QueryTabs.d.ts +3 -0
  169. package/lib/components/QueryTabs/QueryTabs.js +29 -4
  170. package/lib/components/QueryTabs/QueryTabs.js.map +1 -1
  171. package/package.json +6 -5
  172. package/public/vizard/download/react-typescript-antd-table.zip +0 -0
  173. package/public/vizard/download/react-typescript-chartjs-area+bar+doughnut+line+pie.zip +0 -0
  174. package/lib/QueryBuilderV2/QueryBuilderDevSidePanel.d.ts +0 -1
  175. package/lib/QueryBuilderV2/QueryBuilderDevSidePanel.js +0 -203
  176. package/lib/QueryBuilderV2/QueryBuilderDevSidePanel.js.map +0 -1
  177. package/lib/QueryBuilderV2/components/DeleteFilterButton.d.ts +0 -122
  178. package/lib/QueryBuilderV2/components/DeleteFilterButton.js +0 -10
  179. package/lib/QueryBuilderV2/components/DeleteFilterButton.js.map +0 -1
  180. package/lib/QueryBuilderV2/components/MemberFilter.d.ts +0 -13
  181. package/lib/QueryBuilderV2/components/MemberFilter.js +0 -106
  182. package/lib/QueryBuilderV2/components/MemberFilter.js.map +0 -1
  183. package/lib/QueryBuilderV2/components/Panel.d.ts +0 -19
  184. package/lib/QueryBuilderV2/components/Panel.js +0 -88
  185. package/lib/QueryBuilderV2/components/Panel.js.map +0 -1
  186. package/lib/QueryBuilderV2/components/QueryVisualization.d.ts +0 -8
  187. package/lib/QueryBuilderV2/components/QueryVisualization.js +0 -85
  188. package/lib/QueryBuilderV2/components/QueryVisualization.js.map +0 -1
  189. package/lib/QueryBuilderV2/hooks/list-mode.d.ts +0 -3
  190. package/lib/QueryBuilderV2/hooks/list-mode.js +0 -9
  191. package/lib/QueryBuilderV2/hooks/list-mode.js.map +0 -1
  192. package/lib/QueryBuilderV2/icons/ArrowIcon.js +0 -30
  193. package/lib/QueryBuilderV2/icons/ArrowIcon.js.map +0 -1
@@ -1,12 +1,37 @@
1
1
  import { useEffect, useMemo, useRef, useState } from 'react';
2
- import { ResultSet, validateQuery, } from '@cubejs-client/core';
3
- import { extractMembersFromFilters, getUsedCubesAndMembers, getQueryHash, movePivotItem, prepareQuery, useIsFirstRender, } from '../utils';
2
+ import { ResultSet, } from '@cubejs-client/core';
3
+ import { extractMembersFromFilters, getUsedCubesAndMembers, getQueryHash, movePivotItem, prepareQuery, useIsFirstRender, validateQuery, } from '../utils';
4
4
  import { useEvent } from './event';
5
5
  const SIMPLE_MEMBERS = ['dimensions', 'measures', 'segments'];
6
+ const removeFiltersByMember = (filters, memberName) => {
7
+ if (!Array.isArray(filters) || !filters.length) {
8
+ return [];
9
+ }
10
+ return filters
11
+ .map((filter) => {
12
+ // If it's a logical filter, process its subfilters
13
+ if ('and' in filter || 'or' in filter) {
14
+ const key = 'and' in filter ? 'and' : 'or';
15
+ const sanitizedSubFilters = removeFiltersByMember('and' in filter ? filter.and : filter.or, memberName);
16
+ // If all subfilters are removed, return null
17
+ if (sanitizedSubFilters.length === 0) {
18
+ return null;
19
+ }
20
+ // Return the logical filter with sanitized subfilters
21
+ return { [key]: sanitizedSubFilters };
22
+ }
23
+ // If it's a unary or binary filter, check its member
24
+ if ('member' in filter && filter.member === memberName) {
25
+ return null; // Remove the filter
26
+ }
27
+ return filter; // Keep the filter
28
+ })
29
+ .filter(Boolean); // Remove null values
30
+ };
6
31
  export function useQueryBuilder(props) {
7
32
  const mutexRef = useRef({});
8
33
  const firstRun = useIsFirstRender();
9
- let { cubeApi, schemaVersion, defaultChartType, defaultQuery, defaultPivotConfig, tracking, queryValidator, onQueryChange, } = props;
34
+ let { cubeApi, schemaVersion, defaultChartType, defaultQuery, defaultPivotConfig, tracking, queryValidator, displayPrivateItems = true, memberViewType = 'name', onQueryChange, } = props;
10
35
  function queryValidation(query) {
11
36
  let validatedQuery = validateQuery(query);
12
37
  prepareQuery(validatedQuery);
@@ -68,7 +93,33 @@ export function useQueryBuilder(props) {
68
93
  const progressCallback = (progressResult) => {
69
94
  setProgress(progressResult);
70
95
  };
71
- const { usedCubes, usedMembers } = getUsedCubesAndMembers(query);
96
+ const { usedCubes, usedMembers, usedMembersInFilters, usedMembersInGrouping, usedGranularities } = useMemo(() => getUsedCubesAndMembers(query, dateRangesStore), [query, dateRangesStore.join()]);
97
+ const [missingCubes, missingMembers] = useMemo(() => {
98
+ return [
99
+ usedCubes.filter((cube) => !cubes.some((c) => c.name === cube)),
100
+ [
101
+ ...(query.dimensions
102
+ ?.filter((dimension) => !members.dimensions[dimension])
103
+ .map((name) => ({ name, category: 'dimensions' })) || []),
104
+ ...(query.measures
105
+ ?.filter((measure) => !members.measures[measure])
106
+ .map((name) => ({ name, category: 'measures' })) || []),
107
+ ...(query.segments
108
+ ?.filter((segment) => !members.segments[segment])
109
+ .map((name) => ({ name, category: 'segments' })) || []),
110
+ ...(query.timeDimensions
111
+ ?.filter((timeDimension) => !members.dimensions[timeDimension.dimension])
112
+ .map(({ dimension, granularity }) => ({
113
+ name: dimension,
114
+ category: 'timeDimensions',
115
+ granularity,
116
+ })) || []),
117
+ ...(usedMembersInFilters
118
+ .filter((dimension) => !members.dimensions[dimension] && !members.measures[dimension])
119
+ .map((name) => ({ name, category: 'dimensions' })) || []),
120
+ ],
121
+ ];
122
+ }, [usedCubes, usedMembers, meta]);
72
123
  // place joined cubes first
73
124
  cubes.sort((c1, c2) => {
74
125
  const c1joined = isCubeUsed(c1.name);
@@ -124,7 +175,13 @@ export function useQueryBuilder(props) {
124
175
  loadingRef.current++;
125
176
  setIsLoading(false);
126
177
  setQuery({});
178
+ setExecutedQuery(null);
179
+ setResultSet(null);
127
180
  setDateRangesStore([]);
181
+ setError(null);
182
+ selectCubeName(null);
183
+ setError(null);
184
+ setVerificationError(null);
128
185
  }
129
186
  function loadMeta() {
130
187
  const currentRequest = ++metaLoadingRef.current;
@@ -132,12 +189,15 @@ export function useQueryBuilder(props) {
132
189
  return;
133
190
  }
134
191
  setIsMetaLoading(true);
135
- cubeApi
192
+ return cubeApi
136
193
  .meta()
137
194
  .then((newMeta) => {
138
195
  if (currentRequest !== metaLoadingRef.current) {
139
196
  return;
140
197
  }
198
+ const visibilityFilter = (item) => {
199
+ return !displayPrivateItems ? item.public : true;
200
+ };
141
201
  setIsMetaLoading(false);
142
202
  setMeta(newMeta);
143
203
  const memberData = {
@@ -145,21 +205,34 @@ export function useQueryBuilder(props) {
145
205
  measures: {},
146
206
  segments: {},
147
207
  };
148
- newMeta.meta.cubes.forEach((cube) => {
149
- cube.dimensions.forEach((dimension) => {
208
+ newMeta.meta.cubes.filter(visibilityFilter).forEach((cube) => {
209
+ cube.dimensions.filter(visibilityFilter).forEach((dimension) => {
150
210
  memberData.dimensions[dimension.name] = dimension;
151
211
  });
152
- cube.measures.forEach((measure) => {
212
+ cube.measures.filter(visibilityFilter).forEach((measure) => {
153
213
  memberData.measures[measure.name] = measure;
154
214
  });
155
- cube.segments.forEach((segment) => {
215
+ cube.segments.filter(visibilityFilter).forEach((segment) => {
156
216
  memberData.segments[segment.name] = segment;
157
217
  });
158
218
  });
159
219
  setMembers(memberData);
160
- setCubes(newMeta.meta.cubes.sort((a, b) => a.name.localeCompare(b.name)));
220
+ setCubes(newMeta.meta.cubes
221
+ .filter(visibilityFilter)
222
+ .map((cube) => {
223
+ return {
224
+ ...cube,
225
+ measures: cube.measures.filter(visibilityFilter),
226
+ dimensions: cube.dimensions.filter(visibilityFilter),
227
+ segments: cube.segments.filter(visibilityFilter),
228
+ };
229
+ })
230
+ .sort((a, b) => a.name.localeCompare(b.name)));
161
231
  })
162
232
  .catch((error) => {
233
+ if (currentRequest !== metaLoadingRef.current) {
234
+ return;
235
+ }
163
236
  setIsMetaLoading(false);
164
237
  setMetaError(error.response?.plainError?.trim() || String(error));
165
238
  setRichMetaError(error);
@@ -167,7 +240,6 @@ export function useQueryBuilder(props) {
167
240
  });
168
241
  }
169
242
  function dryRun() {
170
- setVerificationError(null);
171
243
  const currentRequest = ++verificationRef.current;
172
244
  if (!meta || !cubeApi || !usedCubes.length) {
173
245
  return;
@@ -179,6 +251,7 @@ export function useQueryBuilder(props) {
179
251
  if (currentRequest !== verificationRef.current) {
180
252
  return;
181
253
  }
254
+ setVerificationError(null);
182
255
  setIsVerifying(false);
183
256
  setDryRunResponse(dryRunResponse);
184
257
  setPivotConfig(ResultSet.getNormalizedPivotConfig(dryRunResponse.pivotQuery, pivotConfig));
@@ -224,13 +297,6 @@ export function useQueryBuilder(props) {
224
297
  ...queryPart,
225
298
  });
226
299
  }
227
- Object.keys(query).forEach((key) => {
228
- if (query[key] == null ||
229
- (Array.isArray(query[key]) && query[key]?.length === 0) ||
230
- (typeof query[key] === 'object' && Object.keys(query[key]).length === 0)) {
231
- delete query[key];
232
- }
233
- });
234
300
  return originalHash !== getQueryHash(query) ? query : originalQuery;
235
301
  }
236
302
  catch (e) {
@@ -253,10 +319,37 @@ export function useQueryBuilder(props) {
253
319
  if (!member || !('format' in member)) {
254
320
  return null;
255
321
  }
256
- // @TODO update typings to support format
257
- // @ts-ignore
258
322
  return member.format;
259
323
  }
324
+ // Find all dimensions inside hierarchies that can be added alongside the given dimension.
325
+ const getConnectedDimensionNames = useEvent((name) => {
326
+ const names = [name];
327
+ const cubeName = name.split('.')[0];
328
+ const cube = getCubeByName(cubeName);
329
+ if (cube) {
330
+ // Find all hierarchies that include the given dimension
331
+ const hierarchiesToFill = (cube.hierarchies ?? []).filter((hierarchy) => {
332
+ return hierarchy.levels.includes(name);
333
+ });
334
+ // If there is only one hierarchy that can be filled, we can add all levels that are above the given dimension
335
+ if (hierarchiesToFill.length === 1) {
336
+ const levels = hierarchiesToFill[0].levels;
337
+ // If no dimension in the hierarchy selected, then we can proceed
338
+ if (!levels.some((dimensionName) => query.dimensions?.includes(dimensionName))) {
339
+ levels
340
+ .slice(0, levels.indexOf(name))
341
+ .reverse()
342
+ .forEach((otherName) => {
343
+ if (names.includes(otherName)) {
344
+ return names;
345
+ }
346
+ names.push(otherName);
347
+ });
348
+ }
349
+ }
350
+ }
351
+ return names;
352
+ });
260
353
  // Updaters with simple common logic for dimensions, measures and segments
261
354
  const simpleUpdaters = SIMPLE_MEMBERS.reduce((acc, type) => {
262
355
  acc[type] = {
@@ -266,11 +359,17 @@ export function useQueryBuilder(props) {
266
359
  console.log(`Unable to add ${type.slice(0, -1)}. Member is not found`, name);
267
360
  return false;
268
361
  }
362
+ let names;
363
+ if (type === 'dimensions') {
364
+ names = getConnectedDimensionNames(name);
365
+ }
269
366
  updateQuery((query) => {
270
367
  const list = query[type] || [];
271
- if (!list?.includes(name)) {
272
- list.push(name);
273
- }
368
+ names.forEach((name) => {
369
+ if (!list?.includes(name)) {
370
+ list.push(name);
371
+ }
372
+ });
274
373
  return { [type]: list };
275
374
  });
276
375
  return true;
@@ -296,7 +395,12 @@ export function useQueryBuilder(props) {
296
395
  console.log(`Unable to toggle ${type.slice(0, -1)}. Member is not found`, name);
297
396
  return;
298
397
  }
299
- list.push(name);
398
+ if (type === 'dimensions') {
399
+ list.push(...getConnectedDimensionNames(name));
400
+ }
401
+ else {
402
+ list.push(name);
403
+ }
300
404
  }
301
405
  else {
302
406
  list.splice(index, 1);
@@ -305,6 +409,13 @@ export function useQueryBuilder(props) {
305
409
  });
306
410
  return true;
307
411
  },
412
+ clear() {
413
+ updateQuery(() => {
414
+ return {
415
+ [type]: [],
416
+ };
417
+ });
418
+ },
308
419
  get list() {
309
420
  return query[type] || [];
310
421
  },
@@ -408,6 +519,13 @@ export function useQueryBuilder(props) {
408
519
  return { timeDimensions: reordered };
409
520
  });
410
521
  },
522
+ clear() {
523
+ updateQuery((query) => {
524
+ return {
525
+ timeDimensions: query.timeDimensions?.filter((d) => !d.granularity),
526
+ };
527
+ });
528
+ },
411
529
  };
412
530
  const dateRanges = {
413
531
  set(name, dateRange) {
@@ -466,6 +584,14 @@ export function useQueryBuilder(props) {
466
584
  get list() {
467
585
  return dateRangesStore;
468
586
  },
587
+ clear() {
588
+ updateQuery((query) => {
589
+ return {
590
+ timeDimensions: query.timeDimensions?.filter((d) => !d.dateRange),
591
+ };
592
+ });
593
+ setDateRangesStore([]);
594
+ },
469
595
  };
470
596
  const order = {
471
597
  set(name, order) {
@@ -536,6 +662,13 @@ export function useQueryBuilder(props) {
536
662
  const orderMap = (query.order || {});
537
663
  return Object.keys(orderMap);
538
664
  },
665
+ clear() {
666
+ updateQuery(() => {
667
+ return {
668
+ order: undefined,
669
+ };
670
+ });
671
+ },
539
672
  };
540
673
  const filters = {
541
674
  add(filter) {
@@ -569,11 +702,8 @@ export function useQueryBuilder(props) {
569
702
  },
570
703
  removeByMember(name) {
571
704
  updateQuery((query) => {
572
- return {
573
- filters: (query?.filters || []).filter((filter) => {
574
- return !('member' in filter) || filter.member !== name;
575
- }),
576
- };
705
+ const filters = query.filters || [];
706
+ return { filters: removeFiltersByMember(filters, name) };
577
707
  });
578
708
  return true;
579
709
  },
@@ -590,6 +720,13 @@ export function useQueryBuilder(props) {
590
720
  get list() {
591
721
  return query?.filters || [];
592
722
  },
723
+ clear() {
724
+ updateQuery(() => {
725
+ return {
726
+ filters: [],
727
+ };
728
+ });
729
+ },
593
730
  };
594
731
  // UI state management
595
732
  useEffect(() => {
@@ -616,7 +753,7 @@ export function useQueryBuilder(props) {
616
753
  if (executedQuery) {
617
754
  setIsDataModelChanged(true);
618
755
  }
619
- }, [schemaVersion]);
756
+ }, [schemaVersion, cubeApi]);
620
757
  // After time dimensions updated...
621
758
  useEffect(() => {
622
759
  let updateDateRanges = false;
@@ -643,7 +780,7 @@ export function useQueryBuilder(props) {
643
780
  }, [JSON.stringify(query.timeDimensions), JSON.stringify(dateRangesStore)]);
644
781
  // Each time schema is changed we need to reload meta
645
782
  useEffect(() => {
646
- loadMeta();
783
+ void loadMeta();
647
784
  }, [schemaVersion, cubeApi]);
648
785
  const isQueryEmpty = !query.measures?.length &&
649
786
  !query.dimensions?.length &&
@@ -653,7 +790,10 @@ export function useQueryBuilder(props) {
653
790
  // @ts-ignore
654
791
  const connectionId = usedCubes[0]
655
792
  ? // @ts-ignore
656
- getCubeByName(usedCubes[0])?.connectedComponent
793
+ (() => {
794
+ const cubeName = usedCubes.find((cubeName) => getCubeByName(cubeName)?.connectedComponent);
795
+ return cubeName ? getCubeByName(cubeName)?.connectedComponent : undefined;
796
+ })()
657
797
  : undefined;
658
798
  // @ts-ignore
659
799
  const joinableCubes = !usedCubes.length
@@ -661,6 +801,18 @@ export function useQueryBuilder(props) {
661
801
  : cubes.filter((cube) =>
662
802
  // @ts-ignore
663
803
  connectionId != null ? cube.connectedComponent === connectionId : cube.name === usedCubes[0]);
804
+ const joinableCubeNames = joinableCubes.map((cube) => cube.name);
805
+ const joinableMembers = useMemo(() => !usedCubes.length
806
+ ? {
807
+ dimensions: members.dimensions,
808
+ measures: members.measures,
809
+ segments: members.segments,
810
+ }
811
+ : {
812
+ dimensions: Object.fromEntries(Object.entries(members.dimensions).filter(([name]) => joinableCubeNames.includes(name.split('.')[0]))),
813
+ measures: Object.fromEntries(Object.entries(members.measures).filter(([name]) => joinableCubeNames.includes(name.split('.')[0]))),
814
+ segments: Object.fromEntries(Object.entries(members.segments).filter(([name]) => joinableCubeNames.includes(name.split('.')[0]))),
815
+ }, [joinableCubeNames.join(',')]);
664
816
  const updatePivotConfig = {
665
817
  moveItem: ({ sourceIndex, destinationIndex, sourceAxis, destinationAxis, }) => {
666
818
  setPivotConfig(ResultSet.getNormalizedPivotConfig({ ...query, queryType: 'regularQuery' }, {
@@ -701,40 +853,49 @@ export function useQueryBuilder(props) {
701
853
  dimensions: [],
702
854
  segments: [],
703
855
  filters: [],
856
+ folders: {},
857
+ hierarchies: {},
704
858
  dateRanges: [],
705
859
  grouping: [],
706
860
  timeDimensions: [],
707
861
  instance: cube,
862
+ isUsed: false,
708
863
  };
709
864
  const cubePrefix = `${cubeName}.`;
710
865
  measures?.forEach((measure) => {
711
866
  if (measure.includes(cubePrefix)) {
712
867
  stats.measures.push(measure);
868
+ stats.isUsed = true;
713
869
  }
714
870
  });
715
871
  dimensions?.forEach((dimension) => {
716
872
  if (dimension.includes(cubePrefix)) {
717
873
  stats.dimensions.push(dimension);
874
+ stats.isUsed = true;
718
875
  }
719
876
  });
720
877
  segments?.forEach((segment) => {
721
878
  if (segment.includes(cubePrefix)) {
722
879
  stats.segments.push(segment);
880
+ stats.isUsed = true;
723
881
  }
724
882
  });
725
883
  filters.forEach((member) => {
726
884
  if (member.includes(cubePrefix)) {
727
885
  stats.filters.push(member);
886
+ stats.isUsed = true;
728
887
  }
729
888
  });
730
889
  dateRanges.forEach((member) => {
731
890
  if (member.includes(cubePrefix)) {
732
891
  stats.dateRanges.push(member);
892
+ stats.isUsed = true;
733
893
  }
734
894
  });
735
895
  grouping.forEach((member) => {
736
896
  if (member.includes(cubePrefix)) {
737
897
  stats.grouping.push(member);
898
+ stats.isUsed = true;
738
899
  }
739
900
  });
740
901
  stats.timeDimensions = [...stats.dateRanges];
@@ -743,6 +904,54 @@ export function useQueryBuilder(props) {
743
904
  stats.timeDimensions.push(member);
744
905
  }
745
906
  });
907
+ cube?.hierarchies?.forEach((hierarchy) => {
908
+ const hierarchyName = hierarchy.name;
909
+ stats.hierarchies[hierarchyName] = [];
910
+ const dimensions = stats.hierarchies[hierarchyName];
911
+ hierarchy.levels.forEach((dimensionName) => {
912
+ if (stats.dimensions.includes(dimensionName)) {
913
+ dimensions.push(dimensionName);
914
+ }
915
+ });
916
+ });
917
+ cube?.folders?.forEach((folder) => {
918
+ const folderName = folder.name;
919
+ stats.folders[folderName] = {
920
+ dimensions: [],
921
+ measures: [],
922
+ segments: [],
923
+ grouping: [],
924
+ };
925
+ const folderStats = stats.folders[folderName];
926
+ folder.members.forEach((memberName) => {
927
+ if (stats.dimensions.includes(memberName)) {
928
+ if (!folderStats.dimensions.includes(memberName)) {
929
+ folderStats.dimensions.push(memberName);
930
+ }
931
+ }
932
+ else if (stats.measures.includes(memberName)) {
933
+ if (!folderStats.measures.includes(memberName)) {
934
+ folderStats.measures.push(memberName);
935
+ }
936
+ }
937
+ else if (stats.segments.includes(memberName)) {
938
+ if (!folderStats.segments.includes(memberName)) {
939
+ folderStats.segments.push(memberName);
940
+ }
941
+ }
942
+ else if (stats.hierarchies[memberName]) {
943
+ // add all selected dimensions from the hierarchy
944
+ stats.hierarchies[memberName].forEach((levelMemberName) => {
945
+ if (!folderStats.dimensions.includes(levelMemberName)) {
946
+ folderStats.dimensions.push(levelMemberName);
947
+ }
948
+ });
949
+ }
950
+ if (grouping.includes(memberName)) {
951
+ folderStats.grouping.push(memberName);
952
+ }
953
+ });
954
+ });
746
955
  allStats[cubeName] = stats;
747
956
  return allStats;
748
957
  }, {});
@@ -757,8 +966,11 @@ export function useQueryBuilder(props) {
757
966
  });
758
967
  }, [usedCubes, usedMembers]);
759
968
  return {
969
+ // options
970
+ memberViewType,
760
971
  // query
761
972
  query: JSON.parse(JSON.stringify(query)),
973
+ queryHash,
762
974
  executedQuery,
763
975
  runQuery,
764
976
  stopQuery,
@@ -792,16 +1004,24 @@ export function useQueryBuilder(props) {
792
1004
  cubes,
793
1005
  members,
794
1006
  joinableCubes,
1007
+ joinableMembers,
1008
+ usedCubes,
1009
+ usedMembers,
1010
+ usedGranularities,
1011
+ usedMembersInGrouping,
1012
+ usedMembersInFilters,
1013
+ missingCubes,
1014
+ missingMembers,
795
1015
  // updaters
796
1016
  ...simpleUpdaters,
797
1017
  grouping,
798
1018
  dateRanges,
799
1019
  order,
800
1020
  filters,
1021
+ // state
801
1022
  chartType,
1023
+ hasPrivateMembers,
802
1024
  setChartType,
803
- usedCubes,
804
- usedMembers,
805
1025
  isCubeJoined: isCubeUsed,
806
1026
  isMemberJoined: isMemberUsed,
807
1027
  isCubeUsed,
@@ -810,12 +1030,14 @@ export function useQueryBuilder(props) {
810
1030
  isDataModelChanged,
811
1031
  isResultOutdated: !!(executedQuery &&
812
1032
  (queryHash !== getQueryHash(executedQuery) || isApiTokenChanged || isDataModelChanged)),
813
- queryHash,
1033
+ // api
814
1034
  cubeApi,
815
- hasPrivateMembers,
1035
+ mutexObj: mutexRef.current,
816
1036
  // ui
817
1037
  selectedCube,
818
1038
  selectCube: useEvent((name) => selectCubeName(name)),
1039
+ // @ts-ignore
1040
+ totalRows: resultSet?.totalRows(),
819
1041
  };
820
1042
  }
821
1043
  //# sourceMappingURL=query-builder.js.map