@finos/legend-query-builder 4.14.55 → 4.14.56
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/lib/__lib__/QueryBuilderTesting.d.ts +5 -1
- package/lib/__lib__/QueryBuilderTesting.d.ts.map +1 -1
- package/lib/__lib__/QueryBuilderTesting.js +10 -1
- package/lib/__lib__/QueryBuilderTesting.js.map +1 -1
- package/lib/components/QueryBuilder.js +3 -3
- package/lib/components/QueryBuilder.js.map +1 -1
- package/lib/components/QueryBuilderPropertyExpressionEditor.d.ts +9 -1
- package/lib/components/QueryBuilderPropertyExpressionEditor.d.ts.map +1 -1
- package/lib/components/QueryBuilderPropertyExpressionEditor.js +10 -8
- package/lib/components/QueryBuilderPropertyExpressionEditor.js.map +1 -1
- package/lib/components/QueryLoader.js +3 -3
- package/lib/components/QueryLoader.js.map +1 -1
- package/lib/components/execution-plan/ExecutionPlanViewer.js +2 -2
- package/lib/components/execution-plan/ExecutionPlanViewer.js.map +1 -1
- package/lib/components/explorer/QueryBuilderExplorerPanel.d.ts +12 -2
- package/lib/components/explorer/QueryBuilderExplorerPanel.d.ts.map +1 -1
- package/lib/components/explorer/QueryBuilderExplorerPanel.js +4 -4
- package/lib/components/explorer/QueryBuilderExplorerPanel.js.map +1 -1
- package/lib/components/explorer/QueryBuilderFunctionsExplorerPanel.js +2 -2
- package/lib/components/explorer/QueryBuilderFunctionsExplorerPanel.js.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.d.ts +1 -1
- package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.d.ts.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js +55 -45
- package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +2 -2
- package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.js +5 -5
- package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.js.map +1 -1
- package/lib/components/filter/QueryBuilderFilterPanel.js +3 -3
- package/lib/components/filter/QueryBuilderFilterPanel.js.map +1 -1
- package/lib/components/result/QueryBuilderResultPanel.js +3 -3
- package/lib/components/result/QueryBuilderResultPanel.js.map +1 -1
- package/lib/index.css +2 -2
- package/lib/index.css.map +1 -1
- package/lib/index.d.ts +12 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +12 -0
- package/lib/index.js.map +1 -1
- package/lib/package.json +3 -3
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.d.ts +4 -2
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js +12 -4
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js.map +1 -1
- package/lib/stores/filter/QueryBuilderFilterStateBuilder.d.ts +2 -1
- package/lib/stores/filter/QueryBuilderFilterStateBuilder.d.ts.map +1 -1
- package/lib/stores/filter/QueryBuilderFilterStateBuilder.js +15 -0
- package/lib/stores/filter/QueryBuilderFilterStateBuilder.js.map +1 -1
- package/lib/stores/filter/QueryBuilderFilterValueSpecificationBuilder.d.ts +3 -2
- package/lib/stores/filter/QueryBuilderFilterValueSpecificationBuilder.d.ts.map +1 -1
- package/lib/stores/filter/QueryBuilderFilterValueSpecificationBuilder.js +1 -1
- package/lib/stores/filter/QueryBuilderFilterValueSpecificationBuilder.js.map +1 -1
- package/package.json +11 -11
- package/src/__lib__/QueryBuilderTesting.ts +10 -1
- package/src/components/QueryBuilder.tsx +5 -5
- package/src/components/QueryBuilderPropertyExpressionEditor.tsx +35 -16
- package/src/components/QueryLoader.tsx +5 -5
- package/src/components/execution-plan/ExecutionPlanViewer.tsx +3 -3
- package/src/components/explorer/QueryBuilderExplorerPanel.tsx +5 -5
- package/src/components/explorer/QueryBuilderFunctionsExplorerPanel.tsx +3 -3
- package/src/components/fetch-structure/QueryBuilderPostFilterPanel.tsx +181 -160
- package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +3 -3
- package/src/components/fetch-structure/QueryBuilderTDSWindowPanel.tsx +9 -9
- package/src/components/filter/QueryBuilderFilterPanel.tsx +5 -5
- package/src/components/result/QueryBuilderResultPanel.tsx +5 -5
- package/src/index.ts +24 -2
- package/src/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.ts +15 -3
- package/src/stores/filter/QueryBuilderFilterStateBuilder.ts +39 -0
- package/src/stores/filter/QueryBuilderFilterValueSpecificationBuilder.ts +1 -1
|
@@ -20,12 +20,9 @@ import {
|
|
|
20
20
|
type TreeNodeViewProps,
|
|
21
21
|
BlankPanelPlaceholder,
|
|
22
22
|
CaretDownIcon,
|
|
23
|
-
ChevronDownIcon,
|
|
24
|
-
ChevronRightIcon,
|
|
25
23
|
clsx,
|
|
26
24
|
ContextMenu,
|
|
27
|
-
|
|
28
|
-
FilledTriangleIcon,
|
|
25
|
+
ControlledDropdownMenu,
|
|
29
26
|
MenuContent,
|
|
30
27
|
MenuContentItem,
|
|
31
28
|
TimesIcon,
|
|
@@ -65,6 +62,7 @@ import { observer } from 'mobx-react-lite';
|
|
|
65
62
|
import React, {
|
|
66
63
|
forwardRef,
|
|
67
64
|
useCallback,
|
|
65
|
+
useEffect,
|
|
68
66
|
useMemo,
|
|
69
67
|
useRef,
|
|
70
68
|
useState,
|
|
@@ -96,8 +94,8 @@ import { QUERY_BUILDER_GROUP_OPERATION } from '../../stores/QueryBuilderGroupOpe
|
|
|
96
94
|
import { QueryBuilderTDSState } from '../../stores/fetch-structure/tds/QueryBuilderTDSState.js';
|
|
97
95
|
import {
|
|
98
96
|
type QueryBuilderVariableDragSource,
|
|
99
|
-
BasicValueSpecificationEditor,
|
|
100
97
|
QUERY_BUILDER_VARIABLE_DND_TYPE,
|
|
98
|
+
EditableBasicValueSpecificationEditor,
|
|
101
99
|
} from '../shared/BasicValueSpecificationEditor.js';
|
|
102
100
|
import {
|
|
103
101
|
QueryBuilderColumnInfoTooltip,
|
|
@@ -114,6 +112,8 @@ import {
|
|
|
114
112
|
QueryBuilderPostFilterOperator_In,
|
|
115
113
|
QueryBuilderPostFilterOperator_NotIn,
|
|
116
114
|
} from '../../stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_In.js';
|
|
115
|
+
import { QueryBuilderPropertyNameDisplay } from '../QueryBuilderPropertyExpressionEditor.js';
|
|
116
|
+
import { convertTextToPrimitiveInstanceValue } from '../../stores/shared/ValueSpecificationEditorHelper.js';
|
|
117
117
|
|
|
118
118
|
const QueryBuilderPostFilterConditionContextMenu = observer(
|
|
119
119
|
forwardRef<
|
|
@@ -185,28 +185,21 @@ const QueryBuilderPostFilterGroupConditionEditor = observer(
|
|
|
185
185
|
node.groupOperation === QUERY_BUILDER_GROUP_OPERATION.AND ? 'AND' : 'OR';
|
|
186
186
|
|
|
187
187
|
return (
|
|
188
|
-
<div className="
|
|
188
|
+
<div className="dnd__entry__container">
|
|
189
189
|
<PanelEntryDropZonePlaceholder
|
|
190
190
|
isDragOver={isDragOver}
|
|
191
191
|
isDroppable={isDroppable}
|
|
192
|
-
label={
|
|
192
|
+
label={operationName}
|
|
193
|
+
className="query-builder-post-filter-tree__group-node__drop-zone"
|
|
193
194
|
>
|
|
194
195
|
<div
|
|
195
|
-
className=
|
|
196
|
-
'query-builder-post-filter-tree__group-node--and':
|
|
197
|
-
node.groupOperation === QUERY_BUILDER_GROUP_OPERATION.AND,
|
|
198
|
-
'query-builder-post-filter-tree__group-node--or':
|
|
199
|
-
node.groupOperation === QUERY_BUILDER_GROUP_OPERATION.OR,
|
|
200
|
-
})}
|
|
196
|
+
className="query-builder-post-filter-tree__group-node"
|
|
201
197
|
title="Switch Operation"
|
|
202
198
|
onClick={switchOperation}
|
|
203
199
|
>
|
|
204
|
-
<div className="query-builder-post-filter-tree__group-node__label">
|
|
200
|
+
<div className="query-builder-post-filter-tree__group-node__label editable-value">
|
|
205
201
|
{node.groupOperation}
|
|
206
202
|
</div>
|
|
207
|
-
<button className="query-builder-post-filter-tree__group-node__action">
|
|
208
|
-
<FilledTriangleIcon />
|
|
209
|
-
</button>
|
|
210
203
|
</div>
|
|
211
204
|
</PanelEntryDropZonePlaceholder>
|
|
212
205
|
</div>
|
|
@@ -217,10 +210,10 @@ const QueryBuilderPostFilterGroupConditionEditor = observer(
|
|
|
217
210
|
export const QueryBuilderColumnBadge = observer(
|
|
218
211
|
(props: {
|
|
219
212
|
colState: QueryBuilderTDSColumnState;
|
|
213
|
+
removeColumn: () => void;
|
|
220
214
|
onColumnChange?:
|
|
221
215
|
| ((columnState: QueryBuilderProjectionColumnState) => Promise<void>)
|
|
222
216
|
| undefined;
|
|
223
|
-
removeColumn?: () => void;
|
|
224
217
|
}) => {
|
|
225
218
|
const { colState, onColumnChange, removeColumn } = props;
|
|
226
219
|
const applicationStore = useApplicationStore();
|
|
@@ -283,16 +276,14 @@ export const QueryBuilderColumnBadge = observer(
|
|
|
283
276
|
<InfoCircleIcon />
|
|
284
277
|
</div>
|
|
285
278
|
</QueryBuilderColumnInfoTooltip>
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
</button>
|
|
295
|
-
)}
|
|
279
|
+
<button
|
|
280
|
+
className="query-builder-column-badge__action"
|
|
281
|
+
name="Reset"
|
|
282
|
+
title="Reset"
|
|
283
|
+
onClick={removeColumn}
|
|
284
|
+
>
|
|
285
|
+
<RefreshIcon />
|
|
286
|
+
</button>
|
|
296
287
|
</div>
|
|
297
288
|
);
|
|
298
289
|
|
|
@@ -419,11 +410,17 @@ const QueryBuilderPostFilterConditionEditor = observer(
|
|
|
419
410
|
};
|
|
420
411
|
const debouncedTypeaheadSearch = useMemo(
|
|
421
412
|
() =>
|
|
422
|
-
debounce(
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
413
|
+
debounce((inputValue: string) => {
|
|
414
|
+
const inputValueSpec = convertTextToPrimitiveInstanceValue(
|
|
415
|
+
PrimitiveType.STRING,
|
|
416
|
+
inputValue,
|
|
417
|
+
queryBuilderState.observerContext,
|
|
418
|
+
);
|
|
419
|
+
return node.condition.handleTypeaheadSearch(
|
|
420
|
+
inputValueSpec ?? undefined,
|
|
421
|
+
);
|
|
422
|
+
}, 1000),
|
|
423
|
+
[node, queryBuilderState.observerContext],
|
|
427
424
|
);
|
|
428
425
|
const cleanUpReloadValues = (): void => {
|
|
429
426
|
node.condition.typeaheadSearchState.complete();
|
|
@@ -458,7 +455,7 @@ const QueryBuilderPostFilterConditionEditor = observer(
|
|
|
458
455
|
isDroppable={isFilterValueDroppable}
|
|
459
456
|
label="Change Filter Value"
|
|
460
457
|
>
|
|
461
|
-
<
|
|
458
|
+
<EditableBasicValueSpecificationEditor
|
|
462
459
|
valueSpecification={rightConditionValue.value}
|
|
463
460
|
setValueSpecification={changeValueSpecification}
|
|
464
461
|
graph={graph}
|
|
@@ -473,6 +470,7 @@ const QueryBuilderPostFilterConditionEditor = observer(
|
|
|
473
470
|
isConstant={queryBuilderState.constantState.isValueSpecConstant(
|
|
474
471
|
rightConditionValue.value,
|
|
475
472
|
)}
|
|
473
|
+
initializeAsEditable={node.isNewlyAdded}
|
|
476
474
|
/>
|
|
477
475
|
</PanelEntryDropZonePlaceholder>
|
|
478
476
|
</div>
|
|
@@ -496,15 +494,13 @@ const QueryBuilderPostFilterConditionEditor = observer(
|
|
|
496
494
|
isDroppable={isFilterValueDroppable}
|
|
497
495
|
label="Change Filter Value"
|
|
498
496
|
>
|
|
499
|
-
<
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
/>
|
|
507
|
-
</div>
|
|
497
|
+
<QueryBuilderColumnBadge
|
|
498
|
+
colState={rightConditionValue.tdsColumn}
|
|
499
|
+
onColumnChange={
|
|
500
|
+
isFilterValueDroppable ? changeRightCol : undefined
|
|
501
|
+
}
|
|
502
|
+
removeColumn={removeTDSColumnValue}
|
|
503
|
+
/>
|
|
508
504
|
</PanelEntryDropZonePlaceholder>
|
|
509
505
|
</div>
|
|
510
506
|
);
|
|
@@ -512,8 +508,12 @@ const QueryBuilderPostFilterConditionEditor = observer(
|
|
|
512
508
|
return null;
|
|
513
509
|
};
|
|
514
510
|
|
|
511
|
+
useEffect(() => {
|
|
512
|
+
node.setIsNewlyAdded(false);
|
|
513
|
+
}, [node]);
|
|
514
|
+
|
|
515
515
|
return (
|
|
516
|
-
<div className="
|
|
516
|
+
<div className="dnd__entry__container">
|
|
517
517
|
<PanelEntryDropZonePlaceholder
|
|
518
518
|
isDragOver={isDragOver && !isFilterValueDragOver}
|
|
519
519
|
alwaysShowChildren={true}
|
|
@@ -521,11 +521,12 @@ const QueryBuilderPostFilterConditionEditor = observer(
|
|
|
521
521
|
>
|
|
522
522
|
<div className="query-builder-post-filter-tree__condition-node">
|
|
523
523
|
<div className="query-builder-post-filter-tree__condition-node__property">
|
|
524
|
-
<
|
|
525
|
-
|
|
524
|
+
<QueryBuilderPropertyNameDisplay
|
|
525
|
+
columnName={node.condition.leftConditionValue.columnName}
|
|
526
|
+
title={node.condition.leftConditionValue.columnName}
|
|
526
527
|
/>
|
|
527
528
|
</div>
|
|
528
|
-
<
|
|
529
|
+
<ControlledDropdownMenu
|
|
529
530
|
className="query-builder-post-filter-tree__condition-node__operator"
|
|
530
531
|
title="Choose Operator..."
|
|
531
532
|
content={
|
|
@@ -553,7 +554,7 @@ const QueryBuilderPostFilterConditionEditor = observer(
|
|
|
553
554
|
<div className="query-builder-post-filter-tree__condition-node__operator__dropdown__trigger">
|
|
554
555
|
<CaretDownIcon />
|
|
555
556
|
</div>
|
|
556
|
-
</
|
|
557
|
+
</ControlledDropdownMenu>
|
|
557
558
|
{renderRightVal()}
|
|
558
559
|
</div>
|
|
559
560
|
</PanelEntryDropZonePlaceholder>
|
|
@@ -594,19 +595,18 @@ const QueryBuilderPostFilterTreeNodeContainer = observer(
|
|
|
594
595
|
}
|
|
595
596
|
>,
|
|
596
597
|
) => {
|
|
597
|
-
const { node,
|
|
598
|
+
const { node, onNodeSelect, innerProps } = props;
|
|
598
599
|
const { tdsState } = innerProps;
|
|
599
|
-
const
|
|
600
|
+
const dragRef = useRef<HTMLDivElement>(null);
|
|
600
601
|
const [isSelectedFromContextMenu, setIsSelectedFromContextMenu] =
|
|
601
602
|
useState(false);
|
|
602
603
|
const applicationStore = useApplicationStore();
|
|
603
604
|
const postFilterState = tdsState.postFilterState;
|
|
604
|
-
const isExpandable =
|
|
605
|
-
node instanceof QueryBuilderPostFilterTreeGroupNodeData;
|
|
606
605
|
const selectNode = (): void => onNodeSelect?.(node);
|
|
607
|
-
const toggleExpandNode = (): void => node.setIsOpen(!node.isOpen);
|
|
608
606
|
const removeNode = (): void =>
|
|
609
607
|
postFilterState.removeNodeAndPruneBranch(node);
|
|
608
|
+
|
|
609
|
+
// Drag and Drop
|
|
610
610
|
const handleDrop = useCallback(
|
|
611
611
|
(item: QueryBuilderPostFilterDropTarget, type: string): void => {
|
|
612
612
|
if (QUERY_BUILDER_POST_FILTER_DND_TYPE.CONDITION === type) {
|
|
@@ -622,6 +622,7 @@ const QueryBuilderPostFilterTreeNodeContainer = observer(
|
|
|
622
622
|
nodeBeingDragged.id,
|
|
623
623
|
) as QueryBuilderPostFilterTreeConditionNodeData
|
|
624
624
|
).condition,
|
|
625
|
+
true,
|
|
625
626
|
);
|
|
626
627
|
|
|
627
628
|
if (node instanceof QueryBuilderPostFilterTreeConditionNodeData) {
|
|
@@ -667,6 +668,7 @@ const QueryBuilderPostFilterTreeNodeContainer = observer(
|
|
|
667
668
|
new QueryBuilderPostFilterTreeConditionNodeData(
|
|
668
669
|
undefined,
|
|
669
670
|
conditionState,
|
|
671
|
+
true,
|
|
670
672
|
),
|
|
671
673
|
node,
|
|
672
674
|
);
|
|
@@ -730,16 +732,15 @@ const QueryBuilderPostFilterTreeNodeContainer = observer(
|
|
|
730
732
|
: QUERY_BUILDER_POST_FILTER_DND_TYPE.BLANK_CONDITION,
|
|
731
733
|
item: () => ({ node }),
|
|
732
734
|
end: (): void => postFilterState.setRearrangingConditions(false),
|
|
735
|
+
canDrag: () =>
|
|
736
|
+
node instanceof QueryBuilderPostFilterTreeConditionNodeData ||
|
|
737
|
+
node instanceof QueryBuilderPostFilterTreeBlankConditionNodeData,
|
|
733
738
|
}),
|
|
734
739
|
[node, postFilterState],
|
|
735
740
|
);
|
|
736
|
-
dragConnector(dropConnector(
|
|
741
|
+
dragConnector(dropConnector(dragRef));
|
|
737
742
|
useDragPreviewLayer(dragPreviewConnector);
|
|
738
743
|
|
|
739
|
-
// context menu
|
|
740
|
-
const onContextMenuOpen = (): void => setIsSelectedFromContextMenu(true);
|
|
741
|
-
const onContextMenuClose = (): void => setIsSelectedFromContextMenu(false);
|
|
742
|
-
|
|
743
744
|
const { isDroppable } = useDragLayer((monitor) => ({
|
|
744
745
|
isDroppable:
|
|
745
746
|
monitor.isDragging() &&
|
|
@@ -747,95 +748,94 @@ const QueryBuilderPostFilterTreeNodeContainer = observer(
|
|
|
747
748
|
monitor.getItemType() === QUERY_BUILDER_WINDOW_COLUMN_DND_TYPE),
|
|
748
749
|
}));
|
|
749
750
|
|
|
751
|
+
// context menu
|
|
752
|
+
const onContextMenuOpen = (): void => setIsSelectedFromContextMenu(true);
|
|
753
|
+
const onContextMenuClose = (): void => setIsSelectedFromContextMenu(false);
|
|
754
|
+
|
|
755
|
+
const showRemoveButton =
|
|
756
|
+
node instanceof QueryBuilderPostFilterTreeConditionNodeData ||
|
|
757
|
+
node instanceof QueryBuilderPostFilterTreeBlankConditionNodeData;
|
|
758
|
+
|
|
750
759
|
return (
|
|
751
|
-
<
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
760
|
+
<div
|
|
761
|
+
data-testid={
|
|
762
|
+
QUERY_BUILDER_TEST_ID.QUERY_BUILDER_POST_FILTER_TREE_NODE_CONTAINER
|
|
763
|
+
}
|
|
764
|
+
onClick={
|
|
765
|
+
node instanceof QueryBuilderPostFilterTreeConditionNodeData ||
|
|
766
|
+
node instanceof QueryBuilderPostFilterTreeBlankConditionNodeData
|
|
767
|
+
? selectNode
|
|
768
|
+
: undefined
|
|
757
769
|
}
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
770
|
+
className={clsx('query-builder-post-filter-tree__node__container', {
|
|
771
|
+
'query-builder-post-filter-tree__node__container--group':
|
|
772
|
+
node instanceof QueryBuilderPostFilterTreeGroupNodeData,
|
|
773
|
+
'query-builder-post-filter-tree__node__container--condition':
|
|
774
|
+
node instanceof QueryBuilderPostFilterTreeConditionNodeData ||
|
|
775
|
+
node instanceof QueryBuilderPostFilterTreeBlankConditionNodeData,
|
|
776
|
+
'query-builder-post-filter-tree__node__container--no-hover':
|
|
777
|
+
postFilterState.isRearrangingConditions,
|
|
778
|
+
'query-builder-post-filter-tree__node__container--selected':
|
|
779
|
+
node === postFilterState.selectedNode,
|
|
780
|
+
'query-builder-post-filter-tree__node__container--selected-from-context-menu':
|
|
781
|
+
isSelectedFromContextMenu,
|
|
782
|
+
})}
|
|
761
783
|
>
|
|
762
|
-
<
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
784
|
+
<ContextMenu
|
|
785
|
+
content={
|
|
786
|
+
<QueryBuilderPostFilterConditionContextMenu
|
|
787
|
+
tdsState={tdsState}
|
|
788
|
+
node={node}
|
|
789
|
+
/>
|
|
766
790
|
}
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
postFilterState.isRearrangingConditions,
|
|
772
|
-
'query-builder-post-filter-tree__node__container--selected':
|
|
773
|
-
node === postFilterState.selectedNode,
|
|
774
|
-
'query-builder-post-filter-tree__node__container--selected-from-context-menu':
|
|
775
|
-
isSelectedFromContextMenu,
|
|
776
|
-
},
|
|
777
|
-
)}
|
|
791
|
+
menuProps={{ elevation: 7 }}
|
|
792
|
+
onOpen={onContextMenuOpen}
|
|
793
|
+
onClose={onContextMenuClose}
|
|
794
|
+
className="query-builder-post-filter-tree__node__context-menu"
|
|
778
795
|
>
|
|
779
796
|
<div
|
|
797
|
+
data-testid={
|
|
798
|
+
QUERY_BUILDER_TEST_ID.QUERY_BUILDER_POST_FILTER_TREE_NODE_CONTENT
|
|
799
|
+
}
|
|
780
800
|
className="query-builder-post-filter-tree__node__content"
|
|
781
|
-
|
|
782
|
-
paddingLeft: `${(level - 1) * (stepPaddingInRem ?? 2) + 1.5}rem`,
|
|
783
|
-
display: 'flex',
|
|
784
|
-
}}
|
|
785
|
-
onClick={selectNode}
|
|
801
|
+
ref={dragRef}
|
|
786
802
|
>
|
|
787
|
-
{
|
|
788
|
-
<
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
803
|
+
{node instanceof QueryBuilderPostFilterTreeGroupNodeData && (
|
|
804
|
+
<QueryBuilderPostFilterGroupConditionEditor
|
|
805
|
+
node={node}
|
|
806
|
+
isDroppable={isDroppable}
|
|
807
|
+
isDragOver={isDragOver}
|
|
808
|
+
/>
|
|
809
|
+
)}
|
|
810
|
+
{node instanceof QueryBuilderPostFilterTreeConditionNodeData && (
|
|
811
|
+
<QueryBuilderPostFilterConditionEditor
|
|
812
|
+
node={node}
|
|
813
|
+
isDragOver={deepIsDragOver}
|
|
814
|
+
/>
|
|
815
|
+
)}
|
|
816
|
+
{node instanceof
|
|
817
|
+
QueryBuilderPostFilterTreeBlankConditionNodeData && (
|
|
818
|
+
<QueryBuilderPostFilterBlankConditionEditor
|
|
819
|
+
node={node}
|
|
820
|
+
isDragOver={isDragOver}
|
|
821
|
+
isDroppable={isDroppable}
|
|
822
|
+
/>
|
|
794
823
|
)}
|
|
795
|
-
<div
|
|
796
|
-
className={clsx(
|
|
797
|
-
'tree-view__node__label query-builder-post-filter-tree__node__label',
|
|
798
|
-
{
|
|
799
|
-
'query-builder-post-filter-tree__node__label--expandable':
|
|
800
|
-
isExpandable,
|
|
801
|
-
},
|
|
802
|
-
)}
|
|
803
|
-
>
|
|
804
|
-
{node instanceof QueryBuilderPostFilterTreeGroupNodeData && (
|
|
805
|
-
<QueryBuilderPostFilterGroupConditionEditor
|
|
806
|
-
node={node}
|
|
807
|
-
isDroppable={isDroppable}
|
|
808
|
-
isDragOver={isDragOver}
|
|
809
|
-
/>
|
|
810
|
-
)}
|
|
811
|
-
{node instanceof QueryBuilderPostFilterTreeConditionNodeData && (
|
|
812
|
-
<QueryBuilderPostFilterConditionEditor
|
|
813
|
-
node={node}
|
|
814
|
-
isDragOver={deepIsDragOver}
|
|
815
|
-
/>
|
|
816
|
-
)}
|
|
817
|
-
{node instanceof
|
|
818
|
-
QueryBuilderPostFilterTreeBlankConditionNodeData && (
|
|
819
|
-
<QueryBuilderPostFilterBlankConditionEditor
|
|
820
|
-
node={node}
|
|
821
|
-
isDragOver={isDragOver}
|
|
822
|
-
isDroppable={isDroppable}
|
|
823
|
-
/>
|
|
824
|
-
)}
|
|
825
|
-
</div>
|
|
826
|
-
</div>
|
|
827
|
-
<div className="query-builder-post-filter-tree__node__actions">
|
|
828
|
-
<button
|
|
829
|
-
className="query-builder-post-filter-tree__node__action"
|
|
830
|
-
tabIndex={-1}
|
|
831
|
-
title="Remove"
|
|
832
|
-
onClick={removeNode}
|
|
833
|
-
>
|
|
834
|
-
<TimesIcon />
|
|
835
|
-
</button>
|
|
836
824
|
</div>
|
|
837
|
-
|
|
838
|
-
|
|
825
|
+
{showRemoveButton && (
|
|
826
|
+
<div className="query-builder-post-filter-tree__node__actions">
|
|
827
|
+
<button
|
|
828
|
+
className="query-builder-post-filter-tree__node__action"
|
|
829
|
+
tabIndex={-1}
|
|
830
|
+
title="Remove"
|
|
831
|
+
onClick={removeNode}
|
|
832
|
+
>
|
|
833
|
+
<TimesIcon />
|
|
834
|
+
</button>
|
|
835
|
+
</div>
|
|
836
|
+
)}
|
|
837
|
+
</ContextMenu>
|
|
838
|
+
</div>
|
|
839
839
|
);
|
|
840
840
|
},
|
|
841
841
|
);
|
|
@@ -858,7 +858,15 @@ const QueryBuilderPostFilterTreeNodeView = observer(
|
|
|
858
858
|
innerProps,
|
|
859
859
|
} = props;
|
|
860
860
|
return (
|
|
861
|
-
<div
|
|
861
|
+
<div
|
|
862
|
+
data-testid={
|
|
863
|
+
QUERY_BUILDER_TEST_ID.QUERY_BUILDER_POST_FILTER_TREE_NODE_BLOCK
|
|
864
|
+
}
|
|
865
|
+
className={clsx('query-builder-post-filter-tree__node__block', {
|
|
866
|
+
'query-builder-post-filter-tree__node__block--group':
|
|
867
|
+
node instanceof QueryBuilderPostFilterTreeGroupNodeData,
|
|
868
|
+
})}
|
|
869
|
+
>
|
|
862
870
|
<QueryBuilderPostFilterTreeNodeContainer
|
|
863
871
|
node={node}
|
|
864
872
|
level={level + 1}
|
|
@@ -866,17 +874,25 @@ const QueryBuilderPostFilterTreeNodeView = observer(
|
|
|
866
874
|
onNodeSelect={onNodeSelect}
|
|
867
875
|
innerProps={innerProps}
|
|
868
876
|
/>
|
|
869
|
-
{node.isOpen &&
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
877
|
+
{node.isOpen && getChildNodes(node).length > 0 && (
|
|
878
|
+
<div
|
|
879
|
+
data-testid={
|
|
880
|
+
QUERY_BUILDER_TEST_ID.QUERY_BUILDER_POST_FILTER_TREE_NODE_CHILDREN
|
|
881
|
+
}
|
|
882
|
+
className="query-builder-post-filter-tree__node__children"
|
|
883
|
+
>
|
|
884
|
+
{getChildNodes(node).map((childNode) => (
|
|
885
|
+
<QueryBuilderPostFilterTreeNodeView
|
|
886
|
+
key={childNode.id}
|
|
887
|
+
node={childNode}
|
|
888
|
+
level={level + 1}
|
|
889
|
+
onNodeSelect={onNodeSelect}
|
|
890
|
+
getChildNodes={getChildNodes}
|
|
891
|
+
innerProps={innerProps}
|
|
892
|
+
/>
|
|
893
|
+
))}
|
|
894
|
+
</div>
|
|
895
|
+
)}
|
|
880
896
|
</div>
|
|
881
897
|
);
|
|
882
898
|
},
|
|
@@ -900,7 +916,10 @@ const QueryBuilderPostFilterTree = observer(
|
|
|
900
916
|
? node.childrenIds.map((id) => postFilterState.getNode(id))
|
|
901
917
|
: [];
|
|
902
918
|
return (
|
|
903
|
-
<div
|
|
919
|
+
<div
|
|
920
|
+
data-testid={QUERY_BUILDER_TEST_ID.QUERY_BUILDER_POST_FILTER_TREE}
|
|
921
|
+
className="tree-view__node__root query-builder-post-filter-tree__root"
|
|
922
|
+
>
|
|
904
923
|
{rootNodes.map((node) => (
|
|
905
924
|
<QueryBuilderPostFilterTreeNodeView
|
|
906
925
|
key={node.id}
|
|
@@ -990,6 +1009,14 @@ const QueryBuilderPostFilterPanelContent = observer(
|
|
|
990
1009
|
);
|
|
991
1010
|
}
|
|
992
1011
|
};
|
|
1012
|
+
|
|
1013
|
+
const { isDroppable } = useDragLayer((monitor) => ({
|
|
1014
|
+
isDroppable:
|
|
1015
|
+
monitor.isDragging() &&
|
|
1016
|
+
(monitor.getItemType() === QUERY_BUILDER_PROJECTION_COLUMN_DND_TYPE ||
|
|
1017
|
+
monitor.getItemType() === QUERY_BUILDER_WINDOW_COLUMN_DND_TYPE),
|
|
1018
|
+
}));
|
|
1019
|
+
|
|
993
1020
|
// Drag and Drop
|
|
994
1021
|
const handleDrop = useCallback(
|
|
995
1022
|
async (item: QueryBuilderPostFilterDropTarget): Promise<void> => {
|
|
@@ -1031,6 +1058,7 @@ const QueryBuilderPostFilterPanelContent = observer(
|
|
|
1031
1058
|
new QueryBuilderPostFilterTreeConditionNodeData(
|
|
1032
1059
|
undefined,
|
|
1033
1060
|
postFilterConditionState,
|
|
1061
|
+
true,
|
|
1034
1062
|
),
|
|
1035
1063
|
undefined,
|
|
1036
1064
|
);
|
|
@@ -1062,13 +1090,6 @@ const QueryBuilderPostFilterPanelContent = observer(
|
|
|
1062
1090
|
const addPostFilterRef = useRef<HTMLInputElement>(null);
|
|
1063
1091
|
dropTargetConnector(addPostFilterRef);
|
|
1064
1092
|
|
|
1065
|
-
const { isDroppable } = useDragLayer((monitor) => ({
|
|
1066
|
-
isDroppable:
|
|
1067
|
-
monitor.isDragging() &&
|
|
1068
|
-
(monitor.getItemType() === QUERY_BUILDER_PROJECTION_COLUMN_DND_TYPE ||
|
|
1069
|
-
monitor.getItemType() === QUERY_BUILDER_WINDOW_COLUMN_DND_TYPE),
|
|
1070
|
-
}));
|
|
1071
|
-
|
|
1072
1093
|
return (
|
|
1073
1094
|
<>
|
|
1074
1095
|
<div className="panel__header">
|
|
@@ -1081,7 +1102,7 @@ const QueryBuilderPostFilterPanelContent = observer(
|
|
|
1081
1102
|
)}
|
|
1082
1103
|
</div>
|
|
1083
1104
|
<div className="panel__header__actions">
|
|
1084
|
-
<
|
|
1105
|
+
<ControlledDropdownMenu
|
|
1085
1106
|
className="panel__header__action"
|
|
1086
1107
|
title="Show Post-Filter Options Menu..."
|
|
1087
1108
|
content={
|
|
@@ -1154,7 +1175,7 @@ const QueryBuilderPostFilterPanelContent = observer(
|
|
|
1154
1175
|
}
|
|
1155
1176
|
>
|
|
1156
1177
|
<MoreVerticalIcon className="query-builder__icon__more-options" />
|
|
1157
|
-
</
|
|
1178
|
+
</ControlledDropdownMenu>
|
|
1158
1179
|
</div>
|
|
1159
1180
|
</div>
|
|
1160
1181
|
<PanelContent>
|
|
@@ -1196,7 +1217,7 @@ const QueryBuilderPostFilterPanelContent = observer(
|
|
|
1196
1217
|
className="query-builder-post-filter-tree__free-drop-zone"
|
|
1197
1218
|
label="Add post-filter to main group"
|
|
1198
1219
|
>
|
|
1199
|
-
<></>
|
|
1220
|
+
<></>
|
|
1200
1221
|
</PanelEntryDropZonePlaceholder>
|
|
1201
1222
|
</div>
|
|
1202
1223
|
)}
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
BlankPanelPlaceholder,
|
|
22
22
|
CalculatorIcon,
|
|
23
23
|
TimesIcon,
|
|
24
|
-
|
|
24
|
+
ControlledDropdownMenu,
|
|
25
25
|
MenuContent,
|
|
26
26
|
MenuContentItem,
|
|
27
27
|
CaretDownIcon,
|
|
@@ -1044,7 +1044,7 @@ const QueryBuilderProjectionColumnEditor = observer(
|
|
|
1044
1044
|
<CalendarClockIcon />
|
|
1045
1045
|
</div>
|
|
1046
1046
|
)}
|
|
1047
|
-
<
|
|
1047
|
+
<ControlledDropdownMenu
|
|
1048
1048
|
className="query-builder__projection__column__aggregate__operator__dropdown"
|
|
1049
1049
|
title="Choose Aggregate Operator..."
|
|
1050
1050
|
disabled={!aggreateOperators.length}
|
|
@@ -1089,7 +1089,7 @@ const QueryBuilderProjectionColumnEditor = observer(
|
|
|
1089
1089
|
<div className="query-builder__projection__column__aggregate__operator__dropdown__trigger">
|
|
1090
1090
|
<CaretDownIcon />
|
|
1091
1091
|
</div>
|
|
1092
|
-
</
|
|
1092
|
+
</ControlledDropdownMenu>
|
|
1093
1093
|
</div>
|
|
1094
1094
|
</div>
|
|
1095
1095
|
<div className="query-builder__projection__column__actions">
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
PanelContent,
|
|
21
21
|
PanelDropZone,
|
|
22
22
|
BlankPanelPlaceholder,
|
|
23
|
-
|
|
23
|
+
ControlledDropdownMenu,
|
|
24
24
|
InputWithInlineValidation,
|
|
25
25
|
MenuContent,
|
|
26
26
|
MenuContentItem,
|
|
@@ -439,7 +439,7 @@ const QueryBuilderWindowColumnModalEditor = observer(
|
|
|
439
439
|
>
|
|
440
440
|
{selectedOperatorState.operator.getLabel()}
|
|
441
441
|
</div>
|
|
442
|
-
<
|
|
442
|
+
<ControlledDropdownMenu
|
|
443
443
|
className="query-builder__olap__column__operation__operator__dropdown"
|
|
444
444
|
title="Choose Window Function Operator..."
|
|
445
445
|
disabled={!operators.length}
|
|
@@ -474,7 +474,7 @@ const QueryBuilderWindowColumnModalEditor = observer(
|
|
|
474
474
|
<div className="query-builder__olap__column__operation__operator__dropdown__trigger">
|
|
475
475
|
<CaretDownIcon />
|
|
476
476
|
</div>
|
|
477
|
-
</
|
|
477
|
+
</ControlledDropdownMenu>
|
|
478
478
|
</div>
|
|
479
479
|
</div>
|
|
480
480
|
</div>
|
|
@@ -553,7 +553,7 @@ const QueryBuilderWindowColumnModalEditor = observer(
|
|
|
553
553
|
{selectedSortBy.sortType.toLowerCase()}
|
|
554
554
|
</div>
|
|
555
555
|
)}
|
|
556
|
-
<
|
|
556
|
+
<ControlledDropdownMenu
|
|
557
557
|
className="query-builder__olap__column__sortby__operator__dropdown"
|
|
558
558
|
title="Choose Window Function SortBy Operator..."
|
|
559
559
|
content={
|
|
@@ -601,7 +601,7 @@ const QueryBuilderWindowColumnModalEditor = observer(
|
|
|
601
601
|
>
|
|
602
602
|
<CaretDownIcon />
|
|
603
603
|
</div>
|
|
604
|
-
</
|
|
604
|
+
</ControlledDropdownMenu>
|
|
605
605
|
</div>
|
|
606
606
|
</div>
|
|
607
607
|
</PanelFormSection>
|
|
@@ -1007,7 +1007,7 @@ const QueryBuilderWindowColumnEditor = observer(
|
|
|
1007
1007
|
>
|
|
1008
1008
|
{operationState.operator.getLabel()}
|
|
1009
1009
|
</div>
|
|
1010
|
-
<
|
|
1010
|
+
<ControlledDropdownMenu
|
|
1011
1011
|
className="query-builder__olap__column__operation__operator__dropdown"
|
|
1012
1012
|
disabled={!operators.length}
|
|
1013
1013
|
title="Choose Window Function Operator..."
|
|
@@ -1036,7 +1036,7 @@ const QueryBuilderWindowColumnEditor = observer(
|
|
|
1036
1036
|
<div className="query-builder__olap__column__operation__operator__dropdown__trigger">
|
|
1037
1037
|
<CaretDownIcon />
|
|
1038
1038
|
</div>
|
|
1039
|
-
</
|
|
1039
|
+
</ControlledDropdownMenu>
|
|
1040
1040
|
</div>
|
|
1041
1041
|
</div>
|
|
1042
1042
|
<div className="query-builder__olap__column__window">
|
|
@@ -1132,7 +1132,7 @@ const QueryBuilderWindowColumnEditor = observer(
|
|
|
1132
1132
|
{sortByState.sortType.toLowerCase()}
|
|
1133
1133
|
</div>
|
|
1134
1134
|
)}
|
|
1135
|
-
<
|
|
1135
|
+
<ControlledDropdownMenu
|
|
1136
1136
|
className="query-builder__olap__column__sortby__operator__dropdown"
|
|
1137
1137
|
title="Choose Window Function SortBy Operator..."
|
|
1138
1138
|
content={
|
|
@@ -1176,7 +1176,7 @@ const QueryBuilderWindowColumnEditor = observer(
|
|
|
1176
1176
|
<div className="query-builder__olap__column__sortby__operator__dropdown__trigger">
|
|
1177
1177
|
<CaretDownIcon />
|
|
1178
1178
|
</div>
|
|
1179
|
-
</
|
|
1179
|
+
</ControlledDropdownMenu>
|
|
1180
1180
|
</div>
|
|
1181
1181
|
</div>
|
|
1182
1182
|
<div className="query-builder__olap__column__name">
|