@finos/legend-query-builder 4.0.9 → 4.0.10

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