@finos/legend-query-builder 4.0.8 → 4.0.10
Sign up to get free protection for your applications and to get access to all the features.
- package/lib/__lib__/QueryBuilderColorTheme.js +1 -1
- package/lib/__lib__/QueryBuilderColorTheme.js.map +1 -1
- package/lib/__lib__/QueryBuilderDocumentation.js +1 -1
- package/lib/__lib__/QueryBuilderDocumentation.js.map +1 -1
- package/lib/__lib__/QueryBuilderEvent.js +3 -3
- package/lib/__lib__/QueryBuilderEvent.js.map +1 -1
- package/lib/__lib__/QueryBuilderSetting.js +1 -1
- package/lib/__lib__/QueryBuilderSetting.js.map +1 -1
- package/lib/__lib__/QueryBuilderTesting.js +1 -1
- package/lib/__lib__/QueryBuilderTesting.js.map +1 -1
- package/lib/components/QueryBuilderComponentElement.js +1 -1
- package/lib/components/QueryBuilderComponentElement.js.map +1 -1
- package/lib/components/QueryBuilderResultPanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderResultPanel.js +210 -69
- package/lib/components/QueryBuilderResultPanel.js.map +1 -1
- package/lib/components/QueryBuilder_LegendApplicationPlugin.js +1 -2
- package/lib/components/QueryBuilder_LegendApplicationPlugin.js.map +1 -1
- package/lib/components/explorer/QueryBuilderExplorerPanel.d.ts.map +1 -1
- package/lib/components/explorer/QueryBuilderExplorerPanel.js +3 -3
- package/lib/components/explorer/QueryBuilderExplorerPanel.js.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderFetchStructurePanel.d.ts.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderFetchStructurePanel.js +3 -3
- package/lib/components/fetch-structure/QueryBuilderFetchStructurePanel.js.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.d.ts.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js +60 -21
- 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 +10 -2
- 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 +2 -2
- package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.js.map +1 -1
- package/lib/components/filter/QueryBuilderFilterPanel.d.ts +4 -0
- package/lib/components/filter/QueryBuilderFilterPanel.d.ts.map +1 -1
- package/lib/components/filter/QueryBuilderFilterPanel.js +69 -31
- package/lib/components/filter/QueryBuilderFilterPanel.js.map +1 -1
- package/lib/components/shared/CustomDatePicker.js +1 -1
- package/lib/components/shared/CustomDatePicker.js.map +1 -1
- package/lib/graph/QueryBuilderMetaModelConst.js +3 -3
- package/lib/graph/QueryBuilderMetaModelConst.js.map +1 -1
- package/lib/graph-manager/QueryBuilderConst.js +1 -1
- package/lib/graph-manager/QueryBuilderConst.js.map +1 -1
- package/lib/graph-manager/protocol/pure/v1/V1_QueryBuilder_PureGraphManagerExtension.d.ts.map +1 -1
- package/lib/graph-manager/protocol/pure/v1/V1_QueryBuilder_PureGraphManagerExtension.js +4 -4
- package/lib/graph-manager/protocol/pure/v1/V1_QueryBuilder_PureGraphManagerExtension.js.map +1 -1
- package/lib/index.css +17 -1
- package/lib/index.css.map +1 -1
- package/lib/package.json +7 -7
- package/lib/stores/QueryBuilderChangeDetectionState.js +1 -1
- package/lib/stores/QueryBuilderChangeDetectionState.js.map +1 -1
- package/lib/stores/QueryBuilderCommand.js +1 -1
- package/lib/stores/QueryBuilderCommand.js.map +1 -1
- package/lib/stores/QueryBuilderConfig.js +2 -2
- package/lib/stores/QueryBuilderConfig.js.map +1 -1
- package/lib/stores/QueryBuilderGroupOperationHelper.js +1 -1
- package/lib/stores/QueryBuilderGroupOperationHelper.js.map +1 -1
- package/lib/stores/QueryBuilderResultState.d.ts +19 -0
- package/lib/stores/QueryBuilderResultState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderResultState.js +48 -1
- package/lib/stores/QueryBuilderResultState.js.map +1 -1
- package/lib/stores/QueryBuilderStateHashUtils.js +1 -1
- package/lib/stores/QueryBuilderStateHashUtils.js.map +1 -1
- package/lib/stores/QueryBuilderTextEditorState.js +1 -1
- package/lib/stores/QueryBuilderTextEditorState.js.map +1 -1
- package/lib/stores/execution-plan/ExecutionPlanState.js +1 -1
- package/lib/stores/execution-plan/ExecutionPlanState.js.map +1 -1
- package/lib/stores/explorer/QueryBuilderExplorerState.js +1 -1
- package/lib/stores/explorer/QueryBuilderExplorerState.js.map +1 -1
- package/lib/stores/fetch-structure/QueryBuilderFetchStructureImplementationState.js +1 -1
- package/lib/stores/fetch-structure/QueryBuilderFetchStructureImplementationState.js.map +1 -1
- package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.js +2 -2
- package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.js.map +1 -1
- package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.js +1 -1
- package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.js.map +1 -1
- package/lib/stores/fetch-structure/tds/QueryResultSetModifierState.js +1 -1
- package/lib/stores/fetch-structure/tds/QueryResultSetModifierState.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 +2 -2
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js.map +1 -1
- package/lib/stores/filter/QueryBuilderFilterState.js +1 -1
- package/lib/stores/filter/QueryBuilderFilterState.js.map +1 -1
- package/lib/stores/shared/LambdaParameterState.d.ts.map +1 -1
- package/lib/stores/shared/LambdaParameterState.js +2 -2
- package/lib/stores/shared/LambdaParameterState.js.map +1 -1
- package/lib/stores/shared/ValueSpecificationEditorHelper.d.ts +5 -2
- package/lib/stores/shared/ValueSpecificationEditorHelper.d.ts.map +1 -1
- package/lib/stores/shared/ValueSpecificationEditorHelper.js +30 -40
- package/lib/stores/shared/ValueSpecificationEditorHelper.js.map +1 -1
- package/package.json +15 -15
- package/src/components/QueryBuilderResultPanel.tsx +358 -93
- package/src/components/explorer/QueryBuilderExplorerPanel.tsx +10 -14
- package/src/components/fetch-structure/QueryBuilderFetchStructurePanel.tsx +6 -4
- package/src/components/fetch-structure/QueryBuilderPostFilterPanel.tsx +103 -14
- package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +18 -1
- package/src/components/fetch-structure/QueryBuilderTDSWindowPanel.tsx +12 -10
- package/src/components/filter/QueryBuilderFilterPanel.tsx +134 -42
- package/src/graph-manager/protocol/pure/v1/V1_QueryBuilder_PureGraphManagerExtension.ts +4 -5
- package/src/stores/QueryBuilderResultState.ts +82 -0
- package/src/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.ts +1 -0
- package/src/stores/shared/LambdaParameterState.ts +1 -0
- package/src/stores/shared/ValueSpecificationEditorHelper.ts +80 -57
@@ -56,7 +56,7 @@ import {
|
|
56
56
|
QueryBuilderFilterTreeBlankConditionNodeData,
|
57
57
|
QueryBuilderFilterTreeGroupNodeData,
|
58
58
|
} from '../../stores/filter/QueryBuilderFilterState.js';
|
59
|
-
import { useDrag, useDrop } from 'react-dnd';
|
59
|
+
import { useDrag, useDragLayer, useDrop } from 'react-dnd';
|
60
60
|
import {
|
61
61
|
type QueryBuilderExplorerTreeDragSource,
|
62
62
|
type QueryBuilderExplorerTreePropertyNodeData,
|
@@ -88,12 +88,26 @@ import {
|
|
88
88
|
} from '../shared/BasicValueSpecificationEditor.js';
|
89
89
|
import { QueryBuilderTelemetryHelper } from '../../__lib__/QueryBuilderTelemetryHelper.js';
|
90
90
|
|
91
|
+
export const IS_DRAGGABLE_FILTER_DND_TYPES_FETCH_SUPPORTED = [
|
92
|
+
QUERY_BUILDER_FILTER_DND_TYPE.CONDITION,
|
93
|
+
QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.ENUM_PROPERTY,
|
94
|
+
QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.PRIMITIVE_PROPERTY,
|
95
|
+
QUERY_BUILDER_PROJECTION_COLUMN_DND_TYPE,
|
96
|
+
];
|
97
|
+
|
98
|
+
export const IS_DRAGGABLE_FILTER_DND_TYPES = [
|
99
|
+
QUERY_BUILDER_FILTER_DND_TYPE.CONDITION,
|
100
|
+
QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.ENUM_PROPERTY,
|
101
|
+
QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.PRIMITIVE_PROPERTY,
|
102
|
+
];
|
103
|
+
|
91
104
|
const QueryBuilderFilterGroupConditionEditor = observer(
|
92
105
|
(props: {
|
93
106
|
node: QueryBuilderFilterTreeGroupNodeData;
|
94
107
|
isDragOver: boolean;
|
108
|
+
showDroppableSuggestion: boolean;
|
95
109
|
}) => {
|
96
|
-
const { node, isDragOver } = props;
|
110
|
+
const { node, isDragOver, showDroppableSuggestion } = props;
|
97
111
|
const switchOperation: React.MouseEventHandler<HTMLDivElement> = (
|
98
112
|
event,
|
99
113
|
): void => {
|
@@ -105,30 +119,31 @@ const QueryBuilderFilterGroupConditionEditor = observer(
|
|
105
119
|
);
|
106
120
|
};
|
107
121
|
return (
|
108
|
-
<div className="query-builder-filter-tree__node__label__content">
|
109
|
-
|
110
|
-
showPlaceholder={isDragOver}
|
111
|
-
label="Add to Logical Group"
|
112
|
-
className="query-builder__dnd__placeholder"
|
113
|
-
>
|
122
|
+
<div className="query-builder-filter-tree__node__label__content dnd__entry__container">
|
123
|
+
{showDroppableSuggestion && (
|
114
124
|
<div
|
115
|
-
className={clsx('
|
116
|
-
'
|
117
|
-
node.groupOperation === QUERY_BUILDER_GROUP_OPERATION.AND,
|
118
|
-
'query-builder-filter-tree__group-node--or':
|
119
|
-
node.groupOperation === QUERY_BUILDER_GROUP_OPERATION.OR,
|
125
|
+
className={clsx('dnd__entry--droppable__indicator ', {
|
126
|
+
'dnd__entry--droppable__indicator--dragover': isDragOver,
|
120
127
|
})}
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
128
|
+
></div>
|
129
|
+
)}
|
130
|
+
<div
|
131
|
+
className={clsx('query-builder-filter-tree__group-node', {
|
132
|
+
'query-builder-filter-tree__group-node--and':
|
133
|
+
node.groupOperation === QUERY_BUILDER_GROUP_OPERATION.AND,
|
134
|
+
'query-builder-filter-tree__group-node--or':
|
135
|
+
node.groupOperation === QUERY_BUILDER_GROUP_OPERATION.OR,
|
136
|
+
})}
|
137
|
+
title="Switch Operation"
|
138
|
+
onClick={switchOperation}
|
139
|
+
>
|
140
|
+
<div className="query-builder-filter-tree__group-node__label">
|
141
|
+
{node.groupOperation}
|
130
142
|
</div>
|
131
|
-
|
143
|
+
<button className="query-builder-filter-tree__group-node__action">
|
144
|
+
<FilledTriangleIcon />
|
145
|
+
</button>
|
146
|
+
</div>
|
132
147
|
</div>
|
133
148
|
);
|
134
149
|
},
|
@@ -190,6 +205,7 @@ const QueryBuilderFilterConditionEditor = observer(
|
|
190
205
|
}),
|
191
206
|
[handleDrop],
|
192
207
|
);
|
208
|
+
|
193
209
|
const resetNode = (): void => {
|
194
210
|
node.condition.setValue(
|
195
211
|
node.condition.operator.getDefaultFilterConditionValue(node.condition),
|
@@ -215,8 +231,29 @@ const QueryBuilderFilterConditionEditor = observer(
|
|
215
231
|
reloadValues: debouncedTypeaheadSearch,
|
216
232
|
cleanUpReloadValues,
|
217
233
|
};
|
234
|
+
|
235
|
+
const { showDroppableSuggestion } = useDragLayer((monitor) => ({
|
236
|
+
showDroppableSuggestion:
|
237
|
+
monitor.isDragging() &&
|
238
|
+
(queryBuilderState.TEMPORARY__isDnDFetchStructureToFilterSupported
|
239
|
+
? IS_DRAGGABLE_FILTER_DND_TYPES_FETCH_SUPPORTED
|
240
|
+
: IS_DRAGGABLE_FILTER_DND_TYPES
|
241
|
+
).includes(monitor.getItemType()?.toString() ?? ''),
|
242
|
+
}));
|
243
|
+
|
218
244
|
return (
|
219
|
-
<div className="query-builder-filter-tree__node__label__content">
|
245
|
+
<div className="query-builder-filter-tree__node__label__content dnd__entry__container">
|
246
|
+
{showDroppableSuggestion && (
|
247
|
+
<div
|
248
|
+
className={clsx(
|
249
|
+
'dnd__entry--droppable__indicator dnd__entry-potential__oiodropzone__indicator--full',
|
250
|
+
{
|
251
|
+
'dnd__entry--droppable__indicator--dragover': isDragOver,
|
252
|
+
},
|
253
|
+
)}
|
254
|
+
></div>
|
255
|
+
)}
|
256
|
+
|
220
257
|
<PanelEntryDropZonePlaceholder
|
221
258
|
showPlaceholder={isDragOver}
|
222
259
|
label="Add New Logical Group"
|
@@ -299,8 +336,9 @@ const QueryBuilderFilterBlankConditionEditor = observer(
|
|
299
336
|
(props: {
|
300
337
|
node: QueryBuilderFilterTreeBlankConditionNodeData;
|
301
338
|
isDragOver: boolean;
|
339
|
+
showDroppableSuggestion: boolean;
|
302
340
|
}) => {
|
303
|
-
const { isDragOver } = props;
|
341
|
+
const { isDragOver, showDroppableSuggestion } = props;
|
304
342
|
return (
|
305
343
|
<div className="query-builder-filter-tree__node__label__content">
|
306
344
|
<PanelEntryDropZonePlaceholder
|
@@ -308,6 +346,9 @@ const QueryBuilderFilterBlankConditionEditor = observer(
|
|
308
346
|
label="Create Condition"
|
309
347
|
className="query-builder__dnd__placeholder"
|
310
348
|
>
|
349
|
+
{showDroppableSuggestion && (
|
350
|
+
<div className="query-builder-filter-tree__blank-node--droppable"></div>
|
351
|
+
)}
|
311
352
|
<div className="query-builder-filter-tree__blank-node">blank</div>
|
312
353
|
</PanelEntryDropZonePlaceholder>
|
313
354
|
</div>
|
@@ -390,11 +431,31 @@ const QueryBuilderFilterTreeNodeContainer = observer(
|
|
390
431
|
// Drag and Drop
|
391
432
|
const handleDrop = useCallback(
|
392
433
|
(item: QueryBuilderFilterDropTarget, type: string): void => {
|
393
|
-
if (
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
434
|
+
if (QUERY_BUILDER_FILTER_DND_TYPE.CONDITION === type) {
|
435
|
+
const nodeBeingDragged = (
|
436
|
+
item as QueryBuilderFilterConditionDragSource
|
437
|
+
).node;
|
438
|
+
|
439
|
+
const newCreatedNode = new QueryBuilderFilterTreeConditionNodeData(
|
440
|
+
undefined,
|
441
|
+
(
|
442
|
+
filterState.nodes.get(
|
443
|
+
nodeBeingDragged.id,
|
444
|
+
) as QueryBuilderFilterTreeConditionNodeData
|
445
|
+
).condition,
|
446
|
+
);
|
447
|
+
|
448
|
+
if (node instanceof QueryBuilderFilterTreeBlankConditionNodeData) {
|
449
|
+
filterState.replaceBlankNodeWithNode(newCreatedNode, node);
|
450
|
+
filterState.removeNodeAndPruneBranch(nodeBeingDragged);
|
451
|
+
} else if (node instanceof QueryBuilderFilterTreeConditionNodeData) {
|
452
|
+
filterState.newGroupWithConditionFromNode(newCreatedNode, node);
|
453
|
+
|
454
|
+
filterState.removeNodeAndPruneBranch(nodeBeingDragged);
|
455
|
+
} else if (node instanceof QueryBuilderFilterTreeGroupNodeData) {
|
456
|
+
filterState.addNodeFromNode(newCreatedNode, node);
|
457
|
+
filterState.removeNodeAndPruneBranch(nodeBeingDragged);
|
458
|
+
}
|
398
459
|
} else {
|
399
460
|
let filterConditionState: FilterConditionState;
|
400
461
|
try {
|
@@ -469,17 +530,8 @@ const QueryBuilderFilterTreeNodeContainer = observer(
|
|
469
530
|
() => ({
|
470
531
|
accept:
|
471
532
|
queryBuilderState.TEMPORARY__isDnDFetchStructureToFilterSupported
|
472
|
-
?
|
473
|
-
|
474
|
-
QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.ENUM_PROPERTY,
|
475
|
-
QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.PRIMITIVE_PROPERTY,
|
476
|
-
QUERY_BUILDER_PROJECTION_COLUMN_DND_TYPE,
|
477
|
-
]
|
478
|
-
: [
|
479
|
-
...Object.values(QUERY_BUILDER_FILTER_DND_TYPE),
|
480
|
-
QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.ENUM_PROPERTY,
|
481
|
-
QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.PRIMITIVE_PROPERTY,
|
482
|
-
],
|
533
|
+
? IS_DRAGGABLE_FILTER_DND_TYPES_FETCH_SUPPORTED
|
534
|
+
: IS_DRAGGABLE_FILTER_DND_TYPES,
|
483
535
|
drop: (item, monitor): void => {
|
484
536
|
if (!monitor.didDrop()) {
|
485
537
|
handleDrop(item, monitor.getItemType() as string);
|
@@ -508,6 +560,15 @@ const QueryBuilderFilterTreeNodeContainer = observer(
|
|
508
560
|
dragConnector(dropConnector(ref));
|
509
561
|
useDragPreviewLayer(dragPreviewConnector);
|
510
562
|
|
563
|
+
const { showDroppableSuggestion } = useDragLayer((monitor) => ({
|
564
|
+
showDroppableSuggestion:
|
565
|
+
monitor.isDragging() &&
|
566
|
+
(queryBuilderState.TEMPORARY__isDnDFetchStructureToFilterSupported
|
567
|
+
? IS_DRAGGABLE_FILTER_DND_TYPES_FETCH_SUPPORTED
|
568
|
+
: IS_DRAGGABLE_FILTER_DND_TYPES
|
569
|
+
).includes(monitor.getItemType()?.toString() ?? ''),
|
570
|
+
}));
|
571
|
+
|
511
572
|
// context menu
|
512
573
|
const onContextMenuOpen = (): void => setIsSelectedFromContextMenu(true);
|
513
574
|
const onContextMenuClose = (): void => setIsSelectedFromContextMenu(false);
|
@@ -566,6 +627,7 @@ const QueryBuilderFilterTreeNodeContainer = observer(
|
|
566
627
|
{node instanceof QueryBuilderFilterTreeGroupNodeData && (
|
567
628
|
<QueryBuilderFilterGroupConditionEditor
|
568
629
|
node={node}
|
630
|
+
showDroppableSuggestion={showDroppableSuggestion}
|
569
631
|
isDragOver={isDragOver}
|
570
632
|
/>
|
571
633
|
)}
|
@@ -579,6 +641,7 @@ const QueryBuilderFilterTreeNodeContainer = observer(
|
|
579
641
|
<QueryBuilderFilterBlankConditionEditor
|
580
642
|
node={node}
|
581
643
|
isDragOver={isDragOver}
|
644
|
+
showDroppableSuggestion={showDroppableSuggestion}
|
582
645
|
/>
|
583
646
|
)}
|
584
647
|
</div>
|
@@ -747,6 +810,16 @@ export const QueryBuilderFilterPanel = observer(
|
|
747
810
|
);
|
748
811
|
}
|
749
812
|
};
|
813
|
+
|
814
|
+
const { showDroppableSuggestion } = useDragLayer((monitor) => ({
|
815
|
+
showDroppableSuggestion:
|
816
|
+
monitor.isDragging() &&
|
817
|
+
(queryBuilderState.TEMPORARY__isDnDFetchStructureToFilterSupported
|
818
|
+
? IS_DRAGGABLE_FILTER_DND_TYPES_FETCH_SUPPORTED
|
819
|
+
: IS_DRAGGABLE_FILTER_DND_TYPES
|
820
|
+
).includes(monitor.getItemType()?.toString() ?? ''),
|
821
|
+
}));
|
822
|
+
|
750
823
|
// Drag and Drop
|
751
824
|
const handleDrop = useCallback(
|
752
825
|
(item: QueryBuilderFilterDropTarget, type: string): void => {
|
@@ -795,6 +868,7 @@ export const QueryBuilderFilterPanel = observer(
|
|
795
868
|
},
|
796
869
|
[applicationStore, filterState],
|
797
870
|
);
|
871
|
+
|
798
872
|
const [{ isDragOver }, dropTargetConnector] = useDrop<
|
799
873
|
QueryBuilderExplorerTreeDragSource,
|
800
874
|
void,
|
@@ -913,7 +987,11 @@ export const QueryBuilderFilterPanel = observer(
|
|
913
987
|
</div>
|
914
988
|
<PanelContent>
|
915
989
|
<PanelDropZone
|
916
|
-
isDragOver={isDragOver}
|
990
|
+
isDragOver={isDragOver && filterState.isEmpty}
|
991
|
+
showDroppableSuggestion={
|
992
|
+
showDroppableSuggestion && filterState.isEmpty
|
993
|
+
}
|
994
|
+
className="query-builder__panel--droppable"
|
917
995
|
dropTargetConnector={dropTargetConnector}
|
918
996
|
>
|
919
997
|
{filterState.isEmpty && (
|
@@ -933,6 +1011,20 @@ export const QueryBuilderFilterPanel = observer(
|
|
933
1011
|
<QueryBuilderFilterTree queryBuilderState={queryBuilderState} />
|
934
1012
|
</>
|
935
1013
|
)}
|
1014
|
+
|
1015
|
+
{showDroppableSuggestion && !filterState.isEmpty && (
|
1016
|
+
<div
|
1017
|
+
ref={dropTargetConnector}
|
1018
|
+
className={clsx(
|
1019
|
+
'query-builder-post-filter-tree__blank-node--droppable--tall',
|
1020
|
+
{
|
1021
|
+
'dnd__entry--droppable__indicator--dragover': isDragOver,
|
1022
|
+
},
|
1023
|
+
)}
|
1024
|
+
>
|
1025
|
+
Add filter to main group
|
1026
|
+
</div>
|
1027
|
+
)}
|
936
1028
|
</PanelDropZone>
|
937
1029
|
</PanelContent>
|
938
1030
|
</div>
|
@@ -25,7 +25,6 @@ import {
|
|
25
25
|
V1_PureMultiExecution,
|
26
26
|
V1_Service,
|
27
27
|
V1_PackageableRuntime,
|
28
|
-
type V1_PackageableElement,
|
29
28
|
type PureModel,
|
30
29
|
V1_PureGraphManager,
|
31
30
|
PureClientVersion,
|
@@ -72,10 +71,10 @@ export class V1_QueryBuilder_PureGraphManagerExtension extends QueryBuilder_Pure
|
|
72
71
|
entities,
|
73
72
|
dependencyEntitiesIndex,
|
74
73
|
(entity: Entity): boolean =>
|
75
|
-
(
|
76
|
-
|
77
|
-
(
|
78
|
-
|
74
|
+
(entity.content._type as string) ===
|
75
|
+
V1_MAPPING_ELEMENT_PROTOCOL_TYPE ||
|
76
|
+
(entity.content._type as string) ===
|
77
|
+
V1_PACKAGEABLE_RUNTIME_ELEMENT_PROTOCOL_TYPE,
|
79
78
|
);
|
80
79
|
// handle mapping includes
|
81
80
|
const mappings = [
|
@@ -37,6 +37,7 @@ import {
|
|
37
37
|
buildRawLambdaFromLambdaFunction,
|
38
38
|
reportGraphAnalytics,
|
39
39
|
extractExecutionResultValues,
|
40
|
+
TDSExecutionResult,
|
40
41
|
} from '@finos/legend-graph';
|
41
42
|
import { buildLambdaFunction } from './QueryBuilderValueSpecificationBuilder.js';
|
42
43
|
import { DEFAULT_TAB_SIZE } from '@finos/legend-application';
|
@@ -56,6 +57,17 @@ export interface ExportDataInfo {
|
|
56
57
|
serializationFormat?: EXECUTION_SERIALIZATION_FORMAT | undefined;
|
57
58
|
}
|
58
59
|
|
60
|
+
export interface QueryBuilderTDSResultCellData {
|
61
|
+
value: string | number | boolean | null | undefined;
|
62
|
+
columnName: string;
|
63
|
+
coordinates: QueryBuilderTDSResultCellCoordinate;
|
64
|
+
}
|
65
|
+
|
66
|
+
export interface QueryBuilderTDSResultCellCoordinate {
|
67
|
+
rowIndex: number;
|
68
|
+
colIndex: number;
|
69
|
+
}
|
70
|
+
|
59
71
|
export class QueryBuilderResultState {
|
60
72
|
readonly queryBuilderState: QueryBuilderState;
|
61
73
|
readonly exportDataState = ActionState.create();
|
@@ -70,6 +82,10 @@ export class QueryBuilderResultState {
|
|
70
82
|
latestRunHashCode?: string | undefined;
|
71
83
|
queryRunPromise: Promise<ExecutionResult> | undefined = undefined;
|
72
84
|
|
85
|
+
selectedCells: QueryBuilderTDSResultCellData[];
|
86
|
+
mousedOverCell: QueryBuilderTDSResultCellData | null = null;
|
87
|
+
isSelectingCells: boolean;
|
88
|
+
|
73
89
|
constructor(queryBuilderState: QueryBuilderState) {
|
74
90
|
makeObservable(this, {
|
75
91
|
executionResult: observable,
|
@@ -78,18 +94,28 @@ export class QueryBuilderResultState {
|
|
78
94
|
latestRunHashCode: observable,
|
79
95
|
queryRunPromise: observable,
|
80
96
|
isGeneratingPlan: observable,
|
97
|
+
selectedCells: observable,
|
98
|
+
mousedOverCell: observable,
|
81
99
|
isRunningQuery: observable,
|
100
|
+
isSelectingCells: observable,
|
101
|
+
setIsSelectingCells: action,
|
82
102
|
setIsRunningQuery: action,
|
83
103
|
setExecutionResult: action,
|
84
104
|
setExecutionDuration: action,
|
85
105
|
setPreviewLimit: action,
|
106
|
+
addCellData: action,
|
107
|
+
setSelectedCells: action,
|
108
|
+
setMouseOverCell: action,
|
86
109
|
setQueryRunPromise: action,
|
110
|
+
|
87
111
|
exportData: flow,
|
88
112
|
runQuery: flow,
|
89
113
|
cancelQuery: flow,
|
90
114
|
generatePlan: flow,
|
91
115
|
});
|
116
|
+
this.isSelectingCells = false;
|
92
117
|
|
118
|
+
this.selectedCells = [];
|
93
119
|
this.queryBuilderState = queryBuilderState;
|
94
120
|
this.executionPlanState = new ExecutionPlanState(
|
95
121
|
this.queryBuilderState.applicationStore,
|
@@ -97,6 +123,10 @@ export class QueryBuilderResultState {
|
|
97
123
|
);
|
98
124
|
}
|
99
125
|
|
126
|
+
setIsSelectingCells = (val: boolean): void => {
|
127
|
+
this.isSelectingCells = val;
|
128
|
+
};
|
129
|
+
|
100
130
|
setIsRunningQuery = (val: boolean): void => {
|
101
131
|
this.isRunningQuery = val;
|
102
132
|
};
|
@@ -113,12 +143,64 @@ export class QueryBuilderResultState {
|
|
113
143
|
this.previewLimit = Math.max(1, val);
|
114
144
|
};
|
115
145
|
|
146
|
+
addCellData = (val: QueryBuilderTDSResultCellData): void => {
|
147
|
+
this.selectedCells.push(val);
|
148
|
+
};
|
149
|
+
|
150
|
+
setSelectedCells = (val: QueryBuilderTDSResultCellData[]): void => {
|
151
|
+
this.selectedCells = val;
|
152
|
+
};
|
153
|
+
|
154
|
+
setMouseOverCell = (val: QueryBuilderTDSResultCellData | null): void => {
|
155
|
+
this.mousedOverCell = val;
|
156
|
+
};
|
157
|
+
|
116
158
|
setQueryRunPromise = (
|
117
159
|
promise: Promise<ExecutionResult> | undefined,
|
118
160
|
): void => {
|
119
161
|
this.queryRunPromise = promise;
|
120
162
|
};
|
121
163
|
|
164
|
+
findColumnFromCoordinates = (
|
165
|
+
colIndex: number,
|
166
|
+
): string | number | boolean | null | undefined => {
|
167
|
+
if (
|
168
|
+
!this.executionResult ||
|
169
|
+
!(this.executionResult instanceof TDSExecutionResult)
|
170
|
+
) {
|
171
|
+
return undefined;
|
172
|
+
}
|
173
|
+
return this.executionResult.result.columns[colIndex];
|
174
|
+
};
|
175
|
+
|
176
|
+
findRowFromRowIndex = (
|
177
|
+
rowIndex: number,
|
178
|
+
): (string | number | boolean | null)[] => {
|
179
|
+
if (
|
180
|
+
!this.executionResult ||
|
181
|
+
!(this.executionResult instanceof TDSExecutionResult)
|
182
|
+
) {
|
183
|
+
return [''];
|
184
|
+
}
|
185
|
+
return this.executionResult.result.rows[rowIndex]?.values ?? [''];
|
186
|
+
};
|
187
|
+
|
188
|
+
findResultValueFromCoordinates = (
|
189
|
+
resultCoordinate: [number, number],
|
190
|
+
): string | number | boolean | null | undefined => {
|
191
|
+
const rowIndex = resultCoordinate[0];
|
192
|
+
const colIndex = resultCoordinate[1];
|
193
|
+
|
194
|
+
if (
|
195
|
+
!this.executionResult ||
|
196
|
+
!(this.executionResult instanceof TDSExecutionResult)
|
197
|
+
) {
|
198
|
+
return undefined;
|
199
|
+
}
|
200
|
+
|
201
|
+
return this.executionResult.result.rows[rowIndex]?.values[colIndex];
|
202
|
+
};
|
203
|
+
|
122
204
|
get checkForStaleResults(): boolean {
|
123
205
|
if (this.latestRunHashCode !== this.queryBuilderState.hashCode) {
|
124
206
|
return true;
|
@@ -41,16 +41,22 @@ import {
|
|
41
41
|
Multiplicity,
|
42
42
|
CORE_PURE_PATH,
|
43
43
|
buildRawLambdaFromLambdaFunction,
|
44
|
+
getValueSpecificationReturnType,
|
44
45
|
} from '@finos/legend-graph';
|
45
|
-
import {
|
46
|
+
import {
|
47
|
+
Randomizer,
|
48
|
+
UnsupportedOperationError,
|
49
|
+
returnUndefOnError,
|
50
|
+
} from '@finos/legend-shared';
|
46
51
|
import { generateDefaultValueForPrimitiveType } from '../QueryBuilderValueSpecificationHelper.js';
|
47
52
|
import {
|
48
53
|
instanceValue_setValues,
|
49
54
|
valueSpecification_setGenericType,
|
50
55
|
} from './ValueSpecificationModifierHelper.js';
|
51
|
-
import {
|
52
|
-
|
53
|
-
|
56
|
+
import {
|
57
|
+
QUERY_BUILDER_PURE_PATH,
|
58
|
+
QUERY_BUILDER_SUPPORTED_FUNCTIONS,
|
59
|
+
} from '../../graph/QueryBuilderMetaModelConst.js';
|
54
60
|
|
55
61
|
export const createSupportedFunctionExpression = (
|
56
62
|
supportedFuncName: string,
|
@@ -63,52 +69,60 @@ export const createSupportedFunctionExpression = (
|
|
63
69
|
);
|
64
70
|
return funcExpression;
|
65
71
|
};
|
72
|
+
export const buildPrimitiveInstanceValue = (
|
73
|
+
graph: PureModel,
|
74
|
+
type: PRIMITIVE_TYPE,
|
75
|
+
value: unknown,
|
76
|
+
observerContext: ObserverContext,
|
77
|
+
): PrimitiveInstanceValue => {
|
78
|
+
const instance = new PrimitiveInstanceValue(
|
79
|
+
GenericTypeExplicitReference.create(
|
80
|
+
new GenericType(graph.getPrimitiveType(type)),
|
81
|
+
),
|
82
|
+
);
|
83
|
+
instanceValue_setValues(instance, [value], observerContext);
|
84
|
+
return instance;
|
85
|
+
};
|
66
86
|
|
67
87
|
const createMockPrimitiveValueSpecification = (
|
68
88
|
primitiveType: PrimitiveType,
|
69
|
-
|
89
|
+
graph: PureModel,
|
70
90
|
observerContext: ObserverContext,
|
91
|
+
options?: {
|
92
|
+
useCurrentDateDependentFunctions?: boolean;
|
93
|
+
},
|
71
94
|
): ValueSpecification => {
|
72
95
|
const primitiveTypeName = primitiveType.name;
|
73
|
-
if (
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
96
|
+
if (options?.useCurrentDateDependentFunctions) {
|
97
|
+
if (
|
98
|
+
primitiveTypeName === PRIMITIVE_TYPE.DATE ||
|
99
|
+
primitiveTypeName === PRIMITIVE_TYPE.DATETIME
|
100
|
+
) {
|
101
|
+
return createSupportedFunctionExpression(
|
102
|
+
QUERY_BUILDER_SUPPORTED_FUNCTIONS.NOW,
|
103
|
+
PrimitiveType.DATETIME,
|
104
|
+
);
|
105
|
+
} else if (primitiveTypeName === PRIMITIVE_TYPE.STRICTDATE) {
|
106
|
+
return createSupportedFunctionExpression(
|
107
|
+
QUERY_BUILDER_SUPPORTED_FUNCTIONS.TODAY,
|
108
|
+
PrimitiveType.STRICTDATE,
|
109
|
+
);
|
110
|
+
}
|
111
|
+
}
|
112
|
+
if (primitiveTypeName === PRIMITIVE_TYPE.DATE) {
|
113
|
+
return buildPrimitiveInstanceValue(
|
114
|
+
graph,
|
115
|
+
PRIMITIVE_TYPE.STRICTDATE,
|
116
|
+
generateDefaultValueForPrimitiveType(primitiveTypeName),
|
117
|
+
observerContext,
|
85
118
|
);
|
86
119
|
}
|
87
|
-
|
88
|
-
|
120
|
+
return buildPrimitiveInstanceValue(
|
121
|
+
graph,
|
122
|
+
primitiveTypeName as PRIMITIVE_TYPE,
|
123
|
+
generateDefaultValueForPrimitiveType(primitiveTypeName as PRIMITIVE_TYPE),
|
124
|
+
observerContext,
|
89
125
|
);
|
90
|
-
const randomizer = new Randomizer();
|
91
|
-
let value: string | boolean | number;
|
92
|
-
switch (primitiveType.name) {
|
93
|
-
case PRIMITIVE_TYPE.BOOLEAN:
|
94
|
-
value = randomizer.getRandomItemInCollection([true, false]) ?? true;
|
95
|
-
break;
|
96
|
-
case PRIMITIVE_TYPE.FLOAT:
|
97
|
-
value = randomizer.getRandomFloat();
|
98
|
-
break;
|
99
|
-
case PRIMITIVE_TYPE.DECIMAL:
|
100
|
-
value = randomizer.getRandomDouble();
|
101
|
-
break;
|
102
|
-
case PRIMITIVE_TYPE.NUMBER:
|
103
|
-
case PRIMITIVE_TYPE.INTEGER:
|
104
|
-
value = randomizer.getRandomWholeNumber(100);
|
105
|
-
break;
|
106
|
-
case PRIMITIVE_TYPE.STRING:
|
107
|
-
default:
|
108
|
-
value = `${propertyName} ${randomizer.getRandomWholeNumber(100)}`;
|
109
|
-
}
|
110
|
-
instanceValue_setValues(primitiveInstanceValue, [value], observerContext);
|
111
|
-
return primitiveInstanceValue;
|
112
126
|
};
|
113
127
|
|
114
128
|
export const createMockEnumerationProperty = (
|
@@ -116,21 +130,6 @@ export const createMockEnumerationProperty = (
|
|
116
130
|
): string =>
|
117
131
|
new Randomizer().getRandomItemInCollection(enumeration.values)?.name ?? '';
|
118
132
|
|
119
|
-
export const buildPrimitiveInstanceValue = (
|
120
|
-
graph: PureModel,
|
121
|
-
type: PRIMITIVE_TYPE,
|
122
|
-
value: unknown,
|
123
|
-
observerContext: ObserverContext,
|
124
|
-
): PrimitiveInstanceValue => {
|
125
|
-
const instance = new PrimitiveInstanceValue(
|
126
|
-
GenericTypeExplicitReference.create(
|
127
|
-
new GenericType(graph.getPrimitiveType(type)),
|
128
|
-
),
|
129
|
-
);
|
130
|
-
instanceValue_setValues(instance, [value], observerContext);
|
131
|
-
return instance;
|
132
|
-
};
|
133
|
-
|
134
133
|
export const buildDefaultInstanceValue = (
|
135
134
|
graph: PureModel,
|
136
135
|
type: Type,
|
@@ -219,6 +218,9 @@ export const generateVariableExpressionMockValue = (
|
|
219
218
|
parameter: VariableExpression,
|
220
219
|
graph: PureModel,
|
221
220
|
observerContext: ObserverContext,
|
221
|
+
options?: {
|
222
|
+
useCurrentDateDependentFunctions?: boolean;
|
223
|
+
},
|
222
224
|
): ValueSpecification | undefined => {
|
223
225
|
const varType = parameter.genericType?.value.rawType;
|
224
226
|
const multiplicity = parameter.multiplicity;
|
@@ -231,8 +233,9 @@ export const generateVariableExpressionMockValue = (
|
|
231
233
|
if (varType instanceof PrimitiveType) {
|
232
234
|
return createMockPrimitiveValueSpecification(
|
233
235
|
varType,
|
234
|
-
|
236
|
+
graph,
|
235
237
|
observerContext,
|
238
|
+
options,
|
236
239
|
);
|
237
240
|
} else if (varType instanceof Enumeration) {
|
238
241
|
const enumValueInstance = new EnumValueInstanceValue(
|
@@ -272,3 +275,23 @@ export const getValueSpecificationStringValue = (
|
|
272
275
|
}
|
273
276
|
return undefined;
|
274
277
|
};
|
278
|
+
|
279
|
+
export const valueSpecReturnTDS = (
|
280
|
+
val: ValueSpecification,
|
281
|
+
graph: PureModel,
|
282
|
+
): boolean => {
|
283
|
+
const retunType = returnUndefOnError(() =>
|
284
|
+
getValueSpecificationReturnType(val),
|
285
|
+
);
|
286
|
+
const tdsType = returnUndefOnError(() =>
|
287
|
+
graph.getClass(QUERY_BUILDER_PURE_PATH.TDS_TABULAR_DATASET),
|
288
|
+
);
|
289
|
+
const tdsRowType = returnUndefOnError(() =>
|
290
|
+
graph.getClass(QUERY_BUILDER_PURE_PATH.TDS_ROW),
|
291
|
+
);
|
292
|
+
// FIXME: we sometimes return tds row when tds is the return type of the lambda. We do this to properly build post filters.
|
293
|
+
// We should fix this to properly build filter functions after a tds function
|
294
|
+
return Boolean(
|
295
|
+
retunType && tdsType && (retunType === tdsType || retunType === tdsRowType),
|
296
|
+
);
|
297
|
+
};
|