@finos/legend-query-builder 4.14.55 → 4.14.57

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/lib/__lib__/QueryBuilderTesting.d.ts +5 -1
  2. package/lib/__lib__/QueryBuilderTesting.d.ts.map +1 -1
  3. package/lib/__lib__/QueryBuilderTesting.js +10 -1
  4. package/lib/__lib__/QueryBuilderTesting.js.map +1 -1
  5. package/lib/components/QueryBuilder.js +3 -3
  6. package/lib/components/QueryBuilder.js.map +1 -1
  7. package/lib/components/QueryBuilderPropertyExpressionEditor.d.ts +9 -1
  8. package/lib/components/QueryBuilderPropertyExpressionEditor.d.ts.map +1 -1
  9. package/lib/components/QueryBuilderPropertyExpressionEditor.js +10 -8
  10. package/lib/components/QueryBuilderPropertyExpressionEditor.js.map +1 -1
  11. package/lib/components/QueryLoader.d.ts.map +1 -1
  12. package/lib/components/QueryLoader.js +51 -11
  13. package/lib/components/QueryLoader.js.map +1 -1
  14. package/lib/components/execution-plan/ExecutionPlanViewer.js +2 -2
  15. package/lib/components/execution-plan/ExecutionPlanViewer.js.map +1 -1
  16. package/lib/components/explorer/QueryBuilderExplorerPanel.d.ts +12 -2
  17. package/lib/components/explorer/QueryBuilderExplorerPanel.d.ts.map +1 -1
  18. package/lib/components/explorer/QueryBuilderExplorerPanel.js +4 -4
  19. package/lib/components/explorer/QueryBuilderExplorerPanel.js.map +1 -1
  20. package/lib/components/explorer/QueryBuilderFunctionsExplorerPanel.js +2 -2
  21. package/lib/components/explorer/QueryBuilderFunctionsExplorerPanel.js.map +1 -1
  22. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.d.ts +1 -1
  23. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.d.ts.map +1 -1
  24. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js +55 -45
  25. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js.map +1 -1
  26. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +2 -2
  27. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
  28. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.js +5 -5
  29. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.js.map +1 -1
  30. package/lib/components/filter/QueryBuilderFilterPanel.js +3 -3
  31. package/lib/components/filter/QueryBuilderFilterPanel.js.map +1 -1
  32. package/lib/components/result/QueryBuilderResultPanel.js +3 -3
  33. package/lib/components/result/QueryBuilderResultPanel.js.map +1 -1
  34. package/lib/components/result/tds/QueryBuilderTDSGridResult.js +2 -2
  35. package/lib/components/result/tds/QueryBuilderTDSGridResult.js.map +1 -1
  36. package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.d.ts.map +1 -1
  37. package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.js +7 -6
  38. package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.js.map +1 -1
  39. package/lib/index.css +2 -2
  40. package/lib/index.css.map +1 -1
  41. package/lib/index.d.ts +12 -0
  42. package/lib/index.d.ts.map +1 -1
  43. package/lib/index.js +12 -0
  44. package/lib/index.js.map +1 -1
  45. package/lib/package.json +6 -6
  46. package/lib/stores/QueryLoaderState.d.ts +11 -0
  47. package/lib/stores/QueryLoaderState.d.ts.map +1 -1
  48. package/lib/stores/QueryLoaderState.js +15 -3
  49. package/lib/stores/QueryLoaderState.js.map +1 -1
  50. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.d.ts +4 -2
  51. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.d.ts.map +1 -1
  52. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js +12 -4
  53. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js.map +1 -1
  54. package/lib/stores/filter/QueryBuilderFilterStateBuilder.d.ts +2 -1
  55. package/lib/stores/filter/QueryBuilderFilterStateBuilder.d.ts.map +1 -1
  56. package/lib/stores/filter/QueryBuilderFilterStateBuilder.js +15 -0
  57. package/lib/stores/filter/QueryBuilderFilterStateBuilder.js.map +1 -1
  58. package/lib/stores/filter/QueryBuilderFilterValueSpecificationBuilder.d.ts +3 -2
  59. package/lib/stores/filter/QueryBuilderFilterValueSpecificationBuilder.d.ts.map +1 -1
  60. package/lib/stores/filter/QueryBuilderFilterValueSpecificationBuilder.js +1 -1
  61. package/lib/stores/filter/QueryBuilderFilterValueSpecificationBuilder.js.map +1 -1
  62. package/package.json +14 -14
  63. package/src/__lib__/QueryBuilderTesting.ts +10 -1
  64. package/src/components/QueryBuilder.tsx +5 -5
  65. package/src/components/QueryBuilderPropertyExpressionEditor.tsx +35 -16
  66. package/src/components/QueryLoader.tsx +69 -9
  67. package/src/components/execution-plan/ExecutionPlanViewer.tsx +3 -3
  68. package/src/components/explorer/QueryBuilderExplorerPanel.tsx +5 -5
  69. package/src/components/explorer/QueryBuilderFunctionsExplorerPanel.tsx +3 -3
  70. package/src/components/fetch-structure/QueryBuilderPostFilterPanel.tsx +181 -160
  71. package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +3 -3
  72. package/src/components/fetch-structure/QueryBuilderTDSWindowPanel.tsx +9 -9
  73. package/src/components/filter/QueryBuilderFilterPanel.tsx +5 -5
  74. package/src/components/result/QueryBuilderResultPanel.tsx +5 -5
  75. package/src/components/result/tds/QueryBuilderTDSGridResult.tsx +2 -2
  76. package/src/components/result/tds/QueryBuilderTDSSimpleGridResult.tsx +7 -5
  77. package/src/index.ts +24 -2
  78. package/src/stores/QueryLoaderState.ts +24 -5
  79. package/src/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.ts +15 -3
  80. package/src/stores/filter/QueryBuilderFilterStateBuilder.ts +39 -0
  81. package/src/stores/filter/QueryBuilderFilterValueSpecificationBuilder.ts +1 -1
@@ -20,7 +20,7 @@ import {
20
20
  PanelContent,
21
21
  PanelDropZone,
22
22
  BlankPanelPlaceholder,
23
- DropdownMenu,
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
- <DropdownMenu
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
- </DropdownMenu>
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
- <DropdownMenu
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
- </DropdownMenu>
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
- <DropdownMenu
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
- </DropdownMenu>
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
- <DropdownMenu
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
- </DropdownMenu>
1179
+ </ControlledDropdownMenu>
1180
1180
  </div>
1181
1181
  </div>
1182
1182
  <div className="query-builder__olap__column__name">
@@ -28,7 +28,7 @@ import {
28
28
  type TreeNodeViewProps,
29
29
  clsx,
30
30
  ContextMenu,
31
- DropdownMenu,
31
+ ControlledDropdownMenu,
32
32
  MenuContent,
33
33
  MenuContentItem,
34
34
  BlankPanelPlaceholder,
@@ -828,7 +828,7 @@ const QueryBuilderFilterConditionEditor = observer(
828
828
  propertyExpressionState={node.condition.propertyExpressionState}
829
829
  />
830
830
  </div>
831
- <DropdownMenu
831
+ <ControlledDropdownMenu
832
832
  className="query-builder-filter-tree__condition-node__operator"
833
833
  title="Choose Operator..."
834
834
  content={
@@ -856,7 +856,7 @@ const QueryBuilderFilterConditionEditor = observer(
856
856
  <div className="query-builder-filter-tree__condition-node__operator__dropdown__trigger">
857
857
  <CaretDownIcon />
858
858
  </div>
859
- </DropdownMenu>
859
+ </ControlledDropdownMenu>
860
860
  {node.condition.value && (
861
861
  <div
862
862
  ref={dropConnector}
@@ -1499,7 +1499,7 @@ export const QueryBuilderFilterPanel = observer(
1499
1499
  </div>
1500
1500
 
1501
1501
  <div className="panel__header__actions">
1502
- <DropdownMenu
1502
+ <ControlledDropdownMenu
1503
1503
  className="panel__header__action"
1504
1504
  title="Show Filter Options Menu..."
1505
1505
  content={
@@ -1572,7 +1572,7 @@ export const QueryBuilderFilterPanel = observer(
1572
1572
  }
1573
1573
  >
1574
1574
  <MoreVerticalIcon className="query-builder__icon__more-options" />
1575
- </DropdownMenu>
1575
+ </ControlledDropdownMenu>
1576
1576
  </div>
1577
1577
  </div>
1578
1578
  <PanelContent>
@@ -17,7 +17,7 @@
17
17
  import {
18
18
  BlankPanelContent,
19
19
  PlayIcon,
20
- DropdownMenu,
20
+ ControlledDropdownMenu,
21
21
  MenuContent,
22
22
  MenuContentItem,
23
23
  CaretDownIcon,
@@ -517,7 +517,7 @@ export const QueryBuilderResultPanel = observer(
517
517
  <PlayIcon />
518
518
  Run Query
519
519
  </button>
520
- <DropdownMenu
520
+ <ControlledDropdownMenu
521
521
  className="btn__dropdown-combo__dropdown-btn query-builder__result__execute-btn__btn query-builder__result__execute-btn__btn--green"
522
522
  disabled={isRunQueryDisabled}
523
523
  content={
@@ -552,11 +552,11 @@ export const QueryBuilderResultPanel = observer(
552
552
  }}
553
553
  >
554
554
  <CaretDownIcon />
555
- </DropdownMenu>
555
+ </ControlledDropdownMenu>
556
556
  </>
557
557
  )}
558
558
  </div>
559
- <DropdownMenu
559
+ <ControlledDropdownMenu
560
560
  className="query-builder__result__export__dropdown"
561
561
  title="Export"
562
562
  disabled={!isQueryValid}
@@ -604,7 +604,7 @@ export const QueryBuilderResultPanel = observer(
604
604
  <div className="query-builder__result__export__dropdown__trigger">
605
605
  <CaretDownIcon />
606
606
  </div>
607
- </DropdownMenu>
607
+ </ControlledDropdownMenu>
608
608
  {resultState.isQueryUsageViewerOpened && (
609
609
  <QueryUsageViewer resultState={resultState} />
610
610
  )}
@@ -427,10 +427,10 @@ export const QueryBuilderTDSGridResult = observer(
427
427
  const weightedColumnId =
428
428
  resultState.wavgAggregationState?.weightedColumnIdPairs.get(column);
429
429
  if (weightedColumnId) {
430
- const weightedColumnSum = param.rowNode.allLeafChildren
430
+ const weightedColumnSum = (param.rowNode.allLeafChildren ?? [])
431
431
  .map((node) => node.data[weightedColumnId])
432
432
  .reduce((a, b) => a + b) as number;
433
- const weightedColumnMultiply = param.rowNode.allLeafChildren
433
+ const weightedColumnMultiply = (param.rowNode.allLeafChildren ?? [])
434
434
  .map((node) => node.data[weightedColumnId] * node.data[column])
435
435
  .reduce((a, b) => a + b);
436
436
  if (weightedColumnSum !== 0) {
@@ -33,6 +33,7 @@ import {
33
33
  import { QueryBuilderTDSState } from '../../../stores/fetch-structure/tds/QueryBuilderTDSState.js';
34
34
  import { DEFAULT_LOCALE } from '../../../graph-manager/QueryBuilderConst.js';
35
35
  import {
36
+ guaranteeNonNullable,
36
37
  isBoolean,
37
38
  isNumber,
38
39
  isString,
@@ -54,6 +55,7 @@ const QueryResultCellRenderer = observer(
54
55
  resultState.queryBuilderState.fetchStructureState.implementation;
55
56
  const applicationStore = resultState.queryBuilderState.applicationStore;
56
57
  const cellValue = params.value as QueryBuilderTDSResultCellDataType;
58
+ const nodeRowIndex = guaranteeNonNullable(params.node.rowIndex);
57
59
  const darkMode =
58
60
  !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled;
59
61
 
@@ -82,7 +84,7 @@ const QueryResultCellRenderer = observer(
82
84
 
83
85
  const currentCellCoordinates = findCoordinatesFromResultValue(
84
86
  columnName,
85
- params.rowIndex,
87
+ nodeRowIndex,
86
88
  );
87
89
  const cellInFilteredResults = resultState.selectedCells.some(
88
90
  (result) =>
@@ -143,7 +145,7 @@ const QueryResultCellRenderer = observer(
143
145
  if (event.shiftKey) {
144
146
  const coordinates = findCoordinatesFromResultValue(
145
147
  columnName,
146
- params.rowIndex,
148
+ nodeRowIndex,
147
149
  );
148
150
  const actualValue = findResultValueFromCoordinates([
149
151
  coordinates.rowIndex,
@@ -162,7 +164,7 @@ const QueryResultCellRenderer = observer(
162
164
  resultState.setSelectedCells([]);
163
165
  const coordinates = findCoordinatesFromResultValue(
164
166
  columnName,
165
- params.rowIndex,
167
+ nodeRowIndex,
166
168
  );
167
169
  const actualValue = findResultValueFromCoordinates([
168
170
  coordinates.rowIndex,
@@ -181,7 +183,7 @@ const QueryResultCellRenderer = observer(
181
183
  if (event.button === 2) {
182
184
  const coordinates = findCoordinatesFromResultValue(
183
185
  columnName,
184
- params.rowIndex,
186
+ nodeRowIndex,
185
187
  );
186
188
  const isInSelected = isCoordinatesSelected(coordinates);
187
189
  if (!isInSelected) {
@@ -218,7 +220,7 @@ const QueryResultCellRenderer = observer(
218
220
  const firstCorner = results.coordinates;
219
221
  const secondCorner = findCoordinatesFromResultValue(
220
222
  columnName,
221
- params.rowIndex,
223
+ nodeRowIndex,
222
224
  );
223
225
 
224
226
  resultState.setSelectedCells([results]);
package/src/index.ts CHANGED
@@ -17,7 +17,10 @@
17
17
  // application
18
18
  export * from './__lib__/QueryBuilderTelemetryHelper.js';
19
19
  export * from './__lib__/QueryBuilderEvent.js';
20
-
20
+ export {
21
+ QueryBuilderExplorerState,
22
+ QueryBuilderExplorerPreviewDataState,
23
+ } from './stores/explorer/QueryBuilderExplorerState.js';
21
24
  export { QueryBuilder_GraphManagerPreset } from './graph-manager/QueryBuilder_GraphManagerPreset.js';
22
25
  export { QueryBuilderConfig } from './graph-manager/QueryBuilderConfig.js';
23
26
  export { QUERY_BUILDER_TEST_ID } from './__lib__/QueryBuilderTesting.js';
@@ -72,7 +75,18 @@ export {
72
75
  QueryBuilderChangeDetectionState,
73
76
  } from './stores/QueryBuilderChangeDetectionState.js';
74
77
  export { QueryBuilderResultValues } from './components/result/QueryBuilderResultPanel.js';
75
-
78
+ export {
79
+ QueryBuilderTaggedValueInfoTooltip,
80
+ QueryBuilderPropertyInfoTooltip,
81
+ QueryBuilderDerivationInfoTooltip,
82
+ } from './components/shared/QueryBuilderPropertyInfoTooltip.js';
83
+ export { QueryBuilderRootClassInfoTooltip } from './components/shared/QueryBuilderRootClassInfoTooltip.js';
84
+ export {
85
+ renderPropertyTypeIcon,
86
+ checkForDeprecatedNode,
87
+ getQueryBuilderExplorerTreeNodeSortRank,
88
+ QueryBuilderSubclassInfoTooltip,
89
+ } from './components/explorer/QueryBuilderExplorerPanel.js';
76
90
  // ------------------------------------------- Shared components -------------------------------------------
77
91
 
78
92
  export * from './components/shared/LambdaEditor.js';
@@ -97,3 +111,11 @@ export * from './stores/QueryBuilder_LegendApplicationPlugin_Extension.js';
97
111
  export * from './stores/data-access/DataAccessState.js';
98
112
  export * from './components/data-access/DataAccessOverview.js';
99
113
  export * from './stores/query-workflow/QueryBuilderWorkFlowState.js';
114
+ export * from './stores/explorer/QueryBuilderExplorerState.js';
115
+ export * from './stores/explorer/QueryBuilderPropertySearchState.js';
116
+ export * from './stores/explorer/QueryFunctionsExplorerState.js';
117
+ export * from './components/filter/QueryBuilderFilterPanel.js';
118
+ export * from './stores/filter/QueryBuilderFilterValueSpecificationBuilder.js';
119
+ export * from './stores/QueryBuilderValueSpecificationHelper.js';
120
+ export * from './stores/filter/QueryBuilderFilterState.js';
121
+ export * from './stores/filter/QueryBuilderFilterStateBuilder.js';
@@ -45,6 +45,14 @@ import type {
45
45
  export const QUERY_LOADER_TYPEAHEAD_SEARCH_LIMIT = 50;
46
46
  export const QUERY_LOADER_DEFAULT_QUERY_SEARCH_LIMIT = 10;
47
47
 
48
+ export enum SORT_BY_OPTIONS {
49
+ SORT_BY_CREATE = 'Last Created',
50
+ SORT_BY_VIEW = 'Last Viewed',
51
+ SORT_BY_UPDATE = 'Last Updated',
52
+ }
53
+
54
+ export type SortByOption = { label: string; value: string };
55
+
48
56
  export class QueryLoaderState {
49
57
  readonly applicationStore: GenericLegendApplicationStore;
50
58
  readonly graphManagerState: BasicGraphManagerState;
@@ -84,6 +92,7 @@ export class QueryLoaderState {
84
92
  showingDefaultQueries = true;
85
93
  showPreviewViewer = false;
86
94
  queryPreviewContent?: QueryInfo | { name: string; content: string };
95
+ sortBy = '';
87
96
 
88
97
  constructor(
89
98
  applicationStore: GenericLegendApplicationStore,
@@ -115,6 +124,8 @@ export class QueryLoaderState {
115
124
  searchText: observable,
116
125
  isCuratedTemplateToggled: observable,
117
126
  curatedTemplateQuerySepcifications: observable,
127
+ sortBy: observable,
128
+ setSortBy: action,
118
129
  setSearchText: action,
119
130
  setQueryLoaderDialogOpen: action,
120
131
  setQueries: action,
@@ -147,6 +158,10 @@ export class QueryLoaderState {
147
158
  this.isCuratedTemplateToggled = val;
148
159
  }
149
160
 
161
+ setSortBy(val: string): void {
162
+ this.sortBy = val;
163
+ }
164
+
150
165
  setSearchText(val: string): void {
151
166
  this.searchText = val;
152
167
  }
@@ -156,7 +171,7 @@ export class QueryLoaderState {
156
171
  }
157
172
 
158
173
  setQueries(val: LightQuery[]): void {
159
- this.queries = val;
174
+ this.queries = val.sort((a, b) => a.name.localeCompare(b.name));
160
175
  }
161
176
 
162
177
  setShowPreviewViewer(val: boolean): void {
@@ -225,7 +240,9 @@ export class QueryLoaderState {
225
240
  if (!this.fetchDefaultQueries) {
226
241
  return;
227
242
  }
228
- this.queries = (yield this.fetchDefaultQueries()) as LightQuery[];
243
+ this.queries = (
244
+ (yield this.fetchDefaultQueries()) as LightQuery[]
245
+ ).sort((a, b) => a.name.localeCompare(b.name));
229
246
  this.searchQueriesState.pass();
230
247
  } catch (error) {
231
248
  this.searchQueriesState.fail();
@@ -271,9 +288,11 @@ export class QueryLoaderState {
271
288
  searchSpecification =
272
289
  this.decorateSearchSpecification?.(searchSpecification) ??
273
290
  searchSpecification;
274
- this.queries = (yield this.graphManagerState.graphManager.searchQueries(
275
- searchSpecification,
276
- )) as LightQuery[];
291
+ this.queries = (
292
+ (yield this.graphManagerState.graphManager.searchQueries(
293
+ searchSpecification,
294
+ )) as LightQuery[]
295
+ ).sort((a, b) => a.name.localeCompare(b.name));
277
296
  this.searchQueriesState.pass();
278
297
  } catch (error) {
279
298
  assertErrorThrown(error);
@@ -216,19 +216,28 @@ export class QueryBuilderPostFilterTreeConditionNodeData
216
216
  implements Hashable
217
217
  {
218
218
  condition: PostFilterConditionState;
219
+ isNewlyAdded: boolean;
219
220
 
220
221
  constructor(
221
222
  parentId: string | undefined,
222
223
  condition: PostFilterConditionState,
224
+ isNewlyAdded?: boolean,
223
225
  ) {
224
226
  super(parentId);
225
227
 
226
228
  makeObservable(this, {
227
229
  condition: observable,
230
+ isNewlyAdded: observable,
231
+ setIsNewlyAdded: action,
228
232
  dragPreviewLabel: computed,
229
233
  });
230
234
 
231
235
  this.condition = condition;
236
+ this.isNewlyAdded = isNewlyAdded ?? false;
237
+ }
238
+
239
+ setIsNewlyAdded(val: boolean): void {
240
+ this.isNewlyAdded = val;
232
241
  }
233
242
 
234
243
  get dragPreviewLabel(): string {
@@ -461,7 +470,9 @@ export class PostFilterConditionState implements Hashable {
461
470
  );
462
471
  }
463
472
  }
464
- *handleTypeaheadSearch(): GeneratorFn<void> {
473
+ *handleTypeaheadSearch(
474
+ searchValue?: ValueSpecification | undefined,
475
+ ): GeneratorFn<void> {
465
476
  try {
466
477
  this.typeaheadSearchState.inProgress();
467
478
  this.typeaheadSearchResults = undefined;
@@ -475,13 +486,14 @@ export class PostFilterConditionState implements Hashable {
475
486
  this.rightConditionValue,
476
487
  PostFilterValueSpecConditionValueState,
477
488
  );
478
- if (performTypeahead(rightConditionValue.value)) {
489
+ const value = searchValue ?? rightConditionValue.value;
490
+ if (performTypeahead(value)) {
479
491
  const result =
480
492
  (yield this.postFilterState.tdsState.queryBuilderState.graphManagerState.graphManager.runQuery(
481
493
  buildProjectionColumnTypeaheadQuery(
482
494
  this.postFilterState.tdsState.queryBuilderState,
483
495
  columnState,
484
- rightConditionValue.value,
496
+ value,
485
497
  ),
486
498
  guaranteeNonNullable(
487
499
  this.postFilterState.tdsState.queryBuilderState
@@ -399,3 +399,42 @@ export const processFilterExpression = (
399
399
  */
400
400
  filterState.simplifyTree();
401
401
  };
402
+
403
+ export const processFilterLambda = (
404
+ lambdaFunc: LambdaFunction,
405
+ queryBuilderState: QueryBuilderState,
406
+ ): void => {
407
+ const filterState = queryBuilderState.filterState;
408
+
409
+ assertTrue(
410
+ lambdaFunc.expressionSequence.length === 1,
411
+ `Can't process filter() lambda: only support filter() lambda body with 1 expression`,
412
+ );
413
+ const rootExpression = guaranteeType(
414
+ lambdaFunc.expressionSequence[0],
415
+ SimpleFunctionExpression,
416
+ `Can't process filter() lambda: only support filter() lambda body with 1 expression`,
417
+ );
418
+
419
+ assertTrue(
420
+ lambdaFunc.functionType.parameters.length === 1,
421
+ `Can't process filter() lambda: only support filter() lambda with 1 parameter`,
422
+ );
423
+ filterState.setLambdaParameterName(
424
+ guaranteeType(
425
+ lambdaFunc.functionType.parameters[0],
426
+ VariableExpression,
427
+ `Can't process filter() lambda: only support filter() lambda with 1 parameter`,
428
+ ).name,
429
+ );
430
+
431
+ processFilterTree(rootExpression, filterState, undefined);
432
+
433
+ /**
434
+ * NOTE: Since group operations like and/or do not take more than 2 parameters, if there are
435
+ * more than 2 clauses in each group operations, then these clauses are converted into an
436
+ * unbalanced tree. However, this would look quite bad for UX, as such, we simplify the tree.
437
+ * After building the filter state.
438
+ */
439
+ filterState.simplifyTree();
440
+ };
@@ -39,7 +39,7 @@ import { QUERY_BUILDER_SUPPORTED_FUNCTIONS } from '../../graph/QueryBuilderMetaM
39
39
  import { DEFAULT_LAMBDA_VARIABLE_NAME } from '../QueryBuilderConfig.js';
40
40
  import { buildPropertyExpressionChain } from '../QueryBuilderValueSpecificationBuilderHelper.js';
41
41
 
42
- const buildFilterConditionExpression = (
42
+ export const buildFilterConditionExpression = (
43
43
  filterState: QueryBuilderFilterState,
44
44
  node: QueryBuilderFilterTreeNodeData,
45
45
  ): ValueSpecification | undefined => {