@finos/legend-query-builder 4.0.9 → 4.0.10

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 (25) hide show
  1. package/lib/components/QueryBuilderResultPanel.d.ts.map +1 -1
  2. package/lib/components/QueryBuilderResultPanel.js +208 -67
  3. package/lib/components/QueryBuilderResultPanel.js.map +1 -1
  4. package/lib/index.css +2 -2
  5. package/lib/index.css.map +1 -1
  6. package/lib/package.json +4 -4
  7. package/lib/stores/QueryBuilderResultState.d.ts +19 -0
  8. package/lib/stores/QueryBuilderResultState.d.ts.map +1 -1
  9. package/lib/stores/QueryBuilderResultState.js +48 -1
  10. package/lib/stores/QueryBuilderResultState.js.map +1 -1
  11. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.d.ts.map +1 -1
  12. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js.map +1 -1
  13. package/lib/stores/shared/LambdaParameterState.d.ts.map +1 -1
  14. package/lib/stores/shared/LambdaParameterState.js +1 -1
  15. package/lib/stores/shared/LambdaParameterState.js.map +1 -1
  16. package/lib/stores/shared/ValueSpecificationEditorHelper.d.ts +5 -2
  17. package/lib/stores/shared/ValueSpecificationEditorHelper.d.ts.map +1 -1
  18. package/lib/stores/shared/ValueSpecificationEditorHelper.js +30 -40
  19. package/lib/stores/shared/ValueSpecificationEditorHelper.js.map +1 -1
  20. package/package.json +12 -12
  21. package/src/components/QueryBuilderResultPanel.tsx +357 -91
  22. package/src/stores/QueryBuilderResultState.ts +82 -0
  23. package/src/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.ts +1 -0
  24. package/src/stores/shared/LambdaParameterState.ts +1 -0
  25. package/src/stores/shared/ValueSpecificationEditorHelper.ts +80 -57
@@ -37,6 +37,7 @@ import {
37
37
  buildRawLambdaFromLambdaFunction,
38
38
  reportGraphAnalytics,
39
39
  extractExecutionResultValues,
40
+ TDSExecutionResult,
40
41
  } from '@finos/legend-graph';
41
42
  import { buildLambdaFunction } from './QueryBuilderValueSpecificationBuilder.js';
42
43
  import { DEFAULT_TAB_SIZE } from '@finos/legend-application';
@@ -56,6 +57,17 @@ export interface ExportDataInfo {
56
57
  serializationFormat?: EXECUTION_SERIALIZATION_FORMAT | undefined;
57
58
  }
58
59
 
60
+ export interface QueryBuilderTDSResultCellData {
61
+ value: string | number | boolean | null | undefined;
62
+ columnName: string;
63
+ coordinates: QueryBuilderTDSResultCellCoordinate;
64
+ }
65
+
66
+ export interface QueryBuilderTDSResultCellCoordinate {
67
+ rowIndex: number;
68
+ colIndex: number;
69
+ }
70
+
59
71
  export class QueryBuilderResultState {
60
72
  readonly queryBuilderState: QueryBuilderState;
61
73
  readonly exportDataState = ActionState.create();
@@ -70,6 +82,10 @@ export class QueryBuilderResultState {
70
82
  latestRunHashCode?: string | undefined;
71
83
  queryRunPromise: Promise<ExecutionResult> | undefined = undefined;
72
84
 
85
+ selectedCells: QueryBuilderTDSResultCellData[];
86
+ mousedOverCell: QueryBuilderTDSResultCellData | null = null;
87
+ isSelectingCells: boolean;
88
+
73
89
  constructor(queryBuilderState: QueryBuilderState) {
74
90
  makeObservable(this, {
75
91
  executionResult: observable,
@@ -78,18 +94,28 @@ export class QueryBuilderResultState {
78
94
  latestRunHashCode: observable,
79
95
  queryRunPromise: observable,
80
96
  isGeneratingPlan: observable,
97
+ selectedCells: observable,
98
+ mousedOverCell: observable,
81
99
  isRunningQuery: observable,
100
+ isSelectingCells: observable,
101
+ setIsSelectingCells: action,
82
102
  setIsRunningQuery: action,
83
103
  setExecutionResult: action,
84
104
  setExecutionDuration: action,
85
105
  setPreviewLimit: action,
106
+ addCellData: action,
107
+ setSelectedCells: action,
108
+ setMouseOverCell: action,
86
109
  setQueryRunPromise: action,
110
+
87
111
  exportData: flow,
88
112
  runQuery: flow,
89
113
  cancelQuery: flow,
90
114
  generatePlan: flow,
91
115
  });
116
+ this.isSelectingCells = false;
92
117
 
118
+ this.selectedCells = [];
93
119
  this.queryBuilderState = queryBuilderState;
94
120
  this.executionPlanState = new ExecutionPlanState(
95
121
  this.queryBuilderState.applicationStore,
@@ -97,6 +123,10 @@ export class QueryBuilderResultState {
97
123
  );
98
124
  }
99
125
 
126
+ setIsSelectingCells = (val: boolean): void => {
127
+ this.isSelectingCells = val;
128
+ };
129
+
100
130
  setIsRunningQuery = (val: boolean): void => {
101
131
  this.isRunningQuery = val;
102
132
  };
@@ -113,12 +143,64 @@ export class QueryBuilderResultState {
113
143
  this.previewLimit = Math.max(1, val);
114
144
  };
115
145
 
146
+ addCellData = (val: QueryBuilderTDSResultCellData): void => {
147
+ this.selectedCells.push(val);
148
+ };
149
+
150
+ setSelectedCells = (val: QueryBuilderTDSResultCellData[]): void => {
151
+ this.selectedCells = val;
152
+ };
153
+
154
+ setMouseOverCell = (val: QueryBuilderTDSResultCellData | null): void => {
155
+ this.mousedOverCell = val;
156
+ };
157
+
116
158
  setQueryRunPromise = (
117
159
  promise: Promise<ExecutionResult> | undefined,
118
160
  ): void => {
119
161
  this.queryRunPromise = promise;
120
162
  };
121
163
 
164
+ findColumnFromCoordinates = (
165
+ colIndex: number,
166
+ ): string | number | boolean | null | undefined => {
167
+ if (
168
+ !this.executionResult ||
169
+ !(this.executionResult instanceof TDSExecutionResult)
170
+ ) {
171
+ return undefined;
172
+ }
173
+ return this.executionResult.result.columns[colIndex];
174
+ };
175
+
176
+ findRowFromRowIndex = (
177
+ rowIndex: number,
178
+ ): (string | number | boolean | null)[] => {
179
+ if (
180
+ !this.executionResult ||
181
+ !(this.executionResult instanceof TDSExecutionResult)
182
+ ) {
183
+ return [''];
184
+ }
185
+ return this.executionResult.result.rows[rowIndex]?.values ?? [''];
186
+ };
187
+
188
+ findResultValueFromCoordinates = (
189
+ resultCoordinate: [number, number],
190
+ ): string | number | boolean | null | undefined => {
191
+ const rowIndex = resultCoordinate[0];
192
+ const colIndex = resultCoordinate[1];
193
+
194
+ if (
195
+ !this.executionResult ||
196
+ !(this.executionResult instanceof TDSExecutionResult)
197
+ ) {
198
+ return undefined;
199
+ }
200
+
201
+ return this.executionResult.result.rows[rowIndex]?.values[colIndex];
202
+ };
203
+
122
204
  get checkForStaleResults(): boolean {
123
205
  if (this.latestRunHashCode !== this.queryBuilderState.hashCode) {
124
206
  return true;
@@ -569,6 +569,7 @@ export class QueryBuilderPostFilterState
569
569
  undefined,
570
570
  QUERY_BUILDER_GROUP_OPERATION.AND,
571
571
  );
572
+
572
573
  groupNode.addChildNode(rootNode);
573
574
  groupNode.addChildNode(node);
574
575
  this.rootIds = [groupNode.id];
@@ -235,6 +235,7 @@ export class LambdaParameterState implements Hashable {
235
235
  this.parameter,
236
236
  this.graph,
237
237
  this.observerContext,
238
+ { useCurrentDateDependentFunctions: true },
238
239
  ),
239
240
  );
240
241
  }
@@ -41,16 +41,22 @@ import {
41
41
  Multiplicity,
42
42
  CORE_PURE_PATH,
43
43
  buildRawLambdaFromLambdaFunction,
44
+ getValueSpecificationReturnType,
44
45
  } from '@finos/legend-graph';
45
- import { Randomizer, UnsupportedOperationError } from '@finos/legend-shared';
46
+ import {
47
+ Randomizer,
48
+ UnsupportedOperationError,
49
+ returnUndefOnError,
50
+ } from '@finos/legend-shared';
46
51
  import { generateDefaultValueForPrimitiveType } from '../QueryBuilderValueSpecificationHelper.js';
47
52
  import {
48
53
  instanceValue_setValues,
49
54
  valueSpecification_setGenericType,
50
55
  } from './ValueSpecificationModifierHelper.js';
51
- import { QUERY_BUILDER_SUPPORTED_FUNCTIONS } from '../../graph/QueryBuilderMetaModelConst.js';
52
-
53
- const VAR_DEFAULT_NAME = 'var';
56
+ import {
57
+ QUERY_BUILDER_PURE_PATH,
58
+ QUERY_BUILDER_SUPPORTED_FUNCTIONS,
59
+ } from '../../graph/QueryBuilderMetaModelConst.js';
54
60
 
55
61
  export const createSupportedFunctionExpression = (
56
62
  supportedFuncName: string,
@@ -63,52 +69,60 @@ export const createSupportedFunctionExpression = (
63
69
  );
64
70
  return funcExpression;
65
71
  };
72
+ export const buildPrimitiveInstanceValue = (
73
+ graph: PureModel,
74
+ type: PRIMITIVE_TYPE,
75
+ value: unknown,
76
+ observerContext: ObserverContext,
77
+ ): PrimitiveInstanceValue => {
78
+ const instance = new PrimitiveInstanceValue(
79
+ GenericTypeExplicitReference.create(
80
+ new GenericType(graph.getPrimitiveType(type)),
81
+ ),
82
+ );
83
+ instanceValue_setValues(instance, [value], observerContext);
84
+ return instance;
85
+ };
66
86
 
67
87
  const createMockPrimitiveValueSpecification = (
68
88
  primitiveType: PrimitiveType,
69
- propertyName: string,
89
+ graph: PureModel,
70
90
  observerContext: ObserverContext,
91
+ options?: {
92
+ useCurrentDateDependentFunctions?: boolean;
93
+ },
71
94
  ): ValueSpecification => {
72
95
  const primitiveTypeName = primitiveType.name;
73
- if (
74
- primitiveTypeName === PRIMITIVE_TYPE.DATE ||
75
- primitiveTypeName === PRIMITIVE_TYPE.DATETIME
76
- ) {
77
- return createSupportedFunctionExpression(
78
- QUERY_BUILDER_SUPPORTED_FUNCTIONS.NOW,
79
- PrimitiveType.DATETIME,
80
- );
81
- } else if (primitiveTypeName === PRIMITIVE_TYPE.STRICTDATE) {
82
- return createSupportedFunctionExpression(
83
- QUERY_BUILDER_SUPPORTED_FUNCTIONS.TODAY,
84
- PrimitiveType.STRICTDATE,
96
+ if (options?.useCurrentDateDependentFunctions) {
97
+ if (
98
+ primitiveTypeName === PRIMITIVE_TYPE.DATE ||
99
+ primitiveTypeName === PRIMITIVE_TYPE.DATETIME
100
+ ) {
101
+ return createSupportedFunctionExpression(
102
+ QUERY_BUILDER_SUPPORTED_FUNCTIONS.NOW,
103
+ PrimitiveType.DATETIME,
104
+ );
105
+ } else if (primitiveTypeName === PRIMITIVE_TYPE.STRICTDATE) {
106
+ return createSupportedFunctionExpression(
107
+ QUERY_BUILDER_SUPPORTED_FUNCTIONS.TODAY,
108
+ PrimitiveType.STRICTDATE,
109
+ );
110
+ }
111
+ }
112
+ if (primitiveTypeName === PRIMITIVE_TYPE.DATE) {
113
+ return buildPrimitiveInstanceValue(
114
+ graph,
115
+ PRIMITIVE_TYPE.STRICTDATE,
116
+ generateDefaultValueForPrimitiveType(primitiveTypeName),
117
+ observerContext,
85
118
  );
86
119
  }
87
- const primitiveInstanceValue = new PrimitiveInstanceValue(
88
- GenericTypeExplicitReference.create(new GenericType(primitiveType)),
120
+ return buildPrimitiveInstanceValue(
121
+ graph,
122
+ primitiveTypeName as PRIMITIVE_TYPE,
123
+ generateDefaultValueForPrimitiveType(primitiveTypeName as PRIMITIVE_TYPE),
124
+ observerContext,
89
125
  );
90
- const randomizer = new Randomizer();
91
- let value: string | boolean | number;
92
- switch (primitiveType.name) {
93
- case PRIMITIVE_TYPE.BOOLEAN:
94
- value = randomizer.getRandomItemInCollection([true, false]) ?? true;
95
- break;
96
- case PRIMITIVE_TYPE.FLOAT:
97
- value = randomizer.getRandomFloat();
98
- break;
99
- case PRIMITIVE_TYPE.DECIMAL:
100
- value = randomizer.getRandomDouble();
101
- break;
102
- case PRIMITIVE_TYPE.NUMBER:
103
- case PRIMITIVE_TYPE.INTEGER:
104
- value = randomizer.getRandomWholeNumber(100);
105
- break;
106
- case PRIMITIVE_TYPE.STRING:
107
- default:
108
- value = `${propertyName} ${randomizer.getRandomWholeNumber(100)}`;
109
- }
110
- instanceValue_setValues(primitiveInstanceValue, [value], observerContext);
111
- return primitiveInstanceValue;
112
126
  };
113
127
 
114
128
  export const createMockEnumerationProperty = (
@@ -116,21 +130,6 @@ export const createMockEnumerationProperty = (
116
130
  ): string =>
117
131
  new Randomizer().getRandomItemInCollection(enumeration.values)?.name ?? '';
118
132
 
119
- export const buildPrimitiveInstanceValue = (
120
- graph: PureModel,
121
- type: PRIMITIVE_TYPE,
122
- value: unknown,
123
- observerContext: ObserverContext,
124
- ): PrimitiveInstanceValue => {
125
- const instance = new PrimitiveInstanceValue(
126
- GenericTypeExplicitReference.create(
127
- new GenericType(graph.getPrimitiveType(type)),
128
- ),
129
- );
130
- instanceValue_setValues(instance, [value], observerContext);
131
- return instance;
132
- };
133
-
134
133
  export const buildDefaultInstanceValue = (
135
134
  graph: PureModel,
136
135
  type: Type,
@@ -219,6 +218,9 @@ export const generateVariableExpressionMockValue = (
219
218
  parameter: VariableExpression,
220
219
  graph: PureModel,
221
220
  observerContext: ObserverContext,
221
+ options?: {
222
+ useCurrentDateDependentFunctions?: boolean;
223
+ },
222
224
  ): ValueSpecification | undefined => {
223
225
  const varType = parameter.genericType?.value.rawType;
224
226
  const multiplicity = parameter.multiplicity;
@@ -231,8 +233,9 @@ export const generateVariableExpressionMockValue = (
231
233
  if (varType instanceof PrimitiveType) {
232
234
  return createMockPrimitiveValueSpecification(
233
235
  varType,
234
- VAR_DEFAULT_NAME,
236
+ graph,
235
237
  observerContext,
238
+ options,
236
239
  );
237
240
  } else if (varType instanceof Enumeration) {
238
241
  const enumValueInstance = new EnumValueInstanceValue(
@@ -272,3 +275,23 @@ export const getValueSpecificationStringValue = (
272
275
  }
273
276
  return undefined;
274
277
  };
278
+
279
+ export const valueSpecReturnTDS = (
280
+ val: ValueSpecification,
281
+ graph: PureModel,
282
+ ): boolean => {
283
+ const retunType = returnUndefOnError(() =>
284
+ getValueSpecificationReturnType(val),
285
+ );
286
+ const tdsType = returnUndefOnError(() =>
287
+ graph.getClass(QUERY_BUILDER_PURE_PATH.TDS_TABULAR_DATASET),
288
+ );
289
+ const tdsRowType = returnUndefOnError(() =>
290
+ graph.getClass(QUERY_BUILDER_PURE_PATH.TDS_ROW),
291
+ );
292
+ // FIXME: we sometimes return tds row when tds is the return type of the lambda. We do this to properly build post filters.
293
+ // We should fix this to properly build filter functions after a tds function
294
+ return Boolean(
295
+ retunType && tdsType && (retunType === tdsType || retunType === tdsRowType),
296
+ );
297
+ };