@finos/legend-query-builder 4.15.2 → 4.15.4

Sign up to get free protection for your applications and to get access to all the features.
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,