@finos/legend-query-builder 4.15.2 → 4.15.4

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 (108) hide show
  1. package/lib/__lib__/QueryBuilderTesting.d.ts +1 -0
  2. package/lib/__lib__/QueryBuilderTesting.d.ts.map +1 -1
  3. package/lib/__lib__/QueryBuilderTesting.js +2 -0
  4. package/lib/__lib__/QueryBuilderTesting.js.map +1 -1
  5. package/lib/components/data-cube/QueryBuilderDataCube.d.ts.map +1 -1
  6. package/lib/components/data-cube/QueryBuilderDataCube.js +6 -7
  7. package/lib/components/data-cube/QueryBuilderDataCube.js.map +1 -1
  8. package/lib/components/explorer/QueryBuilderFunctionsExplorerPanel.d.ts.map +1 -1
  9. package/lib/components/explorer/QueryBuilderFunctionsExplorerPanel.js +38 -33
  10. package/lib/components/explorer/QueryBuilderFunctionsExplorerPanel.js.map +1 -1
  11. package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
  12. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +12 -5
  13. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
  14. package/lib/components/filter/QueryBuilderFilterPanel.js +2 -2
  15. package/lib/components/filter/QueryBuilderFilterPanel.js.map +1 -1
  16. package/lib/components/result/tds/QueryBuilderTDSGridResult.d.ts.map +1 -1
  17. package/lib/components/result/tds/QueryBuilderTDSGridResult.js +4 -3
  18. package/lib/components/result/tds/QueryBuilderTDSGridResult.js.map +1 -1
  19. package/lib/components/result/tds/QueryBuilderTDSResultShared.d.ts +2 -2
  20. package/lib/components/result/tds/QueryBuilderTDSResultShared.d.ts.map +1 -1
  21. package/lib/components/result/tds/QueryBuilderTDSResultShared.js +157 -19
  22. package/lib/components/result/tds/QueryBuilderTDSResultShared.js.map +1 -1
  23. package/lib/index.css +2 -2
  24. package/lib/index.css.map +1 -1
  25. package/lib/index.d.ts +1 -1
  26. package/lib/index.d.ts.map +1 -1
  27. package/lib/index.js.map +1 -1
  28. package/lib/package.json +1 -1
  29. package/lib/stores/QueryBuilderState.d.ts +6 -1
  30. package/lib/stores/QueryBuilderState.d.ts.map +1 -1
  31. package/lib/stores/QueryBuilderState.js +3 -0
  32. package/lib/stores/QueryBuilderState.js.map +1 -1
  33. package/lib/stores/explorer/QueryFunctionsExplorerState.d.ts +17 -6
  34. package/lib/stores/explorer/QueryFunctionsExplorerState.d.ts.map +1 -1
  35. package/lib/stores/explorer/QueryFunctionsExplorerState.js +142 -59
  36. package/lib/stores/explorer/QueryFunctionsExplorerState.js.map +1 -1
  37. package/lib/stores/filter/QueryBuilderFilterOperator.d.ts +1 -1
  38. package/lib/stores/filter/QueryBuilderFilterOperator.d.ts.map +1 -1
  39. package/lib/stores/filter/QueryBuilderFilterState.d.ts +1 -1
  40. package/lib/stores/filter/QueryBuilderFilterState.d.ts.map +1 -1
  41. package/lib/stores/filter/QueryBuilderFilterState.js +8 -3
  42. package/lib/stores/filter/QueryBuilderFilterState.js.map +1 -1
  43. package/lib/stores/filter/QueryBuilderFilterStateBuilder.js +1 -1
  44. package/lib/stores/filter/QueryBuilderFilterStateBuilder.js.map +1 -1
  45. package/lib/stores/filter/operators/QueryBuilderFilterOperator_Contain.d.ts +2 -2
  46. package/lib/stores/filter/operators/QueryBuilderFilterOperator_Contain.d.ts.map +1 -1
  47. package/lib/stores/filter/operators/QueryBuilderFilterOperator_Contain.js +3 -3
  48. package/lib/stores/filter/operators/QueryBuilderFilterOperator_Contain.js.map +1 -1
  49. package/lib/stores/filter/operators/QueryBuilderFilterOperator_EndWith.d.ts +2 -2
  50. package/lib/stores/filter/operators/QueryBuilderFilterOperator_EndWith.d.ts.map +1 -1
  51. package/lib/stores/filter/operators/QueryBuilderFilterOperator_EndWith.js +3 -3
  52. package/lib/stores/filter/operators/QueryBuilderFilterOperator_EndWith.js.map +1 -1
  53. package/lib/stores/filter/operators/QueryBuilderFilterOperator_Equal.d.ts +2 -2
  54. package/lib/stores/filter/operators/QueryBuilderFilterOperator_Equal.d.ts.map +1 -1
  55. package/lib/stores/filter/operators/QueryBuilderFilterOperator_Equal.js +2 -2
  56. package/lib/stores/filter/operators/QueryBuilderFilterOperator_Equal.js.map +1 -1
  57. package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThan.d.ts +1 -1
  58. package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThan.d.ts.map +1 -1
  59. package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThan.js +2 -2
  60. package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThan.js.map +1 -1
  61. package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThanEqual.d.ts +1 -1
  62. package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThanEqual.d.ts.map +1 -1
  63. package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThanEqual.js +2 -2
  64. package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThanEqual.js.map +1 -1
  65. package/lib/stores/filter/operators/QueryBuilderFilterOperator_In.d.ts +2 -2
  66. package/lib/stores/filter/operators/QueryBuilderFilterOperator_In.d.ts.map +1 -1
  67. package/lib/stores/filter/operators/QueryBuilderFilterOperator_In.js +2 -2
  68. package/lib/stores/filter/operators/QueryBuilderFilterOperator_In.js.map +1 -1
  69. package/lib/stores/filter/operators/QueryBuilderFilterOperator_IsEmpty.d.ts +2 -2
  70. package/lib/stores/filter/operators/QueryBuilderFilterOperator_IsEmpty.d.ts.map +1 -1
  71. package/lib/stores/filter/operators/QueryBuilderFilterOperator_IsEmpty.js +2 -2
  72. package/lib/stores/filter/operators/QueryBuilderFilterOperator_IsEmpty.js.map +1 -1
  73. package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThan.d.ts +1 -1
  74. package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThan.d.ts.map +1 -1
  75. package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThan.js +2 -2
  76. package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThan.js.map +1 -1
  77. package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThanEqual.d.ts +1 -1
  78. package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThanEqual.d.ts.map +1 -1
  79. package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThanEqual.js +2 -2
  80. package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThanEqual.js.map +1 -1
  81. package/lib/stores/filter/operators/QueryBuilderFilterOperator_StartWith.d.ts +2 -2
  82. package/lib/stores/filter/operators/QueryBuilderFilterOperator_StartWith.d.ts.map +1 -1
  83. package/lib/stores/filter/operators/QueryBuilderFilterOperator_StartWith.js +3 -3
  84. package/lib/stores/filter/operators/QueryBuilderFilterOperator_StartWith.js.map +1 -1
  85. package/package.json +6 -6
  86. package/src/__lib__/QueryBuilderTesting.ts +2 -0
  87. package/src/components/data-cube/QueryBuilderDataCube.tsx +15 -25
  88. package/src/components/explorer/QueryBuilderFunctionsExplorerPanel.tsx +63 -70
  89. package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +23 -11
  90. package/src/components/filter/QueryBuilderFilterPanel.tsx +2 -2
  91. package/src/components/result/tds/QueryBuilderTDSGridResult.tsx +7 -3
  92. package/src/components/result/tds/QueryBuilderTDSResultShared.tsx +334 -26
  93. package/src/index.ts +1 -0
  94. package/src/stores/QueryBuilderState.ts +12 -0
  95. package/src/stores/explorer/QueryFunctionsExplorerState.ts +227 -94
  96. package/src/stores/filter/QueryBuilderFilterOperator.ts +1 -1
  97. package/src/stores/filter/QueryBuilderFilterState.ts +10 -5
  98. package/src/stores/filter/QueryBuilderFilterStateBuilder.ts +1 -1
  99. package/src/stores/filter/operators/QueryBuilderFilterOperator_Contain.ts +3 -5
  100. package/src/stores/filter/operators/QueryBuilderFilterOperator_EndWith.ts +3 -5
  101. package/src/stores/filter/operators/QueryBuilderFilterOperator_Equal.ts +2 -2
  102. package/src/stores/filter/operators/QueryBuilderFilterOperator_GreaterThan.ts +2 -4
  103. package/src/stores/filter/operators/QueryBuilderFilterOperator_GreaterThanEqual.ts +2 -4
  104. package/src/stores/filter/operators/QueryBuilderFilterOperator_In.ts +2 -2
  105. package/src/stores/filter/operators/QueryBuilderFilterOperator_IsEmpty.ts +2 -2
  106. package/src/stores/filter/operators/QueryBuilderFilterOperator_LessThan.ts +2 -4
  107. package/src/stores/filter/operators/QueryBuilderFilterOperator_LessThanEqual.ts +2 -4
  108. package/src/stores/filter/operators/QueryBuilderFilterOperator_StartWith.ts +3 -5
@@ -22,12 +22,13 @@ import {
22
22
  import { observer } from 'mobx-react-lite';
23
23
  import { flowResult } from 'mobx';
24
24
  import {
25
- type TDSExecutionResult,
25
+ type AbstractPropertyExpression,
26
26
  type Enumeration,
27
- InstanceValue,
28
- EnumValueInstanceValue,
29
- EnumValueExplicitReference,
30
27
  type ExecutionResult,
28
+ type TDSExecutionResult,
29
+ EnumValueExplicitReference,
30
+ EnumValueInstanceValue,
31
+ InstanceValue,
31
32
  RelationalExecutionActivities,
32
33
  } from '@finos/legend-graph';
33
34
  import { format as formatSQL } from 'sql-formatter';
@@ -47,6 +48,7 @@ import { forwardRef } from 'react';
47
48
  import {
48
49
  QueryBuilderDerivationProjectionColumnState,
49
50
  QueryBuilderProjectionColumnState,
51
+ QueryBuilderSimpleProjectionColumnState,
50
52
  } from '../../../stores/fetch-structure/tds/projection/QueryBuilderProjectionColumnState.js';
51
53
  import {
52
54
  type QueryBuilderPostFilterTreeNodeData,
@@ -81,6 +83,30 @@ import {
81
83
  } from '../../../stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_IsEmpty.js';
82
84
  import { getTDSColumnState } from '../../../stores/fetch-structure/tds/QueryBuilderTDSHelper.js';
83
85
  import type { QueryBuilderTDSColumnState } from '../../../stores/fetch-structure/tds/QueryBuilderTDSColumnState.js';
86
+ import {
87
+ type QueryBuilderFilterState,
88
+ type QueryBuilderFilterTreeNodeData,
89
+ FilterConditionState,
90
+ FilterValueSpecConditionValueState,
91
+ isCollectionProperty,
92
+ QueryBuilderFilterTreeConditionNodeData,
93
+ } from '../../../stores/filter/QueryBuilderFilterState.js';
94
+ import { QueryBuilderAggregateColumnState } from '../../../stores/fetch-structure/tds/aggregation/QueryBuilderAggregationState.js';
95
+ import type { QueryBuilderFilterOperator } from '../../../stores/filter/QueryBuilderFilterOperator.js';
96
+ import {
97
+ QueryBuilderFilterOperator_Equal,
98
+ QueryBuilderFilterOperator_NotEqual,
99
+ } from '../../../stores/filter/operators/QueryBuilderFilterOperator_Equal.js';
100
+ import {
101
+ QueryBuilderFilterOperator_In,
102
+ QueryBuilderFilterOperator_NotIn,
103
+ } from '../../../stores/filter/operators/QueryBuilderFilterOperator_In.js';
104
+ import {
105
+ QueryBuilderFilterOperator_IsEmpty,
106
+ QueryBuilderFilterOperator_IsNotEmpty,
107
+ } from '../../../stores/filter/operators/QueryBuilderFilterOperator_IsEmpty.js';
108
+ import type { QueryBuilderState } from '../../../stores/QueryBuilderState.js';
109
+ import type { QueryBuilderPropertyExpressionState } from '../../../stores/QueryBuilderPropertyEditorState.js';
84
110
 
85
111
  export const tryToFormatSql = (sql: string): string => {
86
112
  try {
@@ -139,6 +165,13 @@ export type IQueryRendererParamsWithGridType = DataGridCellRendererParams & {
139
165
  tdsExecutionResult: TDSExecutionResult;
140
166
  };
141
167
 
168
+ const filterEqualOperator = new QueryBuilderFilterOperator_Equal();
169
+ const filterNotEqualOperator = new QueryBuilderFilterOperator_NotEqual();
170
+ const filterInOperator = new QueryBuilderFilterOperator_In();
171
+ const filterNotInOperator = new QueryBuilderFilterOperator_NotIn();
172
+ const filterEmptyOperator = new QueryBuilderFilterOperator_IsEmpty();
173
+ const filterNotEmptyOperator = new QueryBuilderFilterOperator_IsNotEmpty();
174
+
142
175
  const postFilterEqualOperator = new QueryBuilderPostFilterOperator_Equal();
143
176
  const postFilterInOperator = new QueryBuilderPostFilterOperator_In();
144
177
  const postFilterEmptyOperator = new QueryBuilderPostFilterOperator_IsEmpty();
@@ -148,6 +181,22 @@ const postFilterNotEqualOperator =
148
181
  new QueryBuilderPostFilterOperator_NotEqual();
149
182
  const postFilterNotInOperator = new QueryBuilderPostFilterOperator_NotIn();
150
183
 
184
+ const getExistingFilterNode = (
185
+ operators: QueryBuilderFilterOperator[],
186
+ propertyExpressionState: QueryBuilderPropertyExpressionState | undefined,
187
+ filterState: QueryBuilderFilterState,
188
+ ): QueryBuilderFilterTreeNodeData | undefined =>
189
+ Array.from(filterState.nodes.values())
190
+ .filter(filterByType(QueryBuilderFilterTreeConditionNodeData))
191
+ .filter(
192
+ (node) =>
193
+ node.condition.propertyExpressionState.path ===
194
+ propertyExpressionState?.path &&
195
+ operators
196
+ .map((op) => op.getLabel())
197
+ .includes(node.condition.operator.getLabel()),
198
+ )[0];
199
+
151
200
  const getExistingPostFilterNode = (
152
201
  operators: QueryBuilderPostFilterOperator[],
153
202
  projectionColumnName: string | undefined,
@@ -173,7 +222,7 @@ const getExistingPostFilterNode = (
173
222
  const updateFilterConditionValue = (
174
223
  conditionValue: InstanceValue,
175
224
  _cellData: QueryBuilderTDSResultCellData,
176
- tdsState: QueryBuilderTDSState,
225
+ queryBuilderState: QueryBuilderState,
177
226
  ): void => {
178
227
  if (_cellData.value) {
179
228
  instanceValue_setValue(
@@ -188,11 +237,58 @@ const updateFilterConditionValue = (
188
237
  )
189
238
  : _cellData.value,
190
239
  0,
191
- tdsState.queryBuilderState.observerContext,
240
+ queryBuilderState.observerContext,
192
241
  );
193
242
  }
194
243
  };
195
244
 
245
+ const generateNewFilterConditionNodeData = (
246
+ applicationStore: ApplicationStore<
247
+ LegendApplicationConfig,
248
+ LegendApplicationPluginManager<LegendApplicationPlugin>
249
+ >,
250
+ operator: QueryBuilderFilterOperator,
251
+ _cellData: QueryBuilderTDSResultCellData,
252
+ filterState: QueryBuilderFilterState,
253
+ propertyExpression: AbstractPropertyExpression | undefined,
254
+ ): void => {
255
+ let filterConditionState: FilterConditionState;
256
+ try {
257
+ if (propertyExpression) {
258
+ filterConditionState = new FilterConditionState(
259
+ filterState,
260
+ propertyExpression,
261
+ operator,
262
+ );
263
+
264
+ const defaultFilterConditionValue =
265
+ filterConditionState.operator.getDefaultFilterConditionValue(
266
+ filterConditionState,
267
+ );
268
+
269
+ filterConditionState.buildRightConditionValueFromValueSpec(
270
+ defaultFilterConditionValue,
271
+ );
272
+ updateFilterConditionValue(
273
+ defaultFilterConditionValue as InstanceValue,
274
+ _cellData,
275
+ filterState.queryBuilderState,
276
+ );
277
+ filterState.addNodeFromNode(
278
+ new QueryBuilderFilterTreeConditionNodeData(
279
+ undefined,
280
+ filterConditionState,
281
+ ),
282
+ undefined,
283
+ );
284
+ }
285
+ } catch (error) {
286
+ assertErrorThrown(error);
287
+ applicationStore.notificationService.notifyWarning(error.message);
288
+ return;
289
+ }
290
+ };
291
+
196
292
  const generateNewPostFilterConditionNodeData = async (
197
293
  applicationStore: ApplicationStore<
198
294
  LegendApplicationConfig,
@@ -235,7 +331,7 @@ const generateNewPostFilterConditionNodeData = async (
235
331
  updateFilterConditionValue(
236
332
  defaultFilterConditionValue as InstanceValue,
237
333
  _cellData,
238
- tdsState,
334
+ tdsState.queryBuilderState,
239
335
  );
240
336
  tdsState.postFilterState.addNodeFromNode(
241
337
  new QueryBuilderPostFilterTreeConditionNodeData(
@@ -252,6 +348,91 @@ const generateNewPostFilterConditionNodeData = async (
252
348
  }
253
349
  };
254
350
 
351
+ const updateExistingFilterConditionNodeData = (
352
+ existingPreFilterNode: QueryBuilderFilterTreeNodeData,
353
+ isFilterBy: boolean,
354
+ _cellData: QueryBuilderTDSResultCellData,
355
+ operator: QueryBuilderFilterOperator,
356
+ data: QueryBuilderTDSResultCellData | null,
357
+ queryBuilderState: QueryBuilderState,
358
+ ): void => {
359
+ if (operator === filterEmptyOperator || operator === filterNotEmptyOperator) {
360
+ const conditionState = (
361
+ existingPreFilterNode as QueryBuilderFilterTreeConditionNodeData
362
+ ).condition;
363
+ if (conditionState.operator.getLabel() !== operator.getLabel()) {
364
+ conditionState.changeOperator(
365
+ isFilterBy ? filterEmptyOperator : filterNotEmptyOperator,
366
+ );
367
+ }
368
+ return;
369
+ }
370
+ const conditionState = (
371
+ existingPreFilterNode as QueryBuilderFilterTreeConditionNodeData
372
+ ).condition;
373
+
374
+ const rightSide = conditionState.rightConditionValue;
375
+ if (rightSide instanceof FilterValueSpecConditionValueState) {
376
+ if (conditionState.operator.getLabel() === operator.getLabel()) {
377
+ const doesValueAlreadyExist =
378
+ rightSide.value instanceof InstanceValue &&
379
+ (rightSide.value instanceof EnumValueInstanceValue
380
+ ? rightSide.value.values.map((ef) => ef.value.name)
381
+ : rightSide.value.values
382
+ ).includes(_cellData.value);
383
+
384
+ if (!doesValueAlreadyExist) {
385
+ const currentValueSpecificaton = rightSide.value;
386
+ const newValueSpecification =
387
+ conditionState.operator.getDefaultFilterConditionValue(
388
+ conditionState,
389
+ );
390
+ updateFilterConditionValue(
391
+ newValueSpecification as InstanceValue,
392
+ _cellData,
393
+ queryBuilderState,
394
+ );
395
+ conditionState.changeOperator(
396
+ isFilterBy ? filterInOperator : filterNotInOperator,
397
+ );
398
+ instanceValue_setValues(
399
+ rightSide.value as InstanceValue,
400
+ [currentValueSpecificaton, newValueSpecification],
401
+ queryBuilderState.observerContext,
402
+ );
403
+ }
404
+ } else {
405
+ const doesValueAlreadyExist =
406
+ rightSide.value instanceof InstanceValue &&
407
+ rightSide.value.values
408
+ .filter((v) => v instanceof InstanceValue)
409
+ .map((v) =>
410
+ v instanceof EnumValueInstanceValue
411
+ ? v.values.map((ef) => ef.value.name)
412
+ : v.values,
413
+ )
414
+ .flat()
415
+ .includes(_cellData.value ?? data?.value);
416
+
417
+ if (!doesValueAlreadyExist) {
418
+ const newValueSpecification = (
419
+ isFilterBy ? filterEqualOperator : filterNotEqualOperator
420
+ ).getDefaultFilterConditionValue(conditionState);
421
+ updateFilterConditionValue(
422
+ newValueSpecification as InstanceValue,
423
+ _cellData,
424
+ queryBuilderState,
425
+ );
426
+ instanceValue_setValues(
427
+ rightSide.value as InstanceValue,
428
+ [...(rightSide.value as InstanceValue).values, newValueSpecification],
429
+ queryBuilderState.observerContext,
430
+ );
431
+ }
432
+ }
433
+ }
434
+ };
435
+
255
436
  const updateExistingPostFilterConditionNodeData = (
256
437
  existingPostFilterNode: QueryBuilderPostFilterTreeNodeData,
257
438
  isFilterBy: boolean,
@@ -297,7 +478,7 @@ const updateExistingPostFilterConditionNodeData = (
297
478
  updateFilterConditionValue(
298
479
  newValueSpecification as InstanceValue,
299
480
  _cellData,
300
- tdsState,
481
+ tdsState.queryBuilderState,
301
482
  );
302
483
  conditionState.changeOperator(
303
484
  isFilterBy ? postFilterInOperator : postFilterNotInOperator,
@@ -328,7 +509,7 @@ const updateExistingPostFilterConditionNodeData = (
328
509
  updateFilterConditionValue(
329
510
  newValueSpecification as InstanceValue,
330
511
  _cellData,
331
- tdsState,
512
+ tdsState.queryBuilderState,
332
513
  );
333
514
  instanceValue_setValues(
334
515
  rightSide.value as InstanceValue,
@@ -343,6 +524,25 @@ const updateExistingPostFilterConditionNodeData = (
343
524
  const getFilterOperator = (
344
525
  isFilterBy: boolean,
345
526
  _cellData: QueryBuilderTDSResultCellData,
527
+ ): QueryBuilderFilterOperator => {
528
+ if (isFilterBy) {
529
+ if (_cellData.value === null) {
530
+ return filterEmptyOperator;
531
+ } else {
532
+ return filterEqualOperator;
533
+ }
534
+ } else {
535
+ if (_cellData.value === null) {
536
+ return filterNotEmptyOperator;
537
+ } else {
538
+ return filterNotEqualOperator;
539
+ }
540
+ }
541
+ };
542
+
543
+ const getPostFilterOperator = (
544
+ isFilterBy: boolean,
545
+ _cellData: QueryBuilderTDSResultCellData,
346
546
  ): QueryBuilderPostFilterOperator => {
347
547
  if (isFilterBy) {
348
548
  if (_cellData.value === null) {
@@ -359,7 +559,7 @@ const getFilterOperator = (
359
559
  }
360
560
  };
361
561
 
362
- const filterByOrOutValue = (
562
+ const preFilterByOrOutValue = (
363
563
  applicationStore: ApplicationStore<
364
564
  LegendApplicationConfig,
365
565
  LegendApplicationPluginManager<LegendApplicationPlugin>
@@ -367,13 +567,58 @@ const filterByOrOutValue = (
367
567
  isFilterBy: boolean,
368
568
  _cellData: QueryBuilderTDSResultCellData,
369
569
  data: QueryBuilderTDSResultCellData | null,
370
- tdsState: QueryBuilderTDSState,
570
+ propertyExpressionState: QueryBuilderPropertyExpressionState,
571
+ queryBuilderState: QueryBuilderState,
371
572
  ): void => {
372
- tdsState.setShowPostFilterPanel(true);
573
+ queryBuilderState.filterState.setShowPanel(true);
373
574
  const operator = getFilterOperator(isFilterBy, _cellData);
374
- const tdsColState = data?.columnName
375
- ? getTDSColumnState(tdsState, data.columnName)
376
- : undefined;
575
+ const existingPreFilterNode = getExistingFilterNode(
576
+ _cellData.value === null
577
+ ? [filterEmptyOperator, filterNotEmptyOperator]
578
+ : isFilterBy
579
+ ? [filterEqualOperator, filterInOperator]
580
+ : [filterNotEqualOperator, filterNotInOperator],
581
+ propertyExpressionState,
582
+ queryBuilderState.filterState,
583
+ );
584
+ if (existingPreFilterNode) {
585
+ updateExistingFilterConditionNodeData(
586
+ existingPreFilterNode,
587
+ isFilterBy,
588
+ _cellData,
589
+ operator,
590
+ data,
591
+ queryBuilderState,
592
+ );
593
+ } else {
594
+ try {
595
+ generateNewFilterConditionNodeData(
596
+ applicationStore,
597
+ operator,
598
+ _cellData,
599
+ queryBuilderState.filterState,
600
+ propertyExpressionState.propertyExpression,
601
+ );
602
+ } catch (error) {
603
+ assertErrorThrown(error);
604
+ applicationStore.alertUnhandledError(error);
605
+ }
606
+ }
607
+ };
608
+
609
+ const postFilterByOrOutValue = async (
610
+ applicationStore: ApplicationStore<
611
+ LegendApplicationConfig,
612
+ LegendApplicationPluginManager<LegendApplicationPlugin>
613
+ >,
614
+ isFilterBy: boolean,
615
+ _cellData: QueryBuilderTDSResultCellData,
616
+ data: QueryBuilderTDSResultCellData | null,
617
+ tdsColState: QueryBuilderTDSColumnState,
618
+ tdsState: QueryBuilderTDSState,
619
+ ): Promise<void> => {
620
+ tdsState.setShowPostFilterPanel(true);
621
+ const operator = getPostFilterOperator(isFilterBy, _cellData);
377
622
  const existingPostFilterNode = getExistingPostFilterNode(
378
623
  _cellData.value === null
379
624
  ? [postFilterEmptyOperator, postFilterNotEmptyOperator]
@@ -394,17 +639,69 @@ const filterByOrOutValue = (
394
639
  tdsState,
395
640
  );
396
641
  } else {
397
- generateNewPostFilterConditionNodeData(
642
+ try {
643
+ await generateNewPostFilterConditionNodeData(
644
+ applicationStore,
645
+ operator,
646
+ _cellData,
647
+ tdsState,
648
+ tdsColState,
649
+ );
650
+ } catch (error) {
651
+ assertErrorThrown(error);
652
+ applicationStore.alertUnhandledError(error);
653
+ }
654
+ }
655
+ };
656
+
657
+ const filterByOrOutValue = async (
658
+ applicationStore: ApplicationStore<
659
+ LegendApplicationConfig,
660
+ LegendApplicationPluginManager<LegendApplicationPlugin>
661
+ >,
662
+ isFilterBy: boolean,
663
+ _cellData: QueryBuilderTDSResultCellData,
664
+ data: QueryBuilderTDSResultCellData | null,
665
+ tdsState: QueryBuilderTDSState,
666
+ ): Promise<void> => {
667
+ const tdsColState = data?.columnName
668
+ ? getTDSColumnState(tdsState, _cellData.columnName)
669
+ : _cellData.columnName
670
+ ? getTDSColumnState(tdsState, _cellData.columnName)
671
+ : undefined;
672
+ if (
673
+ tdsColState instanceof QueryBuilderDerivationProjectionColumnState ||
674
+ tdsColState instanceof QueryBuilderAggregateColumnState ||
675
+ (tdsColState instanceof QueryBuilderSimpleProjectionColumnState &&
676
+ isCollectionProperty(
677
+ tdsColState.propertyExpressionState.propertyExpression,
678
+ ))
679
+ ) {
680
+ await postFilterByOrOutValue(
398
681
  applicationStore,
399
- operator,
682
+ isFilterBy,
400
683
  _cellData,
401
- tdsState,
684
+ data,
402
685
  tdsColState,
403
- ).catch(applicationStore.alertUnhandledError);
686
+ tdsState,
687
+ );
688
+ } else if (tdsColState instanceof QueryBuilderSimpleProjectionColumnState) {
689
+ preFilterByOrOutValue(
690
+ applicationStore,
691
+ isFilterBy,
692
+ _cellData,
693
+ data,
694
+ tdsColState.propertyExpressionState,
695
+ tdsState.queryBuilderState,
696
+ );
697
+ } else {
698
+ applicationStore.notificationService.notifyError(
699
+ `Can't filter column '${data?.columnName ? data.columnName : _cellData.columnName}'`,
700
+ );
404
701
  }
405
702
  };
406
703
 
407
- export const filterByOrOutValues = (
704
+ export const filterByOrOutValues = async (
408
705
  applicationStore: ApplicationStore<
409
706
  LegendApplicationConfig,
410
707
  LegendApplicationPluginManager<LegendApplicationPlugin>
@@ -412,10 +709,17 @@ export const filterByOrOutValues = (
412
709
  data: QueryBuilderTDSResultCellData | null,
413
710
  isFilterBy: boolean,
414
711
  tdsState: QueryBuilderTDSState,
415
- ): void => {
416
- tdsState.queryBuilderState.resultState.selectedCells.forEach((_cellData) => {
417
- filterByOrOutValue(applicationStore, isFilterBy, _cellData, data, tdsState);
418
- });
712
+ ): Promise<void> => {
713
+ for (const _cellData of tdsState.queryBuilderState.resultState
714
+ .selectedCells) {
715
+ await filterByOrOutValue(
716
+ applicationStore,
717
+ isFilterBy,
718
+ _cellData,
719
+ data,
720
+ tdsState,
721
+ );
722
+ }
419
723
  };
420
724
 
421
725
  export const QueryBuilderGridResultContextMenu = observer(
@@ -440,7 +744,9 @@ export const QueryBuilderGridResultContextMenu = observer(
440
744
  <MenuContentItem
441
745
  disabled={!tdsColState}
442
746
  onClick={(): void => {
443
- filterByOrOutValues(applicationStore, data, true, tdsState);
747
+ filterByOrOutValues(applicationStore, data, true, tdsState).catch(
748
+ tdsState.queryBuilderState.applicationStore.alertUnhandledError,
749
+ );
444
750
  }}
445
751
  >
446
752
  Filter By
@@ -448,7 +754,9 @@ export const QueryBuilderGridResultContextMenu = observer(
448
754
  <MenuContentItem
449
755
  disabled={!tdsColState}
450
756
  onClick={(): void => {
451
- filterByOrOutValues(applicationStore, data, false, tdsState);
757
+ filterByOrOutValues(applicationStore, data, false, tdsState).catch(
758
+ tdsState.queryBuilderState.applicationStore.alertUnhandledError,
759
+ );
452
760
  }}
453
761
  >
454
762
  Filter Out
package/src/index.ts CHANGED
@@ -34,6 +34,7 @@ export { QueryBuilder } from './components/QueryBuilder.js';
34
34
  export { QUERY_BUILDER_COMPONENT_ELEMENT_ID } from './components/QueryBuilderComponentElement.js';
35
35
  export {
36
36
  type QueryableSourceInfo as QuerySDLC,
37
+ type QueryBuilderExtraFunctionAnalysisInfo,
37
38
  QueryBuilderState,
38
39
  QUERY_BUILDER_LAMBDA_WRITER_MODE,
39
40
  INTERNAL__BasicQueryBuilderState,
@@ -56,6 +56,7 @@ import {
56
56
  type Type,
57
57
  type QueryGridConfig,
58
58
  type QueryExecutionContext,
59
+ type FunctionAnalysisInfo,
59
60
  GRAPH_MANAGER_EVENT,
60
61
  CompilationError,
61
62
  extractSourceInformationCoordinates,
@@ -117,6 +118,11 @@ export type QueryableClassMappingRuntimeInfo = QueryableSourceInfo & {
117
118
  runtime: string;
118
119
  };
119
120
 
121
+ export type QueryBuilderExtraFunctionAnalysisInfo = {
122
+ functionInfoMap: Map<string, FunctionAnalysisInfo>;
123
+ dependencyFunctionInfoMap: Map<string, FunctionAnalysisInfo>;
124
+ };
125
+
120
126
  export enum QUERY_BUILDER_LAMBDA_WRITER_MODE {
121
127
  STANDARD = 'STANDARD',
122
128
  TYPED_FETCH_STRUCTURE = 'TYPED_FETCH_STRUCTURE',
@@ -832,6 +838,12 @@ export abstract class QueryBuilderState implements CommandRegistrar {
832
838
  );
833
839
  }
834
840
 
841
+ buildFunctionAnalysisInfo():
842
+ | QueryBuilderExtraFunctionAnalysisInfo
843
+ | undefined {
844
+ return undefined;
845
+ }
846
+
835
847
  /**
836
848
  * This method can be used to simplify the current query builder state
837
849
  * to a basic one that can be used for testing or some special operations,