@finos/legend-query-builder 4.17.85 → 4.17.87
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.
- package/lib/components/workflows/DataProductQueryBuilder.d.ts.map +1 -1
- package/lib/components/workflows/DataProductQueryBuilder.js +59 -16
- package/lib/components/workflows/DataProductQueryBuilder.js.map +1 -1
- package/lib/data-access-overview.css +1 -1
- package/lib/index.css +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/QueryBuilderState.d.ts +6 -1
- package/lib/stores/QueryBuilderState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderState.js +9 -1
- package/lib/stores/QueryBuilderState.js.map +1 -1
- package/lib/stores/QueryBuilderValueSpecificationBuilder.d.ts +2 -0
- package/lib/stores/QueryBuilderValueSpecificationBuilder.d.ts.map +1 -1
- package/lib/stores/QueryBuilderValueSpecificationBuilder.js +2 -2
- package/lib/stores/QueryBuilderValueSpecificationBuilder.js.map +1 -1
- package/lib/stores/workflows/dataProduct/DataProductQueryBuilderState.d.ts +46 -5
- package/lib/stores/workflows/dataProduct/DataProductQueryBuilderState.d.ts.map +1 -1
- package/lib/stores/workflows/dataProduct/DataProductQueryBuilderState.js +182 -15
- package/lib/stores/workflows/dataProduct/DataProductQueryBuilderState.js.map +1 -1
- package/package.json +7 -7
- package/src/components/workflows/DataProductQueryBuilder.tsx +147 -24
- package/src/index.ts +7 -1
- package/src/stores/QueryBuilderState.ts +19 -1
- package/src/stores/QueryBuilderValueSpecificationBuilder.ts +2 -5
- package/src/stores/workflows/dataProduct/DataProductQueryBuilderState.ts +278 -16
|
@@ -20,12 +20,26 @@ import {
|
|
|
20
20
|
DataProduct,
|
|
21
21
|
type V1_DataProductArtifact,
|
|
22
22
|
ModelAccessPointGroup,
|
|
23
|
-
|
|
23
|
+
NativeModelExecutionContext,
|
|
24
24
|
CORE_PURE_PATH,
|
|
25
25
|
type NativeModelAccess,
|
|
26
|
+
type Mapping,
|
|
27
|
+
type DataProductElementScope,
|
|
28
|
+
PackageableRuntime,
|
|
26
29
|
resolveUsableDataProductClasses,
|
|
30
|
+
LakehouseRuntime,
|
|
31
|
+
type LambdaFunction,
|
|
32
|
+
SimpleFunctionExpression,
|
|
33
|
+
InstanceValue,
|
|
34
|
+
Multiplicity,
|
|
35
|
+
extractElementNameFromPath,
|
|
36
|
+
SUPPORTED_FUNCTIONS,
|
|
37
|
+
PackageableElementExplicitReference,
|
|
38
|
+
resolveDataProductExecutionState,
|
|
39
|
+
RuntimePointer,
|
|
27
40
|
} from '@finos/legend-graph';
|
|
28
41
|
import { QueryBuilderState } from '../../QueryBuilderState.js';
|
|
42
|
+
|
|
29
43
|
import { type GenericLegendApplicationStore } from '@finos/legend-application';
|
|
30
44
|
import type {
|
|
31
45
|
QueryBuilderActionConfig,
|
|
@@ -35,7 +49,9 @@ import type { QueryBuilderConfig } from '../../../graph-manager/QueryBuilderConf
|
|
|
35
49
|
import { renderDataProductQueryBuilderSetupPanelContent } from '../../../components/workflows/DataProductQueryBuilder.js';
|
|
36
50
|
import {
|
|
37
51
|
ActionState,
|
|
52
|
+
assertErrorThrown,
|
|
38
53
|
filterByType,
|
|
54
|
+
guaranteeNonNullable,
|
|
39
55
|
type GeneratorFn,
|
|
40
56
|
} from '@finos/legend-shared';
|
|
41
57
|
import { action, computed, flow, makeObservable, observable } from 'mobx';
|
|
@@ -44,6 +60,7 @@ import {
|
|
|
44
60
|
type QueryableSourceInfo,
|
|
45
61
|
} from '@finos/legend-storage';
|
|
46
62
|
import { compareLabelFn } from '@finos/legend-art';
|
|
63
|
+
import { QueryBuilderEmbeddedFromExecutionContextState } from '../../QueryBuilderExecutionContextState.js';
|
|
47
64
|
|
|
48
65
|
export type DataProductOption = {
|
|
49
66
|
label: string;
|
|
@@ -69,6 +86,113 @@ export const buildExecOptions = (
|
|
|
69
86
|
};
|
|
70
87
|
};
|
|
71
88
|
|
|
89
|
+
export type ModelAccessPointGroupOption = {
|
|
90
|
+
label: string;
|
|
91
|
+
value: ModelAccessPointGroup;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
export const buildModelAccessPointGroupOption = (
|
|
95
|
+
value: ModelAccessPointGroup,
|
|
96
|
+
): ModelAccessPointGroupOption => ({
|
|
97
|
+
label: value.title ?? value.id,
|
|
98
|
+
value,
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
export abstract class DataProductExecutionState<T> {
|
|
102
|
+
readonly queryBuilderState: DataProductQueryBuilderState;
|
|
103
|
+
exectionValue: T;
|
|
104
|
+
|
|
105
|
+
constructor(
|
|
106
|
+
executionState: T,
|
|
107
|
+
queryBuilderState: DataProductQueryBuilderState,
|
|
108
|
+
) {
|
|
109
|
+
this.queryBuilderState = queryBuilderState;
|
|
110
|
+
this.exectionValue = executionState;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
abstract get label(): string;
|
|
114
|
+
|
|
115
|
+
abstract get mapping(): Mapping;
|
|
116
|
+
|
|
117
|
+
abstract get featuredElements(): DataProductElementScope[] | undefined;
|
|
118
|
+
|
|
119
|
+
get selectedOption(): { label: string; value: T } {
|
|
120
|
+
return {
|
|
121
|
+
label: this.label,
|
|
122
|
+
value: this.exectionValue,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export class NativeModelDataProductExecutionState extends DataProductExecutionState<NativeModelExecutionContext> {
|
|
128
|
+
nativeModelAccess: NativeModelAccess;
|
|
129
|
+
|
|
130
|
+
constructor(
|
|
131
|
+
executionState: NativeModelExecutionContext,
|
|
132
|
+
queryBuilderState: DataProductQueryBuilderState,
|
|
133
|
+
) {
|
|
134
|
+
super(executionState, queryBuilderState);
|
|
135
|
+
this.nativeModelAccess = executionState.__owner;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
override get label(): string {
|
|
139
|
+
return this.exectionValue.key;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
get mapping(): Mapping {
|
|
143
|
+
return this.exectionValue.mapping.value;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
get featuredElements(): DataProductElementScope[] | undefined {
|
|
147
|
+
return this.nativeModelAccess.featuredElements;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export class ModelAccessPointDataProductExecutionState extends DataProductExecutionState<ModelAccessPointGroup> {
|
|
152
|
+
selectedRuntime: PackageableRuntime | undefined;
|
|
153
|
+
|
|
154
|
+
constructor(
|
|
155
|
+
executionState: ModelAccessPointGroup,
|
|
156
|
+
queryBuilderState: DataProductQueryBuilderState,
|
|
157
|
+
) {
|
|
158
|
+
super(executionState, queryBuilderState);
|
|
159
|
+
makeObservable(this, {
|
|
160
|
+
selectedRuntime: observable,
|
|
161
|
+
compatibleRuntimes: computed,
|
|
162
|
+
showRuntimeOptions: computed,
|
|
163
|
+
changeSelectedRuntime: action,
|
|
164
|
+
});
|
|
165
|
+
this.selectedRuntime = this.compatibleRuntimes[0];
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
changeSelectedRuntime(val: PackageableRuntime): void {
|
|
169
|
+
this.selectedRuntime = val;
|
|
170
|
+
this.queryBuilderState.changeRuntime(val);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
override get label(): string {
|
|
174
|
+
return this.exectionValue.title ?? this.exectionValue.id;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
get mapping(): Mapping {
|
|
178
|
+
return this.exectionValue.mapping.value;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
get featuredElements(): DataProductElementScope[] | undefined {
|
|
182
|
+
return this.exectionValue.featuredElements;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
get showRuntimeOptions(): boolean {
|
|
186
|
+
return this.compatibleRuntimes.length > 1;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
get compatibleRuntimes(): PackageableRuntime[] {
|
|
190
|
+
return this.queryBuilderState.graphManagerState.usableRuntimes.filter(
|
|
191
|
+
(runtime) => runtime.runtimeValue instanceof LakehouseRuntime,
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
72
196
|
export class DataProductQueryBuilderState extends QueryBuilderState {
|
|
73
197
|
readonly onClassChange?: ((val: Class) => void) | undefined;
|
|
74
198
|
readonly onDataProductChange?: (val: DepotEntityWithOrigin) => Promise<void>;
|
|
@@ -77,10 +201,11 @@ export class DataProductQueryBuilderState extends QueryBuilderState {
|
|
|
77
201
|
| undefined;
|
|
78
202
|
|
|
79
203
|
loadDataProductModelState = ActionState.create();
|
|
80
|
-
nativeModelAccess: NativeModelAccess;
|
|
81
204
|
dataProduct: DataProduct;
|
|
82
205
|
dataProductArtifact: V1_DataProductArtifact | undefined;
|
|
83
|
-
|
|
206
|
+
executionState: DataProductExecutionState<
|
|
207
|
+
NativeModelExecutionContext | ModelAccessPointGroup
|
|
208
|
+
>;
|
|
84
209
|
entities: DepotEntityWithOrigin[] | undefined;
|
|
85
210
|
|
|
86
211
|
prioritizeEntityFunc?: ((val: DepotEntityWithOrigin) => boolean) | undefined;
|
|
@@ -95,8 +220,7 @@ export class DataProductQueryBuilderState extends QueryBuilderState {
|
|
|
95
220
|
dataProduct: DataProduct,
|
|
96
221
|
artifact: V1_DataProductArtifact | undefined,
|
|
97
222
|
actionConfig: QueryBuilderActionConfig,
|
|
98
|
-
|
|
99
|
-
nativeModelExecContext: NativeModelExecutionContext,
|
|
223
|
+
executionState: NativeModelExecutionContext | ModelAccessPointGroup,
|
|
100
224
|
prioritizeEntityFunc: ((val: DepotEntityWithOrigin) => boolean) | undefined,
|
|
101
225
|
onDataProductChange: (val: DepotEntityWithOrigin) => Promise<void>,
|
|
102
226
|
onExecutionContextChange?:
|
|
@@ -108,19 +232,31 @@ export class DataProductQueryBuilderState extends QueryBuilderState {
|
|
|
108
232
|
) {
|
|
109
233
|
super(applicationStore, graphManagerState, workflow, config, sourceInfo);
|
|
110
234
|
makeObservable(this, {
|
|
111
|
-
selectedExecContext: observable,
|
|
112
235
|
dataProduct: observable,
|
|
113
|
-
|
|
236
|
+
executionState: observable,
|
|
237
|
+
initWithDataProduct: action,
|
|
238
|
+
handleDataProductChange: action,
|
|
239
|
+
setExecutionState: action,
|
|
114
240
|
selectedDataProductOption: computed,
|
|
115
241
|
isProductLinkable: computed,
|
|
242
|
+
modelAccessPointGroups: computed,
|
|
243
|
+
hasModelAccessPointGroups: computed,
|
|
244
|
+
modelAccessPointGroupOptions: computed,
|
|
245
|
+
activeMapping: computed,
|
|
246
|
+
activeFeaturedElements: computed,
|
|
116
247
|
loadEntities: flow,
|
|
117
248
|
entities: observable,
|
|
118
249
|
});
|
|
250
|
+
// for queries against data product, we always want to default to from
|
|
251
|
+
this.executionContextState =
|
|
252
|
+
new QueryBuilderEmbeddedFromExecutionContextState(this);
|
|
119
253
|
this.workflowState.updateActionConfig(actionConfig);
|
|
120
254
|
this.dataProduct = dataProduct;
|
|
121
255
|
this.dataProductArtifact = artifact;
|
|
122
|
-
this.
|
|
123
|
-
|
|
256
|
+
this.executionState =
|
|
257
|
+
executionState instanceof NativeModelExecutionContext
|
|
258
|
+
? new NativeModelDataProductExecutionState(executionState, this)
|
|
259
|
+
: new ModelAccessPointDataProductExecutionState(executionState, this);
|
|
124
260
|
this.prioritizeEntityFunc = prioritizeEntityFunc;
|
|
125
261
|
this.onDataProductChange = onDataProductChange;
|
|
126
262
|
this.onExecutionContextChange = onExecutionContextChange;
|
|
@@ -131,6 +267,63 @@ export class DataProductQueryBuilderState extends QueryBuilderState {
|
|
|
131
267
|
return false;
|
|
132
268
|
}
|
|
133
269
|
|
|
270
|
+
handleDataProductChange(val: DepotEntityWithOrigin): void {
|
|
271
|
+
try {
|
|
272
|
+
this.loadDataProductModelState.inProgress();
|
|
273
|
+
const dataProduct = this.graphManagerState.graph.getDataProduct(val.path);
|
|
274
|
+
this.initWithDataProduct(dataProduct);
|
|
275
|
+
} catch (error) {
|
|
276
|
+
assertErrorThrown(error);
|
|
277
|
+
this.applicationStore.notificationService.notifyError(
|
|
278
|
+
`Failed to change Data Product: ${error.message}`,
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
initWithDataProduct(dataProduct: DataProduct): void {
|
|
284
|
+
try {
|
|
285
|
+
const execValue = resolveDataProductExecutionState(dataProduct);
|
|
286
|
+
this.dataProduct = dataProduct;
|
|
287
|
+
this.executionState =
|
|
288
|
+
execValue instanceof NativeModelExecutionContext
|
|
289
|
+
? new NativeModelDataProductExecutionState(execValue, this)
|
|
290
|
+
: new ModelAccessPointDataProductExecutionState(execValue, this);
|
|
291
|
+
this.changeMapping(this.executionState.mapping);
|
|
292
|
+
if (this.executionState instanceof NativeModelDataProductExecutionState) {
|
|
293
|
+
const runtime = guaranteeNonNullable(
|
|
294
|
+
this.executionState.exectionValue.runtime,
|
|
295
|
+
'runtime unable to be resolved',
|
|
296
|
+
);
|
|
297
|
+
this.changeRuntime(new RuntimePointer(runtime));
|
|
298
|
+
} else if (
|
|
299
|
+
this.executionState instanceof
|
|
300
|
+
ModelAccessPointDataProductExecutionState &&
|
|
301
|
+
this.executionState.selectedRuntime instanceof PackageableRuntime
|
|
302
|
+
) {
|
|
303
|
+
this.changeRuntime(this.executionState.selectedRuntime);
|
|
304
|
+
}
|
|
305
|
+
const compatibleClasses = resolveUsableDataProductClasses(
|
|
306
|
+
this.activeFeaturedElements,
|
|
307
|
+
this.executionState.mapping,
|
|
308
|
+
this.graphManagerState,
|
|
309
|
+
undefined,
|
|
310
|
+
);
|
|
311
|
+
// if there is no chosen class or the chosen one is not compatible
|
|
312
|
+
// with the mapping then pick a compatible class if possible
|
|
313
|
+
if (!this.class || !compatibleClasses.includes(this.class)) {
|
|
314
|
+
const possibleNewClass = compatibleClasses[0];
|
|
315
|
+
if (possibleNewClass) {
|
|
316
|
+
this.changeClass(possibleNewClass);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
} catch (error) {
|
|
320
|
+
assertErrorThrown(error);
|
|
321
|
+
this.applicationStore.notificationService.notifyError(
|
|
322
|
+
`Failed to load Data Product: ${error.message}`,
|
|
323
|
+
);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
134
327
|
copyDataProductLinkToClipBoard(): void {
|
|
135
328
|
if (!this.isProductLinkable) {
|
|
136
329
|
this.applicationStore.notificationService.notifyError(
|
|
@@ -143,8 +336,77 @@ export class DataProductQueryBuilderState extends QueryBuilderState {
|
|
|
143
336
|
return DataProduct;
|
|
144
337
|
}
|
|
145
338
|
|
|
146
|
-
|
|
147
|
-
|
|
339
|
+
setExecutionState(
|
|
340
|
+
val: NativeModelExecutionContext | ModelAccessPointGroup,
|
|
341
|
+
): void {
|
|
342
|
+
this.executionState =
|
|
343
|
+
val instanceof NativeModelExecutionContext
|
|
344
|
+
? new NativeModelDataProductExecutionState(val, this)
|
|
345
|
+
: new ModelAccessPointDataProductExecutionState(val, this);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
get modelAccessPointGroups(): ModelAccessPointGroup[] {
|
|
349
|
+
return this.dataProduct.accessPointGroups.filter(
|
|
350
|
+
filterByType(ModelAccessPointGroup),
|
|
351
|
+
);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
get hasModelAccessPointGroups(): boolean {
|
|
355
|
+
return this.modelAccessPointGroups.length > 0;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
get modelAccessPointGroupOptions(): ModelAccessPointGroupOption[] {
|
|
359
|
+
return this.modelAccessPointGroups
|
|
360
|
+
.map(buildModelAccessPointGroupOption)
|
|
361
|
+
.sort(compareLabelFn);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
get activeMapping(): Mapping | undefined {
|
|
365
|
+
return this.executionState.mapping;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
get activeFeaturedElements(): DataProductElementScope[] | undefined {
|
|
369
|
+
return this.executionState.featuredElements;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
override buildExecutionContextExpression(
|
|
373
|
+
lambdaFunction: LambdaFunction,
|
|
374
|
+
): LambdaFunction {
|
|
375
|
+
if (
|
|
376
|
+
this.executionState instanceof ModelAccessPointDataProductExecutionState
|
|
377
|
+
) {
|
|
378
|
+
// for model access point group with attached ->with(dataProduct)->from(runtime) to execute query
|
|
379
|
+
let precedingExpression = guaranteeNonNullable(
|
|
380
|
+
lambdaFunction.expressionSequence[0],
|
|
381
|
+
`Can't build from() expression: preceding expression is not defined`,
|
|
382
|
+
);
|
|
383
|
+
const withFunc = new SimpleFunctionExpression(
|
|
384
|
+
extractElementNameFromPath(SUPPORTED_FUNCTIONS.WITH),
|
|
385
|
+
);
|
|
386
|
+
const dataProductInstance = new InstanceValue(
|
|
387
|
+
Multiplicity.ONE,
|
|
388
|
+
undefined,
|
|
389
|
+
);
|
|
390
|
+
dataProductInstance.values = [
|
|
391
|
+
PackageableElementExplicitReference.create(this.dataProduct),
|
|
392
|
+
];
|
|
393
|
+
withFunc.parametersValues = [precedingExpression, dataProductInstance];
|
|
394
|
+
precedingExpression = withFunc;
|
|
395
|
+
const fromFunc = new SimpleFunctionExpression(
|
|
396
|
+
extractElementNameFromPath(SUPPORTED_FUNCTIONS.FROM),
|
|
397
|
+
);
|
|
398
|
+
const runtime = this.executionState.selectedRuntime;
|
|
399
|
+
if (runtime) {
|
|
400
|
+
const runtimeInstance = new InstanceValue(Multiplicity.ONE, undefined);
|
|
401
|
+
runtimeInstance.values = [
|
|
402
|
+
PackageableElementExplicitReference.create(runtime),
|
|
403
|
+
];
|
|
404
|
+
fromFunc.parametersValues = [precedingExpression, runtimeInstance];
|
|
405
|
+
lambdaFunction.expressionSequence[0] = fromFunc;
|
|
406
|
+
}
|
|
407
|
+
return lambdaFunction;
|
|
408
|
+
}
|
|
409
|
+
return super.buildExecutionContextExpression(lambdaFunction);
|
|
148
410
|
}
|
|
149
411
|
|
|
150
412
|
*loadEntities(): GeneratorFn<void> {
|
|
@@ -216,14 +478,14 @@ export class DataProductQueryBuilderState extends QueryBuilderState {
|
|
|
216
478
|
requireReBuildingGraph?: boolean | undefined,
|
|
217
479
|
): Promise<void> {
|
|
218
480
|
const currentMapping = this.executionContextState.mapping;
|
|
219
|
-
const
|
|
220
|
-
if (
|
|
221
|
-
this.changeMapping(
|
|
481
|
+
const newMapping = this.activeMapping;
|
|
482
|
+
if (newMapping && newMapping !== currentMapping) {
|
|
483
|
+
this.changeMapping(newMapping, {
|
|
222
484
|
keepQueryContent: true,
|
|
223
485
|
});
|
|
224
486
|
const classes = resolveUsableDataProductClasses(
|
|
225
|
-
this.
|
|
226
|
-
|
|
487
|
+
this.activeFeaturedElements,
|
|
488
|
+
newMapping,
|
|
227
489
|
this.graphManagerState,
|
|
228
490
|
undefined,
|
|
229
491
|
);
|