@finos/legend-application-query 13.8.52 → 13.8.54

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 (127) hide show
  1. package/lib/__lib__/LegendQueryAgentChatTelemetryHelper.d.ts +23 -4
  2. package/lib/__lib__/LegendQueryAgentChatTelemetryHelper.d.ts.map +1 -1
  3. package/lib/__lib__/LegendQueryAgentChatTelemetryHelper.js +15 -10
  4. package/lib/__lib__/LegendQueryAgentChatTelemetryHelper.js.map +1 -1
  5. package/lib/__lib__/LegendQueryEvent.d.ts +19 -0
  6. package/lib/__lib__/LegendQueryEvent.d.ts.map +1 -1
  7. package/lib/__lib__/LegendQueryEvent.js +22 -0
  8. package/lib/__lib__/LegendQueryEvent.js.map +1 -1
  9. package/lib/__lib__/LegendQueryLifecycleTelemetry.d.ts +58 -0
  10. package/lib/__lib__/LegendQueryLifecycleTelemetry.d.ts.map +1 -0
  11. package/lib/__lib__/LegendQueryLifecycleTelemetry.js +90 -0
  12. package/lib/__lib__/LegendQueryLifecycleTelemetry.js.map +1 -0
  13. package/lib/__lib__/LegendQueryNavigation.d.ts +3 -3
  14. package/lib/__lib__/LegendQueryNavigation.d.ts.map +1 -1
  15. package/lib/__lib__/LegendQueryNavigation.js +13 -3
  16. package/lib/__lib__/LegendQueryNavigation.js.map +1 -1
  17. package/lib/__lib__/LegendQuerySourceInfo.d.ts +137 -0
  18. package/lib/__lib__/LegendQuerySourceInfo.d.ts.map +1 -0
  19. package/lib/__lib__/LegendQuerySourceInfo.js +33 -0
  20. package/lib/__lib__/LegendQuerySourceInfo.js.map +1 -0
  21. package/lib/__lib__/LegendQueryTelemetryHelper.d.ts +127 -1
  22. package/lib/__lib__/LegendQueryTelemetryHelper.d.ts.map +1 -1
  23. package/lib/__lib__/LegendQueryTelemetryHelper.js +63 -0
  24. package/lib/__lib__/LegendQueryTelemetryHelper.js.map +1 -1
  25. package/lib/application/LegendQueryApplicationConfig.d.ts +4 -4
  26. package/lib/application/LegendQueryApplicationConfig.d.ts.map +1 -1
  27. package/lib/application/LegendQueryApplicationConfig.js +4 -5
  28. package/lib/application/LegendQueryApplicationConfig.js.map +1 -1
  29. package/lib/components/Core_LegendQueryApplicationPlugin.d.ts.map +1 -1
  30. package/lib/components/Core_LegendQueryApplicationPlugin.js +21 -3
  31. package/lib/components/Core_LegendQueryApplicationPlugin.js.map +1 -1
  32. package/lib/components/QueryEditor.d.ts.map +1 -1
  33. package/lib/components/QueryEditor.js +21 -6
  34. package/lib/components/QueryEditor.js.map +1 -1
  35. package/lib/components/data-space/DataSpaceInfo.js +6 -6
  36. package/lib/components/data-space/DataSpaceInfo.js.map +1 -1
  37. package/lib/components/data-space/DataSpaceQuerySetup.d.ts.map +1 -1
  38. package/lib/components/data-space/DataSpaceQuerySetup.js +19 -0
  39. package/lib/components/data-space/DataSpaceQuerySetup.js.map +1 -1
  40. package/lib/components/data-space/LegendQueryDataSpaceQueryBuilder.d.ts.map +1 -1
  41. package/lib/components/data-space/LegendQueryDataSpaceQueryBuilder.js +19 -0
  42. package/lib/components/data-space/LegendQueryDataSpaceQueryBuilder.js.map +1 -1
  43. package/lib/index.css +1 -1
  44. package/lib/index.d.ts +2 -1
  45. package/lib/index.d.ts.map +1 -1
  46. package/lib/index.js +2 -1
  47. package/lib/index.js.map +1 -1
  48. package/lib/light-mode.css +1 -1
  49. package/lib/package.json +1 -1
  50. package/lib/stores/EditExistingQuerySetupStore.d.ts.map +1 -1
  51. package/lib/stores/EditExistingQuerySetupStore.js +4 -13
  52. package/lib/stores/EditExistingQuerySetupStore.js.map +1 -1
  53. package/lib/stores/LegendQueryApplicationPlugin.d.ts +2 -1
  54. package/lib/stores/LegendQueryApplicationPlugin.d.ts.map +1 -1
  55. package/lib/stores/LegendQueryApplicationPlugin.js +23 -0
  56. package/lib/stores/LegendQueryApplicationPlugin.js.map +1 -1
  57. package/lib/stores/QueryEditorStore.d.ts +50 -2
  58. package/lib/stores/QueryEditorStore.d.ts.map +1 -1
  59. package/lib/stores/QueryEditorStore.js +195 -82
  60. package/lib/stores/QueryEditorStore.js.map +1 -1
  61. package/lib/stores/QueryProductionizerSetupStore.d.ts.map +1 -1
  62. package/lib/stores/QueryProductionizerSetupStore.js +17 -13
  63. package/lib/stores/QueryProductionizerSetupStore.js.map +1 -1
  64. package/lib/stores/QuerySetupStore.d.ts.map +1 -1
  65. package/lib/stores/QuerySetupStore.js +2 -0
  66. package/lib/stores/QuerySetupStore.js.map +1 -1
  67. package/lib/stores/__test-utils__/LegendQueryApplicationTestUtils.d.ts.map +1 -1
  68. package/lib/stores/__test-utils__/LegendQueryApplicationTestUtils.js +0 -3
  69. package/lib/stores/__test-utils__/LegendQueryApplicationTestUtils.js.map +1 -1
  70. package/lib/stores/data-cube/ExistingQueryDataCubeViewer.d.ts.map +1 -1
  71. package/lib/stores/data-cube/ExistingQueryDataCubeViewer.js +1 -0
  72. package/lib/stores/data-cube/ExistingQueryDataCubeViewer.js.map +1 -1
  73. package/lib/stores/data-product/DataProductSampleQueryCreatorStore.d.ts +2 -0
  74. package/lib/stores/data-product/DataProductSampleQueryCreatorStore.d.ts.map +1 -1
  75. package/lib/stores/data-product/DataProductSampleQueryCreatorStore.js +12 -1
  76. package/lib/stores/data-product/DataProductSampleQueryCreatorStore.js.map +1 -1
  77. package/lib/stores/data-space/DataProductQueryCreatorStore.d.ts +10 -0
  78. package/lib/stores/data-space/DataProductQueryCreatorStore.d.ts.map +1 -1
  79. package/lib/stores/data-space/DataProductQueryCreatorStore.js +63 -19
  80. package/lib/stores/data-space/DataProductQueryCreatorStore.js.map +1 -1
  81. package/lib/stores/data-space/DataProductSelectorState.d.ts +4 -2
  82. package/lib/stores/data-space/DataProductSelectorState.d.ts.map +1 -1
  83. package/lib/stores/data-space/DataProductSelectorState.js +30 -9
  84. package/lib/stores/data-space/DataProductSelectorState.js.map +1 -1
  85. package/lib/stores/data-space/DataSpaceQueryBuilderHelper.d.ts.map +1 -1
  86. package/lib/stores/data-space/DataSpaceQueryBuilderHelper.js +5 -1
  87. package/lib/stores/data-space/DataSpaceQueryBuilderHelper.js.map +1 -1
  88. package/lib/stores/data-space/DataSpaceTemplateQueryCreatorStore.d.ts +2 -0
  89. package/lib/stores/data-space/DataSpaceTemplateQueryCreatorStore.d.ts.map +1 -1
  90. package/lib/stores/data-space/DataSpaceTemplateQueryCreatorStore.js +13 -7
  91. package/lib/stores/data-space/DataSpaceTemplateQueryCreatorStore.js.map +1 -1
  92. package/lib/stores/data-space/LegendQueryBareQueryBuilderState.d.ts.map +1 -1
  93. package/lib/stores/data-space/LegendQueryBareQueryBuilderState.js +1 -1
  94. package/lib/stores/data-space/LegendQueryBareQueryBuilderState.js.map +1 -1
  95. package/lib/stores/ingest/IngestQueryCreatorStore.d.ts +2 -0
  96. package/lib/stores/ingest/IngestQueryCreatorStore.d.ts.map +1 -1
  97. package/lib/stores/ingest/IngestQueryCreatorStore.js +10 -3
  98. package/lib/stores/ingest/IngestQueryCreatorStore.js.map +1 -1
  99. package/package.json +13 -13
  100. package/src/__lib__/LegendQueryAgentChatTelemetryHelper.ts +66 -10
  101. package/src/__lib__/LegendQueryEvent.ts +25 -0
  102. package/src/__lib__/LegendQueryLifecycleTelemetry.ts +132 -0
  103. package/src/__lib__/LegendQueryNavigation.ts +24 -5
  104. package/src/__lib__/LegendQuerySourceInfo.ts +162 -0
  105. package/src/__lib__/LegendQueryTelemetryHelper.ts +277 -1
  106. package/src/application/LegendQueryApplicationConfig.ts +12 -12
  107. package/src/components/Core_LegendQueryApplicationPlugin.tsx +47 -4
  108. package/src/components/QueryEditor.tsx +30 -2
  109. package/src/components/data-space/DataSpaceInfo.tsx +8 -8
  110. package/src/components/data-space/DataSpaceQuerySetup.tsx +25 -0
  111. package/src/components/data-space/LegendQueryDataSpaceQueryBuilder.tsx +25 -0
  112. package/src/index.ts +6 -1
  113. package/src/stores/EditExistingQuerySetupStore.ts +8 -20
  114. package/src/stores/LegendQueryApplicationPlugin.tsx +38 -0
  115. package/src/stores/QueryEditorStore.ts +269 -95
  116. package/src/stores/QueryProductionizerSetupStore.ts +24 -20
  117. package/src/stores/QuerySetupStore.ts +3 -0
  118. package/src/stores/__test-utils__/LegendQueryApplicationTestUtils.ts +0 -3
  119. package/src/stores/data-cube/ExistingQueryDataCubeViewer.ts +1 -0
  120. package/src/stores/data-product/DataProductSampleQueryCreatorStore.ts +17 -0
  121. package/src/stores/data-space/DataProductQueryCreatorStore.ts +99 -33
  122. package/src/stores/data-space/DataProductSelectorState.ts +58 -13
  123. package/src/stores/data-space/DataSpaceQueryBuilderHelper.ts +6 -1
  124. package/src/stores/data-space/DataSpaceTemplateQueryCreatorStore.ts +17 -6
  125. package/src/stores/data-space/LegendQueryBareQueryBuilderState.ts +5 -1
  126. package/src/stores/ingest/IngestQueryCreatorStore.ts +16 -5
  127. package/tsconfig.json +2 -0
@@ -15,14 +15,17 @@
15
15
  */
16
16
 
17
17
  import type { TelemetryService } from '@finos/legend-application';
18
+ import type { TelemetryErrorFields, TimingsRecord } from '@finos/legend-shared';
18
19
  import { LEGEND_QUERY_APP_EVENT } from './LegendQueryEvent.js';
20
+ import type { QueryableSourceInfo } from '@finos/legend-storage';
21
+ import type { QueryBuilderTelemetryContext } from '@finos/legend-query-builder';
19
22
  import {
20
23
  type GraphManagerOperationReport,
21
24
  GRAPH_MANAGER_EVENT,
22
25
  type GraphInitializationReport,
23
26
  } from '@finos/legend-graph';
24
27
 
25
- type Query_TelemetryData = {
28
+ export type Query_TelemetryData = {
26
29
  query: {
27
30
  name: string;
28
31
  id: string;
@@ -46,6 +49,129 @@ type IntializeQueryState_TelemetryData = Query_TelemetryData &
46
49
  dependenciesCount: number;
47
50
  };
48
51
 
52
+ /**
53
+ * Where the query creator was started from, returned by each creator store's
54
+ * `getInitializeTelemetrySource()`.
55
+ *
56
+ * The entry point the query creator was started from ({@link
57
+ * LegendQuerySourceInfo}) is spread FLAT into this payload, matching how
58
+ * `sourceInfo` is reported on every other query telemetry event.
59
+ *
60
+ * The index signature is what allows those flat keys — they vary by entry point
61
+ * and `LegendQuerySourceInfo` is a union, so they cannot be enumerated here.
62
+ * The union stays strictly typed where it is built, in each creator store's
63
+ * `getSourceInfo()` override.
64
+ */
65
+ export type InitializeTelemetrySource = Record<PropertyKey, unknown> & {
66
+ /**
67
+ * Whether the most recently visited source was reopened, rather than the
68
+ * source being specified by the route
69
+ */
70
+ restoredFromRecent: boolean;
71
+ };
72
+
73
+ /**
74
+ * Base payload for the query creator failure event.
75
+ *
76
+ * There is no success counterpart: a successful load is reported by
77
+ * `query-builder.opened` from `legend-query-builder`, which fires for every
78
+ * route rather than creators only. This one survives because when a load fails
79
+ * there is no query builder to emit from, so it is the only record that an
80
+ * attempt happened.
81
+ */
82
+ export type InitializeQueryCreator_TelemetryData = InitializeTelemetrySource & {
83
+ timings: TimingsRecord;
84
+ };
85
+
86
+ export type InitializeQueryCreatorFailure_TelemetryData =
87
+ InitializeQueryCreator_TelemetryData & TelemetryErrorFields;
88
+
89
+ /**
90
+ * The query a lifecycle event acted on. `id` is always known for update, rename
91
+ * and delete — they act on a query that already exists. Identity beyond the id
92
+ * is partial: a delete resolves the entry from the loaded list, which may not
93
+ * contain it.
94
+ */
95
+ export type PartialQuery_TelemetryData = {
96
+ query: {
97
+ id: string;
98
+ name?: string | undefined;
99
+ versionId?: string | undefined;
100
+ groupId?: string | undefined;
101
+ artifactId?: string | undefined;
102
+ };
103
+ };
104
+
105
+ /**
106
+ * Payload for a failed *create*.
107
+ *
108
+ * Deliberately has no `query` block: the server assigns the id, and a failed
109
+ * create never got that far, so no query exists to identify. The name the user
110
+ * chose is the only identity there is. Keeping this a separate type from
111
+ * {@link QueryLifecycleFailure_TelemetryData} means the three events that *do*
112
+ * always have an id cannot accidentally omit it.
113
+ */
114
+ export type QueryCreateFailure_TelemetryData = {
115
+ queryName: string;
116
+ } & TelemetryErrorFields;
117
+
118
+ /**
119
+ * Payload for a failed update, rename or delete — actions on a query that
120
+ * already exists, so `query.id` is always present.
121
+ */
122
+ export type QueryLifecycleFailure_TelemetryData = PartialQuery_TelemetryData &
123
+ TelemetryErrorFields;
124
+
125
+ /**
126
+ * Payload for a failure during the existing-query load flow (graph build,
127
+ * query state init, viewer load).
128
+ *
129
+ * The query being loaded is identified by its route id — the full identity
130
+ * (`name`, `groupId`, ...) is only known once the query resolves, which by
131
+ * definition may not have happened when these failures fire. `queryId` is
132
+ * therefore the only guaranteed field; anything else that happens to be
133
+ * resolved is merged in via {@link PartialQuery_TelemetryData}.
134
+ */
135
+ export type QueryLoadFailure_TelemetryData = {
136
+ queryId: string;
137
+ } & Partial<PartialQuery_TelemetryData> &
138
+ TelemetryErrorFields;
139
+
140
+ /**
141
+ * Payload for an in-session data-space or data-product switch made from the
142
+ * query-builder setup panel.
143
+ *
144
+ * `sourceInfo` (the query builder's source info at the moment the switch is
145
+ * made — i.e. what the user is switching *from*) is spread FLAT into the
146
+ * payload, matching how every other query telemetry event reports
147
+ * `sourceInfo`. It is typed as {@link QueryableSourceInfo} rather than
148
+ * `LegendQuerySourceInfo` because it comes off the query builder state
149
+ * (which types it generically) even though at runtime it is always a
150
+ * `LegendQuerySourceInfo` produced by an editor store's `getSourceInfo()`.
151
+ *
152
+ * `to` is the GAV + element path of the target selection: the group,
153
+ * artifact and version the data space / data product lives in, and its
154
+ * element path. A missing GAV (rare, but the `origin` field on
155
+ * `DepotEntityWithOrigin` is optional) is reported as `undefined` rather than
156
+ * omitted, so dashboards can distinguish "no origin" from "field absent".
157
+ */
158
+ export type ChangeDataSpaceOrProduct_TelemetryData = {
159
+ sourceInfo?: QueryableSourceInfo | undefined;
160
+ to: {
161
+ groupId: string | undefined;
162
+ artifactId: string | undefined;
163
+ versionId: string | undefined;
164
+ path: string;
165
+ };
166
+ };
167
+
168
+ const flattenChangeDataSpaceOrProductSourceInfo = (
169
+ data: ChangeDataSpaceOrProduct_TelemetryData,
170
+ ): Record<string, unknown> => {
171
+ const { sourceInfo, ...rest } = data;
172
+ return { ...rest, ...(sourceInfo ?? {}) };
173
+ };
174
+
49
175
  export class LegendQueryTelemetryHelper {
50
176
  static logEvent_ViewQuerySucceeded(
51
177
  service: TelemetryService,
@@ -64,6 +190,16 @@ export class LegendQueryTelemetryHelper {
64
190
  );
65
191
  }
66
192
 
193
+ static logEvent_InitializeQueryCreatorFailed(
194
+ service: TelemetryService,
195
+ data: InitializeQueryCreatorFailure_TelemetryData,
196
+ ): void {
197
+ service.logEvent(
198
+ LEGEND_QUERY_APP_EVENT.INITIALIZE_QUERY_CREATOR__FAILURE,
199
+ data,
200
+ );
201
+ }
202
+
67
203
  static logEvent_CreateQuerySucceeded(
68
204
  service: TelemetryService,
69
205
  data: Query_TelemetryData,
@@ -95,6 +231,57 @@ export class LegendQueryTelemetryHelper {
95
231
  service.logEvent(LEGEND_QUERY_APP_EVENT.VIEW_SDLC_PROJECT__LAUNCH, {});
96
232
  }
97
233
 
234
+ // ── Query builder Help-menu items injected by Legend Query ───────────────
235
+ //
236
+ // Each takes the shared query builder telemetry envelope (source info flat +
237
+ // `state` nested), pulled from `queryBuilderState.safeGetTelemetryContext()`
238
+ // at the callsite.
239
+
240
+ static logEvent_AboutQueryInfoLaunched(
241
+ service: TelemetryService,
242
+ data: QueryBuilderTelemetryContext,
243
+ ): void {
244
+ service.logEvent(LEGEND_QUERY_APP_EVENT.ABOUT_QUERY_INFO__LAUNCH, data);
245
+ }
246
+
247
+ static logEvent_QueryVersionHistoryLaunched(
248
+ service: TelemetryService,
249
+ data: QueryBuilderTelemetryContext,
250
+ ): void {
251
+ service.logEvent(
252
+ LEGEND_QUERY_APP_EVENT.QUERY_VERSION_HISTORY__LAUNCH,
253
+ data,
254
+ );
255
+ }
256
+
257
+ static logEvent_AboutLegendQueryLaunched(
258
+ service: TelemetryService,
259
+ data: QueryBuilderTelemetryContext,
260
+ ): void {
261
+ service.logEvent(LEGEND_QUERY_APP_EVENT.ABOUT_LEGEND_QUERY__LAUNCH, data);
262
+ }
263
+
264
+ static logEvent_AboutDataSpaceLaunched(
265
+ service: TelemetryService,
266
+ data: QueryBuilderTelemetryContext,
267
+ ): void {
268
+ service.logEvent(LEGEND_QUERY_APP_EVENT.ABOUT_DATA_SPACE__LAUNCH, data);
269
+ }
270
+
271
+ static logEvent_AboutDataProductLaunched(
272
+ service: TelemetryService,
273
+ data: QueryBuilderTelemetryContext,
274
+ ): void {
275
+ service.logEvent(LEGEND_QUERY_APP_EVENT.ABOUT_DATA_PRODUCT__LAUNCH, data);
276
+ }
277
+
278
+ static logEvent_AboutIngestLaunched(
279
+ service: TelemetryService,
280
+ data: QueryBuilderTelemetryContext,
281
+ ): void {
282
+ service.logEvent(LEGEND_QUERY_APP_EVENT.ABOUT_INGEST__LAUNCH, data);
283
+ }
284
+
98
285
  static logEvent_GraphInitializationSucceeded(
99
286
  service: TelemetryService,
100
287
  data: QueryGraphInitialization_TelemetryData | GraphInitializationReport,
@@ -109,6 +296,75 @@ export class LegendQueryTelemetryHelper {
109
296
  service.logEvent(LEGEND_QUERY_APP_EVENT.RENAME_QUERY__SUCCESS, data);
110
297
  }
111
298
 
299
+ static logEvent_DeleteQuerySucceeded(
300
+ service: TelemetryService,
301
+ data: PartialQuery_TelemetryData,
302
+ ): void {
303
+ service.logEvent(LEGEND_QUERY_APP_EVENT.DELETE_QUERY__SUCCESS, data);
304
+ }
305
+
306
+ static logEvent_CreateQueryFailed(
307
+ service: TelemetryService,
308
+ data: QueryCreateFailure_TelemetryData,
309
+ ): void {
310
+ service.logEvent(LEGEND_QUERY_APP_EVENT.CREATE_QUERY__FAILURE, data);
311
+ }
312
+
313
+ static logEvent_UpdateQueryFailed(
314
+ service: TelemetryService,
315
+ data: QueryLifecycleFailure_TelemetryData,
316
+ ): void {
317
+ service.logEvent(LEGEND_QUERY_APP_EVENT.UPDATE_QUERY__FAILURE, data);
318
+ }
319
+
320
+ static logEvent_RenameQueryFailed(
321
+ service: TelemetryService,
322
+ data: QueryLifecycleFailure_TelemetryData,
323
+ ): void {
324
+ service.logEvent(LEGEND_QUERY_APP_EVENT.RENAME_QUERY__FAILURE, data);
325
+ }
326
+
327
+ static logEvent_DeleteQueryFailed(
328
+ service: TelemetryService,
329
+ data: QueryLifecycleFailure_TelemetryData,
330
+ ): void {
331
+ service.logEvent(LEGEND_QUERY_APP_EVENT.DELETE_QUERY__FAILURE, data);
332
+ }
333
+
334
+ static logEvent_ViewQueryFailed(
335
+ service: TelemetryService,
336
+ data: QueryLoadFailure_TelemetryData,
337
+ ): void {
338
+ service.logEvent(LEGEND_QUERY_APP_EVENT.VIEW_QUERY__FAILURE, data);
339
+ }
340
+
341
+ static logEvent_InitializeQueryStateFailed(
342
+ service: TelemetryService,
343
+ data: QueryLoadFailure_TelemetryData,
344
+ ): void {
345
+ service.logEvent(
346
+ LEGEND_QUERY_APP_EVENT.INITIALIZE_QUERY_STATE__FAILURE,
347
+ data,
348
+ );
349
+ }
350
+
351
+ static logEvent_GraphInitializationFailed(
352
+ service: TelemetryService,
353
+ data: TelemetryErrorFields & Partial<PartialQuery_TelemetryData>,
354
+ ): void {
355
+ service.logEvent(
356
+ LEGEND_QUERY_APP_EVENT.GRAPH_INITIALIZATION__FAILURE,
357
+ data,
358
+ );
359
+ }
360
+
361
+ static logEvent_ProductionizeQueryLaunched(
362
+ service: TelemetryService,
363
+ data: PartialQuery_TelemetryData,
364
+ ): void {
365
+ service.logEvent(LEGEND_QUERY_APP_EVENT.PRODUCTIONIZE_QUERY__LAUNCH, data);
366
+ }
367
+
112
368
  static logEvent_QueryAISuggestLaunched(service: TelemetryService): void {
113
369
  service.logEvent(LEGEND_QUERY_APP_EVENT.LEGENDAI_QUERY_SUGGEST__LAUNCH, {});
114
370
  }
@@ -132,4 +388,24 @@ export class LegendQueryTelemetryHelper {
132
388
  errorMessage,
133
389
  });
134
390
  }
391
+
392
+ static logEvent_ChangeDataSpace(
393
+ service: TelemetryService,
394
+ data: ChangeDataSpaceOrProduct_TelemetryData,
395
+ ): void {
396
+ service.logEvent(
397
+ LEGEND_QUERY_APP_EVENT.CHANGE_DATA_SPACE,
398
+ flattenChangeDataSpaceOrProductSourceInfo(data),
399
+ );
400
+ }
401
+
402
+ static logEvent_ChangeDataProduct(
403
+ service: TelemetryService,
404
+ data: ChangeDataSpaceOrProduct_TelemetryData,
405
+ ): void {
406
+ service.logEvent(
407
+ LEGEND_QUERY_APP_EVENT.CHANGE_DATA_PRODUCT,
408
+ flattenChangeDataSpaceOrProductSourceInfo(data),
409
+ );
410
+ }
135
411
  }
@@ -142,13 +142,15 @@ export interface LegendQueryApplicationConfigurationData
142
142
  depot: {
143
143
  url: string;
144
144
  };
145
- engine: { url: string; queryUrl?: string };
146
- studio: {
145
+ engine: {
147
146
  url: string;
148
- instances: LegendStudioApplicationInstanceConfigurationData[];
147
+ queryUrl?: string;
148
+ useCookieAuthOnly?: boolean;
149
+ queryClientName?: string;
149
150
  };
150
- taxonomy?: {
151
+ studio: {
151
152
  url: string;
153
+ instances: LegendStudioApplicationInstanceConfigurationData[];
152
154
  };
153
155
  dataCube?: {
154
156
  url: string;
@@ -171,9 +173,10 @@ export class LegendQueryApplicationConfig extends LegendApplicationConfig {
171
173
 
172
174
  readonly engineServerUrl: string;
173
175
  readonly engineQueryServerUrl?: string | undefined;
176
+ readonly engineUseCookieAuthOnly: boolean;
177
+ readonly engineQueryClientName?: string | undefined;
174
178
  readonly depotServerUrl: string;
175
179
  readonly studioApplicationUrl: string;
176
- readonly taxonomyApplicationUrl?: string;
177
180
  readonly dataCubeApplicationUrl?: string;
178
181
  readonly marketplaceApplicationUrl?: string;
179
182
  readonly marketplaceProductionParallelUrl?: string;
@@ -204,6 +207,10 @@ export class LegendQueryApplicationConfig extends LegendApplicationConfig {
204
207
  input.configData.engine.queryUrl,
205
208
  )
206
209
  : undefined;
210
+ this.engineUseCookieAuthOnly = Boolean(
211
+ input.configData.engine.useCookieAuthOnly,
212
+ );
213
+ this.engineQueryClientName = input.configData.engine.queryClientName;
207
214
 
208
215
  // depot
209
216
  assertNonNullable(
@@ -233,13 +240,6 @@ export class LegendQueryApplicationConfig extends LegendApplicationConfig {
233
240
  `Can't configure application: 'studio.instances' field is missing`,
234
241
  );
235
242
 
236
- // taxonomy
237
- if (input.configData.taxonomy?.url) {
238
- this.taxonomyApplicationUrl = LegendApplicationConfig.resolveAbsoluteUrl(
239
- input.configData.taxonomy.url,
240
- );
241
- }
242
-
243
243
  // datacube
244
244
  if (input.configData.dataCube?.url) {
245
245
  this.dataCubeApplicationUrl = LegendApplicationConfig.resolveAbsoluteUrl(
@@ -141,6 +141,19 @@ import { LegendQueryDataProductQueryBuilderState } from '../stores/data-product/
141
141
  import { IngestLegendQueryBuilderState } from '../stores/ingest/IngestLegendQueryBuilderState.js';
142
142
  import { renderDataProductSampleQueryPanelContent } from './data-product/DataProductSampleQueryPanel.js';
143
143
 
144
+ const isDataProductOrIngestQuery = (
145
+ queryBuilderState: QueryBuilderState,
146
+ ): boolean =>
147
+ queryBuilderState instanceof DataProductQueryBuilderState ||
148
+ queryBuilderState instanceof IngestLegendQueryBuilderState;
149
+
150
+ const getUnsupportedExportActionMessage = (
151
+ queryBuilderState: QueryBuilderState,
152
+ ): string =>
153
+ isDataProductOrIngestQuery(queryBuilderState)
154
+ ? 'Not supported for Data Product or Ingest queries'
155
+ : 'Requires saved query';
156
+
144
157
  export const QUERY_DATACUBE_USAGE_TITLE = 'Legend DataCube';
145
158
  const QUERY_DATACUBE_SOURCE_TYPE = 'legendQuery';
146
159
 
@@ -387,6 +400,9 @@ export class Core_LegendQueryApplicationPlugin extends LegendQueryApplicationPlu
387
400
  title: 'Promote Curated Template query...',
388
401
  label: 'Curated Template Query',
389
402
  disableFunc: (queryBuilderState): boolean => {
403
+ if (isDataProductOrIngestQuery(queryBuilderState)) {
404
+ return true;
405
+ }
390
406
  if (
391
407
  queryBuilderState.workflowState.actionConfig instanceof
392
408
  QueryBuilderActionConfig_QueryApplication
@@ -463,13 +479,16 @@ export class Core_LegendQueryApplicationPlugin extends LegendQueryApplicationPlu
463
479
  }
464
480
  },
465
481
  icon: <ArrowCircleUpIcon />,
466
- disableMessage: 'Requires saved query',
482
+ getDisableMessage: getUnsupportedExportActionMessage,
467
483
  },
468
484
  {
469
485
  key: 'legend-datacube-query',
470
486
  title: 'Launch Legend DataCube...',
471
487
  label: 'Legend DataCube',
472
488
  disableFunc: (queryBuilderState): boolean => {
489
+ if (isDataProductOrIngestQuery(queryBuilderState)) {
490
+ return true;
491
+ }
473
492
  if (
474
493
  queryBuilderState.workflowState.actionConfig instanceof
475
494
  QueryBuilderActionConfig_QueryApplication
@@ -515,7 +534,7 @@ export class Core_LegendQueryApplicationPlugin extends LegendQueryApplicationPlu
515
534
  }
516
535
  },
517
536
  icon: <CubeIcon />,
518
- disableMessage: 'Requires saved query',
537
+ getDisableMessage: getUnsupportedExportActionMessage,
519
538
  },
520
539
  ];
521
540
  }
@@ -547,6 +566,10 @@ export class Core_LegendQueryApplicationPlugin extends LegendQueryApplicationPlu
547
566
  const editorStore =
548
567
  queryBuilderState.workflowState.actionConfig.editorStore;
549
568
  if (editorStore instanceof ExistingQueryEditorStore) {
569
+ LegendQueryTelemetryHelper.logEvent_AboutQueryInfoLaunched(
570
+ editorStore.applicationStore.telemetryService,
571
+ queryBuilderState.safeGetTelemetryContext(),
572
+ );
550
573
  editorStore.updateState.setShowQueryInfo(true);
551
574
  }
552
575
  }
@@ -577,6 +600,10 @@ export class Core_LegendQueryApplicationPlugin extends LegendQueryApplicationPlu
577
600
  const editorStore =
578
601
  queryBuilderState.workflowState.actionConfig.editorStore;
579
602
  if (editorStore instanceof ExistingQueryEditorStore) {
603
+ LegendQueryTelemetryHelper.logEvent_QueryVersionHistoryLaunched(
604
+ editorStore.applicationStore.telemetryService,
605
+ queryBuilderState.safeGetTelemetryContext(),
606
+ );
580
607
  editorStore.showQueryVersionHistory();
581
608
  }
582
609
  }
@@ -635,6 +662,10 @@ export class Core_LegendQueryApplicationPlugin extends LegendQueryApplicationPlu
635
662
  ) {
636
663
  const editorStore =
637
664
  queryBuilderState.workflowState.actionConfig.editorStore;
665
+ LegendQueryTelemetryHelper.logEvent_AboutLegendQueryLaunched(
666
+ editorStore.applicationStore.telemetryService,
667
+ queryBuilderState.safeGetTelemetryContext(),
668
+ );
638
669
  editorStore.setShowAppInfo(true);
639
670
  }
640
671
  },
@@ -663,6 +694,10 @@ export class Core_LegendQueryApplicationPlugin extends LegendQueryApplicationPlu
663
694
  const editorStore =
664
695
  queryBuilderState.workflowState.actionConfig.editorStore;
665
696
  if (queryBuilderState instanceof DataSpaceQueryBuilderState) {
697
+ LegendQueryTelemetryHelper.logEvent_AboutDataSpaceLaunched(
698
+ editorStore.applicationStore.telemetryService,
699
+ queryBuilderState.safeGetTelemetryContext(),
700
+ );
666
701
  editorStore.setShowDataspaceInfo(true);
667
702
  }
668
703
  }
@@ -692,6 +727,10 @@ export class Core_LegendQueryApplicationPlugin extends LegendQueryApplicationPlu
692
727
  const editorStore =
693
728
  queryBuilderState.workflowState.actionConfig.editorStore;
694
729
  if (queryBuilderState instanceof DataProductQueryBuilderState) {
730
+ LegendQueryTelemetryHelper.logEvent_AboutDataProductLaunched(
731
+ editorStore.applicationStore.telemetryService,
732
+ queryBuilderState.safeGetTelemetryContext(),
733
+ );
695
734
  editorStore.setShowDataProductInfo(true);
696
735
  }
697
736
  }
@@ -710,9 +749,13 @@ export class Core_LegendQueryApplicationPlugin extends LegendQueryApplicationPlu
710
749
  QueryBuilderActionConfig_QueryApplication &&
711
750
  queryBuilderState instanceof IngestLegendQueryBuilderState
712
751
  ) {
713
- queryBuilderState.workflowState.actionConfig.editorStore.setShowIngestInfo(
714
- true,
752
+ const editorStore =
753
+ queryBuilderState.workflowState.actionConfig.editorStore;
754
+ LegendQueryTelemetryHelper.logEvent_AboutIngestLaunched(
755
+ editorStore.applicationStore.telemetryService,
756
+ queryBuilderState.safeGetTelemetryContext(),
715
757
  );
758
+ editorStore.setShowIngestInfo(true);
716
759
  }
717
760
  },
718
761
  icon: <InfoCircleIcon />,
@@ -99,6 +99,7 @@ import {
99
99
  HttpStatus,
100
100
  isValidUrl,
101
101
  NetworkClientError,
102
+ StopWatch,
102
103
  } from '@finos/legend-shared';
103
104
  import { DSL_DATA_SPACE_LEGEND_QUERY_DOCUMENTATION_KEY } from '../__lib__/DSL_DataSpace_LegendQueryDocumentation.js';
104
105
  import { LegendQueryInfo } from './LegendQueryAppInfo.js';
@@ -188,22 +189,33 @@ const CreateQueryDialog = observer(() => {
188
189
  if (!aiSuggester || !editorStore.queryBuilderState || !legendAIUrl) {
189
190
  return;
190
191
  }
192
+ const sourceInfo = editorStore.getSourceInfo();
191
193
  LegendQueryAgentChatTelemetryHelper.logEvent_QueryAISuggestLaunched(
192
194
  applicationStore.telemetryService,
195
+ { sourceInfo },
193
196
  );
194
197
  setIsSuggestingWithAI(true);
195
198
  setAISuggestion(undefined);
199
+ const stopWatch = new StopWatch();
196
200
  try {
197
201
  const request = await buildAISuggestionRequest(
198
202
  editorStore.queryBuilderState,
199
203
  );
200
204
  const suggestion = await aiSuggester(request, legendAIUrl);
201
205
  setAISuggestion(suggestion);
206
+ LegendQueryAgentChatTelemetryHelper.logEvent_QueryAISuggestSucceeded(
207
+ applicationStore.telemetryService,
208
+ { sourceInfo, durationMs: stopWatch.elapsed },
209
+ );
202
210
  } catch (error) {
203
211
  assertErrorThrown(error);
204
212
  LegendQueryAgentChatTelemetryHelper.logEvent_QueryAISuggestFailure(
205
213
  applicationStore.telemetryService,
206
- error.message,
214
+ {
215
+ sourceInfo,
216
+ durationMs: stopWatch.elapsed,
217
+ errorMessage: error.message,
218
+ },
207
219
  );
208
220
  if (
209
221
  error instanceof NetworkClientError &&
@@ -228,6 +240,7 @@ const CreateQueryDialog = observer(() => {
228
240
  }
229
241
  LegendQueryAgentChatTelemetryHelper.logEvent_QueryAISuggestApplied(
230
242
  applicationStore.telemetryService,
243
+ { sourceInfo: editorStore.getSourceInfo() },
231
244
  );
232
245
  createQueryState.setQueryName(aiSuggestion.title);
233
246
  createQueryState.setQueryDescription(aiSuggestion.description);
@@ -236,6 +249,7 @@ const CreateQueryDialog = observer(() => {
236
249
  const discardAISuggestion = (): void => {
237
250
  LegendQueryAgentChatTelemetryHelper.logEvent_QueryAISuggestDiscarded(
238
251
  applicationStore.telemetryService,
252
+ { sourceInfo: editorStore.getSourceInfo() },
239
253
  );
240
254
  setAISuggestion(undefined);
241
255
  };
@@ -510,8 +524,14 @@ const RenameQueryDialog = observer(
510
524
  ) {
511
525
  return;
512
526
  }
527
+ const sourceInfo = existingEditorStore.getSourceInfo();
528
+ LegendQueryAgentChatTelemetryHelper.logEvent_QueryAISuggestLaunched(
529
+ applicationStore.telemetryService,
530
+ { sourceInfo },
531
+ );
513
532
  setIsSuggestingWithAI(true);
514
533
  setAISuggestion(undefined);
534
+ const stopWatch = new StopWatch();
515
535
  try {
516
536
  const request = await buildAISuggestionRequest(
517
537
  existingEditorStore.queryBuilderState,
@@ -519,11 +539,19 @@ const RenameQueryDialog = observer(
519
539
  );
520
540
  const suggestion = await aiSuggester(request, legendAIUrl);
521
541
  setAISuggestion(suggestion);
542
+ LegendQueryAgentChatTelemetryHelper.logEvent_QueryAISuggestSucceeded(
543
+ applicationStore.telemetryService,
544
+ { sourceInfo, durationMs: stopWatch.elapsed },
545
+ );
522
546
  } catch (error) {
523
547
  assertErrorThrown(error);
524
548
  LegendQueryAgentChatTelemetryHelper.logEvent_QueryAISuggestFailure(
525
549
  applicationStore.telemetryService,
526
- error.message,
550
+ {
551
+ sourceInfo,
552
+ durationMs: stopWatch.elapsed,
553
+ errorMessage: error.message,
554
+ },
527
555
  );
528
556
  if (
529
557
  error instanceof NetworkClientError &&
@@ -34,8 +34,8 @@ import {
34
34
  DataSpaceSupportEmail,
35
35
  } from '@finos/legend-extension-dsl-data-space/graph';
36
36
  import {
37
+ EXTERNAL_APPLICATION_NAVIGATION__generateMarketplaceDataspaceViewUrl,
37
38
  EXTERNAL_APPLICATION_NAVIGATION__generateStudioSDLCProjectViewUrl,
38
- EXTERNAL_APPLICATION_NAVIGATION__generateTaxonomyDataspaceViewUrl,
39
39
  } from '../../__lib__/LegendQueryNavigation.js';
40
40
  import { flowResult } from 'mobx';
41
41
  import { assertErrorThrown, guaranteeType } from '@finos/legend-shared';
@@ -134,14 +134,14 @@ export const QueryEditorDataspaceInfoModal = observer(
134
134
  const storePath =
135
135
  connection?.store?.value.path ?? dataSpaceMedata?.storePath;
136
136
 
137
- const openInTaxonomy = (): void => {
137
+ const openInMarketplace = (): void => {
138
138
  if (
139
139
  projectInfo &&
140
- editorStore.applicationStore.config.taxonomyApplicationUrl
140
+ editorStore.applicationStore.config.marketplaceApplicationUrl
141
141
  ) {
142
142
  editorStore.applicationStore.navigationService.navigator.visitAddress(
143
- EXTERNAL_APPLICATION_NAVIGATION__generateTaxonomyDataspaceViewUrl(
144
- editorStore.applicationStore.config.taxonomyApplicationUrl,
143
+ EXTERNAL_APPLICATION_NAVIGATION__generateMarketplaceDataspaceViewUrl(
144
+ editorStore.applicationStore.config.marketplaceApplicationUrl,
145
145
  projectInfo.groupId,
146
146
  projectInfo.artifactId,
147
147
  projectInfo.versionId,
@@ -176,11 +176,11 @@ export const QueryEditorDataspaceInfoModal = observer(
176
176
  title="Close"
177
177
  disabled={
178
178
  !(
179
- editorStore.applicationStore.config.taxonomyApplicationUrl &&
180
- projectInfo
179
+ editorStore.applicationStore.config
180
+ .marketplaceApplicationUrl && projectInfo
181
181
  )
182
182
  }
183
- onClick={openInTaxonomy}
183
+ onClick={openInMarketplace}
184
184
  >
185
185
  Open Data Space
186
186
  </button>
@@ -38,6 +38,7 @@ import type {
38
38
  } from '../../stores/data-space/DataProductSelectorState.js';
39
39
  import { flowResult } from 'mobx';
40
40
  import { DepotEntityWithOrigin } from '@finos/legend-storage';
41
+ import { LegendQueryTelemetryHelper } from '../../__lib__/LegendQueryTelemetryHelper.js';
41
42
 
42
43
  // Custom format function to handle both DataSpace and DataProduct options
43
44
  const formatDataSpaceOrProductOptionLabel = (
@@ -90,8 +91,32 @@ const DataProductQuerySetupSetupPanelContent = observer(
90
91
  queryBuilderState.queryAgentChatState?.abort();
91
92
  const value = option?.value;
92
93
  if (value instanceof ResolvedDataSpaceEntityWithOrigin) {
94
+ LegendQueryTelemetryHelper.logEvent_ChangeDataSpace(
95
+ applicationStore.telemetryService,
96
+ {
97
+ sourceInfo: queryBuilderState.sourceInfo,
98
+ to: {
99
+ groupId: value.origin?.groupId,
100
+ artifactId: value.origin?.artifactId,
101
+ versionId: value.origin?.versionId,
102
+ path: value.path,
103
+ },
104
+ },
105
+ );
93
106
  queryBuilderState.changeHandlers.onDataSpaceChange(value);
94
107
  } else if (value instanceof DepotEntityWithOrigin) {
108
+ LegendQueryTelemetryHelper.logEvent_ChangeDataProduct(
109
+ applicationStore.telemetryService,
110
+ {
111
+ sourceInfo: queryBuilderState.sourceInfo,
112
+ to: {
113
+ groupId: value.origin?.groupId,
114
+ artifactId: value.origin?.artifactId,
115
+ versionId: value.origin?.versionId,
116
+ path: value.path,
117
+ },
118
+ },
119
+ );
95
120
  queryBuilderState.changeHandlers.onDataProductChange(value);
96
121
  }
97
122
  };