@finos/legend-query-builder 4.19.13 → 4.19.14

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.
@@ -266,18 +266,36 @@ export const QueryBuilder = observer(
266
266
  );
267
267
  };
268
268
  const toggleShowParameterPanel = (): void => {
269
- queryBuilderState.setShowParametersPanel(
270
- !queryBuilderState.showParametersPanel,
269
+ const nextEnabled = !queryBuilderState.showParametersPanel;
270
+ queryBuilderState.setShowParametersPanel(nextEnabled);
271
+ QueryBuilderTelemetryHelper.logEvent_TogglePanelParameter(
272
+ applicationStore.telemetryService,
273
+ {
274
+ ...queryBuilderState.safeGetTelemetryContext(),
275
+ enabled: nextEnabled,
276
+ },
271
277
  );
272
278
  };
273
279
  const toggleConstantPanel = (): void => {
274
- queryBuilderState.constantState.setShowConstantPanel(
275
- !queryBuilderState.constantState.showConstantPanel,
280
+ const nextEnabled = !queryBuilderState.constantState.showConstantPanel;
281
+ queryBuilderState.constantState.setShowConstantPanel(nextEnabled);
282
+ QueryBuilderTelemetryHelper.logEvent_TogglePanelConstant(
283
+ applicationStore.telemetryService,
284
+ {
285
+ ...queryBuilderState.safeGetTelemetryContext(),
286
+ enabled: nextEnabled,
287
+ },
276
288
  );
277
289
  };
278
290
  const toggleShowFilterPanel = (): void => {
279
- queryBuilderState.filterState.setShowPanel(
280
- !queryBuilderState.filterState.showPanel,
291
+ const nextEnabled = !queryBuilderState.filterState.showPanel;
292
+ queryBuilderState.filterState.setShowPanel(nextEnabled);
293
+ QueryBuilderTelemetryHelper.logEvent_TogglePanelFilter(
294
+ applicationStore.telemetryService,
295
+ {
296
+ ...queryBuilderState.safeGetTelemetryContext(),
297
+ enabled: nextEnabled,
298
+ },
281
299
  );
282
300
  };
283
301
  const toggleShowPostFilterPanel = (): void => {
@@ -291,6 +309,13 @@ export const QueryBuilder = observer(
291
309
  QUERY_BUILDER_SETTING_KEY.SHOW_POST_FILTER_PANEL,
292
310
  tdsState.showPostFilterPanel,
293
311
  );
312
+ QueryBuilderTelemetryHelper.logEvent_TogglePanelPostFilter(
313
+ applicationStore.telemetryService,
314
+ {
315
+ ...queryBuilderState.safeGetTelemetryContext(),
316
+ enabled: tdsState.showPostFilterPanel,
317
+ },
318
+ );
294
319
  }
295
320
  };
296
321
 
@@ -312,6 +337,13 @@ export const QueryBuilder = observer(
312
337
  ) {
313
338
  queryBuilderState.fetchStructureState.implementation.aggregationState.disableCalendar();
314
339
  }
340
+ QueryBuilderTelemetryHelper.logEvent_ToggleCalendar(
341
+ applicationStore.telemetryService,
342
+ {
343
+ ...queryBuilderState.safeGetTelemetryContext(),
344
+ enabled: false,
345
+ },
346
+ );
315
347
  },
316
348
  },
317
349
  {
@@ -331,7 +363,16 @@ export const QueryBuilder = observer(
331
363
  {
332
364
  label: 'Proceed',
333
365
  type: ActionAlertActionType.PROCEED_WITH_CAUTION,
334
- handler: (): void => queryBuilderState.setIsCalendarEnabled(true),
366
+ handler: (): void => {
367
+ queryBuilderState.setIsCalendarEnabled(true);
368
+ QueryBuilderTelemetryHelper.logEvent_ToggleCalendar(
369
+ applicationStore.telemetryService,
370
+ {
371
+ ...queryBuilderState.safeGetTelemetryContext(),
372
+ enabled: true,
373
+ },
374
+ );
375
+ },
335
376
  },
336
377
  {
337
378
  label: 'Cancel',
@@ -348,6 +389,13 @@ export const QueryBuilder = observer(
348
389
  queryBuilderState.setLambdaWriteMode(
349
390
  QUERY_BUILDER_LAMBDA_WRITER_MODE.STANDARD,
350
391
  );
392
+ QueryBuilderTelemetryHelper.logEvent_ToggleTypedTDS(
393
+ applicationStore.telemetryService,
394
+ {
395
+ ...queryBuilderState.safeGetTelemetryContext(),
396
+ enabled: false,
397
+ },
398
+ );
351
399
  } else {
352
400
  queryBuilderState.applicationStore.alertService.setActionAlertInfo({
353
401
  message:
@@ -358,10 +406,18 @@ export const QueryBuilder = observer(
358
406
  {
359
407
  label: 'Proceed',
360
408
  type: ActionAlertActionType.PROCEED_WITH_CAUTION,
361
- handler: (): void =>
409
+ handler: (): void => {
362
410
  queryBuilderState.setLambdaWriteMode(
363
411
  QUERY_BUILDER_LAMBDA_WRITER_MODE.TYPED_FETCH_STRUCTURE,
364
- ),
412
+ );
413
+ QueryBuilderTelemetryHelper.logEvent_ToggleTypedTDS(
414
+ applicationStore.telemetryService,
415
+ {
416
+ ...queryBuilderState.safeGetTelemetryContext(),
417
+ enabled: true,
418
+ },
419
+ );
420
+ },
365
421
  },
366
422
  {
367
423
  label: 'Cancel',
@@ -374,16 +430,32 @@ export const QueryBuilder = observer(
374
430
  };
375
431
 
376
432
  const editPure = (): void => {
433
+ QueryBuilderTelemetryHelper.logEvent_EditPureLaunched(
434
+ applicationStore.telemetryService,
435
+ queryBuilderState.safeGetTelemetryContext(),
436
+ );
377
437
  openLambdaEditor(QueryBuilderTextEditorMode.TEXT);
378
438
  };
379
439
  const showPure = (): void => {
440
+ QueryBuilderTelemetryHelper.logEvent_ShowPureLaunched(
441
+ applicationStore.telemetryService,
442
+ queryBuilderState.safeGetTelemetryContext(),
443
+ );
380
444
  openPure();
381
445
  };
382
446
  const showProtocol = (): void => {
447
+ QueryBuilderTelemetryHelper.logEvent_ShowProtocolLaunched(
448
+ applicationStore.telemetryService,
449
+ queryBuilderState.safeGetTelemetryContext(),
450
+ );
383
451
  openLambdaEditor(QueryBuilderTextEditorMode.JSON);
384
452
  };
385
453
 
386
454
  const openCheckEntitlmentsEditor = (): void => {
455
+ QueryBuilderTelemetryHelper.logEvent_CheckEntitlementsLaunched(
456
+ applicationStore.telemetryService,
457
+ queryBuilderState.safeGetTelemetryContext(),
458
+ );
387
459
  queryBuilderState.checkEntitlementsState.setShowCheckEntitlementsViewer(
388
460
  true,
389
461
  );
@@ -400,7 +472,15 @@ export const QueryBuilder = observer(
400
472
  queryBuilderState.fetchStructureState.implementation,
401
473
  QueryBuilderTDSState,
402
474
  );
403
- tdsState.setShowWindowFuncPanel(!tdsState.showWindowFuncPanel);
475
+ const nextEnabled = !tdsState.showWindowFuncPanel;
476
+ tdsState.setShowWindowFuncPanel(nextEnabled);
477
+ QueryBuilderTelemetryHelper.logEvent_TogglePanelWindow(
478
+ applicationStore.telemetryService,
479
+ {
480
+ ...queryBuilderState.safeGetTelemetryContext(),
481
+ enabled: nextEnabled,
482
+ },
483
+ );
404
484
  }
405
485
  };
406
486
  const showPostFetchStructurePanel =
@@ -447,6 +527,10 @@ export const QueryBuilder = observer(
447
527
  );
448
528
  const openQueryTutorial = (): void => {
449
529
  if (queryDocEntry?.url) {
530
+ QueryBuilderTelemetryHelper.logEvent_OpenDocumentationLaunched(
531
+ applicationStore.telemetryService,
532
+ queryBuilderState.safeGetTelemetryContext(),
533
+ );
450
534
  applicationStore.navigationService.navigator.visitAddress(
451
535
  queryDocEntry.url,
452
536
  );
@@ -454,6 +538,10 @@ export const QueryBuilder = observer(
454
538
  };
455
539
  const openFrequentlyAskedQuestions = (): void => {
456
540
  if (frequentlyAskedQuestionEntry?.url) {
541
+ QueryBuilderTelemetryHelper.logEvent_OpenFAQLaunched(
542
+ applicationStore.telemetryService,
543
+ queryBuilderState.safeGetTelemetryContext(),
544
+ );
457
545
  applicationStore.navigationService.navigator.visitAddress(
458
546
  frequentlyAskedQuestionEntry.url,
459
547
  );
@@ -461,14 +549,28 @@ export const QueryBuilder = observer(
461
549
  };
462
550
  const openSupportTickets = (): void => {
463
551
  if (supportTicketsEntry?.url) {
552
+ QueryBuilderTelemetryHelper.logEvent_OpenSupportTicketsLaunched(
553
+ applicationStore.telemetryService,
554
+ queryBuilderState.safeGetTelemetryContext(),
555
+ );
464
556
  applicationStore.navigationService.navigator.visitAddress(
465
557
  supportTicketsEntry.url,
466
558
  );
467
559
  }
468
560
  };
469
561
 
470
- const toggleAssistant = (): void =>
562
+ const toggleAssistant = (): void => {
471
563
  applicationStore.assistantService.toggleAssistant();
564
+ // Read the post-toggle state directly rather than pre-computing it —
565
+ // avoids drifting if `toggleAssistant()` ever becomes non-symmetric.
566
+ QueryBuilderTelemetryHelper.logEvent_ToggleVirtualAssistant(
567
+ applicationStore.telemetryService,
568
+ {
569
+ ...queryBuilderState.safeGetTelemetryContext(),
570
+ enabled: !applicationStore.assistantService.isHidden,
571
+ },
572
+ );
573
+ };
472
574
 
473
575
  const extraHelpMenuContentItems = applicationStore.pluginManager
474
576
  .getApplicationPlugins()
@@ -491,11 +593,20 @@ export const QueryBuilder = observer(
491
593
  </MenuContentItem>
492
594
  ));
493
595
 
494
- const compileQuery = applicationStore.guardUnhandledError(() =>
495
- flowResult(queryBuilderState.compileQuery()),
496
- );
497
- const showDiff = (): void =>
596
+ const compileQuery = applicationStore.guardUnhandledError(() => {
597
+ QueryBuilderTelemetryHelper.logEvent_CompileQueryLaunched(
598
+ applicationStore.telemetryService,
599
+ queryBuilderState.safeGetTelemetryContext(),
600
+ );
601
+ return flowResult(queryBuilderState.compileQuery());
602
+ });
603
+ const showDiff = (): void => {
604
+ QueryBuilderTelemetryHelper.logEvent_ShowQueryDiffLaunched(
605
+ applicationStore.telemetryService,
606
+ queryBuilderState.safeGetTelemetryContext(),
607
+ );
498
608
  queryBuilderState.changeDetectionState.showDiffViewPanel();
609
+ };
499
610
 
500
611
  useEffect(() => {
501
612
  // this condition is for passing all exisitng tests because when we initialize a queryBuilderState for a test,
package/src/index.ts CHANGED
@@ -36,6 +36,7 @@ export { QUERY_BUILDER_COMPONENT_ELEMENT_ID } from './components/QueryBuilderCom
36
36
  export {
37
37
  type QueryBuilderExtraFunctionAnalysisInfo,
38
38
  type EntityWithOriginOption,
39
+ type QueryBuilderTelemetryContext,
39
40
  QueryBuilderState,
40
41
  ExtraOptionsConfig,
41
42
  BaseQueryBuilderState,
@@ -26,6 +26,7 @@ import {
26
26
  type GeneratorFn,
27
27
  LogEvent,
28
28
  assertErrorThrown,
29
+ buildTelemetryErrorFields,
29
30
  guaranteeNonNullable,
30
31
  guaranteeType,
31
32
  filterByType,
@@ -186,6 +187,14 @@ export type QueryBuilderTelemetryContext = QueryableSourceInfo &
186
187
  */
187
188
  export type QueryBuilderQueryInfo = {
188
189
  fetchStructureType: FETCH_STRUCTURE_IMPLEMENTATION | string;
190
+ /**
191
+ * `false` when the query lambda could not be built into the form-mode
192
+ * builder and the user landed on the raw-lambda / unsupported-query editor
193
+ * instead. Reported on every event that carries `queryInfo` so dashboards can
194
+ * separate supported-mode activity from unsupported-mode fallback without
195
+ * relying on the (fire-and-forget) `unsupported-query.launch` event alone.
196
+ */
197
+ isQuerySupported: boolean;
189
198
  /**
190
199
  * `true` when the TDS query is authored against the typed relation function
191
200
  * family (`->project`/`->groupBy`/etc. over relation columns). `false` for
@@ -645,6 +654,7 @@ export abstract class QueryBuilderState implements CommandRegistrar {
645
654
  getQueryInfo(): QueryBuilderQueryInfo {
646
655
  const base: QueryBuilderQueryInfo = {
647
656
  fetchStructureType: this.fetchStructureState.implementation.type,
657
+ isQuerySupported: !this.unsupportedQueryState.rawLambda,
648
658
  parameterCount: this.parametersState.parameterStates.length,
649
659
  constantCount: this.constantState.constants.length,
650
660
  hasFilter: !this.filterState.isEmpty,
@@ -1185,6 +1195,17 @@ export abstract class QueryBuilderState implements CommandRegistrar {
1185
1195
  LogEvent.create(QUERY_BUILDER_EVENT.UNSUPPORTED_QUERY_LAUNCH),
1186
1196
  error,
1187
1197
  );
1198
+ // Also route to the telemetry service so unsupported-lambda fallback is
1199
+ // countable per entry point / GAV, not just visible in developer logs.
1200
+ // The full untruncated stack is already in `logService.error` above; this
1201
+ // event carries the shared envelope + capped error dimensions.
1202
+ QueryBuilderTelemetryHelper.logEvent_UnsupportedQueryLaunched(
1203
+ this.applicationStore.telemetryService,
1204
+ {
1205
+ ...this.safeGetTelemetryContext(),
1206
+ ...buildTelemetryErrorFields(error),
1207
+ },
1208
+ );
1188
1209
  this.resetQueryResult({ preserveResult: options?.preserveResult });
1189
1210
  this.resetQueryContent();
1190
1211
  this.unsupportedQueryState.setLambdaError(error);