@finos/legend-query-builder 4.19.12 → 4.19.13

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 (118) hide show
  1. package/lib/__lib__/QueryBuilderDocumentation.d.ts +2 -1
  2. package/lib/__lib__/QueryBuilderDocumentation.d.ts.map +1 -1
  3. package/lib/__lib__/QueryBuilderDocumentation.js +1 -0
  4. package/lib/__lib__/QueryBuilderDocumentation.js.map +1 -1
  5. package/lib/__lib__/QueryBuilderEvent.d.ts +45 -1
  6. package/lib/__lib__/QueryBuilderEvent.d.ts.map +1 -1
  7. package/lib/__lib__/QueryBuilderEvent.js +48 -0
  8. package/lib/__lib__/QueryBuilderEvent.js.map +1 -1
  9. package/lib/__lib__/QueryBuilderTelemetryHelper.d.ts +162 -8
  10. package/lib/__lib__/QueryBuilderTelemetryHelper.d.ts.map +1 -1
  11. package/lib/__lib__/QueryBuilderTelemetryHelper.js +48 -0
  12. package/lib/__lib__/QueryBuilderTelemetryHelper.js.map +1 -1
  13. package/lib/components/QueryBuilder.d.ts.map +1 -1
  14. package/lib/components/QueryBuilder.js +9 -5
  15. package/lib/components/QueryBuilder.js.map +1 -1
  16. package/lib/components/QueryBuilderConstantExpressionPanel.d.ts.map +1 -1
  17. package/lib/components/QueryBuilderConstantExpressionPanel.js +18 -1
  18. package/lib/components/QueryBuilderConstantExpressionPanel.js.map +1 -1
  19. package/lib/components/QueryBuilderParametersPanel.d.ts.map +1 -1
  20. package/lib/components/QueryBuilderParametersPanel.js +18 -1
  21. package/lib/components/QueryBuilderParametersPanel.js.map +1 -1
  22. package/lib/components/QueryBuilderSideBar.d.ts.map +1 -1
  23. package/lib/components/QueryBuilderSideBar.js +19 -0
  24. package/lib/components/QueryBuilderSideBar.js.map +1 -1
  25. package/lib/components/fetch-structure/QueryBuilderGraphFetchTreePanel.d.ts.map +1 -1
  26. package/lib/components/fetch-structure/QueryBuilderGraphFetchTreePanel.js +42 -1
  27. package/lib/components/fetch-structure/QueryBuilderGraphFetchTreePanel.js.map +1 -1
  28. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.d.ts.map +1 -1
  29. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js +25 -5
  30. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js.map +1 -1
  31. package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.d.ts.map +1 -1
  32. package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.js +55 -0
  33. package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.js.map +1 -1
  34. package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
  35. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +95 -8
  36. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
  37. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.d.ts.map +1 -1
  38. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.js +37 -4
  39. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.js.map +1 -1
  40. package/lib/components/filter/QueryBuilderFilterPanel.d.ts.map +1 -1
  41. package/lib/components/filter/QueryBuilderFilterPanel.js +24 -5
  42. package/lib/components/filter/QueryBuilderFilterPanel.js.map +1 -1
  43. package/lib/components/result/QueryBuilderDataProductErrorPanel.d.ts +61 -0
  44. package/lib/components/result/QueryBuilderDataProductErrorPanel.d.ts.map +1 -0
  45. package/lib/components/result/QueryBuilderDataProductErrorPanel.js +176 -0
  46. package/lib/components/result/QueryBuilderDataProductErrorPanel.js.map +1 -0
  47. package/lib/components/result/QueryBuilderResultPanel.d.ts.map +1 -1
  48. package/lib/components/result/QueryBuilderResultPanel.js +24 -18
  49. package/lib/components/result/QueryBuilderResultPanel.js.map +1 -1
  50. package/lib/data-access-overview.css +1 -1
  51. package/lib/index.css +2 -2
  52. package/lib/index.css.map +1 -1
  53. package/lib/index.d.ts +1 -0
  54. package/lib/index.d.ts.map +1 -1
  55. package/lib/index.js +1 -0
  56. package/lib/index.js.map +1 -1
  57. package/lib/package.json +1 -1
  58. package/lib/stores/QueryBuilderResultState.d.ts +11 -1
  59. package/lib/stores/QueryBuilderResultState.d.ts.map +1 -1
  60. package/lib/stores/QueryBuilderResultState.js +79 -15
  61. package/lib/stores/QueryBuilderResultState.js.map +1 -1
  62. package/lib/stores/QueryBuilderState.d.ts +131 -9
  63. package/lib/stores/QueryBuilderState.d.ts.map +1 -1
  64. package/lib/stores/QueryBuilderState.js +124 -21
  65. package/lib/stores/QueryBuilderState.js.map +1 -1
  66. package/lib/stores/QueryBuilder_LegendApplicationPlugin_Extension.d.ts +13 -0
  67. package/lib/stores/QueryBuilder_LegendApplicationPlugin_Extension.d.ts.map +1 -1
  68. package/lib/stores/QueryLoaderState.d.ts +33 -5
  69. package/lib/stores/QueryLoaderState.d.ts.map +1 -1
  70. package/lib/stores/QueryLoaderState.js +10 -1
  71. package/lib/stores/QueryLoaderState.js.map +1 -1
  72. package/lib/stores/data-access/DataProductAccessInfo.d.ts +37 -0
  73. package/lib/stores/data-access/DataProductAccessInfo.d.ts.map +1 -0
  74. package/lib/stores/data-access/DataProductAccessInfo.js +17 -0
  75. package/lib/stores/data-access/DataProductAccessInfo.js.map +1 -0
  76. package/lib/stores/data-cube/QueryBuilderDataCubeEngine.js +1 -1
  77. package/lib/stores/data-cube/QueryBuilderDataCubeEngine.js.map +1 -1
  78. package/lib/stores/explorer/QueryBuilderExplorerState.js +1 -1
  79. package/lib/stores/explorer/QueryBuilderExplorerState.js.map +1 -1
  80. package/lib/stores/milestoning/QueryBuilderMilestoningHelper.d.ts.map +1 -1
  81. package/lib/stores/milestoning/QueryBuilderMilestoningHelper.js +34 -9
  82. package/lib/stores/milestoning/QueryBuilderMilestoningHelper.js.map +1 -1
  83. package/lib/stores/milestoning/QueryBuilderMilestoningState.d.ts +5 -0
  84. package/lib/stores/milestoning/QueryBuilderMilestoningState.d.ts.map +1 -1
  85. package/lib/stores/milestoning/QueryBuilderMilestoningState.js +13 -0
  86. package/lib/stores/milestoning/QueryBuilderMilestoningState.js.map +1 -1
  87. package/lib/stores/workflows/dataProduct/DataProductQueryBuilderState.d.ts +2 -0
  88. package/lib/stores/workflows/dataProduct/DataProductQueryBuilderState.d.ts.map +1 -1
  89. package/lib/stores/workflows/dataProduct/DataProductQueryBuilderState.js +50 -1
  90. package/lib/stores/workflows/dataProduct/DataProductQueryBuilderState.js.map +1 -1
  91. package/package.json +10 -10
  92. package/src/__lib__/QueryBuilderDocumentation.ts +1 -0
  93. package/src/__lib__/QueryBuilderEvent.ts +52 -0
  94. package/src/__lib__/QueryBuilderTelemetryHelper.ts +292 -8
  95. package/src/components/QueryBuilder.tsx +31 -23
  96. package/src/components/QueryBuilderConstantExpressionPanel.tsx +24 -2
  97. package/src/components/QueryBuilderParametersPanel.tsx +25 -2
  98. package/src/components/QueryBuilderSideBar.tsx +28 -0
  99. package/src/components/fetch-structure/QueryBuilderGraphFetchTreePanel.tsx +56 -1
  100. package/src/components/fetch-structure/QueryBuilderPostFilterPanel.tsx +31 -4
  101. package/src/components/fetch-structure/QueryBuilderResultModifierPanel.tsx +74 -0
  102. package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +123 -8
  103. package/src/components/fetch-structure/QueryBuilderTDSWindowPanel.tsx +49 -4
  104. package/src/components/filter/QueryBuilderFilterPanel.tsx +31 -4
  105. package/src/components/result/QueryBuilderDataProductErrorPanel.tsx +441 -0
  106. package/src/components/result/QueryBuilderResultPanel.tsx +49 -32
  107. package/src/index.ts +1 -0
  108. package/src/stores/QueryBuilderResultState.ts +107 -19
  109. package/src/stores/QueryBuilderState.ts +239 -29
  110. package/src/stores/QueryBuilder_LegendApplicationPlugin_Extension.ts +20 -0
  111. package/src/stores/QueryLoaderState.ts +47 -6
  112. package/src/stores/data-access/DataProductAccessInfo.ts +37 -0
  113. package/src/stores/data-cube/QueryBuilderDataCubeEngine.ts +1 -1
  114. package/src/stores/explorer/QueryBuilderExplorerState.ts +1 -1
  115. package/src/stores/milestoning/QueryBuilderMilestoningHelper.ts +63 -8
  116. package/src/stores/milestoning/QueryBuilderMilestoningState.ts +20 -0
  117. package/src/stores/workflows/dataProduct/DataProductQueryBuilderState.ts +68 -0
  118. package/tsconfig.json +2 -0
@@ -144,8 +144,19 @@ const QueryBuilderPostFilterConditionContextMenu = observer(
144
144
  >(function QueryBuilderPostFilterConditionContextMenu(props, ref) {
145
145
  const { tdsState, node } = props;
146
146
  const postFilterState = tdsState.postFilterState;
147
- const removeNode = (): void =>
147
+ const applicationStore = useApplicationStore();
148
+ const removeNode = (): void => {
148
149
  postFilterState.removeNodeAndPruneBranch(node);
150
+ QueryBuilderTelemetryHelper.logEvent_PostFilterChanged(
151
+ applicationStore.telemetryService,
152
+ {
153
+ ...tdsState.queryBuilderState.safeGetTelemetryContext(),
154
+ change: {
155
+ action: 'remove',
156
+ },
157
+ },
158
+ );
159
+ };
149
160
  const createCondition = (): void => {
150
161
  postFilterState.addNodeFromNode(
151
162
  new QueryBuilderPostFilterTreeBlankConditionNodeData(undefined),
@@ -184,19 +195,34 @@ const QueryBuilderPostFilterConditionContextMenu = observer(
184
195
 
185
196
  const QueryBuilderPostFilterGroupConditionEditor = observer(
186
197
  (props: {
198
+ tdsState: QueryBuilderTDSState;
187
199
  node: QueryBuilderPostFilterTreeGroupNodeData;
188
200
  isDragOver: boolean;
189
201
  isDroppable: boolean;
190
202
  }) => {
191
- const { node, isDragOver, isDroppable } = props;
203
+ const { tdsState, node, isDragOver, isDroppable } = props;
204
+ const applicationStore = useApplicationStore();
192
205
  const switchOperation: React.MouseEventHandler<HTMLDivElement> = (
193
206
  event,
194
207
  ): void => {
195
208
  event.stopPropagation(); // prevent triggering selecting the node
196
- node.setGroupOperation(
209
+ const nextOperation =
197
210
  node.groupOperation === QUERY_BUILDER_GROUP_OPERATION.AND
198
211
  ? QUERY_BUILDER_GROUP_OPERATION.OR
199
- : QUERY_BUILDER_GROUP_OPERATION.AND,
212
+ : QUERY_BUILDER_GROUP_OPERATION.AND;
213
+ node.setGroupOperation(nextOperation);
214
+ QueryBuilderTelemetryHelper.logEvent_PostFilterChanged(
215
+ applicationStore.telemetryService,
216
+ {
217
+ ...tdsState.queryBuilderState.safeGetTelemetryContext(),
218
+ change: {
219
+ action: 'group-operation-change',
220
+ groupOperation:
221
+ nextOperation === QUERY_BUILDER_GROUP_OPERATION.AND
222
+ ? 'and'
223
+ : 'or',
224
+ },
225
+ },
200
226
  );
201
227
  };
202
228
 
@@ -771,6 +797,7 @@ const QueryBuilderPostFilterTreeNodeContainer = observer(
771
797
  >
772
798
  {node instanceof QueryBuilderPostFilterTreeGroupNodeData && (
773
799
  <QueryBuilderPostFilterGroupConditionEditor
800
+ tdsState={tdsState}
774
801
  node={node}
775
802
  isDroppable={isDroppable}
776
803
  isDragOver={isDragOver}
@@ -37,6 +37,7 @@ import {
37
37
  PanelFormListItems,
38
38
  } from '@finos/legend-art';
39
39
  import { SortColumnState } from '../../stores/fetch-structure/tds/QueryResultSetModifierState.js';
40
+ import { QueryBuilderTelemetryHelper } from '../../__lib__/QueryBuilderTelemetryHelper.js';
40
41
  import {
41
42
  addUniqueEntry,
42
43
  clone,
@@ -646,6 +647,12 @@ export const QueryResultModifierModal = observer(
646
647
  };
647
648
 
648
649
  const applyChanges = (): void => {
650
+ const previousWatermarkValue = watermarkState.value;
651
+ const previousBusinessDate = milestoningState.businessDate;
652
+ const previousProcessingDate = milestoningState.processingDate;
653
+ const wasAllVersionsEnabled = milestoningState.isAllVersionsEnabled;
654
+ const wasAllVersionsInRangeEnabled =
655
+ milestoningState.isAllVersionsInRangeEnabled;
649
656
  resultSetModifierState.setSortColumns(sortColumns);
650
657
  resultSetModifierState.setDistinct(distinct);
651
658
  resultSetModifierState.setLimit(limitResults);
@@ -655,7 +662,30 @@ export const QueryResultModifierModal = observer(
655
662
  resultSetModifierState.setSlice(undefined);
656
663
  }
657
664
  resultSetModifierState.setShowModal(false);
665
+ QueryBuilderTelemetryHelper.logEvent_ResultModifierChanged(
666
+ applicationStore.telemetryService,
667
+ {
668
+ ...tdsState.queryBuilderState.safeGetTelemetryContext(),
669
+ change: {
670
+ limitSet: resultSetModifierState.limit !== undefined,
671
+ distinctOn: resultSetModifierState.distinct,
672
+ sortColumnCount: resultSetModifierState.sortColumns.length,
673
+ sliceSet: resultSetModifierState.slice !== undefined,
674
+ },
675
+ },
676
+ );
658
677
  watermarkState.setValue(watermarkValue);
678
+ if (watermarkValue !== previousWatermarkValue) {
679
+ QueryBuilderTelemetryHelper.logEvent_WatermarkChanged(
680
+ applicationStore.telemetryService,
681
+ {
682
+ ...tdsState.queryBuilderState.safeGetTelemetryContext(),
683
+ change: {
684
+ enabled: watermarkValue !== undefined,
685
+ },
686
+ },
687
+ );
688
+ }
659
689
  milestoningState.queryBuilderState.parametersState.setParameters(
660
690
  parameterStates,
661
691
  );
@@ -671,11 +701,33 @@ export const QueryResultModifierModal = observer(
671
701
  startDateValue,
672
702
  );
673
703
  milestoningState.updateMilestoningParameterValue(endDate, endDateValue);
704
+ if (!wasAllVersionsInRangeEnabled) {
705
+ QueryBuilderTelemetryHelper.logEvent_MilestoningChanged(
706
+ applicationStore.telemetryService,
707
+ {
708
+ ...tdsState.queryBuilderState.safeGetTelemetryContext(),
709
+ change: {
710
+ subtype: 'all-versions-in-range',
711
+ },
712
+ },
713
+ );
714
+ }
674
715
  } else if (isAllVersionsEnabled) {
675
716
  milestoningState.clearGetAllParameters();
676
717
  milestoningState.queryBuilderState.setGetAllFunction(
677
718
  QUERY_BUILDER_SUPPORTED_GET_ALL_FUNCTIONS.GET_ALL_VERSIONS,
678
719
  );
720
+ if (!wasAllVersionsEnabled) {
721
+ QueryBuilderTelemetryHelper.logEvent_MilestoningChanged(
722
+ applicationStore.telemetryService,
723
+ {
724
+ ...tdsState.queryBuilderState.safeGetTelemetryContext(),
725
+ change: {
726
+ subtype: 'all-versions',
727
+ },
728
+ },
729
+ );
730
+ }
679
731
  } else if (
680
732
  tdsState.queryBuilderState.milestoningState.isMilestonedQuery
681
733
  ) {
@@ -693,6 +745,28 @@ export const QueryResultModifierModal = observer(
693
745
  businessDate,
694
746
  businessDateValue,
695
747
  );
748
+ if (businessDate !== previousBusinessDate) {
749
+ QueryBuilderTelemetryHelper.logEvent_MilestoningChanged(
750
+ applicationStore.telemetryService,
751
+ {
752
+ ...tdsState.queryBuilderState.safeGetTelemetryContext(),
753
+ change: {
754
+ subtype: 'business-date',
755
+ },
756
+ },
757
+ );
758
+ }
759
+ if (processingDate !== previousProcessingDate) {
760
+ QueryBuilderTelemetryHelper.logEvent_MilestoningChanged(
761
+ applicationStore.telemetryService,
762
+ {
763
+ ...tdsState.queryBuilderState.safeGetTelemetryContext(),
764
+ change: {
765
+ subtype: 'processing-date',
766
+ },
767
+ },
768
+ );
769
+ }
696
770
  }
697
771
  milestoningState.updateQueryBuilderState();
698
772
  };
@@ -70,6 +70,7 @@ import {
70
70
  } from '../QueryBuilderPropertyExpressionEditor.js';
71
71
  import { QueryResultModifierModal } from './QueryBuilderResultModifierPanel.js';
72
72
  import { QUERY_BUILDER_TEST_ID } from '../../__lib__/QueryBuilderTesting.js';
73
+ import { QueryBuilderTelemetryHelper } from '../../__lib__/QueryBuilderTelemetryHelper.js';
73
74
  import { flowResult } from 'mobx';
74
75
  import { useApplicationStore } from '@finos/legend-application';
75
76
  import {
@@ -167,8 +168,20 @@ const QueryBuilderProjectionColumnContextMenu = observer(
167
168
  }
168
169
  >(function QueryBuilderProjectionColumnContextMenu(props, ref) {
169
170
  const { projectionColumnState } = props;
170
- const removeColumn = (): void =>
171
- projectionColumnState.tdsState.removeColumn(projectionColumnState);
171
+ const removeColumn = (): void => {
172
+ const tdsState = projectionColumnState.tdsState;
173
+ tdsState.removeColumn(projectionColumnState);
174
+ QueryBuilderTelemetryHelper.logEvent_ProjectionChanged(
175
+ tdsState.queryBuilderState.applicationStore.telemetryService,
176
+ {
177
+ ...tdsState.queryBuilderState.safeGetTelemetryContext(),
178
+ change: {
179
+ action: 'remove',
180
+ columnCount: tdsState.projectionColumns.length,
181
+ },
182
+ },
183
+ );
184
+ };
172
185
  const convertToDerivation = (): void => {
173
186
  if (
174
187
  projectionColumnState instanceof QueryBuilderSimpleProjectionColumnState
@@ -418,8 +431,19 @@ const QueryBuilderProjectionColumnEditor = observer(
418
431
  const isCalendarEnabled = tdsState.queryBuilderState.isCalendarEnabled;
419
432
  const isRemovalDisabled = tdsState.isColumnInUse(projectionColumnState);
420
433
 
421
- const removeColumn = (): void =>
434
+ const removeColumn = (): void => {
422
435
  tdsState.removeColumn(projectionColumnState);
436
+ QueryBuilderTelemetryHelper.logEvent_ProjectionChanged(
437
+ applicationStore.telemetryService,
438
+ {
439
+ ...tdsState.queryBuilderState.safeGetTelemetryContext(),
440
+ change: {
441
+ action: 'remove',
442
+ columnCount: tdsState.projectionColumns.length,
443
+ },
444
+ },
445
+ );
446
+ };
423
447
 
424
448
  // name
425
449
  const setColumnName = (columnName: string): void =>
@@ -435,11 +459,22 @@ const QueryBuilderProjectionColumnEditor = observer(
435
459
  op.isCompatibleWithColumn(projectionColumnState),
436
460
  );
437
461
  const changeOperator =
438
- (val: QueryBuilderAggregateOperator | undefined) => (): void =>
462
+ (val: QueryBuilderAggregateOperator | undefined) => (): void => {
439
463
  tdsState.aggregationState.changeColumnAggregateOperator(
440
464
  val,
441
465
  projectionColumnState,
442
466
  );
467
+ QueryBuilderTelemetryHelper.logEvent_AggregationChanged(
468
+ applicationStore.telemetryService,
469
+ {
470
+ ...tdsState.queryBuilderState.safeGetTelemetryContext(),
471
+ change: {
472
+ action: 'operator-change',
473
+ operatorName: val?.getLabel(projectionColumnState),
474
+ },
475
+ },
476
+ );
477
+ };
443
478
 
444
479
  // calendar
445
480
  const aggregateCalendarFunctionDateColumns =
@@ -570,12 +605,23 @@ const QueryBuilderProjectionColumnEditor = observer(
570
605
  ? tdsState.projectionColumns.length - 1
571
606
  : currentRearrangeDropGapIndex,
572
607
  );
608
+ QueryBuilderTelemetryHelper.logEvent_ProjectionChanged(
609
+ applicationStore.telemetryService,
610
+ {
611
+ ...tdsState.queryBuilderState.safeGetTelemetryContext(),
612
+ change: {
613
+ action: 'move',
614
+ columnCount: tdsState.projectionColumns.length,
615
+ },
616
+ },
617
+ );
573
618
  }
574
619
  setCurrentRearrangeDraggedColumnIndex(undefined);
575
620
  setCurrentRearrangeDropGapIndex(undefined);
576
621
  },
577
622
  [
578
623
  tdsState,
624
+ applicationStore.telemetryService,
579
625
  currentRearrangeDropGapIndex,
580
626
  currentRearrangeDraggedColumnIndex,
581
627
  setCurrentRearrangeDraggedColumnIndex,
@@ -669,8 +715,7 @@ const QueryBuilderProjectionColumnEditor = observer(
669
715
  * @workaround typings - https://github.com/react-dnd/react-dnd/pull/3484
670
716
  */
671
717
  projectionColumnBeingDragged:
672
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
673
- (monitor.getItem() as QueryBuilderProjectionColumnDragSource | null)
718
+ monitor.getItem<QueryBuilderProjectionColumnDragSource | null>()
674
719
  ?.columnState,
675
720
  }),
676
721
  }),
@@ -1304,12 +1349,38 @@ export const QueryBuilderTDSPanel = observer(
1304
1349
  // Toolbar
1305
1350
  const openResultSetModifierEditor = (): void =>
1306
1351
  tdsState.resultSetModifierState.setShowModal(true);
1307
- const addNewBlankDerivation = (): void => tdsState.addNewBlankDerivation();
1352
+ const addNewBlankDerivation = (): void => {
1353
+ tdsState.addNewBlankDerivation();
1354
+ QueryBuilderTelemetryHelper.logEvent_ProjectionChanged(
1355
+ applicationStore.telemetryService,
1356
+ {
1357
+ ...tdsState.queryBuilderState.safeGetTelemetryContext(),
1358
+ change: {
1359
+ action: 'add-derivation',
1360
+ sourceType: 'derivation',
1361
+ columnCount: tdsState.projectionColumns.length,
1362
+ },
1363
+ },
1364
+ );
1365
+ };
1308
1366
 
1309
1367
  const clearAllProjectionColumns = (): void => {
1310
1368
  tdsState.checkBeforeClearingColumns(() => {
1369
+ // capture before the clear so we report how many columns were removed,
1370
+ // rather than the post-clear count which is always 0
1371
+ const clearedColumnCount = tdsState.projectionColumns.length;
1311
1372
  tdsState.removeAllColumns();
1312
1373
  tdsState.resultSetModifierState.reset();
1374
+ QueryBuilderTelemetryHelper.logEvent_ProjectionChanged(
1375
+ applicationStore.telemetryService,
1376
+ {
1377
+ ...tdsState.queryBuilderState.safeGetTelemetryContext(),
1378
+ change: {
1379
+ action: 'clear',
1380
+ columnCount: clearedColumnCount,
1381
+ },
1382
+ },
1383
+ );
1313
1384
  });
1314
1385
  };
1315
1386
 
@@ -1338,6 +1409,17 @@ export const QueryBuilderTDSPanel = observer(
1338
1409
  `${DEFAULT_LAMBDA_VARIABLE_NAME}${LAMBDA_PIPE}${functionPrettyName} `,
1339
1410
  );
1340
1411
  tdsState.addColumn(derivationProjectionColumn);
1412
+ QueryBuilderTelemetryHelper.logEvent_ProjectionChanged(
1413
+ applicationStore.telemetryService,
1414
+ {
1415
+ ...tdsState.queryBuilderState.safeGetTelemetryContext(),
1416
+ change: {
1417
+ action: 'add',
1418
+ sourceType: 'function',
1419
+ columnCount: tdsState.projectionColumns.length,
1420
+ },
1421
+ },
1422
+ );
1341
1423
  break;
1342
1424
  }
1343
1425
  case QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.ENUM_PROPERTY:
@@ -1352,6 +1434,17 @@ export const QueryBuilderTDSPanel = observer(
1352
1434
  tdsState.queryBuilderState.explorerState.humanizePropertyName,
1353
1435
  ),
1354
1436
  );
1437
+ QueryBuilderTelemetryHelper.logEvent_ProjectionChanged(
1438
+ applicationStore.telemetryService,
1439
+ {
1440
+ ...tdsState.queryBuilderState.safeGetTelemetryContext(),
1441
+ change: {
1442
+ action: 'add',
1443
+ sourceType: 'explorer-property',
1444
+ columnCount: tdsState.projectionColumns.length,
1445
+ },
1446
+ },
1447
+ );
1355
1448
  break;
1356
1449
  case QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.RELATION_COLUMN: {
1357
1450
  const dragNode = (
@@ -1366,6 +1459,17 @@ export const QueryBuilderTDSPanel = observer(
1366
1459
  true,
1367
1460
  ),
1368
1461
  );
1462
+ QueryBuilderTelemetryHelper.logEvent_ProjectionChanged(
1463
+ applicationStore.telemetryService,
1464
+ {
1465
+ ...tdsState.queryBuilderState.safeGetTelemetryContext(),
1466
+ change: {
1467
+ action: 'add',
1468
+ sourceType: 'explorer-relation',
1469
+ columnCount: tdsState.projectionColumns.length,
1470
+ },
1471
+ },
1472
+ );
1369
1473
  break;
1370
1474
  }
1371
1475
  case QUERY_BUILDER_FILTER_DND_TYPE.CONDITION:
@@ -1394,13 +1498,24 @@ export const QueryBuilderTDSPanel = observer(
1394
1498
  tdsState.queryBuilderState.explorerState.humanizePropertyName,
1395
1499
  ),
1396
1500
  );
1501
+ QueryBuilderTelemetryHelper.logEvent_ProjectionChanged(
1502
+ applicationStore.telemetryService,
1503
+ {
1504
+ ...tdsState.queryBuilderState.safeGetTelemetryContext(),
1505
+ change: {
1506
+ action: 'add',
1507
+ sourceType: 'filter-condition',
1508
+ columnCount: tdsState.projectionColumns.length,
1509
+ },
1510
+ },
1511
+ );
1397
1512
  }
1398
1513
  break;
1399
1514
  default:
1400
1515
  break;
1401
1516
  }
1402
1517
  },
1403
- [tdsState],
1518
+ [tdsState, applicationStore.telemetryService],
1404
1519
  );
1405
1520
 
1406
1521
  const [{ isDragOver }, panelDropConnector] = useDrop<
@@ -79,6 +79,7 @@ import { QUERY_BUILDER_PROJECTION_COLUMN_DND_TYPE } from '../../stores/fetch-str
79
79
  import type { QueryBuilderTDSColumnState } from '../../stores/fetch-structure/tds/QueryBuilderTDSColumnState.js';
80
80
  import type { QueryBuilderTDSState } from '../../stores/fetch-structure/tds/QueryBuilderTDSState.js';
81
81
  import { QUERY_BUILDER_TEST_ID } from '../../__lib__/QueryBuilderTesting.js';
82
+ import { QueryBuilderTelemetryHelper } from '../../__lib__/QueryBuilderTelemetryHelper.js';
82
83
  import { QueryBuilderPanelIssueCountBadge } from '../shared/QueryBuilderPanelIssueCountBadge.js';
83
84
  import { COLUMN_SORT_TYPE } from '../../graph/QueryBuilderMetaModelConst.js';
84
85
  import { CAN_DROP_MAIN_GROUP_DND_TYPES } from './QueryBuilderPostFilterPanel.js';
@@ -138,10 +139,23 @@ const QueryBuilderWindowColumnContextMenu = observer(
138
139
  }
139
140
  >(function QueryBuilderWindowGroupByColumnContextMenu(props, ref) {
140
141
  const { columnState } = props;
142
+ const applicationStore = useApplicationStore();
141
143
  const editColumn = (): void =>
142
144
  columnState.windowState.setEditColumn(columnState);
143
- const removeColumn = (): void =>
144
- columnState.windowState.removeColumn(columnState);
145
+ const removeColumn = (): void => {
146
+ const windowState = columnState.windowState;
147
+ windowState.removeColumn(columnState);
148
+ QueryBuilderTelemetryHelper.logEvent_WindowChanged(
149
+ applicationStore.telemetryService,
150
+ {
151
+ ...windowState.tdsState.queryBuilderState.safeGetTelemetryContext(),
152
+ change: {
153
+ action: 'remove',
154
+ columnCount: windowState.windowColumns.length,
155
+ },
156
+ },
157
+ );
158
+ };
145
159
 
146
160
  return (
147
161
  <MenuContent ref={ref}>
@@ -370,11 +384,22 @@ const QueryBuilderWindowColumnModalEditor = observer(
370
384
  };
371
385
 
372
386
  const handleApply = (): void => {
387
+ const isEdit = windowState.windowColumns.includes(windowColumnState);
373
388
  windowColumnState.setColumnName(selectedColumnName);
374
389
  windowColumnState.setOperatorState(selectedOperatorState);
375
390
  windowColumnState.setWindows(selectedWindowColumns);
376
391
  windowColumnState.setSortBy(selectedSortBy);
377
392
  windowState.addWindowColumn(windowColumnState);
393
+ QueryBuilderTelemetryHelper.logEvent_WindowChanged(
394
+ applicationStore.telemetryService,
395
+ {
396
+ ...windowState.tdsState.queryBuilderState.safeGetTelemetryContext(),
397
+ change: {
398
+ action: isEdit ? 'edit' : 'add',
399
+ columnCount: windowState.windowColumns.length,
400
+ },
401
+ },
402
+ );
378
403
  handleCancel();
379
404
  };
380
405
 
@@ -781,6 +806,7 @@ const QueryBuilderWindowColumnEditor = observer(
781
806
  const { windowColumnState } = props;
782
807
  const windowState = windowColumnState.windowState;
783
808
  const tdsState = windowState.tdsState;
809
+ const applicationStore = useApplicationStore();
784
810
  const operators = windowState.operators;
785
811
  const supportedOperators = tdsState.queryBuilderState.useRelation
786
812
  ? operators.filter((op) => op.relationFunc !== undefined)
@@ -852,6 +878,16 @@ const QueryBuilderWindowColumnEditor = observer(
852
878
  windowState.tdsState.isColumnInUse(windowColumnState);
853
879
  const removeColumn = (): void => {
854
880
  windowColumnState.windowState.removeColumn(windowColumnState);
881
+ QueryBuilderTelemetryHelper.logEvent_WindowChanged(
882
+ applicationStore.telemetryService,
883
+ {
884
+ ...windowColumnState.windowState.tdsState.queryBuilderState.safeGetTelemetryContext(),
885
+ change: {
886
+ action: 'remove',
887
+ columnCount: windowColumnState.windowState.windowColumns.length,
888
+ },
889
+ },
890
+ );
855
891
  };
856
892
  const editoColumn = (): void => {
857
893
  windowState.setEditColumn(windowColumnState);
@@ -914,8 +950,7 @@ const QueryBuilderWindowColumnEditor = observer(
914
950
  * @workaround typings - https://github.com/react-dnd/react-dnd/pull/3484
915
951
  */
916
952
  olapColumnBeingDragged:
917
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
918
- (monitor.getItem() as QueryBuilderWindowColumnDragSource | null)
953
+ monitor.getItem<QueryBuilderWindowColumnDragSource | null>()
919
954
  ?.columnState,
920
955
  }),
921
956
  }),
@@ -1264,6 +1299,16 @@ export const QueryBuilderTDSWindowPanel = observer(
1264
1299
  tdsWindowState.tdsState,
1265
1300
  );
1266
1301
  tdsWindowState.addWindowColumn(newWindowState);
1302
+ QueryBuilderTelemetryHelper.logEvent_WindowChanged(
1303
+ applicationStore.telemetryService,
1304
+ {
1305
+ ...tdsWindowState.tdsState.queryBuilderState.safeGetTelemetryContext(),
1306
+ change: {
1307
+ action: 'add',
1308
+ columnCount: tdsWindowState.windowColumns.length,
1309
+ },
1310
+ },
1311
+ );
1267
1312
  } catch (error) {
1268
1313
  assertErrorThrown(error);
1269
1314
  applicationStore.notificationService.notifyError(error.message);
@@ -639,19 +639,34 @@ const buildFilterTree = (
639
639
 
640
640
  const QueryBuilderFilterGroupConditionEditor = observer(
641
641
  (props: {
642
+ queryBuilderState: QueryBuilderState;
642
643
  node: QueryBuilderFilterTreeGroupNodeData;
643
644
  isDragOver: boolean;
644
645
  isDroppable: boolean;
645
646
  }) => {
646
- const { node, isDragOver, isDroppable } = props;
647
+ const { queryBuilderState, node, isDragOver, isDroppable } = props;
648
+ const applicationStore = useApplicationStore();
647
649
  const switchOperation: React.MouseEventHandler<HTMLDivElement> = (
648
650
  event,
649
651
  ): void => {
650
652
  event.stopPropagation(); // prevent triggering selecting the node
651
- node.setGroupOperation(
653
+ const nextOperation =
652
654
  node.groupOperation === QUERY_BUILDER_GROUP_OPERATION.AND
653
655
  ? QUERY_BUILDER_GROUP_OPERATION.OR
654
- : QUERY_BUILDER_GROUP_OPERATION.AND,
656
+ : QUERY_BUILDER_GROUP_OPERATION.AND;
657
+ node.setGroupOperation(nextOperation);
658
+ QueryBuilderTelemetryHelper.logEvent_FilterChanged(
659
+ applicationStore.telemetryService,
660
+ {
661
+ ...queryBuilderState.safeGetTelemetryContext(),
662
+ change: {
663
+ action: 'group-operation-change',
664
+ groupOperation:
665
+ nextOperation === QUERY_BUILDER_GROUP_OPERATION.AND
666
+ ? 'and'
667
+ : 'or',
668
+ },
669
+ },
655
670
  );
656
671
  };
657
672
 
@@ -1281,7 +1296,18 @@ const QueryBuilderFilterConditionContextMenu = observer(
1281
1296
  >(function QueryBuilderFilterConditionContextMenu(props, ref) {
1282
1297
  const { queryBuilderState, node } = props;
1283
1298
  const filterState = queryBuilderState.filterState;
1284
- const removeNode = (): void => filterState.removeNodeAndPruneBranch(node);
1299
+ const removeNode = (): void => {
1300
+ filterState.removeNodeAndPruneBranch(node);
1301
+ QueryBuilderTelemetryHelper.logEvent_FilterChanged(
1302
+ queryBuilderState.applicationStore.telemetryService,
1303
+ {
1304
+ ...queryBuilderState.safeGetTelemetryContext(),
1305
+ change: {
1306
+ action: 'remove',
1307
+ },
1308
+ },
1309
+ );
1310
+ };
1285
1311
  const createCondition = (): void => {
1286
1312
  filterState.addNodeFromNode(
1287
1313
  new QueryBuilderFilterTreeBlankConditionNodeData(undefined),
@@ -1591,6 +1617,7 @@ const QueryBuilderFilterTreeNodeContainer = observer(
1591
1617
  >
1592
1618
  {node instanceof QueryBuilderFilterTreeGroupNodeData && (
1593
1619
  <QueryBuilderFilterGroupConditionEditor
1620
+ queryBuilderState={queryBuilderState}
1594
1621
  node={node}
1595
1622
  isDroppable={isDroppable}
1596
1623
  isDragOver={isDragOver}