@finos/legend-query-builder 4.14.71 → 4.14.73

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. package/lib/components/QueryLoader.d.ts.map +1 -1
  2. package/lib/components/QueryLoader.js +12 -34
  3. package/lib/components/QueryLoader.js.map +1 -1
  4. package/lib/components/explorer/QueryBuilderPropertySearchPanel.d.ts.map +1 -1
  5. package/lib/components/explorer/QueryBuilderPropertySearchPanel.js +108 -36
  6. package/lib/components/explorer/QueryBuilderPropertySearchPanel.js.map +1 -1
  7. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.d.ts.map +1 -1
  8. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js +10 -3
  9. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js.map +1 -1
  10. package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.d.ts.map +1 -1
  11. package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.js +2 -2
  12. package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.js.map +1 -1
  13. package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
  14. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +6 -2
  15. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
  16. package/lib/components/filter/QueryBuilderFilterPanel.d.ts.map +1 -1
  17. package/lib/components/filter/QueryBuilderFilterPanel.js +5 -1
  18. package/lib/components/filter/QueryBuilderFilterPanel.js.map +1 -1
  19. package/lib/components/result/QueryBuilderResultPanel.d.ts.map +1 -1
  20. package/lib/components/result/QueryBuilderResultPanel.js +3 -1
  21. package/lib/components/result/QueryBuilderResultPanel.js.map +1 -1
  22. package/lib/components/result/tds/QueryBuilderTDSGridResult.d.ts.map +1 -1
  23. package/lib/components/result/tds/QueryBuilderTDSGridResult.js +5 -2
  24. package/lib/components/result/tds/QueryBuilderTDSGridResult.js.map +1 -1
  25. package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.d.ts +3 -0
  26. package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.d.ts.map +1 -1
  27. package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.js +92 -2
  28. package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.js.map +1 -1
  29. package/lib/index.css +1 -17
  30. package/lib/index.css.map +1 -1
  31. package/lib/package.json +1 -1
  32. package/lib/stores/QueryBuilderConfig.d.ts +2 -1
  33. package/lib/stores/QueryBuilderConfig.d.ts.map +1 -1
  34. package/lib/stores/QueryBuilderConfig.js +2 -1
  35. package/lib/stores/QueryBuilderConfig.js.map +1 -1
  36. package/lib/stores/QueryBuilderResultState.d.ts.map +1 -1
  37. package/lib/stores/QueryBuilderResultState.js +4 -1
  38. package/lib/stores/QueryBuilderResultState.js.map +1 -1
  39. package/lib/stores/QueryBuilderValueSpecificationHelper.d.ts +1 -1
  40. package/lib/stores/QueryBuilderValueSpecificationHelper.d.ts.map +1 -1
  41. package/lib/stores/QueryBuilderValueSpecificationHelper.js +1 -0
  42. package/lib/stores/QueryBuilderValueSpecificationHelper.js.map +1 -1
  43. package/lib/stores/QueryLoaderState.d.ts +8 -6
  44. package/lib/stores/QueryLoaderState.d.ts.map +1 -1
  45. package/lib/stores/QueryLoaderState.js +30 -7
  46. package/lib/stores/QueryLoaderState.js.map +1 -1
  47. package/lib/stores/explorer/QueryBuilderExplorerState.d.ts +4 -3
  48. package/lib/stores/explorer/QueryBuilderExplorerState.d.ts.map +1 -1
  49. package/lib/stores/explorer/QueryBuilderExplorerState.js +22 -7
  50. package/lib/stores/explorer/QueryBuilderExplorerState.js.map +1 -1
  51. package/lib/stores/explorer/QueryBuilderFuzzySearchAdvancedConfigState.d.ts.map +1 -1
  52. package/lib/stores/explorer/QueryBuilderFuzzySearchAdvancedConfigState.js +1 -1
  53. package/lib/stores/explorer/QueryBuilderFuzzySearchAdvancedConfigState.js.map +1 -1
  54. package/lib/stores/explorer/QueryBuilderPropertySearchState.d.ts +7 -1
  55. package/lib/stores/explorer/QueryBuilderPropertySearchState.d.ts.map +1 -1
  56. package/lib/stores/explorer/QueryBuilderPropertySearchState.js +160 -74
  57. package/lib/stores/explorer/QueryBuilderPropertySearchState.js.map +1 -1
  58. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.d.ts +4 -1
  59. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.d.ts.map +1 -1
  60. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js +23 -12
  61. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js.map +1 -1
  62. package/lib/stores/filter/QueryBuilderFilterState.d.ts +1 -1
  63. package/lib/stores/filter/QueryBuilderFilterState.d.ts.map +1 -1
  64. package/lib/stores/filter/QueryBuilderFilterState.js +9 -5
  65. package/lib/stores/filter/QueryBuilderFilterState.js.map +1 -1
  66. package/package.json +3 -3
  67. package/src/components/QueryLoader.tsx +37 -54
  68. package/src/components/explorer/QueryBuilderPropertySearchPanel.tsx +249 -226
  69. package/src/components/fetch-structure/QueryBuilderPostFilterPanel.tsx +24 -2
  70. package/src/components/fetch-structure/QueryBuilderResultModifierPanel.tsx +6 -2
  71. package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +10 -2
  72. package/src/components/filter/QueryBuilderFilterPanel.tsx +10 -1
  73. package/src/components/result/QueryBuilderResultPanel.tsx +3 -1
  74. package/src/components/result/tds/QueryBuilderTDSGridResult.tsx +8 -2
  75. package/src/components/result/tds/QueryBuilderTDSSimpleGridResult.tsx +106 -1
  76. package/src/stores/QueryBuilderConfig.ts +2 -1
  77. package/src/stores/QueryBuilderResultState.ts +4 -0
  78. package/src/stores/QueryBuilderValueSpecificationHelper.ts +2 -1
  79. package/src/stores/QueryLoaderState.ts +43 -17
  80. package/src/stores/explorer/QueryBuilderExplorerState.ts +58 -5
  81. package/src/stores/explorer/QueryBuilderFuzzySearchAdvancedConfigState.ts +1 -1
  82. package/src/stores/explorer/QueryBuilderPropertySearchState.ts +194 -92
  83. package/src/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.ts +43 -13
  84. package/src/stores/filter/QueryBuilderFilterState.ts +16 -7
@@ -1020,13 +1020,22 @@ const QueryBuilderFilterConditionEditor = observer(
1020
1020
  rightConditionValue instanceof FilterValueSpecConditionValueState &&
1021
1021
  rightConditionValue.value
1022
1022
  ) {
1023
+ const isInvalidVariable =
1024
+ rightConditionValue.value instanceof VariableExpression &&
1025
+ node.condition.filterState.isInvalidValueSpecFilterValue(node);
1023
1026
  return (
1024
1027
  <div
1025
1028
  ref={dropConnector}
1026
1029
  data-testid={
1027
1030
  QUERY_BUILDER_TEST_ID.QUERY_BUILDER_FILTER_TREE_CONDITION_NODE_VALUE
1028
1031
  }
1029
- className="query-builder-filter-tree__condition-node__value"
1032
+ className={clsx(
1033
+ 'query-builder-filter-tree__condition-node__value',
1034
+ {
1035
+ 'query-builder-filter-tree__condition-node__value--error':
1036
+ isInvalidVariable,
1037
+ },
1038
+ )}
1030
1039
  >
1031
1040
  <PanelEntryDropZonePlaceholder
1032
1041
  isDragOver={isFilterValueDragOver}
@@ -403,7 +403,9 @@ export const QueryBuilderResultPanel = observer(
403
403
  };
404
404
  const resultDescription = executionResult
405
405
  ? getResultSetDescription(executionResult)
406
- : undefined;
406
+ : resultState.executionError
407
+ ? 'fail to execute'
408
+ : undefined;
407
409
 
408
410
  const [previewLimitValue, setPreviewLimitValue] = useState(
409
411
  resultState.previewLimit,
@@ -61,6 +61,10 @@ import {
61
61
  Dialog,
62
62
  CustomSelectorInput,
63
63
  } from '@finos/legend-art';
64
+ import {
65
+ getTDSColumnCustomizations,
66
+ MAXIMUM_FRACTION_DIGITS,
67
+ } from './QueryBuilderTDSSimpleGridResult.js';
64
68
 
65
69
  export const enum QueryBuilderDataGridCustomAggregationFunction {
66
70
  wavg = 'wavg',
@@ -109,7 +113,7 @@ const QueryResultCellRenderer = observer(
109
113
  const formattedCellValue = (): QueryBuilderTDSResultCellDataType => {
110
114
  if (isNumber(cellValue)) {
111
115
  return Intl.NumberFormat(DEFAULT_LOCALE, {
112
- maximumFractionDigits: 4,
116
+ maximumFractionDigits: MAXIMUM_FRACTION_DIGITS,
113
117
  }).format(Number(cellValue));
114
118
  } else if (isBoolean(cellValue)) {
115
119
  return String(cellValue);
@@ -173,6 +177,7 @@ const getLocalColDefs = (
173
177
  tdsExecutionResult: executionResult,
174
178
  },
175
179
  ...getAggregationTDSColumnCustomizations(executionResult, colName),
180
+ ...getTDSColumnCustomizations(executionResult, colName),
176
181
  } as DataGridColumnDefinition;
177
182
  const persistedColumn = resultState.gridConfig?.columns.find(
178
183
  (c) => c.colId === colName,
@@ -207,8 +212,8 @@ const getFilterTDSColumnCustomizations = (
207
212
  };
208
213
  case PRIMITIVE_TYPE.DECIMAL:
209
214
  case PRIMITIVE_TYPE.INTEGER:
210
- case PRIMITIVE_TYPE.FLOAT:
211
215
  case PRIMITIVE_TYPE.NUMBER:
216
+ case PRIMITIVE_TYPE.FLOAT:
212
217
  return {
213
218
  filter: 'agNumberColumnFilter',
214
219
  };
@@ -241,6 +246,7 @@ const getColDefs = (
241
246
  tdsExecutionResult: executionResult,
242
247
  },
243
248
  ...getFilterTDSColumnCustomizations(executionResult, colName),
249
+ ...getTDSColumnCustomizations(executionResult, colName),
244
250
  }) as DataGridColumnDefinition,
245
251
  );
246
252
 
@@ -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,109 @@ import type {
47
48
  } from '../../../stores/QueryBuilderResultState.js';
48
49
  import { QUERY_BUILDER_TEST_ID } from '../../../__lib__/QueryBuilderTesting.js';
49
50
 
51
+ export const MAXIMUM_FRACTION_DIGITS = 4;
52
+
53
+ export const getFloatGridColumnCustomHeader = (): string =>
54
+ `<div class="ag-cell-label-container" role="presentation">
55
+ <span
56
+ data-ref="eMenu"
57
+ class="ag-header-icon ag-header-cell-menu-button"
58
+ ></span>
59
+ <span
60
+ data-ref="eFilterButton"
61
+ class="ag-header-icon ag-header-cell-filter-button"
62
+ ></span>
63
+ <div data-ref="eLabel" class="ag-header-cell-label" role="presentation">
64
+ <span
65
+ data-ref="eSortOrder"
66
+ class="ag-header-icon ag-sort-order ag-hidden"
67
+ ></span>
68
+ <span
69
+ data-ref="eSortAsc"
70
+ class="ag-header-icon ag-sort-ascending-icon ag-hidden"
71
+ ></span>
72
+ <span
73
+ data-ref="eSortDesc"
74
+ class="ag-header-icon ag-sort-descending-icon ag-hidden"
75
+ ></span>
76
+ <span
77
+ data-ref="eSortMixed"
78
+ class="ag-header-icon ag-sort-mixed-icon ag-hidden"
79
+ ></span>
80
+ <span
81
+ data-ref="eSortNone"
82
+ class="ag-header-icon ag-sort-none-icon ag-hidden"
83
+ ></span>
84
+ <span
85
+ data-ref="eText"
86
+ class="ag-header-cell-text"
87
+ role="columnheader"
88
+ ></span>
89
+ <span data-ref="eFilter" class="ag-header-icon ag-filter-icon"></span>
90
+ </div>
91
+ <div
92
+ data-testid="query__builder__result__grid__custom-header"
93
+ class="query-builder__result__values__table__custom-header"
94
+ >
95
+ <div
96
+ class="query-builder__result__values__table__custom-header__icon"
97
+ title="some values have been rounded using en-us format in this preview grid (defaults to max 4 decimal places)"
98
+ >
99
+ <svg
100
+ stroke="currentColor"
101
+ fill="currentColor"
102
+ stroke-width="0"
103
+ viewBox="0 0 576 512"
104
+ height="1em"
105
+ width="1em"
106
+ xmlns="http://www.w3.org/2000/svg"
107
+ >
108
+ <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>
109
+ </svg>
110
+ </div>
111
+ </div>
112
+ </div>`;
113
+
114
+ export const getTDSColumnCustomizations = (
115
+ result: TDSExecutionResult,
116
+ columnName: string,
117
+ ): object => {
118
+ const index = result.builder.columns.findIndex(
119
+ (col) => col.name === columnName,
120
+ );
121
+ if (index >= 0) {
122
+ const columnType = result.builder.columns[index]?.type;
123
+ const colValues = result.result.rows.map((r) => r.values[index]);
124
+ const isTruncated = (
125
+ vals: (string | number | boolean | null | undefined)[],
126
+ ): boolean =>
127
+ Boolean(
128
+ vals.some((val) => {
129
+ if (val) {
130
+ const decimalPart = val.toString().split('.')[1];
131
+ return decimalPart && decimalPart.length > MAXIMUM_FRACTION_DIGITS;
132
+ }
133
+ return false;
134
+ }),
135
+ );
136
+ switch (columnType) {
137
+ case PRIMITIVE_TYPE.NUMBER:
138
+ case PRIMITIVE_TYPE.DECIMAL:
139
+ case PRIMITIVE_TYPE.FLOAT:
140
+ return isTruncated(colValues)
141
+ ? {
142
+ headerComponentParams: {
143
+ template: getFloatGridColumnCustomHeader(),
144
+ },
145
+ }
146
+ : {};
147
+ default:
148
+ return {};
149
+ }
150
+ }
151
+ return {};
152
+ };
153
+
50
154
  const QueryResultCellRenderer = observer(
51
155
  (params: IQueryRendererParamsWithGridType) => {
52
156
  const resultState = params.resultState;
@@ -62,7 +166,7 @@ const QueryResultCellRenderer = observer(
62
166
  const formattedCellValue = (): QueryBuilderTDSResultCellDataType => {
63
167
  if (isNumber(cellValue)) {
64
168
  return Intl.NumberFormat(DEFAULT_LOCALE, {
65
- maximumFractionDigits: 4,
169
+ maximumFractionDigits: MAXIMUM_FRACTION_DIGITS,
66
170
  }).format(Number(cellValue));
67
171
  } else if (isBoolean(cellValue)) {
68
172
  return String(cellValue);
@@ -368,6 +472,7 @@ export const QueryBuilderTDSSimpleGridResult = observer(
368
472
  resizable: true,
369
473
  field: colName,
370
474
  flex: 1,
475
+ ...getTDSColumnCustomizations(executionResult, colName),
371
476
  cellRenderer: QueryResultCellRenderer,
372
477
  cellRendererParams: {
373
478
  resultState: resultState,
@@ -25,12 +25,13 @@ export const DEFAULT_VARIABLE_NAME = 'var';
25
25
  export const DEFAULT_CONSTANT_VARIABLE_NAME = 'c_var';
26
26
  export const DEFAULT_POST_FILTER_LAMBDA_VARIABLE_NAME = 'row';
27
27
 
28
- export const QUERY_BUILDER_PROPERTY_SEARCH_MAX_DEPTH = 5;
28
+ export const QUERY_BUILDER_PROPERTY_SEARCH_MAX_DEPTH = 10;
29
29
  export const QUERY_BUILDER_PROPERTY_SEARCH_MAX_NODES = 10000;
30
30
  export const QUERY_BUILDER_PROPERTY_SEARCH_RESULTS_LIMIT = 100;
31
31
 
32
32
  export enum QUERY_BUILDER_PROPERTY_SEARCH_TYPE {
33
33
  CLASS = 'CLASS',
34
+ ENUMERATION = 'ENUMERATION',
34
35
  STRING = 'STRING',
35
36
  BOOLEAN = 'BOOLEAN',
36
37
  NUMBER = 'NUMBER',
@@ -38,6 +38,7 @@ import {
38
38
  reportGraphAnalytics,
39
39
  TDSExecutionResult,
40
40
  V1_ZIPKIN_TRACE_HEADER,
41
+ ExecutionError,
41
42
  } from '@finos/legend-graph';
42
43
  import { buildLambdaFunction } from './QueryBuilderValueSpecificationBuilder.js';
43
44
  import {
@@ -536,6 +537,9 @@ export class QueryBuilderResultState {
536
537
  error,
537
538
  );
538
539
  this.setExecutionError(error);
540
+ if (error instanceof ExecutionError && error.executionTraceId) {
541
+ this.setExecutionTraceId(error.executionTraceId);
542
+ }
539
543
  }
540
544
  } finally {
541
545
  this.setIsRunningQuery(false);
@@ -213,7 +213,7 @@ export const isPropertyExpressionChainOptional = (
213
213
 
214
214
  export const isTypeCompatibleForAssignment = (
215
215
  type: Type | undefined,
216
- assignmentType: Type,
216
+ assignmentType: Type | undefined,
217
217
  ): boolean => {
218
218
  const NUMERIC_PRIMITIVE_TYPES = [
219
219
  PRIMITIVE_TYPE.NUMBER,
@@ -231,6 +231,7 @@ export const isTypeCompatibleForAssignment = (
231
231
  // When changing the return type for LHS, the RHS value should be adjusted accordingly.
232
232
  return (
233
233
  type !== undefined &&
234
+ assignmentType !== undefined &&
234
235
  // Numeric value is handled loosely because of autoboxing
235
236
  // e.g. LHS (integer) = RHS (float) is acceptable
236
237
  ((NUMERIC_PRIMITIVE_TYPES.includes(type.path) &&
@@ -19,17 +19,18 @@ import {
19
19
  type GenericLegendApplicationStore,
20
20
  } from '@finos/legend-application';
21
21
  import {
22
- QuerySearchSpecification,
23
- GRAPH_MANAGER_EVENT,
24
22
  type QueryInfo,
25
23
  type LightQuery,
26
24
  type BasicGraphManagerState,
27
25
  type Query,
28
26
  type RawLambda,
27
+ QuerySearchSpecification,
28
+ GRAPH_MANAGER_EVENT,
29
+ QuerySearchSortBy,
29
30
  } from '@finos/legend-graph';
30
31
  import {
31
- ActionState,
32
32
  type GeneratorFn,
33
+ ActionState,
33
34
  assertErrorThrown,
34
35
  guaranteeNonNullable,
35
36
  LogEvent,
@@ -51,7 +52,7 @@ export enum SORT_BY_OPTIONS {
51
52
  SORT_BY_UPDATE = 'Last Updated',
52
53
  }
53
54
 
54
- export type SortByOption = { label: string; value: string };
55
+ export type SortByOption = { label: SORT_BY_OPTIONS; value: SORT_BY_OPTIONS };
55
56
 
56
57
  export class QueryLoaderState {
57
58
  readonly applicationStore: GenericLegendApplicationStore;
@@ -92,7 +93,7 @@ export class QueryLoaderState {
92
93
  showingDefaultQueries = true;
93
94
  showPreviewViewer = false;
94
95
  queryPreviewContent?: QueryInfo | { name: string; content: string };
95
- sortBy = '';
96
+ sortBy = SORT_BY_OPTIONS.SORT_BY_VIEW;
96
97
 
97
98
  constructor(
98
99
  applicationStore: GenericLegendApplicationStore,
@@ -158,10 +159,23 @@ export class QueryLoaderState {
158
159
  this.isCuratedTemplateToggled = val;
159
160
  }
160
161
 
161
- setSortBy(val: string): void {
162
+ setSortBy(val: SORT_BY_OPTIONS): void {
162
163
  this.sortBy = val;
163
164
  }
164
165
 
166
+ getQuerySearchSortBy(sortByValue: string): QuerySearchSortBy | undefined {
167
+ switch (sortByValue) {
168
+ case SORT_BY_OPTIONS.SORT_BY_CREATE:
169
+ return QuerySearchSortBy.SORT_BY_CREATE;
170
+ case SORT_BY_OPTIONS.SORT_BY_UPDATE:
171
+ return QuerySearchSortBy.SORT_BY_UPDATE;
172
+ case SORT_BY_OPTIONS.SORT_BY_VIEW:
173
+ return QuerySearchSortBy.SORT_BY_VIEW;
174
+ default:
175
+ return undefined;
176
+ }
177
+ }
178
+
165
179
  setSearchText(val: string): void {
166
180
  this.searchText = val;
167
181
  }
@@ -171,7 +185,16 @@ export class QueryLoaderState {
171
185
  }
172
186
 
173
187
  setQueries(val: LightQuery[]): void {
174
- this.queries = val.sort((a, b) => a.name.localeCompare(b.name));
188
+ this.queries = val;
189
+ }
190
+
191
+ // search query using search specification
192
+ canPerformAdvancedSearch(searchText: string): boolean {
193
+ return !(
194
+ searchText.length < DEFAULT_TYPEAHEAD_SEARCH_MINIMUM_SEARCH_LENGTH &&
195
+ !this.showCurrentUserQueriesOnly &&
196
+ Array.from(this.extraFilters.values()).every((value) => value === false)
197
+ );
175
198
  }
176
199
 
177
200
  setShowPreviewViewer(val: boolean): void {
@@ -226,11 +249,7 @@ export class QueryLoaderState {
226
249
  }
227
250
 
228
251
  *searchQueries(searchText: string): GeneratorFn<void> {
229
- if (
230
- searchText.length < DEFAULT_TYPEAHEAD_SEARCH_MINIMUM_SEARCH_LENGTH &&
231
- !this.showCurrentUserQueriesOnly &&
232
- Array.from(this.extraFilters.values()).every((value) => value === false)
233
- ) {
252
+ if (!this.canPerformAdvancedSearch(searchText)) {
234
253
  // if no search text is specified, use fetch the default queries
235
254
  if (!searchText) {
236
255
  this.showingDefaultQueries = true;
@@ -268,6 +287,10 @@ export class QueryLoaderState {
268
287
  searchSpecification.limit = QUERY_LOADER_TYPEAHEAD_SEARCH_LIMIT + 1;
269
288
  searchSpecification.showCurrentUserQueriesOnly =
270
289
  this.showCurrentUserQueriesOnly;
290
+ const querySearchSortBy = this.getQuerySearchSortBy(this.sortBy);
291
+ if (querySearchSortBy) {
292
+ searchSpecification.sortByOption = querySearchSortBy;
293
+ }
271
294
  if (this.queryBuilderState) {
272
295
  Array.from(this.extraFilters.entries()).forEach(([key, value]) => {
273
296
  if (value) {
@@ -288,11 +311,14 @@ export class QueryLoaderState {
288
311
  searchSpecification =
289
312
  this.decorateSearchSpecification?.(searchSpecification) ??
290
313
  searchSpecification;
291
- this.queries = (
292
- (yield this.graphManagerState.graphManager.searchQueries(
293
- searchSpecification,
294
- )) as LightQuery[]
295
- ).sort((a, b) => a.name.localeCompare(b.name));
314
+ this.queries = (yield this.graphManagerState.graphManager.searchQueries(
315
+ searchSpecification,
316
+ )) as LightQuery[];
317
+ if (!querySearchSortBy) {
318
+ this.queries = this.queries.sort((a, b) =>
319
+ a.name.localeCompare(b.name),
320
+ );
321
+ }
296
322
  this.searchQueriesState.pass();
297
323
  } catch (error) {
298
324
  assertErrorThrown(error);
@@ -31,6 +31,7 @@ import {
31
31
  type MappingModelCoverageAnalysisResult,
32
32
  type EnumMappedProperty,
33
33
  type MappedEntity,
34
+ type ExecutionResultWithMetadata,
34
35
  AbstractPropertyExpression,
35
36
  Class,
36
37
  VariableExpression,
@@ -55,7 +56,6 @@ import {
55
56
  Association,
56
57
  PRIMITIVE_TYPE,
57
58
  TDSExecutionResult,
58
- type ExecutionResult,
59
59
  getAllSubclasses,
60
60
  PropertyExplicitReference,
61
61
  reportGraphAnalytics,
@@ -115,6 +115,7 @@ export abstract class QueryBuilderExplorerTreeNodeData implements TreeNodeData {
115
115
  isPartOfDerivedPropertyBranch: boolean,
116
116
  type: Type,
117
117
  mappingData: QueryBuilderExplorerTreeNodeMappingData,
118
+ childrenIds?: string[] | undefined,
118
119
  ) {
119
120
  makeObservable(this, {
120
121
  isHighlighting: observable,
@@ -131,6 +132,9 @@ export abstract class QueryBuilderExplorerTreeNodeData implements TreeNodeData {
131
132
  this.isPartOfDerivedPropertyBranch = isPartOfDerivedPropertyBranch;
132
133
  this.type = type;
133
134
  this.mappingData = mappingData;
135
+ if (childrenIds) {
136
+ this.childrenIds = childrenIds;
137
+ }
134
138
  this.elementRef = createRef();
135
139
  }
136
140
 
@@ -169,6 +173,7 @@ export class QueryBuilderExplorerTreePropertyNodeData extends QueryBuilderExplor
169
173
  isPartOfDerivedPropertyBranch: boolean,
170
174
  mappingData: QueryBuilderExplorerTreeNodeMappingData,
171
175
  type?: Type | undefined,
176
+ childrenIds?: string[],
172
177
  ) {
173
178
  super(
174
179
  id,
@@ -177,6 +182,7 @@ export class QueryBuilderExplorerTreePropertyNodeData extends QueryBuilderExplor
177
182
  isPartOfDerivedPropertyBranch,
178
183
  type ?? property.genericType.value.rawType,
179
184
  mappingData,
185
+ childrenIds,
180
186
  );
181
187
  this.property = property;
182
188
  this.parentId = parentId;
@@ -197,6 +203,7 @@ export class QueryBuilderExplorerTreeSubTypeNodeData extends QueryBuilderExplore
197
203
  isPartOfDerivedPropertyBranch: boolean,
198
204
  mappingData: QueryBuilderExplorerTreeNodeMappingData,
199
205
  multiplicity: Multiplicity,
206
+ childrenIds?: string[],
200
207
  ) {
201
208
  super(
202
209
  id,
@@ -205,6 +212,7 @@ export class QueryBuilderExplorerTreeSubTypeNodeData extends QueryBuilderExplore
205
212
  isPartOfDerivedPropertyBranch,
206
213
  subclass,
207
214
  mappingData,
215
+ childrenIds,
208
216
  );
209
217
  this.subclass = subclass;
210
218
  this.parentId = parentId;
@@ -652,6 +660,49 @@ const getQueryBuilderTreeData = (
652
660
  return { rootIds, nodes };
653
661
  };
654
662
 
663
+ export const cloneQueryBuilderExplorerTreeNodeData = (
664
+ node: QueryBuilderExplorerTreeNodeData,
665
+ ): QueryBuilderExplorerTreeNodeData => {
666
+ if (node instanceof QueryBuilderExplorerTreeRootNodeData) {
667
+ return new QueryBuilderExplorerTreeRootNodeData(
668
+ node.id,
669
+ node.label,
670
+ node.dndText,
671
+ node.isPartOfDerivedPropertyBranch,
672
+ node.type,
673
+ node.mappingData,
674
+ node.childrenIds,
675
+ );
676
+ } else if (node instanceof QueryBuilderExplorerTreePropertyNodeData) {
677
+ return new QueryBuilderExplorerTreePropertyNodeData(
678
+ node.id,
679
+ node.label,
680
+ node.dndText,
681
+ node.property,
682
+ node.parentId,
683
+ node.isPartOfDerivedPropertyBranch,
684
+ node.mappingData,
685
+ node.type,
686
+ node.childrenIds,
687
+ );
688
+ } else if (node instanceof QueryBuilderExplorerTreeSubTypeNodeData) {
689
+ return new QueryBuilderExplorerTreeSubTypeNodeData(
690
+ node.id,
691
+ node.label,
692
+ node.dndText,
693
+ node.subclass,
694
+ node.parentId,
695
+ node.isPartOfDerivedPropertyBranch,
696
+ node.mappingData,
697
+ node.multiplicity,
698
+ node.childrenIds,
699
+ );
700
+ }
701
+ throw new UnsupportedOperationError(
702
+ `Unable to clone node of type ${node.constructor.name}`,
703
+ );
704
+ };
705
+
655
706
  export class QueryBuilderExplorerPreviewDataState {
656
707
  isGeneratingPreviewData = false;
657
708
  propertyName = '(unknown)';
@@ -957,7 +1008,7 @@ export class QueryBuilderExplorerState {
957
1008
  case PRIMITIVE_TYPE.INTEGER:
958
1009
  case PRIMITIVE_TYPE.DECIMAL:
959
1010
  case PRIMITIVE_TYPE.FLOAT: {
960
- const previewResult =
1011
+ const previewResult = (
961
1012
  (yield this.queryBuilderState.graphManagerState.graphManager.runQuery(
962
1013
  buildNumericPreviewDataQuery(
963
1014
  this.queryBuilderState,
@@ -970,7 +1021,8 @@ export class QueryBuilderExplorerState {
970
1021
  abortController:
971
1022
  this.previewDataState.previewDataAbortController,
972
1023
  },
973
- )) as ExecutionResult;
1024
+ )) as ExecutionResultWithMetadata
1025
+ ).executionResult;
974
1026
  assertType(
975
1027
  previewResult,
976
1028
  TDSExecutionResult,
@@ -998,7 +1050,7 @@ export class QueryBuilderExplorerState {
998
1050
  case PRIMITIVE_TYPE.DATE:
999
1051
  case PRIMITIVE_TYPE.STRICTDATE:
1000
1052
  case PRIMITIVE_TYPE.DATETIME: {
1001
- const previewResult =
1053
+ const previewResult = (
1002
1054
  (yield this.queryBuilderState.graphManagerState.graphManager.runQuery(
1003
1055
  buildNonNumericPreviewDataQuery(
1004
1056
  this.queryBuilderState,
@@ -1011,7 +1063,8 @@ export class QueryBuilderExplorerState {
1011
1063
  abortController:
1012
1064
  this.previewDataState.previewDataAbortController,
1013
1065
  },
1014
- )) as ExecutionResult;
1066
+ )) as ExecutionResultWithMetadata
1067
+ ).executionResult;
1015
1068
  assertType(
1016
1069
  previewResult,
1017
1070
  TDSExecutionResult,
@@ -18,7 +18,7 @@ import { FuzzySearchAdvancedConfigState } from '@finos/legend-shared';
18
18
  import { action, makeObservable, observable } from 'mobx';
19
19
 
20
20
  export class QueryBuilderFuzzySearchAdvancedConfigState extends FuzzySearchAdvancedConfigState {
21
- includeSubTypes = false;
21
+ includeSubTypes = true;
22
22
  includeDocumentation = false;
23
23
 
24
24
  constructor(