@finos/legend-query-builder 4.9.4 → 4.10.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. package/lib/__lib__/QueryBuilderTesting.d.ts +4 -1
  2. package/lib/__lib__/QueryBuilderTesting.d.ts.map +1 -1
  3. package/lib/__lib__/QueryBuilderTesting.js +5 -1
  4. package/lib/__lib__/QueryBuilderTesting.js.map +1 -1
  5. package/lib/components/QueryBuilderResultPanel.d.ts.map +1 -1
  6. package/lib/components/QueryBuilderResultPanel.js +80 -90
  7. package/lib/components/QueryBuilderResultPanel.js.map +1 -1
  8. package/lib/components/__test-utils__/QueryBuilderComponentTestUtils.d.ts +1 -0
  9. package/lib/components/__test-utils__/QueryBuilderComponentTestUtils.d.ts.map +1 -1
  10. package/lib/components/__test-utils__/QueryBuilderComponentTestUtils.js +13 -1
  11. package/lib/components/__test-utils__/QueryBuilderComponentTestUtils.js.map +1 -1
  12. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.d.ts +2 -2
  13. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.d.ts.map +1 -1
  14. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js +42 -24
  15. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js.map +1 -1
  16. package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
  17. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +1 -1
  18. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
  19. package/lib/components/filter/QueryBuilderFilterPanel.d.ts +3 -2
  20. package/lib/components/filter/QueryBuilderFilterPanel.d.ts.map +1 -1
  21. package/lib/components/filter/QueryBuilderFilterPanel.js +145 -8
  22. package/lib/components/filter/QueryBuilderFilterPanel.js.map +1 -1
  23. package/lib/index.css +16 -0
  24. package/lib/package.json +1 -1
  25. package/lib/stores/QueryBuilderConstantsState.d.ts +5 -1
  26. package/lib/stores/QueryBuilderConstantsState.d.ts.map +1 -1
  27. package/lib/stores/QueryBuilderConstantsState.js +14 -1
  28. package/lib/stores/QueryBuilderConstantsState.js.map +1 -1
  29. package/lib/stores/QueryBuilderResultState.d.ts +3 -0
  30. package/lib/stores/QueryBuilderResultState.d.ts.map +1 -1
  31. package/lib/stores/QueryBuilderResultState.js +31 -2
  32. package/lib/stores/QueryBuilderResultState.js.map +1 -1
  33. package/lib/stores/QueryBuilderStateHashUtils.d.ts +2 -0
  34. package/lib/stores/QueryBuilderStateHashUtils.d.ts.map +1 -1
  35. package/lib/stores/QueryBuilderStateHashUtils.js +2 -0
  36. package/lib/stores/QueryBuilderStateHashUtils.js.map +1 -1
  37. package/lib/stores/QueryBuilderValueSpecificationBuilder.d.ts.map +1 -1
  38. package/lib/stores/QueryBuilderValueSpecificationBuilder.js +3 -23
  39. package/lib/stores/QueryBuilderValueSpecificationBuilder.js.map +1 -1
  40. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterOperator.js +1 -1
  41. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterOperator.js.map +1 -1
  42. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.d.ts +31 -5
  43. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.d.ts.map +1 -1
  44. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js +125 -30
  45. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js.map +1 -1
  46. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterStateBuilder.d.ts.map +1 -1
  47. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterStateBuilder.js +21 -8
  48. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterStateBuilder.js.map +1 -1
  49. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperatorValueSpecificationBuilder.d.ts +3 -1
  50. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperatorValueSpecificationBuilder.d.ts.map +1 -1
  51. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperatorValueSpecificationBuilder.js +20 -17
  52. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperatorValueSpecificationBuilder.js.map +1 -1
  53. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Contain.d.ts.map +1 -1
  54. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Contain.js +4 -6
  55. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Contain.js.map +1 -1
  56. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_EndWith.d.ts.map +1 -1
  57. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_EndWith.js +4 -6
  58. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_EndWith.js.map +1 -1
  59. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Equal.d.ts +1 -1
  60. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Equal.d.ts.map +1 -1
  61. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Equal.js +10 -10
  62. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Equal.js.map +1 -1
  63. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_GreaterThan.d.ts.map +1 -1
  64. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_GreaterThan.js +10 -10
  65. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_GreaterThan.js.map +1 -1
  66. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_GreaterThanEqual.d.ts.map +1 -1
  67. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_GreaterThanEqual.js +5 -5
  68. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_GreaterThanEqual.js.map +1 -1
  69. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_In.d.ts +1 -1
  70. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_In.d.ts.map +1 -1
  71. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_In.js +32 -27
  72. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_In.js.map +1 -1
  73. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_IsEmpty.d.ts.map +1 -1
  74. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_IsEmpty.js +10 -5
  75. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_IsEmpty.js.map +1 -1
  76. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_LessThan.d.ts.map +1 -1
  77. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_LessThan.js +10 -10
  78. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_LessThan.js.map +1 -1
  79. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_LessThanEqual.d.ts.map +1 -1
  80. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_LessThanEqual.js +5 -5
  81. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_LessThanEqual.js.map +1 -1
  82. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_StartWith.d.ts.map +1 -1
  83. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_StartWith.js +4 -6
  84. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_StartWith.js.map +1 -1
  85. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionColumnState.d.ts.map +1 -1
  86. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionColumnState.js +17 -3
  87. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionColumnState.js.map +1 -1
  88. package/lib/stores/filter/QueryBuilderFilterState.d.ts +7 -1
  89. package/lib/stores/filter/QueryBuilderFilterState.d.ts.map +1 -1
  90. package/lib/stores/filter/QueryBuilderFilterState.js +27 -0
  91. package/lib/stores/filter/QueryBuilderFilterState.js.map +1 -1
  92. package/package.json +5 -5
  93. package/src/__lib__/QueryBuilderTesting.ts +5 -1
  94. package/src/components/QueryBuilderResultPanel.tsx +127 -135
  95. package/src/components/__test-utils__/QueryBuilderComponentTestUtils.tsx +25 -1
  96. package/src/components/fetch-structure/QueryBuilderPostFilterPanel.tsx +102 -49
  97. package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +6 -2
  98. package/src/components/filter/QueryBuilderFilterPanel.tsx +239 -21
  99. package/src/stores/QueryBuilderConstantsState.ts +30 -0
  100. package/src/stores/QueryBuilderResultState.ts +36 -1
  101. package/src/stores/QueryBuilderStateHashUtils.ts +2 -0
  102. package/src/stores/QueryBuilderValueSpecificationBuilder.ts +4 -50
  103. package/src/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterOperator.ts +1 -1
  104. package/src/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.ts +180 -34
  105. package/src/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterStateBuilder.ts +38 -9
  106. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperatorValueSpecificationBuilder.ts +36 -20
  107. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Contain.ts +5 -6
  108. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_EndWith.ts +6 -6
  109. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Equal.ts +12 -13
  110. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_GreaterThan.ts +10 -9
  111. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_GreaterThanEqual.ts +5 -4
  112. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_In.ts +48 -43
  113. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_IsEmpty.ts +12 -4
  114. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_LessThan.ts +10 -9
  115. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_LessThanEqual.ts +5 -4
  116. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_StartWith.ts +6 -6
  117. package/src/stores/fetch-structure/tds/projection/QueryBuilderProjectionColumnState.ts +26 -4
  118. package/src/stores/filter/QueryBuilderFilterState.ts +40 -1
@@ -17,14 +17,15 @@
17
17
  import { action, flow, makeObservable, observable } from 'mobx';
18
18
  import {
19
19
  type GeneratorFn,
20
+ type ContentType,
20
21
  assertErrorThrown,
21
22
  LogEvent,
22
23
  guaranteeNonNullable,
23
- type ContentType,
24
24
  downloadFileUsingDataURI,
25
25
  ActionState,
26
26
  StopWatch,
27
27
  getContentTypeFileExtension,
28
+ isBoolean,
28
29
  } from '@finos/legend-shared';
29
30
  import type { QueryBuilderState } from './QueryBuilderState.js';
30
31
  import {
@@ -37,6 +38,7 @@ import {
37
38
  buildRawLambdaFromLambdaFunction,
38
39
  reportGraphAnalytics,
39
40
  extractExecutionResultValues,
41
+ TDSExecutionResult,
40
42
  } from '@finos/legend-graph';
41
43
  import { buildLambdaFunction } from './QueryBuilderValueSpecificationBuilder.js';
42
44
  import { DEFAULT_TAB_SIZE } from '@finos/legend-application';
@@ -81,6 +83,7 @@ export class QueryBuilderResultState {
81
83
  latestRunHashCode?: string | undefined;
82
84
  queryRunPromise: Promise<ExecutionResult> | undefined = undefined;
83
85
  isQueryUsageViewerOpened = false;
86
+ rowData: Record<string, string | number | boolean | null>[] = [];
84
87
 
85
88
  selectedCells: QueryBuilderTDSResultCellData[];
86
89
  mousedOverCell: QueryBuilderTDSResultCellData | null = null;
@@ -110,6 +113,8 @@ export class QueryBuilderResultState {
110
113
  setQueryRunPromise: action,
111
114
  setIsQueryUsageViewerOpened: action,
112
115
  exportData: flow,
116
+ getRowData: action,
117
+ setRowData: action,
113
118
  runQuery: flow,
114
119
  cancelQuery: flow,
115
120
  generatePlan: flow,
@@ -124,6 +129,36 @@ export class QueryBuilderResultState {
124
129
  );
125
130
  }
126
131
 
132
+ getRowData(): Record<string, string | number | boolean | null>[] {
133
+ if (
134
+ this.executionResult &&
135
+ this.executionResult instanceof TDSExecutionResult
136
+ ) {
137
+ const data = this.executionResult.result.rows.map((_row, rowIdx) => {
138
+ const row: Record<string, string | number | boolean | null> = {};
139
+ const cols = (this.executionResult as TDSExecutionResult).result
140
+ .columns;
141
+ _row.values.forEach((value, colIdx) => {
142
+ // `ag-grid` shows `false` value as empty string so we have
143
+ // call `.toString()` to avoid this behavior.
144
+ // See https://github.com/finos/legend-studio/issues/1008
145
+ row[cols[colIdx] as string] = isBoolean(value)
146
+ ? String(value)
147
+ : value;
148
+ });
149
+ row.rowNumber = rowIdx;
150
+ return row;
151
+ });
152
+ this.rowData = data;
153
+ return data;
154
+ }
155
+ return [];
156
+ }
157
+
158
+ setRowData(val: Record<string, string | number | boolean | null>[]): void {
159
+ this.rowData = val;
160
+ }
161
+
127
162
  setIsSelectingCells(val: boolean): void {
128
163
  this.isSelectingCells = val;
129
164
  }
@@ -45,6 +45,8 @@ export enum QUERY_BUILDER_STATE_HASH_STRUCTURE {
45
45
  POST_FILTER_TREE_CONDIITION_NODE_DATA = 'POST_FILTER_TREE_CONDITION_NODE_DATA',
46
46
  POST_FILTER_TREE_BLANK_CONDITION_NODE_DATA = 'POST_FILTER_TREE_BLANK_CONDITION_NODE_DATA',
47
47
  POST_FILTER_CONDITION_STATE = 'POST_FILTER_CONDITION_STATE',
48
+ POST_FILTER_CONDITION_RIGHT_VALUE = 'POST_FILTER_CONDITION_RIGHT_VALUE',
49
+ POST_FILTER_CONDITION_RIGHT_VALUE_SPEC = 'POST_FILTER_CONDITION_RIGHT_VALUE_SPEC',
48
50
  POST_FILTER_OPERATOR_CONTAIN = 'POST_FILTER_OPERATOR_CONTAIN',
49
51
  POST_FILTER_OPERATOR_NOT_CONTAIN = 'POST_FILTER_OPERATOR_NOT_CONTAIN',
50
52
  POST_FILTER_OPERATOR_END_WITH = 'POST_FILTER_OPERATOR_END_WITH',
@@ -14,14 +14,9 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import {
18
- UnsupportedOperationError,
19
- guaranteeNonNullable,
20
- guaranteeType,
21
- } from '@finos/legend-shared';
17
+ import { guaranteeNonNullable, guaranteeType } from '@finos/legend-shared';
22
18
  import {
23
19
  type Class,
24
- type ValueSpecification,
25
20
  Multiplicity,
26
21
  getMilestoneTemporalStereotype,
27
22
  extractElementNameFromPath,
@@ -33,11 +28,8 @@ import {
33
28
  GenericTypeExplicitReference,
34
29
  LambdaFunction,
35
30
  SimpleFunctionExpression,
36
- PrimitiveInstanceValue,
37
- PrimitiveType,
38
31
  SUPPORTED_FUNCTIONS,
39
32
  RuntimePointer,
40
- INTERNAL__UnknownValueSpecification,
41
33
  } from '@finos/legend-graph';
42
34
  import type { QueryBuilderState } from './QueryBuilderState.js';
43
35
  import { buildFilterExpression } from './filter/QueryBuilderFilterValueSpecificationBuilder.js';
@@ -46,11 +38,6 @@ import type { QueryBuilderFetchStructureState } from './fetch-structure/QueryBui
46
38
  import { QUERY_BUILDER_SUPPORTED_FUNCTIONS } from '../graph/QueryBuilderMetaModelConst.js';
47
39
  import { buildWatermarkExpression } from './watermark/QueryBuilderWatermarkValueSpecificationBuilder.js';
48
40
  import { buildExecutionQueryFromLambdaFunction } from './shared/LambdaParameterState.js';
49
- import {
50
- QueryBuilderSimpleConstantExpressionState,
51
- type QueryBuilderConstantExpressionState,
52
- QueryBuilderCalculatedConstantExpressionState,
53
- } from './QueryBuilderConstantsState.js';
54
41
  import {
55
42
  QueryBuilderEmbeddedFromExecutionContextState,
56
43
  type QueryBuilderExecutionContextState,
@@ -90,40 +77,6 @@ const buildGetAllVersionsFunction = (
90
77
  return _func;
91
78
  };
92
79
 
93
- const buildLetExpression = (
94
- constantExpressionState: QueryBuilderConstantExpressionState,
95
- ): SimpleFunctionExpression => {
96
- const varName = constantExpressionState.variable.name;
97
- const leftSide = new PrimitiveInstanceValue(
98
- GenericTypeExplicitReference.create(new GenericType(PrimitiveType.STRING)),
99
- );
100
- leftSide.values = [varName];
101
- const letFunc = new SimpleFunctionExpression(
102
- extractElementNameFromPath(SUPPORTED_FUNCTIONS.LET),
103
- );
104
- let value: ValueSpecification;
105
- if (
106
- constantExpressionState instanceof QueryBuilderSimpleConstantExpressionState
107
- ) {
108
- value = constantExpressionState.value;
109
- } else if (
110
- constantExpressionState instanceof
111
- QueryBuilderCalculatedConstantExpressionState
112
- ) {
113
- value = new INTERNAL__UnknownValueSpecification(
114
- constantExpressionState.value,
115
- );
116
- } else {
117
- throw new UnsupportedOperationError(
118
- `Can't build let() expression: unsupported constant state`,
119
- constantExpressionState,
120
- );
121
- }
122
-
123
- letFunc.parametersValues = [leftSide, value];
124
- return letFunc;
125
- };
126
-
127
80
  const buildExecutionContextState = (
128
81
  executionState: QueryBuilderExecutionContextState,
129
82
  lambdaFunction: LambdaFunction,
@@ -237,8 +190,9 @@ export const buildLambdaFunction = (
237
190
 
238
191
  // build variable expressions
239
192
  if (queryBuilderState.constantState.constants.length) {
240
- const letExpressions =
241
- queryBuilderState.constantState.constants.map(buildLetExpression);
193
+ const letExpressions = queryBuilderState.constantState.constants.map((e) =>
194
+ e.buildLetExpression(),
195
+ );
242
196
  lambdaFunction.expressionSequence = [
243
197
  ...letExpressions,
244
198
  ...lambdaFunction.expressionSequence,
@@ -48,7 +48,7 @@ export abstract class QueryBuilderPostFilterOperator implements Hashable {
48
48
  isCompatibleWithPostFilterColumn(
49
49
  postFilterState: PostFilterConditionState,
50
50
  ): boolean {
51
- const columnType = postFilterState.columnState.getColumnType();
51
+ const columnType = postFilterState.leftConditionValue.getColumnType();
52
52
  if (columnType) {
53
53
  return this.isCompatibleWithType(columnType);
54
54
  }
@@ -21,10 +21,12 @@ import {
21
21
  type ValueSpecification,
22
22
  type ExecutionResult,
23
23
  type VariableExpression,
24
+ type SimpleFunctionExpression,
24
25
  Enumeration,
25
26
  PRIMITIVE_TYPE,
26
27
  observe_ValueSpecification,
27
28
  PrimitiveType,
29
+ CollectionInstanceValue,
28
30
  } from '@finos/legend-graph';
29
31
  import {
30
32
  type GeneratorFn,
@@ -70,7 +72,12 @@ import { QUERY_BUILDER_GROUP_OPERATION } from '../../../QueryBuilderGroupOperati
70
72
  import type { QueryBuilderTDSState } from '../QueryBuilderTDSState.js';
71
73
  import { QUERY_BUILDER_STATE_HASH_STRUCTURE } from '../../../QueryBuilderStateHashUtils.js';
72
74
  import type { QueryBuilderTDSColumnState } from '../QueryBuilderTDSColumnState.js';
73
- import { isValueExpressionReferencedInValue } from '../../../QueryBuilderValueSpecificationHelper.js';
75
+ import {
76
+ getCollectionValueSpecificationType,
77
+ getNonCollectionValueSpecificationType,
78
+ isValueExpressionReferencedInValue,
79
+ } from '../../../QueryBuilderValueSpecificationHelper.js';
80
+ import { buildtdsPropertyExpressionFromColState } from './operators/QueryBuilderPostFilterOperatorValueSpecificationBuilder.js';
74
81
 
75
82
  export enum QUERY_BUILDER_POST_FILTER_DND_TYPE {
76
83
  GROUP_CONDITION = 'GROUP_CONDITION',
@@ -207,8 +214,8 @@ export class QueryBuilderPostFilterTreeGroupNodeData
207
214
  super(parentId);
208
215
  makeObservable(this, {
209
216
  groupOperation: observable,
210
- childrenIds: observable,
211
217
  setGroupOperation: action,
218
+ childrenIds: observable,
212
219
  addChildNode: action,
213
220
  removeChildNode: action,
214
221
  dragPreviewLabel: computed,
@@ -307,10 +314,130 @@ export class QueryBuilderPostFilterTreeBlankConditionNodeData
307
314
  }
308
315
  }
309
316
 
317
+ export abstract class PostFilterConditionValueState implements Hashable {
318
+ conditionState: PostFilterConditionState;
319
+
320
+ constructor(conditionState: PostFilterConditionState) {
321
+ this.conditionState = conditionState;
322
+ }
323
+
324
+ get type(): Type | undefined {
325
+ return undefined;
326
+ }
327
+
328
+ get isCollection(): boolean {
329
+ return false;
330
+ }
331
+
332
+ get hashCode(): string {
333
+ return hashArray([
334
+ QUERY_BUILDER_STATE_HASH_STRUCTURE.POST_FILTER_CONDITION_RIGHT_VALUE,
335
+ ]);
336
+ }
337
+
338
+ abstract appendConditionValue(expressionVal: SimpleFunctionExpression): void;
339
+ }
340
+
341
+ export class PostFilterValueSpecConditionValueState extends PostFilterConditionValueState {
342
+ value?: ValueSpecification | undefined;
343
+
344
+ constructor(
345
+ conditionState: PostFilterConditionState,
346
+ value?: ValueSpecification | undefined,
347
+ ) {
348
+ super(conditionState);
349
+ makeObservable(this, {
350
+ value: observable,
351
+ setValue: action,
352
+ });
353
+ this.value = this.setValue(value);
354
+ }
355
+
356
+ override get type(): Type | undefined {
357
+ if (this.value instanceof CollectionInstanceValue) {
358
+ return getCollectionValueSpecificationType(
359
+ this.conditionState.postFilterState.tdsState.queryBuilderState
360
+ .graphManagerState.graph,
361
+ this.value.values,
362
+ );
363
+ }
364
+ return this.value
365
+ ? getNonCollectionValueSpecificationType(this.value)
366
+ : undefined;
367
+ }
368
+
369
+ setValue(
370
+ val: ValueSpecification | undefined,
371
+ ): ValueSpecification | undefined {
372
+ this.value = val
373
+ ? observe_ValueSpecification(
374
+ val,
375
+ this.conditionState.postFilterState.tdsState.queryBuilderState
376
+ .observerContext,
377
+ )
378
+ : undefined;
379
+ return this.value;
380
+ }
381
+ override appendConditionValue(expressionVal: SimpleFunctionExpression): void {
382
+ if (this.value) {
383
+ expressionVal.parametersValues.push(this.value);
384
+ }
385
+ }
386
+
387
+ override get isCollection(): boolean {
388
+ return this.value instanceof CollectionInstanceValue;
389
+ }
390
+
391
+ override get hashCode(): string {
392
+ return hashArray([
393
+ QUERY_BUILDER_STATE_HASH_STRUCTURE.POST_FILTER_CONDITION_RIGHT_VALUE_SPEC,
394
+ this.value,
395
+ ]);
396
+ }
397
+ }
398
+
399
+ export class PostFilterTDSColumnValueConditionValueState extends PostFilterConditionValueState {
400
+ tdsColumn: QueryBuilderTDSColumnState;
401
+
402
+ constructor(
403
+ conditionState: PostFilterConditionState,
404
+ tdsColumn: QueryBuilderTDSColumnState,
405
+ ) {
406
+ super(conditionState);
407
+ makeObservable(this, {
408
+ tdsColumn: observable,
409
+ changeCol: action,
410
+ });
411
+ this.tdsColumn = tdsColumn;
412
+ }
413
+
414
+ override get type(): Type | undefined {
415
+ return this.tdsColumn.getColumnType();
416
+ }
417
+
418
+ override get isCollection(): boolean {
419
+ return false;
420
+ }
421
+ override appendConditionValue(expressionVal: SimpleFunctionExpression): void {
422
+ const tdsPropertyExpression = buildtdsPropertyExpressionFromColState(
423
+ this.conditionState,
424
+ this.tdsColumn,
425
+ this.conditionState.postFilterState.tdsState.queryBuilderState
426
+ .graphManagerState.graph,
427
+ undefined,
428
+ );
429
+ expressionVal.parametersValues.push(tdsPropertyExpression);
430
+ }
431
+
432
+ changeCol(col: QueryBuilderTDSColumnState): void {
433
+ this.tdsColumn = col;
434
+ }
435
+ }
436
+
310
437
  export class PostFilterConditionState implements Hashable {
311
438
  readonly postFilterState: QueryBuilderPostFilterState;
312
- columnState: QueryBuilderTDSColumnState;
313
- value?: ValueSpecification | undefined;
439
+ leftConditionValue: QueryBuilderTDSColumnState;
440
+ rightConditionValue: PostFilterConditionValueState;
314
441
  operator: QueryBuilderPostFilterOperator;
315
442
  typeaheadSearchResults: string[] | undefined;
316
443
  typeaheadSearchState = ActionState.create();
@@ -318,18 +445,18 @@ export class PostFilterConditionState implements Hashable {
318
445
  constructor(
319
446
  postFilterState: QueryBuilderPostFilterState,
320
447
  colState: QueryBuilderTDSColumnState,
321
- value: ValueSpecification | undefined,
322
448
  operator: QueryBuilderPostFilterOperator | undefined,
323
449
  ) {
324
450
  makeObservable(this, {
325
451
  postFilterState: observable,
326
- value: observable,
452
+ rightConditionValue: observable,
327
453
  operator: observable,
328
- columnState: observable,
454
+ leftConditionValue: observable,
329
455
  typeaheadSearchResults: observable,
330
456
  changeOperator: action,
331
457
  setColumnState: action,
332
- setValue: action,
458
+ setRightConditionVal: action,
459
+ buildFromValueSpec: action,
333
460
  setOperator: action,
334
461
  changeColumn: flow,
335
462
  handleTypeaheadSearch: flow,
@@ -338,21 +465,24 @@ export class PostFilterConditionState implements Hashable {
338
465
  });
339
466
 
340
467
  this.postFilterState = postFilterState;
341
- this.columnState = colState;
342
- this.setValue(value);
468
+ this.leftConditionValue = colState;
469
+ this.rightConditionValue = new PostFilterValueSpecConditionValueState(
470
+ this,
471
+ undefined,
472
+ );
343
473
  if (operator) {
344
474
  this.operator = operator;
345
475
  } else {
346
476
  assertTrue(
347
477
  this.operators.length !== 0,
348
- `Can't find an operator for column '${this.columnState.columnName}`,
478
+ `Can't find an operator for column '${this.leftConditionValue.columnName}`,
349
479
  );
350
480
  this.operator = guaranteeNonNullable(this.operators[0]);
351
481
  }
352
482
  }
353
483
 
354
484
  get columnName(): string {
355
- return this.columnState.columnName;
485
+ return this.leftConditionValue.columnName;
356
486
  }
357
487
 
358
488
  get operators(): QueryBuilderPostFilterOperator[] {
@@ -361,23 +491,43 @@ export class PostFilterConditionState implements Hashable {
361
491
  );
362
492
  }
363
493
 
494
+ setRightConditionVal(val: PostFilterConditionValueState): void {
495
+ this.rightConditionValue = val;
496
+ }
497
+
498
+ buildFromValueSpec(val: ValueSpecification | undefined): void {
499
+ if (
500
+ this.rightConditionValue instanceof PostFilterValueSpecConditionValueState
501
+ ) {
502
+ this.rightConditionValue.setValue(val);
503
+ return;
504
+ } else {
505
+ this.setRightConditionVal(
506
+ new PostFilterValueSpecConditionValueState(this, val),
507
+ );
508
+ }
509
+ }
364
510
  *handleTypeaheadSearch(): GeneratorFn<void> {
365
511
  try {
366
512
  this.typeaheadSearchState.inProgress();
367
513
  this.typeaheadSearchResults = undefined;
368
514
  const _columnState =
369
- this.columnState instanceof QueryBuilderProjectionColumnState ||
370
- this.columnState instanceof QueryBuilderAggregateColumnState
371
- ? this.columnState
515
+ this.leftConditionValue instanceof QueryBuilderProjectionColumnState ||
516
+ this.leftConditionValue instanceof QueryBuilderAggregateColumnState
517
+ ? this.leftConditionValue
372
518
  : undefined;
373
519
  const columnState = guaranteeNonNullable(_columnState);
374
- if (performTypeahead(this.value)) {
520
+ const rightConditionValue = guaranteeType(
521
+ this.rightConditionValue,
522
+ PostFilterValueSpecConditionValueState,
523
+ );
524
+ if (performTypeahead(rightConditionValue.value)) {
375
525
  const result =
376
526
  (yield this.postFilterState.tdsState.queryBuilderState.graphManagerState.graphManager.runQuery(
377
527
  buildProjectionColumnTypeaheadQuery(
378
528
  this.postFilterState.tdsState.queryBuilderState,
379
529
  columnState,
380
- this.value,
530
+ rightConditionValue.value,
381
531
  ),
382
532
  guaranteeNonNullable(
383
533
  this.postFilterState.tdsState.queryBuilderState
@@ -404,23 +554,15 @@ export class PostFilterConditionState implements Hashable {
404
554
  changeOperator(val: QueryBuilderPostFilterOperator): void {
405
555
  this.setOperator(val);
406
556
  if (!this.operator.isCompatibleWithConditionValue(this)) {
407
- this.setValue(this.operator.getDefaultFilterConditionValue(this));
557
+ this.buildFromValueSpec(
558
+ this.operator.getDefaultFilterConditionValue(this),
559
+ );
408
560
  }
409
561
  }
410
-
411
- setValue(val: ValueSpecification | undefined): void {
412
- this.value = val
413
- ? observe_ValueSpecification(
414
- val,
415
- this.postFilterState.tdsState.queryBuilderState.observerContext,
416
- )
417
- : undefined;
418
- }
419
-
420
562
  setColumnState(
421
563
  val: QueryBuilderProjectionColumnState | QueryBuilderAggregateColumnState,
422
564
  ): void {
423
- this.columnState = val;
565
+ this.leftConditionValue = val;
424
566
  }
425
567
 
426
568
  setOperator(val: QueryBuilderPostFilterOperator): void {
@@ -450,7 +592,9 @@ export class PostFilterConditionState implements Hashable {
450
592
 
451
593
  // value
452
594
  if (!this.operator.isCompatibleWithConditionValue(this)) {
453
- this.setValue(this.operator.getDefaultFilterConditionValue(this));
595
+ this.buildFromValueSpec(
596
+ this.operator.getDefaultFilterConditionValue(this),
597
+ );
454
598
  }
455
599
  } catch (error) {
456
600
  assertErrorThrown(error);
@@ -463,8 +607,8 @@ export class PostFilterConditionState implements Hashable {
463
607
  get hashCode(): string {
464
608
  return hashArray([
465
609
  QUERY_BUILDER_STATE_HASH_STRUCTURE.POST_FILTER_CONDITION_STATE,
466
- this.columnState,
467
- this.value ?? '',
610
+ this.leftConditionValue,
611
+ this.rightConditionValue,
468
612
  this.operator,
469
613
  ]);
470
614
  }
@@ -555,7 +699,7 @@ export class QueryBuilderPostFilterState
555
699
  return uniq(
556
700
  Array.from(this.nodes.values())
557
701
  .filter(filterByType(QueryBuilderPostFilterTreeConditionNodeData))
558
- .map((n) => n.condition.columnState),
702
+ .map((n) => n.condition.leftConditionValue),
559
703
  );
560
704
  }
561
705
 
@@ -883,7 +1027,9 @@ export class QueryBuilderPostFilterState
883
1027
  return Boolean(
884
1028
  Array.from(this.nodes.values())
885
1029
  .filter(filterByType(QueryBuilderPostFilterTreeConditionNodeData))
886
- .map((node) => node.condition.value)
1030
+ .map((node) => node.condition.rightConditionValue)
1031
+ .filter(filterByType(PostFilterValueSpecConditionValueState))
1032
+ .map((condition) => condition.value)
887
1033
  .filter(isNonNullable)
888
1034
  .find((value) => isValueExpressionReferencedInValue(variable, value)),
889
1035
  );
@@ -23,6 +23,7 @@ import {
23
23
  VariableExpression,
24
24
  FunctionExpression,
25
25
  type SimpleFunctionExpression,
26
+ type ValueSpecification,
26
27
  } from '@finos/legend-graph';
27
28
  import {
28
29
  assertTrue,
@@ -30,6 +31,7 @@ import {
30
31
  guaranteeIsString,
31
32
  guaranteeNonNullable,
32
33
  guaranteeType,
34
+ returnUndefOnError,
33
35
  UnsupportedOperationError,
34
36
  } from '@finos/legend-shared';
35
37
  import { QueryBuilderDerivationProjectionColumnState } from '../projection/QueryBuilderProjectionColumnState.js';
@@ -44,6 +46,8 @@ import {
44
46
  QueryBuilderPostFilterTreeGroupNodeData,
45
47
  TDS_COLUMN_GETTER,
46
48
  getTypeFromDerivedProperty,
49
+ PostFilterValueSpecConditionValueState,
50
+ PostFilterTDSColumnValueConditionValueState,
47
51
  } from './QueryBuilderPostFilterState.js';
48
52
  import { QUERY_BUILDER_SUPPORTED_FUNCTIONS } from '../../../../graph/QueryBuilderMetaModelConst.js';
49
53
  import type { QueryBuilderState } from '../../../QueryBuilderState.js';
@@ -102,6 +106,36 @@ const findProjectionColumnState = (
102
106
  return columnState;
103
107
  };
104
108
 
109
+ const buildPostFilterConditionValueState = (
110
+ rightVal: ValueSpecification | undefined,
111
+ conditionState: PostFilterConditionState,
112
+ ): void => {
113
+ if (rightVal instanceof AbstractPropertyExpression) {
114
+ const rightCol = returnUndefOnError(() =>
115
+ findProjectionColumnState(rightVal, conditionState.postFilterState),
116
+ );
117
+ if (rightCol) {
118
+ conditionState.setRightConditionVal(
119
+ new PostFilterTDSColumnValueConditionValueState(
120
+ conditionState,
121
+ rightCol,
122
+ ),
123
+ );
124
+ return;
125
+ }
126
+ }
127
+ const val = rightVal
128
+ ? simplifyValueExpression(
129
+ rightVal,
130
+ conditionState.postFilterState.tdsState.queryBuilderState
131
+ .observerContext,
132
+ )
133
+ : undefined;
134
+ conditionState.setRightConditionVal(
135
+ new PostFilterValueSpecConditionValueState(conditionState, val),
136
+ );
137
+ };
138
+
105
139
  export const buildPostFilterConditionState = (
106
140
  postFilterState: QueryBuilderPostFilterState,
107
141
  expression: FunctionExpression,
@@ -119,7 +153,6 @@ export const buildPostFilterConditionState = (
119
153
  postConditionState = new PostFilterConditionState(
120
154
  postFilterState,
121
155
  columnState,
122
- undefined,
123
156
  operator,
124
157
  );
125
158
  return postConditionState;
@@ -150,21 +183,17 @@ export const buildPostFilterConditionState = (
150
183
  );
151
184
 
152
185
  // get operation value specification
153
- const value = expression.parametersValues[1];
186
+ const rightSide = expression.parametersValues[1];
154
187
 
155
188
  // create state
156
189
  postConditionState = new PostFilterConditionState(
157
190
  postFilterState,
158
191
  columnState,
159
- value
160
- ? simplifyValueExpression(
161
- value,
162
- postFilterState.tdsState.queryBuilderState.observerContext,
163
- )
164
- : undefined,
165
192
  operator,
166
193
  );
167
194
 
195
+ buildPostFilterConditionValueState(rightSide, postConditionState);
196
+
168
197
  //post checks
169
198
  assertTrue(
170
199
  operator.isCompatibleWithPostFilterColumn(postConditionState),
@@ -174,7 +203,7 @@ export const buildPostFilterConditionState = (
174
203
  );
175
204
  assertTrue(
176
205
  operator.isCompatibleWithConditionValue(postConditionState),
177
- `Operator '${operator.getLabel()}' not compatible with value specification ${value?.toString()}`,
206
+ `Operator '${operator.getLabel()}' not compatible with value specification ${rightSide?.toString()}`,
178
207
  );
179
208
  }
180
209
  return postConditionState;