@finos/legend-query-builder 4.15.2 → 4.15.3
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/data-cube/QueryBuilderDataCube.d.ts.map +1 -1
- package/lib/components/data-cube/QueryBuilderDataCube.js +6 -7
- package/lib/components/data-cube/QueryBuilderDataCube.js.map +1 -1
- package/lib/components/filter/QueryBuilderFilterPanel.js +2 -2
- 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 +4 -3
- package/lib/components/result/tds/QueryBuilderTDSGridResult.js.map +1 -1
- package/lib/components/result/tds/QueryBuilderTDSResultShared.d.ts +2 -2
- package/lib/components/result/tds/QueryBuilderTDSResultShared.d.ts.map +1 -1
- package/lib/components/result/tds/QueryBuilderTDSResultShared.js +157 -19
- package/lib/components/result/tds/QueryBuilderTDSResultShared.js.map +1 -1
- package/lib/index.css +1 -17
- package/lib/index.css.map +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/filter/QueryBuilderFilterOperator.d.ts +1 -1
- package/lib/stores/filter/QueryBuilderFilterOperator.d.ts.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 -3
- package/lib/stores/filter/QueryBuilderFilterState.js.map +1 -1
- package/lib/stores/filter/QueryBuilderFilterStateBuilder.js +1 -1
- package/lib/stores/filter/QueryBuilderFilterStateBuilder.js.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_Contain.d.ts +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_Contain.d.ts.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_Contain.js +3 -3
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_Contain.js.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_EndWith.d.ts +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_EndWith.d.ts.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_EndWith.js +3 -3
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_EndWith.js.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_Equal.d.ts +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_Equal.d.ts.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_Equal.js +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_Equal.js.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThan.d.ts +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThan.d.ts.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThan.js +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThan.js.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThanEqual.d.ts +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThanEqual.d.ts.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThanEqual.js +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThanEqual.js.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_In.d.ts +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_In.d.ts.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_In.js +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_In.js.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_IsEmpty.d.ts +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_IsEmpty.d.ts.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_IsEmpty.js +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_IsEmpty.js.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThan.d.ts +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThan.d.ts.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThan.js +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThan.js.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThanEqual.d.ts +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThanEqual.d.ts.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThanEqual.js +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThanEqual.js.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_StartWith.d.ts +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_StartWith.d.ts.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_StartWith.js +3 -3
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_StartWith.js.map +1 -1
- package/package.json +5 -5
- package/src/components/data-cube/QueryBuilderDataCube.tsx +15 -25
- package/src/components/filter/QueryBuilderFilterPanel.tsx +2 -2
- package/src/components/result/tds/QueryBuilderTDSGridResult.tsx +7 -3
- package/src/components/result/tds/QueryBuilderTDSResultShared.tsx +334 -26
- package/src/stores/filter/QueryBuilderFilterOperator.ts +1 -1
- package/src/stores/filter/QueryBuilderFilterState.ts +10 -5
- package/src/stores/filter/QueryBuilderFilterStateBuilder.ts +1 -1
- package/src/stores/filter/operators/QueryBuilderFilterOperator_Contain.ts +3 -5
- package/src/stores/filter/operators/QueryBuilderFilterOperator_EndWith.ts +3 -5
- package/src/stores/filter/operators/QueryBuilderFilterOperator_Equal.ts +2 -2
- package/src/stores/filter/operators/QueryBuilderFilterOperator_GreaterThan.ts +2 -4
- package/src/stores/filter/operators/QueryBuilderFilterOperator_GreaterThanEqual.ts +2 -4
- package/src/stores/filter/operators/QueryBuilderFilterOperator_In.ts +2 -2
- package/src/stores/filter/operators/QueryBuilderFilterOperator_IsEmpty.ts +2 -2
- package/src/stores/filter/operators/QueryBuilderFilterOperator_LessThan.ts +2 -4
- package/src/stores/filter/operators/QueryBuilderFilterOperator_LessThanEqual.ts +2 -4
- package/src/stores/filter/operators/QueryBuilderFilterOperator_StartWith.ts +3 -5
|
@@ -20,6 +20,7 @@ import { PRIMITIVE_TYPE, type TDSExecutionResult } from '@finos/legend-graph';
|
|
|
20
20
|
import { useState, useCallback, useEffect } from 'react';
|
|
21
21
|
import {
|
|
22
22
|
DataGrid,
|
|
23
|
+
type DataGridCellSelectionChangedEvent,
|
|
23
24
|
type DataGridApi,
|
|
24
25
|
type DataGridCellRange,
|
|
25
26
|
type DataGridColumnDefinition,
|
|
@@ -347,7 +348,7 @@ export const QueryBuilderTDSGridResult = observer(
|
|
|
347
348
|
resultState.mousedOverCell,
|
|
348
349
|
true,
|
|
349
350
|
fetchStructureImplementation,
|
|
350
|
-
);
|
|
351
|
+
).catch(queryBuilderState.applicationStore.alertUnhandledError);
|
|
351
352
|
},
|
|
352
353
|
},
|
|
353
354
|
{
|
|
@@ -358,7 +359,7 @@ export const QueryBuilderTDSGridResult = observer(
|
|
|
358
359
|
resultState.mousedOverCell,
|
|
359
360
|
false,
|
|
360
361
|
fetchStructureImplementation,
|
|
361
|
-
);
|
|
362
|
+
).catch(queryBuilderState.applicationStore.alertUnhandledError);
|
|
362
363
|
},
|
|
363
364
|
},
|
|
364
365
|
'copy',
|
|
@@ -377,6 +378,7 @@ export const QueryBuilderTDSGridResult = observer(
|
|
|
377
378
|
applicationStore,
|
|
378
379
|
resultState.mousedOverCell,
|
|
379
380
|
resultState.queryBuilderState.fetchStructureState.implementation,
|
|
381
|
+
queryBuilderState.applicationStore.alertUnhandledError,
|
|
380
382
|
],
|
|
381
383
|
);
|
|
382
384
|
|
|
@@ -554,7 +556,9 @@ export const QueryBuilderTDSGridResult = observer(
|
|
|
554
556
|
onRowDataUpdated={(params) => {
|
|
555
557
|
params.api.refreshCells({ force: true });
|
|
556
558
|
}}
|
|
557
|
-
|
|
559
|
+
onCellSelectionChanged={(
|
|
560
|
+
event: DataGridCellSelectionChangedEvent<QueryBuilderTDSRowDataType>,
|
|
561
|
+
) => {
|
|
558
562
|
const selectedCells = getSelectedCells(event.api);
|
|
559
563
|
resultState.setSelectedCells([]);
|
|
560
564
|
selectedCells.forEach((cell) =>
|
|
@@ -22,12 +22,13 @@ import {
|
|
|
22
22
|
import { observer } from 'mobx-react-lite';
|
|
23
23
|
import { flowResult } from 'mobx';
|
|
24
24
|
import {
|
|
25
|
-
type
|
|
25
|
+
type AbstractPropertyExpression,
|
|
26
26
|
type Enumeration,
|
|
27
|
-
InstanceValue,
|
|
28
|
-
EnumValueInstanceValue,
|
|
29
|
-
EnumValueExplicitReference,
|
|
30
27
|
type ExecutionResult,
|
|
28
|
+
type TDSExecutionResult,
|
|
29
|
+
EnumValueExplicitReference,
|
|
30
|
+
EnumValueInstanceValue,
|
|
31
|
+
InstanceValue,
|
|
31
32
|
RelationalExecutionActivities,
|
|
32
33
|
} from '@finos/legend-graph';
|
|
33
34
|
import { format as formatSQL } from 'sql-formatter';
|
|
@@ -47,6 +48,7 @@ import { forwardRef } from 'react';
|
|
|
47
48
|
import {
|
|
48
49
|
QueryBuilderDerivationProjectionColumnState,
|
|
49
50
|
QueryBuilderProjectionColumnState,
|
|
51
|
+
QueryBuilderSimpleProjectionColumnState,
|
|
50
52
|
} from '../../../stores/fetch-structure/tds/projection/QueryBuilderProjectionColumnState.js';
|
|
51
53
|
import {
|
|
52
54
|
type QueryBuilderPostFilterTreeNodeData,
|
|
@@ -81,6 +83,30 @@ import {
|
|
|
81
83
|
} from '../../../stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_IsEmpty.js';
|
|
82
84
|
import { getTDSColumnState } from '../../../stores/fetch-structure/tds/QueryBuilderTDSHelper.js';
|
|
83
85
|
import type { QueryBuilderTDSColumnState } from '../../../stores/fetch-structure/tds/QueryBuilderTDSColumnState.js';
|
|
86
|
+
import {
|
|
87
|
+
type QueryBuilderFilterState,
|
|
88
|
+
type QueryBuilderFilterTreeNodeData,
|
|
89
|
+
FilterConditionState,
|
|
90
|
+
FilterValueSpecConditionValueState,
|
|
91
|
+
isCollectionProperty,
|
|
92
|
+
QueryBuilderFilterTreeConditionNodeData,
|
|
93
|
+
} from '../../../stores/filter/QueryBuilderFilterState.js';
|
|
94
|
+
import { QueryBuilderAggregateColumnState } from '../../../stores/fetch-structure/tds/aggregation/QueryBuilderAggregationState.js';
|
|
95
|
+
import type { QueryBuilderFilterOperator } from '../../../stores/filter/QueryBuilderFilterOperator.js';
|
|
96
|
+
import {
|
|
97
|
+
QueryBuilderFilterOperator_Equal,
|
|
98
|
+
QueryBuilderFilterOperator_NotEqual,
|
|
99
|
+
} from '../../../stores/filter/operators/QueryBuilderFilterOperator_Equal.js';
|
|
100
|
+
import {
|
|
101
|
+
QueryBuilderFilterOperator_In,
|
|
102
|
+
QueryBuilderFilterOperator_NotIn,
|
|
103
|
+
} from '../../../stores/filter/operators/QueryBuilderFilterOperator_In.js';
|
|
104
|
+
import {
|
|
105
|
+
QueryBuilderFilterOperator_IsEmpty,
|
|
106
|
+
QueryBuilderFilterOperator_IsNotEmpty,
|
|
107
|
+
} from '../../../stores/filter/operators/QueryBuilderFilterOperator_IsEmpty.js';
|
|
108
|
+
import type { QueryBuilderState } from '../../../stores/QueryBuilderState.js';
|
|
109
|
+
import type { QueryBuilderPropertyExpressionState } from '../../../stores/QueryBuilderPropertyEditorState.js';
|
|
84
110
|
|
|
85
111
|
export const tryToFormatSql = (sql: string): string => {
|
|
86
112
|
try {
|
|
@@ -139,6 +165,13 @@ export type IQueryRendererParamsWithGridType = DataGridCellRendererParams & {
|
|
|
139
165
|
tdsExecutionResult: TDSExecutionResult;
|
|
140
166
|
};
|
|
141
167
|
|
|
168
|
+
const filterEqualOperator = new QueryBuilderFilterOperator_Equal();
|
|
169
|
+
const filterNotEqualOperator = new QueryBuilderFilterOperator_NotEqual();
|
|
170
|
+
const filterInOperator = new QueryBuilderFilterOperator_In();
|
|
171
|
+
const filterNotInOperator = new QueryBuilderFilterOperator_NotIn();
|
|
172
|
+
const filterEmptyOperator = new QueryBuilderFilterOperator_IsEmpty();
|
|
173
|
+
const filterNotEmptyOperator = new QueryBuilderFilterOperator_IsNotEmpty();
|
|
174
|
+
|
|
142
175
|
const postFilterEqualOperator = new QueryBuilderPostFilterOperator_Equal();
|
|
143
176
|
const postFilterInOperator = new QueryBuilderPostFilterOperator_In();
|
|
144
177
|
const postFilterEmptyOperator = new QueryBuilderPostFilterOperator_IsEmpty();
|
|
@@ -148,6 +181,22 @@ const postFilterNotEqualOperator =
|
|
|
148
181
|
new QueryBuilderPostFilterOperator_NotEqual();
|
|
149
182
|
const postFilterNotInOperator = new QueryBuilderPostFilterOperator_NotIn();
|
|
150
183
|
|
|
184
|
+
const getExistingFilterNode = (
|
|
185
|
+
operators: QueryBuilderFilterOperator[],
|
|
186
|
+
propertyExpressionState: QueryBuilderPropertyExpressionState | undefined,
|
|
187
|
+
filterState: QueryBuilderFilterState,
|
|
188
|
+
): QueryBuilderFilterTreeNodeData | undefined =>
|
|
189
|
+
Array.from(filterState.nodes.values())
|
|
190
|
+
.filter(filterByType(QueryBuilderFilterTreeConditionNodeData))
|
|
191
|
+
.filter(
|
|
192
|
+
(node) =>
|
|
193
|
+
node.condition.propertyExpressionState.path ===
|
|
194
|
+
propertyExpressionState?.path &&
|
|
195
|
+
operators
|
|
196
|
+
.map((op) => op.getLabel())
|
|
197
|
+
.includes(node.condition.operator.getLabel()),
|
|
198
|
+
)[0];
|
|
199
|
+
|
|
151
200
|
const getExistingPostFilterNode = (
|
|
152
201
|
operators: QueryBuilderPostFilterOperator[],
|
|
153
202
|
projectionColumnName: string | undefined,
|
|
@@ -173,7 +222,7 @@ const getExistingPostFilterNode = (
|
|
|
173
222
|
const updateFilterConditionValue = (
|
|
174
223
|
conditionValue: InstanceValue,
|
|
175
224
|
_cellData: QueryBuilderTDSResultCellData,
|
|
176
|
-
|
|
225
|
+
queryBuilderState: QueryBuilderState,
|
|
177
226
|
): void => {
|
|
178
227
|
if (_cellData.value) {
|
|
179
228
|
instanceValue_setValue(
|
|
@@ -188,11 +237,58 @@ const updateFilterConditionValue = (
|
|
|
188
237
|
)
|
|
189
238
|
: _cellData.value,
|
|
190
239
|
0,
|
|
191
|
-
|
|
240
|
+
queryBuilderState.observerContext,
|
|
192
241
|
);
|
|
193
242
|
}
|
|
194
243
|
};
|
|
195
244
|
|
|
245
|
+
const generateNewFilterConditionNodeData = (
|
|
246
|
+
applicationStore: ApplicationStore<
|
|
247
|
+
LegendApplicationConfig,
|
|
248
|
+
LegendApplicationPluginManager<LegendApplicationPlugin>
|
|
249
|
+
>,
|
|
250
|
+
operator: QueryBuilderFilterOperator,
|
|
251
|
+
_cellData: QueryBuilderTDSResultCellData,
|
|
252
|
+
filterState: QueryBuilderFilterState,
|
|
253
|
+
propertyExpression: AbstractPropertyExpression | undefined,
|
|
254
|
+
): void => {
|
|
255
|
+
let filterConditionState: FilterConditionState;
|
|
256
|
+
try {
|
|
257
|
+
if (propertyExpression) {
|
|
258
|
+
filterConditionState = new FilterConditionState(
|
|
259
|
+
filterState,
|
|
260
|
+
propertyExpression,
|
|
261
|
+
operator,
|
|
262
|
+
);
|
|
263
|
+
|
|
264
|
+
const defaultFilterConditionValue =
|
|
265
|
+
filterConditionState.operator.getDefaultFilterConditionValue(
|
|
266
|
+
filterConditionState,
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
filterConditionState.buildRightConditionValueFromValueSpec(
|
|
270
|
+
defaultFilterConditionValue,
|
|
271
|
+
);
|
|
272
|
+
updateFilterConditionValue(
|
|
273
|
+
defaultFilterConditionValue as InstanceValue,
|
|
274
|
+
_cellData,
|
|
275
|
+
filterState.queryBuilderState,
|
|
276
|
+
);
|
|
277
|
+
filterState.addNodeFromNode(
|
|
278
|
+
new QueryBuilderFilterTreeConditionNodeData(
|
|
279
|
+
undefined,
|
|
280
|
+
filterConditionState,
|
|
281
|
+
),
|
|
282
|
+
undefined,
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
} catch (error) {
|
|
286
|
+
assertErrorThrown(error);
|
|
287
|
+
applicationStore.notificationService.notifyWarning(error.message);
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
|
|
196
292
|
const generateNewPostFilterConditionNodeData = async (
|
|
197
293
|
applicationStore: ApplicationStore<
|
|
198
294
|
LegendApplicationConfig,
|
|
@@ -235,7 +331,7 @@ const generateNewPostFilterConditionNodeData = async (
|
|
|
235
331
|
updateFilterConditionValue(
|
|
236
332
|
defaultFilterConditionValue as InstanceValue,
|
|
237
333
|
_cellData,
|
|
238
|
-
tdsState,
|
|
334
|
+
tdsState.queryBuilderState,
|
|
239
335
|
);
|
|
240
336
|
tdsState.postFilterState.addNodeFromNode(
|
|
241
337
|
new QueryBuilderPostFilterTreeConditionNodeData(
|
|
@@ -252,6 +348,91 @@ const generateNewPostFilterConditionNodeData = async (
|
|
|
252
348
|
}
|
|
253
349
|
};
|
|
254
350
|
|
|
351
|
+
const updateExistingFilterConditionNodeData = (
|
|
352
|
+
existingPreFilterNode: QueryBuilderFilterTreeNodeData,
|
|
353
|
+
isFilterBy: boolean,
|
|
354
|
+
_cellData: QueryBuilderTDSResultCellData,
|
|
355
|
+
operator: QueryBuilderFilterOperator,
|
|
356
|
+
data: QueryBuilderTDSResultCellData | null,
|
|
357
|
+
queryBuilderState: QueryBuilderState,
|
|
358
|
+
): void => {
|
|
359
|
+
if (operator === filterEmptyOperator || operator === filterNotEmptyOperator) {
|
|
360
|
+
const conditionState = (
|
|
361
|
+
existingPreFilterNode as QueryBuilderFilterTreeConditionNodeData
|
|
362
|
+
).condition;
|
|
363
|
+
if (conditionState.operator.getLabel() !== operator.getLabel()) {
|
|
364
|
+
conditionState.changeOperator(
|
|
365
|
+
isFilterBy ? filterEmptyOperator : filterNotEmptyOperator,
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
const conditionState = (
|
|
371
|
+
existingPreFilterNode as QueryBuilderFilterTreeConditionNodeData
|
|
372
|
+
).condition;
|
|
373
|
+
|
|
374
|
+
const rightSide = conditionState.rightConditionValue;
|
|
375
|
+
if (rightSide instanceof FilterValueSpecConditionValueState) {
|
|
376
|
+
if (conditionState.operator.getLabel() === operator.getLabel()) {
|
|
377
|
+
const doesValueAlreadyExist =
|
|
378
|
+
rightSide.value instanceof InstanceValue &&
|
|
379
|
+
(rightSide.value instanceof EnumValueInstanceValue
|
|
380
|
+
? rightSide.value.values.map((ef) => ef.value.name)
|
|
381
|
+
: rightSide.value.values
|
|
382
|
+
).includes(_cellData.value);
|
|
383
|
+
|
|
384
|
+
if (!doesValueAlreadyExist) {
|
|
385
|
+
const currentValueSpecificaton = rightSide.value;
|
|
386
|
+
const newValueSpecification =
|
|
387
|
+
conditionState.operator.getDefaultFilterConditionValue(
|
|
388
|
+
conditionState,
|
|
389
|
+
);
|
|
390
|
+
updateFilterConditionValue(
|
|
391
|
+
newValueSpecification as InstanceValue,
|
|
392
|
+
_cellData,
|
|
393
|
+
queryBuilderState,
|
|
394
|
+
);
|
|
395
|
+
conditionState.changeOperator(
|
|
396
|
+
isFilterBy ? filterInOperator : filterNotInOperator,
|
|
397
|
+
);
|
|
398
|
+
instanceValue_setValues(
|
|
399
|
+
rightSide.value as InstanceValue,
|
|
400
|
+
[currentValueSpecificaton, newValueSpecification],
|
|
401
|
+
queryBuilderState.observerContext,
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
} else {
|
|
405
|
+
const doesValueAlreadyExist =
|
|
406
|
+
rightSide.value instanceof InstanceValue &&
|
|
407
|
+
rightSide.value.values
|
|
408
|
+
.filter((v) => v instanceof InstanceValue)
|
|
409
|
+
.map((v) =>
|
|
410
|
+
v instanceof EnumValueInstanceValue
|
|
411
|
+
? v.values.map((ef) => ef.value.name)
|
|
412
|
+
: v.values,
|
|
413
|
+
)
|
|
414
|
+
.flat()
|
|
415
|
+
.includes(_cellData.value ?? data?.value);
|
|
416
|
+
|
|
417
|
+
if (!doesValueAlreadyExist) {
|
|
418
|
+
const newValueSpecification = (
|
|
419
|
+
isFilterBy ? filterEqualOperator : filterNotEqualOperator
|
|
420
|
+
).getDefaultFilterConditionValue(conditionState);
|
|
421
|
+
updateFilterConditionValue(
|
|
422
|
+
newValueSpecification as InstanceValue,
|
|
423
|
+
_cellData,
|
|
424
|
+
queryBuilderState,
|
|
425
|
+
);
|
|
426
|
+
instanceValue_setValues(
|
|
427
|
+
rightSide.value as InstanceValue,
|
|
428
|
+
[...(rightSide.value as InstanceValue).values, newValueSpecification],
|
|
429
|
+
queryBuilderState.observerContext,
|
|
430
|
+
);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
|
|
255
436
|
const updateExistingPostFilterConditionNodeData = (
|
|
256
437
|
existingPostFilterNode: QueryBuilderPostFilterTreeNodeData,
|
|
257
438
|
isFilterBy: boolean,
|
|
@@ -297,7 +478,7 @@ const updateExistingPostFilterConditionNodeData = (
|
|
|
297
478
|
updateFilterConditionValue(
|
|
298
479
|
newValueSpecification as InstanceValue,
|
|
299
480
|
_cellData,
|
|
300
|
-
tdsState,
|
|
481
|
+
tdsState.queryBuilderState,
|
|
301
482
|
);
|
|
302
483
|
conditionState.changeOperator(
|
|
303
484
|
isFilterBy ? postFilterInOperator : postFilterNotInOperator,
|
|
@@ -328,7 +509,7 @@ const updateExistingPostFilterConditionNodeData = (
|
|
|
328
509
|
updateFilterConditionValue(
|
|
329
510
|
newValueSpecification as InstanceValue,
|
|
330
511
|
_cellData,
|
|
331
|
-
tdsState,
|
|
512
|
+
tdsState.queryBuilderState,
|
|
332
513
|
);
|
|
333
514
|
instanceValue_setValues(
|
|
334
515
|
rightSide.value as InstanceValue,
|
|
@@ -343,6 +524,25 @@ const updateExistingPostFilterConditionNodeData = (
|
|
|
343
524
|
const getFilterOperator = (
|
|
344
525
|
isFilterBy: boolean,
|
|
345
526
|
_cellData: QueryBuilderTDSResultCellData,
|
|
527
|
+
): QueryBuilderFilterOperator => {
|
|
528
|
+
if (isFilterBy) {
|
|
529
|
+
if (_cellData.value === null) {
|
|
530
|
+
return filterEmptyOperator;
|
|
531
|
+
} else {
|
|
532
|
+
return filterEqualOperator;
|
|
533
|
+
}
|
|
534
|
+
} else {
|
|
535
|
+
if (_cellData.value === null) {
|
|
536
|
+
return filterNotEmptyOperator;
|
|
537
|
+
} else {
|
|
538
|
+
return filterNotEqualOperator;
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
};
|
|
542
|
+
|
|
543
|
+
const getPostFilterOperator = (
|
|
544
|
+
isFilterBy: boolean,
|
|
545
|
+
_cellData: QueryBuilderTDSResultCellData,
|
|
346
546
|
): QueryBuilderPostFilterOperator => {
|
|
347
547
|
if (isFilterBy) {
|
|
348
548
|
if (_cellData.value === null) {
|
|
@@ -359,7 +559,7 @@ const getFilterOperator = (
|
|
|
359
559
|
}
|
|
360
560
|
};
|
|
361
561
|
|
|
362
|
-
const
|
|
562
|
+
const preFilterByOrOutValue = (
|
|
363
563
|
applicationStore: ApplicationStore<
|
|
364
564
|
LegendApplicationConfig,
|
|
365
565
|
LegendApplicationPluginManager<LegendApplicationPlugin>
|
|
@@ -367,13 +567,58 @@ const filterByOrOutValue = (
|
|
|
367
567
|
isFilterBy: boolean,
|
|
368
568
|
_cellData: QueryBuilderTDSResultCellData,
|
|
369
569
|
data: QueryBuilderTDSResultCellData | null,
|
|
370
|
-
|
|
570
|
+
propertyExpressionState: QueryBuilderPropertyExpressionState,
|
|
571
|
+
queryBuilderState: QueryBuilderState,
|
|
371
572
|
): void => {
|
|
372
|
-
|
|
573
|
+
queryBuilderState.filterState.setShowPanel(true);
|
|
373
574
|
const operator = getFilterOperator(isFilterBy, _cellData);
|
|
374
|
-
const
|
|
375
|
-
|
|
376
|
-
|
|
575
|
+
const existingPreFilterNode = getExistingFilterNode(
|
|
576
|
+
_cellData.value === null
|
|
577
|
+
? [filterEmptyOperator, filterNotEmptyOperator]
|
|
578
|
+
: isFilterBy
|
|
579
|
+
? [filterEqualOperator, filterInOperator]
|
|
580
|
+
: [filterNotEqualOperator, filterNotInOperator],
|
|
581
|
+
propertyExpressionState,
|
|
582
|
+
queryBuilderState.filterState,
|
|
583
|
+
);
|
|
584
|
+
if (existingPreFilterNode) {
|
|
585
|
+
updateExistingFilterConditionNodeData(
|
|
586
|
+
existingPreFilterNode,
|
|
587
|
+
isFilterBy,
|
|
588
|
+
_cellData,
|
|
589
|
+
operator,
|
|
590
|
+
data,
|
|
591
|
+
queryBuilderState,
|
|
592
|
+
);
|
|
593
|
+
} else {
|
|
594
|
+
try {
|
|
595
|
+
generateNewFilterConditionNodeData(
|
|
596
|
+
applicationStore,
|
|
597
|
+
operator,
|
|
598
|
+
_cellData,
|
|
599
|
+
queryBuilderState.filterState,
|
|
600
|
+
propertyExpressionState.propertyExpression,
|
|
601
|
+
);
|
|
602
|
+
} catch (error) {
|
|
603
|
+
assertErrorThrown(error);
|
|
604
|
+
applicationStore.alertUnhandledError(error);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
};
|
|
608
|
+
|
|
609
|
+
const postFilterByOrOutValue = async (
|
|
610
|
+
applicationStore: ApplicationStore<
|
|
611
|
+
LegendApplicationConfig,
|
|
612
|
+
LegendApplicationPluginManager<LegendApplicationPlugin>
|
|
613
|
+
>,
|
|
614
|
+
isFilterBy: boolean,
|
|
615
|
+
_cellData: QueryBuilderTDSResultCellData,
|
|
616
|
+
data: QueryBuilderTDSResultCellData | null,
|
|
617
|
+
tdsColState: QueryBuilderTDSColumnState,
|
|
618
|
+
tdsState: QueryBuilderTDSState,
|
|
619
|
+
): Promise<void> => {
|
|
620
|
+
tdsState.setShowPostFilterPanel(true);
|
|
621
|
+
const operator = getPostFilterOperator(isFilterBy, _cellData);
|
|
377
622
|
const existingPostFilterNode = getExistingPostFilterNode(
|
|
378
623
|
_cellData.value === null
|
|
379
624
|
? [postFilterEmptyOperator, postFilterNotEmptyOperator]
|
|
@@ -394,17 +639,69 @@ const filterByOrOutValue = (
|
|
|
394
639
|
tdsState,
|
|
395
640
|
);
|
|
396
641
|
} else {
|
|
397
|
-
|
|
642
|
+
try {
|
|
643
|
+
await generateNewPostFilterConditionNodeData(
|
|
644
|
+
applicationStore,
|
|
645
|
+
operator,
|
|
646
|
+
_cellData,
|
|
647
|
+
tdsState,
|
|
648
|
+
tdsColState,
|
|
649
|
+
);
|
|
650
|
+
} catch (error) {
|
|
651
|
+
assertErrorThrown(error);
|
|
652
|
+
applicationStore.alertUnhandledError(error);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
};
|
|
656
|
+
|
|
657
|
+
const filterByOrOutValue = async (
|
|
658
|
+
applicationStore: ApplicationStore<
|
|
659
|
+
LegendApplicationConfig,
|
|
660
|
+
LegendApplicationPluginManager<LegendApplicationPlugin>
|
|
661
|
+
>,
|
|
662
|
+
isFilterBy: boolean,
|
|
663
|
+
_cellData: QueryBuilderTDSResultCellData,
|
|
664
|
+
data: QueryBuilderTDSResultCellData | null,
|
|
665
|
+
tdsState: QueryBuilderTDSState,
|
|
666
|
+
): Promise<void> => {
|
|
667
|
+
const tdsColState = data?.columnName
|
|
668
|
+
? getTDSColumnState(tdsState, _cellData.columnName)
|
|
669
|
+
: _cellData.columnName
|
|
670
|
+
? getTDSColumnState(tdsState, _cellData.columnName)
|
|
671
|
+
: undefined;
|
|
672
|
+
if (
|
|
673
|
+
tdsColState instanceof QueryBuilderDerivationProjectionColumnState ||
|
|
674
|
+
tdsColState instanceof QueryBuilderAggregateColumnState ||
|
|
675
|
+
(tdsColState instanceof QueryBuilderSimpleProjectionColumnState &&
|
|
676
|
+
isCollectionProperty(
|
|
677
|
+
tdsColState.propertyExpressionState.propertyExpression,
|
|
678
|
+
))
|
|
679
|
+
) {
|
|
680
|
+
await postFilterByOrOutValue(
|
|
398
681
|
applicationStore,
|
|
399
|
-
|
|
682
|
+
isFilterBy,
|
|
400
683
|
_cellData,
|
|
401
|
-
|
|
684
|
+
data,
|
|
402
685
|
tdsColState,
|
|
403
|
-
|
|
686
|
+
tdsState,
|
|
687
|
+
);
|
|
688
|
+
} else if (tdsColState instanceof QueryBuilderSimpleProjectionColumnState) {
|
|
689
|
+
preFilterByOrOutValue(
|
|
690
|
+
applicationStore,
|
|
691
|
+
isFilterBy,
|
|
692
|
+
_cellData,
|
|
693
|
+
data,
|
|
694
|
+
tdsColState.propertyExpressionState,
|
|
695
|
+
tdsState.queryBuilderState,
|
|
696
|
+
);
|
|
697
|
+
} else {
|
|
698
|
+
applicationStore.notificationService.notifyError(
|
|
699
|
+
`Can't filter column '${data?.columnName ? data.columnName : _cellData.columnName}'`,
|
|
700
|
+
);
|
|
404
701
|
}
|
|
405
702
|
};
|
|
406
703
|
|
|
407
|
-
export const filterByOrOutValues = (
|
|
704
|
+
export const filterByOrOutValues = async (
|
|
408
705
|
applicationStore: ApplicationStore<
|
|
409
706
|
LegendApplicationConfig,
|
|
410
707
|
LegendApplicationPluginManager<LegendApplicationPlugin>
|
|
@@ -412,10 +709,17 @@ export const filterByOrOutValues = (
|
|
|
412
709
|
data: QueryBuilderTDSResultCellData | null,
|
|
413
710
|
isFilterBy: boolean,
|
|
414
711
|
tdsState: QueryBuilderTDSState,
|
|
415
|
-
): void => {
|
|
416
|
-
tdsState.queryBuilderState.resultState
|
|
417
|
-
|
|
418
|
-
|
|
712
|
+
): Promise<void> => {
|
|
713
|
+
for (const _cellData of tdsState.queryBuilderState.resultState
|
|
714
|
+
.selectedCells) {
|
|
715
|
+
await filterByOrOutValue(
|
|
716
|
+
applicationStore,
|
|
717
|
+
isFilterBy,
|
|
718
|
+
_cellData,
|
|
719
|
+
data,
|
|
720
|
+
tdsState,
|
|
721
|
+
);
|
|
722
|
+
}
|
|
419
723
|
};
|
|
420
724
|
|
|
421
725
|
export const QueryBuilderGridResultContextMenu = observer(
|
|
@@ -440,7 +744,9 @@ export const QueryBuilderGridResultContextMenu = observer(
|
|
|
440
744
|
<MenuContentItem
|
|
441
745
|
disabled={!tdsColState}
|
|
442
746
|
onClick={(): void => {
|
|
443
|
-
filterByOrOutValues(applicationStore, data, true, tdsState)
|
|
747
|
+
filterByOrOutValues(applicationStore, data, true, tdsState).catch(
|
|
748
|
+
tdsState.queryBuilderState.applicationStore.alertUnhandledError,
|
|
749
|
+
);
|
|
444
750
|
}}
|
|
445
751
|
>
|
|
446
752
|
Filter By
|
|
@@ -448,7 +754,9 @@ export const QueryBuilderGridResultContextMenu = observer(
|
|
|
448
754
|
<MenuContentItem
|
|
449
755
|
disabled={!tdsColState}
|
|
450
756
|
onClick={(): void => {
|
|
451
|
-
filterByOrOutValues(applicationStore, data, false, tdsState)
|
|
757
|
+
filterByOrOutValues(applicationStore, data, false, tdsState).catch(
|
|
758
|
+
tdsState.queryBuilderState.applicationStore.alertUnhandledError,
|
|
759
|
+
);
|
|
452
760
|
}}
|
|
453
761
|
>
|
|
454
762
|
Filter Out
|
|
@@ -27,7 +27,7 @@ import type {
|
|
|
27
27
|
export abstract class QueryBuilderFilterOperator implements Hashable {
|
|
28
28
|
readonly uuid = uuid();
|
|
29
29
|
|
|
30
|
-
abstract getLabel(
|
|
30
|
+
abstract getLabel(): string;
|
|
31
31
|
|
|
32
32
|
abstract isCompatibleWithFilterConditionProperty(
|
|
33
33
|
filterConditionState: FilterConditionState,
|
|
@@ -246,6 +246,7 @@ export class FilterConditionState implements Hashable {
|
|
|
246
246
|
constructor(
|
|
247
247
|
filterState: QueryBuilderFilterState,
|
|
248
248
|
propertyExpression: AbstractPropertyExpression,
|
|
249
|
+
operator?: QueryBuilderFilterOperator,
|
|
249
250
|
) {
|
|
250
251
|
makeObservable(this, {
|
|
251
252
|
propertyExpressionState: observable,
|
|
@@ -271,11 +272,15 @@ export class FilterConditionState implements Hashable {
|
|
|
271
272
|
);
|
|
272
273
|
|
|
273
274
|
// operator
|
|
274
|
-
|
|
275
|
-
this.
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
275
|
+
if (operator) {
|
|
276
|
+
this.operator = operator;
|
|
277
|
+
} else {
|
|
278
|
+
assertTrue(
|
|
279
|
+
this.operators.length !== 0,
|
|
280
|
+
`Can't find an operator for property '${this.propertyExpressionState.path}': no operators registered`,
|
|
281
|
+
);
|
|
282
|
+
this.operator = this.operators[0] as QueryBuilderFilterOperator;
|
|
283
|
+
}
|
|
279
284
|
this.buildRightConditionValueFromValueSpec(
|
|
280
285
|
this.operator.getDefaultFilterConditionValue(this),
|
|
281
286
|
);
|
|
@@ -332,7 +332,7 @@ const processFilterTree = (
|
|
|
332
332
|
assertTrue(
|
|
333
333
|
parentLambdaVariableName === variableName,
|
|
334
334
|
`Can't process ${extractElementNameFromPath(
|
|
335
|
-
filterConditionState.operator.getLabel(
|
|
335
|
+
filterConditionState.operator.getLabel(),
|
|
336
336
|
)}() expression: expects variable used in lambda body '${variableName}' to match lambda parameter '${parentLambdaVariableName}'`,
|
|
337
337
|
);
|
|
338
338
|
filterState.addNodeFromNode(
|
|
@@ -46,7 +46,7 @@ export class QueryBuilderFilterOperator_Contain
|
|
|
46
46
|
extends QueryBuilderFilterOperator
|
|
47
47
|
implements Hashable
|
|
48
48
|
{
|
|
49
|
-
getLabel(
|
|
49
|
+
getLabel(): string {
|
|
50
50
|
return 'contains';
|
|
51
51
|
}
|
|
52
52
|
|
|
@@ -90,9 +90,7 @@ export class QueryBuilderFilterOperator_Contain
|
|
|
90
90
|
}
|
|
91
91
|
default:
|
|
92
92
|
throw new UnsupportedOperationError(
|
|
93
|
-
`Can't get default value for filter operator '${this.getLabel(
|
|
94
|
-
filterConditionState,
|
|
95
|
-
)}' when the LHS property is of type '${propertyType.path}'`,
|
|
93
|
+
`Can't get default value for filter operator '${this.getLabel()}' when the LHS property is of type '${propertyType.path}'`,
|
|
96
94
|
);
|
|
97
95
|
}
|
|
98
96
|
}
|
|
@@ -128,7 +126,7 @@ export class QueryBuilderFilterOperator_Contain
|
|
|
128
126
|
}
|
|
129
127
|
|
|
130
128
|
export class QueryBuilderFilterOperator_NotContain extends QueryBuilderFilterOperator_Contain {
|
|
131
|
-
override getLabel(
|
|
129
|
+
override getLabel(): string {
|
|
132
130
|
return `doesn't contain`;
|
|
133
131
|
}
|
|
134
132
|
|
|
@@ -46,7 +46,7 @@ export class QueryBuilderFilterOperator_EndWith
|
|
|
46
46
|
extends QueryBuilderFilterOperator
|
|
47
47
|
implements Hashable
|
|
48
48
|
{
|
|
49
|
-
getLabel(
|
|
49
|
+
getLabel(): string {
|
|
50
50
|
return 'ends with';
|
|
51
51
|
}
|
|
52
52
|
|
|
@@ -90,9 +90,7 @@ export class QueryBuilderFilterOperator_EndWith
|
|
|
90
90
|
}
|
|
91
91
|
default:
|
|
92
92
|
throw new UnsupportedOperationError(
|
|
93
|
-
`Can't get default value for filter operator '${this.getLabel(
|
|
94
|
-
filterConditionState,
|
|
95
|
-
)}' when the LHS property is of type '${propertyType.path}'`,
|
|
93
|
+
`Can't get default value for filter operator '${this.getLabel()}' when the LHS property is of type '${propertyType.path}'`,
|
|
96
94
|
);
|
|
97
95
|
}
|
|
98
96
|
}
|
|
@@ -128,7 +126,7 @@ export class QueryBuilderFilterOperator_EndWith
|
|
|
128
126
|
}
|
|
129
127
|
|
|
130
128
|
export class QueryBuilderFilterOperator_NotEndWith extends QueryBuilderFilterOperator_EndWith {
|
|
131
|
-
override getLabel(
|
|
129
|
+
override getLabel(): string {
|
|
132
130
|
return `doesn't end with`;
|
|
133
131
|
}
|
|
134
132
|
|
|
@@ -44,7 +44,7 @@ export class QueryBuilderFilterOperator_Equal
|
|
|
44
44
|
extends QueryBuilderFilterOperator
|
|
45
45
|
implements Hashable
|
|
46
46
|
{
|
|
47
|
-
getLabel(
|
|
47
|
+
getLabel(): string {
|
|
48
48
|
return 'is';
|
|
49
49
|
}
|
|
50
50
|
|
|
@@ -143,7 +143,7 @@ export class QueryBuilderFilterOperator_Equal
|
|
|
143
143
|
}
|
|
144
144
|
|
|
145
145
|
export class QueryBuilderFilterOperator_NotEqual extends QueryBuilderFilterOperator_Equal {
|
|
146
|
-
override getLabel(
|
|
146
|
+
override getLabel(): string {
|
|
147
147
|
return `is not`;
|
|
148
148
|
}
|
|
149
149
|
|
|
@@ -43,7 +43,7 @@ export class QueryBuilderFilterOperator_GreaterThan
|
|
|
43
43
|
extends QueryBuilderFilterOperator
|
|
44
44
|
implements Hashable
|
|
45
45
|
{
|
|
46
|
-
getLabel(
|
|
46
|
+
getLabel(): string {
|
|
47
47
|
return '>';
|
|
48
48
|
}
|
|
49
49
|
|
|
@@ -104,9 +104,7 @@ export class QueryBuilderFilterOperator_GreaterThan
|
|
|
104
104
|
}
|
|
105
105
|
default:
|
|
106
106
|
throw new UnsupportedOperationError(
|
|
107
|
-
`Can't get default value for filter operator '${this.getLabel(
|
|
108
|
-
filterConditionState,
|
|
109
|
-
)}' when the LHS property is of type '${propertyType.path}'`,
|
|
107
|
+
`Can't get default value for filter operator '${this.getLabel()}' when the LHS property is of type '${propertyType.path}'`,
|
|
110
108
|
);
|
|
111
109
|
}
|
|
112
110
|
}
|