@finos/legend-query-builder 4.11.5 → 4.11.6
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/result/QueryBuilderResultPanel.d.ts.map +1 -1
- package/lib/components/result/QueryBuilderResultPanel.js.map +1 -1
- package/lib/components/result/tds/QueryBuilderTDSGridResult.d.ts.map +1 -1
- package/lib/components/result/tds/QueryBuilderTDSGridResult.js +76 -12
- package/lib/components/result/tds/QueryBuilderTDSGridResult.js.map +1 -1
- package/lib/components/result/tds/QueryBuilderTDSResultShared.d.ts +8 -12
- package/lib/components/result/tds/QueryBuilderTDSResultShared.d.ts.map +1 -1
- package/lib/components/result/tds/QueryBuilderTDSResultShared.js +134 -348
- package/lib/components/result/tds/QueryBuilderTDSResultShared.js.map +1 -1
- package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.d.ts +1 -1
- package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.d.ts.map +1 -1
- package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.js +179 -2
- package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.js.map +1 -1
- package/lib/index.css +1 -1
- package/lib/package.json +1 -1
- package/package.json +3 -3
- package/src/components/result/QueryBuilderResultPanel.tsx +0 -1
- package/src/components/result/tds/QueryBuilderTDSGridResult.tsx +125 -18
- package/src/components/result/tds/QueryBuilderTDSResultShared.tsx +299 -663
- package/src/components/result/tds/QueryBuilderTDSSimpleGridResult.tsx +310 -3
@@ -17,43 +17,42 @@
|
|
17
17
|
import {
|
18
18
|
MenuContent,
|
19
19
|
MenuContentItem,
|
20
|
-
ContextMenu,
|
21
|
-
clsx,
|
22
20
|
MenuContentDivider,
|
23
21
|
} from '@finos/legend-art';
|
24
22
|
import { observer } from 'mobx-react-lite';
|
25
23
|
import { flowResult } from 'mobx';
|
26
24
|
import {
|
25
|
+
type TDSExecutionResult,
|
27
26
|
type Enumeration,
|
28
27
|
InstanceValue,
|
29
|
-
TDSExecutionResult,
|
30
28
|
EnumValueInstanceValue,
|
31
29
|
EnumValueExplicitReference,
|
32
|
-
getTDSRowRankByColumnInAsc,
|
33
30
|
PRIMITIVE_TYPE,
|
34
31
|
type ExecutionResult,
|
35
32
|
RelationalExecutionActivities,
|
36
33
|
} from '@finos/legend-graph';
|
37
34
|
import { format as formatSQL } from 'sql-formatter';
|
38
|
-
import {
|
35
|
+
import {
|
36
|
+
type ApplicationStore,
|
37
|
+
type LegendApplicationConfig,
|
38
|
+
type LegendApplicationPlugin,
|
39
|
+
type LegendApplicationPluginManager,
|
40
|
+
useApplicationStore,
|
41
|
+
} from '@finos/legend-application';
|
39
42
|
import {
|
40
43
|
assertErrorThrown,
|
41
44
|
guaranteeNonNullable,
|
42
|
-
isValidURL,
|
43
|
-
isString,
|
44
|
-
isNumber,
|
45
45
|
filterByType,
|
46
46
|
isBoolean,
|
47
|
-
type PlainObject,
|
48
47
|
} from '@finos/legend-shared';
|
49
48
|
import { forwardRef } from 'react';
|
50
|
-
|
51
49
|
import {
|
52
50
|
QueryBuilderDerivationProjectionColumnState,
|
53
51
|
QueryBuilderProjectionColumnState,
|
54
52
|
} from '../../../stores/fetch-structure/tds/projection/QueryBuilderProjectionColumnState.js';
|
55
53
|
import {
|
56
54
|
type QueryBuilderPostFilterTreeNodeData,
|
55
|
+
type QueryBuilderPostFilterState,
|
57
56
|
PostFilterConditionState,
|
58
57
|
QueryBuilderPostFilterTreeConditionNodeData,
|
59
58
|
PostFilterValueSpecConditionValueState,
|
@@ -67,28 +66,23 @@ import {
|
|
67
66
|
QueryBuilderPostFilterOperator_NotIn,
|
68
67
|
} from '../../../stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_In.js';
|
69
68
|
import type { QueryBuilderPostFilterOperator } from '../../../stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterOperator.js';
|
70
|
-
import { QueryBuilderTDSState } from '../../../stores/fetch-structure/tds/QueryBuilderTDSState.js';
|
69
|
+
import type { QueryBuilderTDSState } from '../../../stores/fetch-structure/tds/QueryBuilderTDSState.js';
|
71
70
|
import {
|
72
71
|
instanceValue_setValue,
|
73
72
|
instanceValue_setValues,
|
74
73
|
} from '../../../stores/shared/ValueSpecificationModifierHelper.js';
|
75
|
-
import {
|
76
|
-
isEnterpriseModeEnabled,
|
77
|
-
type DataGridApi,
|
78
|
-
type DataGridCellRendererParams,
|
79
|
-
} from '@finos/legend-lego/data-grid';
|
74
|
+
import { type DataGridCellRendererParams } from '@finos/legend-lego/data-grid';
|
80
75
|
import type {
|
81
|
-
QueryBuilderTDSResultCellCoordinate,
|
82
76
|
QueryBuilderResultState,
|
83
77
|
QueryBuilderTDSResultCellData,
|
84
78
|
QueryBuilderTDSRowDataType,
|
85
|
-
QueryBuilderTDSResultCellDataType,
|
86
79
|
} from '../../../stores/QueryBuilderResultState.js';
|
87
80
|
import {
|
88
81
|
QueryBuilderPostFilterOperator_IsEmpty,
|
89
82
|
QueryBuilderPostFilterOperator_IsNotEmpty,
|
90
83
|
} from '../../../stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_IsEmpty.js';
|
91
|
-
import {
|
84
|
+
import { getTDSColumnState } from '../../../stores/fetch-structure/tds/QueryBuilderTDSHelper.js';
|
85
|
+
import type { QueryBuilderTDSColumnState } from '../../../stores/fetch-structure/tds/QueryBuilderTDSColumnState.js';
|
92
86
|
|
93
87
|
export const tryToFormatSql = (sql: string): string => {
|
94
88
|
try {
|
@@ -161,9 +155,9 @@ export const getAggregationTDSColumnCustomizations = (
|
|
161
155
|
|
162
156
|
export const getRowDataFromExecutionResult = (
|
163
157
|
executionResult: TDSExecutionResult,
|
164
|
-
):
|
158
|
+
): QueryBuilderTDSRowDataType[] => {
|
165
159
|
const rowData = executionResult.result.rows.map((_row, rowIdx) => {
|
166
|
-
const row:
|
160
|
+
const row: QueryBuilderTDSRowDataType = {};
|
167
161
|
const cols = executionResult.result.columns;
|
168
162
|
_row.values.forEach((value, colIdx) => {
|
169
163
|
// `ag-grid` shows `false` value as empty string so we have
|
@@ -183,684 +177,326 @@ export type IQueryRendererParamsWithGridType = DataGridCellRendererParams & {
|
|
183
177
|
tdsExecutionResult: TDSExecutionResult;
|
184
178
|
};
|
185
179
|
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
180
|
+
const postFilterEqualOperator = new QueryBuilderPostFilterOperator_Equal();
|
181
|
+
const postFilterInOperator = new QueryBuilderPostFilterOperator_In();
|
182
|
+
const postFilterEmptyOperator = new QueryBuilderPostFilterOperator_IsEmpty();
|
183
|
+
const postFilterNotEmptyOperator =
|
184
|
+
new QueryBuilderPostFilterOperator_IsNotEmpty();
|
185
|
+
const postFilterNotEqualOperator =
|
186
|
+
new QueryBuilderPostFilterOperator_NotEqual();
|
187
|
+
const postFilterNotInOperator = new QueryBuilderPostFilterOperator_NotIn();
|
188
|
+
|
189
|
+
const getExistingPostFilterNode = (
|
190
|
+
operators: QueryBuilderPostFilterOperator[],
|
191
|
+
projectionColumnName: string | undefined,
|
192
|
+
postFilterState: QueryBuilderPostFilterState,
|
193
|
+
tdsColState: QueryBuilderTDSColumnState | undefined,
|
194
|
+
): QueryBuilderPostFilterTreeNodeData | undefined =>
|
195
|
+
Array.from(postFilterState.nodes.values())
|
196
|
+
.filter(filterByType(QueryBuilderPostFilterTreeConditionNodeData))
|
197
|
+
.filter(
|
198
|
+
(node) =>
|
199
|
+
node.condition.leftConditionValue instanceof
|
200
|
+
QueryBuilderProjectionColumnState,
|
201
|
+
)
|
202
|
+
.filter(
|
203
|
+
(node) =>
|
204
|
+
node.condition.leftConditionValue.columnName ===
|
205
|
+
(projectionColumnName ?? tdsColState?.columnName) &&
|
206
|
+
operators
|
207
|
+
.map((op) => op.getLabel())
|
208
|
+
.includes(node.condition.operator.getLabel()),
|
209
|
+
)[0];
|
210
|
+
|
211
|
+
const updateFilterConditionValue = (
|
212
|
+
conditionValue: InstanceValue,
|
213
|
+
_cellData: QueryBuilderTDSResultCellData,
|
214
|
+
tdsState: QueryBuilderTDSState,
|
215
|
+
): void => {
|
216
|
+
if (_cellData.value) {
|
217
|
+
instanceValue_setValue(
|
218
|
+
conditionValue,
|
219
|
+
conditionValue instanceof EnumValueInstanceValue
|
220
|
+
? EnumValueExplicitReference.create(
|
221
|
+
guaranteeNonNullable(
|
222
|
+
(
|
223
|
+
conditionValue.genericType?.ownerReference.value as Enumeration
|
224
|
+
).values.filter((v) => v.name === _cellData.value)[0],
|
225
|
+
),
|
226
|
+
)
|
227
|
+
: _cellData.value,
|
228
|
+
0,
|
229
|
+
tdsState.queryBuilderState.observerContext,
|
230
|
+
);
|
231
|
+
}
|
232
|
+
};
|
209
233
|
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
).condition.operator.getLabel(),
|
239
|
-
),
|
240
|
-
)[0];
|
234
|
+
const generateNewPostFilterConditionNodeData = async (
|
235
|
+
applicationStore: ApplicationStore<
|
236
|
+
LegendApplicationConfig,
|
237
|
+
LegendApplicationPluginManager<LegendApplicationPlugin>
|
238
|
+
>,
|
239
|
+
operator: QueryBuilderPostFilterOperator,
|
240
|
+
_cellData: QueryBuilderTDSResultCellData,
|
241
|
+
tdsState: QueryBuilderTDSState,
|
242
|
+
tdsColState: QueryBuilderTDSColumnState | undefined,
|
243
|
+
): Promise<void> => {
|
244
|
+
let postFilterConditionState: PostFilterConditionState;
|
245
|
+
try {
|
246
|
+
const possibleProjectionColumnState = _cellData.columnName
|
247
|
+
? tdsState.projectionColumns
|
248
|
+
.filter((c) => c.columnName === _cellData.columnName)
|
249
|
+
.concat(
|
250
|
+
tdsState.aggregationState.columns
|
251
|
+
.filter((c) => c.columnName === _cellData.columnName)
|
252
|
+
.map((ag) => ag.projectionColumnState),
|
253
|
+
)[0]
|
254
|
+
: tdsColState;
|
255
|
+
|
256
|
+
if (possibleProjectionColumnState) {
|
257
|
+
postFilterConditionState = new PostFilterConditionState(
|
258
|
+
tdsState.postFilterState,
|
259
|
+
possibleProjectionColumnState,
|
260
|
+
operator,
|
261
|
+
);
|
241
262
|
|
242
|
-
|
243
|
-
|
244
|
-
cellData: QueryBuilderTDSResultCellData,
|
245
|
-
): void => {
|
246
|
-
if (cellData.value) {
|
247
|
-
instanceValue_setValue(
|
248
|
-
conditionValue,
|
249
|
-
conditionValue instanceof EnumValueInstanceValue
|
250
|
-
? EnumValueExplicitReference.create(
|
251
|
-
guaranteeNonNullable(
|
252
|
-
(
|
253
|
-
conditionValue.genericType?.ownerReference
|
254
|
-
.value as Enumeration
|
255
|
-
).values.filter((v) => v.name === cellData.value)[0],
|
256
|
-
),
|
257
|
-
)
|
258
|
-
: cellData.value,
|
259
|
-
0,
|
260
|
-
tdsState.queryBuilderState.observerContext,
|
261
|
-
);
|
263
|
+
if (tdsColState instanceof QueryBuilderDerivationProjectionColumnState) {
|
264
|
+
await flowResult(tdsColState.fetchDerivationLambdaReturnType());
|
262
265
|
}
|
263
|
-
};
|
264
|
-
|
265
|
-
const generateNewPostFilterConditionNodeData = async (
|
266
|
-
operator: QueryBuilderPostFilterOperator,
|
267
|
-
cellData: QueryBuilderTDSResultCellData,
|
268
|
-
): Promise<void> => {
|
269
|
-
let postFilterConditionState: PostFilterConditionState;
|
270
|
-
try {
|
271
|
-
const possibleProjectionColumnState = cellData.columnName
|
272
|
-
? tdsState.projectionColumns
|
273
|
-
.filter((c) => c.columnName === cellData.columnName)
|
274
|
-
.concat(
|
275
|
-
tdsState.aggregationState.columns
|
276
|
-
.filter((c) => c.columnName === cellData.columnName)
|
277
|
-
.map((ag) => ag.projectionColumnState),
|
278
|
-
)[0]
|
279
|
-
: projectionColumnState;
|
280
|
-
|
281
|
-
if (possibleProjectionColumnState) {
|
282
|
-
postFilterConditionState = new PostFilterConditionState(
|
283
|
-
postFilterState,
|
284
|
-
possibleProjectionColumnState,
|
285
|
-
operator,
|
286
|
-
);
|
287
|
-
|
288
|
-
if (
|
289
|
-
projectionColumnState instanceof
|
290
|
-
QueryBuilderDerivationProjectionColumnState
|
291
|
-
) {
|
292
|
-
await flowResult(
|
293
|
-
projectionColumnState.fetchDerivationLambdaReturnType(),
|
294
|
-
);
|
295
|
-
}
|
296
266
|
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
267
|
+
const defaultFilterConditionValue =
|
268
|
+
postFilterConditionState.operator.getDefaultFilterConditionValue(
|
269
|
+
postFilterConditionState,
|
270
|
+
);
|
301
271
|
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
};
|
272
|
+
postFilterConditionState.buildFromValueSpec(defaultFilterConditionValue);
|
273
|
+
updateFilterConditionValue(
|
274
|
+
defaultFilterConditionValue as InstanceValue,
|
275
|
+
_cellData,
|
276
|
+
tdsState,
|
277
|
+
);
|
278
|
+
tdsState.postFilterState.addNodeFromNode(
|
279
|
+
new QueryBuilderPostFilterTreeConditionNodeData(
|
280
|
+
undefined,
|
281
|
+
postFilterConditionState,
|
282
|
+
),
|
283
|
+
undefined,
|
284
|
+
);
|
285
|
+
}
|
286
|
+
} catch (error) {
|
287
|
+
assertErrorThrown(error);
|
288
|
+
applicationStore.notificationService.notifyWarning(error.message);
|
289
|
+
return;
|
290
|
+
}
|
291
|
+
};
|
323
292
|
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
293
|
+
const updateExistingPostFilterConditionNodeData = (
|
294
|
+
existingPostFilterNode: QueryBuilderPostFilterTreeNodeData,
|
295
|
+
isFilterBy: boolean,
|
296
|
+
_cellData: QueryBuilderTDSResultCellData,
|
297
|
+
operator: QueryBuilderPostFilterOperator,
|
298
|
+
data: QueryBuilderTDSResultCellData | null,
|
299
|
+
tdsState: QueryBuilderTDSState,
|
300
|
+
): void => {
|
301
|
+
if (
|
302
|
+
operator === postFilterEmptyOperator ||
|
303
|
+
operator === postFilterNotEmptyOperator
|
304
|
+
) {
|
305
|
+
const conditionState = (
|
306
|
+
existingPostFilterNode as QueryBuilderPostFilterTreeConditionNodeData
|
307
|
+
).condition;
|
308
|
+
if (conditionState.operator.getLabel() !== operator.getLabel()) {
|
309
|
+
conditionState.changeOperator(
|
310
|
+
isFilterBy ? postFilterEmptyOperator : postFilterNotEmptyOperator,
|
311
|
+
);
|
312
|
+
}
|
313
|
+
return;
|
314
|
+
}
|
315
|
+
const conditionState = (
|
316
|
+
existingPostFilterNode as QueryBuilderPostFilterTreeConditionNodeData
|
317
|
+
).condition;
|
318
|
+
|
319
|
+
const rightSide = conditionState.rightConditionValue;
|
320
|
+
if (rightSide instanceof PostFilterValueSpecConditionValueState) {
|
321
|
+
if (conditionState.operator.getLabel() === operator.getLabel()) {
|
322
|
+
const doesValueAlreadyExist =
|
323
|
+
rightSide.value instanceof InstanceValue &&
|
324
|
+
(rightSide.value instanceof EnumValueInstanceValue
|
325
|
+
? rightSide.value.values.map((ef) => ef.value.name)
|
326
|
+
: rightSide.value.values
|
327
|
+
).includes(_cellData.value);
|
328
|
+
|
329
|
+
if (!doesValueAlreadyExist) {
|
330
|
+
const currentValueSpecificaton = rightSide.value;
|
331
|
+
const newValueSpecification =
|
332
|
+
conditionState.operator.getDefaultFilterConditionValue(
|
333
|
+
conditionState,
|
340
334
|
);
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
? rightSide.value.values.map((ef) => ef.value.name)
|
355
|
-
: rightSide.value.values
|
356
|
-
).includes(cellData.value);
|
357
|
-
|
358
|
-
if (!doesValueAlreadyExist) {
|
359
|
-
const currentValueSpecificaton = rightSide.value;
|
360
|
-
const newValueSpecification =
|
361
|
-
conditionState.operator.getDefaultFilterConditionValue(
|
362
|
-
conditionState,
|
363
|
-
);
|
364
|
-
updateFilterConditionValue(
|
365
|
-
newValueSpecification as InstanceValue,
|
366
|
-
cellData,
|
367
|
-
);
|
368
|
-
conditionState.changeOperator(
|
369
|
-
isFilterBy ? postFilterInOperator : postFilterNotInOperator,
|
370
|
-
);
|
371
|
-
instanceValue_setValues(
|
372
|
-
rightSide.value as InstanceValue,
|
373
|
-
[currentValueSpecificaton, newValueSpecification],
|
374
|
-
tdsState.queryBuilderState.observerContext,
|
375
|
-
);
|
376
|
-
}
|
377
|
-
} else {
|
378
|
-
const doesValueAlreadyExist =
|
379
|
-
rightSide.value instanceof InstanceValue &&
|
380
|
-
rightSide.value.values
|
381
|
-
.filter((v) => v instanceof InstanceValue)
|
382
|
-
.map((v) =>
|
383
|
-
v instanceof EnumValueInstanceValue
|
384
|
-
? v.values.map((ef) => ef.value.name)
|
385
|
-
: (v as InstanceValue).values,
|
386
|
-
)
|
387
|
-
.flat()
|
388
|
-
.includes(cellData.value ?? data?.value);
|
389
|
-
|
390
|
-
if (!doesValueAlreadyExist) {
|
391
|
-
const newValueSpecification = (
|
392
|
-
isFilterBy ? postFilterEqualOperator : postFilterNotEqualOperator
|
393
|
-
).getDefaultFilterConditionValue(conditionState);
|
394
|
-
updateFilterConditionValue(
|
395
|
-
newValueSpecification as InstanceValue,
|
396
|
-
cellData,
|
397
|
-
);
|
398
|
-
instanceValue_setValues(
|
399
|
-
rightSide.value as InstanceValue,
|
400
|
-
[
|
401
|
-
...(rightSide.value as InstanceValue).values,
|
402
|
-
newValueSpecification,
|
403
|
-
],
|
404
|
-
tdsState.queryBuilderState.observerContext,
|
405
|
-
);
|
406
|
-
}
|
407
|
-
}
|
335
|
+
updateFilterConditionValue(
|
336
|
+
newValueSpecification as InstanceValue,
|
337
|
+
_cellData,
|
338
|
+
tdsState,
|
339
|
+
);
|
340
|
+
conditionState.changeOperator(
|
341
|
+
isFilterBy ? postFilterInOperator : postFilterNotInOperator,
|
342
|
+
);
|
343
|
+
instanceValue_setValues(
|
344
|
+
rightSide.value as InstanceValue,
|
345
|
+
[currentValueSpecificaton, newValueSpecification],
|
346
|
+
tdsState.queryBuilderState.observerContext,
|
347
|
+
);
|
408
348
|
}
|
409
|
-
}
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
349
|
+
} else {
|
350
|
+
const doesValueAlreadyExist =
|
351
|
+
rightSide.value instanceof InstanceValue &&
|
352
|
+
rightSide.value.values
|
353
|
+
.filter((v) => v instanceof InstanceValue)
|
354
|
+
.map((v) =>
|
355
|
+
v instanceof EnumValueInstanceValue
|
356
|
+
? v.values.map((ef) => ef.value.name)
|
357
|
+
: (v as InstanceValue).values,
|
358
|
+
)
|
359
|
+
.flat()
|
360
|
+
.includes(_cellData.value ?? data?.value);
|
361
|
+
|
362
|
+
if (!doesValueAlreadyExist) {
|
363
|
+
const newValueSpecification = (
|
364
|
+
isFilterBy ? postFilterEqualOperator : postFilterNotEqualOperator
|
365
|
+
).getDefaultFilterConditionValue(conditionState);
|
366
|
+
updateFilterConditionValue(
|
367
|
+
newValueSpecification as InstanceValue,
|
368
|
+
_cellData,
|
369
|
+
tdsState,
|
370
|
+
);
|
371
|
+
instanceValue_setValues(
|
372
|
+
rightSide.value as InstanceValue,
|
373
|
+
[...(rightSide.value as InstanceValue).values, newValueSpecification],
|
374
|
+
tdsState.queryBuilderState.observerContext,
|
375
|
+
);
|
427
376
|
}
|
428
|
-
}
|
429
|
-
|
430
|
-
|
431
|
-
isFilterBy: boolean,
|
432
|
-
cellData: QueryBuilderTDSResultCellData,
|
433
|
-
): void => {
|
434
|
-
tdsState.setShowPostFilterPanel(true);
|
435
|
-
|
436
|
-
const operator = getFilterOperator(isFilterBy, cellData);
|
437
|
-
|
438
|
-
const existingPostFilterNode = getExistingPostFilterNode(
|
439
|
-
cellData.value === null
|
440
|
-
? [postFilterEmptyOperator, postFilterNotEmptyOperator]
|
441
|
-
: isFilterBy
|
442
|
-
? [postFilterEqualOperator, postFilterInOperator]
|
443
|
-
: [postFilterNotEqualOperator, postFilterNotInOperator],
|
444
|
-
cellData.columnName,
|
445
|
-
);
|
377
|
+
}
|
378
|
+
}
|
379
|
+
};
|
446
380
|
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
381
|
+
const getFilterOperator = (
|
382
|
+
isFilterBy: boolean,
|
383
|
+
_cellData: QueryBuilderTDSResultCellData,
|
384
|
+
): QueryBuilderPostFilterOperator => {
|
385
|
+
if (isFilterBy) {
|
386
|
+
if (_cellData.value === null) {
|
387
|
+
return postFilterEmptyOperator;
|
388
|
+
} else {
|
389
|
+
return postFilterEqualOperator;
|
390
|
+
}
|
391
|
+
} else {
|
392
|
+
if (_cellData.value === null) {
|
393
|
+
return postFilterNotEmptyOperator;
|
394
|
+
} else {
|
395
|
+
return postFilterNotEqualOperator;
|
396
|
+
}
|
397
|
+
}
|
398
|
+
};
|
458
399
|
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
400
|
+
const filterByOrOutValue = (
|
401
|
+
applicationStore: ApplicationStore<
|
402
|
+
LegendApplicationConfig,
|
403
|
+
LegendApplicationPluginManager<LegendApplicationPlugin>
|
404
|
+
>,
|
405
|
+
isFilterBy: boolean,
|
406
|
+
_cellData: QueryBuilderTDSResultCellData,
|
407
|
+
data: QueryBuilderTDSResultCellData | null,
|
408
|
+
tdsState: QueryBuilderTDSState,
|
409
|
+
): void => {
|
410
|
+
tdsState.setShowPostFilterPanel(true);
|
411
|
+
const operator = getFilterOperator(isFilterBy, _cellData);
|
412
|
+
const tdsColState = data?.columnName
|
413
|
+
? getTDSColumnState(tdsState, data.columnName)
|
414
|
+
: undefined;
|
415
|
+
const existingPostFilterNode = getExistingPostFilterNode(
|
416
|
+
_cellData.value === null
|
417
|
+
? [postFilterEmptyOperator, postFilterNotEmptyOperator]
|
418
|
+
: isFilterBy
|
419
|
+
? [postFilterEqualOperator, postFilterInOperator]
|
420
|
+
: [postFilterNotEqualOperator, postFilterNotInOperator],
|
421
|
+
_cellData.columnName,
|
422
|
+
tdsState.postFilterState,
|
423
|
+
tdsColState,
|
424
|
+
);
|
425
|
+
existingPostFilterNode === undefined
|
426
|
+
? generateNewPostFilterConditionNodeData(
|
427
|
+
applicationStore,
|
428
|
+
operator,
|
429
|
+
_cellData,
|
430
|
+
tdsState,
|
431
|
+
tdsColState,
|
432
|
+
).catch(applicationStore.alertUnhandledError)
|
433
|
+
: updateExistingPostFilterConditionNodeData(
|
434
|
+
existingPostFilterNode,
|
435
|
+
isFilterBy,
|
436
|
+
_cellData,
|
437
|
+
operator,
|
438
|
+
data,
|
439
|
+
tdsState,
|
464
440
|
);
|
465
|
-
|
441
|
+
};
|
466
442
|
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
443
|
+
export const filterByOrOutValues = (
|
444
|
+
applicationStore: ApplicationStore<
|
445
|
+
LegendApplicationConfig,
|
446
|
+
LegendApplicationPluginManager<LegendApplicationPlugin>
|
447
|
+
>,
|
448
|
+
data: QueryBuilderTDSResultCellData | null,
|
449
|
+
isFilterBy: boolean,
|
450
|
+
tdsState: QueryBuilderTDSState,
|
451
|
+
): void => {
|
452
|
+
tdsState.queryBuilderState.resultState.selectedCells.forEach((_cellData) => {
|
453
|
+
filterByOrOutValue(applicationStore, isFilterBy, _cellData, data, tdsState);
|
454
|
+
});
|
455
|
+
};
|
478
456
|
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
)
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
const valueArr: QueryBuilderTDSResultCellDataType[] = [];
|
492
|
-
Object.entries(
|
493
|
-
dataGridApi.getRenderedNodes().find((n) => n.rowIndex === rowIndex)
|
494
|
-
?.data as QueryBuilderTDSRowDataType,
|
495
|
-
).forEach((entry) => {
|
496
|
-
if (entry[0] !== 'rowNumber') {
|
497
|
-
valueArr.push(entry[1] as QueryBuilderTDSResultCellDataType);
|
498
|
-
}
|
499
|
-
});
|
500
|
-
return valueArr.join(',');
|
501
|
-
};
|
457
|
+
export const QueryBuilderGridResultContextMenu = observer(
|
458
|
+
forwardRef<
|
459
|
+
HTMLDivElement,
|
460
|
+
{
|
461
|
+
data: QueryBuilderTDSResultCellData | null;
|
462
|
+
tdsState: QueryBuilderTDSState;
|
463
|
+
copyCellValueFunc: () => void;
|
464
|
+
copyCellRowValueFunc: () => void;
|
465
|
+
}
|
466
|
+
>(function QueryBuilderResultContextMenu(props, ref) {
|
467
|
+
const { data, tdsState, copyCellValueFunc, copyCellRowValueFunc } = props;
|
468
|
+
const applicationStore = useApplicationStore();
|
502
469
|
|
503
|
-
const
|
504
|
-
? ()
|
505
|
-
|
506
|
-
}
|
507
|
-
: applicationStore.guardUnhandledError(() =>
|
508
|
-
applicationStore.clipboardService.copyTextToClipboard(
|
509
|
-
findRowFromRowIndex(
|
510
|
-
tdsState.queryBuilderState.resultState.selectedCells[0]
|
511
|
-
?.coordinates.rowIndex ?? 0,
|
512
|
-
),
|
513
|
-
),
|
514
|
-
);
|
470
|
+
const tdsColState = data?.columnName
|
471
|
+
? getTDSColumnState(tdsState, data.columnName)
|
472
|
+
: undefined;
|
515
473
|
|
516
474
|
return (
|
517
475
|
<MenuContent ref={ref}>
|
518
476
|
<MenuContentItem
|
519
|
-
disabled={!
|
477
|
+
disabled={!tdsColState}
|
520
478
|
onClick={(): void => {
|
521
|
-
filterByOrOutValues(true);
|
479
|
+
filterByOrOutValues(applicationStore, data, true, tdsState);
|
522
480
|
}}
|
523
481
|
>
|
524
482
|
Filter By
|
525
483
|
</MenuContentItem>
|
526
484
|
<MenuContentItem
|
527
|
-
disabled={!
|
485
|
+
disabled={!tdsColState}
|
528
486
|
onClick={(): void => {
|
529
|
-
filterByOrOutValues(false);
|
487
|
+
filterByOrOutValues(applicationStore, data, false, tdsState);
|
530
488
|
}}
|
531
489
|
>
|
532
490
|
Filter Out
|
533
491
|
</MenuContentItem>
|
534
492
|
<MenuContentDivider />
|
535
|
-
<MenuContentItem onClick={
|
493
|
+
<MenuContentItem onClick={copyCellValueFunc}>
|
536
494
|
Copy Cell Value
|
537
495
|
</MenuContentItem>
|
538
|
-
<MenuContentItem onClick={
|
496
|
+
<MenuContentItem onClick={copyCellRowValueFunc}>
|
539
497
|
Copy Row Value
|
540
498
|
</MenuContentItem>
|
541
499
|
</MenuContent>
|
542
500
|
);
|
543
501
|
}),
|
544
502
|
);
|
545
|
-
|
546
|
-
export const QueryResultEnterpriseCellRenderer = observer(
|
547
|
-
(params: IQueryRendererParamsWithGridType) => {
|
548
|
-
const resultState = params.resultState;
|
549
|
-
const fetchStructureImplementation =
|
550
|
-
resultState.queryBuilderState.fetchStructureState.implementation;
|
551
|
-
const cellValue = params.value as QueryBuilderTDSResultCellDataType;
|
552
|
-
const formattedCellValue = (): QueryBuilderTDSResultCellDataType => {
|
553
|
-
if (isNumber(cellValue)) {
|
554
|
-
return Intl.NumberFormat(DEFAULT_LOCALE, {
|
555
|
-
maximumFractionDigits: 4,
|
556
|
-
}).format(Number(cellValue));
|
557
|
-
}
|
558
|
-
return cellValue;
|
559
|
-
};
|
560
|
-
const cellValueUrlLink =
|
561
|
-
isString(cellValue) && isValidURL(cellValue) ? cellValue : undefined;
|
562
|
-
|
563
|
-
const mouseDown: React.MouseEventHandler = (event) => {
|
564
|
-
event.preventDefault();
|
565
|
-
if (event.button === 0 || event.button === 2) {
|
566
|
-
resultState.setMouseOverCell(resultState.selectedCells[0] ?? null);
|
567
|
-
}
|
568
|
-
};
|
569
|
-
const mouseUp: React.MouseEventHandler = (event) => {
|
570
|
-
resultState.setIsSelectingCells(false);
|
571
|
-
};
|
572
|
-
const mouseOver: React.MouseEventHandler = (event) => {
|
573
|
-
resultState.setMouseOverCell(resultState.selectedCells[0] ?? null);
|
574
|
-
};
|
575
|
-
|
576
|
-
return (
|
577
|
-
<ContextMenu
|
578
|
-
content={
|
579
|
-
// NOTE: we only support this functionality for grid result with a projection fetch-structure
|
580
|
-
fetchStructureImplementation instanceof QueryBuilderTDSState ? (
|
581
|
-
<QueryBuilderGridResultContextMenu
|
582
|
-
data={resultState.mousedOverCell}
|
583
|
-
tdsState={fetchStructureImplementation}
|
584
|
-
dataGridApi={params.api}
|
585
|
-
/>
|
586
|
-
) : null
|
587
|
-
}
|
588
|
-
disabled={
|
589
|
-
!(
|
590
|
-
resultState.queryBuilderState.fetchStructureState
|
591
|
-
.implementation instanceof QueryBuilderTDSState
|
592
|
-
) ||
|
593
|
-
!resultState.queryBuilderState.isQuerySupported ||
|
594
|
-
!resultState.mousedOverCell
|
595
|
-
}
|
596
|
-
menuProps={{ elevation: 7 }}
|
597
|
-
className={clsx('ag-theme-balham-dark query-builder__result__tds-grid')}
|
598
|
-
>
|
599
|
-
<div
|
600
|
-
className={clsx('query-builder__result__values__table__cell')}
|
601
|
-
onMouseDown={(event) => mouseDown(event)}
|
602
|
-
onMouseUp={(event) => mouseUp(event)}
|
603
|
-
onMouseOver={(event) => mouseOver(event)}
|
604
|
-
>
|
605
|
-
{cellValueUrlLink ? (
|
606
|
-
<a href={cellValueUrlLink} target="_blank" rel="noreferrer">
|
607
|
-
{cellValueUrlLink}
|
608
|
-
</a>
|
609
|
-
) : (
|
610
|
-
<span>{formattedCellValue()}</span>
|
611
|
-
)}
|
612
|
-
</div>
|
613
|
-
</ContextMenu>
|
614
|
-
);
|
615
|
-
},
|
616
|
-
);
|
617
|
-
|
618
|
-
export const QueryResultCellRenderer = observer(
|
619
|
-
(params: IQueryRendererParamsWithGridType) => {
|
620
|
-
const resultState = params.resultState;
|
621
|
-
const tdsExecutionResult = params.tdsExecutionResult;
|
622
|
-
const fetchStructureImplementation =
|
623
|
-
resultState.queryBuilderState.fetchStructureState.implementation;
|
624
|
-
const cellValue = params.value as QueryBuilderTDSResultCellDataType;
|
625
|
-
const formattedCellValue = (): QueryBuilderTDSResultCellDataType => {
|
626
|
-
if (isNumber(cellValue)) {
|
627
|
-
return Intl.NumberFormat(DEFAULT_LOCALE, {
|
628
|
-
maximumFractionDigits: 4,
|
629
|
-
}).format(Number(cellValue));
|
630
|
-
}
|
631
|
-
return cellValue;
|
632
|
-
};
|
633
|
-
const cellValueUrlLink =
|
634
|
-
isString(cellValue) && isValidURL(cellValue) ? cellValue : undefined;
|
635
|
-
const columnName = params.column?.getColId() ?? '';
|
636
|
-
const findCoordinatesFromResultValue = (
|
637
|
-
colId: string,
|
638
|
-
rowNumber: number,
|
639
|
-
): QueryBuilderTDSResultCellCoordinate => {
|
640
|
-
const colIndex = tdsExecutionResult.result.columns.findIndex(
|
641
|
-
(col) => col === colId,
|
642
|
-
);
|
643
|
-
return { rowIndex: rowNumber, colIndex: colIndex };
|
644
|
-
};
|
645
|
-
|
646
|
-
const currentCellCoordinates = findCoordinatesFromResultValue(
|
647
|
-
columnName,
|
648
|
-
params.rowIndex,
|
649
|
-
);
|
650
|
-
const cellInFilteredResults = resultState.selectedCells.some(
|
651
|
-
(result) =>
|
652
|
-
result.coordinates.colIndex === currentCellCoordinates.colIndex &&
|
653
|
-
result.coordinates.rowIndex === currentCellCoordinates.rowIndex,
|
654
|
-
);
|
655
|
-
|
656
|
-
const findColumnFromCoordinates = (
|
657
|
-
colIndex: number,
|
658
|
-
): QueryBuilderTDSResultCellDataType => {
|
659
|
-
if (
|
660
|
-
!resultState.executionResult ||
|
661
|
-
!(resultState.executionResult instanceof TDSExecutionResult)
|
662
|
-
) {
|
663
|
-
return undefined;
|
664
|
-
}
|
665
|
-
return resultState.executionResult.result.columns[colIndex];
|
666
|
-
};
|
667
|
-
|
668
|
-
const findResultValueFromCoordinates = (
|
669
|
-
resultCoordinate: [number, number],
|
670
|
-
): QueryBuilderTDSResultCellDataType => {
|
671
|
-
const rowIndex = resultCoordinate[0];
|
672
|
-
const colIndex = resultCoordinate[1];
|
673
|
-
|
674
|
-
if (
|
675
|
-
!resultState.executionResult ||
|
676
|
-
!(resultState.executionResult instanceof TDSExecutionResult)
|
677
|
-
) {
|
678
|
-
return undefined;
|
679
|
-
}
|
680
|
-
if (params.columnApi.getColumnState()[colIndex]?.sort === 'asc') {
|
681
|
-
resultState.executionResult.result.rows.sort((a, b) =>
|
682
|
-
getTDSRowRankByColumnInAsc(a, b, colIndex),
|
683
|
-
);
|
684
|
-
} else if (params.columnApi.getColumnState()[colIndex]?.sort === 'desc') {
|
685
|
-
resultState.executionResult.result.rows.sort((a, b) =>
|
686
|
-
getTDSRowRankByColumnInAsc(b, a, colIndex),
|
687
|
-
);
|
688
|
-
}
|
689
|
-
return resultState.executionResult.result.rows[rowIndex]?.values[
|
690
|
-
colIndex
|
691
|
-
];
|
692
|
-
};
|
693
|
-
|
694
|
-
const isCoordinatesSelected = (
|
695
|
-
resultCoordinate: QueryBuilderTDSResultCellCoordinate,
|
696
|
-
): boolean =>
|
697
|
-
resultState.selectedCells.some(
|
698
|
-
(cell) =>
|
699
|
-
cell.coordinates.rowIndex === resultCoordinate.rowIndex &&
|
700
|
-
cell.coordinates.colIndex === resultCoordinate.colIndex,
|
701
|
-
);
|
702
|
-
|
703
|
-
const mouseDown: React.MouseEventHandler = (event) => {
|
704
|
-
event.preventDefault();
|
705
|
-
|
706
|
-
if (event.shiftKey) {
|
707
|
-
const coordinates = findCoordinatesFromResultValue(
|
708
|
-
columnName,
|
709
|
-
params.rowIndex,
|
710
|
-
);
|
711
|
-
const actualValue = findResultValueFromCoordinates([
|
712
|
-
coordinates.rowIndex,
|
713
|
-
coordinates.colIndex,
|
714
|
-
]);
|
715
|
-
resultState.addSelectedCell({
|
716
|
-
value: actualValue,
|
717
|
-
columnName: columnName,
|
718
|
-
coordinates: coordinates,
|
719
|
-
});
|
720
|
-
return;
|
721
|
-
}
|
722
|
-
|
723
|
-
if (event.button === 0) {
|
724
|
-
resultState.setIsSelectingCells(true);
|
725
|
-
resultState.setSelectedCells([]);
|
726
|
-
const coordinates = findCoordinatesFromResultValue(
|
727
|
-
columnName,
|
728
|
-
params.rowIndex,
|
729
|
-
);
|
730
|
-
const actualValue = findResultValueFromCoordinates([
|
731
|
-
coordinates.rowIndex,
|
732
|
-
coordinates.colIndex,
|
733
|
-
]);
|
734
|
-
resultState.setSelectedCells([
|
735
|
-
{
|
736
|
-
value: actualValue,
|
737
|
-
columnName: columnName,
|
738
|
-
coordinates: coordinates,
|
739
|
-
},
|
740
|
-
]);
|
741
|
-
resultState.setMouseOverCell(resultState.selectedCells[0] ?? null);
|
742
|
-
}
|
743
|
-
|
744
|
-
if (event.button === 2) {
|
745
|
-
const coordinates = findCoordinatesFromResultValue(
|
746
|
-
columnName,
|
747
|
-
params.rowIndex,
|
748
|
-
);
|
749
|
-
const isInSelected = isCoordinatesSelected(coordinates);
|
750
|
-
if (!isInSelected) {
|
751
|
-
const actualValue = findResultValueFromCoordinates([
|
752
|
-
coordinates.rowIndex,
|
753
|
-
coordinates.colIndex,
|
754
|
-
]);
|
755
|
-
resultState.setSelectedCells([
|
756
|
-
{
|
757
|
-
value: actualValue,
|
758
|
-
columnName: columnName,
|
759
|
-
coordinates: coordinates,
|
760
|
-
},
|
761
|
-
]);
|
762
|
-
resultState.setMouseOverCell(resultState.selectedCells[0] ?? null);
|
763
|
-
}
|
764
|
-
}
|
765
|
-
};
|
766
|
-
|
767
|
-
const mouseUp: React.MouseEventHandler = (event) => {
|
768
|
-
resultState.setIsSelectingCells(false);
|
769
|
-
};
|
770
|
-
|
771
|
-
const mouseOver: React.MouseEventHandler = (event) => {
|
772
|
-
if (resultState.isSelectingCells) {
|
773
|
-
if (resultState.selectedCells.length < 1) {
|
774
|
-
return;
|
775
|
-
}
|
776
|
-
const results = resultState.selectedCells[0];
|
777
|
-
if (!results) {
|
778
|
-
return;
|
779
|
-
}
|
780
|
-
|
781
|
-
const firstCorner = results.coordinates;
|
782
|
-
const secondCorner = findCoordinatesFromResultValue(
|
783
|
-
columnName,
|
784
|
-
params.rowIndex,
|
785
|
-
);
|
786
|
-
|
787
|
-
resultState.setSelectedCells([results]);
|
788
|
-
|
789
|
-
const minRow = Math.min(firstCorner.rowIndex, secondCorner.rowIndex);
|
790
|
-
const minCol = Math.min(firstCorner.colIndex, secondCorner.colIndex);
|
791
|
-
const maxRow = Math.max(firstCorner.rowIndex, secondCorner.rowIndex);
|
792
|
-
const maxCol = Math.max(firstCorner.colIndex, secondCorner.colIndex);
|
793
|
-
|
794
|
-
for (let x = minRow; x <= maxRow; x++) {
|
795
|
-
for (let y = minCol; y <= maxCol; y++) {
|
796
|
-
const actualValue = findResultValueFromCoordinates([x, y]);
|
797
|
-
|
798
|
-
const valueAndColumnId = {
|
799
|
-
value: actualValue,
|
800
|
-
columnName: findColumnFromCoordinates(y),
|
801
|
-
coordinates: {
|
802
|
-
rowIndex: x,
|
803
|
-
colIndex: y,
|
804
|
-
},
|
805
|
-
} as QueryBuilderTDSResultCellData;
|
806
|
-
|
807
|
-
if (
|
808
|
-
!resultState.selectedCells.find(
|
809
|
-
(result) =>
|
810
|
-
result.coordinates.colIndex === y &&
|
811
|
-
result.coordinates.rowIndex === x,
|
812
|
-
)
|
813
|
-
) {
|
814
|
-
resultState.addSelectedCell(valueAndColumnId);
|
815
|
-
}
|
816
|
-
}
|
817
|
-
}
|
818
|
-
}
|
819
|
-
|
820
|
-
resultState.setMouseOverCell(resultState.selectedCells[0] ?? null);
|
821
|
-
};
|
822
|
-
|
823
|
-
return (
|
824
|
-
<ContextMenu
|
825
|
-
content={
|
826
|
-
// NOTE: we only support this functionality for grid result with a projection fetch-structure
|
827
|
-
fetchStructureImplementation instanceof QueryBuilderTDSState ? (
|
828
|
-
<QueryBuilderGridResultContextMenu
|
829
|
-
data={resultState.mousedOverCell}
|
830
|
-
tdsState={fetchStructureImplementation}
|
831
|
-
dataGridApi={params.api}
|
832
|
-
/>
|
833
|
-
) : null
|
834
|
-
}
|
835
|
-
disabled={
|
836
|
-
!(
|
837
|
-
resultState.queryBuilderState.fetchStructureState
|
838
|
-
.implementation instanceof QueryBuilderTDSState
|
839
|
-
) ||
|
840
|
-
!resultState.queryBuilderState.isQuerySupported ||
|
841
|
-
!resultState.mousedOverCell
|
842
|
-
}
|
843
|
-
menuProps={{ elevation: 7 }}
|
844
|
-
className={clsx('ag-theme-balham-dark query-builder__result__tds-grid')}
|
845
|
-
>
|
846
|
-
<div
|
847
|
-
className={clsx('query-builder__result__values__table__cell', {
|
848
|
-
'query-builder__result__values__table__cell--active':
|
849
|
-
cellInFilteredResults,
|
850
|
-
})}
|
851
|
-
onMouseDown={(event) => mouseDown(event)}
|
852
|
-
onMouseUp={(event) => mouseUp(event)}
|
853
|
-
onMouseOver={(event) => mouseOver(event)}
|
854
|
-
>
|
855
|
-
{cellValueUrlLink ? (
|
856
|
-
<a href={cellValueUrlLink} target="_blank" rel="noreferrer">
|
857
|
-
{cellValueUrlLink}
|
858
|
-
</a>
|
859
|
-
) : (
|
860
|
-
<span>{formattedCellValue()}</span>
|
861
|
-
)}
|
862
|
-
</div>
|
863
|
-
</ContextMenu>
|
864
|
-
);
|
865
|
-
},
|
866
|
-
);
|