@finos/legend-query-builder 4.5.1 → 4.7.0

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 (57) 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 +1 -0
  4. package/lib/__lib__/QueryBuilderTesting.js.map +1 -1
  5. package/lib/components/QueryBuilderConstantExpressionPanel.d.ts.map +1 -1
  6. package/lib/components/QueryBuilderConstantExpressionPanel.js +46 -9
  7. package/lib/components/QueryBuilderConstantExpressionPanel.js.map +1 -1
  8. package/lib/components/QueryBuilderParametersPanel.d.ts.map +1 -1
  9. package/lib/components/QueryBuilderParametersPanel.js.map +1 -1
  10. package/lib/components/QueryBuilderResultPanel.d.ts.map +1 -1
  11. package/lib/components/QueryBuilderResultPanel.js +1 -1
  12. package/lib/components/QueryBuilderResultPanel.js.map +1 -1
  13. package/lib/components/shared/BasicValueSpecificationEditor.d.ts.map +1 -1
  14. package/lib/components/shared/BasicValueSpecificationEditor.js +2 -2
  15. package/lib/components/shared/BasicValueSpecificationEditor.js.map +1 -1
  16. package/lib/components/shared/CustomDatePicker.d.ts.map +1 -1
  17. package/lib/components/shared/CustomDatePicker.js +6 -2
  18. package/lib/components/shared/CustomDatePicker.js.map +1 -1
  19. package/lib/components/shared/LambdaEditor.d.ts +11 -0
  20. package/lib/components/shared/LambdaEditor.d.ts.map +1 -1
  21. package/lib/components/shared/LambdaEditor.js +3 -3
  22. package/lib/components/shared/LambdaEditor.js.map +1 -1
  23. package/lib/components/shared/QueryBuilderVariableSelector.d.ts +9 -2
  24. package/lib/components/shared/QueryBuilderVariableSelector.d.ts.map +1 -1
  25. package/lib/components/shared/QueryBuilderVariableSelector.js +38 -19
  26. package/lib/components/shared/QueryBuilderVariableSelector.js.map +1 -1
  27. package/lib/index.css +1 -17
  28. package/lib/index.css.map +1 -1
  29. package/lib/package.json +1 -1
  30. package/lib/stores/QueryBuilderConfig.d.ts +2 -1
  31. package/lib/stores/QueryBuilderConfig.d.ts.map +1 -1
  32. package/lib/stores/QueryBuilderConfig.js +1 -0
  33. package/lib/stores/QueryBuilderConfig.js.map +1 -1
  34. package/lib/stores/QueryBuilderConstantsState.d.ts +26 -2
  35. package/lib/stores/QueryBuilderConstantsState.d.ts.map +1 -1
  36. package/lib/stores/QueryBuilderConstantsState.js +107 -5
  37. package/lib/stores/QueryBuilderConstantsState.js.map +1 -1
  38. package/lib/stores/QueryBuilderStateBuilder.d.ts +1 -1
  39. package/lib/stores/QueryBuilderStateBuilder.d.ts.map +1 -1
  40. package/lib/stores/QueryBuilderStateBuilder.js +9 -4
  41. package/lib/stores/QueryBuilderStateBuilder.js.map +1 -1
  42. package/lib/stores/QueryBuilderValueSpecificationBuilder.d.ts.map +1 -1
  43. package/lib/stores/QueryBuilderValueSpecificationBuilder.js +14 -3
  44. package/lib/stores/QueryBuilderValueSpecificationBuilder.js.map +1 -1
  45. package/package.json +5 -5
  46. package/src/__lib__/QueryBuilderTesting.ts +1 -0
  47. package/src/components/QueryBuilderConstantExpressionPanel.tsx +95 -13
  48. package/src/components/QueryBuilderParametersPanel.tsx +0 -1
  49. package/src/components/QueryBuilderResultPanel.tsx +4 -1
  50. package/src/components/shared/BasicValueSpecificationEditor.tsx +4 -7
  51. package/src/components/shared/CustomDatePicker.tsx +6 -7
  52. package/src/components/shared/LambdaEditor.tsx +4 -2
  53. package/src/components/shared/QueryBuilderVariableSelector.tsx +192 -83
  54. package/src/stores/QueryBuilderConfig.ts +1 -0
  55. package/src/stores/QueryBuilderConstantsState.ts +175 -5
  56. package/src/stores/QueryBuilderStateBuilder.ts +20 -8
  57. package/src/stores/QueryBuilderValueSpecificationBuilder.ts +31 -3
@@ -21,6 +21,9 @@ import {
21
21
  GenericTypeExplicitReference,
22
22
  observe_ValueSpecification,
23
23
  VariableExpression,
24
+ buildSourceInformationSourceId,
25
+ ParserError,
26
+ GRAPH_MANAGER_EVENT,
24
27
  } from '@finos/legend-graph';
25
28
  import {
26
29
  type Hashable,
@@ -30,17 +33,48 @@ import {
30
33
  IllegalStateError,
31
34
  uuid,
32
35
  assertErrorThrown,
36
+ type GeneratorFn,
37
+ type PlainObject,
38
+ LogEvent,
39
+ changeEntry,
40
+ assertTrue,
33
41
  } from '@finos/legend-shared';
34
42
  import { action, makeObservable, observable } from 'mobx';
35
43
  import { QUERY_BUILDER_STATE_HASH_STRUCTURE } from './QueryBuilderStateHashUtils.js';
36
44
  import type { QueryBuilderState } from './QueryBuilderState.js';
37
- import { buildDefaultInstanceValue } from './shared/ValueSpecificationEditorHelper.js';
45
+ import {
46
+ buildDefaultEmptyStringRawLambda,
47
+ buildDefaultInstanceValue,
48
+ } from './shared/ValueSpecificationEditorHelper.js';
38
49
  import { valueSpecification_setGenericType } from './shared/ValueSpecificationModifierHelper.js';
50
+ import { LambdaEditorState } from './shared/LambdaEditorState.js';
51
+ import { QUERY_BUILDER_SOURCE_ID_LABEL } from './QueryBuilderConfig.js';
39
52
 
40
- export class QueryBuilderConstantExpressionState implements Hashable {
53
+ export abstract class QueryBuilderConstantExpressionState implements Hashable {
41
54
  readonly queryBuilderState: QueryBuilderState;
42
55
  readonly uuid = uuid();
43
56
  variable: VariableExpression;
57
+
58
+ constructor(
59
+ queryBuilderState: QueryBuilderState,
60
+ variable: VariableExpression,
61
+ ) {
62
+ this.queryBuilderState = queryBuilderState;
63
+ this.variable = variable;
64
+ }
65
+
66
+ get hashCode(): string {
67
+ return hashArray([
68
+ QUERY_BUILDER_STATE_HASH_STRUCTURE.CONSTANT_EXPRESSION_STATE,
69
+ this.variable.name,
70
+ ]);
71
+ }
72
+ }
73
+
74
+ export class QueryBuilderSimpleConstantExpressionState
75
+ extends QueryBuilderConstantExpressionState
76
+ implements Hashable
77
+ {
44
78
  value: ValueSpecification;
45
79
 
46
80
  constructor(
@@ -48,13 +82,13 @@ export class QueryBuilderConstantExpressionState implements Hashable {
48
82
  variable: VariableExpression,
49
83
  value: ValueSpecification,
50
84
  ) {
85
+ super(queryBuilderState, variable);
51
86
  makeObservable(this, {
52
87
  variable: observable,
53
88
  value: observable,
54
89
  setValueSpec: action,
55
90
  changeValSpecType: action,
56
91
  });
57
- this.queryBuilderState = queryBuilderState;
58
92
  this.value = observe_ValueSpecification(
59
93
  value,
60
94
  this.queryBuilderState.observerContext,
@@ -63,7 +97,6 @@ export class QueryBuilderConstantExpressionState implements Hashable {
63
97
  variable,
64
98
  this.queryBuilderState.observerContext,
65
99
  );
66
- this.variable = variable;
67
100
  }
68
101
 
69
102
  changeValSpecType(type: Type): void {
@@ -107,7 +140,7 @@ export class QueryBuilderConstantExpressionState implements Hashable {
107
140
  }
108
141
  }
109
142
 
110
- get hashCode(): string {
143
+ override get hashCode(): string {
111
144
  return hashArray([
112
145
  QUERY_BUILDER_STATE_HASH_STRUCTURE.CONSTANT_EXPRESSION_STATE,
113
146
  this.variable.name,
@@ -116,6 +149,119 @@ export class QueryBuilderConstantExpressionState implements Hashable {
116
149
  }
117
150
  }
118
151
 
152
+ export class QueryBuilderConstantLambdaEditorState extends LambdaEditorState {
153
+ readonly queryBuilderState: QueryBuilderState;
154
+ calculatedState: QueryBuilderCalculatedConstantExpressionState;
155
+ constructor(calculatedState: QueryBuilderCalculatedConstantExpressionState) {
156
+ super('', '');
157
+ makeObservable(this, {
158
+ calculatedState: observable,
159
+ buildEmptyValueSpec: observable,
160
+ });
161
+ this.calculatedState = calculatedState;
162
+ this.queryBuilderState = calculatedState.queryBuilderState;
163
+ }
164
+
165
+ buildEmptyValueSpec(): PlainObject {
166
+ return this.queryBuilderState.graphManagerState.graphManager.serializeRawValueSpecification(
167
+ buildDefaultEmptyStringRawLambda(
168
+ this.queryBuilderState.graphManagerState,
169
+ this.queryBuilderState.observerContext,
170
+ ),
171
+ );
172
+ }
173
+
174
+ get lambdaId(): string {
175
+ return buildSourceInformationSourceId([
176
+ // TODO: to be reworked
177
+ // See https://github.com/finos/legend-studio/issues/1168
178
+ QUERY_BUILDER_SOURCE_ID_LABEL.QUERY_BUILDER,
179
+ QUERY_BUILDER_SOURCE_ID_LABEL.CONSTANT,
180
+ this.calculatedState.uuid,
181
+ ]);
182
+ }
183
+
184
+ override *convertLambdaGrammarStringToObject(): GeneratorFn<void> {
185
+ if (this.lambdaString) {
186
+ try {
187
+ const valSpec =
188
+ (yield this.queryBuilderState.graphManagerState.graphManager.pureCodeToValueSpecification(
189
+ this.fullLambdaString,
190
+ )) as PlainObject<ValueSpecification>;
191
+ this.setParserError(undefined);
192
+ this.calculatedState.setValue(valSpec);
193
+ } catch (error) {
194
+ assertErrorThrown(error);
195
+ if (error instanceof ParserError) {
196
+ this.setParserError(error);
197
+ }
198
+ this.queryBuilderState.applicationStore.logService.error(
199
+ LogEvent.create(GRAPH_MANAGER_EVENT.PARSING_FAILURE),
200
+ error,
201
+ );
202
+ }
203
+ } else {
204
+ this.clearErrors();
205
+ this.calculatedState.setValue(this.buildEmptyValueSpec());
206
+ }
207
+ }
208
+ override *convertLambdaObjectToGrammarString(
209
+ options?:
210
+ | {
211
+ pretty?: boolean | undefined;
212
+ preserveCompilationError?: boolean | undefined;
213
+ }
214
+ | undefined,
215
+ ): GeneratorFn<void> {
216
+ try {
217
+ const value = this.calculatedState.value;
218
+ const grammarText =
219
+ (yield this.queryBuilderState.graphManagerState.graphManager.valueSpecificationToPureCode(
220
+ value,
221
+ options?.pretty,
222
+ )) as string;
223
+ this.setLambdaString(grammarText);
224
+ this.clearErrors({
225
+ preserveCompilationError: options?.preserveCompilationError,
226
+ });
227
+ } catch (error) {
228
+ assertErrorThrown(error);
229
+ this.queryBuilderState.applicationStore.logService.error(
230
+ LogEvent.create(GRAPH_MANAGER_EVENT.PARSING_FAILURE),
231
+ error,
232
+ );
233
+ }
234
+ }
235
+ }
236
+
237
+ export class QueryBuilderCalculatedConstantExpressionState
238
+ extends QueryBuilderConstantExpressionState
239
+ implements Hashable
240
+ {
241
+ value: PlainObject;
242
+ lambdaState: QueryBuilderConstantLambdaEditorState;
243
+
244
+ constructor(
245
+ queryBuilderState: QueryBuilderState,
246
+ variable: VariableExpression,
247
+ value: PlainObject,
248
+ ) {
249
+ super(queryBuilderState, variable);
250
+ makeObservable(this, {
251
+ variable: observable,
252
+ lambdaState: observable,
253
+ value: observable,
254
+ setValue: action,
255
+ });
256
+ this.value = value;
257
+ this.lambdaState = new QueryBuilderConstantLambdaEditorState(this);
258
+ }
259
+
260
+ setValue(val: PlainObject): void {
261
+ this.value = val;
262
+ }
263
+ }
264
+
119
265
  export class QueryBuilderConstantsState implements Hashable {
120
266
  readonly queryBuilderState: QueryBuilderState;
121
267
  showConstantPanel = false;
@@ -133,6 +279,7 @@ export class QueryBuilderConstantsState implements Hashable {
133
279
  removeConstant: action,
134
280
  setShowConstantPanel: action,
135
281
  setSelectedConstant: action,
282
+ convertToCalculated: action,
136
283
  });
137
284
  }
138
285
 
@@ -167,6 +314,29 @@ export class QueryBuilderConstantsState implements Hashable {
167
314
  return false;
168
315
  }
169
316
 
317
+ convertToCalculated(val: QueryBuilderSimpleConstantExpressionState): void {
318
+ try {
319
+ const content =
320
+ this.queryBuilderState.graphManagerState.graphManager.serializeValueSpecification(
321
+ val.value,
322
+ );
323
+ const constantState = new QueryBuilderCalculatedConstantExpressionState(
324
+ this.queryBuilderState,
325
+ val.variable,
326
+ content,
327
+ );
328
+ assertTrue(
329
+ changeEntry(this.constants, val, constantState),
330
+ 'Unable to convert to calculated constant',
331
+ );
332
+ } catch (error) {
333
+ assertErrorThrown(error);
334
+ this.queryBuilderState.applicationStore.notificationService.notifyError(
335
+ error,
336
+ );
337
+ }
338
+ }
339
+
170
340
  get hashCode(): string {
171
341
  return hashArray([
172
342
  QUERY_BUILDER_STATE_HASH_STRUCTURE.CONSTANT_STATE,
@@ -31,7 +31,7 @@ import {
31
31
  type GraphFetchTreeInstanceValue,
32
32
  type ValueSpecificationVisitor,
33
33
  InstanceValue,
34
- type INTERNAL__UnknownValueSpecification,
34
+ INTERNAL__UnknownValueSpecification,
35
35
  type LambdaFunction,
36
36
  type KeyExpressionInstanceValue,
37
37
  matchFunctionName,
@@ -81,7 +81,11 @@ import {
81
81
  import { LambdaParameterState } from './shared/LambdaParameterState.js';
82
82
  import { processTDS_OLAPGroupByExpression } from './fetch-structure/tds/window/QueryBuilderWindowStateBuilder.js';
83
83
  import { processWatermarkExpression } from './watermark/QueryBuilderWatermarkStateBuilder.js';
84
- import { QueryBuilderConstantExpressionState } from './QueryBuilderConstantsState.js';
84
+ import {
85
+ type QueryBuilderConstantExpressionState,
86
+ QueryBuilderCalculatedConstantExpressionState,
87
+ QueryBuilderSimpleConstantExpressionState,
88
+ } from './QueryBuilderConstantsState.js';
85
89
  import { checkIfEquivalent } from './milestoning/QueryBuilderMilestoningHelper.js';
86
90
  import type { QueryBuilderParameterValue } from './QueryBuilderParametersState.js';
87
91
  import { QueryBuilderEmbeddedFromExecutionContextState } from './QueryBuilderExecutionContextState.js';
@@ -143,12 +147,20 @@ const processLetExpression = (
143
147
  );
144
148
  // process right side (value)
145
149
  const rightSide = guaranteeNonNullable(parameters[1]);
146
- // final
147
- const constantExpression = new QueryBuilderConstantExpressionState(
148
- queryBuilderState,
149
- varExp,
150
- rightSide,
151
- );
150
+ let constantExpression: QueryBuilderConstantExpressionState;
151
+ if (rightSide instanceof INTERNAL__UnknownValueSpecification) {
152
+ constantExpression = new QueryBuilderCalculatedConstantExpressionState(
153
+ queryBuilderState,
154
+ varExp,
155
+ rightSide.content,
156
+ );
157
+ } else {
158
+ constantExpression = new QueryBuilderSimpleConstantExpressionState(
159
+ queryBuilderState,
160
+ varExp,
161
+ rightSide,
162
+ );
163
+ }
152
164
  queryBuilderState.constantState.setShowConstantPanel(true);
153
165
  queryBuilderState.constantState.addConstant(constantExpression);
154
166
  };
@@ -14,9 +14,14 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import { guaranteeNonNullable, guaranteeType } from '@finos/legend-shared';
17
+ import {
18
+ UnsupportedOperationError,
19
+ guaranteeNonNullable,
20
+ guaranteeType,
21
+ } from '@finos/legend-shared';
18
22
  import {
19
23
  type Class,
24
+ type ValueSpecification,
20
25
  Multiplicity,
21
26
  getMilestoneTemporalStereotype,
22
27
  extractElementNameFromPath,
@@ -32,6 +37,7 @@ import {
32
37
  PrimitiveType,
33
38
  SUPPORTED_FUNCTIONS,
34
39
  RuntimePointer,
40
+ INTERNAL__UnknownValueSpecification,
35
41
  } from '@finos/legend-graph';
36
42
  import type { QueryBuilderState } from './QueryBuilderState.js';
37
43
  import { buildFilterExpression } from './filter/QueryBuilderFilterValueSpecificationBuilder.js';
@@ -40,7 +46,11 @@ import type { QueryBuilderFetchStructureState } from './fetch-structure/QueryBui
40
46
  import { QUERY_BUILDER_SUPPORTED_FUNCTIONS } from '../graph/QueryBuilderMetaModelConst.js';
41
47
  import { buildWatermarkExpression } from './watermark/QueryBuilderWatermarkValueSpecificationBuilder.js';
42
48
  import { buildExecutionQueryFromLambdaFunction } from './shared/LambdaParameterState.js';
43
- import type { QueryBuilderConstantExpressionState } from './QueryBuilderConstantsState.js';
49
+ import {
50
+ QueryBuilderSimpleConstantExpressionState,
51
+ type QueryBuilderConstantExpressionState,
52
+ QueryBuilderCalculatedConstantExpressionState,
53
+ } from './QueryBuilderConstantsState.js';
44
54
  import {
45
55
  QueryBuilderEmbeddedFromExecutionContextState,
46
56
  type QueryBuilderExecutionContextState,
@@ -84,7 +94,6 @@ const buildLetExpression = (
84
94
  constantExpressionState: QueryBuilderConstantExpressionState,
85
95
  ): SimpleFunctionExpression => {
86
96
  const varName = constantExpressionState.variable.name;
87
- const value = constantExpressionState.value;
88
97
  const leftSide = new PrimitiveInstanceValue(
89
98
  GenericTypeExplicitReference.create(new GenericType(PrimitiveType.STRING)),
90
99
  );
@@ -92,6 +101,25 @@ const buildLetExpression = (
92
101
  const letFunc = new SimpleFunctionExpression(
93
102
  extractElementNameFromPath(SUPPORTED_FUNCTIONS.LET),
94
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
+
95
123
  letFunc.parametersValues = [leftSide, value];
96
124
  return letFunc;
97
125
  };