@finos/legend-query-builder 4.14.69 → 4.14.70

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. package/lib/__lib__/QueryBuilderTesting.d.ts +1 -0
  2. package/lib/__lib__/QueryBuilderTesting.d.ts.map +1 -1
  3. package/lib/__lib__/QueryBuilderTesting.js +1 -0
  4. package/lib/__lib__/QueryBuilderTesting.js.map +1 -1
  5. package/lib/components/explorer/QueryBuilderExplorerPanel.d.ts +1 -0
  6. package/lib/components/explorer/QueryBuilderExplorerPanel.d.ts.map +1 -1
  7. package/lib/components/explorer/QueryBuilderExplorerPanel.js +87 -52
  8. package/lib/components/explorer/QueryBuilderExplorerPanel.js.map +1 -1
  9. package/lib/components/explorer/QueryBuilderPropertySearchPanel.d.ts +4 -0
  10. package/lib/components/explorer/QueryBuilderPropertySearchPanel.d.ts.map +1 -1
  11. package/lib/components/explorer/QueryBuilderPropertySearchPanel.js +172 -108
  12. package/lib/components/explorer/QueryBuilderPropertySearchPanel.js.map +1 -1
  13. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.d.ts.map +1 -1
  14. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js +2 -1
  15. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js.map +1 -1
  16. package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
  17. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +29 -18
  18. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
  19. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.d.ts.map +1 -1
  20. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.js +13 -4
  21. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.js.map +1 -1
  22. package/lib/components/filter/QueryBuilderFilterPanel.d.ts.map +1 -1
  23. package/lib/components/filter/QueryBuilderFilterPanel.js +4 -3
  24. package/lib/components/filter/QueryBuilderFilterPanel.js.map +1 -1
  25. package/lib/components/result/QueryBuilderResultPanel.d.ts +12 -0
  26. package/lib/components/result/QueryBuilderResultPanel.d.ts.map +1 -1
  27. package/lib/components/result/QueryBuilderResultPanel.js +60 -8
  28. package/lib/components/result/QueryBuilderResultPanel.js.map +1 -1
  29. package/lib/components/result/tds/QueryBuilderTDSGridResult.d.ts.map +1 -1
  30. package/lib/components/result/tds/QueryBuilderTDSGridResult.js +16 -2
  31. package/lib/components/result/tds/QueryBuilderTDSGridResult.js.map +1 -1
  32. package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.d.ts +1 -0
  33. package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.d.ts.map +1 -1
  34. package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.js +34 -1
  35. package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.js.map +1 -1
  36. package/lib/components/shared/QueryBuilderFilterHelper.d.ts.map +1 -1
  37. package/lib/components/shared/QueryBuilderFilterHelper.js +3 -0
  38. package/lib/components/shared/QueryBuilderFilterHelper.js.map +1 -1
  39. package/lib/components/shared/QueryBuilderPropertyInfoTooltip.d.ts +11 -0
  40. package/lib/components/shared/QueryBuilderPropertyInfoTooltip.d.ts.map +1 -1
  41. package/lib/components/shared/QueryBuilderPropertyInfoTooltip.js +6 -3
  42. package/lib/components/shared/QueryBuilderPropertyInfoTooltip.js.map +1 -1
  43. package/lib/graph-manager/QueryBuilderConfig.d.ts +4 -0
  44. package/lib/graph-manager/QueryBuilderConfig.d.ts.map +1 -1
  45. package/lib/graph-manager/QueryBuilderConfig.js +5 -0
  46. package/lib/graph-manager/QueryBuilderConfig.js.map +1 -1
  47. package/lib/index.css +2 -2
  48. package/lib/index.css.map +1 -1
  49. package/lib/package.json +1 -1
  50. package/lib/stores/QueryBuilderResultState.d.ts +11 -3
  51. package/lib/stores/QueryBuilderResultState.d.ts.map +1 -1
  52. package/lib/stores/QueryBuilderResultState.js +47 -4
  53. package/lib/stores/QueryBuilderResultState.js.map +1 -1
  54. package/lib/stores/QueryBuilderValueSpecificationBuilderHelper.d.ts +4 -0
  55. package/lib/stores/QueryBuilderValueSpecificationBuilderHelper.d.ts.map +1 -1
  56. package/lib/stores/explorer/QueryBuilderExplorerState.d.ts +3 -1
  57. package/lib/stores/explorer/QueryBuilderExplorerState.d.ts.map +1 -1
  58. package/lib/stores/explorer/QueryBuilderExplorerState.js +63 -8
  59. package/lib/stores/explorer/QueryBuilderExplorerState.js.map +1 -1
  60. package/lib/stores/explorer/QueryBuilderFuzzySearchAdvancedConfigState.d.ts +24 -0
  61. package/lib/stores/explorer/QueryBuilderFuzzySearchAdvancedConfigState.d.ts.map +1 -0
  62. package/lib/stores/explorer/QueryBuilderFuzzySearchAdvancedConfigState.js +39 -0
  63. package/lib/stores/explorer/QueryBuilderFuzzySearchAdvancedConfigState.js.map +1 -0
  64. package/lib/stores/explorer/QueryBuilderPropertySearchState.d.ts +8 -4
  65. package/lib/stores/explorer/QueryBuilderPropertySearchState.d.ts.map +1 -1
  66. package/lib/stores/explorer/QueryBuilderPropertySearchState.js +204 -114
  67. package/lib/stores/explorer/QueryBuilderPropertySearchState.js.map +1 -1
  68. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.d.ts.map +1 -1
  69. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js +8 -1
  70. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js.map +1 -1
  71. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.d.ts.map +1 -1
  72. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.js +12 -1
  73. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.js.map +1 -1
  74. package/lib/stores/filter/QueryBuilderFilterState.d.ts +8 -1
  75. package/lib/stores/filter/QueryBuilderFilterState.d.ts.map +1 -1
  76. package/lib/stores/filter/QueryBuilderFilterState.js +27 -10
  77. package/lib/stores/filter/QueryBuilderFilterState.js.map +1 -1
  78. package/package.json +8 -8
  79. package/src/__lib__/QueryBuilderTesting.ts +1 -0
  80. package/src/components/explorer/QueryBuilderExplorerPanel.tsx +220 -114
  81. package/src/components/explorer/QueryBuilderPropertySearchPanel.tsx +618 -388
  82. package/src/components/fetch-structure/QueryBuilderPostFilterPanel.tsx +5 -2
  83. package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +78 -44
  84. package/src/components/fetch-structure/QueryBuilderTDSWindowPanel.tsx +63 -10
  85. package/src/components/filter/QueryBuilderFilterPanel.tsx +4 -2
  86. package/src/components/result/QueryBuilderResultPanel.tsx +207 -20
  87. package/src/components/result/tds/QueryBuilderTDSGridResult.tsx +16 -2
  88. package/src/components/result/tds/QueryBuilderTDSSimpleGridResult.tsx +43 -0
  89. package/src/components/shared/QueryBuilderFilterHelper.ts +8 -0
  90. package/src/components/shared/QueryBuilderPropertyInfoTooltip.tsx +13 -3
  91. package/src/graph-manager/QueryBuilderConfig.ts +6 -0
  92. package/src/stores/QueryBuilderResultState.ts +64 -10
  93. package/src/stores/QueryBuilderValueSpecificationBuilderHelper.ts +5 -0
  94. package/src/stores/explorer/QueryBuilderExplorerState.ts +92 -8
  95. package/src/stores/explorer/QueryBuilderFuzzySearchAdvancedConfigState.ts +46 -0
  96. package/src/stores/explorer/QueryBuilderPropertySearchState.ts +280 -142
  97. package/src/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.ts +8 -1
  98. package/src/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.ts +15 -2
  99. package/src/stores/filter/QueryBuilderFilterState.ts +34 -11
  100. package/tsconfig.json +1 -0
@@ -61,6 +61,7 @@ import {
61
61
  Dialog,
62
62
  CustomSelectorInput,
63
63
  } from '@finos/legend-art';
64
+ import { getFloatGridColumnCustomHeader } from './QueryBuilderTDSSimpleGridResult.js';
64
65
 
65
66
  export const enum QueryBuilderDataGridCustomAggregationFunction {
66
67
  wavg = 'wavg',
@@ -87,13 +88,20 @@ const getAggregationTDSColumnCustomizations = (
87
88
  filter: 'agDateColumnFilter',
88
89
  allowedAggFuncs: ['count'],
89
90
  };
90
- case PRIMITIVE_TYPE.DECIMAL:
91
91
  case PRIMITIVE_TYPE.NUMBER:
92
92
  case PRIMITIVE_TYPE.INTEGER:
93
+ return {
94
+ filter: 'agNumberColumnFilter',
95
+ allowedAggFuncs: ['count', 'sum', 'max', 'min', 'avg', 'wavg'],
96
+ };
97
+ case PRIMITIVE_TYPE.DECIMAL:
93
98
  case PRIMITIVE_TYPE.FLOAT:
94
99
  return {
95
100
  filter: 'agNumberColumnFilter',
96
101
  allowedAggFuncs: ['count', 'sum', 'max', 'min', 'avg', 'wavg'],
102
+ headerComponentParams: {
103
+ template: getFloatGridColumnCustomHeader(columnName),
104
+ },
97
105
  };
98
106
  default:
99
107
  return {
@@ -207,11 +215,17 @@ const getFilterTDSColumnCustomizations = (
207
215
  };
208
216
  case PRIMITIVE_TYPE.DECIMAL:
209
217
  case PRIMITIVE_TYPE.INTEGER:
210
- case PRIMITIVE_TYPE.FLOAT:
211
218
  case PRIMITIVE_TYPE.NUMBER:
212
219
  return {
213
220
  filter: 'agNumberColumnFilter',
214
221
  };
222
+ case PRIMITIVE_TYPE.FLOAT:
223
+ return {
224
+ filter: 'agNumberColumnFilter',
225
+ headerComponentParams: {
226
+ template: getFloatGridColumnCustomHeader(columnName),
227
+ },
228
+ };
215
229
  default:
216
230
  // we default all other columns to use filter true which defaults to set filters
217
231
  return {
@@ -19,6 +19,7 @@ import { observer } from 'mobx-react-lite';
19
19
  import type { QueryBuilderState } from '../../../stores/QueryBuilderState.js';
20
20
  import {
21
21
  getTDSRowRankByColumnInAsc,
22
+ PRIMITIVE_TYPE,
22
23
  TDSExecutionResult,
23
24
  } from '@finos/legend-graph';
24
25
  import {
@@ -47,6 +48,47 @@ import type {
47
48
  } from '../../../stores/QueryBuilderResultState.js';
48
49
  import { QUERY_BUILDER_TEST_ID } from '../../../__lib__/QueryBuilderTesting.js';
49
50
 
51
+ export const getFloatGridColumnCustomHeader = (
52
+ columnName: string,
53
+ ): string => ` <div data-testid="query__builder__result__grid__custom-header" class="query-builder__result__values__table__custom-header">
54
+ <div>${columnName}</div>
55
+ <div
56
+ class="query-builder__result__stale-status__icon"
57
+ title="some values have been rounded using en-us format in this preview grid (defaults to max 4 decimal places)"
58
+ >
59
+ <svg
60
+ stroke="currentColor"
61
+ fill="currentColor"
62
+ stroke-width="0"
63
+ viewBox="0 0 576 512"
64
+ height="1em"
65
+ width="1em"
66
+ xmlns="http://www.w3.org/2000/svg"
67
+ >
68
+ <path d="M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"></path>
69
+ </svg>
70
+ </div>
71
+ </div>`;
72
+
73
+ const getTDSColumnCustomizations = (
74
+ result: TDSExecutionResult,
75
+ columnName: string,
76
+ ): object => {
77
+ const columnType = result.builder.columns.find(
78
+ (col) => col.name === columnName,
79
+ )?.type;
80
+ switch (columnType) {
81
+ case PRIMITIVE_TYPE.FLOAT:
82
+ return {
83
+ headerComponentParams: {
84
+ template: getFloatGridColumnCustomHeader(columnName),
85
+ },
86
+ };
87
+ default:
88
+ return {};
89
+ }
90
+ };
91
+
50
92
  const QueryResultCellRenderer = observer(
51
93
  (params: IQueryRendererParamsWithGridType) => {
52
94
  const resultState = params.resultState;
@@ -368,6 +410,7 @@ export const QueryBuilderTDSSimpleGridResult = observer(
368
410
  resizable: true,
369
411
  field: colName,
370
412
  flex: 1,
413
+ ...getTDSColumnCustomizations(executionResult, colName),
371
414
  cellRenderer: QueryResultCellRenderer,
372
415
  cellRendererParams: {
373
416
  resultState: resultState,
@@ -28,6 +28,10 @@ import {
28
28
  QUERY_BUILDER_VARIABLE_DND_TYPE,
29
29
  type QueryBuilderVariableDragSource,
30
30
  } from './BasicValueSpecificationEditor.js';
31
+ import {
32
+ QUERY_BUILDER_WINDOW_COLUMN_DND_TYPE,
33
+ type QueryBuilderWindowColumnDragSource,
34
+ } from '../../stores/fetch-structure/tds/window/QueryBuilderWindowState.js';
31
35
 
32
36
  export const getDNDItemType = (
33
37
  item: QueryBuilderFilterValueDropTarget,
@@ -45,6 +49,10 @@ export const getDNDItemType = (
45
49
  case QUERY_BUILDER_VARIABLE_DND_TYPE:
46
50
  return (item as QueryBuilderVariableDragSource).variable.genericType
47
51
  ?.value.rawType;
52
+ case QUERY_BUILDER_WINDOW_COLUMN_DND_TYPE:
53
+ return (
54
+ item as QueryBuilderWindowColumnDragSource
55
+ ).columnState.getColumnType();
48
56
  default:
49
57
  return undefined;
50
58
  }
@@ -117,7 +117,7 @@ export const QueryBuilderTaggedValueInfoTooltip: React.FC<{
117
117
  );
118
118
  };
119
119
 
120
- const QueryBuilderBaseInfoTooltip: React.FC<{
120
+ export const QueryBuilderBaseInfoTooltip: React.FC<{
121
121
  title: string;
122
122
  data: {
123
123
  label: string;
@@ -133,7 +133,10 @@ const QueryBuilderBaseInfoTooltip: React.FC<{
133
133
  const [open, setIsOpen] = useState(false);
134
134
 
135
135
  return (
136
- <ClickAwayListener onClickAway={() => setIsOpen(false)}>
136
+ <ClickAwayListener
137
+ onClickAway={() => setIsOpen(false)}
138
+ mouseEvent="onMouseDown"
139
+ >
137
140
  <div>
138
141
  <Tooltip
139
142
  arrow={true}
@@ -172,7 +175,14 @@ const QueryBuilderBaseInfoTooltip: React.FC<{
172
175
  </div>
173
176
  }
174
177
  >
175
- <div onClick={() => setIsOpen(true)}>{children}</div>
178
+ <div
179
+ onClick={(event: React.MouseEvent) => {
180
+ setIsOpen(!open);
181
+ event.stopPropagation();
182
+ }}
183
+ >
184
+ {children}
185
+ </div>
176
186
  </Tooltip>
177
187
  </div>
178
188
  </ClickAwayListener>
@@ -33,11 +33,17 @@ export class QueryBuilderConfig {
33
33
  */
34
34
  legendAIServiceURL = '';
35
35
 
36
+ /**
37
+ * This is the URL of the zipkin trace
38
+ */
39
+ zipkinTraceBaseURL = '';
40
+
36
41
  static readonly serialization = new SerializationFactory(
37
42
  createModelSchema(QueryBuilderConfig, {
38
43
  TEMPORARY__disableQueryBuilderChat: optional(primitive()),
39
44
  TEMPORARY__enableGridEnterpriseMode: optional(primitive()),
40
45
  legendAIServiceURL: optional(primitive()),
46
+ zipkinTraceBaseURL: optional(primitive()),
41
47
  }),
42
48
  );
43
49
  }
@@ -17,10 +17,10 @@
17
17
  import { action, flow, makeObservable, observable } from 'mobx';
18
18
  import {
19
19
  type GeneratorFn,
20
+ type ContentType,
20
21
  assertErrorThrown,
21
22
  LogEvent,
22
23
  guaranteeNonNullable,
23
- type ContentType,
24
24
  ActionState,
25
25
  StopWatch,
26
26
  getContentTypeFileExtension,
@@ -32,11 +32,13 @@ import {
32
32
  type RawLambda,
33
33
  type EXECUTION_SERIALIZATION_FORMAT,
34
34
  type QueryGridConfig,
35
+ type ExecutionResultWithMetadata,
35
36
  GRAPH_MANAGER_EVENT,
36
37
  buildRawLambdaFromLambdaFunction,
37
38
  reportGraphAnalytics,
39
+ TDSExecutionResult,
40
+ V1_ZIPKIN_TRACE_HEADER,
38
41
  } from '@finos/legend-graph';
39
-
40
42
  import { buildLambdaFunction } from './QueryBuilderValueSpecificationBuilder.js';
41
43
  import {
42
44
  buildExecutionParameterValues,
@@ -49,6 +51,7 @@ import { ExecutionPlanState } from './execution-plan/ExecutionPlanState.js';
49
51
  import type { DataGridColumnState } from '@finos/legend-lego/data-grid';
50
52
  import { downloadStream } from '@finos/legend-application';
51
53
  import { QueryBuilderDataGridCustomAggregationFunction } from '../components/result/tds/QueryBuilderTDSGridResult.js';
54
+ import { QueryBuilderTDSState } from './fetch-structure/tds/QueryBuilderTDSState.js';
52
55
 
53
56
  export const DEFAULT_LIMIT = 1000;
54
57
 
@@ -125,10 +128,13 @@ export class QueryBuilderResultState {
125
128
  isRunningQuery = false;
126
129
  isGeneratingPlan = false;
127
130
  executionResult?: ExecutionResult | undefined;
131
+ isExecutionResultOverflowing = false;
128
132
  executionDuration?: number | undefined;
133
+ executionTraceId?: string;
129
134
  latestRunHashCode?: string | undefined;
130
- queryRunPromise: Promise<ExecutionResult> | undefined = undefined;
135
+ queryRunPromise: Promise<ExecutionResultWithMetadata> | undefined = undefined;
131
136
  isQueryUsageViewerOpened = false;
137
+ executionError: Error | string | undefined;
132
138
 
133
139
  selectedCells: QueryBuilderTDSResultCellData[];
134
140
  mousedOverCell: QueryBuilderTDSResultCellData | null = null;
@@ -140,6 +146,7 @@ export class QueryBuilderResultState {
140
146
  constructor(queryBuilderState: QueryBuilderState) {
141
147
  makeObservable(this, {
142
148
  executionResult: observable,
149
+ executionTraceId: observable,
143
150
  previewLimit: observable,
144
151
  executionDuration: observable,
145
152
  latestRunHashCode: observable,
@@ -150,13 +157,16 @@ export class QueryBuilderResultState {
150
157
  isRunningQuery: observable,
151
158
  isSelectingCells: observable,
152
159
  isQueryUsageViewerOpened: observable,
160
+ isExecutionResultOverflowing: observable,
153
161
  gridConfig: observable,
154
162
  wavgAggregationState: observable,
163
+ executionError: observable,
155
164
  setGridConfig: action,
156
165
  setWavgAggregationState: action,
157
166
  setIsSelectingCells: action,
158
167
  setIsRunningQuery: action,
159
168
  setExecutionResult: action,
169
+ setExecutionTraceId: action,
160
170
  setExecutionDuration: action,
161
171
  setPreviewLimit: action,
162
172
  addSelectedCell: action,
@@ -164,8 +174,10 @@ export class QueryBuilderResultState {
164
174
  setMouseOverCell: action,
165
175
  setQueryRunPromise: action,
166
176
  setIsQueryUsageViewerOpened: action,
177
+ setIsExecutionResultOverflowing: action,
167
178
  handlePreConfiguredGridConfig: action,
168
179
  updatePreviewLimitInConfig: action,
180
+ setExecutionError: action,
169
181
  exportData: flow,
170
182
  runQuery: flow,
171
183
  cancelQuery: flow,
@@ -204,6 +216,10 @@ export class QueryBuilderResultState {
204
216
  this.executionResult = val;
205
217
  }
206
218
 
219
+ setExecutionTraceId(val: string): void {
220
+ this.executionTraceId = val;
221
+ }
222
+
207
223
  setExecutionDuration(val: number | undefined): void {
208
224
  this.executionDuration = val;
209
225
  }
@@ -224,7 +240,9 @@ export class QueryBuilderResultState {
224
240
  this.mousedOverCell = val;
225
241
  }
226
242
 
227
- setQueryRunPromise(promise: Promise<ExecutionResult> | undefined): void {
243
+ setQueryRunPromise(
244
+ promise: Promise<ExecutionResultWithMetadata> | undefined,
245
+ ): void {
228
246
  this.queryRunPromise = promise;
229
247
  }
230
248
 
@@ -232,12 +250,44 @@ export class QueryBuilderResultState {
232
250
  this.isQueryUsageViewerOpened = val;
233
251
  }
234
252
 
253
+ setExecutionError(val: Error | string | undefined): void {
254
+ this.executionError = val;
255
+ }
256
+
257
+ setIsExecutionResultOverflowing(val: boolean): void {
258
+ this.isExecutionResultOverflowing = val;
259
+ }
260
+
235
261
  updatePreviewLimitInConfig(): void {
236
262
  if (this.gridConfig) {
237
263
  this.gridConfig.previewLimit = this.previewLimit;
238
264
  }
239
265
  }
240
266
 
267
+ getExecutionResultLimit = (): number =>
268
+ Math.min(
269
+ this.queryBuilderState.fetchStructureState.implementation instanceof
270
+ QueryBuilderTDSState &&
271
+ this.queryBuilderState.fetchStructureState.implementation
272
+ .resultSetModifierState.limit
273
+ ? this.queryBuilderState.fetchStructureState.implementation
274
+ .resultSetModifierState.limit
275
+ : Number.MAX_SAFE_INTEGER,
276
+ this.previewLimit,
277
+ );
278
+
279
+ processExecutionResult = (result: ExecutionResult): void => {
280
+ this.setIsExecutionResultOverflowing(false);
281
+ if (result instanceof TDSExecutionResult) {
282
+ const resultLimit = this.getExecutionResultLimit();
283
+ if (result.result.rows.length > resultLimit) {
284
+ this.setIsExecutionResultOverflowing(true);
285
+ result.result.rows = result.result.rows.slice(0, resultLimit);
286
+ }
287
+ }
288
+ this.setExecutionResult(result);
289
+ };
290
+
241
291
  processWeightedColumnPairsMap(
242
292
  config: QueryGridConfig,
243
293
  ): Map<string, string> | undefined {
@@ -421,7 +471,9 @@ export class QueryBuilderResultState {
421
471
  this.queryBuilderState.executionContextState.runtimeValue,
422
472
  `Runtime is required to execute query`,
423
473
  );
424
- const query = this.buildExecutionRawLambda();
474
+ const query = this.buildExecutionRawLambda({
475
+ withDataOverflowCheck: true,
476
+ });
425
477
  const parameterValues = buildExecutionParameterValues(
426
478
  this.queryBuilderState.parametersState.parameterStates,
427
479
  this.queryBuilderState.graphManagerState,
@@ -444,13 +496,17 @@ export class QueryBuilderResultState {
444
496
  {
445
497
  parameterValues,
446
498
  convertUnsafeNumbersToString: true,
499
+ preservedResponseHeadersList: [V1_ZIPKIN_TRACE_HEADER],
447
500
  },
448
501
  );
449
502
 
450
503
  this.setQueryRunPromise(promise);
451
- const result = (yield promise) as ExecutionResult;
504
+ const result = (yield promise) as ExecutionResultWithMetadata;
452
505
  if (this.queryRunPromise === promise) {
453
- this.setExecutionResult(result);
506
+ this.processExecutionResult(result.executionResult);
507
+ if (result.executionTraceId) {
508
+ this.setExecutionTraceId(result.executionTraceId);
509
+ }
454
510
  this.latestRunHashCode = currentHashCode;
455
511
  this.setExecutionDuration(stopWatch.elapsed);
456
512
 
@@ -479,9 +535,7 @@ export class QueryBuilderResultState {
479
535
  LogEvent.create(GRAPH_MANAGER_EVENT.EXECUTION_FAILURE),
480
536
  error,
481
537
  );
482
- this.queryBuilderState.applicationStore.notificationService.notifyError(
483
- error,
484
- );
538
+ this.setExecutionError(error);
485
539
  }
486
540
  } finally {
487
541
  this.setIsRunningQuery(false);
@@ -210,4 +210,9 @@ export type LambdaFunctionBuilderOption = {
210
210
  * typed in engine. This is still an experimental feature, hence we should only enable this flag when user wants to enable this directly.
211
211
  */
212
212
  useTypedRelationFunctions?: boolean | undefined;
213
+
214
+ /**
215
+ * Set this flag to `true` when you want to execute a query that exceeds the limit to check for additional data in the database.
216
+ */
217
+ withDataOverflowCheck?: boolean | undefined;
213
218
  };
@@ -118,8 +118,10 @@ export abstract class QueryBuilderExplorerTreeNodeData implements TreeNodeData {
118
118
  ) {
119
119
  makeObservable(this, {
120
120
  isHighlighting: observable,
121
+ isOpen: observable,
121
122
  isSelected: observable,
122
123
  setIsHighlighting: action,
124
+ setIsOpen: action,
123
125
  setIsSelected: action,
124
126
  });
125
127
 
@@ -136,6 +138,10 @@ export abstract class QueryBuilderExplorerTreeNodeData implements TreeNodeData {
136
138
  this.isSelected = val;
137
139
  }
138
140
 
141
+ setIsOpen(val: boolean | undefined): void {
142
+ this.isOpen = val;
143
+ }
144
+
139
145
  setIsHighlighting(val: boolean | undefined): void {
140
146
  this.isHighlighting = val;
141
147
  }
@@ -761,21 +767,99 @@ export class QueryBuilderExplorerState {
761
767
  );
762
768
  }
763
769
 
764
- highlightTreeNode(key: string): void {
765
- const nodeToHighlight = this.treeData?.nodes.get(key);
766
- if (nodeToHighlight instanceof QueryBuilderExplorerTreePropertyNodeData) {
770
+ generateOpenNodeChildren(node: QueryBuilderExplorerTreeNodeData): void {
771
+ if (
772
+ node.isOpen &&
773
+ (node instanceof QueryBuilderExplorerTreePropertyNodeData ||
774
+ node instanceof QueryBuilderExplorerTreeSubTypeNodeData) &&
775
+ node.type instanceof Class
776
+ ) {
777
+ (node instanceof QueryBuilderExplorerTreeSubTypeNodeData
778
+ ? getAllOwnClassProperties(node.type)
779
+ : getAllClassProperties(node.type).concat(
780
+ getAllClassDerivedProperties(node.type),
781
+ )
782
+ ).forEach((property) => {
783
+ const propertyTreeNodeData = getQueryBuilderPropertyNodeData(
784
+ property,
785
+ node,
786
+ guaranteeNonNullable(this.mappingModelCoverageAnalysisResult),
787
+ );
788
+ if (propertyTreeNodeData) {
789
+ this.nonNullableTreeData.nodes.set(
790
+ propertyTreeNodeData.id,
791
+ propertyTreeNodeData,
792
+ );
793
+ }
794
+ });
795
+ node.type._subclasses.forEach((subclass) => {
796
+ const subTypeTreeNodeData = getQueryBuilderSubTypeNodeData(
797
+ subclass,
798
+ node,
799
+ guaranteeNonNullable(this.mappingModelCoverageAnalysisResult),
800
+ );
801
+ this.nonNullableTreeData.nodes.set(
802
+ subTypeTreeNodeData.id,
803
+ subTypeTreeNodeData,
804
+ );
805
+ });
806
+ this.refreshTree();
807
+ }
808
+ }
809
+
810
+ highlightTreeNode(nodeId: string): void {
811
+ // If the node doesn't yet exist in the explorer tree,
812
+ // we need to open all the parent nodes of the node and
813
+ // generate their children.
814
+ if (this.nonNullableTreeData.nodes.get(nodeId) === undefined) {
815
+ const parentNodeIdElements: string[][] = nodeId
816
+ .split('@')
817
+ .map((subpath) => subpath.split('.'));
818
+ // remove last element of final subpath, as it is the node id and not a parent
819
+ if (
820
+ parentNodeIdElements.length > 0 &&
821
+ parentNodeIdElements[parentNodeIdElements.length - 1] !== undefined
822
+ ) {
823
+ parentNodeIdElements[parentNodeIdElements.length - 1]!.pop();
824
+ }
825
+
826
+ let currentNodeId = '';
827
+
828
+ parentNodeIdElements.forEach((subpath) => {
829
+ subpath.forEach((element, index) => {
830
+ currentNodeId += `${index > 0 ? '.' : ''}${element}`;
831
+ const currentNode = this.nonNullableTreeData.nodes.get(currentNodeId);
832
+ if (currentNode) {
833
+ currentNode.setIsOpen(true);
834
+ this.generateOpenNodeChildren(currentNode);
835
+ }
836
+ });
837
+ currentNodeId += '@';
838
+ });
839
+ }
840
+
841
+ // All parent nodes should be created now, so we can get the node to highlight.
842
+ const nodeToHighlight = this.nonNullableTreeData.nodes.get(nodeId);
843
+
844
+ // If we didn't need to open and create the parent nodes above, we will
845
+ // open the parent nodes here in case they are closed. Then, we will highlight
846
+ // and scroll to the node.
847
+ if (
848
+ nodeToHighlight instanceof QueryBuilderExplorerTreePropertyNodeData ||
849
+ nodeToHighlight instanceof QueryBuilderExplorerTreeSubTypeNodeData
850
+ ) {
767
851
  let nodeToOpen: QueryBuilderExplorerTreeNodeData | null =
768
- this.treeData?.nodes.get(nodeToHighlight.parentId) ?? null;
852
+ this.nonNullableTreeData.nodes.get(nodeToHighlight.parentId) ?? null;
769
853
  while (nodeToOpen !== null) {
770
854
  if (!nodeToOpen.isOpen) {
771
- nodeToOpen.isOpen = true;
855
+ nodeToOpen.setIsOpen(true);
772
856
  }
773
857
  nodeToOpen =
774
- nodeToOpen instanceof QueryBuilderExplorerTreePropertyNodeData
775
- ? (this.treeData?.nodes.get(nodeToOpen.parentId) ?? null)
858
+ nodeToOpen instanceof QueryBuilderExplorerTreePropertyNodeData ||
859
+ nodeToOpen instanceof QueryBuilderExplorerTreeSubTypeNodeData
860
+ ? (this.nonNullableTreeData.nodes.get(nodeToOpen.parentId) ?? null)
776
861
  : null;
777
862
  }
778
- this.refreshTree();
779
863
  nodeToHighlight.setIsHighlighting(true);
780
864
  // scrollIntoView must be called in a setTimeout because it must happen after
781
865
  // the tree nodes are recursively opened and the tree is refreshed.
@@ -0,0 +1,46 @@
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 { FuzzySearchAdvancedConfigState } from '@finos/legend-shared';
18
+ import { action, makeObservable, observable } from 'mobx';
19
+
20
+ export class QueryBuilderFuzzySearchAdvancedConfigState extends FuzzySearchAdvancedConfigState {
21
+ includeSubTypes = false;
22
+ includeDocumentation = false;
23
+
24
+ constructor(
25
+ onSearchModeChange: () => Promise<void>,
26
+ onSearchModeChangeError: (error: Error) => void,
27
+ ) {
28
+ super(() => {
29
+ onSearchModeChange().catch(onSearchModeChangeError);
30
+ });
31
+ makeObservable(this, {
32
+ includeSubTypes: observable,
33
+ includeDocumentation: observable,
34
+ setIncludeSubTypes: action,
35
+ setIncludeDocumentation: action,
36
+ });
37
+ }
38
+
39
+ setIncludeSubTypes(val: boolean): void {
40
+ this.includeSubTypes = val;
41
+ }
42
+
43
+ setIncludeDocumentation(val: boolean): void {
44
+ this.includeDocumentation = val;
45
+ }
46
+ }