@finos/legend-query-builder 4.14.69 → 4.14.70
Sign up to get free protection for your applications and to get access to all the features.
- package/lib/__lib__/QueryBuilderTesting.d.ts +1 -0
- package/lib/__lib__/QueryBuilderTesting.d.ts.map +1 -1
- package/lib/__lib__/QueryBuilderTesting.js +1 -0
- package/lib/__lib__/QueryBuilderTesting.js.map +1 -1
- package/lib/components/explorer/QueryBuilderExplorerPanel.d.ts +1 -0
- package/lib/components/explorer/QueryBuilderExplorerPanel.d.ts.map +1 -1
- package/lib/components/explorer/QueryBuilderExplorerPanel.js +87 -52
- package/lib/components/explorer/QueryBuilderExplorerPanel.js.map +1 -1
- package/lib/components/explorer/QueryBuilderPropertySearchPanel.d.ts +4 -0
- package/lib/components/explorer/QueryBuilderPropertySearchPanel.d.ts.map +1 -1
- package/lib/components/explorer/QueryBuilderPropertySearchPanel.js +172 -108
- package/lib/components/explorer/QueryBuilderPropertySearchPanel.js.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.d.ts.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js +2 -1
- package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +29 -18
- package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.d.ts.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.js +13 -4
- package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.js.map +1 -1
- package/lib/components/filter/QueryBuilderFilterPanel.d.ts.map +1 -1
- package/lib/components/filter/QueryBuilderFilterPanel.js +4 -3
- package/lib/components/filter/QueryBuilderFilterPanel.js.map +1 -1
- package/lib/components/result/QueryBuilderResultPanel.d.ts +12 -0
- package/lib/components/result/QueryBuilderResultPanel.d.ts.map +1 -1
- package/lib/components/result/QueryBuilderResultPanel.js +60 -8
- package/lib/components/result/QueryBuilderResultPanel.js.map +1 -1
- package/lib/components/result/tds/QueryBuilderTDSGridResult.d.ts.map +1 -1
- package/lib/components/result/tds/QueryBuilderTDSGridResult.js +16 -2
- package/lib/components/result/tds/QueryBuilderTDSGridResult.js.map +1 -1
- package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.d.ts +1 -0
- package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.d.ts.map +1 -1
- package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.js +34 -1
- package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.js.map +1 -1
- package/lib/components/shared/QueryBuilderFilterHelper.d.ts.map +1 -1
- package/lib/components/shared/QueryBuilderFilterHelper.js +3 -0
- package/lib/components/shared/QueryBuilderFilterHelper.js.map +1 -1
- package/lib/components/shared/QueryBuilderPropertyInfoTooltip.d.ts +11 -0
- package/lib/components/shared/QueryBuilderPropertyInfoTooltip.d.ts.map +1 -1
- package/lib/components/shared/QueryBuilderPropertyInfoTooltip.js +6 -3
- package/lib/components/shared/QueryBuilderPropertyInfoTooltip.js.map +1 -1
- package/lib/graph-manager/QueryBuilderConfig.d.ts +4 -0
- package/lib/graph-manager/QueryBuilderConfig.d.ts.map +1 -1
- package/lib/graph-manager/QueryBuilderConfig.js +5 -0
- package/lib/graph-manager/QueryBuilderConfig.js.map +1 -1
- package/lib/index.css +2 -2
- package/lib/index.css.map +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/QueryBuilderResultState.d.ts +11 -3
- package/lib/stores/QueryBuilderResultState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderResultState.js +47 -4
- package/lib/stores/QueryBuilderResultState.js.map +1 -1
- package/lib/stores/QueryBuilderValueSpecificationBuilderHelper.d.ts +4 -0
- package/lib/stores/QueryBuilderValueSpecificationBuilderHelper.d.ts.map +1 -1
- package/lib/stores/explorer/QueryBuilderExplorerState.d.ts +3 -1
- package/lib/stores/explorer/QueryBuilderExplorerState.d.ts.map +1 -1
- package/lib/stores/explorer/QueryBuilderExplorerState.js +63 -8
- package/lib/stores/explorer/QueryBuilderExplorerState.js.map +1 -1
- package/lib/stores/explorer/QueryBuilderFuzzySearchAdvancedConfigState.d.ts +24 -0
- package/lib/stores/explorer/QueryBuilderFuzzySearchAdvancedConfigState.d.ts.map +1 -0
- package/lib/stores/explorer/QueryBuilderFuzzySearchAdvancedConfigState.js +39 -0
- package/lib/stores/explorer/QueryBuilderFuzzySearchAdvancedConfigState.js.map +1 -0
- package/lib/stores/explorer/QueryBuilderPropertySearchState.d.ts +8 -4
- package/lib/stores/explorer/QueryBuilderPropertySearchState.d.ts.map +1 -1
- package/lib/stores/explorer/QueryBuilderPropertySearchState.js +204 -114
- package/lib/stores/explorer/QueryBuilderPropertySearchState.js.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js +8 -1
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js.map +1 -1
- package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.js +12 -1
- package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.js.map +1 -1
- package/lib/stores/filter/QueryBuilderFilterState.d.ts +8 -1
- package/lib/stores/filter/QueryBuilderFilterState.d.ts.map +1 -1
- package/lib/stores/filter/QueryBuilderFilterState.js +27 -10
- package/lib/stores/filter/QueryBuilderFilterState.js.map +1 -1
- package/package.json +8 -8
- package/src/__lib__/QueryBuilderTesting.ts +1 -0
- package/src/components/explorer/QueryBuilderExplorerPanel.tsx +220 -114
- package/src/components/explorer/QueryBuilderPropertySearchPanel.tsx +618 -388
- package/src/components/fetch-structure/QueryBuilderPostFilterPanel.tsx +5 -2
- package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +78 -44
- package/src/components/fetch-structure/QueryBuilderTDSWindowPanel.tsx +63 -10
- package/src/components/filter/QueryBuilderFilterPanel.tsx +4 -2
- package/src/components/result/QueryBuilderResultPanel.tsx +207 -20
- package/src/components/result/tds/QueryBuilderTDSGridResult.tsx +16 -2
- package/src/components/result/tds/QueryBuilderTDSSimpleGridResult.tsx +43 -0
- package/src/components/shared/QueryBuilderFilterHelper.ts +8 -0
- package/src/components/shared/QueryBuilderPropertyInfoTooltip.tsx +13 -3
- package/src/graph-manager/QueryBuilderConfig.ts +6 -0
- package/src/stores/QueryBuilderResultState.ts +64 -10
- package/src/stores/QueryBuilderValueSpecificationBuilderHelper.ts +5 -0
- package/src/stores/explorer/QueryBuilderExplorerState.ts +92 -8
- package/src/stores/explorer/QueryBuilderFuzzySearchAdvancedConfigState.ts +46 -0
- package/src/stores/explorer/QueryBuilderPropertySearchState.ts +280 -142
- package/src/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.ts +8 -1
- package/src/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.ts +15 -2
- package/src/stores/filter/QueryBuilderFilterState.ts +34 -11
- package/tsconfig.json +1 -0
@@ -317,7 +317,10 @@ const QueryBuilderPostFilterConditionEditor = observer(
|
|
317
317
|
const conditionValueType =
|
318
318
|
node.condition.leftConditionValue.getColumnType();
|
319
319
|
if (canDropTypeOntoNodeValue(itemType, node.condition)) {
|
320
|
-
if (
|
320
|
+
if (
|
321
|
+
type === QUERY_BUILDER_PROJECTION_COLUMN_DND_TYPE ||
|
322
|
+
type === QUERY_BUILDER_WINDOW_COLUMN_DND_TYPE
|
323
|
+
) {
|
321
324
|
const columnState = (item as QueryBuilderProjectionColumnDragSource)
|
322
325
|
.columnState;
|
323
326
|
node.condition.setRightConditionVal(
|
@@ -1047,7 +1050,7 @@ const QueryBuilderPostFilterPanelContent = observer(
|
|
1047
1050
|
[applicationStore, handleDrop],
|
1048
1051
|
);
|
1049
1052
|
|
1050
|
-
const addPostFilterRef = useRef<
|
1053
|
+
const addPostFilterRef = useRef<HTMLDivElement>(null);
|
1051
1054
|
dropTargetConnector(addPostFilterRef);
|
1052
1055
|
|
1053
1056
|
return (
|
@@ -119,6 +119,41 @@ import {
|
|
119
119
|
} from '../shared/QueryBuilderPropertyInfoTooltip.js';
|
120
120
|
import { getNameOfValueSpecification } from '../shared/QueryBuilderVariableSelector.js';
|
121
121
|
import { QueryBuilderAggregateOperator_Percentile } from '../../stores/fetch-structure/tds/aggregation/operators/QueryBuilderAggregateOperator_Percentile.js';
|
122
|
+
import {
|
123
|
+
getFurthestExistsNodeParent,
|
124
|
+
isExistsNodeChild,
|
125
|
+
QUERY_BUILDER_FILTER_DND_TYPE,
|
126
|
+
QueryBuilderFilterTreeConditionNodeData,
|
127
|
+
type QueryBuilderFilterConditionDragSource,
|
128
|
+
} from '../../stores/filter/QueryBuilderFilterState.js';
|
129
|
+
import { cloneAbstractPropertyExpression } from '../../stores/shared/ValueSpecificationEditorHelper.js';
|
130
|
+
import { buildPropertyExpressionFromExistsNode } from '../filter/QueryBuilderFilterPanel.js';
|
131
|
+
|
132
|
+
const CAN_DROP_MAIN_GROUP_DND_TYPES = [
|
133
|
+
QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.ENUM_PROPERTY,
|
134
|
+
QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.PRIMITIVE_PROPERTY,
|
135
|
+
QUERY_BUILDER_FILTER_DND_TYPE.CONDITION,
|
136
|
+
QUERY_BUILDER_FUNCTION_DND_TYPE,
|
137
|
+
];
|
138
|
+
|
139
|
+
const CAN_DROP_DERIVATION_PROJECTION_COLUMN_DND_TYPES = [
|
140
|
+
QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.ROOT,
|
141
|
+
QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.CLASS_PROPERTY,
|
142
|
+
QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.ENUM_PROPERTY,
|
143
|
+
QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.PRIMITIVE_PROPERTY,
|
144
|
+
QUERY_BUILDER_VARIABLE_DND_TYPE,
|
145
|
+
QUERY_BUILDER_FUNCTION_DND_TYPE,
|
146
|
+
];
|
147
|
+
|
148
|
+
type QueryBuilderTDSPanelDropTarget =
|
149
|
+
| QueryBuilderExplorerTreeDragSource
|
150
|
+
| QueryBuilderFunctionsExplorerDragSource
|
151
|
+
| QueryBuilderFilterConditionDragSource;
|
152
|
+
|
153
|
+
type QueryBuilderDerivationProjectionColumnDropTarget =
|
154
|
+
| QueryBuilderExplorerTreeDragSource
|
155
|
+
| QueryBuilderVariableDragSource
|
156
|
+
| QueryBuilderFunctionsExplorerDragSource;
|
122
157
|
|
123
158
|
const QueryBuilderProjectionColumnContextMenu = observer(
|
124
159
|
forwardRef<
|
@@ -192,10 +227,7 @@ const QueryBuilderDerivationProjectionColumnEditor = observer(
|
|
192
227
|
};
|
193
228
|
const handleDrop = useCallback(
|
194
229
|
(
|
195
|
-
item:
|
196
|
-
| QueryBuilderExplorerTreeDragSource
|
197
|
-
| QueryBuilderVariableDragSource
|
198
|
-
| QueryBuilderFunctionsExplorerDragSource,
|
230
|
+
item: QueryBuilderDerivationProjectionColumnDropTarget,
|
199
231
|
type: string,
|
200
232
|
): void => {
|
201
233
|
if (type === QUERY_BUILDER_VARIABLE_DND_TYPE) {
|
@@ -224,28 +256,18 @@ const QueryBuilderDerivationProjectionColumnEditor = observer(
|
|
224
256
|
},
|
225
257
|
[projectionColumnState],
|
226
258
|
);
|
227
|
-
const [, dropConnector] =
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
QUERY_BUILDER_FUNCTION_DND_TYPE,
|
240
|
-
],
|
241
|
-
drop: (item, monitor): void => {
|
242
|
-
if (!monitor.didDrop()) {
|
243
|
-
handleDrop(item, monitor.getItemType() as string);
|
244
|
-
} // prevent drop event propagation to accomondate for nested DnD
|
245
|
-
},
|
246
|
-
}),
|
247
|
-
[handleDrop],
|
248
|
-
);
|
259
|
+
const [, dropConnector] =
|
260
|
+
useDrop<QueryBuilderDerivationProjectionColumnDropTarget>(
|
261
|
+
() => ({
|
262
|
+
accept: CAN_DROP_DERIVATION_PROJECTION_COLUMN_DND_TYPES,
|
263
|
+
drop: (item, monitor): void => {
|
264
|
+
if (!monitor.didDrop()) {
|
265
|
+
handleDrop(item, monitor.getItemType() as string);
|
266
|
+
} // prevent drop event propagation to accomondate for nested DnD
|
267
|
+
},
|
268
|
+
}),
|
269
|
+
[handleDrop],
|
270
|
+
);
|
249
271
|
|
250
272
|
return (
|
251
273
|
<div
|
@@ -1230,12 +1252,7 @@ export const QueryBuilderTDSPanel = observer(
|
|
1230
1252
|
|
1231
1253
|
// Drag and Drop
|
1232
1254
|
const handleDrop = useCallback(
|
1233
|
-
(
|
1234
|
-
item:
|
1235
|
-
| QueryBuilderExplorerTreeDragSource
|
1236
|
-
| QueryBuilderFunctionsExplorerDragSource,
|
1237
|
-
type: string,
|
1238
|
-
): void => {
|
1255
|
+
(item: QueryBuilderTDSPanelDropTarget, type: string): void => {
|
1239
1256
|
switch (type) {
|
1240
1257
|
case QUERY_BUILDER_FUNCTION_DND_TYPE: {
|
1241
1258
|
const derivationProjectionColumn =
|
@@ -1267,6 +1284,30 @@ export const QueryBuilderTDSPanel = observer(
|
|
1267
1284
|
),
|
1268
1285
|
);
|
1269
1286
|
break;
|
1287
|
+
case QUERY_BUILDER_FILTER_DND_TYPE.CONDITION:
|
1288
|
+
if (item.node instanceof QueryBuilderFilterTreeConditionNodeData) {
|
1289
|
+
const propertyExpression = isExistsNodeChild(item.node)
|
1290
|
+
? buildPropertyExpressionFromExistsNode(
|
1291
|
+
tdsState.queryBuilderState.filterState,
|
1292
|
+
guaranteeNonNullable(
|
1293
|
+
getFurthestExistsNodeParent(item.node),
|
1294
|
+
),
|
1295
|
+
item.node,
|
1296
|
+
)
|
1297
|
+
: cloneAbstractPropertyExpression(
|
1298
|
+
item.node.condition.propertyExpressionState
|
1299
|
+
.propertyExpression,
|
1300
|
+
tdsState.queryBuilderState.observerContext,
|
1301
|
+
);
|
1302
|
+
tdsState.addColumn(
|
1303
|
+
new QueryBuilderSimpleProjectionColumnState(
|
1304
|
+
tdsState,
|
1305
|
+
propertyExpression,
|
1306
|
+
tdsState.queryBuilderState.explorerState.humanizePropertyName,
|
1307
|
+
),
|
1308
|
+
);
|
1309
|
+
}
|
1310
|
+
break;
|
1270
1311
|
default:
|
1271
1312
|
break;
|
1272
1313
|
}
|
@@ -1275,17 +1316,12 @@ export const QueryBuilderTDSPanel = observer(
|
|
1275
1316
|
);
|
1276
1317
|
|
1277
1318
|
const [{ isDragOver }, dropTargetConnector] = useDrop<
|
1278
|
-
|
1279
|
-
| QueryBuilderFunctionsExplorerDragSource,
|
1319
|
+
QueryBuilderTDSPanelDropTarget,
|
1280
1320
|
void,
|
1281
1321
|
{ isDragOver: boolean }
|
1282
1322
|
>(
|
1283
1323
|
() => ({
|
1284
|
-
accept:
|
1285
|
-
QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.ENUM_PROPERTY,
|
1286
|
-
QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.PRIMITIVE_PROPERTY,
|
1287
|
-
QUERY_BUILDER_FUNCTION_DND_TYPE,
|
1288
|
-
],
|
1324
|
+
accept: CAN_DROP_MAIN_GROUP_DND_TYPES,
|
1289
1325
|
drop: (item, monitor): void => {
|
1290
1326
|
if (!monitor.didDrop()) {
|
1291
1327
|
handleDrop(item, monitor.getItemType() as string);
|
@@ -1315,11 +1351,9 @@ export const QueryBuilderTDSPanel = observer(
|
|
1315
1351
|
const { isDroppable } = useDragLayer((monitor) => ({
|
1316
1352
|
isDroppable:
|
1317
1353
|
monitor.isDragging() &&
|
1318
|
-
|
1319
|
-
|
1320
|
-
|
1321
|
-
QUERY_BUILDER_FUNCTION_DND_TYPE,
|
1322
|
-
].includes(monitor.getItemType()?.toString() ?? ''),
|
1354
|
+
CAN_DROP_MAIN_GROUP_DND_TYPES.includes(
|
1355
|
+
monitor.getItemType()?.toString() ?? '',
|
1356
|
+
),
|
1323
1357
|
}));
|
1324
1358
|
|
1325
1359
|
useEffect(() => {
|
@@ -48,6 +48,7 @@ import {
|
|
48
48
|
PanelHeader,
|
49
49
|
PanelHeaderActions,
|
50
50
|
Panel,
|
51
|
+
DragPreviewLayer,
|
51
52
|
} from '@finos/legend-art';
|
52
53
|
import {
|
53
54
|
assertErrorThrown,
|
@@ -57,7 +58,12 @@ import {
|
|
57
58
|
} from '@finos/legend-shared';
|
58
59
|
import { observer } from 'mobx-react-lite';
|
59
60
|
import { forwardRef, useCallback, useRef, useState } from 'react';
|
60
|
-
import {
|
61
|
+
import {
|
62
|
+
type DropTargetMonitor,
|
63
|
+
useDrag,
|
64
|
+
useDragLayer,
|
65
|
+
useDrop,
|
66
|
+
} from 'react-dnd';
|
61
67
|
import type { QueryBuilderTDS_WindowOperator } from '../../stores/fetch-structure/tds/window/operators/QueryBuilderTDS_WindowOperator.js';
|
62
68
|
import {
|
63
69
|
type QueryBuilderWindowState,
|
@@ -75,6 +81,7 @@ import type { QueryBuilderTDSState } from '../../stores/fetch-structure/tds/Quer
|
|
75
81
|
import { QUERY_BUILDER_TEST_ID } from '../../__lib__/QueryBuilderTesting.js';
|
76
82
|
import { QueryBuilderPanelIssueCountBadge } from '../shared/QueryBuilderPanelIssueCountBadge.js';
|
77
83
|
import { COLUMN_SORT_TYPE } from '../../graph/QueryBuilderMetaModelConst.js';
|
84
|
+
import { CAN_DROP_MAIN_GROUP_DND_TYPES } from './QueryBuilderPostFilterPanel.js';
|
78
85
|
|
79
86
|
// helpers
|
80
87
|
const createWindowColumnState = (
|
@@ -965,6 +972,10 @@ const QueryBuilderWindowColumnEditor = observer(
|
|
965
972
|
ref={ref}
|
966
973
|
className="query-builder__olap__column"
|
967
974
|
showPlaceholder={isBeingDragged}
|
975
|
+
placeholder={
|
976
|
+
<div className="query-builder__olap__column__placeholder" />
|
977
|
+
}
|
978
|
+
placeholderContainerClassName="query-builder__olap__column__placeholder__container"
|
968
979
|
>
|
969
980
|
<ContextMenu
|
970
981
|
content={
|
@@ -1236,6 +1247,7 @@ export const QueryBuilderTDSWindowPanel = observer(
|
|
1236
1247
|
tdsWindowState.setEditColumn(newWindowState);
|
1237
1248
|
}
|
1238
1249
|
};
|
1250
|
+
|
1239
1251
|
// Drag and Drop
|
1240
1252
|
const handleDrop = useCallback(
|
1241
1253
|
async (item: QueryBuilderWindowDropTarget): Promise<void> => {
|
@@ -1253,6 +1265,7 @@ export const QueryBuilderTDSWindowPanel = observer(
|
|
1253
1265
|
},
|
1254
1266
|
[applicationStore, tdsWindowState],
|
1255
1267
|
);
|
1268
|
+
|
1256
1269
|
const [{ isDragOver }, dropTargetConnector] = useDrop<
|
1257
1270
|
QueryBuilderWindowDropTarget,
|
1258
1271
|
void,
|
@@ -1274,6 +1287,18 @@ export const QueryBuilderTDSWindowPanel = observer(
|
|
1274
1287
|
}),
|
1275
1288
|
[applicationStore, handleDrop],
|
1276
1289
|
);
|
1290
|
+
|
1291
|
+
const { isDroppable } = useDragLayer((monitor) => ({
|
1292
|
+
isDroppable:
|
1293
|
+
monitor.isDragging() &&
|
1294
|
+
CAN_DROP_MAIN_GROUP_DND_TYPES.includes(
|
1295
|
+
monitor.getItemType()?.toString() ?? '',
|
1296
|
+
),
|
1297
|
+
}));
|
1298
|
+
|
1299
|
+
const addWindowColumnRef = useRef<HTMLDivElement>(null);
|
1300
|
+
dropTargetConnector(addWindowColumnRef);
|
1301
|
+
|
1277
1302
|
return (
|
1278
1303
|
<Panel>
|
1279
1304
|
<div
|
@@ -1301,7 +1326,8 @@ export const QueryBuilderTDSWindowPanel = observer(
|
|
1301
1326
|
</PanelHeader>
|
1302
1327
|
<PanelContent>
|
1303
1328
|
<PanelDropZone
|
1304
|
-
isDragOver={isDragOver}
|
1329
|
+
isDragOver={isDragOver && tdsWindowState.isEmpty}
|
1330
|
+
isDroppable={isDroppable && tdsWindowState.isEmpty}
|
1305
1331
|
dropTargetConnector={dropTargetConnector}
|
1306
1332
|
>
|
1307
1333
|
{tdsWindowState.isEmpty && (
|
@@ -1311,16 +1337,43 @@ export const QueryBuilderTDSWindowPanel = observer(
|
|
1311
1337
|
/>
|
1312
1338
|
)}
|
1313
1339
|
{!tdsWindowState.isEmpty && (
|
1340
|
+
<>
|
1341
|
+
<DragPreviewLayer
|
1342
|
+
labelGetter={(
|
1343
|
+
item: QueryBuilderWindowColumnDragSource,
|
1344
|
+
): string =>
|
1345
|
+
item.columnState.columnName === ''
|
1346
|
+
? '(unknown)'
|
1347
|
+
: item.columnState.columnName
|
1348
|
+
}
|
1349
|
+
types={[QUERY_BUILDER_WINDOW_COLUMN_DND_TYPE]}
|
1350
|
+
/>
|
1351
|
+
<div
|
1352
|
+
data-testid={QUERY_BUILDER_TEST_ID.QUERY_BUILDER_TDS}
|
1353
|
+
className="query-builder__olap__columns"
|
1354
|
+
>
|
1355
|
+
{tdsWindowState.windowColumns.map((col) => (
|
1356
|
+
<QueryBuilderWindowColumnEditor
|
1357
|
+
windowColumnState={col}
|
1358
|
+
key={col.uuid}
|
1359
|
+
/>
|
1360
|
+
))}
|
1361
|
+
</div>
|
1362
|
+
</>
|
1363
|
+
)}
|
1364
|
+
{isDroppable && !tdsWindowState.isEmpty && (
|
1314
1365
|
<div
|
1315
|
-
|
1316
|
-
className="query-
|
1366
|
+
ref={addWindowColumnRef}
|
1367
|
+
className="query-builder__olap__free-drop-zone__container"
|
1317
1368
|
>
|
1318
|
-
|
1319
|
-
|
1320
|
-
|
1321
|
-
|
1322
|
-
|
1323
|
-
|
1369
|
+
<PanelEntryDropZonePlaceholder
|
1370
|
+
isDragOver={isDragOver}
|
1371
|
+
isDroppable={isDroppable}
|
1372
|
+
className="query-builder__olap__free-drop-zone"
|
1373
|
+
label="Add new window function column"
|
1374
|
+
>
|
1375
|
+
<></>
|
1376
|
+
</PanelEntryDropZonePlaceholder>
|
1324
1377
|
</div>
|
1325
1378
|
)}
|
1326
1379
|
</PanelDropZone>
|
@@ -68,6 +68,7 @@ import {
|
|
68
68
|
FilterPropertyExpressionStateConditionValueState,
|
69
69
|
isCollectionProperty,
|
70
70
|
type QueryBuilderFilterValueDropTarget,
|
71
|
+
isExistsNodeChild,
|
71
72
|
} from '../../stores/filter/QueryBuilderFilterState.js';
|
72
73
|
import { useDrag, useDragLayer, useDrop } from 'react-dnd';
|
73
74
|
import {
|
@@ -830,6 +831,7 @@ const QueryBuilderFilterConditionEditor = observer(
|
|
830
831
|
const queryBuilderState = node.condition.filterState.queryBuilderState;
|
831
832
|
const rightConditionValue = node.condition.rightConditionValue;
|
832
833
|
const applicationStore = useApplicationStore();
|
834
|
+
const isNodeExistsNodeChild = isExistsNodeChild(node);
|
833
835
|
|
834
836
|
// Drag and Drop on filter condition value
|
835
837
|
const handleDrop = useCallback(
|
@@ -845,7 +847,7 @@ const QueryBuilderFilterConditionEditor = observer(
|
|
845
847
|
type === QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.ENUM_PROPERTY ||
|
846
848
|
type ===
|
847
849
|
QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.PRIMITIVE_PROPERTY) &&
|
848
|
-
|
850
|
+
isNodeExistsNodeChild
|
849
851
|
) {
|
850
852
|
throw new UnsupportedOperationError(
|
851
853
|
'Collection filter does not support property for filter condition value.',
|
@@ -931,8 +933,8 @@ const QueryBuilderFilterConditionEditor = observer(
|
|
931
933
|
[
|
932
934
|
applicationStore,
|
933
935
|
queryBuilderState,
|
936
|
+
isNodeExistsNodeChild,
|
934
937
|
node.condition,
|
935
|
-
node.isExistsNodeChild,
|
936
938
|
],
|
937
939
|
);
|
938
940
|
|
@@ -44,6 +44,8 @@ import {
|
|
44
44
|
ReportIcon,
|
45
45
|
CubesLoadingIndicatorIcon,
|
46
46
|
CubesLoadingIndicator,
|
47
|
+
InfoCircleIcon,
|
48
|
+
ShareBoxIcon,
|
47
49
|
} from '@finos/legend-art';
|
48
50
|
import { observer } from 'mobx-react-lite';
|
49
51
|
import { flowResult } from 'mobx';
|
@@ -77,6 +79,108 @@ import { QueryBuilderTDSSimpleGridResult } from './tds/QueryBuilderTDSSimpleGrid
|
|
77
79
|
import { getExecutedSqlFromExecutionResult } from './tds/QueryBuilderTDSResultShared.js';
|
78
80
|
import { QueryBuilderTDSGridResult } from './tds/QueryBuilderTDSGridResult.js';
|
79
81
|
import type { QueryBuilder_LegendApplicationPlugin_Extension } from '../../stores/QueryBuilder_LegendApplicationPlugin_Extension.js';
|
82
|
+
import type { QueryBuilderResultState } from '../../stores/QueryBuilderResultState.js';
|
83
|
+
|
84
|
+
const PERMISSION_ERRORS = ['permission denied', 'invalid user id or password'];
|
85
|
+
|
86
|
+
export const QueryBuilderExecutionErrorPanel = observer(
|
87
|
+
(props: {
|
88
|
+
resultState: QueryBuilderResultState;
|
89
|
+
executionError: string | Error;
|
90
|
+
}) => {
|
91
|
+
const { resultState, executionError } = props;
|
92
|
+
const queryBuilderState = resultState.queryBuilderState;
|
93
|
+
const errorMessage = executionError
|
94
|
+
? queryBuilderState.applicationStore.notificationService.getErrorMessage(
|
95
|
+
executionError,
|
96
|
+
)
|
97
|
+
: '';
|
98
|
+
const isPermissionDeniedError = () =>
|
99
|
+
Boolean(
|
100
|
+
PERMISSION_ERRORS.find((e) => errorMessage?.toLowerCase().includes(e)),
|
101
|
+
);
|
102
|
+
const openCheckEntitlmentsEditor = (): void => {
|
103
|
+
queryBuilderState.checkEntitlementsState.setShowCheckEntitlementsViewer(
|
104
|
+
true,
|
105
|
+
);
|
106
|
+
};
|
107
|
+
|
108
|
+
return (
|
109
|
+
<>
|
110
|
+
{isPermissionDeniedError() && (
|
111
|
+
<div className="query-builder__result__permission-error">
|
112
|
+
<div className="query-builder__result__permission-error__header">
|
113
|
+
Entitlement / Authorization error - Please
|
114
|
+
</div>
|
115
|
+
<button
|
116
|
+
className="query-builder__result__permission-error__button"
|
117
|
+
disabled={
|
118
|
+
(queryBuilderState.isQuerySupported &&
|
119
|
+
queryBuilderState.fetchStructureState
|
120
|
+
.implementation instanceof QueryBuilderTDSState &&
|
121
|
+
queryBuilderState.fetchStructureState.implementation
|
122
|
+
.projectionColumns.length === 0) ||
|
123
|
+
!queryBuilderState.canBuildQuery
|
124
|
+
}
|
125
|
+
onClick={openCheckEntitlmentsEditor}
|
126
|
+
>
|
127
|
+
Click Here to Check Entitlements
|
128
|
+
</button>
|
129
|
+
</div>
|
130
|
+
)}
|
131
|
+
<div className="query-builder__result__execution-error">
|
132
|
+
<div className="query-builder__result__execution-error__header">
|
133
|
+
<span style={{ fontWeight: 'bold' }}>Error Execution Query</span>.
|
134
|
+
Please try again later or review options in application`s
|
135
|
+
<span style={{ fontWeight: 'bold' }}> Help</span> menu.
|
136
|
+
</div>
|
137
|
+
<div className="query-builder__result__execution-error__body">
|
138
|
+
{errorMessage}
|
139
|
+
</div>
|
140
|
+
</div>
|
141
|
+
</>
|
142
|
+
);
|
143
|
+
},
|
144
|
+
);
|
145
|
+
|
146
|
+
export const QueryBuilderEmptyExecutionResultPanel = observer(
|
147
|
+
(props: { queryBuilderState: QueryBuilderState }) => {
|
148
|
+
const { queryBuilderState } = props;
|
149
|
+
|
150
|
+
const openCheckEntitlmentsEditor = (): void => {
|
151
|
+
queryBuilderState.checkEntitlementsState.setShowCheckEntitlementsViewer(
|
152
|
+
true,
|
153
|
+
);
|
154
|
+
};
|
155
|
+
|
156
|
+
return (
|
157
|
+
<div className="query-builder__result__empty-result-warning">
|
158
|
+
<div className="query-builder__result__empty-result-warning__header">
|
159
|
+
Query returned no data
|
160
|
+
</div>
|
161
|
+
<div className="query-builder__result__empty-result-warning__body">
|
162
|
+
If you believe the query should return data, please
|
163
|
+
<button
|
164
|
+
className="query-builder__result__permission-error__button"
|
165
|
+
disabled={
|
166
|
+
(queryBuilderState.isQuerySupported &&
|
167
|
+
queryBuilderState.fetchStructureState.implementation instanceof
|
168
|
+
QueryBuilderTDSState &&
|
169
|
+
queryBuilderState.fetchStructureState.implementation
|
170
|
+
.projectionColumns.length === 0) ||
|
171
|
+
!queryBuilderState.canBuildQuery
|
172
|
+
}
|
173
|
+
onClick={openCheckEntitlmentsEditor}
|
174
|
+
>
|
175
|
+
Click Here to Check Entitlements
|
176
|
+
</button>
|
177
|
+
or See Help menu for more options
|
178
|
+
</div>
|
179
|
+
</div>
|
180
|
+
);
|
181
|
+
},
|
182
|
+
);
|
183
|
+
import { QueryBuilderBaseInfoTooltip } from '../shared/QueryBuilderPropertyInfoTooltip.js';
|
80
184
|
|
81
185
|
export const QueryBuilderResultValues = observer(
|
82
186
|
(props: {
|
@@ -85,20 +189,28 @@ export const QueryBuilderResultValues = observer(
|
|
85
189
|
}) => {
|
86
190
|
const { executionResult, queryBuilderState } = props;
|
87
191
|
if (executionResult instanceof TDSExecutionResult) {
|
88
|
-
if (
|
192
|
+
if (executionResult.result.rows.length === 0) {
|
89
193
|
return (
|
90
|
-
<
|
194
|
+
<QueryBuilderEmptyExecutionResultPanel
|
91
195
|
queryBuilderState={queryBuilderState}
|
92
|
-
executionResult={executionResult}
|
93
196
|
/>
|
94
197
|
);
|
95
198
|
} else {
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
199
|
+
if (queryBuilderState.config?.TEMPORARY__enableGridEnterpriseMode) {
|
200
|
+
return (
|
201
|
+
<QueryBuilderTDSGridResult
|
202
|
+
queryBuilderState={queryBuilderState}
|
203
|
+
executionResult={executionResult}
|
204
|
+
/>
|
205
|
+
);
|
206
|
+
} else {
|
207
|
+
return (
|
208
|
+
<QueryBuilderTDSSimpleGridResult
|
209
|
+
queryBuilderState={queryBuilderState}
|
210
|
+
executionResult={executionResult}
|
211
|
+
/>
|
212
|
+
);
|
213
|
+
}
|
102
214
|
}
|
103
215
|
} else if (executionResult instanceof RawExecutionResult) {
|
104
216
|
const inputValue =
|
@@ -134,6 +246,7 @@ export const QueryBuilderResultPanel = observer(
|
|
134
246
|
const resultState = queryBuilderState.resultState;
|
135
247
|
const queryParametersState = queryBuilderState.parametersState;
|
136
248
|
const executionResult = resultState.executionResult;
|
249
|
+
const resultLimit = resultState.getExecutionResultLimit();
|
137
250
|
const [showSqlModal, setShowSqlModal] = useState(false);
|
138
251
|
const executedSql = executionResult
|
139
252
|
? getExecutedSqlFromExecutionResult(executionResult, true)
|
@@ -211,6 +324,7 @@ export const QueryBuilderResultPanel = observer(
|
|
211
324
|
|
212
325
|
const runQuery = (): void => {
|
213
326
|
resultState.setSelectedCells([]);
|
327
|
+
resultState.setExecutionError(undefined);
|
214
328
|
resultState.pressedRunQuery.inProgress();
|
215
329
|
if (
|
216
330
|
queryParametersState.parameterStates.length &&
|
@@ -278,8 +392,7 @@ export const QueryBuilderResultPanel = observer(
|
|
278
392
|
})
|
279
393
|
: undefined;
|
280
394
|
if (_executionResult instanceof TDSExecutionResult) {
|
281
|
-
|
282
|
-
return `${rowLength} row(s)${
|
395
|
+
return `${_executionResult.result.rows.length} row(s)${
|
283
396
|
queryDuration ? ` in ${queryDuration}` : ''
|
284
397
|
}`;
|
285
398
|
}
|
@@ -419,13 +532,62 @@ export const QueryBuilderResultPanel = observer(
|
|
419
532
|
Running Query...
|
420
533
|
</div>
|
421
534
|
)}
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
535
|
+
{resultDescription && resultState.executionTraceId && (
|
536
|
+
<div
|
537
|
+
data-testid={
|
538
|
+
QUERY_BUILDER_TEST_ID.QUERY_BUILDER_RESULT_ANALYTICS
|
539
|
+
}
|
540
|
+
className="query-builder__result__analytics"
|
541
|
+
>
|
542
|
+
<QueryBuilderBaseInfoTooltip
|
543
|
+
title="Execution Result Analytics"
|
544
|
+
data={[
|
545
|
+
{
|
546
|
+
label: 'Trace',
|
547
|
+
value: 'available here',
|
548
|
+
actionButton: (
|
549
|
+
<div className="query-builder__tooltip__item__action">
|
550
|
+
<button
|
551
|
+
disabled={
|
552
|
+
!queryBuilderState.config?.zipkinTraceBaseURL
|
553
|
+
}
|
554
|
+
title={
|
555
|
+
queryBuilderState.config?.zipkinTraceBaseURL
|
556
|
+
? ''
|
557
|
+
: 'No zipkin trace URL configured'
|
558
|
+
}
|
559
|
+
onClick={() => {
|
560
|
+
if (
|
561
|
+
queryBuilderState.config?.zipkinTraceBaseURL
|
562
|
+
) {
|
563
|
+
applicationStore.navigationService.navigator.visitAddress(
|
564
|
+
queryBuilderState.config.zipkinTraceBaseURL +
|
565
|
+
resultState.executionTraceId,
|
566
|
+
);
|
567
|
+
}
|
568
|
+
}}
|
569
|
+
>
|
570
|
+
<ShareBoxIcon />
|
571
|
+
</button>
|
572
|
+
</div>
|
573
|
+
),
|
574
|
+
},
|
575
|
+
]}
|
576
|
+
>
|
577
|
+
<div className="editable-value">{resultDescription}</div>
|
578
|
+
</QueryBuilderBaseInfoTooltip>
|
579
|
+
</div>
|
580
|
+
)}
|
581
|
+
{resultDescription && !resultState.executionTraceId && (
|
582
|
+
<div
|
583
|
+
data-testid={
|
584
|
+
QUERY_BUILDER_TEST_ID.QUERY_BUILDER_RESULT_ANALYTICS
|
585
|
+
}
|
586
|
+
className="query-builder__result__analytics"
|
587
|
+
>
|
588
|
+
{resultDescription}
|
589
|
+
</div>
|
590
|
+
)}
|
429
591
|
{executionResult && resultState.checkForStaleResults && (
|
430
592
|
<div className="query-builder__result__stale-status">
|
431
593
|
<div className="query-builder__result__stale-status__icon">
|
@@ -436,6 +598,25 @@ export const QueryBuilderResultPanel = observer(
|
|
436
598
|
</div>
|
437
599
|
</div>
|
438
600
|
)}
|
601
|
+
{executionResult &&
|
602
|
+
executionResult instanceof TDSExecutionResult &&
|
603
|
+
resultState.isExecutionResultOverflowing && (
|
604
|
+
<div className="query-builder__result__stale-status">
|
605
|
+
<div className="query-builder__result__stale-status__icon">
|
606
|
+
<ExclamationTriangleIcon />
|
607
|
+
</div>
|
608
|
+
<div className="query-builder__result__stale-status__label">
|
609
|
+
Data below is not complete - query produces more rows than
|
610
|
+
the set grid preview limit
|
611
|
+
</div>
|
612
|
+
<div
|
613
|
+
className="query-builder__result__stale-status__icon"
|
614
|
+
title={`The preview limit is set to ${resultLimit}. The results in the grid below are being limited by this limit and running query with a higher limit would produce more rows. Export will not apply this limit.`}
|
615
|
+
>
|
616
|
+
<InfoCircleIcon />
|
617
|
+
</div>
|
618
|
+
</div>
|
619
|
+
)}
|
439
620
|
</div>
|
440
621
|
<div className="panel__header__actions query-builder__result__header__actions">
|
441
622
|
{resultState.exportState.isInProgress && (
|
@@ -638,12 +819,18 @@ export const QueryBuilderResultPanel = observer(
|
|
638
819
|
<CubesLoadingIndicator isLoading={isLoading}>
|
639
820
|
<CubesLoadingIndicatorIcon />
|
640
821
|
</CubesLoadingIndicator>
|
641
|
-
{!executionResult && !isLoading && (
|
822
|
+
{!executionResult && !isLoading && !resultState.executionError && (
|
642
823
|
<BlankPanelContent>
|
643
824
|
Build or load a valid query first
|
644
825
|
</BlankPanelContent>
|
645
826
|
)}
|
646
|
-
{
|
827
|
+
{!isLoading && resultState.executionError && (
|
828
|
+
<QueryBuilderExecutionErrorPanel
|
829
|
+
resultState={resultState}
|
830
|
+
executionError={resultState.executionError}
|
831
|
+
/>
|
832
|
+
)}
|
833
|
+
{executionResult && !isLoading && !resultState.executionError && (
|
647
834
|
<div className="query-builder__result__values">
|
648
835
|
<QueryBuilderResultValues
|
649
836
|
executionResult={executionResult}
|