@finos/legend-query-builder 4.14.70 → 4.14.72
Sign up to get free protection for your applications and to get access to all the features.
- package/lib/components/QueryBuilderConstantExpressionPanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderConstantExpressionPanel.js +2 -1
- package/lib/components/QueryBuilderConstantExpressionPanel.js.map +1 -1
- 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 -16
- package/lib/components/result/tds/QueryBuilderTDSGridResult.js.map +1 -1
- package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.d.ts +3 -1
- package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.d.ts.map +1 -1
- package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.js +88 -31
- 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/QueryBuilderConstantsState.d.ts +1 -0
- package/lib/stores/QueryBuilderConstantsState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderConstantsState.js +6 -1
- package/lib/stores/QueryBuilderConstantsState.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/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/QueryBuilderConstantExpressionPanel.tsx +2 -1
- 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 -16
- package/src/components/result/tds/QueryBuilderTDSSimpleGridResult.tsx +96 -34
- package/src/stores/QueryBuilderConstantsState.ts +16 -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
@@ -746,7 +746,8 @@ export const QueryResultModifierModal = observer(
|
|
746
746
|
classes={{
|
747
747
|
root: 'editor-modal__root-container',
|
748
748
|
container: 'editor-modal__container',
|
749
|
-
paper:
|
749
|
+
paper:
|
750
|
+
'editor-modal__content query-builder__projection__modal__content',
|
750
751
|
}}
|
751
752
|
data-testid={QUERY_BUILDER_TEST_ID.QUERY_BUILDER_RESULT_MODIFIER_PANEL}
|
752
753
|
>
|
@@ -756,7 +757,10 @@ export const QueryResultModifierModal = observer(
|
|
756
757
|
}
|
757
758
|
className="editor-modal query-builder__projection__modal"
|
758
759
|
>
|
759
|
-
<ModalHeader
|
760
|
+
<ModalHeader
|
761
|
+
className="query-builder__projection__modal__header"
|
762
|
+
title="Query Options"
|
763
|
+
/>
|
760
764
|
<ModalBody className="query-builder__projection__modal__body">
|
761
765
|
<div className="query-builder__projection__options">
|
762
766
|
{tdsState.queryBuilderState.milestoningState
|
@@ -214,7 +214,8 @@ const QueryBuilderDerivationProjectionColumnEditor = observer(
|
|
214
214
|
}) => {
|
215
215
|
const { projectionColumnState } = props;
|
216
216
|
const hasParserError = projectionColumnState.tdsState.hasParserError;
|
217
|
-
|
217
|
+
|
218
|
+
const onEditorBlur = useCallback((): void => {
|
218
219
|
flowResult(
|
219
220
|
projectionColumnState.fetchDerivationLambdaReturnType({
|
220
221
|
forceConversionStringToLambda: true,
|
@@ -224,7 +225,8 @@ const QueryBuilderDerivationProjectionColumnEditor = observer(
|
|
224
225
|
projectionColumnState.tdsState.queryBuilderState.applicationStore
|
225
226
|
.alertUnhandledError,
|
226
227
|
);
|
227
|
-
};
|
228
|
+
}, [projectionColumnState]);
|
229
|
+
|
228
230
|
const handleDrop = useCallback(
|
229
231
|
(
|
230
232
|
item: QueryBuilderDerivationProjectionColumnDropTarget,
|
@@ -256,6 +258,7 @@ const QueryBuilderDerivationProjectionColumnEditor = observer(
|
|
256
258
|
},
|
257
259
|
[projectionColumnState],
|
258
260
|
);
|
261
|
+
|
259
262
|
const [, dropConnector] =
|
260
263
|
useDrop<QueryBuilderDerivationProjectionColumnDropTarget>(
|
261
264
|
() => ({
|
@@ -269,6 +272,11 @@ const QueryBuilderDerivationProjectionColumnEditor = observer(
|
|
269
272
|
[handleDrop],
|
270
273
|
);
|
271
274
|
|
275
|
+
// Calculate derivation return type on mount
|
276
|
+
useEffect(() => {
|
277
|
+
onEditorBlur();
|
278
|
+
}, [onEditorBlur]);
|
279
|
+
|
272
280
|
return (
|
273
281
|
<div
|
274
282
|
ref={dropConnector}
|
@@ -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}
|
@@ -61,7 +61,10 @@ import {
|
|
61
61
|
Dialog,
|
62
62
|
CustomSelectorInput,
|
63
63
|
} from '@finos/legend-art';
|
64
|
-
import {
|
64
|
+
import {
|
65
|
+
getTDSColumnCustomizations,
|
66
|
+
MAXIMUM_FRACTION_DIGITS,
|
67
|
+
} from './QueryBuilderTDSSimpleGridResult.js';
|
65
68
|
|
66
69
|
export const enum QueryBuilderDataGridCustomAggregationFunction {
|
67
70
|
wavg = 'wavg',
|
@@ -88,20 +91,13 @@ const getAggregationTDSColumnCustomizations = (
|
|
88
91
|
filter: 'agDateColumnFilter',
|
89
92
|
allowedAggFuncs: ['count'],
|
90
93
|
};
|
94
|
+
case PRIMITIVE_TYPE.DECIMAL:
|
91
95
|
case PRIMITIVE_TYPE.NUMBER:
|
92
96
|
case PRIMITIVE_TYPE.INTEGER:
|
93
|
-
return {
|
94
|
-
filter: 'agNumberColumnFilter',
|
95
|
-
allowedAggFuncs: ['count', 'sum', 'max', 'min', 'avg', 'wavg'],
|
96
|
-
};
|
97
|
-
case PRIMITIVE_TYPE.DECIMAL:
|
98
97
|
case PRIMITIVE_TYPE.FLOAT:
|
99
98
|
return {
|
100
99
|
filter: 'agNumberColumnFilter',
|
101
100
|
allowedAggFuncs: ['count', 'sum', 'max', 'min', 'avg', 'wavg'],
|
102
|
-
headerComponentParams: {
|
103
|
-
template: getFloatGridColumnCustomHeader(columnName),
|
104
|
-
},
|
105
101
|
};
|
106
102
|
default:
|
107
103
|
return {
|
@@ -117,7 +113,7 @@ const QueryResultCellRenderer = observer(
|
|
117
113
|
const formattedCellValue = (): QueryBuilderTDSResultCellDataType => {
|
118
114
|
if (isNumber(cellValue)) {
|
119
115
|
return Intl.NumberFormat(DEFAULT_LOCALE, {
|
120
|
-
maximumFractionDigits:
|
116
|
+
maximumFractionDigits: MAXIMUM_FRACTION_DIGITS,
|
121
117
|
}).format(Number(cellValue));
|
122
118
|
} else if (isBoolean(cellValue)) {
|
123
119
|
return String(cellValue);
|
@@ -181,6 +177,7 @@ const getLocalColDefs = (
|
|
181
177
|
tdsExecutionResult: executionResult,
|
182
178
|
},
|
183
179
|
...getAggregationTDSColumnCustomizations(executionResult, colName),
|
180
|
+
...getTDSColumnCustomizations(executionResult, colName),
|
184
181
|
} as DataGridColumnDefinition;
|
185
182
|
const persistedColumn = resultState.gridConfig?.columns.find(
|
186
183
|
(c) => c.colId === colName,
|
@@ -216,15 +213,9 @@ const getFilterTDSColumnCustomizations = (
|
|
216
213
|
case PRIMITIVE_TYPE.DECIMAL:
|
217
214
|
case PRIMITIVE_TYPE.INTEGER:
|
218
215
|
case PRIMITIVE_TYPE.NUMBER:
|
219
|
-
return {
|
220
|
-
filter: 'agNumberColumnFilter',
|
221
|
-
};
|
222
216
|
case PRIMITIVE_TYPE.FLOAT:
|
223
217
|
return {
|
224
218
|
filter: 'agNumberColumnFilter',
|
225
|
-
headerComponentParams: {
|
226
|
-
template: getFloatGridColumnCustomHeader(columnName),
|
227
|
-
},
|
228
219
|
};
|
229
220
|
default:
|
230
221
|
// we default all other columns to use filter true which defaults to set filters
|
@@ -255,6 +246,7 @@ const getColDefs = (
|
|
255
246
|
tdsExecutionResult: executionResult,
|
256
247
|
},
|
257
248
|
...getFilterTDSColumnCustomizations(executionResult, colName),
|
249
|
+
...getTDSColumnCustomizations(executionResult, colName),
|
258
250
|
}) as DataGridColumnDefinition,
|
259
251
|
);
|
260
252
|
|
@@ -48,45 +48,107 @@ import type {
|
|
48
48
|
} from '../../../stores/QueryBuilderResultState.js';
|
49
49
|
import { QUERY_BUILDER_TEST_ID } from '../../../__lib__/QueryBuilderTesting.js';
|
50
50
|
|
51
|
-
export const
|
52
|
-
|
53
|
-
): string =>
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
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>`;
|
72
113
|
|
73
|
-
const getTDSColumnCustomizations = (
|
114
|
+
export const getTDSColumnCustomizations = (
|
74
115
|
result: TDSExecutionResult,
|
75
116
|
columnName: string,
|
76
117
|
): object => {
|
77
|
-
const
|
118
|
+
const index = result.builder.columns.findIndex(
|
78
119
|
(col) => col.name === columnName,
|
79
|
-
)
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
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
|
+
}
|
89
150
|
}
|
151
|
+
return {};
|
90
152
|
};
|
91
153
|
|
92
154
|
const QueryResultCellRenderer = observer(
|
@@ -104,7 +166,7 @@ const QueryResultCellRenderer = observer(
|
|
104
166
|
const formattedCellValue = (): QueryBuilderTDSResultCellDataType => {
|
105
167
|
if (isNumber(cellValue)) {
|
106
168
|
return Intl.NumberFormat(DEFAULT_LOCALE, {
|
107
|
-
maximumFractionDigits:
|
169
|
+
maximumFractionDigits: MAXIMUM_FRACTION_DIGITS,
|
108
170
|
}).format(Number(cellValue));
|
109
171
|
} else if (isBoolean(cellValue)) {
|
110
172
|
return String(cellValue);
|
@@ -288,6 +288,7 @@ export class QueryBuilderCalculatedConstantExpressionState
|
|
288
288
|
variable: observable,
|
289
289
|
lambdaState: observable,
|
290
290
|
value: observable,
|
291
|
+
setLambdaState: action,
|
291
292
|
setValue: action,
|
292
293
|
});
|
293
294
|
this.value = value;
|
@@ -298,6 +299,10 @@ export class QueryBuilderCalculatedConstantExpressionState
|
|
298
299
|
);
|
299
300
|
}
|
300
301
|
|
302
|
+
setLambdaState(val: QueryBuilderConstantLambdaEditorState): void {
|
303
|
+
this.lambdaState = val;
|
304
|
+
}
|
305
|
+
|
301
306
|
setValue(val: PlainObject): void {
|
302
307
|
this.value = val;
|
303
308
|
}
|
@@ -393,8 +398,18 @@ export class QueryBuilderConstantsState implements Hashable {
|
|
393
398
|
export const cloneQueryBuilderConstantLambdaEditorState = (
|
394
399
|
state: QueryBuilderConstantLambdaEditorState,
|
395
400
|
): QueryBuilderConstantLambdaEditorState => {
|
401
|
+
const clonedCalculatedState =
|
402
|
+
new QueryBuilderCalculatedConstantExpressionState(
|
403
|
+
state.calculatedState.queryBuilderState,
|
404
|
+
new VariableExpression(
|
405
|
+
state.calculatedState.variable.name,
|
406
|
+
state.calculatedState.variable.multiplicity,
|
407
|
+
state.calculatedState.variable.genericType,
|
408
|
+
),
|
409
|
+
deepClone(state.calculatedState.value),
|
410
|
+
);
|
396
411
|
const clonedState = new QueryBuilderConstantLambdaEditorState(
|
397
|
-
|
412
|
+
clonedCalculatedState,
|
398
413
|
);
|
399
414
|
clonedState.lambdaString = state.lambdaString;
|
400
415
|
clonedState.parserError = deepClone(state.parserError);
|
@@ -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
|
|