@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.
- package/lib/components/QueryBuilderResultPanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderResultPanel.js +208 -67
- package/lib/components/QueryBuilderResultPanel.js.map +1 -1
- package/lib/index.css +2 -2
- package/lib/index.css.map +1 -1
- package/lib/package.json +4 -4
- package/lib/stores/QueryBuilderResultState.d.ts +19 -0
- package/lib/stores/QueryBuilderResultState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderResultState.js +48 -1
- package/lib/stores/QueryBuilderResultState.js.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js.map +1 -1
- package/lib/stores/shared/LambdaParameterState.d.ts.map +1 -1
- package/lib/stores/shared/LambdaParameterState.js +1 -1
- package/lib/stores/shared/LambdaParameterState.js.map +1 -1
- package/lib/stores/shared/ValueSpecificationEditorHelper.d.ts +5 -2
- package/lib/stores/shared/ValueSpecificationEditorHelper.d.ts.map +1 -1
- package/lib/stores/shared/ValueSpecificationEditorHelper.js +30 -40
- package/lib/stores/shared/ValueSpecificationEditorHelper.js.map +1 -1
- package/package.json +12 -12
- package/src/components/QueryBuilderResultPanel.tsx +357 -91
- package/src/stores/QueryBuilderResultState.ts +82 -0
- package/src/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.ts +1 -0
- package/src/stores/shared/LambdaParameterState.ts +1 -0
- 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;
|
@@ -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 {
|
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 {
|
52
|
-
|
53
|
-
|
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
|
-
|
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
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
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
|
-
|
88
|
-
|
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
|
-
|
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
|
+
};
|