@finos/legend-query-builder 4.14.71 → 4.14.72
Sign up to get free protection for your applications and to get access to all the features.
- 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/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/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 +2 -2
- package/lib/index.css.map +1 -1
- package/lib/package.json +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/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 +22 -11
- 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 +8 -4
- package/lib/stores/filter/QueryBuilderFilterState.js.map +1 -1
- package/package.json +3 -3
- package/src/components/QueryLoader.tsx +37 -54
- 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/tds/QueryBuilderTDSGridResult.tsx +8 -2
- package/src/components/result/tds/QueryBuilderTDSSimpleGridResult.tsx +106 -1
- package/src/stores/QueryBuilderValueSpecificationHelper.ts +2 -1
- package/src/stores/QueryLoaderState.ts +43 -17
- package/src/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.ts +39 -10
- package/src/stores/filter/QueryBuilderFilterState.ts +11 -3
@@ -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,
|
@@ -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);
|
@@ -20,12 +20,12 @@ import {
|
|
20
20
|
type Type,
|
21
21
|
type ValueSpecification,
|
22
22
|
type ExecutionResult,
|
23
|
-
type VariableExpression,
|
24
23
|
type SimpleFunctionExpression,
|
25
24
|
observe_ValueSpecification,
|
26
25
|
PrimitiveType,
|
27
26
|
CollectionInstanceValue,
|
28
27
|
InstanceValue,
|
28
|
+
VariableExpression,
|
29
29
|
} from '@finos/legend-graph';
|
30
30
|
import {
|
31
31
|
type GeneratorFn,
|
@@ -74,11 +74,13 @@ import type { QueryBuilderTDSColumnState } from '../QueryBuilderTDSColumnState.j
|
|
74
74
|
import {
|
75
75
|
getCollectionValueSpecificationType,
|
76
76
|
getNonCollectionValueSpecificationType,
|
77
|
+
isTypeCompatibleForAssignment,
|
77
78
|
isValidInstanceValue,
|
78
79
|
isValueExpressionReferencedInValue,
|
79
80
|
} from '../../../QueryBuilderValueSpecificationHelper.js';
|
80
81
|
import { buildtdsPropertyExpressionFromColState } from './operators/QueryBuilderPostFilterOperatorValueSpecificationBuilder.js';
|
81
82
|
import { TDS_COLUMN_GETTER } from '../../../../graph/QueryBuilderMetaModelConst.js';
|
83
|
+
import type { QueryBuilderFilterTreeNodeData } from '../../../filter/QueryBuilderFilterState.js';
|
82
84
|
|
83
85
|
export enum QUERY_BUILDER_POST_FILTER_DND_TYPE {
|
84
86
|
GROUP_CONDITION = 'QUERY_BUILDER_POST_FILTER_DND_TYPE.GROUP_CONDITION',
|
@@ -1011,15 +1013,45 @@ export class QueryBuilderPostFilterState
|
|
1011
1013
|
);
|
1012
1014
|
}
|
1013
1015
|
|
1016
|
+
isInvalidValueSpecPostFilterValue(
|
1017
|
+
node: QueryBuilderPostFilterTreeNodeData,
|
1018
|
+
): boolean {
|
1019
|
+
return (
|
1020
|
+
node instanceof QueryBuilderPostFilterTreeConditionNodeData &&
|
1021
|
+
node.condition.rightConditionValue instanceof
|
1022
|
+
PostFilterValueSpecConditionValueState &&
|
1023
|
+
((node.condition.rightConditionValue.value instanceof InstanceValue &&
|
1024
|
+
!isValidInstanceValue(node.condition.rightConditionValue.value)) ||
|
1025
|
+
(node.condition.rightConditionValue.value instanceof
|
1026
|
+
VariableExpression &&
|
1027
|
+
!isTypeCompatibleForAssignment(
|
1028
|
+
node.condition.leftConditionValue.getColumnType(),
|
1029
|
+
node.condition.rightConditionValue.type,
|
1030
|
+
)))
|
1031
|
+
);
|
1032
|
+
}
|
1033
|
+
|
1034
|
+
isInvalidTDSColumnPostFilterValue(
|
1035
|
+
node: QueryBuilderFilterTreeNodeData,
|
1036
|
+
): boolean {
|
1037
|
+
return (
|
1038
|
+
node instanceof QueryBuilderPostFilterTreeConditionNodeData &&
|
1039
|
+
node.condition.rightConditionValue instanceof
|
1040
|
+
PostFilterTDSColumnValueConditionValueState &&
|
1041
|
+
!isTypeCompatibleForAssignment(
|
1042
|
+
node.condition.leftConditionValue.getColumnType(),
|
1043
|
+
node.condition.rightConditionValue.type,
|
1044
|
+
)
|
1045
|
+
);
|
1046
|
+
}
|
1047
|
+
|
1014
1048
|
get allValidationIssues(): string[] {
|
1015
1049
|
const validationIssues: string[] = [];
|
1016
1050
|
Array.from(this.nodes.values()).forEach((node) => {
|
1017
1051
|
if (node instanceof QueryBuilderPostFilterTreeConditionNodeData) {
|
1018
1052
|
if (
|
1019
|
-
node
|
1020
|
-
|
1021
|
-
node.condition.rightConditionValue.value instanceof InstanceValue &&
|
1022
|
-
!isValidInstanceValue(node.condition.rightConditionValue.value)
|
1053
|
+
this.isInvalidValueSpecPostFilterValue(node) ||
|
1054
|
+
this.isInvalidTDSColumnPostFilterValue(node)
|
1023
1055
|
) {
|
1024
1056
|
validationIssues.push(
|
1025
1057
|
`Filter value for ${node.condition.leftConditionValue.columnName} is missing or invalid`,
|
@@ -1042,11 +1074,8 @@ export class QueryBuilderPostFilterState
|
|
1042
1074
|
get hasInvalidFilterValues(): boolean {
|
1043
1075
|
return Array.from(this.nodes.values()).some(
|
1044
1076
|
(node) =>
|
1045
|
-
node
|
1046
|
-
node
|
1047
|
-
PostFilterValueSpecConditionValueState &&
|
1048
|
-
node.condition.rightConditionValue.value instanceof InstanceValue &&
|
1049
|
-
!isValidInstanceValue(node.condition.rightConditionValue.value),
|
1077
|
+
this.isInvalidValueSpecPostFilterValue(node) ||
|
1078
|
+
this.isInvalidTDSColumnPostFilterValue(node),
|
1050
1079
|
);
|
1051
1080
|
}
|
1052
1081
|
|
@@ -40,12 +40,12 @@ import {
|
|
40
40
|
type ExecutionResult,
|
41
41
|
AbstractPropertyExpression,
|
42
42
|
type ValueSpecification,
|
43
|
-
type VariableExpression,
|
44
43
|
type Type,
|
45
44
|
observe_ValueSpecification,
|
46
45
|
CollectionInstanceValue,
|
47
46
|
InstanceValue,
|
48
47
|
SimpleFunctionExpression,
|
48
|
+
VariableExpression,
|
49
49
|
matchFunctionName,
|
50
50
|
} from '@finos/legend-graph';
|
51
51
|
import { DEFAULT_LAMBDA_VARIABLE_NAME } from '../QueryBuilderConfig.js';
|
@@ -61,6 +61,7 @@ import { QUERY_BUILDER_STATE_HASH_STRUCTURE } from '../QueryBuilderStateHashUtil
|
|
61
61
|
import {
|
62
62
|
getCollectionValueSpecificationType,
|
63
63
|
getNonCollectionValueSpecificationType,
|
64
|
+
isTypeCompatibleForAssignment,
|
64
65
|
isValidInstanceValue,
|
65
66
|
isValueExpressionReferencedInValue,
|
66
67
|
} from '../QueryBuilderValueSpecificationHelper.js';
|
@@ -1185,8 +1186,15 @@ export class QueryBuilderFilterState
|
|
1185
1186
|
node instanceof QueryBuilderFilterTreeConditionNodeData &&
|
1186
1187
|
node.condition.rightConditionValue instanceof
|
1187
1188
|
FilterValueSpecConditionValueState &&
|
1188
|
-
node.condition.rightConditionValue.value instanceof InstanceValue &&
|
1189
|
-
|
1189
|
+
((node.condition.rightConditionValue.value instanceof InstanceValue &&
|
1190
|
+
!isValidInstanceValue(node.condition.rightConditionValue.value)) ||
|
1191
|
+
(node.condition.rightConditionValue.value instanceof
|
1192
|
+
VariableExpression &&
|
1193
|
+
!isTypeCompatibleForAssignment(
|
1194
|
+
node.condition.propertyExpressionState.propertyExpression.func.value
|
1195
|
+
.genericType.value.rawType,
|
1196
|
+
node.condition.rightConditionValue.value.genericType?.value.rawType,
|
1197
|
+
)))
|
1190
1198
|
);
|
1191
1199
|
}
|
1192
1200
|
|