@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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finos/legend-application-query",
3
- "version": "13.8.52",
3
+ "version": "13.8.54",
4
4
  "description": "Legend Query application core",
5
5
  "keywords": [
6
6
  "legend",
@@ -44,18 +44,18 @@
44
44
  "test:watch": "jest --watch"
45
45
  },
46
46
  "dependencies": {
47
- "@finos/legend-application": "16.0.123",
48
- "@finos/legend-art": "7.1.163",
49
- "@finos/legend-code-editor": "2.0.203",
50
- "@finos/legend-data-cube": "0.3.121",
51
- "@finos/legend-extension-dsl-data-space": "10.4.255",
52
- "@finos/legend-graph": "32.6.34",
53
- "@finos/legend-lego": "2.0.223",
54
- "@finos/legend-query-builder": "4.19.12",
55
- "@finos/legend-server-depot": "6.1.20",
56
- "@finos/legend-server-lakehouse": "0.3.83",
57
- "@finos/legend-shared": "11.0.28",
58
- "@finos/legend-storage": "3.0.150",
47
+ "@finos/legend-application": "16.0.125",
48
+ "@finos/legend-art": "7.1.165",
49
+ "@finos/legend-code-editor": "2.0.205",
50
+ "@finos/legend-data-cube": "0.3.123",
51
+ "@finos/legend-extension-dsl-data-space": "10.4.257",
52
+ "@finos/legend-graph": "32.7.1",
53
+ "@finos/legend-lego": "2.0.225",
54
+ "@finos/legend-query-builder": "4.19.14",
55
+ "@finos/legend-server-depot": "6.1.22",
56
+ "@finos/legend-server-lakehouse": "0.3.85",
57
+ "@finos/legend-shared": "11.0.30",
58
+ "@finos/legend-storage": "3.0.152",
59
59
  "@testing-library/dom": "10.4.0",
60
60
  "@testing-library/react": "16.2.0",
61
61
  "@types/react": "19.0.10",
@@ -16,6 +16,36 @@
16
16
 
17
17
  import type { TelemetryService } from '@finos/legend-application';
18
18
  import { LEGEND_QUERY_APP_EVENT } from './LegendQueryEvent.js';
19
+ import type { LegendQuerySourceInfo } from './LegendQuerySourceInfo.js';
20
+
21
+ /**
22
+ * The entry point the suggestion was triggered from ({@link LegendQuerySourceInfo})
23
+ * is spread FLAT into the payload, matching how `sourceInfo` is reported on
24
+ * every other query telemetry event.
25
+ */
26
+ export type QueryAISuggest_TelemetryData = {
27
+ sourceInfo?: LegendQuerySourceInfo | undefined;
28
+ };
29
+
30
+ export type QueryAISuggestSuccess_TelemetryData =
31
+ QueryAISuggest_TelemetryData & {
32
+ /** Wall-clock duration of the suggester call, in milliseconds. */
33
+ durationMs: number;
34
+ };
35
+
36
+ export type QueryAISuggestFailure_TelemetryData =
37
+ QueryAISuggest_TelemetryData & {
38
+ /** Wall-clock duration until the suggester call failed, in milliseconds. */
39
+ durationMs: number;
40
+ errorMessage: string;
41
+ };
42
+
43
+ const flattenSourceInfo = (
44
+ data: QueryAISuggest_TelemetryData,
45
+ ): Record<string, unknown> => {
46
+ const { sourceInfo, ...rest } = data;
47
+ return { ...rest, ...(sourceInfo ?? {}) };
48
+ };
19
49
 
20
50
  /**
21
51
  * Telemetry surface for Legend AI agent-chat and AI-suggest flows. These
@@ -41,27 +71,53 @@ export class LegendQueryAgentChatTelemetryHelper {
41
71
  );
42
72
  }
43
73
 
44
- static logEvent_QueryAISuggestLaunched(service: TelemetryService): void {
45
- service.logEvent(LEGEND_QUERY_APP_EVENT.LEGENDAI_QUERY_SUGGEST__LAUNCH, {});
74
+ static logEvent_QueryAISuggestLaunched(
75
+ service: TelemetryService,
76
+ data: QueryAISuggest_TelemetryData = {},
77
+ ): void {
78
+ service.logEvent(
79
+ LEGEND_QUERY_APP_EVENT.LEGENDAI_QUERY_SUGGEST__LAUNCH,
80
+ flattenSourceInfo(data),
81
+ );
46
82
  }
47
83
 
48
- static logEvent_QueryAISuggestApplied(service: TelemetryService): void {
49
- service.logEvent(LEGEND_QUERY_APP_EVENT.LEGENDAI_QUERY_SUGGEST__APPLY, {});
84
+ static logEvent_QueryAISuggestSucceeded(
85
+ service: TelemetryService,
86
+ data: QueryAISuggestSuccess_TelemetryData,
87
+ ): void {
88
+ service.logEvent(
89
+ LEGEND_QUERY_APP_EVENT.LEGENDAI_QUERY_SUGGEST__SUCCESS,
90
+ flattenSourceInfo(data),
91
+ );
92
+ }
93
+
94
+ static logEvent_QueryAISuggestApplied(
95
+ service: TelemetryService,
96
+ data: QueryAISuggest_TelemetryData = {},
97
+ ): void {
98
+ service.logEvent(
99
+ LEGEND_QUERY_APP_EVENT.LEGENDAI_QUERY_SUGGEST__APPLY,
100
+ flattenSourceInfo(data),
101
+ );
50
102
  }
51
103
 
52
- static logEvent_QueryAISuggestDiscarded(service: TelemetryService): void {
104
+ static logEvent_QueryAISuggestDiscarded(
105
+ service: TelemetryService,
106
+ data: QueryAISuggest_TelemetryData = {},
107
+ ): void {
53
108
  service.logEvent(
54
109
  LEGEND_QUERY_APP_EVENT.LEGENDAI_QUERY_SUGGEST__DISCARD,
55
- {},
110
+ flattenSourceInfo(data),
56
111
  );
57
112
  }
58
113
 
59
114
  static logEvent_QueryAISuggestFailure(
60
115
  service: TelemetryService,
61
- errorMessage: string,
116
+ data: QueryAISuggestFailure_TelemetryData,
62
117
  ): void {
63
- service.logEvent(LEGEND_QUERY_APP_EVENT.LEGENDAI_QUERY_SUGGEST__FAILURE, {
64
- errorMessage,
65
- });
118
+ service.logEvent(
119
+ LEGEND_QUERY_APP_EVENT.LEGENDAI_QUERY_SUGGEST__FAILURE,
120
+ flattenSourceInfo(data),
121
+ );
66
122
  }
67
123
  }
@@ -22,17 +22,42 @@ export enum LEGEND_QUERY_APP_EVENT {
22
22
  CREATE_QUERY__SUCCESS = 'query-editor.create-query.success',
23
23
  UPDATE_QUERY__SUCCESS = 'query-editor.update-query.success',
24
24
  RENAME_QUERY__SUCCESS = 'query-editor.rename.query.success',
25
+ DELETE_QUERY__SUCCESS = 'query-editor.delete-query.success',
26
+
27
+ CREATE_QUERY__FAILURE = 'query-editor.create-query.failure',
28
+ UPDATE_QUERY__FAILURE = 'query-editor.update-query.failure',
29
+ RENAME_QUERY__FAILURE = 'query-editor.rename-query.failure',
30
+ DELETE_QUERY__FAILURE = 'query-editor.delete-query.failure',
31
+ VIEW_QUERY__FAILURE = 'query-editor.view-query.failure',
32
+ INITIALIZE_QUERY_STATE__FAILURE = 'query-editor.initialize-query-state.failure',
33
+ GRAPH_INITIALIZATION__FAILURE = 'query-editor.graph-initialization.failure',
34
+ PRODUCTIONIZE_QUERY__LAUNCH = 'query-editor.productionize-query.launch',
25
35
  INITIALIZE_QUERY_STATE__SUCCESS = 'query-editor.initialize-query-state.success',
36
+ INITIALIZE_QUERY_CREATOR__FAILURE = 'query-editor.initialize-query-creator.failure',
26
37
  LEGENDAI_QUERY_AGENT_CHAT__OPENED = 'query-editor.legendai-query-agent-chat.opened',
27
38
  LEGENDAI_QUERY_AGENT_CHAT__QUERY_LOADED = 'query-editor.legendai-query-agent-chat.query-loaded',
28
39
  LEGENDAI_QUERY_SUGGEST__LAUNCH = 'query-editor.legendai-query-suggest.launch',
40
+ LEGENDAI_QUERY_SUGGEST__SUCCESS = 'query-editor.legendai-query-suggest.success',
29
41
  LEGENDAI_QUERY_SUGGEST__APPLY = 'query-editor.legendai-query-suggest.apply',
30
42
  LEGENDAI_QUERY_SUGGEST__DISCARD = 'query-editor.legendai-query-suggest.discard',
31
43
  LEGENDAI_QUERY_SUGGEST__FAILURE = 'query-editor.legendai-query-suggest.failure',
32
44
 
45
+ CHANGE_DATA_SPACE = 'query-editor.change-data-space',
46
+ CHANGE_DATA_PRODUCT = 'query-editor.change-data-product',
47
+
33
48
  VIEW_PROJECT__LAUNCH = 'query-editor.view-project.launch',
34
49
  VIEW_SDLC_PROJECT__LAUNCH = 'query-editor.view-sdlc-project.launch',
35
50
 
51
+ // Help-menu items injected by Legend Query into the query builder header.
52
+ // Each carries the shared query builder telemetry envelope (source info flat
53
+ // + `state` nested), matching every other query telemetry event.
54
+ ABOUT_QUERY_INFO__LAUNCH = 'query-editor.about-query-info.launch',
55
+ QUERY_VERSION_HISTORY__LAUNCH = 'query-editor.query-version-history.launch',
56
+ ABOUT_LEGEND_QUERY__LAUNCH = 'query-editor.about-legend-query.launch',
57
+ ABOUT_DATA_SPACE__LAUNCH = 'query-editor.about-data-space.launch',
58
+ ABOUT_DATA_PRODUCT__LAUNCH = 'query-editor.about-data-product.launch',
59
+ ABOUT_INGEST__LAUNCH = 'query-editor.about-ingest.launch',
60
+
36
61
  LOCAL_STORAGE_PERSIST_ERROR = 'LOCAL_STORAGE_PERSIST_ERROR',
37
62
  HOSTED_DATA_CUBE__LAUNCH = 'query-editor.hosted-data-cube.launch',
38
63
  }
@@ -0,0 +1,132 @@
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
+ import type { LightQuery } from '@finos/legend-graph';
18
+ import { buildTelemetryErrorFields } from '@finos/legend-shared';
19
+ import type { GenericLegendApplicationStore } from '@finos/legend-application';
20
+ import type { CompleteQueryLoaderLifecycleHandlers } from '@finos/legend-query-builder';
21
+ import {
22
+ type PartialQuery_TelemetryData,
23
+ type QueryCreateFailure_TelemetryData,
24
+ type QueryLifecycleFailure_TelemetryData,
25
+ type Query_TelemetryData,
26
+ LegendQueryTelemetryHelper,
27
+ } from './LegendQueryTelemetryHelper.js';
28
+
29
+ /**
30
+ * Builds the error half of a saved-query lifecycle failure payload, applying the
31
+ * same message cap and `errorMessageTruncated` flag as every other failure event.
32
+ */
33
+ export const buildQueryLifecycleFailureData = (
34
+ queryId: string,
35
+ error: Error,
36
+ ): QueryLifecycleFailure_TelemetryData => ({
37
+ // NOTE: only the id is available on these paths — the loader reports a
38
+ // failure by id, and the query it refers to was never resolved
39
+ query: { id: queryId },
40
+ ...buildTelemetryErrorFields(error),
41
+ });
42
+
43
+ /**
44
+ * Maps a query to the identity block every lifecycle event carries.
45
+ */
46
+ export const buildQueryIdentity = (query: LightQuery): Query_TelemetryData => ({
47
+ query: {
48
+ id: query.id,
49
+ name: query.name,
50
+ groupId: query.groupId,
51
+ artifactId: query.artifactId,
52
+ versionId: query.versionId,
53
+ },
54
+ });
55
+
56
+ /**
57
+ * Builds the payload for a failed *create*.
58
+ *
59
+ * Separate from {@link buildQueryLifecycleFailureData} because a failed create
60
+ * has no query to identify — the server assigns the id and the request never got
61
+ * that far. Reporting the chosen name instead of a placeholder id keeps "never
62
+ * persisted" distinguishable from a real value.
63
+ */
64
+ export const buildQueryCreateFailureData = (
65
+ queryName: string,
66
+ error: Error,
67
+ ): QueryCreateFailure_TelemetryData => ({
68
+ queryName,
69
+ ...buildTelemetryErrorFields(error),
70
+ });
71
+
72
+ /**
73
+ * The saved-query lifecycle handlers every `QueryLoaderState` host wires in.
74
+ *
75
+ * Rename and delete happen inside the shared query loader, which reports them
76
+ * back through callbacks — so without this the same emit would be duplicated at
77
+ * each of the three hosts that build a loader (and before this existed, the
78
+ * rename emit was in fact triplicated while delete was reported nowhere).
79
+ *
80
+ * NOTE: these events deliberately carry no source info. They fire from the query
81
+ * *picker*, where the user may rename or delete one query while editing another
82
+ * — attaching the loaded query builder's source info would silently mislabel the
83
+ * row as belonging to the wrong query.
84
+ */
85
+ export const buildQueryLoaderLifecycleTelemetryHandlers = (
86
+ applicationStore: GenericLegendApplicationStore,
87
+ sideEffects?:
88
+ | {
89
+ /**
90
+ * Runs alongside the delete telemetry — hosts use this to prune their
91
+ * recently-viewed list.
92
+ */
93
+ onQueryDeleted?: ((queryId: string) => void) | undefined;
94
+ }
95
+ | undefined,
96
+ ): CompleteQueryLoaderLifecycleHandlers => {
97
+ const { telemetryService } = applicationStore;
98
+ return {
99
+ onQueryRenamed: (query): void => {
100
+ LegendQueryTelemetryHelper.logEvent_RenameQuerySucceeded(
101
+ telemetryService,
102
+ buildQueryIdentity(query),
103
+ );
104
+ },
105
+ onQueryDeleted: (queryId, deletedQuery): void => {
106
+ sideEffects?.onQueryDeleted?.(queryId);
107
+ // the entry may not have been in the loaded list, in which case only the
108
+ // id is known
109
+ const identity: PartialQuery_TelemetryData = deletedQuery
110
+ ? buildQueryIdentity(deletedQuery)
111
+ : { query: { id: queryId } };
112
+ LegendQueryTelemetryHelper.logEvent_DeleteQuerySucceeded(
113
+ telemetryService,
114
+ identity,
115
+ );
116
+ },
117
+ onQueryRenameFailed: (queryId, error): void => {
118
+ // the rename failed, so the loader never resolved the renamed query —
119
+ // only its id and the error are known
120
+ LegendQueryTelemetryHelper.logEvent_RenameQueryFailed(
121
+ telemetryService,
122
+ buildQueryLifecycleFailureData(queryId, error),
123
+ );
124
+ },
125
+ onQueryDeleteFailed: (queryId, error): void => {
126
+ LegendQueryTelemetryHelper.logEvent_DeleteQueryFailed(
127
+ telemetryService,
128
+ buildQueryLifecycleFailureData(queryId, error),
129
+ );
130
+ },
131
+ };
132
+ };
@@ -407,17 +407,17 @@ export const EXTERNAL_APPLICATION_NAVIGATION__generateStudioProductionizeQueryUr
407
407
  `${studioApplicationUrl}/extensions/productionize-query/${queryId}`;
408
408
 
409
409
  /**
410
- * @external_application_navigation This depends on Legend Taxonomy routing and is hardcoded so it's potentially brittle
410
+ * @external_application_navigation This depends on Legend Marketplace routing and is hardcoded so it's potentially brittle
411
411
  */
412
- export const EXTERNAL_APPLICATION_NAVIGATION__generateTaxonomyDataspaceViewUrl =
412
+ export const EXTERNAL_APPLICATION_NAVIGATION__generateMarketplaceDataspaceViewUrl =
413
413
  (
414
- taxonomyApplicationUrl: string,
414
+ marketplaceApplicationUrl: string,
415
415
  groupId: string,
416
416
  artifactId: string,
417
417
  versionId: string,
418
418
  dataspacePath: string,
419
419
  ): string =>
420
- `${taxonomyApplicationUrl}/dataspace/${generateGAVCoordinates(
420
+ `${marketplaceApplicationUrl}/dataProduct/legacy/${generateGAVCoordinates(
421
421
  groupId,
422
422
  artifactId,
423
423
  versionId,
@@ -442,6 +442,20 @@ export const EXTERNAL_APPLICATION_NAVIGATION__generateNewDataCubeUrl = (
442
442
  )}`;
443
443
  };
444
444
 
445
+ /**
446
+ * Mirrors `generateAnchorForSection` from `@finos/legend-extension-dsl-data-product`,
447
+ * which this package does not depend on. The data product viewer registers one anchor
448
+ * per access point group, and reads the zone from the URL hash on load.
449
+ *
450
+ * @external_application_navigation This depends on Legend Marketplace routing and is hardcoded so it's potentially brittle
451
+ */
452
+ const EXTERNAL_APPLICATION_NAVIGATION__generateAccessPointGroupAnchor = (
453
+ accessPointGroupId: string,
454
+ ): string =>
455
+ encodeURIComponent(
456
+ `apg-${accessPointGroupId}`.trim().toLowerCase().replace(/\s+/gu, '-'),
457
+ );
458
+
445
459
  /**
446
460
  * @external_application_navigation This depends on Legend Marketplace routing and is hardcoded so it's potentially brittle
447
461
  */
@@ -450,5 +464,10 @@ export const EXTERNAL_APPLICATION_NAVIGATION__generateMarketplaceDataProductUrl
450
464
  marketplaceApplicationUrl: string,
451
465
  dataProductId: string,
452
466
  deploymentId: string,
467
+ accessPointGroupId?: string | undefined,
453
468
  ): string =>
454
- `${marketplaceApplicationUrl}/dataProduct/deployed/${dataProductId}/${deploymentId}`;
469
+ `${marketplaceApplicationUrl}/dataProduct/deployed/${dataProductId}/${deploymentId}${
470
+ accessPointGroupId
471
+ ? `#${EXTERNAL_APPLICATION_NAVIGATION__generateAccessPointGroupAnchor(accessPointGroupId)}`
472
+ : ''
473
+ }`;
@@ -0,0 +1,162 @@
1
+ /**
2
+ * Copyright (c) 2020-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
+ import type { LegendSourceInfo } from '@finos/legend-storage';
18
+
19
+ /**
20
+ * The entry point a query creator was started from.
21
+ */
22
+ export enum LegendQuerySourceType {
23
+ MAPPING = 'mapping',
24
+ SERVICE = 'service',
25
+ DATA_SPACE = 'data-space',
26
+ DATA_SPACE_TEMPLATE = 'data-space.template',
27
+ DATA_PRODUCT = 'data-product',
28
+ DATA_PRODUCT_SAMPLE = 'data-product.sample',
29
+ INGEST = 'ingest',
30
+ /**
31
+ * The default route, when no data product or data space has been selected yet
32
+ */
33
+ UNSELECTED = 'unselected',
34
+ }
35
+
36
+ /**
37
+ * Coordinates of the project the query is started from
38
+ */
39
+ interface LegendQueryProjectSourceInfo extends LegendSourceInfo {
40
+ groupId: string;
41
+ artifactId: string;
42
+ versionId: string;
43
+ /**
44
+ * Set when a *saved* query was opened (the `/existing/:queryId` route) rather
45
+ * than a new one created from a creator route. The `sourceType` still
46
+ * describes what the query targets — a saved data space query reports
47
+ * `data-space`, same as a freshly created one — so a dashboard can slice by
48
+ * target without caring how the query was opened, and use the presence of
49
+ * this field to separate saved from new when it does care.
50
+ */
51
+ queryId?: string | undefined;
52
+ }
53
+
54
+ /**
55
+ * Query created on a mapping and runtime
56
+ * `/create/manual/:gav/:mappingPath/:runtimePath`
57
+ */
58
+ export interface LegendQueryMappingSourceInfo
59
+ extends LegendQueryProjectSourceInfo {
60
+ sourceType: LegendQuerySourceType.MAPPING;
61
+ mapping: string;
62
+ runtime: string;
63
+ }
64
+
65
+ /**
66
+ * Query created from a service
67
+ * `/create-from-service/:gav/:servicePath`
68
+ */
69
+ export interface LegendQueryServiceSourceInfo
70
+ extends LegendQueryProjectSourceInfo {
71
+ sourceType: LegendQuerySourceType.SERVICE;
72
+ service: string;
73
+ }
74
+
75
+ /**
76
+ * Query created on a data space
77
+ * `/dataspace/:gav/:dataSpacePath/:executionContext?`
78
+ */
79
+ export interface LegendQueryDataSpaceSourceInfo
80
+ extends LegendQueryProjectSourceInfo {
81
+ sourceType: LegendQuerySourceType.DATA_SPACE;
82
+ dataSpace: string;
83
+ /**
84
+ * The key of the execution context the query was started with, when known
85
+ */
86
+ executionContext?: string | undefined;
87
+ }
88
+
89
+ /**
90
+ * Query created from a data space template query
91
+ * `/dataspace/:gav/:dataSpacePath/template/:templateQueryId`
92
+ */
93
+ export interface LegendQueryDataSpaceTemplateSourceInfo
94
+ extends LegendQueryProjectSourceInfo {
95
+ sourceType: LegendQuerySourceType.DATA_SPACE_TEMPLATE;
96
+ dataSpace: string;
97
+ templateQueryId: string;
98
+ }
99
+
100
+ /**
101
+ * Query created on a data product
102
+ * `/data-product/:accessType/:gav/:dataProductPath/:accessId`
103
+ */
104
+ export interface LegendQueryDataProductSourceInfo
105
+ extends LegendQueryProjectSourceInfo {
106
+ sourceType: LegendQuerySourceType.DATA_PRODUCT;
107
+ dataProduct: string;
108
+ /**
109
+ * The access type (e.g. native, model, lakehouse) the query was started
110
+ * with, when known
111
+ */
112
+ accessType?: string | undefined;
113
+ /**
114
+ * The ID of the access point (group) or execution context the query was
115
+ * started with, when known
116
+ */
117
+ accessId?: string | undefined;
118
+ }
119
+
120
+ /**
121
+ * Query created from a data product sample query
122
+ * `/data-product/native/sample-query/:gav/:dataProductPath/:sampleQueryId`
123
+ */
124
+ export interface LegendQueryDataProductSampleSourceInfo
125
+ extends LegendQueryProjectSourceInfo {
126
+ sourceType: LegendQuerySourceType.DATA_PRODUCT_SAMPLE;
127
+ dataProduct: string;
128
+ sampleQueryId: string;
129
+ }
130
+
131
+ /**
132
+ * Query created on an ingest data set
133
+ * `/ingest/:gav/:ingestDefinitionPath/:dataSet`
134
+ */
135
+ export interface LegendQueryIngestSourceInfo
136
+ extends LegendQueryProjectSourceInfo {
137
+ sourceType: LegendQuerySourceType.INGEST;
138
+ ingestDefinitionPath: string;
139
+ dataSet: string;
140
+ }
141
+
142
+ /**
143
+ * The default route `/`, when no data product or data space has been
144
+ * selected yet
145
+ */
146
+ export interface LegendQueryUnselectedSourceInfo extends LegendSourceInfo {
147
+ sourceType: LegendQuerySourceType.UNSELECTED;
148
+ }
149
+
150
+ /**
151
+ * Where a query creator was started from, used as the query builder state
152
+ * source info (see `QueryBuilderState.sourceInfo`) and reported in telemetry
153
+ */
154
+ export type LegendQuerySourceInfo =
155
+ | LegendQueryMappingSourceInfo
156
+ | LegendQueryServiceSourceInfo
157
+ | LegendQueryDataSpaceSourceInfo
158
+ | LegendQueryDataSpaceTemplateSourceInfo
159
+ | LegendQueryDataProductSourceInfo
160
+ | LegendQueryDataProductSampleSourceInfo
161
+ | LegendQueryIngestSourceInfo
162
+ | LegendQueryUnselectedSourceInfo;