@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.
- package/build/assets/{index-wSty61qr.js → index-DgSEz9T1.js} +613 -779
- package/build/index.html +1 -1
- package/build/vizard/download/react-typescript-antd-table.zip +0 -0
- package/build/vizard/download/react-typescript-chartjs-area+bar+doughnut+line+pie.zip +0 -0
- package/lib/.tsbuildinfo +1 -1
- package/lib/App.js +1 -1
- package/lib/App.js.map +1 -1
- package/lib/QueryBuilderV2/QueryBuilder.d.ts +4 -0
- package/lib/QueryBuilderV2/QueryBuilder.js +12 -9
- package/lib/QueryBuilderV2/QueryBuilder.js.map +1 -1
- package/lib/QueryBuilderV2/QueryBuilderChart.js +2 -2
- package/lib/QueryBuilderV2/QueryBuilderChart.js.map +1 -1
- package/lib/QueryBuilderV2/QueryBuilderChartResults.js +4 -4
- package/lib/QueryBuilderV2/QueryBuilderChartResults.js.map +1 -1
- package/lib/QueryBuilderV2/QueryBuilderError.js +1 -3
- package/lib/QueryBuilderV2/QueryBuilderError.js.map +1 -1
- package/lib/QueryBuilderV2/QueryBuilderExtras.d.ts +1 -0
- package/lib/QueryBuilderV2/QueryBuilderExtras.js +39 -18
- package/lib/QueryBuilderV2/QueryBuilderExtras.js.map +1 -1
- package/lib/QueryBuilderV2/QueryBuilderFilters.js +88 -84
- package/lib/QueryBuilderV2/QueryBuilderFilters.js.map +1 -1
- package/lib/QueryBuilderV2/QueryBuilderGraphQL.js +1 -1
- package/lib/QueryBuilderV2/QueryBuilderGraphQL.js.map +1 -1
- package/lib/QueryBuilderV2/QueryBuilderInternals.js +7 -10
- package/lib/QueryBuilderV2/QueryBuilderInternals.js.map +1 -1
- package/lib/QueryBuilderV2/QueryBuilderResults.js +87 -45
- package/lib/QueryBuilderV2/QueryBuilderResults.js.map +1 -1
- package/lib/QueryBuilderV2/QueryBuilderSidePanel.d.ts +4 -3
- package/lib/QueryBuilderV2/QueryBuilderSidePanel.js +95 -54
- package/lib/QueryBuilderV2/QueryBuilderSidePanel.js.map +1 -1
- package/lib/QueryBuilderV2/components/Accordion/AccordionItemTitle.js +1 -1
- package/lib/QueryBuilderV2/components/Accordion/AccordionItemTitle.js.map +1 -1
- package/lib/QueryBuilderV2/components/AddFilterInput.d.ts +10 -0
- package/lib/QueryBuilderV2/components/AddFilterInput.js +195 -0
- package/lib/QueryBuilderV2/components/AddFilterInput.js.map +1 -0
- package/lib/QueryBuilderV2/components/Badge.d.ts +3 -2
- package/lib/QueryBuilderV2/components/Badge.js +4 -3
- package/lib/QueryBuilderV2/components/Badge.js.map +1 -1
- package/lib/QueryBuilderV2/components/ChartRenderer.js +0 -1
- package/lib/QueryBuilderV2/components/ChartRenderer.js.map +1 -1
- package/lib/QueryBuilderV2/components/DateRangeFilter.d.ts +7 -0
- package/lib/QueryBuilderV2/components/DateRangeFilter.js +25 -4
- package/lib/QueryBuilderV2/components/DateRangeFilter.js.map +1 -1
- package/lib/QueryBuilderV2/components/EditQueryDialogForm.js +18 -20
- package/lib/QueryBuilderV2/components/EditQueryDialogForm.js.map +1 -1
- package/lib/QueryBuilderV2/components/FilterByMemberButton.d.ts +6 -1
- package/lib/QueryBuilderV2/components/FilterByMemberButton.js +16 -6
- package/lib/QueryBuilderV2/components/FilterByMemberButton.js.map +1 -1
- package/lib/QueryBuilderV2/components/FilterLabel.d.ts +9 -0
- package/lib/QueryBuilderV2/components/FilterLabel.js +18 -4
- package/lib/QueryBuilderV2/components/FilterLabel.js.map +1 -1
- package/lib/QueryBuilderV2/components/FilterMember.d.ts +19 -0
- package/lib/QueryBuilderV2/components/FilterMember.js +137 -0
- package/lib/QueryBuilderV2/components/FilterMember.js.map +1 -0
- package/lib/QueryBuilderV2/components/FilterOptionsButton.d.ts +8 -0
- package/lib/QueryBuilderV2/components/FilterOptionsButton.js +54 -0
- package/lib/QueryBuilderV2/components/FilterOptionsButton.js.map +1 -0
- package/lib/QueryBuilderV2/components/FilteredLabel.js +10 -2
- package/lib/QueryBuilderV2/components/FilteredLabel.js.map +1 -1
- package/lib/QueryBuilderV2/components/Folder.d.ts +9 -0
- package/lib/QueryBuilderV2/components/Folder.js +47 -0
- package/lib/QueryBuilderV2/components/Folder.js.map +1 -0
- package/lib/QueryBuilderV2/components/GranularityListMember.d.ts +3 -0
- package/lib/QueryBuilderV2/components/GranularityListMember.js +5 -14
- package/lib/QueryBuilderV2/components/GranularityListMember.js.map +1 -1
- package/lib/QueryBuilderV2/components/HierarchyMember.d.ts +14 -0
- package/lib/QueryBuilderV2/components/HierarchyMember.js +47 -0
- package/lib/QueryBuilderV2/components/HierarchyMember.js.map +1 -0
- package/lib/QueryBuilderV2/components/InstanceTooltipProvider.d.ts +15 -0
- package/lib/QueryBuilderV2/components/InstanceTooltipProvider.js +36 -0
- package/lib/QueryBuilderV2/components/InstanceTooltipProvider.js.map +1 -0
- package/lib/QueryBuilderV2/components/ListButton.d.ts +341 -11
- package/lib/QueryBuilderV2/components/ListButton.js +2 -1
- package/lib/QueryBuilderV2/components/ListButton.js.map +1 -1
- package/lib/QueryBuilderV2/components/ListCube.js +2 -2
- package/lib/QueryBuilderV2/components/ListCube.js.map +1 -1
- package/lib/QueryBuilderV2/components/ListMember.d.ts +11 -2
- package/lib/QueryBuilderV2/components/ListMember.js +39 -29
- package/lib/QueryBuilderV2/components/ListMember.js.map +1 -1
- package/lib/QueryBuilderV2/components/ListMemberButton.d.ts +341 -11
- package/lib/QueryBuilderV2/components/ListMemberButton.js +8 -1
- package/lib/QueryBuilderV2/components/ListMemberButton.js.map +1 -1
- package/lib/QueryBuilderV2/components/LogicalFilter.d.ts +12 -0
- package/lib/QueryBuilderV2/components/LogicalFilter.js +152 -0
- package/lib/QueryBuilderV2/components/LogicalFilter.js.map +1 -0
- package/lib/QueryBuilderV2/components/MemberLabel.d.ts +11 -1
- package/lib/QueryBuilderV2/components/MemberLabel.js +14 -6
- package/lib/QueryBuilderV2/components/MemberLabel.js.map +1 -1
- package/lib/QueryBuilderV2/components/MemberLabelText.js +11 -4
- package/lib/QueryBuilderV2/components/MemberLabelText.js.map +1 -1
- package/lib/QueryBuilderV2/components/ReorderableList.d.ts +20 -0
- package/lib/QueryBuilderV2/components/ReorderableList.js +173 -0
- package/lib/QueryBuilderV2/components/ReorderableList.js.map +1 -0
- package/lib/QueryBuilderV2/components/ScrollableArea.d.ts +354 -1
- package/lib/QueryBuilderV2/components/SegmentFilter.d.ts +7 -0
- package/lib/QueryBuilderV2/components/SegmentFilter.js +30 -4
- package/lib/QueryBuilderV2/components/SegmentFilter.js.map +1 -1
- package/lib/QueryBuilderV2/components/SidePanelCubeItem.d.ts +4 -5
- package/lib/QueryBuilderV2/components/SidePanelCubeItem.js +380 -130
- package/lib/QueryBuilderV2/components/SidePanelCubeItem.js.map +1 -1
- package/lib/QueryBuilderV2/components/TimeListMember.d.ts +20 -5
- package/lib/QueryBuilderV2/components/TimeListMember.js +95 -49
- package/lib/QueryBuilderV2/components/TimeListMember.js.map +1 -1
- package/lib/QueryBuilderV2/components/ValuesInput.d.ts +4 -0
- package/lib/QueryBuilderV2/components/ValuesInput.js +65 -41
- package/lib/QueryBuilderV2/components/ValuesInput.js.map +1 -1
- package/lib/QueryBuilderV2/hooks/dimension-values.d.ts +13 -0
- package/lib/QueryBuilderV2/hooks/dimension-values.js +62 -0
- package/lib/QueryBuilderV2/hooks/dimension-values.js.map +1 -0
- package/lib/QueryBuilderV2/hooks/filtered-cubes.d.ts +6 -2
- package/lib/QueryBuilderV2/hooks/filtered-cubes.js +26 -8
- package/lib/QueryBuilderV2/hooks/filtered-cubes.js.map +1 -1
- package/lib/QueryBuilderV2/hooks/filtered-members.d.ts +10 -4
- package/lib/QueryBuilderV2/hooks/filtered-members.js +57 -20
- package/lib/QueryBuilderV2/hooks/filtered-members.js.map +1 -1
- package/lib/QueryBuilderV2/hooks/has-overflow.d.ts +1 -1
- package/lib/QueryBuilderV2/hooks/has-overflow.js +3 -0
- package/lib/QueryBuilderV2/hooks/has-overflow.js.map +1 -1
- package/lib/QueryBuilderV2/hooks/index.d.ts +2 -1
- package/lib/QueryBuilderV2/hooks/index.js +2 -1
- package/lib/QueryBuilderV2/hooks/index.js.map +1 -1
- package/lib/QueryBuilderV2/hooks/local-storage.js +1 -1
- package/lib/QueryBuilderV2/hooks/local-storage.js.map +1 -1
- package/lib/QueryBuilderV2/hooks/query-builder.d.ts +36 -13
- package/lib/QueryBuilderV2/hooks/query-builder.js +258 -36
- package/lib/QueryBuilderV2/hooks/query-builder.js.map +1 -1
- package/lib/QueryBuilderV2/hooks/shown-member-name.d.ts +16 -0
- package/lib/QueryBuilderV2/hooks/shown-member-name.js +20 -0
- package/lib/QueryBuilderV2/hooks/shown-member-name.js.map +1 -0
- package/lib/QueryBuilderV2/icons/{ArrowIcon.d.ts → ChevronIcon.d.ts} +5 -5
- package/lib/QueryBuilderV2/icons/ChevronIcon.js +49 -0
- package/lib/QueryBuilderV2/icons/ChevronIcon.js.map +1 -0
- package/lib/QueryBuilderV2/icons/ItemInfoIcon.d.ts +7 -6
- package/lib/QueryBuilderV2/icons/ItemInfoIcon.js +7 -4
- package/lib/QueryBuilderV2/icons/ItemInfoIcon.js.map +1 -1
- package/lib/QueryBuilderV2/icons/PrimaryKeyIcon.js +1 -1
- package/lib/QueryBuilderV2/icons/PrimaryKeyIcon.js.map +1 -1
- package/lib/QueryBuilderV2/types.d.ts +38 -4
- package/lib/QueryBuilderV2/utils/cube-sql-converter.d.ts +5 -5
- package/lib/QueryBuilderV2/utils/cube-sql-converter.js +48 -25
- package/lib/QueryBuilderV2/utils/cube-sql-converter.js.map +1 -1
- package/lib/QueryBuilderV2/utils/get-member-search-name.d.ts +3 -0
- package/lib/QueryBuilderV2/utils/get-member-search-name.js +11 -0
- package/lib/QueryBuilderV2/utils/get-member-search-name.js.map +1 -0
- package/lib/QueryBuilderV2/utils/get-query-hash.js +2 -29
- package/lib/QueryBuilderV2/utils/get-query-hash.js.map +1 -1
- package/lib/QueryBuilderV2/utils/get-type-icon.d.ts +1 -1
- package/lib/QueryBuilderV2/utils/get-type-icon.js +1 -1
- package/lib/QueryBuilderV2/utils/get-type-icon.js.map +1 -1
- package/lib/QueryBuilderV2/utils/get-used-cubes-and-members.d.ts +7 -1
- package/lib/QueryBuilderV2/utils/get-used-cubes-and-members.js +48 -8
- package/lib/QueryBuilderV2/utils/get-used-cubes-and-members.js.map +1 -1
- package/lib/QueryBuilderV2/utils/graphql-converters.js +9 -12
- package/lib/QueryBuilderV2/utils/graphql-converters.js.map +1 -1
- package/lib/QueryBuilderV2/utils/index.d.ts +2 -0
- package/lib/QueryBuilderV2/utils/index.js +2 -0
- package/lib/QueryBuilderV2/utils/index.js.map +1 -1
- package/lib/QueryBuilderV2/utils/validate-query.d.ts +2 -0
- package/lib/QueryBuilderV2/utils/validate-query.js +109 -0
- package/lib/QueryBuilderV2/utils/validate-query.js.map +1 -0
- package/lib/QueryBuilderV2/values.d.ts +2 -2
- package/lib/QueryBuilderV2/values.js +8 -7
- package/lib/QueryBuilderV2/values.js.map +1 -1
- package/lib/components/Header/Header.js +2 -2
- package/lib/components/Header/Header.js.map +1 -1
- package/lib/components/PlaygroundQueryBuilder/QueryBuilderContainer.js +1 -2
- package/lib/components/PlaygroundQueryBuilder/QueryBuilderContainer.js.map +1 -1
- package/lib/components/QueryTabs/QueryTabs.d.ts +3 -0
- package/lib/components/QueryTabs/QueryTabs.js +29 -4
- package/lib/components/QueryTabs/QueryTabs.js.map +1 -1
- package/package.json +6 -5
- package/public/vizard/download/react-typescript-antd-table.zip +0 -0
- package/public/vizard/download/react-typescript-chartjs-area+bar+doughnut+line+pie.zip +0 -0
- package/lib/QueryBuilderV2/QueryBuilderDevSidePanel.d.ts +0 -1
- package/lib/QueryBuilderV2/QueryBuilderDevSidePanel.js +0 -203
- package/lib/QueryBuilderV2/QueryBuilderDevSidePanel.js.map +0 -1
- package/lib/QueryBuilderV2/components/DeleteFilterButton.d.ts +0 -122
- package/lib/QueryBuilderV2/components/DeleteFilterButton.js +0 -10
- package/lib/QueryBuilderV2/components/DeleteFilterButton.js.map +0 -1
- package/lib/QueryBuilderV2/components/MemberFilter.d.ts +0 -13
- package/lib/QueryBuilderV2/components/MemberFilter.js +0 -106
- package/lib/QueryBuilderV2/components/MemberFilter.js.map +0 -1
- package/lib/QueryBuilderV2/components/Panel.d.ts +0 -19
- package/lib/QueryBuilderV2/components/Panel.js +0 -88
- package/lib/QueryBuilderV2/components/Panel.js.map +0 -1
- package/lib/QueryBuilderV2/components/QueryVisualization.d.ts +0 -8
- package/lib/QueryBuilderV2/components/QueryVisualization.js +0 -85
- package/lib/QueryBuilderV2/components/QueryVisualization.js.map +0 -1
- package/lib/QueryBuilderV2/hooks/list-mode.d.ts +0 -3
- package/lib/QueryBuilderV2/hooks/list-mode.js +0 -9
- package/lib/QueryBuilderV2/hooks/list-mode.js.map +0 -1
- package/lib/QueryBuilderV2/icons/ArrowIcon.js +0 -30
- 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,
|
|
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
|
|
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
|
-
|
|
272
|
-
list
|
|
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
|
-
|
|
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
|
-
|
|
573
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1033
|
+
// api
|
|
814
1034
|
cubeApi,
|
|
815
|
-
|
|
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
|