@finos/legend-application-studio 28.21.42 → 28.21.44

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 (164) hide show
  1. package/lib/__lib__/LegendStudioEvent.d.ts +18 -4
  2. package/lib/__lib__/LegendStudioEvent.d.ts.map +1 -1
  3. package/lib/__lib__/LegendStudioEvent.js +20 -5
  4. package/lib/__lib__/LegendStudioEvent.js.map +1 -1
  5. package/lib/__lib__/LegendStudioTelemetryHelper.d.ts +177 -31
  6. package/lib/__lib__/LegendStudioTelemetryHelper.d.ts.map +1 -1
  7. package/lib/__lib__/LegendStudioTelemetryHelper.js +229 -72
  8. package/lib/__lib__/LegendStudioTelemetryHelper.js.map +1 -1
  9. package/lib/__lib__/LegendStudioUserDataHelper.d.ts +18 -1
  10. package/lib/__lib__/LegendStudioUserDataHelper.d.ts.map +1 -1
  11. package/lib/__lib__/LegendStudioUserDataHelper.js +71 -0
  12. package/lib/__lib__/LegendStudioUserDataHelper.js.map +1 -1
  13. package/lib/application/LegendStudioApplicationConfig.d.ts +12 -0
  14. package/lib/application/LegendStudioApplicationConfig.d.ts.map +1 -1
  15. package/lib/application/LegendStudioApplicationConfig.js +6 -0
  16. package/lib/application/LegendStudioApplicationConfig.js.map +1 -1
  17. package/lib/components/LegendStudioWebApplication.d.ts.map +1 -1
  18. package/lib/components/LegendStudioWebApplication.js +5 -2
  19. package/lib/components/LegendStudioWebApplication.js.map +1 -1
  20. package/lib/components/ShowcaseManager.d.ts.map +1 -1
  21. package/lib/components/ShowcaseManager.js +6 -4
  22. package/lib/components/ShowcaseManager.js.map +1 -1
  23. package/lib/components/editor/ActivityBar.d.ts.map +1 -1
  24. package/lib/components/editor/ActivityBar.js +2 -1
  25. package/lib/components/editor/ActivityBar.js.map +1 -1
  26. package/lib/components/editor/editor-group/GrammarTextEditor.d.ts.map +1 -1
  27. package/lib/components/editor/editor-group/GrammarTextEditor.js +7 -1
  28. package/lib/components/editor/editor-group/GrammarTextEditor.js.map +1 -1
  29. package/lib/components/editor/editor-group/data-editor/RelationElementSampleValuesEditor.d.ts +37 -0
  30. package/lib/components/editor/editor-group/data-editor/RelationElementSampleValuesEditor.d.ts.map +1 -0
  31. package/lib/components/editor/editor-group/data-editor/RelationElementSampleValuesEditor.js +126 -0
  32. package/lib/components/editor/editor-group/data-editor/RelationElementSampleValuesEditor.js.map +1 -0
  33. package/lib/components/editor/editor-group/dataProduct/DataProductEditor.d.ts.map +1 -1
  34. package/lib/components/editor/editor-group/dataProduct/DataProductEditor.js +22 -127
  35. package/lib/components/editor/editor-group/dataProduct/DataProductEditor.js.map +1 -1
  36. package/lib/components/editor/editor-group/service-editor/ServiceEditor.d.ts.map +1 -1
  37. package/lib/components/editor/editor-group/service-editor/ServiceEditor.js +4 -4
  38. package/lib/components/editor/editor-group/service-editor/ServiceEditor.js.map +1 -1
  39. package/lib/components/showcase/ShowcaseFeedback.d.ts +36 -0
  40. package/lib/components/showcase/ShowcaseFeedback.d.ts.map +1 -0
  41. package/lib/components/showcase/ShowcaseFeedback.js +70 -0
  42. package/lib/components/showcase/ShowcaseFeedback.js.map +1 -0
  43. package/lib/components/showcase/ShowcaseViewer.d.ts.map +1 -1
  44. package/lib/components/showcase/ShowcaseViewer.js +3 -1
  45. package/lib/components/showcase/ShowcaseViewer.js.map +1 -1
  46. package/lib/components/workspace-setup/WorkspaceSetup.d.ts.map +1 -1
  47. package/lib/components/workspace-setup/WorkspaceSetup.js +2 -1
  48. package/lib/components/workspace-setup/WorkspaceSetup.js.map +1 -1
  49. package/lib/index.css +2 -2
  50. package/lib/index.css.map +1 -1
  51. package/lib/index.d.ts +2 -1
  52. package/lib/index.d.ts.map +1 -1
  53. package/lib/index.js +2 -1
  54. package/lib/index.js.map +1 -1
  55. package/lib/package.json +1 -1
  56. package/lib/stores/LegendStudioBaseStore.d.ts.map +1 -1
  57. package/lib/stores/LegendStudioBaseStore.js +1 -0
  58. package/lib/stores/LegendStudioBaseStore.js.map +1 -1
  59. package/lib/stores/ShowcaseManagerState.d.ts +5 -3
  60. package/lib/stores/ShowcaseManagerState.d.ts.map +1 -1
  61. package/lib/stores/ShowcaseManagerState.js +44 -11
  62. package/lib/stores/ShowcaseManagerState.js.map +1 -1
  63. package/lib/stores/editor/EditorGraphState.d.ts.map +1 -1
  64. package/lib/stores/editor/EditorGraphState.js +1 -1
  65. package/lib/stores/editor/EditorGraphState.js.map +1 -1
  66. package/lib/stores/editor/EditorStore.d.ts +2 -1
  67. package/lib/stores/editor/EditorStore.d.ts.map +1 -1
  68. package/lib/stores/editor/EditorStore.js +8 -2
  69. package/lib/stores/editor/EditorStore.js.map +1 -1
  70. package/lib/stores/editor/GraphEditFormModeState.d.ts.map +1 -1
  71. package/lib/stores/editor/GraphEditFormModeState.js +2 -2
  72. package/lib/stores/editor/GraphEditFormModeState.js.map +1 -1
  73. package/lib/stores/editor/GraphEditGrammarModeState.d.ts +19 -0
  74. package/lib/stores/editor/GraphEditGrammarModeState.d.ts.map +1 -1
  75. package/lib/stores/editor/GraphEditGrammarModeState.js +92 -4
  76. package/lib/stores/editor/GraphEditGrammarModeState.js.map +1 -1
  77. package/lib/stores/editor/GraphEditorMode.d.ts +1 -0
  78. package/lib/stores/editor/GraphEditorMode.d.ts.map +1 -1
  79. package/lib/stores/editor/GraphEditorMode.js.map +1 -1
  80. package/lib/stores/editor/StandardEditorMode.d.ts +16 -5
  81. package/lib/stores/editor/StandardEditorMode.d.ts.map +1 -1
  82. package/lib/stores/editor/StandardEditorMode.js +4 -2
  83. package/lib/stores/editor/StandardEditorMode.js.map +1 -1
  84. package/lib/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.d.ts +2 -14
  85. package/lib/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.d.ts.map +1 -1
  86. package/lib/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.js +5 -75
  87. package/lib/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.js.map +1 -1
  88. package/lib/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.d.ts +0 -11
  89. package/lib/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.d.ts.map +1 -1
  90. package/lib/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.js +2 -77
  91. package/lib/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.js.map +1 -1
  92. package/lib/stores/editor/editor-state/element-editor-state/service/testable/ServiceTestDataState.d.ts.map +1 -1
  93. package/lib/stores/editor/editor-state/element-editor-state/service/testable/ServiceTestDataState.js +4 -4
  94. package/lib/stores/editor/editor-state/element-editor-state/service/testable/ServiceTestDataState.js.map +1 -1
  95. package/lib/stores/editor/sidebar-state/LocalChangesState.d.ts +1 -0
  96. package/lib/stores/editor/sidebar-state/LocalChangesState.d.ts.map +1 -1
  97. package/lib/stores/editor/sidebar-state/LocalChangesState.js +27 -0
  98. package/lib/stores/editor/sidebar-state/LocalChangesState.js.map +1 -1
  99. package/lib/stores/editor/sidebar-state/WorkspaceUpdaterState.d.ts.map +1 -1
  100. package/lib/stores/editor/sidebar-state/WorkspaceUpdaterState.js +7 -0
  101. package/lib/stores/editor/sidebar-state/WorkspaceUpdaterState.js.map +1 -1
  102. package/lib/stores/editor/sidebar-state/dev-metadata/DevMetadataState.d.ts.map +1 -1
  103. package/lib/stores/editor/sidebar-state/dev-metadata/DevMetadataState.js +7 -2
  104. package/lib/stores/editor/sidebar-state/dev-metadata/DevMetadataState.js.map +1 -1
  105. package/lib/stores/lazy-text-editor/LazyTextEditorStore.d.ts +1 -0
  106. package/lib/stores/lazy-text-editor/LazyTextEditorStore.d.ts.map +1 -1
  107. package/lib/stores/lazy-text-editor/LazyTextEditorStore.js +3 -0
  108. package/lib/stores/lazy-text-editor/LazyTextEditorStore.js.map +1 -1
  109. package/lib/stores/project-reviewer/ProjectReviewerStore.d.ts.map +1 -1
  110. package/lib/stores/project-reviewer/ProjectReviewerStore.js +2 -0
  111. package/lib/stores/project-reviewer/ProjectReviewerStore.js.map +1 -1
  112. package/lib/stores/project-view/ProjectViewerEditorMode.d.ts +2 -2
  113. package/lib/stores/project-view/ProjectViewerEditorMode.d.ts.map +1 -1
  114. package/lib/stores/project-view/ProjectViewerEditorMode.js +12 -0
  115. package/lib/stores/project-view/ProjectViewerEditorMode.js.map +1 -1
  116. package/lib/stores/project-view/ProjectViewerStore.d.ts.map +1 -1
  117. package/lib/stores/project-view/ProjectViewerStore.js +3 -1
  118. package/lib/stores/project-view/ProjectViewerStore.js.map +1 -1
  119. package/lib/stores/showcase/ShowcaseViewerEditorMode.d.ts.map +1 -1
  120. package/lib/stores/showcase/ShowcaseViewerEditorMode.js.map +1 -1
  121. package/lib/stores/showcase/ShowcaseViewerStore.d.ts.map +1 -1
  122. package/lib/stores/showcase/ShowcaseViewerStore.js +7 -3
  123. package/lib/stores/showcase/ShowcaseViewerStore.js.map +1 -1
  124. package/lib/stores/workspace-setup/WorkspaceSetupStore.d.ts.map +1 -1
  125. package/lib/stores/workspace-setup/WorkspaceSetupStore.js +1 -0
  126. package/lib/stores/workspace-setup/WorkspaceSetupStore.js.map +1 -1
  127. package/package.json +16 -16
  128. package/src/__lib__/LegendStudioEvent.ts +22 -6
  129. package/src/__lib__/LegendStudioTelemetryHelper.ts +425 -104
  130. package/src/__lib__/LegendStudioUserDataHelper.ts +115 -0
  131. package/src/application/LegendStudioApplicationConfig.ts +19 -0
  132. package/src/components/LegendStudioWebApplication.tsx +18 -2
  133. package/src/components/ShowcaseManager.tsx +24 -4
  134. package/src/components/editor/ActivityBar.tsx +5 -1
  135. package/src/components/editor/editor-group/GrammarTextEditor.tsx +18 -1
  136. package/src/components/editor/editor-group/data-editor/RelationElementSampleValuesEditor.tsx +285 -0
  137. package/src/components/editor/editor-group/dataProduct/DataProductEditor.tsx +38 -323
  138. package/src/components/editor/editor-group/service-editor/ServiceEditor.tsx +4 -0
  139. package/src/components/showcase/ShowcaseFeedback.tsx +136 -0
  140. package/src/components/showcase/ShowcaseViewer.tsx +10 -0
  141. package/src/components/workspace-setup/WorkspaceSetup.tsx +6 -1
  142. package/src/index.ts +2 -0
  143. package/src/stores/LegendStudioBaseStore.ts +1 -0
  144. package/src/stores/ShowcaseManagerState.ts +67 -8
  145. package/src/stores/editor/EditorGraphState.ts +1 -0
  146. package/src/stores/editor/EditorStore.ts +26 -4
  147. package/src/stores/editor/GraphEditFormModeState.ts +2 -0
  148. package/src/stores/editor/GraphEditGrammarModeState.ts +139 -1
  149. package/src/stores/editor/GraphEditorMode.ts +1 -0
  150. package/src/stores/editor/StandardEditorMode.ts +21 -7
  151. package/src/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.ts +3 -119
  152. package/src/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.ts +1 -136
  153. package/src/stores/editor/editor-state/element-editor-state/service/testable/ServiceTestDataState.ts +4 -0
  154. package/src/stores/editor/sidebar-state/LocalChangesState.ts +47 -0
  155. package/src/stores/editor/sidebar-state/WorkspaceUpdaterState.ts +18 -0
  156. package/src/stores/editor/sidebar-state/dev-metadata/DevMetadataState.ts +7 -0
  157. package/src/stores/lazy-text-editor/LazyTextEditorStore.ts +4 -0
  158. package/src/stores/project-reviewer/ProjectReviewerStore.ts +4 -0
  159. package/src/stores/project-view/ProjectViewerEditorMode.ts +17 -4
  160. package/src/stores/project-view/ProjectViewerStore.ts +5 -0
  161. package/src/stores/showcase/ShowcaseViewerEditorMode.ts +4 -5
  162. package/src/stores/showcase/ShowcaseViewerStore.ts +12 -2
  163. package/src/stores/workspace-setup/WorkspaceSetupStore.ts +2 -0
  164. package/tsconfig.json +2 -0
@@ -18,6 +18,7 @@ import {
18
18
  type GeneratorFn,
19
19
  ActionState,
20
20
  LogEvent,
21
+ StopWatch,
21
22
  assertErrorThrown,
22
23
  guaranteeNonNullable,
23
24
  isNonNullable,
@@ -40,7 +41,11 @@ import {
40
41
  import type { TreeData, TreeNodeData } from '@finos/legend-art';
41
42
  import { DIRECTORY_PATH_DELIMITER } from '@finos/legend-graph';
42
43
  import { SHOWCASE_MANAGER_VIRTUAL_ASSISTANT_TAB_KEY } from '../components/extensions/Core_LegendStudioApplicationPlugin.js';
43
- import { LegendStudioTelemetryHelper } from '../__lib__/LegendStudioTelemetryHelper.js';
44
+ import {
45
+ LegendStudioTelemetryHelper,
46
+ SHOWCASE_LAUNCH_ENTRY_POINT,
47
+ SHOWCASE_MANAGER_ENTRY_POINT,
48
+ } from '../__lib__/LegendStudioTelemetryHelper.js';
44
49
 
45
50
  export enum SHOWCASE_MANAGER_VIEW {
46
51
  EXPLORER = 'EXPLORER',
@@ -164,6 +169,7 @@ export class ShowcaseManagerState extends ApplicationExtensionState {
164
169
  allShowcases: ShowcaseMetadata[] | undefined;
165
170
  currentShowcase?: Showcase | undefined;
166
171
  showcaseLineToScroll?: number | undefined;
172
+ private currentShowcaseOpenedAt?: number | undefined;
167
173
 
168
174
  currentView = SHOWCASE_MANAGER_VIEW.EXPLORER;
169
175
  explorerTreeData?: TreeData<ShowcasesExplorerTreeNodeData> | undefined;
@@ -266,6 +272,7 @@ export class ShowcaseManagerState extends ApplicationExtensionState {
266
272
  *openShowcase(
267
273
  metadata: ShowcaseMetadata,
268
274
  showcaseLineToScroll?: number | undefined,
275
+ entryPoint: SHOWCASE_LAUNCH_ENTRY_POINT = SHOWCASE_LAUNCH_ENTRY_POINT.EXPLORER,
269
276
  ): GeneratorFn<void> {
270
277
  this.fetchShowcaseState.inProgress();
271
278
 
@@ -274,10 +281,15 @@ export class ShowcaseManagerState extends ApplicationExtensionState {
274
281
  metadata.path,
275
282
  )) as Showcase;
276
283
  this.currentShowcase = showcase;
284
+ this.currentShowcaseOpenedAt = Date.now();
277
285
  LegendStudioTelemetryHelper.logEvent_ShowcaseManagerShowcaseProjectLaunch(
278
286
  this.applicationStore.telemetryService,
279
287
  {
280
288
  showcasePath: showcase.path,
289
+ title: showcase.title,
290
+ isDevelopment: metadata.development,
291
+ entryPoint,
292
+ lineNumber: showcaseLineToScroll,
281
293
  },
282
294
  );
283
295
  this.showcaseLineToScroll = showcaseLineToScroll;
@@ -285,18 +297,28 @@ export class ShowcaseManagerState extends ApplicationExtensionState {
285
297
  } catch (error) {
286
298
  assertErrorThrown(error);
287
299
  this.applicationStore.logService.error(
288
- LogEvent.create(LEGEND_STUDIO_APP_EVENT.SHOWCASE_MANAGER_FAILURE),
300
+ LogEvent.create(LEGEND_STUDIO_APP_EVENT.SHOWCASE_MANAGER_OPEN__FAILURE),
289
301
  error,
290
302
  );
303
+ LegendStudioTelemetryHelper.logEvent_ShowcaseManagerOpenFailure(
304
+ this.applicationStore.telemetryService,
305
+ {
306
+ errorMessage: error.message,
307
+ showcasePath: metadata.path,
308
+ },
309
+ );
291
310
  this.fetchShowcaseState.fail();
292
311
  }
293
312
  }
294
313
 
295
- logOpenManager(): void {
314
+ logOpenManager(
315
+ entryPoint: SHOWCASE_MANAGER_ENTRY_POINT = SHOWCASE_MANAGER_ENTRY_POINT.ACTIVITY_BAR,
316
+ ): void {
296
317
  if (this.allShowcases) {
297
318
  const report = {
298
319
  showcasesTotalCount: this.allShowcases.length,
299
320
  showcasesDevelopmentCount: this.nonDevShowcases.length,
321
+ entryPoint,
300
322
  };
301
323
  LegendStudioTelemetryHelper.logEvent_ShowcaseManagerLaunch(
302
324
  this.applicationStore.telemetryService,
@@ -306,7 +328,17 @@ export class ShowcaseManagerState extends ApplicationExtensionState {
306
328
  }
307
329
 
308
330
  closeShowcase(): void {
331
+ if (this.currentShowcase && this.currentShowcaseOpenedAt !== undefined) {
332
+ LegendStudioTelemetryHelper.logEvent_ShowcaseViewerClose(
333
+ this.applicationStore.telemetryService,
334
+ {
335
+ showcasePath: this.currentShowcase.path,
336
+ dwellMs: Date.now() - this.currentShowcaseOpenedAt,
337
+ },
338
+ );
339
+ }
309
340
  this.currentShowcase = undefined;
341
+ this.currentShowcaseOpenedAt = undefined;
310
342
  this.showcaseLineToScroll = undefined;
311
343
  }
312
344
 
@@ -352,9 +384,13 @@ export class ShowcaseManagerState extends ApplicationExtensionState {
352
384
  } catch (error) {
353
385
  assertErrorThrown(error);
354
386
  this.applicationStore.logService.error(
355
- LogEvent.create(LEGEND_STUDIO_APP_EVENT.SHOWCASE_MANAGER_FAILURE),
387
+ LogEvent.create(LEGEND_STUDIO_APP_EVENT.SHOWCASE_MANAGER_INIT__FAILURE),
356
388
  error,
357
389
  );
390
+ LegendStudioTelemetryHelper.logEvent_ShowcaseManagerInitFailure(
391
+ this.applicationStore.telemetryService,
392
+ { errorMessage: error.message },
393
+ );
358
394
  this.initState.fail();
359
395
  }
360
396
  }
@@ -368,14 +404,16 @@ export class ShowcaseManagerState extends ApplicationExtensionState {
368
404
  }
369
405
  this.textSearchState.inProgress();
370
406
 
407
+ const searchText = this.searchText;
371
408
  LegendStudioTelemetryHelper.logEvent_ShowcaseSearchInitiated(
372
409
  this.applicationStore.telemetryService,
373
- { searchText: this.searchText },
410
+ { searchText },
374
411
  );
412
+ const stopWatch = new StopWatch();
375
413
 
376
414
  try {
377
415
  const result = (yield this.client.search(
378
- this.searchText,
416
+ searchText,
379
417
  )) as ShowcaseTextSearchResult;
380
418
  this.textSearchResults = result.textMatches
381
419
  .map((match) => {
@@ -398,12 +436,32 @@ export class ShowcaseManagerState extends ApplicationExtensionState {
398
436
  ),
399
437
  )
400
438
  .filter(isNonNullable);
439
+ const showcaseMatchCount = this.showcaseSearchResults.length;
440
+ const textMatchCount = this.textSearchResults.length;
441
+ const resultCount = showcaseMatchCount + textMatchCount;
442
+ LegendStudioTelemetryHelper.logEvent_ShowcaseSearchCompleted(
443
+ this.applicationStore.telemetryService,
444
+ {
445
+ searchText,
446
+ resultCount,
447
+ showcaseMatchCount,
448
+ textMatchCount,
449
+ durationMs: stopWatch.elapsed,
450
+ hadResults: resultCount > 0,
451
+ },
452
+ );
401
453
  } catch (error) {
402
454
  assertErrorThrown(error);
403
455
  this.applicationStore.logService.error(
404
- LogEvent.create(LEGEND_STUDIO_APP_EVENT.SHOWCASE_MANAGER_FAILURE),
456
+ LogEvent.create(
457
+ LEGEND_STUDIO_APP_EVENT.SHOWCASE_MANAGER_SEARCH__FAILURE,
458
+ ),
405
459
  error,
406
460
  );
461
+ LegendStudioTelemetryHelper.logEvent_ShowcaseManagerSearchFailure(
462
+ this.applicationStore.telemetryService,
463
+ { errorMessage: error.message, searchText },
464
+ );
407
465
  } finally {
408
466
  this.textSearchState.complete();
409
467
  }
@@ -412,6 +470,7 @@ export class ShowcaseManagerState extends ApplicationExtensionState {
412
470
 
413
471
  export const openShowcaseManager = (
414
472
  applicationStore: LegendStudioApplicationStore,
473
+ entryPoint: SHOWCASE_MANAGER_ENTRY_POINT,
415
474
  ): void => {
416
475
  const showcaseManagerState =
417
476
  ShowcaseManagerState.retrieveNullableState(applicationStore);
@@ -422,6 +481,6 @@ export const openShowcaseManager = (
422
481
  applicationStore.assistantService.setSelectedTab(
423
482
  SHOWCASE_MANAGER_VIRTUAL_ASSISTANT_TAB_KEY,
424
483
  );
425
- showcaseManagerState.logOpenManager();
484
+ showcaseManagerState.logOpenManager(entryPoint);
426
485
  }
427
486
  };
@@ -408,6 +408,7 @@ export class EditorGraphState {
408
408
  LegendStudioTelemetryHelper.logEvent_GraphInitializationSucceeded(
409
409
  this.editorStore.applicationStore.telemetryService,
410
410
  graphBuilderReportData,
411
+ this.editorStore.editorMode.getSourceInfo(),
411
412
  );
412
413
 
413
414
  this.editorStore.applicationStore.logService.info(
@@ -93,6 +93,12 @@ import {
93
93
  DEFAULT_TAB_SIZE,
94
94
  } from '@finos/legend-application';
95
95
  import { LEGEND_STUDIO_APP_EVENT } from '../../__lib__/LegendStudioEvent.js';
96
+ import {
97
+ LegendStudioTelemetryHelper,
98
+ TEXT_MODE_ENTER_TRIGGER,
99
+ TEXT_MODE_TOGGLE_DIRECTION,
100
+ TEXT_MODE_TOGGLE_SOURCE,
101
+ } from '../../__lib__/LegendStudioTelemetryHelper.js';
96
102
  import { LegendStudioUserDataHelper } from '../../__lib__/LegendStudioUserDataHelper.js';
97
103
  import type { EditorMode } from './EditorMode.js';
98
104
  import { StandardEditorMode } from './StandardEditorMode.js';
@@ -491,9 +497,9 @@ export class EditorStore implements CommandRegistrar {
491
497
  this.conflictResolutionState.hasResolvedAllConflicts),
492
498
  ),
493
499
  action: () => {
494
- flowResult(this.toggleTextMode()).catch(
495
- this.applicationStore.alertUnhandledError,
496
- );
500
+ flowResult(
501
+ this.toggleTextMode(TEXT_MODE_TOGGLE_SOURCE.KEYBOARD_SHORTCUT),
502
+ ).catch(this.applicationStore.alertUnhandledError);
497
503
  },
498
504
  });
499
505
  this.applicationStore.commandService.registerCommand({
@@ -873,8 +879,11 @@ export class EditorStore implements CommandRegistrar {
873
879
  queryBaseUrl:
874
880
  this.editorConfig?.engineQueryServerUrl ??
875
881
  this.applicationStore.config.engineQueryServerUrl,
882
+ queryClientName: this.applicationStore.config.engineQueryClientName,
876
883
  enableCompression: true,
877
884
  payloadDebugger,
885
+ useCookieAuthOnly:
886
+ this.applicationStore.config.engineUseCookieAuthOnly,
878
887
  },
879
888
  },
880
889
  {
@@ -1019,6 +1028,7 @@ export class EditorStore implements CommandRegistrar {
1019
1028
  yield flowResult(
1020
1029
  this.graphEditorMode.initialize({
1021
1030
  useStoredEntities: true,
1031
+ trigger: TEXT_MODE_ENTER_TRIGGER.INITIAL_LAZY,
1022
1032
  }),
1023
1033
  );
1024
1034
  } catch (error) {
@@ -1215,7 +1225,9 @@ export class EditorStore implements CommandRegistrar {
1215
1225
  this.activePanelMode = val;
1216
1226
  }
1217
1227
 
1218
- *toggleTextMode(): GeneratorFn<void> {
1228
+ *toggleTextMode(
1229
+ source: TEXT_MODE_TOGGLE_SOURCE = TEXT_MODE_TOGGLE_SOURCE.BUTTON,
1230
+ ): GeneratorFn<void> {
1219
1231
  if (this.graphState.checkIfApplicationUpdateOperationIsRunning()) {
1220
1232
  return;
1221
1233
  }
@@ -1224,12 +1236,22 @@ export class EditorStore implements CommandRegistrar {
1224
1236
  return;
1225
1237
  }
1226
1238
  if (this.graphEditorMode instanceof GraphEditFormModeState) {
1239
+ LegendStudioTelemetryHelper.logEvent_TextModeToggleShortcutInvoked(
1240
+ this.applicationStore.telemetryService,
1241
+ this.editorMode.getSourceInfo(),
1242
+ { source, direction: TEXT_MODE_TOGGLE_DIRECTION.TO_TEXT },
1243
+ );
1227
1244
  this.applicationStore.alertService.setBlockingAlert({
1228
1245
  message: 'Switching to text mode...',
1229
1246
  showLoading: true,
1230
1247
  });
1231
1248
  yield flowResult(this.switchModes(GRAPH_EDITOR_MODE.GRAMMAR_TEXT));
1232
1249
  } else if (this.graphEditorMode instanceof GraphEditGrammarModeState) {
1250
+ LegendStudioTelemetryHelper.logEvent_TextModeToggleShortcutInvoked(
1251
+ this.applicationStore.telemetryService,
1252
+ this.editorMode.getSourceInfo(),
1253
+ { source, direction: TEXT_MODE_TOGGLE_DIRECTION.TO_FORM },
1254
+ );
1233
1255
  yield flowResult(this.switchModes(GRAPH_EDITOR_MODE.FORM));
1234
1256
  } else {
1235
1257
  throw new UnsupportedOperationError(
@@ -416,6 +416,7 @@ export class GraphEditFormModeState extends GraphEditorMode {
416
416
  );
417
417
  LegendStudioTelemetryHelper.logEvent_GraphCompilationLaunched(
418
418
  this.editorStore.applicationStore.telemetryService,
419
+ this.editorStore.editorMode.getSourceInfo(),
419
420
  );
420
421
 
421
422
  const currentGraphHash = this.getCurrentGraphHash();
@@ -472,6 +473,7 @@ export class GraphEditFormModeState extends GraphEditorMode {
472
473
  LegendStudioTelemetryHelper.logEvent_GraphCompilationSucceeded(
473
474
  this.editorStore.applicationStore.telemetryService,
474
475
  report,
476
+ this.editorStore.editorMode.getSourceInfo(),
475
477
  );
476
478
 
477
479
  this.editorStore.graphState.setMostRecentCompilationOutcome(
@@ -25,6 +25,7 @@ import {
25
25
  type GraphManagerOperationReport,
26
26
  GRAPH_MANAGER_EVENT,
27
27
  EngineError,
28
+ ParserError,
28
29
  GraphBuilderError,
29
30
  reportGraphAnalytics,
30
31
  INTERNAL__UnknownElement,
@@ -50,7 +51,14 @@ import { TextLocalChangesState } from './sidebar-state/LocalChangesState.js';
50
51
  import { GraphCompilationOutcome, type Problem } from './EditorGraphState.js';
51
52
  import { GRAPH_EDITOR_MODE, PANEL_MODE } from './EditorConfig.js';
52
53
  import { graph_dispose } from '../graph-modifier/GraphModifierHelper.js';
53
- import { LegendStudioTelemetryHelper } from '../../__lib__/LegendStudioTelemetryHelper.js';
54
+ import {
55
+ LegendStudioTelemetryHelper,
56
+ TEXT_MODE_ACTION,
57
+ TEXT_MODE_ACTION_STATUS,
58
+ TEXT_MODE_COMPILATION_ERROR_KIND,
59
+ TEXT_MODE_ENTER_TRIGGER,
60
+ TEXT_MODE_LEAVE_OUTCOME,
61
+ } from '../../__lib__/LegendStudioTelemetryHelper.js';
54
62
  import { GraphEditorMode } from './GraphEditorMode.js';
55
63
  import { ElementEditorState } from './editor-state/element-editor-state/ElementEditorState.js';
56
64
  import { LEGEND_STUDIO_APP_EVENT } from '../../__lib__/LegendStudioEvent.js';
@@ -64,6 +72,12 @@ export class GraphEditGrammarModeState extends GraphEditorMode {
64
72
  grammarTextEditorState: GrammarTextEditorState;
65
73
  generatedFile: FileSystem_File | undefined;
66
74
 
75
+ // Text-mode session telemetry state (not observable; used for analytics only)
76
+ private textModeEnteredAt: number | undefined;
77
+ private textModeEditCount = 0;
78
+ private textModeCompilationCount = 0;
79
+ private textModeHasEmittedFirstEdit = false;
80
+
67
81
  constructor(editorStore: EditorStore) {
68
82
  super(editorStore);
69
83
  makeObservable(this, {
@@ -80,6 +94,81 @@ export class GraphEditGrammarModeState extends GraphEditorMode {
80
94
  return 'Text Mode';
81
95
  }
82
96
 
97
+ /**
98
+ * Whether this is the strict-text (lazy) variant. Overridden by
99
+ * `GraphEditLazyGrammarModeState` to return true.
100
+ */
101
+ protected get isStrictTextMode(): boolean {
102
+ return false;
103
+ }
104
+
105
+ private getCurrentElementPath(): string | undefined {
106
+ const currentTab = this.editorStore.tabManagerState.currentTab;
107
+ return currentTab instanceof ElementEditorState
108
+ ? currentTab.element.path
109
+ : undefined;
110
+ }
111
+
112
+ private startTextModeTelemetrySession(
113
+ trigger: TEXT_MODE_ENTER_TRIGGER,
114
+ ): void {
115
+ this.textModeEnteredAt = Date.now();
116
+ this.textModeEditCount = 0;
117
+ this.textModeCompilationCount = 0;
118
+ this.textModeHasEmittedFirstEdit = false;
119
+ LegendStudioTelemetryHelper.logEvent_TextModeEntered(
120
+ this.editorStore.applicationStore.telemetryService,
121
+ this.editorStore.editorMode.getSourceInfo(),
122
+ {
123
+ trigger,
124
+ strict: this.isStrictTextMode,
125
+ elementPath: this.getCurrentElementPath(),
126
+ },
127
+ );
128
+ if (this.isStrictTextMode) {
129
+ LegendStudioTelemetryHelper.logEvent_TextModeStrictLaunch(
130
+ this.editorStore.applicationStore.telemetryService,
131
+ this.editorStore.editorMode.getSourceInfo(),
132
+ );
133
+ }
134
+ }
135
+
136
+ private emitTextModeLeaveTelemetry(outcome: TEXT_MODE_LEAVE_OUTCOME): void {
137
+ if (this.textModeEnteredAt === undefined) {
138
+ return;
139
+ }
140
+ LegendStudioTelemetryHelper.logEvent_TextModeLeft(
141
+ this.editorStore.applicationStore.telemetryService,
142
+ this.editorStore.editorMode.getSourceInfo(),
143
+ {
144
+ outcome,
145
+ durationMs: Date.now() - this.textModeEnteredAt,
146
+ editCount: this.textModeEditCount,
147
+ compilationCount: this.textModeCompilationCount,
148
+ },
149
+ );
150
+ this.textModeEnteredAt = undefined;
151
+ }
152
+
153
+ /**
154
+ * Notify a user-driven edit in the grammar text buffer. Fires
155
+ * `text-mode.first-edit` once per session.
156
+ */
157
+ notifyGrammarTextEdited(): void {
158
+ if (this.textModeEnteredAt === undefined) {
159
+ return;
160
+ }
161
+ this.textModeEditCount += 1;
162
+ if (!this.textModeHasEmittedFirstEdit) {
163
+ this.textModeHasEmittedFirstEdit = true;
164
+ LegendStudioTelemetryHelper.logEvent_TextModeFirstEdit(
165
+ this.editorStore.applicationStore.telemetryService,
166
+ this.editorStore.editorMode.getSourceInfo(),
167
+ Date.now() - this.textModeEnteredAt,
168
+ );
169
+ }
170
+ }
171
+
83
172
  setGeneratedFile(val: FileSystem_File | undefined): void {
84
173
  this.generatedFile = val;
85
174
  }
@@ -88,6 +177,7 @@ export class GraphEditGrammarModeState extends GraphEditorMode {
88
177
  isCompilationFailure?: boolean;
89
178
  isGraphBuildFailure?: boolean;
90
179
  useStoredEntities?: boolean;
180
+ trigger?: TEXT_MODE_ENTER_TRIGGER;
91
181
  }): GeneratorFn<void> {
92
182
  this.editorStore.localChangesState = new TextLocalChangesState(
93
183
  this.editorStore,
@@ -152,6 +242,16 @@ export class GraphEditGrammarModeState extends GraphEditorMode {
152
242
  });
153
243
  }
154
244
  }
245
+
246
+ // emit text-mode session-start telemetry
247
+ const trigger: TEXT_MODE_ENTER_TRIGGER =
248
+ isFallback?.trigger ??
249
+ (isFallback?.isGraphBuildFailure
250
+ ? TEXT_MODE_ENTER_TRIGGER.FALLBACK_GRAPH_BUILD_FAILURE
251
+ : isFallback?.isCompilationFailure
252
+ ? TEXT_MODE_ENTER_TRIGGER.FALLBACK_FORM_COMPILATION_FAILURE
253
+ : TEXT_MODE_ENTER_TRIGGER.MANUAL_TOGGLE);
254
+ this.startTextModeTelemetrySession(trigger);
155
255
  }
156
256
 
157
257
  *goToElement(elementPath: string): GeneratorFn<void> {
@@ -181,6 +281,14 @@ export class GraphEditGrammarModeState extends GraphEditorMode {
181
281
  LEGEND_STUDIO_APP_EVENT.TEXT_MODE_ACTION_KEYBOARD_SHORTCUT_GO_TO_DEFINITION__SUCCESS,
182
282
  ),
183
283
  );
284
+ LegendStudioTelemetryHelper.logEvent_TextModeAction(
285
+ this.editorStore.applicationStore.telemetryService,
286
+ this.editorStore.editorMode.getSourceInfo(),
287
+ {
288
+ action: TEXT_MODE_ACTION.GO_TO_DEFINITION,
289
+ status: TEXT_MODE_ACTION_STATUS.SUCCESS,
290
+ },
291
+ );
184
292
  } catch (error) {
185
293
  assertErrorThrown(error);
186
294
  this.editorStore.applicationStore.notificationService.notifyError(
@@ -192,6 +300,15 @@ export class GraphEditGrammarModeState extends GraphEditorMode {
192
300
  ),
193
301
  error,
194
302
  );
303
+ LegendStudioTelemetryHelper.logEvent_TextModeAction(
304
+ this.editorStore.applicationStore.telemetryService,
305
+ this.editorStore.editorMode.getSourceInfo(),
306
+ {
307
+ action: TEXT_MODE_ACTION.GO_TO_DEFINITION,
308
+ status: TEXT_MODE_ACTION_STATUS.ERROR,
309
+ errorMessage: error.message,
310
+ },
311
+ );
195
312
  }
196
313
  }
197
314
 
@@ -372,7 +489,9 @@ export class GraphEditGrammarModeState extends GraphEditorMode {
372
489
  );
373
490
  LegendStudioTelemetryHelper.logEvent_TextCompilationLaunched(
374
491
  this.editorStore.applicationStore.telemetryService,
492
+ this.editorStore.editorMode.getSourceInfo(),
375
493
  );
494
+ this.textModeCompilationCount += 1;
376
495
 
377
496
  const currentGraphHash = this.getCurrentGraphHash();
378
497
 
@@ -443,6 +562,7 @@ export class GraphEditGrammarModeState extends GraphEditorMode {
443
562
  LegendStudioTelemetryHelper.logEvent_TextCompilationSucceeded(
444
563
  this.editorStore.applicationStore.telemetryService,
445
564
  report,
565
+ this.editorStore.editorMode.getSourceInfo(),
446
566
  );
447
567
  } catch (error) {
448
568
  assertErrorThrown(error);
@@ -472,6 +592,19 @@ export class GraphEditGrammarModeState extends GraphEditorMode {
472
592
  this.editorStore.graphState.setMostRecentCompilationOutcome(
473
593
  GraphCompilationOutcome.FAILED,
474
594
  );
595
+ LegendStudioTelemetryHelper.logEvent_TextModeCompilationFailure(
596
+ this.editorStore.applicationStore.telemetryService,
597
+ this.editorStore.editorMode.getSourceInfo(),
598
+ {
599
+ errorKind:
600
+ error instanceof ParserError
601
+ ? TEXT_MODE_COMPILATION_ERROR_KIND.PARSER
602
+ : error instanceof EngineError
603
+ ? TEXT_MODE_COMPILATION_ERROR_KIND.COMPILER
604
+ : TEXT_MODE_COMPILATION_ERROR_KIND.OTHER,
605
+ errorMessage: error.message,
606
+ },
607
+ );
475
608
  } finally {
476
609
  this.editorStore.graphState.isRunningGlobalCompile = false;
477
610
  }
@@ -533,6 +666,11 @@ export class GraphEditGrammarModeState extends GraphEditorMode {
533
666
  message: 'Leaving text mode and rebuilding graph...',
534
667
  showLoading: true,
535
668
  });
669
+ this.emitTextModeLeaveTelemetry(
670
+ TEXT_MODE_LEAVE_OUTCOME.COMPILED_AND_LEFT,
671
+ );
672
+ } else {
673
+ this.emitTextModeLeaveTelemetry(TEXT_MODE_LEAVE_OUTCOME.DISCARDED);
536
674
  }
537
675
  }
538
676
 
@@ -56,6 +56,7 @@ export abstract class GraphEditorMode {
56
56
  isCompilationFailure?: boolean;
57
57
  isGraphBuildFailure?: boolean;
58
58
  useStoredEntities?: boolean;
59
+ trigger?: string;
59
60
  }): GeneratorFn<void>;
60
61
  abstract addElement(
61
62
  element: PackageableElement,
@@ -25,16 +25,27 @@ import {
25
25
  generateEditorRoute,
26
26
  generateViewProjectByGAVRoute,
27
27
  } from '../../__lib__/LegendStudioNavigation.js';
28
- import { EditorMode, type LegendStudioSourceType } from './EditorMode.js';
28
+ import { EditorMode, LegendStudioSourceType } from './EditorMode.js';
29
29
  import type { LegendSourceInfo } from '@finos/legend-storage';
30
30
 
31
31
  export interface WorkspaceProjectQuerySDLC extends LegendSourceInfo {
32
32
  sourceType: LegendStudioSourceType.PROJECT_WORKSPACE;
33
33
  projectId: string;
34
34
  workspaceId: string;
35
- WorkspaceType: string;
36
- userId?: string;
37
- source?: string;
35
+ workspaceType: string;
36
+ /** Set only for USER workspaces (owner id); undefined for GROUP. */
37
+ userId?: string | undefined;
38
+ /**
39
+ * Optional SDLC-side hint about where the workspace originated
40
+ * (e.g. `legend-query` productionization). Free-form string until SDLC
41
+ * formalizes a `SourceType` enum.
42
+ */
43
+ source?: string | undefined;
44
+ /**
45
+ * Patch release the workspace is targeting, when the workspace lives on a
46
+ * patch branch. Undefined for regular workspaces on main.
47
+ */
48
+ patchReleaseVersionId?: string | undefined;
38
49
  }
39
50
 
40
51
  export class StandardEditorMode extends EditorMode {
@@ -76,18 +87,21 @@ export class StandardEditorMode extends EditorMode {
76
87
  );
77
88
  }
78
89
 
79
- getSourceInfo(): LegendSourceInfo | undefined {
90
+ getSourceInfo(): WorkspaceProjectQuerySDLC | undefined {
80
91
  if (this.isInitialized) {
81
92
  const workspace = guaranteeNonNullable(
82
93
  this.editorStore.sdlcState.currentWorkspace,
83
94
  );
84
95
  return {
96
+ sourceType: LegendStudioSourceType.PROJECT_WORKSPACE,
85
97
  projectId: this.editorStore.sdlcState.activeProject.projectId,
86
98
  workspaceId: workspace.workspaceId,
87
- WorkspaceType: workspace.workspaceType,
99
+ workspaceType: workspace.workspaceType,
88
100
  userId: workspace.userId,
89
101
  source: workspace.source,
90
- } as WorkspaceProjectQuerySDLC;
102
+ patchReleaseVersionId:
103
+ this.editorStore.sdlcState.activePatch?.patchReleaseVersionId.id,
104
+ };
91
105
  } else {
92
106
  return undefined;
93
107
  }