@finos/legend-query-builder 4.19.11 → 4.19.13

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 (118) hide show
  1. package/lib/__lib__/QueryBuilderDocumentation.d.ts +2 -1
  2. package/lib/__lib__/QueryBuilderDocumentation.d.ts.map +1 -1
  3. package/lib/__lib__/QueryBuilderDocumentation.js +1 -0
  4. package/lib/__lib__/QueryBuilderDocumentation.js.map +1 -1
  5. package/lib/__lib__/QueryBuilderEvent.d.ts +45 -1
  6. package/lib/__lib__/QueryBuilderEvent.d.ts.map +1 -1
  7. package/lib/__lib__/QueryBuilderEvent.js +48 -0
  8. package/lib/__lib__/QueryBuilderEvent.js.map +1 -1
  9. package/lib/__lib__/QueryBuilderTelemetryHelper.d.ts +162 -8
  10. package/lib/__lib__/QueryBuilderTelemetryHelper.d.ts.map +1 -1
  11. package/lib/__lib__/QueryBuilderTelemetryHelper.js +48 -0
  12. package/lib/__lib__/QueryBuilderTelemetryHelper.js.map +1 -1
  13. package/lib/components/QueryBuilder.d.ts.map +1 -1
  14. package/lib/components/QueryBuilder.js +9 -5
  15. package/lib/components/QueryBuilder.js.map +1 -1
  16. package/lib/components/QueryBuilderConstantExpressionPanel.d.ts.map +1 -1
  17. package/lib/components/QueryBuilderConstantExpressionPanel.js +18 -1
  18. package/lib/components/QueryBuilderConstantExpressionPanel.js.map +1 -1
  19. package/lib/components/QueryBuilderParametersPanel.d.ts.map +1 -1
  20. package/lib/components/QueryBuilderParametersPanel.js +18 -1
  21. package/lib/components/QueryBuilderParametersPanel.js.map +1 -1
  22. package/lib/components/QueryBuilderSideBar.d.ts.map +1 -1
  23. package/lib/components/QueryBuilderSideBar.js +19 -0
  24. package/lib/components/QueryBuilderSideBar.js.map +1 -1
  25. package/lib/components/fetch-structure/QueryBuilderGraphFetchTreePanel.d.ts.map +1 -1
  26. package/lib/components/fetch-structure/QueryBuilderGraphFetchTreePanel.js +42 -1
  27. package/lib/components/fetch-structure/QueryBuilderGraphFetchTreePanel.js.map +1 -1
  28. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.d.ts.map +1 -1
  29. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js +25 -5
  30. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js.map +1 -1
  31. package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.d.ts.map +1 -1
  32. package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.js +55 -0
  33. package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.js.map +1 -1
  34. package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
  35. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +95 -8
  36. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
  37. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.d.ts.map +1 -1
  38. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.js +37 -4
  39. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.js.map +1 -1
  40. package/lib/components/filter/QueryBuilderFilterPanel.d.ts.map +1 -1
  41. package/lib/components/filter/QueryBuilderFilterPanel.js +24 -5
  42. package/lib/components/filter/QueryBuilderFilterPanel.js.map +1 -1
  43. package/lib/components/result/QueryBuilderDataProductErrorPanel.d.ts +61 -0
  44. package/lib/components/result/QueryBuilderDataProductErrorPanel.d.ts.map +1 -0
  45. package/lib/components/result/QueryBuilderDataProductErrorPanel.js +176 -0
  46. package/lib/components/result/QueryBuilderDataProductErrorPanel.js.map +1 -0
  47. package/lib/components/result/QueryBuilderResultPanel.d.ts.map +1 -1
  48. package/lib/components/result/QueryBuilderResultPanel.js +24 -18
  49. package/lib/components/result/QueryBuilderResultPanel.js.map +1 -1
  50. package/lib/data-access-overview.css +1 -1
  51. package/lib/index.css +17 -1
  52. package/lib/index.css.map +1 -1
  53. package/lib/index.d.ts +1 -0
  54. package/lib/index.d.ts.map +1 -1
  55. package/lib/index.js +1 -0
  56. package/lib/index.js.map +1 -1
  57. package/lib/package.json +1 -1
  58. package/lib/stores/QueryBuilderResultState.d.ts +11 -1
  59. package/lib/stores/QueryBuilderResultState.d.ts.map +1 -1
  60. package/lib/stores/QueryBuilderResultState.js +79 -15
  61. package/lib/stores/QueryBuilderResultState.js.map +1 -1
  62. package/lib/stores/QueryBuilderState.d.ts +131 -9
  63. package/lib/stores/QueryBuilderState.d.ts.map +1 -1
  64. package/lib/stores/QueryBuilderState.js +124 -21
  65. package/lib/stores/QueryBuilderState.js.map +1 -1
  66. package/lib/stores/QueryBuilder_LegendApplicationPlugin_Extension.d.ts +13 -0
  67. package/lib/stores/QueryBuilder_LegendApplicationPlugin_Extension.d.ts.map +1 -1
  68. package/lib/stores/QueryLoaderState.d.ts +33 -5
  69. package/lib/stores/QueryLoaderState.d.ts.map +1 -1
  70. package/lib/stores/QueryLoaderState.js +10 -1
  71. package/lib/stores/QueryLoaderState.js.map +1 -1
  72. package/lib/stores/data-access/DataProductAccessInfo.d.ts +37 -0
  73. package/lib/stores/data-access/DataProductAccessInfo.d.ts.map +1 -0
  74. package/lib/stores/data-access/DataProductAccessInfo.js +17 -0
  75. package/lib/stores/data-access/DataProductAccessInfo.js.map +1 -0
  76. package/lib/stores/data-cube/QueryBuilderDataCubeEngine.js +1 -1
  77. package/lib/stores/data-cube/QueryBuilderDataCubeEngine.js.map +1 -1
  78. package/lib/stores/explorer/QueryBuilderExplorerState.js +1 -1
  79. package/lib/stores/explorer/QueryBuilderExplorerState.js.map +1 -1
  80. package/lib/stores/milestoning/QueryBuilderMilestoningHelper.d.ts.map +1 -1
  81. package/lib/stores/milestoning/QueryBuilderMilestoningHelper.js +34 -9
  82. package/lib/stores/milestoning/QueryBuilderMilestoningHelper.js.map +1 -1
  83. package/lib/stores/milestoning/QueryBuilderMilestoningState.d.ts +5 -0
  84. package/lib/stores/milestoning/QueryBuilderMilestoningState.d.ts.map +1 -1
  85. package/lib/stores/milestoning/QueryBuilderMilestoningState.js +13 -0
  86. package/lib/stores/milestoning/QueryBuilderMilestoningState.js.map +1 -1
  87. package/lib/stores/workflows/dataProduct/DataProductQueryBuilderState.d.ts +2 -0
  88. package/lib/stores/workflows/dataProduct/DataProductQueryBuilderState.d.ts.map +1 -1
  89. package/lib/stores/workflows/dataProduct/DataProductQueryBuilderState.js +50 -1
  90. package/lib/stores/workflows/dataProduct/DataProductQueryBuilderState.js.map +1 -1
  91. package/package.json +10 -10
  92. package/src/__lib__/QueryBuilderDocumentation.ts +1 -0
  93. package/src/__lib__/QueryBuilderEvent.ts +52 -0
  94. package/src/__lib__/QueryBuilderTelemetryHelper.ts +292 -8
  95. package/src/components/QueryBuilder.tsx +31 -23
  96. package/src/components/QueryBuilderConstantExpressionPanel.tsx +24 -2
  97. package/src/components/QueryBuilderParametersPanel.tsx +25 -2
  98. package/src/components/QueryBuilderSideBar.tsx +28 -0
  99. package/src/components/fetch-structure/QueryBuilderGraphFetchTreePanel.tsx +56 -1
  100. package/src/components/fetch-structure/QueryBuilderPostFilterPanel.tsx +31 -4
  101. package/src/components/fetch-structure/QueryBuilderResultModifierPanel.tsx +74 -0
  102. package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +123 -8
  103. package/src/components/fetch-structure/QueryBuilderTDSWindowPanel.tsx +49 -4
  104. package/src/components/filter/QueryBuilderFilterPanel.tsx +31 -4
  105. package/src/components/result/QueryBuilderDataProductErrorPanel.tsx +441 -0
  106. package/src/components/result/QueryBuilderResultPanel.tsx +49 -32
  107. package/src/index.ts +1 -0
  108. package/src/stores/QueryBuilderResultState.ts +107 -19
  109. package/src/stores/QueryBuilderState.ts +239 -29
  110. package/src/stores/QueryBuilder_LegendApplicationPlugin_Extension.ts +20 -0
  111. package/src/stores/QueryLoaderState.ts +47 -6
  112. package/src/stores/data-access/DataProductAccessInfo.ts +37 -0
  113. package/src/stores/data-cube/QueryBuilderDataCubeEngine.ts +1 -1
  114. package/src/stores/explorer/QueryBuilderExplorerState.ts +1 -1
  115. package/src/stores/milestoning/QueryBuilderMilestoningHelper.ts +63 -8
  116. package/src/stores/milestoning/QueryBuilderMilestoningState.ts +20 -0
  117. package/src/stores/workflows/dataProduct/DataProductQueryBuilderState.ts +68 -0
  118. package/tsconfig.json +2 -0
@@ -68,6 +68,40 @@ export interface QueryRevisionDiffInput {
68
68
  content: string | undefined;
69
69
  }
70
70
 
71
+ /**
72
+ * Callbacks the query loader invokes across the saved-query lifecycle. Hosts
73
+ * implement these to report the actions to telemetry and to keep their own
74
+ * state (a recently-viewed list, say) in sync.
75
+ *
76
+ * Declared as one interface so the loader's fields, its constructor options and
77
+ * a host's handler bundle all derive from a single contract rather than
78
+ * repeating four signatures three times.
79
+ */
80
+ export interface QueryLoaderLifecycleHandlers {
81
+ onQueryRenamed?: ((query: LightQuery) => void) | undefined;
82
+ /**
83
+ * The deleted query is passed alongside its id where it could be resolved
84
+ * from the loaded list, so hosts can report more than a bare id.
85
+ */
86
+ onQueryDeleted?:
87
+ | ((queryId: string, deletedQuery?: LightQuery | undefined) => void)
88
+ | undefined;
89
+ onQueryRenameFailed?: ((queryId: string, error: Error) => void) | undefined;
90
+ onQueryDeleteFailed?: ((queryId: string, error: Error) => void) | undefined;
91
+ }
92
+
93
+ /**
94
+ * The same handlers with every one provided — what a host's complete bundle
95
+ * looks like. Derived from {@link QueryLoaderLifecycleHandlers} so the two
96
+ * cannot drift; `Required` alone would not do, since it strips optionality but
97
+ * leaves the explicit `| undefined` in each property's type.
98
+ */
99
+ export type CompleteQueryLoaderLifecycleHandlers = {
100
+ [K in keyof QueryLoaderLifecycleHandlers]-?: NonNullable<
101
+ QueryLoaderLifecycleHandlers[K]
102
+ >;
103
+ };
104
+
71
105
  export class QueryLoaderState {
72
106
  readonly applicationStore: GenericLegendApplicationStore;
73
107
  readonly graphManager: AbstractPureGraphManager;
@@ -94,8 +128,10 @@ export class QueryLoaderState {
94
128
  | undefined;
95
129
 
96
130
  readonly isReadOnly?: boolean | undefined;
97
- readonly onQueryRenamed?: ((query: LightQuery) => void) | undefined;
98
- readonly onQueryDeleted?: ((query: string) => void) | undefined;
131
+ readonly onQueryRenamed?: QueryLoaderLifecycleHandlers['onQueryRenamed'];
132
+ readonly onQueryDeleted?: QueryLoaderLifecycleHandlers['onQueryDeleted'];
133
+ readonly onQueryRenameFailed?: QueryLoaderLifecycleHandlers['onQueryRenameFailed'];
134
+ readonly onQueryDeleteFailed?: QueryLoaderLifecycleHandlers['onQueryDeleteFailed'];
99
135
  readonly handleFetchDefaultQueriesFailure?: (() => void) | undefined;
100
136
 
101
137
  queryBuilderState?: QueryBuilderState | undefined;
@@ -144,10 +180,8 @@ export class QueryLoaderState {
144
180
  | ((queries: LightQuery[]) => string)
145
181
  | undefined;
146
182
  isReadOnly?: boolean | undefined;
147
- onQueryRenamed?: ((query: LightQuery) => void) | undefined;
148
- onQueryDeleted?: ((query: string) => void) | undefined;
149
183
  handleFetchDefaultQueriesFailure?: (() => void) | undefined;
150
- },
184
+ } & QueryLoaderLifecycleHandlers,
151
185
  ) {
152
186
  makeObservable(this, {
153
187
  isQueryLoaderDialogOpen: observable,
@@ -201,6 +235,8 @@ export class QueryLoaderState {
201
235
  this.isReadOnly = options.isReadOnly;
202
236
  this.onQueryRenamed = options.onQueryRenamed;
203
237
  this.onQueryDeleted = options.onQueryDeleted;
238
+ this.onQueryRenameFailed = options.onQueryRenameFailed;
239
+ this.onQueryDeleteFailed = options.onQueryDeleteFailed;
204
240
  this.handleFetchDefaultQueriesFailure =
205
241
  options.handleFetchDefaultQueriesFailure;
206
242
  }
@@ -429,6 +465,7 @@ export class QueryLoaderState {
429
465
  this.searchQueries(this.searchText); // trigger a search to refresh the query list
430
466
  } catch (error) {
431
467
  assertErrorThrown(error);
468
+ this.onQueryRenameFailed?.(queryId, error);
432
469
  this.applicationStore.notificationService.notifyError(error);
433
470
  this.renameQueryState.fail();
434
471
  }
@@ -463,9 +500,12 @@ export class QueryLoaderState {
463
500
 
464
501
  *deleteQuery(queryId: string): GeneratorFn<void> {
465
502
  this.deleteQueryState.inProgress();
503
+ // resolve before the delete: afterwards the list is refreshed and the entry
504
+ // is gone, so this is the only point where more than the id is available
505
+ const deletedQuery = this.queries.find((query) => query.id === queryId);
466
506
  try {
467
507
  yield this.graphManager.deleteQuery(queryId);
468
- this.onQueryDeleted?.(queryId);
508
+ this.onQueryDeleted?.(queryId, deletedQuery);
469
509
  this.applicationStore.notificationService.notifySuccess(
470
510
  'Deleted query successfully',
471
511
  );
@@ -473,6 +513,7 @@ export class QueryLoaderState {
473
513
  this.searchQueries(this.searchText); // trigger a search to refresh the query list
474
514
  } catch (error) {
475
515
  assertErrorThrown(error);
516
+ this.onQueryDeleteFailed?.(queryId, error);
476
517
  this.applicationStore.notificationService.notifyError(error);
477
518
  this.deleteQueryState.fail();
478
519
  }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Copyright (c) 2026-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ /**
18
+ * Plain description of the data product a query runs against, used to explain
19
+ * entitlement failures and to point the user at where access can be requested.
20
+ *
21
+ * NOTE: this is intentionally plain data rather than the query builder state itself,
22
+ * so the result panel does not have to depend on `DataProductQueryBuilderState`.
23
+ */
24
+ export type DataProductAccessInfo = {
25
+ dataProductLabel: string;
26
+ /**
27
+ * Identifier of the data product as used by external applications (e.g. Marketplace
28
+ * routing), which is not necessarily the same as the display label.
29
+ */
30
+ dataProductId: string;
31
+ accessPointGroupId: string | undefined;
32
+ accessPointGroupLabel: string | undefined;
33
+ deploymentId: string | undefined;
34
+ environment: string | undefined;
35
+ warehouse: string | undefined;
36
+ supportEmails: string[];
37
+ };
@@ -242,7 +242,7 @@ export class QueryBuilderDataCubeEngine extends DataCubeEngine {
242
242
  const reportWithState = Object.assign(
243
243
  {},
244
244
  report,
245
- this.queryBuilderState.getStateInfo(),
245
+ this.queryBuilderState.safeGetTelemetryContext(),
246
246
  );
247
247
  QueryBuilderTelemetryHelper.logEvent_EmbeddedDataCubeQueryRunSucceeded(
248
248
  this.queryBuilderState.applicationStore.telemetryService,
@@ -979,7 +979,7 @@ export class QueryBuilderExplorerState {
979
979
  const reportWithState = Object.assign(
980
980
  {},
981
981
  report,
982
- this.queryBuilderState.getStateInfo(),
982
+ this.queryBuilderState.safeGetTelemetryContext(),
983
983
  );
984
984
  QueryBuilderTelemetryHelper.logEvent_QueryMappingModelCoverageAnalysisSucceeded(
985
985
  this.queryBuilderState.applicationStore.telemetryService,
@@ -26,6 +26,7 @@ import {
26
26
  PrimitiveInstanceValue,
27
27
  PRIMITIVE_TYPE,
28
28
  type PureModel,
29
+ SimpleFunctionExpression,
29
30
  VariableExpression,
30
31
  } from '@finos/legend-graph';
31
32
  import {
@@ -289,6 +290,52 @@ export const generateMilestonedPropertyParameterValue = (
289
290
  derivedPropertyExpressionState,
290
291
  );
291
292
  };
293
+ const isResolvableInQueryScope = (
294
+ value: ValueSpecification | undefined,
295
+ queryBuilderState: QueryBuilderState,
296
+ ): boolean => {
297
+ if (value instanceof PrimitiveInstanceValue) {
298
+ return true;
299
+ } else if (value instanceof VariableExpression) {
300
+ return (
301
+ queryBuilderState.parametersState.parameterStates.some(
302
+ (parameterState) => parameterState.variableName === value.name,
303
+ ) ||
304
+ queryBuilderState.constantState.constants.some(
305
+ (constant) => constant.variable.name === value.name,
306
+ )
307
+ );
308
+ } else if (value instanceof SimpleFunctionExpression) {
309
+ return value.parametersValues.every((parameterValue) =>
310
+ isResolvableInQueryScope(parameterValue, queryBuilderState),
311
+ );
312
+ }
313
+ return false;
314
+ };
315
+
316
+ const seedQueryBusinessDate = (
317
+ value: ValueSpecification | undefined,
318
+ queryBuilderState: QueryBuilderState,
319
+ ): void => {
320
+ if (
321
+ queryBuilderState.milestoningState.businessDate === undefined &&
322
+ isResolvableInQueryScope(value, queryBuilderState)
323
+ ) {
324
+ queryBuilderState.milestoningState.setBusinessDate(value);
325
+ }
326
+ };
327
+
328
+ const seedQueryProcessingDate = (
329
+ value: ValueSpecification | undefined,
330
+ queryBuilderState: QueryBuilderState,
331
+ ): void => {
332
+ if (
333
+ queryBuilderState.milestoningState.processingDate === undefined &&
334
+ isResolvableInQueryScope(value, queryBuilderState)
335
+ ) {
336
+ queryBuilderState.milestoningState.setProcessingDate(value);
337
+ }
338
+ };
292
339
 
293
340
  export const validateMilestoningPropertyExpressionChain = (
294
341
  sourceStereotype: MILESTONING_STEREOTYPE | undefined,
@@ -317,11 +364,13 @@ export const validateMilestoningPropertyExpressionChain = (
317
364
  `Property of milestoning sterotype '${MILESTONING_STEREOTYPE.BITEMPORAL}' should not have more than two parameters`,
318
365
  );
319
366
  }
320
- queryBuilderState.milestoningState.setProcessingDate(
367
+ seedQueryProcessingDate(
321
368
  propertyExpression.parametersValues[1],
369
+ queryBuilderState,
322
370
  );
323
- queryBuilderState.milestoningState.setBusinessDate(
371
+ seedQueryBusinessDate(
324
372
  propertyExpression.parametersValues[2],
373
+ queryBuilderState,
325
374
  );
326
375
  } else if (propertyExpression.parametersValues.length !== 2) {
327
376
  throw new UnsupportedOperationError(
@@ -329,14 +378,16 @@ export const validateMilestoningPropertyExpressionChain = (
329
378
  );
330
379
  }
331
380
  if (targetStereotype === MILESTONING_STEREOTYPE.BUSINESS_TEMPORAL) {
332
- queryBuilderState.milestoningState.setBusinessDate(
381
+ seedQueryBusinessDate(
333
382
  propertyExpression.parametersValues[1],
383
+ queryBuilderState,
334
384
  );
335
385
  } else if (
336
386
  targetStereotype === MILESTONING_STEREOTYPE.PROCESSING_TEMPORAL
337
387
  ) {
338
- queryBuilderState.milestoningState.setProcessingDate(
388
+ seedQueryProcessingDate(
339
389
  propertyExpression.parametersValues[1],
390
+ queryBuilderState,
340
391
  );
341
392
  }
342
393
  }
@@ -346,23 +397,27 @@ export const validateMilestoningPropertyExpressionChain = (
346
397
  propertyExpression.parametersValues.length === 3 &&
347
398
  targetStereotype === MILESTONING_STEREOTYPE.BITEMPORAL
348
399
  ) {
349
- queryBuilderState.milestoningState.setProcessingDate(
400
+ seedQueryProcessingDate(
350
401
  propertyExpression.parametersValues[1],
402
+ queryBuilderState,
351
403
  );
352
- queryBuilderState.milestoningState.setBusinessDate(
404
+ seedQueryBusinessDate(
353
405
  propertyExpression.parametersValues[2],
406
+ queryBuilderState,
354
407
  );
355
408
  }
356
409
  if (propertyExpression.parametersValues.length === 2) {
357
410
  if (targetStereotype === MILESTONING_STEREOTYPE.BUSINESS_TEMPORAL) {
358
- queryBuilderState.milestoningState.setBusinessDate(
411
+ seedQueryBusinessDate(
359
412
  propertyExpression.parametersValues[1],
413
+ queryBuilderState,
360
414
  );
361
415
  } else if (
362
416
  targetStereotype === MILESTONING_STEREOTYPE.PROCESSING_TEMPORAL
363
417
  ) {
364
- queryBuilderState.milestoningState.setProcessingDate(
418
+ seedQueryProcessingDate(
365
419
  propertyExpression.parametersValues[1],
420
+ queryBuilderState,
366
421
  );
367
422
  }
368
423
  }
@@ -54,6 +54,12 @@ import {
54
54
  FilterPropertyExpressionSourceState,
55
55
  } from '../filter/QueryBuilderFilterState.js';
56
56
 
57
+ export type QueryBuilderMilestoningKind =
58
+ | 'get-all'
59
+ | 'all-versions'
60
+ | 'all-versions-in-range'
61
+ | 'none';
62
+
57
63
  export class QueryBuilderMilestoningState implements Hashable {
58
64
  readonly milestoningImplementations: QueryBuilderMilestoningImplementation[] =
59
65
  [];
@@ -92,6 +98,7 @@ export class QueryBuilderMilestoningState implements Hashable {
92
98
  isAllVersionsEnabled: computed,
93
99
  isAllVersionsInRangeEnabled: computed,
94
100
  isMilestonedQuery: computed,
101
+ milestoningKind: computed,
95
102
  hashCode: computed,
96
103
  });
97
104
 
@@ -240,6 +247,19 @@ export class QueryBuilderMilestoningState implements Hashable {
240
247
  );
241
248
  }
242
249
 
250
+ /**
251
+ * Shape-only summary of the milestoning configuration, for telemetry.
252
+ */
253
+ get milestoningKind(): QueryBuilderMilestoningKind {
254
+ return this.isAllVersionsInRangeEnabled
255
+ ? 'all-versions-in-range'
256
+ : this.isAllVersionsEnabled
257
+ ? 'all-versions'
258
+ : this.isMilestonedQuery
259
+ ? 'get-all'
260
+ : 'none';
261
+ }
262
+
243
263
  get isInvalidAllVersionsInRange(): boolean {
244
264
  if (
245
265
  (this.startDate && !this.endDate) ||
@@ -19,6 +19,7 @@ import {
19
19
  type Class,
20
20
  DataProduct,
21
21
  type V1_DataProductArtifact,
22
+ type V1_DataProductInfo,
22
23
  ModelAccessPointGroup,
23
24
  NativeModelExecutionContext,
24
25
  CORE_PURE_PATH,
@@ -29,6 +30,7 @@ import {
29
30
  resolveUsableDataProductClasses,
30
31
  LakehouseRuntime,
31
32
  type LambdaFunction,
33
+ attachRuntimeFromQuery,
32
34
  attachWithFromQuery,
33
35
  type MappingModelCoverageAnalysisResult,
34
36
  PackageableElementExplicitReference,
@@ -77,6 +79,7 @@ import {
77
79
  } from '@finos/legend-storage';
78
80
  import { compareLabelFn } from '@finos/legend-art';
79
81
  import { QueryBuilderEmbeddedFromExecutionContextState } from '../../QueryBuilderExecutionContextState.js';
82
+ import type { DataProductAccessInfo } from '../../data-access/DataProductAccessInfo.js';
80
83
 
81
84
  export const resolveDataProductAccessor = (
82
85
  dataProduct: DataProduct,
@@ -418,6 +421,7 @@ export class DataProductQueryBuilderState extends QueryBuilderState {
418
421
  modelAccessPointGroupOptions: computed,
419
422
  activeMapping: computed,
420
423
  activeFeaturedElements: computed,
424
+ dataProductAccessInfo: computed,
421
425
  loadEntities: flow,
422
426
  entities: observable,
423
427
  });
@@ -858,6 +862,21 @@ export class DataProductQueryBuilderState extends QueryBuilderState {
858
862
  relationMetadata,
859
863
  );
860
864
  this.changeSourceElement(accessor);
865
+ this.executionContextState.setMapping(undefined);
866
+ if (
867
+ this.executionState instanceof LakehouseDataProductExecutionState &&
868
+ this.executionState.selectedRuntime
869
+ ) {
870
+ this.executionContextState.setRuntimeValue(
871
+ new RuntimePointer(
872
+ PackageableElementExplicitReference.create(
873
+ this.executionState.selectedRuntime,
874
+ ),
875
+ ),
876
+ );
877
+ } else {
878
+ this.executionContextState.setRuntimeValue(undefined);
879
+ }
861
880
  }
862
881
  }
863
882
 
@@ -885,6 +904,47 @@ export class DataProductQueryBuilderState extends QueryBuilderState {
885
904
  return this.executionState.featuredElements;
886
905
  }
887
906
 
907
+ get dataProductAccessInfo(): DataProductAccessInfo {
908
+ const execValue = this.executionState.exectionValue;
909
+ // for lakehouse access points, access is granted on the group the access point
910
+ // belongs to, so resolve it from the access point
911
+ const accessPointGroup =
912
+ execValue instanceof ModelAccessPointGroup
913
+ ? execValue
914
+ : execValue instanceof LakehouseAccessPoint
915
+ ? findLakehouseAccessPointGroup(this.dataProduct, execValue.id)?.group
916
+ : undefined;
917
+ const selectedRuntime =
918
+ this.executionState instanceof
919
+ ModelAccessPointDataProductExecutionState ||
920
+ this.executionState instanceof LakehouseDataProductExecutionState
921
+ ? this.executionState.selectedRuntime
922
+ : undefined;
923
+ const lakehouseRuntime =
924
+ selectedRuntime?.runtimeValue instanceof LakehouseRuntime
925
+ ? selectedRuntime.runtimeValue
926
+ : undefined;
927
+ // NOTE: `dataProduct` is declared with definite assignment, but is genuinely unset
928
+ // on an artifact which was constructed rather than deserialized
929
+ const artifactInfo: V1_DataProductInfo | undefined =
930
+ this.dataProductArtifact?.dataProduct;
931
+
932
+ return {
933
+ dataProductLabel: this.dataProduct.title ?? this.dataProduct.name,
934
+ dataProductId: this.dataProduct.name,
935
+ accessPointGroupId: accessPointGroup?.id,
936
+ accessPointGroupLabel: accessPointGroup
937
+ ? (accessPointGroup.title ?? accessPointGroup.id)
938
+ : undefined,
939
+ deploymentId: artifactInfo?.deploymentId,
940
+ environment: lakehouseRuntime?.environment,
941
+ warehouse: lakehouseRuntime?.warehouse,
942
+ supportEmails: (this.dataProduct.supportInfo?.emails ?? []).map(
943
+ (email) => email.address,
944
+ ),
945
+ };
946
+ }
947
+
888
948
  override buildExecutionContextExpression(
889
949
  lambdaFunction: LambdaFunction,
890
950
  ): LambdaFunction {
@@ -896,6 +956,14 @@ export class DataProductQueryBuilderState extends QueryBuilderState {
896
956
  return attachWithFromQuery(lambdaFunction, this.dataProduct, runtime);
897
957
  }
898
958
  return lambdaFunction;
959
+ } else if (
960
+ this.executionState instanceof LakehouseDataProductExecutionState
961
+ ) {
962
+ const runtime = this.executionState.selectedRuntime;
963
+ if (runtime) {
964
+ return attachRuntimeFromQuery(lambdaFunction, runtime);
965
+ }
966
+ return lambdaFunction;
899
967
  }
900
968
  return super.buildExecutionContextExpression(lambdaFunction);
901
969
  }
package/tsconfig.json CHANGED
@@ -108,6 +108,7 @@
108
108
  "./src/stores/__test-utils__/QueryBuilderStateTestUtils.ts",
109
109
  "./src/stores/__test-utils__/TEST_DATA__QueryBuilder_Accessors.ts",
110
110
  "./src/stores/data-access/DataAccessState.ts",
111
+ "./src/stores/data-access/DataProductAccessInfo.ts",
111
112
  "./src/stores/data-cube/QueryBuilderDataCubeEngine.ts",
112
113
  "./src/stores/data-cube/QueryBuilderDataCubeHelper.ts",
113
114
  "./src/stores/data-cube/QueryBuilderDataCubeViewerState.ts",
@@ -282,6 +283,7 @@
282
283
  "./src/components/lakehouse/IngestionDefinitionArtifactViewer.tsx",
283
284
  "./src/components/lineage/LineageViewer.tsx",
284
285
  "./src/components/lineage/PropertyOwnerNode.tsx",
286
+ "./src/components/result/QueryBuilderDataProductErrorPanel.tsx",
285
287
  "./src/components/result/QueryBuilderResultPanel.tsx",
286
288
  "./src/components/result/tds/QueryBuilderTDSCellSelectionStatsBar.tsx",
287
289
  "./src/components/result/tds/QueryBuilderTDSGridResult.tsx",