@finos/legend-query-builder 4.9.4 → 4.10.0
Sign up to get free protection for your applications and to get access to all the features.
- package/lib/__lib__/QueryBuilderTesting.d.ts +3 -1
- package/lib/__lib__/QueryBuilderTesting.d.ts.map +1 -1
- package/lib/__lib__/QueryBuilderTesting.js +4 -1
- package/lib/__lib__/QueryBuilderTesting.js.map +1 -1
- package/lib/components/QueryBuilderResultPanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderResultPanel.js +36 -33
- package/lib/components/QueryBuilderResultPanel.js.map +1 -1
- package/lib/components/__test-utils__/QueryBuilderComponentTestUtils.d.ts +1 -0
- package/lib/components/__test-utils__/QueryBuilderComponentTestUtils.d.ts.map +1 -1
- package/lib/components/__test-utils__/QueryBuilderComponentTestUtils.js +13 -1
- package/lib/components/__test-utils__/QueryBuilderComponentTestUtils.js.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.d.ts +2 -2
- package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.d.ts.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js +42 -24
- package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +1 -1
- package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
- package/lib/index.css +16 -0
- package/lib/package.json +1 -1
- package/lib/stores/QueryBuilderConstantsState.d.ts +5 -1
- package/lib/stores/QueryBuilderConstantsState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderConstantsState.js +14 -1
- package/lib/stores/QueryBuilderConstantsState.js.map +1 -1
- package/lib/stores/QueryBuilderStateHashUtils.d.ts +2 -0
- package/lib/stores/QueryBuilderStateHashUtils.d.ts.map +1 -1
- package/lib/stores/QueryBuilderStateHashUtils.js +2 -0
- package/lib/stores/QueryBuilderStateHashUtils.js.map +1 -1
- package/lib/stores/QueryBuilderValueSpecificationBuilder.d.ts.map +1 -1
- package/lib/stores/QueryBuilderValueSpecificationBuilder.js +3 -23
- package/lib/stores/QueryBuilderValueSpecificationBuilder.js.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterOperator.js +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterOperator.js.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.d.ts +31 -5
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js +125 -30
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterStateBuilder.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterStateBuilder.js +21 -8
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterStateBuilder.js.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperatorValueSpecificationBuilder.d.ts +3 -1
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperatorValueSpecificationBuilder.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperatorValueSpecificationBuilder.js +20 -17
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperatorValueSpecificationBuilder.js.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Contain.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Contain.js +4 -6
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Contain.js.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_EndWith.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_EndWith.js +4 -6
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_EndWith.js.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Equal.d.ts +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Equal.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Equal.js +10 -10
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Equal.js.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_GreaterThan.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_GreaterThan.js +10 -10
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_GreaterThan.js.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_GreaterThanEqual.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_GreaterThanEqual.js +5 -5
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_GreaterThanEqual.js.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_In.d.ts +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_In.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_In.js +32 -27
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_In.js.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_IsEmpty.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_IsEmpty.js +10 -5
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_IsEmpty.js.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_LessThan.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_LessThan.js +10 -10
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_LessThan.js.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_LessThanEqual.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_LessThanEqual.js +5 -5
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_LessThanEqual.js.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_StartWith.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_StartWith.js +4 -6
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_StartWith.js.map +1 -1
- package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionColumnState.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionColumnState.js +17 -3
- package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionColumnState.js.map +1 -1
- package/package.json +4 -4
- package/src/__lib__/QueryBuilderTesting.ts +4 -1
- package/src/components/QueryBuilderResultPanel.tsx +64 -59
- package/src/components/__test-utils__/QueryBuilderComponentTestUtils.tsx +25 -1
- package/src/components/fetch-structure/QueryBuilderPostFilterPanel.tsx +102 -49
- package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +6 -2
- package/src/stores/QueryBuilderConstantsState.ts +30 -0
- package/src/stores/QueryBuilderStateHashUtils.ts +2 -0
- package/src/stores/QueryBuilderValueSpecificationBuilder.ts +4 -50
- package/src/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterOperator.ts +1 -1
- package/src/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.ts +180 -34
- package/src/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterStateBuilder.ts +38 -9
- package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperatorValueSpecificationBuilder.ts +36 -20
- package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Contain.ts +5 -6
- package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_EndWith.ts +6 -6
- package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Equal.ts +12 -13
- package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_GreaterThan.ts +10 -9
- package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_GreaterThanEqual.ts +5 -4
- package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_In.ts +48 -43
- package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_IsEmpty.ts +12 -4
- package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_LessThan.ts +10 -9
- package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_LessThanEqual.ts +5 -4
- package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_StartWith.ts +6 -6
- package/src/stores/fetch-structure/tds/projection/QueryBuilderProjectionColumnState.ts +26 -4
@@ -80,6 +80,7 @@ import {
|
|
80
80
|
type QueryBuilderPostFilterTreeNodeData,
|
81
81
|
PostFilterConditionState,
|
82
82
|
QueryBuilderPostFilterTreeConditionNodeData,
|
83
|
+
PostFilterValueSpecConditionValueState,
|
83
84
|
} from '../stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js';
|
84
85
|
import {
|
85
86
|
QueryBuilderPostFilterOperator_Equal,
|
@@ -171,13 +172,13 @@ const QueryBuilderGridResultContextMenu = observer(
|
|
171
172
|
.filter(
|
172
173
|
(v) =>
|
173
174
|
v instanceof QueryBuilderPostFilterTreeConditionNodeData &&
|
174
|
-
v.condition.
|
175
|
+
v.condition.leftConditionValue instanceof
|
175
176
|
QueryBuilderProjectionColumnState,
|
176
177
|
)
|
177
178
|
.filter(
|
178
179
|
(n) =>
|
179
180
|
(n as QueryBuilderPostFilterTreeConditionNodeData).condition
|
180
|
-
.
|
181
|
+
.leftConditionValue.columnName ===
|
181
182
|
(projectionColumnName ?? projectionColumnState?.columnName) &&
|
182
183
|
operators
|
183
184
|
.map((op) => op.getLabel())
|
@@ -231,7 +232,6 @@ const QueryBuilderGridResultContextMenu = observer(
|
|
231
232
|
postFilterConditionState = new PostFilterConditionState(
|
232
233
|
postFilterState,
|
233
234
|
possibleProjectionColumnState,
|
234
|
-
undefined,
|
235
235
|
operator,
|
236
236
|
);
|
237
237
|
|
@@ -249,7 +249,9 @@ const QueryBuilderGridResultContextMenu = observer(
|
|
249
249
|
postFilterConditionState,
|
250
250
|
);
|
251
251
|
|
252
|
-
postFilterConditionState.
|
252
|
+
postFilterConditionState.buildFromValueSpec(
|
253
|
+
defaultFilterConditionValue,
|
254
|
+
);
|
253
255
|
updateFilterConditionValue(
|
254
256
|
defaultFilterConditionValue as InstanceValue,
|
255
257
|
cellData,
|
@@ -293,62 +295,65 @@ const QueryBuilderGridResultContextMenu = observer(
|
|
293
295
|
existingPostFilterNode as QueryBuilderPostFilterTreeConditionNodeData
|
294
296
|
).condition;
|
295
297
|
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
298
|
+
const rightSide = conditionState.rightConditionValue;
|
299
|
+
if (rightSide instanceof PostFilterValueSpecConditionValueState) {
|
300
|
+
if (conditionState.operator.getLabel() === operator.getLabel()) {
|
301
|
+
const doesValueAlreadyExist =
|
302
|
+
rightSide.value instanceof InstanceValue &&
|
303
|
+
(rightSide.value instanceof EnumValueInstanceValue
|
304
|
+
? rightSide.value.values.map((ef) => ef.value.name)
|
305
|
+
: rightSide.value.values
|
306
|
+
).includes(cellData.value);
|
307
|
+
|
308
|
+
if (!doesValueAlreadyExist) {
|
309
|
+
const currentValueSpecificaton = rightSide.value;
|
310
|
+
const newValueSpecification =
|
311
|
+
conditionState.operator.getDefaultFilterConditionValue(
|
312
|
+
conditionState,
|
313
|
+
);
|
314
|
+
updateFilterConditionValue(
|
315
|
+
newValueSpecification as InstanceValue,
|
316
|
+
cellData,
|
309
317
|
);
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
],
|
350
|
-
tdsState.queryBuilderState.observerContext,
|
351
|
-
);
|
318
|
+
conditionState.changeOperator(
|
319
|
+
isFilterBy ? postFilterInOperator : postFilterNotInOperator,
|
320
|
+
);
|
321
|
+
instanceValue_setValues(
|
322
|
+
rightSide.value as InstanceValue,
|
323
|
+
[currentValueSpecificaton, newValueSpecification],
|
324
|
+
tdsState.queryBuilderState.observerContext,
|
325
|
+
);
|
326
|
+
}
|
327
|
+
} else {
|
328
|
+
const doesValueAlreadyExist =
|
329
|
+
rightSide.value instanceof InstanceValue &&
|
330
|
+
rightSide.value.values
|
331
|
+
.filter((v) => v instanceof InstanceValue)
|
332
|
+
.map((v) =>
|
333
|
+
v instanceof EnumValueInstanceValue
|
334
|
+
? v.values.map((ef) => ef.value.name)
|
335
|
+
: (v as InstanceValue).values,
|
336
|
+
)
|
337
|
+
.flat()
|
338
|
+
.includes(cellData.value ?? data?.value);
|
339
|
+
|
340
|
+
if (!doesValueAlreadyExist) {
|
341
|
+
const newValueSpecification = (
|
342
|
+
isFilterBy ? postFilterEqualOperator : postFilterNotEqualOperator
|
343
|
+
).getDefaultFilterConditionValue(conditionState);
|
344
|
+
updateFilterConditionValue(
|
345
|
+
newValueSpecification as InstanceValue,
|
346
|
+
cellData,
|
347
|
+
);
|
348
|
+
instanceValue_setValues(
|
349
|
+
rightSide.value as InstanceValue,
|
350
|
+
[
|
351
|
+
...(rightSide.value as InstanceValue).values,
|
352
|
+
newValueSpecification,
|
353
|
+
],
|
354
|
+
tdsState.queryBuilderState.observerContext,
|
355
|
+
);
|
356
|
+
}
|
352
357
|
}
|
353
358
|
}
|
354
359
|
};
|
@@ -14,7 +14,14 @@
|
|
14
14
|
* limitations under the License.
|
15
15
|
*/
|
16
16
|
|
17
|
-
import {
|
17
|
+
import {
|
18
|
+
type RenderResult,
|
19
|
+
render,
|
20
|
+
waitFor,
|
21
|
+
fireEvent,
|
22
|
+
findByText,
|
23
|
+
getByText,
|
24
|
+
} from '@testing-library/react';
|
18
25
|
import { LogService } from '@finos/legend-shared';
|
19
26
|
import { createSpy } from '@finos/legend-shared/test';
|
20
27
|
import {
|
@@ -43,6 +50,23 @@ import {
|
|
43
50
|
TEST__getGenericApplicationConfig,
|
44
51
|
} from '../../stores/__test-utils__/QueryBuilderStateTestUtils.js';
|
45
52
|
|
53
|
+
export const dragAndDrop = async (
|
54
|
+
source: HTMLElement,
|
55
|
+
drop: HTMLElement,
|
56
|
+
panel: HTMLElement,
|
57
|
+
draggingHoverText?: string,
|
58
|
+
): Promise<void> => {
|
59
|
+
fireEvent.dragStart(source);
|
60
|
+
fireEvent.dragEnter(drop);
|
61
|
+
fireEvent.dragOver(drop);
|
62
|
+
if (draggingHoverText) {
|
63
|
+
await findByText(panel, draggingHoverText);
|
64
|
+
fireEvent.drop(getByText(panel, draggingHoverText));
|
65
|
+
} else {
|
66
|
+
fireEvent.dragOver(drop);
|
67
|
+
}
|
68
|
+
};
|
69
|
+
|
46
70
|
export const TEST__setUpQueryBuilder = async (
|
47
71
|
entities: Entity[],
|
48
72
|
lambda: RawLambda,
|
@@ -61,7 +61,13 @@ import {
|
|
61
61
|
} from '@finos/legend-shared';
|
62
62
|
import { flowResult } from 'mobx';
|
63
63
|
import { observer } from 'mobx-react-lite';
|
64
|
-
import
|
64
|
+
import React, {
|
65
|
+
forwardRef,
|
66
|
+
useCallback,
|
67
|
+
useMemo,
|
68
|
+
useRef,
|
69
|
+
useState,
|
70
|
+
} from 'react';
|
65
71
|
import { useDrop, useDrag, useDragLayer } from 'react-dnd';
|
66
72
|
import { QueryBuilderAggregateColumnState } from '../../stores/fetch-structure/tds/aggregation/QueryBuilderAggregationState.js';
|
67
73
|
import type { QueryBuilderPostFilterOperator } from '../../stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterOperator.js';
|
@@ -74,6 +80,8 @@ import {
|
|
74
80
|
QueryBuilderPostFilterTreeGroupNodeData,
|
75
81
|
QueryBuilderPostFilterTreeBlankConditionNodeData,
|
76
82
|
QUERY_BUILDER_POST_FILTER_DND_TYPE,
|
83
|
+
PostFilterValueSpecConditionValueState,
|
84
|
+
PostFilterTDSColumnValueConditionValueState,
|
77
85
|
} from '../../stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js';
|
78
86
|
import {
|
79
87
|
type QueryBuilderProjectionColumnState,
|
@@ -203,14 +211,14 @@ const QueryBuilderPostFilterGroupConditionEditor = observer(
|
|
203
211
|
|
204
212
|
export const QueryBuilderColumnBadge = observer(
|
205
213
|
(props: {
|
206
|
-
|
214
|
+
colState: QueryBuilderTDSColumnState;
|
207
215
|
onColumnChange: (
|
208
216
|
columnState: QueryBuilderProjectionColumnState,
|
209
217
|
) => Promise<void>;
|
210
218
|
}) => {
|
211
|
-
const {
|
219
|
+
const { colState, onColumnChange } = props;
|
212
220
|
const applicationStore = useApplicationStore();
|
213
|
-
const type =
|
221
|
+
const type = colState.getColumnType();
|
214
222
|
const handleDrop = useCallback(
|
215
223
|
(item: QueryBuilderProjectionColumnDragSource): Promise<void> =>
|
216
224
|
onColumnChange(item.columnState),
|
@@ -261,12 +269,12 @@ export const QueryBuilderColumnBadge = observer(
|
|
261
269
|
)}
|
262
270
|
<div
|
263
271
|
className="query-builder-column-badge__property"
|
264
|
-
title={`${
|
272
|
+
title={`${colState.columnName}`}
|
265
273
|
>
|
266
|
-
{
|
274
|
+
{colState.columnName}
|
267
275
|
</div>
|
268
276
|
<QueryBuilderColumnInfoTooltip
|
269
|
-
columnState={
|
277
|
+
columnState={colState}
|
270
278
|
placement="bottom-end"
|
271
279
|
>
|
272
280
|
<div className="query-builder-column-badge__property__info">
|
@@ -291,13 +299,15 @@ const QueryBuilderPostFilterConditionEditor = observer(
|
|
291
299
|
const applicationStore = useApplicationStore();
|
292
300
|
const changeOperator = (val: QueryBuilderPostFilterOperator) => (): void =>
|
293
301
|
node.condition.changeOperator(val);
|
302
|
+
const rightConditionValue = node.condition.rightConditionValue;
|
294
303
|
const changeColumn = async (
|
295
304
|
columnState: QueryBuilderProjectionColumnState,
|
296
305
|
): Promise<void> => {
|
297
306
|
const currentColState =
|
298
|
-
node.condition.
|
299
|
-
|
300
|
-
|
307
|
+
node.condition.leftConditionValue instanceof
|
308
|
+
QueryBuilderAggregateColumnState
|
309
|
+
? node.condition.leftConditionValue.projectionColumnState
|
310
|
+
: node.condition.leftConditionValue;
|
301
311
|
if (currentColState !== columnState) {
|
302
312
|
await flowResult(node.condition.changeColumn(columnState));
|
303
313
|
}
|
@@ -306,12 +316,13 @@ const QueryBuilderPostFilterConditionEditor = observer(
|
|
306
316
|
const handleDrop = useCallback(
|
307
317
|
(item: QueryBuilderVariableDragSource): void => {
|
308
318
|
const parameterType = item.variable.genericType?.value.rawType;
|
309
|
-
const conditionValueType =
|
319
|
+
const conditionValueType =
|
320
|
+
node.condition.leftConditionValue.getColumnType();
|
310
321
|
if (
|
311
322
|
conditionValueType &&
|
312
323
|
isTypeCompatibleForAssignment(parameterType, conditionValueType)
|
313
324
|
) {
|
314
|
-
node.condition.
|
325
|
+
node.condition.buildFromValueSpec(item.variable);
|
315
326
|
} else {
|
316
327
|
applicationStore.notificationService.notifyWarning(
|
317
328
|
`Incompatible parameter type ${parameterType?.name}. ${parameterType?.name} is not compatible with type ${conditionValueType?.name}.`,
|
@@ -339,7 +350,7 @@ const QueryBuilderPostFilterConditionEditor = observer(
|
|
339
350
|
[handleDrop],
|
340
351
|
);
|
341
352
|
const resetNode = (): void => {
|
342
|
-
node.condition.
|
353
|
+
node.condition.buildFromValueSpec(
|
343
354
|
node.condition.operator.getDefaultFilterConditionValue(node.condition),
|
344
355
|
);
|
345
356
|
};
|
@@ -355,7 +366,7 @@ const QueryBuilderPostFilterConditionEditor = observer(
|
|
355
366
|
node.condition.typeaheadSearchState.complete();
|
356
367
|
};
|
357
368
|
const changeValueSpecification = (val: ValueSpecification): void => {
|
358
|
-
node.condition.
|
369
|
+
node.condition.buildFromValueSpec(val);
|
359
370
|
};
|
360
371
|
const selectorConfig = {
|
361
372
|
values: node.condition.typeaheadSearchResults,
|
@@ -371,6 +382,70 @@ const QueryBuilderPostFilterConditionEditor = observer(
|
|
371
382
|
monitor.getItemType() === QUERY_BUILDER_WINDOW_COLUMN_DND_TYPE),
|
372
383
|
}));
|
373
384
|
|
385
|
+
const renderRightVal = (): React.ReactNode => {
|
386
|
+
if (
|
387
|
+
rightConditionValue instanceof PostFilterValueSpecConditionValueState &&
|
388
|
+
rightConditionValue.value
|
389
|
+
) {
|
390
|
+
return (
|
391
|
+
<div
|
392
|
+
ref={dropConnector}
|
393
|
+
className="query-builder-post-filter-tree__condition-node__value"
|
394
|
+
>
|
395
|
+
<PanelEntryDropZonePlaceholder
|
396
|
+
isDragOver={isFilterValueDragOver}
|
397
|
+
label="Change Filter Value"
|
398
|
+
>
|
399
|
+
<BasicValueSpecificationEditor
|
400
|
+
valueSpecification={rightConditionValue.value}
|
401
|
+
setValueSpecification={changeValueSpecification}
|
402
|
+
graph={graph}
|
403
|
+
obseverContext={queryBuilderState.observerContext}
|
404
|
+
typeCheckOption={{
|
405
|
+
expectedType: guaranteeNonNullable(
|
406
|
+
node.condition.leftConditionValue.getColumnType(),
|
407
|
+
),
|
408
|
+
}}
|
409
|
+
resetValue={resetNode}
|
410
|
+
selectorConfig={selectorConfig}
|
411
|
+
isConstant={queryBuilderState.constantState.isValueSpecConstant(
|
412
|
+
rightConditionValue.value,
|
413
|
+
)}
|
414
|
+
/>
|
415
|
+
</PanelEntryDropZonePlaceholder>
|
416
|
+
</div>
|
417
|
+
);
|
418
|
+
} else if (
|
419
|
+
rightConditionValue instanceof
|
420
|
+
PostFilterTDSColumnValueConditionValueState
|
421
|
+
) {
|
422
|
+
const changeRightCol = async (
|
423
|
+
columnState: QueryBuilderProjectionColumnState,
|
424
|
+
): Promise<void> => {
|
425
|
+
rightConditionValue.changeCol(columnState);
|
426
|
+
};
|
427
|
+
return (
|
428
|
+
<div
|
429
|
+
ref={dropConnector}
|
430
|
+
className="query-builder-post-filter-tree__condition-node__value"
|
431
|
+
>
|
432
|
+
<PanelEntryDropZonePlaceholder
|
433
|
+
isDragOver={isFilterValueDragOver}
|
434
|
+
label="Change Filter Value"
|
435
|
+
>
|
436
|
+
<div className="query-builder-post-filter-tree__condition-node__property">
|
437
|
+
<QueryBuilderColumnBadge
|
438
|
+
colState={rightConditionValue.tdsColumn}
|
439
|
+
onColumnChange={changeRightCol}
|
440
|
+
/>
|
441
|
+
</div>
|
442
|
+
</PanelEntryDropZonePlaceholder>
|
443
|
+
</div>
|
444
|
+
);
|
445
|
+
}
|
446
|
+
return null;
|
447
|
+
};
|
448
|
+
|
374
449
|
return (
|
375
450
|
<div className="query-builder-post-filter-tree__node__label__content dnd__entry__container">
|
376
451
|
<PanelEntryDropZonePlaceholder
|
@@ -381,7 +456,7 @@ const QueryBuilderPostFilterConditionEditor = observer(
|
|
381
456
|
<div className="query-builder-post-filter-tree__condition-node">
|
382
457
|
<div className="query-builder-post-filter-tree__condition-node__property">
|
383
458
|
<QueryBuilderColumnBadge
|
384
|
-
|
459
|
+
colState={node.condition.leftConditionValue}
|
385
460
|
onColumnChange={changeColumn}
|
386
461
|
/>
|
387
462
|
</div>
|
@@ -414,34 +489,7 @@ const QueryBuilderPostFilterConditionEditor = observer(
|
|
414
489
|
<CaretDownIcon />
|
415
490
|
</div>
|
416
491
|
</DropdownMenu>
|
417
|
-
{
|
418
|
-
<div
|
419
|
-
ref={dropConnector}
|
420
|
-
className="query-builder-post-filter-tree__condition-node__value"
|
421
|
-
>
|
422
|
-
<PanelEntryDropZonePlaceholder
|
423
|
-
isDragOver={isFilterValueDragOver}
|
424
|
-
label="Change Filter Value"
|
425
|
-
>
|
426
|
-
<BasicValueSpecificationEditor
|
427
|
-
valueSpecification={node.condition.value}
|
428
|
-
setValueSpecification={changeValueSpecification}
|
429
|
-
graph={graph}
|
430
|
-
obseverContext={queryBuilderState.observerContext}
|
431
|
-
typeCheckOption={{
|
432
|
-
expectedType: guaranteeNonNullable(
|
433
|
-
node.condition.columnState.getColumnType(),
|
434
|
-
),
|
435
|
-
}}
|
436
|
-
resetValue={resetNode}
|
437
|
-
selectorConfig={selectorConfig}
|
438
|
-
isConstant={queryBuilderState.constantState.isValueSpecConstant(
|
439
|
-
node.condition.value,
|
440
|
-
)}
|
441
|
-
/>
|
442
|
-
</PanelEntryDropZonePlaceholder>
|
443
|
-
</div>
|
444
|
-
)}
|
492
|
+
{renderRightVal()}
|
445
493
|
</div>
|
446
494
|
</PanelEntryDropZonePlaceholder>
|
447
495
|
</div>
|
@@ -538,9 +586,8 @@ const QueryBuilderPostFilterTreeNodeContainer = observer(
|
|
538
586
|
postFilterState,
|
539
587
|
columnState,
|
540
588
|
undefined,
|
541
|
-
undefined,
|
542
589
|
);
|
543
|
-
conditionState.
|
590
|
+
conditionState.buildFromValueSpec(
|
544
591
|
conditionState.operator.getDefaultFilterConditionValue(
|
545
592
|
conditionState,
|
546
593
|
),
|
@@ -648,6 +695,9 @@ const QueryBuilderPostFilterTreeNodeContainer = observer(
|
|
648
695
|
>
|
649
696
|
<div
|
650
697
|
ref={ref}
|
698
|
+
data-testid={
|
699
|
+
QUERY_BUILDER_TEST_ID.QUERY_BUILDER_POST_FILTER_TREE_NODE_CONTENT
|
700
|
+
}
|
651
701
|
className={clsx(
|
652
702
|
'tree-view__node__container query-builder-post-filter-tree__node__container',
|
653
703
|
{
|
@@ -679,6 +729,10 @@ const QueryBuilderPostFilterTreeNodeContainer = observer(
|
|
679
729
|
<div
|
680
730
|
className={clsx(
|
681
731
|
'tree-view__node__label query-builder-post-filter-tree__node__label',
|
732
|
+
{
|
733
|
+
'query-builder-post-filter-tree__node__label--expandable':
|
734
|
+
isExpandable,
|
735
|
+
},
|
682
736
|
)}
|
683
737
|
>
|
684
738
|
{node instanceof QueryBuilderPostFilterTreeGroupNodeData && (
|
@@ -894,9 +948,8 @@ const QueryBuilderPostFilterPanelContent = observer(
|
|
894
948
|
postFilterState,
|
895
949
|
aggregateColumnState ?? columnState,
|
896
950
|
undefined,
|
897
|
-
undefined,
|
898
951
|
);
|
899
|
-
postFilterConditionState.
|
952
|
+
postFilterConditionState.buildFromValueSpec(
|
900
953
|
postFilterConditionState.operator.getDefaultFilterConditionValue(
|
901
954
|
postFilterConditionState,
|
902
955
|
),
|
@@ -959,7 +1012,7 @@ const QueryBuilderPostFilterPanelContent = observer(
|
|
959
1012
|
<div className="panel__header__actions">
|
960
1013
|
<DropdownMenu
|
961
1014
|
className="panel__header__action"
|
962
|
-
title="Show Filter Options Menu..."
|
1015
|
+
title="Show Post-Filter Options Menu..."
|
963
1016
|
content={
|
964
1017
|
<MenuContent>
|
965
1018
|
<MenuContentItem onClick={createCondition}>
|
@@ -1091,7 +1144,7 @@ export const QueryBuilderPostFilterPanel = observer(
|
|
1091
1144
|
|
1092
1145
|
return (
|
1093
1146
|
<div
|
1094
|
-
data-testid={QUERY_BUILDER_TEST_ID.
|
1147
|
+
data-testid={QUERY_BUILDER_TEST_ID.QUERY_BUILDER_POST_FILTER_PANEL}
|
1095
1148
|
className="panel"
|
1096
1149
|
>
|
1097
1150
|
{fetchStructureImplementation instanceof QueryBuilderTDSState && (
|
@@ -688,7 +688,6 @@ const QueryBuilderProjectionColumnEditor = observer(
|
|
688
688
|
}),
|
689
689
|
[handleDrop],
|
690
690
|
);
|
691
|
-
|
692
691
|
return (
|
693
692
|
<PanelDnDEntry
|
694
693
|
ref={ref}
|
@@ -732,7 +731,12 @@ const QueryBuilderProjectionColumnEditor = observer(
|
|
732
731
|
onOpen={onContextMenuOpen}
|
733
732
|
onClose={onContextMenuClose}
|
734
733
|
>
|
735
|
-
<div
|
734
|
+
<div
|
735
|
+
data-testid={
|
736
|
+
QUERY_BUILDER_TEST_ID.QUERY_BUILDER_TDS_PROJECTION_COLUMN
|
737
|
+
}
|
738
|
+
className="query-builder__projection__column__container"
|
739
|
+
>
|
736
740
|
<PanelEntryDragHandle
|
737
741
|
isDragging={false}
|
738
742
|
dragSourceConnector={dragHandleRef}
|
@@ -24,6 +24,12 @@ import {
|
|
24
24
|
buildSourceInformationSourceId,
|
25
25
|
ParserError,
|
26
26
|
GRAPH_MANAGER_EVENT,
|
27
|
+
SimpleFunctionExpression,
|
28
|
+
PrimitiveInstanceValue,
|
29
|
+
PrimitiveType,
|
30
|
+
extractElementNameFromPath,
|
31
|
+
SUPPORTED_FUNCTIONS,
|
32
|
+
INTERNAL__UnknownValueSpecification,
|
27
33
|
} from '@finos/legend-graph';
|
28
34
|
import {
|
29
35
|
type Hashable,
|
@@ -70,6 +76,22 @@ export abstract class QueryBuilderConstantExpressionState implements Hashable {
|
|
70
76
|
this.variable.name,
|
71
77
|
]);
|
72
78
|
}
|
79
|
+
|
80
|
+
buildLetExpression(): SimpleFunctionExpression {
|
81
|
+
const leftSide = new PrimitiveInstanceValue(
|
82
|
+
GenericTypeExplicitReference.create(
|
83
|
+
new GenericType(PrimitiveType.STRING),
|
84
|
+
),
|
85
|
+
);
|
86
|
+
leftSide.values = [this.variable.name];
|
87
|
+
const letFunc = new SimpleFunctionExpression(
|
88
|
+
extractElementNameFromPath(SUPPORTED_FUNCTIONS.LET),
|
89
|
+
);
|
90
|
+
letFunc.parametersValues = [leftSide, this.buildLetAssignmentValue()];
|
91
|
+
return letFunc;
|
92
|
+
}
|
93
|
+
|
94
|
+
abstract buildLetAssignmentValue(): ValueSpecification;
|
73
95
|
}
|
74
96
|
|
75
97
|
export class QueryBuilderSimpleConstantExpressionState
|
@@ -141,6 +163,10 @@ export class QueryBuilderSimpleConstantExpressionState
|
|
141
163
|
}
|
142
164
|
}
|
143
165
|
|
166
|
+
override buildLetAssignmentValue(): ValueSpecification {
|
167
|
+
return this.value;
|
168
|
+
}
|
169
|
+
|
144
170
|
override get hashCode(): string {
|
145
171
|
return hashArray([
|
146
172
|
QUERY_BUILDER_STATE_HASH_STRUCTURE.CONSTANT_EXPRESSION_STATE,
|
@@ -272,6 +298,10 @@ export class QueryBuilderCalculatedConstantExpressionState
|
|
272
298
|
setValue(val: PlainObject): void {
|
273
299
|
this.value = val;
|
274
300
|
}
|
301
|
+
|
302
|
+
override buildLetAssignmentValue(): ValueSpecification {
|
303
|
+
return new INTERNAL__UnknownValueSpecification(this.value);
|
304
|
+
}
|
275
305
|
}
|
276
306
|
|
277
307
|
export class QueryBuilderConstantsState implements Hashable {
|
@@ -45,6 +45,8 @@ export enum QUERY_BUILDER_STATE_HASH_STRUCTURE {
|
|
45
45
|
POST_FILTER_TREE_CONDIITION_NODE_DATA = 'POST_FILTER_TREE_CONDITION_NODE_DATA',
|
46
46
|
POST_FILTER_TREE_BLANK_CONDITION_NODE_DATA = 'POST_FILTER_TREE_BLANK_CONDITION_NODE_DATA',
|
47
47
|
POST_FILTER_CONDITION_STATE = 'POST_FILTER_CONDITION_STATE',
|
48
|
+
POST_FILTER_CONDITION_RIGHT_VALUE = 'POST_FILTER_CONDITION_RIGHT_VALUE',
|
49
|
+
POST_FILTER_CONDITION_RIGHT_VALUE_SPEC = 'POST_FILTER_CONDITION_RIGHT_VALUE_SPEC',
|
48
50
|
POST_FILTER_OPERATOR_CONTAIN = 'POST_FILTER_OPERATOR_CONTAIN',
|
49
51
|
POST_FILTER_OPERATOR_NOT_CONTAIN = 'POST_FILTER_OPERATOR_NOT_CONTAIN',
|
50
52
|
POST_FILTER_OPERATOR_END_WITH = 'POST_FILTER_OPERATOR_END_WITH',
|
@@ -14,14 +14,9 @@
|
|
14
14
|
* limitations under the License.
|
15
15
|
*/
|
16
16
|
|
17
|
-
import {
|
18
|
-
UnsupportedOperationError,
|
19
|
-
guaranteeNonNullable,
|
20
|
-
guaranteeType,
|
21
|
-
} from '@finos/legend-shared';
|
17
|
+
import { guaranteeNonNullable, guaranteeType } from '@finos/legend-shared';
|
22
18
|
import {
|
23
19
|
type Class,
|
24
|
-
type ValueSpecification,
|
25
20
|
Multiplicity,
|
26
21
|
getMilestoneTemporalStereotype,
|
27
22
|
extractElementNameFromPath,
|
@@ -33,11 +28,8 @@ import {
|
|
33
28
|
GenericTypeExplicitReference,
|
34
29
|
LambdaFunction,
|
35
30
|
SimpleFunctionExpression,
|
36
|
-
PrimitiveInstanceValue,
|
37
|
-
PrimitiveType,
|
38
31
|
SUPPORTED_FUNCTIONS,
|
39
32
|
RuntimePointer,
|
40
|
-
INTERNAL__UnknownValueSpecification,
|
41
33
|
} from '@finos/legend-graph';
|
42
34
|
import type { QueryBuilderState } from './QueryBuilderState.js';
|
43
35
|
import { buildFilterExpression } from './filter/QueryBuilderFilterValueSpecificationBuilder.js';
|
@@ -46,11 +38,6 @@ import type { QueryBuilderFetchStructureState } from './fetch-structure/QueryBui
|
|
46
38
|
import { QUERY_BUILDER_SUPPORTED_FUNCTIONS } from '../graph/QueryBuilderMetaModelConst.js';
|
47
39
|
import { buildWatermarkExpression } from './watermark/QueryBuilderWatermarkValueSpecificationBuilder.js';
|
48
40
|
import { buildExecutionQueryFromLambdaFunction } from './shared/LambdaParameterState.js';
|
49
|
-
import {
|
50
|
-
QueryBuilderSimpleConstantExpressionState,
|
51
|
-
type QueryBuilderConstantExpressionState,
|
52
|
-
QueryBuilderCalculatedConstantExpressionState,
|
53
|
-
} from './QueryBuilderConstantsState.js';
|
54
41
|
import {
|
55
42
|
QueryBuilderEmbeddedFromExecutionContextState,
|
56
43
|
type QueryBuilderExecutionContextState,
|
@@ -90,40 +77,6 @@ const buildGetAllVersionsFunction = (
|
|
90
77
|
return _func;
|
91
78
|
};
|
92
79
|
|
93
|
-
const buildLetExpression = (
|
94
|
-
constantExpressionState: QueryBuilderConstantExpressionState,
|
95
|
-
): SimpleFunctionExpression => {
|
96
|
-
const varName = constantExpressionState.variable.name;
|
97
|
-
const leftSide = new PrimitiveInstanceValue(
|
98
|
-
GenericTypeExplicitReference.create(new GenericType(PrimitiveType.STRING)),
|
99
|
-
);
|
100
|
-
leftSide.values = [varName];
|
101
|
-
const letFunc = new SimpleFunctionExpression(
|
102
|
-
extractElementNameFromPath(SUPPORTED_FUNCTIONS.LET),
|
103
|
-
);
|
104
|
-
let value: ValueSpecification;
|
105
|
-
if (
|
106
|
-
constantExpressionState instanceof QueryBuilderSimpleConstantExpressionState
|
107
|
-
) {
|
108
|
-
value = constantExpressionState.value;
|
109
|
-
} else if (
|
110
|
-
constantExpressionState instanceof
|
111
|
-
QueryBuilderCalculatedConstantExpressionState
|
112
|
-
) {
|
113
|
-
value = new INTERNAL__UnknownValueSpecification(
|
114
|
-
constantExpressionState.value,
|
115
|
-
);
|
116
|
-
} else {
|
117
|
-
throw new UnsupportedOperationError(
|
118
|
-
`Can't build let() expression: unsupported constant state`,
|
119
|
-
constantExpressionState,
|
120
|
-
);
|
121
|
-
}
|
122
|
-
|
123
|
-
letFunc.parametersValues = [leftSide, value];
|
124
|
-
return letFunc;
|
125
|
-
};
|
126
|
-
|
127
80
|
const buildExecutionContextState = (
|
128
81
|
executionState: QueryBuilderExecutionContextState,
|
129
82
|
lambdaFunction: LambdaFunction,
|
@@ -237,8 +190,9 @@ export const buildLambdaFunction = (
|
|
237
190
|
|
238
191
|
// build variable expressions
|
239
192
|
if (queryBuilderState.constantState.constants.length) {
|
240
|
-
const letExpressions =
|
241
|
-
|
193
|
+
const letExpressions = queryBuilderState.constantState.constants.map((e) =>
|
194
|
+
e.buildLetExpression(),
|
195
|
+
);
|
242
196
|
lambdaFunction.expressionSequence = [
|
243
197
|
...letExpressions,
|
244
198
|
...lambdaFunction.expressionSequence,
|
@@ -48,7 +48,7 @@ export abstract class QueryBuilderPostFilterOperator implements Hashable {
|
|
48
48
|
isCompatibleWithPostFilterColumn(
|
49
49
|
postFilterState: PostFilterConditionState,
|
50
50
|
): boolean {
|
51
|
-
const columnType = postFilterState.
|
51
|
+
const columnType = postFilterState.leftConditionValue.getColumnType();
|
52
52
|
if (columnType) {
|
53
53
|
return this.isCompatibleWithType(columnType);
|
54
54
|
}
|