@finos/legend-query-builder 4.14.70 → 4.14.72
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/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
|
|