@finos/legend-application-query 13.4.3 → 13.4.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. package/lib/components/QueryEditor.d.ts.map +1 -1
  2. package/lib/components/QueryEditor.js +10 -9
  3. package/lib/components/QueryEditor.js.map +1 -1
  4. package/lib/components/__test-utils__/QueryEditorComponentTestUtils.d.ts.map +1 -1
  5. package/lib/components/__test-utils__/QueryEditorComponentTestUtils.js +5 -3
  6. package/lib/components/__test-utils__/QueryEditorComponentTestUtils.js.map +1 -1
  7. package/lib/components/data-space/QueryDataSpaceUtil.d.ts +1 -2
  8. package/lib/components/data-space/QueryDataSpaceUtil.d.ts.map +1 -1
  9. package/lib/components/data-space/QueryDataSpaceUtil.js +3 -4
  10. package/lib/components/data-space/QueryDataSpaceUtil.js.map +1 -1
  11. package/lib/index.css +1 -1
  12. package/lib/package.json +1 -1
  13. package/lib/stores/QueryEditorStore.d.ts +1 -2
  14. package/lib/stores/QueryEditorStore.d.ts.map +1 -1
  15. package/lib/stores/QueryEditorStore.js +107 -95
  16. package/lib/stores/QueryEditorStore.js.map +1 -1
  17. package/lib/stores/data-space/DataSpaceQueryCreatorStore.d.ts.map +1 -1
  18. package/lib/stores/data-space/DataSpaceQueryCreatorStore.js +1 -7
  19. package/lib/stores/data-space/DataSpaceQueryCreatorStore.js.map +1 -1
  20. package/lib/stores/data-space/DataSpaceTemplateQueryCreatorStore.d.ts.map +1 -1
  21. package/lib/stores/data-space/DataSpaceTemplateQueryCreatorStore.js +2 -11
  22. package/lib/stores/data-space/DataSpaceTemplateQueryCreatorStore.js.map +1 -1
  23. package/package.json +5 -5
  24. package/src/components/QueryEditor.tsx +60 -30
  25. package/src/components/__test-utils__/QueryEditorComponentTestUtils.tsx +5 -3
  26. package/src/components/data-space/QueryDataSpaceUtil.ts +7 -7
  27. package/src/stores/QueryEditorStore.ts +190 -169
  28. package/src/stores/data-space/DataSpaceQueryCreatorStore.ts +0 -6
  29. package/src/stores/data-space/DataSpaceTemplateQueryCreatorStore.ts +1 -19
@@ -37,6 +37,7 @@ import {
37
37
  quantifyList,
38
38
  assertNonNullable,
39
39
  returnUndefOnError,
40
+ UnsupportedOperationError,
40
41
  } from '@finos/legend-shared';
41
42
  import {
42
43
  type LightQuery,
@@ -46,6 +47,7 @@ import {
46
47
  type QueryGridConfig,
47
48
  type ValueSpecification,
48
49
  type GraphInitializationReport,
50
+ type PackageableRuntime,
49
51
  GraphManagerState,
50
52
  Query,
51
53
  PureExecution,
@@ -62,7 +64,8 @@ import {
62
64
  reportGraphAnalytics,
63
65
  cloneQueryStereotype,
64
66
  cloneQueryTaggedValue,
65
- type PackageableRuntime,
67
+ QueryDataSpaceExecutionContext,
68
+ QueryExplicitExecutionContext,
66
69
  } from '@finos/legend-graph';
67
70
  import {
68
71
  EXTERNAL_APPLICATION_NAVIGATION__generateStudioProjectViewUrl,
@@ -110,7 +113,6 @@ import {
110
113
  DataSpaceQueryBuilderState,
111
114
  type DataSpaceInfo,
112
115
  } from '@finos/legend-extension-dsl-data-space/application';
113
- import { getDataSpaceQueryInfo } from '../components/data-space/QueryDataSpaceUtil.js';
114
116
  import {
115
117
  DSL_DataSpace_getGraphManagerExtension,
116
118
  type DataSpace,
@@ -427,15 +429,8 @@ export abstract class QueryEditorStore {
427
429
  this.queryBuilderState.executionContextState.mapping,
428
430
  'Query required mapping to update',
429
431
  );
430
- const runtimeValue = guaranteeType(
431
- this.queryBuilderState.executionContextState.runtimeValue,
432
- RuntimePointer,
433
- 'Query runtime must be of type runtime pointer',
434
- );
435
- query.mapping = PackageableElementExplicitReference.create(
436
- this.queryBuilderState.executionContextState.mapping,
437
- );
438
- query.runtime = runtimeValue.packageableRuntime;
432
+ query.executionContext =
433
+ this.queryBuilderState.getQueryExecutionContext();
439
434
  query.content =
440
435
  await this.graphManagerState.graphManager.lambdaToPureCode(rawLambda);
441
436
  config?.decorator?.(query);
@@ -1053,20 +1048,36 @@ export class ExistingQueryUpdateState {
1053
1048
 
1054
1049
  const resolveExecutionContext = (
1055
1050
  dataSpace: DataSpace,
1056
- queryMapping: Mapping,
1057
- queryRuntime: PackageableRuntime,
1051
+ ex: string | undefined,
1052
+ queryMapping: Mapping | undefined,
1053
+ queryRuntime: PackageableRuntime | undefined,
1058
1054
  ): DataSpaceExecutionContext | undefined => {
1055
+ if (!ex) {
1056
+ if (queryMapping && queryRuntime) {
1057
+ if (
1058
+ dataSpace.defaultExecutionContext.mapping.value !== queryMapping &&
1059
+ dataSpace.defaultExecutionContext.defaultRuntime.value.path !==
1060
+ queryRuntime.path
1061
+ ) {
1062
+ const matchingExecContexts = dataSpace.executionContexts.filter(
1063
+ (ec) => ec.mapping.value === queryMapping,
1064
+ );
1065
+ if (matchingExecContexts.length > 1) {
1066
+ const matchRuntime = matchingExecContexts.find(
1067
+ (exec) => exec.defaultRuntime.value.path === queryRuntime.path,
1068
+ );
1069
+ // TODO: we will safely do this for now. Long term we should save exec context key into query store
1070
+ // we should make runtime/mapping optional
1071
+ return matchRuntime ?? matchingExecContexts[0];
1072
+ }
1073
+ return matchingExecContexts[0];
1074
+ }
1075
+ }
1076
+ return dataSpace.defaultExecutionContext;
1077
+ }
1059
1078
  const matchingExecContexts = dataSpace.executionContexts.filter(
1060
- (ec) => ec.mapping.value === queryMapping,
1079
+ (ec) => ec.name === ex,
1061
1080
  );
1062
- if (matchingExecContexts.length > 1) {
1063
- const matchRuntime = matchingExecContexts.find(
1064
- (exec) => exec.defaultRuntime.value.path === queryRuntime.path,
1065
- );
1066
- // TODO: we will safely do this for now. Long term we should save exec context key into query store
1067
- // we should make runtime/mapping optional
1068
- return matchRuntime ?? matchingExecContexts[0];
1069
- }
1070
1081
  return matchingExecContexts[0];
1071
1082
  };
1072
1083
 
@@ -1149,152 +1160,184 @@ export class ExistingQueryEditorStore extends QueryEditorStore {
1149
1160
  );
1150
1161
  }
1151
1162
 
1152
- async buildDataspaceBuilderState(
1153
- query: Query,
1154
- ): Promise<DataSpaceQueryBuilderState | undefined> {
1155
- const dataSpacePath = getDataSpaceQueryInfo(query);
1156
- if (dataSpacePath) {
1163
+ async initQueryBuildStateFromQuery(query: Query): Promise<QueryBuilderState> {
1164
+ const exec = query.executionContext;
1165
+ if (exec instanceof QueryDataSpaceExecutionContext) {
1157
1166
  const dataSpace = getOwnDataSpace(
1158
- dataSpacePath,
1167
+ exec.dataSpacePath,
1159
1168
  this.graphManagerState.graph,
1160
1169
  );
1161
- const mapping = query.mapping.value;
1162
1170
  const matchingExecutionContext = resolveExecutionContext(
1163
1171
  dataSpace,
1164
- mapping,
1165
- query.runtime.value,
1172
+ exec.executionKey,
1173
+ query.mapping?.value,
1174
+ query.runtime?.value,
1166
1175
  );
1167
- if (!matchingExecutionContext) {
1168
- // if a matching execution context is not found, it means this query is not
1169
- // properly created from a data space, therefore, we cannot support this case
1170
- return undefined;
1171
- }
1172
- let dataSpaceAnalysisResult;
1173
- try {
1174
- const project = StoreProjectData.serialization.fromJson(
1175
- await this.depotServerClient.getProject(
1176
- query.groupId,
1177
- query.artifactId,
1178
- ),
1179
- );
1180
- dataSpaceAnalysisResult = await DSL_DataSpace_getGraphManagerExtension(
1181
- this.graphManagerState.graphManager,
1182
- ).retrieveDataSpaceAnalysisFromCache(() =>
1183
- retrieveAnalyticsResultCache(
1184
- project,
1185
- query.versionId,
1186
- dataSpace.path,
1176
+ if (matchingExecutionContext) {
1177
+ let dataSpaceAnalysisResult;
1178
+ try {
1179
+ const project = StoreProjectData.serialization.fromJson(
1180
+ await this.depotServerClient.getProject(
1181
+ query.groupId,
1182
+ query.artifactId,
1183
+ ),
1184
+ );
1185
+ dataSpaceAnalysisResult =
1186
+ await DSL_DataSpace_getGraphManagerExtension(
1187
+ this.graphManagerState.graphManager,
1188
+ ).retrieveDataSpaceAnalysisFromCache(() =>
1189
+ retrieveAnalyticsResultCache(
1190
+ project,
1191
+ query.versionId,
1192
+ dataSpace.path,
1193
+ this.depotServerClient,
1194
+ ),
1195
+ );
1196
+ } catch {
1197
+ // do nothing
1198
+ }
1199
+ const projectInfo = new DataSpaceProjectInfo(
1200
+ query.groupId,
1201
+ query.artifactId,
1202
+ query.versionId,
1203
+ createViewProjectHandler(this.applicationStore),
1204
+ createViewSDLCProjectHandler(
1205
+ this.applicationStore,
1187
1206
  this.depotServerClient,
1188
1207
  ),
1189
1208
  );
1190
- } catch {
1191
- // do nothing
1192
- }
1193
- const projectInfo = new DataSpaceProjectInfo(
1194
- query.groupId,
1195
- query.artifactId,
1196
- query.versionId,
1197
- createViewProjectHandler(this.applicationStore),
1198
- createViewSDLCProjectHandler(
1209
+ const sourceInfo = {
1210
+ groupId: projectInfo.groupId,
1211
+ artifactId: projectInfo.artifactId,
1212
+ versionId: projectInfo.versionId,
1213
+ dataSpace: dataSpace.path,
1214
+ };
1215
+ const dataSpaceQueryBuilderState = new DataSpaceQueryBuilderState(
1199
1216
  this.applicationStore,
1217
+ this.graphManagerState,
1200
1218
  this.depotServerClient,
1201
- ),
1202
- );
1219
+ dataSpace,
1220
+ matchingExecutionContext,
1221
+ (dataSpaceInfo: DataSpaceInfo) => {
1222
+ if (dataSpaceInfo.defaultExecutionContext) {
1223
+ const proceed = (): void =>
1224
+ this.applicationStore.navigationService.navigator.goToLocation(
1225
+ generateDataSpaceQueryCreatorRoute(
1226
+ guaranteeNonNullable(dataSpaceInfo.groupId),
1227
+ guaranteeNonNullable(dataSpaceInfo.artifactId),
1228
+ LATEST_VERSION_ALIAS, //always default to latest
1229
+ dataSpaceInfo.path,
1230
+ guaranteeNonNullable(dataSpaceInfo.defaultExecutionContext),
1231
+ undefined,
1232
+ undefined,
1233
+ ),
1234
+ );
1235
+ const updateQueryAndProceed = async (): Promise<void> => {
1236
+ try {
1237
+ await flowResult(
1238
+ this.updateState.updateQuery(undefined, undefined),
1239
+ );
1240
+ proceed();
1241
+ } catch (error) {
1242
+ assertErrorThrown(error);
1243
+ this.applicationStore.logService.error(
1244
+ LogEvent.create(LEGEND_QUERY_APP_EVENT.GENERIC_FAILURE),
1245
+ error,
1246
+ );
1247
+ this.applicationStore.notificationService.notifyError(error);
1248
+ }
1249
+ };
1250
+ if (
1251
+ !query.isCurrentUserQuery ||
1252
+ !this.queryBuilderState?.changeDetectionState.hasChanged
1253
+ ) {
1254
+ proceed();
1255
+ } else {
1256
+ this.applicationStore.alertService.setActionAlertInfo({
1257
+ message: `To change the data space, you need to save the current query
1258
+ to proceed`,
1259
+ type: ActionAlertType.CAUTION,
1260
+ actions: [
1261
+ {
1262
+ label: 'Save query and Proceed',
1263
+ type: ActionAlertActionType.PROCEED_WITH_CAUTION,
1264
+ handler: () => {
1265
+ updateQueryAndProceed().catch(
1266
+ this.applicationStore.alertUnhandledError,
1267
+ );
1268
+ },
1269
+ },
1270
+ {
1271
+ label: 'Abort',
1272
+ type: ActionAlertActionType.PROCEED,
1273
+ default: true,
1274
+ },
1275
+ ],
1276
+ });
1277
+ }
1278
+ } else {
1279
+ this.applicationStore.notificationService.notifyWarning(
1280
+ `Can't switch data space: default execution context not specified`,
1281
+ );
1282
+ }
1283
+ },
1284
+ true,
1285
+ dataSpaceAnalysisResult,
1286
+ undefined,
1287
+ undefined,
1288
+ undefined,
1289
+ projectInfo,
1290
+ this.applicationStore.config.options.queryBuilderConfig,
1291
+ sourceInfo,
1292
+ );
1293
+ const mappingModelCoverageAnalysisResult =
1294
+ dataSpaceAnalysisResult?.executionContextsIndex.get(
1295
+ matchingExecutionContext.name,
1296
+ )?.mappingModelCoverageAnalysisResult;
1297
+ if (mappingModelCoverageAnalysisResult) {
1298
+ dataSpaceQueryBuilderState.explorerState.mappingModelCoverageAnalysisResult =
1299
+ mappingModelCoverageAnalysisResult;
1300
+ }
1301
+ dataSpaceQueryBuilderState.executionContextState.setMapping(
1302
+ matchingExecutionContext.mapping.value,
1303
+ );
1304
+ dataSpaceQueryBuilderState.executionContextState.setRuntimeValue(
1305
+ new RuntimePointer(
1306
+ PackageableElementExplicitReference.create(
1307
+ matchingExecutionContext.defaultRuntime.value,
1308
+ ),
1309
+ ),
1310
+ );
1311
+ return dataSpaceQueryBuilderState;
1312
+ } else {
1313
+ throw new UnsupportedOperationError(
1314
+ `Unsupported execution context ${exec.executionKey}`,
1315
+ );
1316
+ }
1317
+ } else if (exec instanceof QueryExplicitExecutionContext) {
1318
+ const projectInfo = this.getProjectInfo();
1203
1319
  const sourceInfo = {
1204
1320
  groupId: projectInfo.groupId,
1205
1321
  artifactId: projectInfo.artifactId,
1206
1322
  versionId: projectInfo.versionId,
1207
- dataSpace: dataSpace.path,
1208
1323
  };
1209
- const dataSpaceQueryBuilderState = new DataSpaceQueryBuilderState(
1324
+ const classQueryBuilderState = new ClassQueryBuilderState(
1210
1325
  this.applicationStore,
1211
1326
  this.graphManagerState,
1212
- this.depotServerClient,
1213
- dataSpace,
1214
- matchingExecutionContext,
1215
- (dataSpaceInfo: DataSpaceInfo) => {
1216
- if (dataSpaceInfo.defaultExecutionContext) {
1217
- const proceed = (): void =>
1218
- this.applicationStore.navigationService.navigator.goToLocation(
1219
- generateDataSpaceQueryCreatorRoute(
1220
- guaranteeNonNullable(dataSpaceInfo.groupId),
1221
- guaranteeNonNullable(dataSpaceInfo.artifactId),
1222
- LATEST_VERSION_ALIAS, //always default to latest
1223
- dataSpaceInfo.path,
1224
- guaranteeNonNullable(dataSpaceInfo.defaultExecutionContext),
1225
- undefined,
1226
- undefined,
1227
- ),
1228
- );
1229
- const updateQueryAndProceed = async (): Promise<void> => {
1230
- try {
1231
- await flowResult(
1232
- this.updateState.updateQuery(undefined, undefined),
1233
- );
1234
- proceed();
1235
- } catch (error) {
1236
- assertErrorThrown(error);
1237
- this.applicationStore.logService.error(
1238
- LogEvent.create(LEGEND_QUERY_APP_EVENT.GENERIC_FAILURE),
1239
- error,
1240
- );
1241
- this.applicationStore.notificationService.notifyError(error);
1242
- }
1243
- };
1244
- if (
1245
- !query.isCurrentUserQuery ||
1246
- !this.queryBuilderState?.changeDetectionState.hasChanged
1247
- ) {
1248
- proceed();
1249
- } else {
1250
- this.applicationStore.alertService.setActionAlertInfo({
1251
- message: `To change the data space, you need to save the current query
1252
- to proceed`,
1253
- type: ActionAlertType.CAUTION,
1254
- actions: [
1255
- {
1256
- label: 'Save query and Proceed',
1257
- type: ActionAlertActionType.PROCEED_WITH_CAUTION,
1258
- handler: () => {
1259
- updateQueryAndProceed().catch(
1260
- this.applicationStore.alertUnhandledError,
1261
- );
1262
- },
1263
- },
1264
- {
1265
- label: 'Abort',
1266
- type: ActionAlertActionType.PROCEED,
1267
- default: true,
1268
- },
1269
- ],
1270
- });
1271
- }
1272
- } else {
1273
- this.applicationStore.notificationService.notifyWarning(
1274
- `Can't switch data space: default execution context not specified`,
1275
- );
1276
- }
1277
- },
1278
- true,
1279
- dataSpaceAnalysisResult,
1280
- undefined,
1281
- undefined,
1282
- undefined,
1283
- projectInfo,
1284
1327
  this.applicationStore.config.options.queryBuilderConfig,
1285
1328
  sourceInfo,
1286
1329
  );
1287
- const mappingModelCoverageAnalysisResult =
1288
- dataSpaceAnalysisResult?.executionContextsIndex.get(
1289
- matchingExecutionContext.name,
1290
- )?.mappingModelCoverageAnalysisResult;
1291
- if (mappingModelCoverageAnalysisResult) {
1292
- dataSpaceQueryBuilderState.explorerState.mappingModelCoverageAnalysisResult =
1293
- mappingModelCoverageAnalysisResult;
1294
- }
1295
- return dataSpaceQueryBuilderState;
1330
+ classQueryBuilderState.executionContextState.setMapping(
1331
+ exec.mapping.value,
1332
+ );
1333
+ classQueryBuilderState.executionContextState.setRuntimeValue(
1334
+ new RuntimePointer(
1335
+ PackageableElementExplicitReference.create(exec.runtime.value),
1336
+ ),
1337
+ );
1338
+ return classQueryBuilderState;
1296
1339
  }
1297
- return undefined;
1340
+ throw new UnsupportedOperationError(`Unsupported query execution context`);
1298
1341
  }
1299
1342
 
1300
1343
  async initializeQueryBuilderState(
@@ -1311,30 +1354,8 @@ export class ExistingQueryEditorStore extends QueryEditorStore {
1311
1354
  );
1312
1355
 
1313
1356
  // if no extension found, fall back to basic `class -> mapping -> runtime` mode
1314
- const projectInfo = this.getProjectInfo();
1315
- const sourceInfo = {
1316
- groupId: projectInfo.groupId,
1317
- artifactId: projectInfo.artifactId,
1318
- versionId: projectInfo.versionId,
1319
- };
1320
- let queryBuilderState: QueryBuilderState | undefined =
1321
- await this.buildDataspaceBuilderState(query);
1357
+ const queryBuilderState = await this.initQueryBuildStateFromQuery(query);
1322
1358
 
1323
- queryBuilderState =
1324
- queryBuilderState ??
1325
- new ClassQueryBuilderState(
1326
- this.applicationStore,
1327
- this.graphManagerState,
1328
- this.applicationStore.config.options.queryBuilderConfig,
1329
- sourceInfo,
1330
- );
1331
-
1332
- queryBuilderState.executionContextState.setMapping(query.mapping.value);
1333
- queryBuilderState.executionContextState.setRuntimeValue(
1334
- new RuntimePointer(
1335
- PackageableElementExplicitReference.create(query.runtime.value),
1336
- ),
1337
- );
1338
1359
  // leverage initialization of query builder state to ensure we handle unsupported queries
1339
1360
  let defaultParameters: Map<string, ValueSpecification> | undefined =
1340
1361
  undefined;
@@ -52,7 +52,6 @@ import {
52
52
  DataSpaceProjectInfo,
53
53
  DataSpaceQueryBuilderState,
54
54
  createQueryClassTaggedValue,
55
- createQueryDataSpaceTaggedValue,
56
55
  type DataSpaceInfo,
57
56
  } from '@finos/legend-extension-dsl-data-space/application';
58
57
  import { generateDataSpaceQueryCreatorRoute } from '../../__lib__/DSL_DataSpace_LegendQueryNavigation.js';
@@ -272,13 +271,8 @@ export class DataSpaceQueryCreatorStore extends QueryEditorStore {
272
271
  query.versionId = this.versionId;
273
272
  if (this.queryBuilderState?.class) {
274
273
  query.taggedValues = [
275
- createQueryDataSpaceTaggedValue(this.dataSpacePath),
276
274
  createQueryClassTaggedValue(this.queryBuilderState.class.path),
277
275
  ];
278
- } else {
279
- query.taggedValues = [
280
- createQueryDataSpaceTaggedValue(this.dataSpacePath),
281
- ];
282
276
  }
283
277
  },
284
278
  };
@@ -36,7 +36,6 @@ import type { LegendQueryApplicationStore } from '../LegendQueryBaseStore.js';
36
36
  import {
37
37
  DSL_DataSpace_getGraphManagerExtension,
38
38
  DataSpaceExecutableTemplate,
39
- type DataSpaceExecutionContext,
40
39
  getDataSpace,
41
40
  retrieveAnalyticsResultCache,
42
41
  } from '@finos/legend-extension-dsl-data-space/graph';
@@ -44,10 +43,8 @@ import {
44
43
  DataSpaceProjectInfo,
45
44
  DataSpaceQueryBuilderState,
46
45
  createQueryClassTaggedValue,
47
- createQueryDataSpaceTaggedValue,
48
46
  type DataSpaceInfo,
49
47
  } from '@finos/legend-extension-dsl-data-space/application';
50
- import { generateDataSpaceTemplateQueryCreatorRoute } from '../../__lib__/DSL_DataSpace_LegendQueryNavigation.js';
51
48
 
52
49
  export class DataSpaceTemplateQueryCreatorStore extends QueryEditorStore {
53
50
  readonly groupId: string;
@@ -150,17 +147,7 @@ export class DataSpaceTemplateQueryCreatorStore extends QueryEditorStore {
150
147
  },
151
148
  true,
152
149
  dataSpaceAnalysisResult,
153
- (ec: DataSpaceExecutionContext) => {
154
- this.applicationStore.navigationService.navigator.updateCurrentLocation(
155
- generateDataSpaceTemplateQueryCreatorRoute(
156
- this.groupId,
157
- this.artifactId,
158
- this.versionId,
159
- dataSpace.path,
160
- this.templateQueryId,
161
- ),
162
- );
163
- },
150
+ undefined,
164
151
  undefined,
165
152
  undefined,
166
153
  projectInfo,
@@ -190,13 +177,8 @@ export class DataSpaceTemplateQueryCreatorStore extends QueryEditorStore {
190
177
  query.versionId = this.versionId;
191
178
  if (this.queryBuilderState?.class) {
192
179
  query.taggedValues = [
193
- createQueryDataSpaceTaggedValue(this.dataSpacePath),
194
180
  createQueryClassTaggedValue(this.queryBuilderState.class.path),
195
181
  ];
196
- } else {
197
- query.taggedValues = [
198
- createQueryDataSpaceTaggedValue(this.dataSpacePath),
199
- ];
200
182
  }
201
183
  },
202
184
  };