@finos/legend-query-builder 4.14.71 → 4.14.73
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.
- package/lib/components/QueryLoader.d.ts.map +1 -1
- package/lib/components/QueryLoader.js +12 -34
- package/lib/components/QueryLoader.js.map +1 -1
- package/lib/components/explorer/QueryBuilderPropertySearchPanel.d.ts.map +1 -1
- package/lib/components/explorer/QueryBuilderPropertySearchPanel.js +108 -36
- package/lib/components/explorer/QueryBuilderPropertySearchPanel.js.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.d.ts.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js +10 -3
- package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.d.ts.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.js +2 -2
- package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.js.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +6 -2
- package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
- package/lib/components/filter/QueryBuilderFilterPanel.d.ts.map +1 -1
- package/lib/components/filter/QueryBuilderFilterPanel.js +5 -1
- package/lib/components/filter/QueryBuilderFilterPanel.js.map +1 -1
- package/lib/components/result/QueryBuilderResultPanel.d.ts.map +1 -1
- package/lib/components/result/QueryBuilderResultPanel.js +3 -1
- package/lib/components/result/QueryBuilderResultPanel.js.map +1 -1
- package/lib/components/result/tds/QueryBuilderTDSGridResult.d.ts.map +1 -1
- package/lib/components/result/tds/QueryBuilderTDSGridResult.js +5 -2
- package/lib/components/result/tds/QueryBuilderTDSGridResult.js.map +1 -1
- package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.d.ts +3 -0
- package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.d.ts.map +1 -1
- package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.js +92 -2
- package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.js.map +1 -1
- package/lib/index.css +1 -17
- package/lib/index.css.map +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/QueryBuilderConfig.d.ts +2 -1
- package/lib/stores/QueryBuilderConfig.d.ts.map +1 -1
- package/lib/stores/QueryBuilderConfig.js +2 -1
- package/lib/stores/QueryBuilderConfig.js.map +1 -1
- package/lib/stores/QueryBuilderResultState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderResultState.js +4 -1
- package/lib/stores/QueryBuilderResultState.js.map +1 -1
- package/lib/stores/QueryBuilderValueSpecificationHelper.d.ts +1 -1
- package/lib/stores/QueryBuilderValueSpecificationHelper.d.ts.map +1 -1
- package/lib/stores/QueryBuilderValueSpecificationHelper.js +1 -0
- package/lib/stores/QueryBuilderValueSpecificationHelper.js.map +1 -1
- package/lib/stores/QueryLoaderState.d.ts +8 -6
- package/lib/stores/QueryLoaderState.d.ts.map +1 -1
- package/lib/stores/QueryLoaderState.js +30 -7
- package/lib/stores/QueryLoaderState.js.map +1 -1
- package/lib/stores/explorer/QueryBuilderExplorerState.d.ts +4 -3
- package/lib/stores/explorer/QueryBuilderExplorerState.d.ts.map +1 -1
- package/lib/stores/explorer/QueryBuilderExplorerState.js +22 -7
- package/lib/stores/explorer/QueryBuilderExplorerState.js.map +1 -1
- package/lib/stores/explorer/QueryBuilderFuzzySearchAdvancedConfigState.d.ts.map +1 -1
- package/lib/stores/explorer/QueryBuilderFuzzySearchAdvancedConfigState.js +1 -1
- package/lib/stores/explorer/QueryBuilderFuzzySearchAdvancedConfigState.js.map +1 -1
- package/lib/stores/explorer/QueryBuilderPropertySearchState.d.ts +7 -1
- package/lib/stores/explorer/QueryBuilderPropertySearchState.d.ts.map +1 -1
- package/lib/stores/explorer/QueryBuilderPropertySearchState.js +160 -74
- package/lib/stores/explorer/QueryBuilderPropertySearchState.js.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.d.ts +4 -1
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js +23 -12
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js.map +1 -1
- package/lib/stores/filter/QueryBuilderFilterState.d.ts +1 -1
- package/lib/stores/filter/QueryBuilderFilterState.d.ts.map +1 -1
- package/lib/stores/filter/QueryBuilderFilterState.js +9 -5
- package/lib/stores/filter/QueryBuilderFilterState.js.map +1 -1
- package/package.json +3 -3
- package/src/components/QueryLoader.tsx +37 -54
- package/src/components/explorer/QueryBuilderPropertySearchPanel.tsx +249 -226
- package/src/components/fetch-structure/QueryBuilderPostFilterPanel.tsx +24 -2
- package/src/components/fetch-structure/QueryBuilderResultModifierPanel.tsx +6 -2
- package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +10 -2
- package/src/components/filter/QueryBuilderFilterPanel.tsx +10 -1
- package/src/components/result/QueryBuilderResultPanel.tsx +3 -1
- package/src/components/result/tds/QueryBuilderTDSGridResult.tsx +8 -2
- package/src/components/result/tds/QueryBuilderTDSSimpleGridResult.tsx +106 -1
- package/src/stores/QueryBuilderConfig.ts +2 -1
- package/src/stores/QueryBuilderResultState.ts +4 -0
- package/src/stores/QueryBuilderValueSpecificationHelper.ts +2 -1
- package/src/stores/QueryLoaderState.ts +43 -17
- package/src/stores/explorer/QueryBuilderExplorerState.ts +58 -5
- package/src/stores/explorer/QueryBuilderFuzzySearchAdvancedConfigState.ts +1 -1
- package/src/stores/explorer/QueryBuilderPropertySearchState.ts +194 -92
- package/src/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.ts +43 -13
- 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=
|
|
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
|
-
:
|
|
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:
|
|
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:
|
|
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 =
|
|
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:
|
|
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:
|
|
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
|
|
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
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
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
|
|
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
|
|
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 =
|
|
21
|
+
includeSubTypes = true;
|
|
22
22
|
includeDocumentation = false;
|
|
23
23
|
|
|
24
24
|
constructor(
|