@finos/legend-data-cube 0.1.1 → 0.1.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/__lib__/DataCubeSetting.d.ts +1 -0
- package/lib/__lib__/DataCubeSetting.d.ts.map +1 -1
- package/lib/__lib__/DataCubeSetting.js +1 -0
- package/lib/__lib__/DataCubeSetting.js.map +1 -1
- package/lib/components/DataCubeStatusBar.d.ts.map +1 -1
- package/lib/components/DataCubeStatusBar.js +10 -3
- package/lib/components/DataCubeStatusBar.js.map +1 -1
- package/lib/components/DataCubeTitleBar.js +1 -1
- package/lib/components/DataCubeTitleBar.js.map +1 -1
- package/lib/components/core/DataCubeAlert.js +1 -1
- package/lib/components/core/DataCubeAlert.js.map +1 -1
- package/lib/components/view/grid/DataCubeGrid.d.ts.map +1 -1
- package/lib/components/view/grid/DataCubeGrid.js +10 -4
- package/lib/components/view/grid/DataCubeGrid.js.map +1 -1
- package/lib/index.css +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/core/DataCubeEngine.d.ts +5 -1
- package/lib/stores/core/DataCubeEngine.d.ts.map +1 -1
- package/lib/stores/core/DataCubeEngine.js +1 -1
- package/lib/stores/core/DataCubeEngine.js.map +1 -1
- package/lib/stores/services/DataCubeSettingService.d.ts.map +1 -1
- package/lib/stores/services/DataCubeSettingService.js +8 -0
- package/lib/stores/services/DataCubeSettingService.js.map +1 -1
- package/lib/stores/services/DataCubeTaskService.d.ts +4 -4
- package/lib/stores/services/DataCubeTaskService.d.ts.map +1 -1
- package/lib/stores/services/DataCubeTaskService.js +7 -7
- package/lib/stores/services/DataCubeTaskService.js.map +1 -1
- package/lib/stores/view/DataCubeViewState.d.ts.map +1 -1
- package/lib/stores/view/DataCubeViewState.js +11 -4
- package/lib/stores/view/DataCubeViewState.js.map +1 -1
- package/lib/stores/view/editor/DataCubeEditorState.js +1 -1
- package/lib/stores/view/editor/DataCubeEditorState.js.map +1 -1
- package/lib/stores/view/extend/DataCubeExtendManagerState.js +2 -2
- package/lib/stores/view/extend/DataCubeExtendManagerState.js.map +1 -1
- package/lib/stores/view/grid/DataCubeGridClientEngine.d.ts.map +1 -1
- package/lib/stores/view/grid/DataCubeGridClientEngine.js +108 -114
- package/lib/stores/view/grid/DataCubeGridClientEngine.js.map +1 -1
- package/lib/stores/view/grid/DataCubeGridConfigurationBuilder.d.ts.map +1 -1
- package/lib/stores/view/grid/DataCubeGridConfigurationBuilder.js +3 -3
- package/lib/stores/view/grid/DataCubeGridConfigurationBuilder.js.map +1 -1
- package/lib/stores/view/grid/DataCubeGridState.d.ts.map +1 -1
- package/lib/stores/view/grid/DataCubeGridState.js +59 -14
- package/lib/stores/view/grid/DataCubeGridState.js.map +1 -1
- package/package.json +5 -5
- package/src/__lib__/DataCubeSetting.ts +1 -0
- package/src/components/DataCubeStatusBar.tsx +18 -3
- package/src/components/DataCubeTitleBar.tsx +3 -3
- package/src/components/core/DataCubeAlert.tsx +1 -1
- package/src/components/view/grid/DataCubeGrid.tsx +15 -2
- package/src/stores/core/DataCubeEngine.tsx +6 -0
- package/src/stores/services/DataCubeSettingService.tsx +8 -0
- package/src/stores/services/DataCubeTaskService.ts +7 -7
- package/src/stores/view/DataCubeViewState.ts +15 -4
- package/src/stores/view/editor/DataCubeEditorState.tsx +1 -1
- package/src/stores/view/extend/DataCubeExtendManagerState.tsx +2 -2
- package/src/stores/view/grid/DataCubeGridClientEngine.ts +154 -170
- package/src/stores/view/grid/DataCubeGridConfigurationBuilder.tsx +6 -7
- package/src/stores/view/grid/DataCubeGridState.ts +83 -18
|
@@ -31,11 +31,7 @@ import {
|
|
|
31
31
|
pruneObject,
|
|
32
32
|
} from '@finos/legend-shared';
|
|
33
33
|
import { buildExecutableQuery } from '../../core/DataCubeQueryBuilder.js';
|
|
34
|
-
import {
|
|
35
|
-
PureClientVersion,
|
|
36
|
-
type TabularDataSet,
|
|
37
|
-
V1_Lambda,
|
|
38
|
-
} from '@finos/legend-graph';
|
|
34
|
+
import { PureClientVersion, type TabularDataSet } from '@finos/legend-graph';
|
|
39
35
|
import { makeObservable, observable, runInAction } from 'mobx';
|
|
40
36
|
import type {
|
|
41
37
|
DataCubeConfiguration,
|
|
@@ -46,7 +42,6 @@ import { _findCol, _sortByColName } from '../../core/model/DataCubeColumn.js';
|
|
|
46
42
|
import { isPivotResultColumnName } from '../../core/DataCubeQueryEngine.js';
|
|
47
43
|
import { buildQuerySnapshot } from './DataCubeGridQuerySnapshotBuilder.js';
|
|
48
44
|
import { AlertType } from '../../services/DataCubeAlertService.js';
|
|
49
|
-
import { sum } from 'mathjs';
|
|
50
45
|
import type { DataCubeViewState } from '../DataCubeViewState.js';
|
|
51
46
|
import {
|
|
52
47
|
_aggCountCol,
|
|
@@ -55,6 +50,8 @@ import {
|
|
|
55
50
|
import { _colSpecArrayParam } from '../../core/DataCubeQuerySnapshotBuilderUtils.js';
|
|
56
51
|
import { DataCubeSettingKey } from '../../../__lib__/DataCubeSetting.js';
|
|
57
52
|
import { DEFAULT_ALERT_WINDOW_CONFIG } from '../../services/DataCubeLayoutService.js';
|
|
53
|
+
import type { DataCubeExecutionResult } from '../../core/DataCubeEngine.js';
|
|
54
|
+
import { _lambda } from '../../core/DataCubeQueryBuilderUtils.js';
|
|
58
55
|
|
|
59
56
|
type DataCubeGridClientCellValue = string | number | boolean | null | undefined;
|
|
60
57
|
type DataCubeGridClientRowData = {
|
|
@@ -231,19 +228,17 @@ function buildRowData(
|
|
|
231
228
|
? value
|
|
232
229
|
: INTERNAL__GRID_CLIENT_MISSING_VALUE;
|
|
233
230
|
if (snapshot.data.pivot && snapshot.data.groupBy) {
|
|
234
|
-
row[INTERNAL__GRID_CLIENT_ROW_GROUPING_COUNT_AGG_COLUMN_ID] =
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
(col)
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
).toString(),
|
|
246
|
-
);
|
|
231
|
+
row[INTERNAL__GRID_CLIENT_ROW_GROUPING_COUNT_AGG_COLUMN_ID] =
|
|
232
|
+
result.columns
|
|
233
|
+
.filter(
|
|
234
|
+
(col) =>
|
|
235
|
+
isPivotResultColumnName(col) &&
|
|
236
|
+
col.endsWith(
|
|
237
|
+
INTERNAL__GRID_CLIENT_ROW_GROUPING_COUNT_AGG_COLUMN_ID,
|
|
238
|
+
),
|
|
239
|
+
)
|
|
240
|
+
.map((col) => (row[col] as number | undefined) ?? 0)
|
|
241
|
+
.reduce((a, b) => a + b, 0);
|
|
247
242
|
}
|
|
248
243
|
});
|
|
249
244
|
return row;
|
|
@@ -275,18 +270,20 @@ async function getCastColumns(
|
|
|
275
270
|
},
|
|
276
271
|
});
|
|
277
272
|
|
|
278
|
-
const
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
273
|
+
const result = await view.engine.executeQuery(
|
|
274
|
+
_lambda([], [query]),
|
|
275
|
+
view.source,
|
|
276
|
+
{
|
|
277
|
+
debug: view.settingService.getBooleanValue(
|
|
278
|
+
DataCubeSettingKey.DEBUGGER__ENABLE_DEBUG_MODE,
|
|
279
|
+
),
|
|
280
|
+
clientVersion: view.settingService.getBooleanValue(
|
|
281
|
+
DataCubeSettingKey.DEBUGGER__USE_DEV_CLIENT_PROTOCOL_VERSION,
|
|
282
|
+
)
|
|
283
|
+
? PureClientVersion.VX_X_X
|
|
284
|
+
: undefined,
|
|
285
|
+
},
|
|
286
|
+
);
|
|
290
287
|
|
|
291
288
|
return result.result.builder.columns.map((column) => ({
|
|
292
289
|
name: column.name,
|
|
@@ -324,7 +321,7 @@ export class DataCubeGridClientServerSideDataSource
|
|
|
324
321
|
}
|
|
325
322
|
|
|
326
323
|
async fetchRows(params: IServerSideGetRowsParams<unknown, unknown>) {
|
|
327
|
-
const task = this._view.taskService.newTask('Fetching data');
|
|
324
|
+
const task = this._view.taskService.newTask('Fetching data...');
|
|
328
325
|
|
|
329
326
|
// ------------------------------ SNAPSHOT ------------------------------
|
|
330
327
|
|
|
@@ -394,29 +391,18 @@ export class DataCubeGridClientServerSideDataSource
|
|
|
394
391
|
|
|
395
392
|
// ------------------------------ DATA ------------------------------
|
|
396
393
|
|
|
394
|
+
const executableQuery = buildGridDataFetchExecutableQuery(
|
|
395
|
+
request,
|
|
396
|
+
newSnapshot,
|
|
397
|
+
this._view.source,
|
|
398
|
+
this._view.engine,
|
|
399
|
+
this._grid.isPaginationEnabled,
|
|
400
|
+
);
|
|
401
|
+
let result: DataCubeExecutionResult;
|
|
402
|
+
|
|
397
403
|
try {
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
newSnapshot,
|
|
401
|
-
this._view.source,
|
|
402
|
-
this._view.engine,
|
|
403
|
-
this._grid.isPaginationEnabled,
|
|
404
|
-
);
|
|
405
|
-
const lambda = new V1_Lambda();
|
|
406
|
-
lambda.body.push(executableQuery);
|
|
407
|
-
if (
|
|
408
|
-
this._view.settingService.getBooleanValue(
|
|
409
|
-
DataCubeSettingKey.DEBUGGER__ENABLE_DEBUG_MODE,
|
|
410
|
-
)
|
|
411
|
-
) {
|
|
412
|
-
this._view.engine.debugProcess(
|
|
413
|
-
`Execution Plan`,
|
|
414
|
-
['Query', lambda],
|
|
415
|
-
['Config', `pagination=${this._grid.isPaginationEnabled}`],
|
|
416
|
-
);
|
|
417
|
-
}
|
|
418
|
-
const result = await this._view.engine.executeQuery(
|
|
419
|
-
lambda,
|
|
404
|
+
result = await this._view.engine.executeQuery(
|
|
405
|
+
_lambda([], [executableQuery]),
|
|
420
406
|
this._view.source,
|
|
421
407
|
{
|
|
422
408
|
debug: this._view.settingService.getBooleanValue(
|
|
@@ -429,136 +415,134 @@ export class DataCubeGridClientServerSideDataSource
|
|
|
429
415
|
: undefined,
|
|
430
416
|
},
|
|
431
417
|
);
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
)
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
[
|
|
442
|
-
'Stats',
|
|
443
|
-
`${rowData.length} rows, ${result.result.result.columns.length} columns`,
|
|
444
|
-
],
|
|
445
|
-
['SQL', result.executedSQL],
|
|
446
|
-
['SQL Execution Time', result.executionTime],
|
|
447
|
-
);
|
|
448
|
-
}
|
|
418
|
+
} catch (error) {
|
|
419
|
+
assertErrorThrown(error);
|
|
420
|
+
this._view.alertService.alertError(error, {
|
|
421
|
+
message: `Data Fetch Failure: ${error.message}`,
|
|
422
|
+
});
|
|
423
|
+
this._view.taskService.endTask(task);
|
|
424
|
+
params.fail();
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
449
427
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
428
|
+
const rowData = buildRowData(result.result.result, newSnapshot);
|
|
429
|
+
if (
|
|
430
|
+
this._view.settingService.getBooleanValue(
|
|
431
|
+
DataCubeSettingKey.DEBUGGER__ENABLE_DEBUG_MODE,
|
|
432
|
+
)
|
|
433
|
+
) {
|
|
434
|
+
this._view.engine.debugProcess(
|
|
435
|
+
`Execution`,
|
|
436
|
+
['Query', result.executedQuery],
|
|
437
|
+
[
|
|
438
|
+
'Stats',
|
|
439
|
+
`${rowData.length} rows, ${result.result.result.columns.length} columns`,
|
|
440
|
+
],
|
|
441
|
+
['SQL', result.executedSQL],
|
|
442
|
+
['SQL Execution Time', result.executionTime],
|
|
443
|
+
);
|
|
444
|
+
}
|
|
458
445
|
|
|
459
|
-
|
|
446
|
+
if (this._grid.isPaginationEnabled) {
|
|
447
|
+
params.success({ rowData });
|
|
448
|
+
// only update row count when loading the top-level drilldown data
|
|
449
|
+
if (isTopLevelRequest) {
|
|
450
|
+
runInAction(() => {
|
|
451
|
+
this.rowCount = (request.startRow ?? 0) + rowData.length;
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// toggle no-rows overlay
|
|
456
|
+
if (isTopLevelRequest && request.startRow === 0 && rowData.length === 0) {
|
|
457
|
+
this._grid.client.showNoRowsOverlay();
|
|
458
|
+
} else {
|
|
459
|
+
this._grid.client.hideOverlay();
|
|
460
|
+
}
|
|
461
|
+
} else {
|
|
462
|
+
// NOTE: When pagination is disabled and the user currently scrolls to somewhere in the grid, as data is fetched
|
|
463
|
+
// and the operation does not force a scroll top (for example, grouping will always force scrolling to the
|
|
464
|
+
// top, while sorting will leave scroll position as is), the grid ends up showing the wrong data because
|
|
465
|
+
// the data being displayed does not take into account the scroll position, but by the start and end row
|
|
466
|
+
// which stay constant as pagination is disabled.
|
|
467
|
+
//
|
|
468
|
+
// In order to handle this, when pagination is disabled, we tune the start and end row by setting the cache block size
|
|
469
|
+
// to a high-enough value (100k-1m). However, ag-grid use cache block size to pre-allocate memory for the rows,
|
|
470
|
+
// which means we must cap/tune this value reasonably to prevent the app from crashing.
|
|
471
|
+
//
|
|
472
|
+
// When there are just too many rows (exceeding the maximum cache block size), we will fallback to a slightly less ideal
|
|
473
|
+
// behavior by forcing a scroll top for every data fetch and also reset the cache block size to the default value to save memory
|
|
474
|
+
if (rowData.length > INTERNAL__GRID_CLIENT_MAX_CACHE_BLOCK_SIZE) {
|
|
460
475
|
if (
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
476
|
+
!this._view.settingService.getBooleanValue(
|
|
477
|
+
DataCubeSettingKey.GRID_CLIENT__SUPPRESS_LARGE_DATASET_WARNING,
|
|
478
|
+
)
|
|
464
479
|
) {
|
|
465
|
-
this.
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
// which stay constant as pagination is disabled.
|
|
475
|
-
//
|
|
476
|
-
// In order to handle this, when pagination is disabled, we tune the start and end row by setting the cache block size
|
|
477
|
-
// to a high-enough value (100k-1m). However, ag-grid use cache block size to pre-allocate memory for the rows,
|
|
478
|
-
// which means we must cap/tune this value reasonably to prevent the app from crashing.
|
|
479
|
-
//
|
|
480
|
-
// When there are just too many rows (exceeding the maximum cache block size), we will fallback to a slightly less ideal
|
|
481
|
-
// behavior by forcing a scroll top for every data fetch and also reset the cache block size to the default value to save memory
|
|
482
|
-
if (rowData.length > INTERNAL__GRID_CLIENT_MAX_CACHE_BLOCK_SIZE) {
|
|
483
|
-
if (
|
|
484
|
-
!this._view.settingService.getBooleanValue(
|
|
485
|
-
DataCubeSettingKey.GRID_CLIENT__SUPPRESS_LARGE_DATASET_WARNING,
|
|
486
|
-
)
|
|
487
|
-
) {
|
|
488
|
-
this._view.alertService.alert({
|
|
489
|
-
message: `Large dataset (>${INTERNAL__GRID_CLIENT_MAX_CACHE_BLOCK_SIZE} rows) detected!`,
|
|
490
|
-
text: `Overall app performance can be impacted by large dataset due to longer query execution time and increased memory usage. At its limit, the engine can crash!\nTo boost performance, consider enabling pagination while working with large dataset.`,
|
|
491
|
-
type: AlertType.WARNING,
|
|
492
|
-
actions: [
|
|
493
|
-
{
|
|
494
|
-
label: 'Enable Pagination',
|
|
495
|
-
handler: () => {
|
|
496
|
-
this._grid.setPaginationEnabled(true);
|
|
497
|
-
},
|
|
480
|
+
this._view.alertService.alert({
|
|
481
|
+
message: `Large dataset (>${INTERNAL__GRID_CLIENT_MAX_CACHE_BLOCK_SIZE} rows) detected!`,
|
|
482
|
+
text: `Overall app performance can be impacted by large dataset due to longer query execution time and increased memory usage. At its limit, the engine can crash!\nTo boost performance, consider enabling pagination while working with large dataset.`,
|
|
483
|
+
type: AlertType.WARNING,
|
|
484
|
+
actions: [
|
|
485
|
+
{
|
|
486
|
+
label: 'Enable Pagination',
|
|
487
|
+
handler: () => {
|
|
488
|
+
this._grid.setPaginationEnabled(true);
|
|
498
489
|
},
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
490
|
+
},
|
|
491
|
+
{
|
|
492
|
+
label: 'Dismiss Warning',
|
|
493
|
+
handler: () => {
|
|
494
|
+
this._view.settingService.updateValue(
|
|
495
|
+
this._view.dataCube.api,
|
|
496
|
+
DataCubeSettingKey.GRID_CLIENT__SUPPRESS_LARGE_DATASET_WARNING,
|
|
497
|
+
true,
|
|
498
|
+
);
|
|
508
499
|
},
|
|
509
|
-
],
|
|
510
|
-
windowConfig: {
|
|
511
|
-
...DEFAULT_ALERT_WINDOW_CONFIG,
|
|
512
|
-
width: 600,
|
|
513
|
-
minWidth: 300,
|
|
514
|
-
minHeight: 150,
|
|
515
500
|
},
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
params.success({
|
|
524
|
-
rowData,
|
|
525
|
-
// Setting row count to disable infinite-scrolling when pagination is disabled
|
|
526
|
-
// See https://www.ag-grid.com/react-data-grid/infinite-scrolling/#setting-last-row-index
|
|
527
|
-
rowCount: rowData.length,
|
|
528
|
-
});
|
|
529
|
-
|
|
530
|
-
// only update row count when loading the top-level drilldown data
|
|
531
|
-
if (isTopLevelRequest) {
|
|
532
|
-
runInAction(() => {
|
|
533
|
-
this.rowCount = rowData.length;
|
|
501
|
+
],
|
|
502
|
+
windowConfig: {
|
|
503
|
+
...DEFAULT_ALERT_WINDOW_CONFIG,
|
|
504
|
+
width: 600,
|
|
505
|
+
minWidth: 300,
|
|
506
|
+
minHeight: 150,
|
|
507
|
+
},
|
|
534
508
|
});
|
|
535
509
|
}
|
|
536
510
|
|
|
537
|
-
//
|
|
538
|
-
|
|
539
|
-
this._grid.client.showNoRowsOverlay();
|
|
540
|
-
} else {
|
|
541
|
-
this._grid.client.hideOverlay();
|
|
542
|
-
}
|
|
511
|
+
// NOTE: when drilldown occurs, we will scroll top until the drilldown row is reached
|
|
512
|
+
params.api.ensureIndexVisible(params.parentNode.rowIndex ?? 0, 'top');
|
|
543
513
|
}
|
|
544
514
|
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
setTimeout(() => {
|
|
551
|
-
this._grid.client.autoSizeAllColumns();
|
|
552
|
-
}, 0);
|
|
553
|
-
} catch (error) {
|
|
554
|
-
assertErrorThrown(error);
|
|
555
|
-
this._view.alertService.alertError(error, {
|
|
556
|
-
message: `Data Fetch Failure: ${error.message}`,
|
|
515
|
+
params.success({
|
|
516
|
+
rowData,
|
|
517
|
+
// Setting row count to disable infinite-scrolling when pagination is disabled
|
|
518
|
+
// See https://www.ag-grid.com/react-data-grid/infinite-scrolling/#setting-last-row-index
|
|
519
|
+
rowCount: rowData.length,
|
|
557
520
|
});
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
521
|
+
|
|
522
|
+
// only update row count when loading the top-level drilldown data
|
|
523
|
+
if (isTopLevelRequest) {
|
|
524
|
+
runInAction(() => {
|
|
525
|
+
this.rowCount = rowData.length;
|
|
526
|
+
});
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
// toggle no-rows overlay
|
|
530
|
+
if (isTopLevelRequest && rowData.length === 0) {
|
|
531
|
+
this._grid.client.showNoRowsOverlay();
|
|
532
|
+
} else {
|
|
533
|
+
this._grid.client.hideOverlay();
|
|
534
|
+
}
|
|
561
535
|
}
|
|
536
|
+
|
|
537
|
+
// Resize columns to fit content on all actions (drilldown, changing queries, fetching new page, etc.)
|
|
538
|
+
// NOTE: we might want to restrict this to only happen on certain actions
|
|
539
|
+
//
|
|
540
|
+
// `setTimeout()` is need to ensure this runs after the grid has been updated with the new data
|
|
541
|
+
// since ag-grid does not provide an event hook for this action for server-side row model.
|
|
542
|
+
setTimeout(() => {
|
|
543
|
+
this._grid.client.autoSizeAllColumns();
|
|
544
|
+
}, 0);
|
|
545
|
+
this._view.taskService.endTask(task);
|
|
562
546
|
}
|
|
563
547
|
|
|
564
548
|
getRows(params: IServerSideGetRowsParams<unknown, unknown>) {
|
|
@@ -62,7 +62,6 @@ import {
|
|
|
62
62
|
} from './DataCubeGridClientEngine.js';
|
|
63
63
|
import {
|
|
64
64
|
at,
|
|
65
|
-
last,
|
|
66
65
|
getQueryParameters,
|
|
67
66
|
getQueryParameterValue,
|
|
68
67
|
isNonNullable,
|
|
@@ -758,15 +757,15 @@ function generateDefinitionForPivotResultColumns(
|
|
|
758
757
|
|
|
759
758
|
// sort the leaf level columns based on the order of selected/configuration columns
|
|
760
759
|
(currentCollection as ColDef[]).sort((a, b) => {
|
|
761
|
-
const colAName =
|
|
762
|
-
a.colId?.split(PIVOT_COLUMN_NAME_VALUE_SEPARATOR) ?? []
|
|
763
|
-
);
|
|
760
|
+
const colAName = (
|
|
761
|
+
a.colId?.split(PIVOT_COLUMN_NAME_VALUE_SEPARATOR) ?? []
|
|
762
|
+
).at(-1);
|
|
764
763
|
const colAConf = colAName
|
|
765
764
|
? _findCol(configuration.columns, colAName)
|
|
766
765
|
: undefined;
|
|
767
|
-
const colBName =
|
|
768
|
-
b.colId?.split(PIVOT_COLUMN_NAME_VALUE_SEPARATOR) ?? []
|
|
769
|
-
);
|
|
766
|
+
const colBName = (
|
|
767
|
+
b.colId?.split(PIVOT_COLUMN_NAME_VALUE_SEPARATOR) ?? []
|
|
768
|
+
).at(-1);
|
|
770
769
|
const colBConf = colBName
|
|
771
770
|
? _findCol(configuration.columns, colBName)
|
|
772
771
|
: undefined;
|
|
@@ -38,6 +38,8 @@ import { DataCubeConfiguration } from '../../core/model/DataCubeConfiguration.js
|
|
|
38
38
|
import { DataCubeGridControllerState } from './DataCubeGridControllerState.js';
|
|
39
39
|
import { DataCubeGridClientExportEngine } from './DataCubeGridClientExportEngine.js';
|
|
40
40
|
import { DataCubeSettingKey } from '../../../__lib__/DataCubeSetting.js';
|
|
41
|
+
import { DEFAULT_ALERT_WINDOW_CONFIG } from '../../services/DataCubeLayoutService.js';
|
|
42
|
+
import { AlertType } from '../../services/DataCubeAlertService.js';
|
|
41
43
|
|
|
42
44
|
/**
|
|
43
45
|
* This query editor state is responsible for syncing the internal state of ag-grid
|
|
@@ -125,32 +127,95 @@ export class DataCubeGridState extends DataCubeQuerySnapshotController {
|
|
|
125
127
|
}
|
|
126
128
|
|
|
127
129
|
async setCachingEnabled(val: boolean) {
|
|
128
|
-
|
|
129
|
-
if (val === currentVal) {
|
|
130
|
+
if (val === this.isCachingEnabled) {
|
|
130
131
|
return;
|
|
131
132
|
}
|
|
132
133
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
134
|
+
// disable caching
|
|
135
|
+
if (val === false) {
|
|
136
|
+
await this._view.disposeCache();
|
|
137
|
+
|
|
138
|
+
runInAction(() => {
|
|
139
|
+
this.isCachingEnabled = val;
|
|
136
140
|
|
|
137
|
-
|
|
141
|
+
// hard reset the grid, this will force the grid to fetch data again
|
|
142
|
+
this.clientDataSource = new DataCubeGridClientServerSideDataSource(
|
|
143
|
+
this,
|
|
144
|
+
this._view,
|
|
145
|
+
);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// enable caching
|
|
152
|
+
const run = async () => {
|
|
138
153
|
await this._view.initializeCache();
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
154
|
+
|
|
155
|
+
// only update value if cache processing succeeds
|
|
156
|
+
if (this._view.processCacheState.hasSucceeded) {
|
|
157
|
+
runInAction(() => {
|
|
158
|
+
this.isCachingEnabled = val;
|
|
159
|
+
|
|
160
|
+
// hard reset the grid, this will force the grid to fetch data again
|
|
161
|
+
this.clientDataSource = new DataCubeGridClientServerSideDataSource(
|
|
162
|
+
this,
|
|
163
|
+
this._view,
|
|
164
|
+
);
|
|
165
|
+
});
|
|
142
166
|
}
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
// TODO?: we might want to do a quick check here for the amount of data the cache
|
|
170
|
+
// will handle, so maybe fire a COUNT query to check for the number of records
|
|
171
|
+
// and check that against a threshold, we will need to alter the prompt below accordingly.
|
|
172
|
+
if (
|
|
173
|
+
this._settingService.getBooleanValue(
|
|
174
|
+
DataCubeSettingKey.GRID_CLIENT__SHOW_CACHE_PERFORMANCE_WARNING,
|
|
175
|
+
)
|
|
176
|
+
) {
|
|
177
|
+
this._view.alertService.alert({
|
|
178
|
+
message: `Confirm you want to proceed with caching`,
|
|
179
|
+
text: `When enabled, the source dataset will be cached locally in order to boost query performance. But depending on computational resource available to your environment, sometimes, caching can negatively impact the overall performance, and can even lead to crashes.\nDo you still want to proceed?`,
|
|
180
|
+
type: AlertType.WARNING,
|
|
181
|
+
actions: [
|
|
182
|
+
{
|
|
183
|
+
label: 'Abort',
|
|
184
|
+
handler: () => {},
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
label: 'Proceed',
|
|
188
|
+
handler: () => {
|
|
189
|
+
run().catch((error) =>
|
|
190
|
+
this._view.alertService.alertUnhandledError(error),
|
|
191
|
+
);
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
label: 'Dismiss Warning and Proceed',
|
|
196
|
+
handler: () => {
|
|
197
|
+
this._view.settingService.updateValue(
|
|
198
|
+
this._view.dataCube.api,
|
|
199
|
+
DataCubeSettingKey.GRID_CLIENT__SHOW_CACHE_PERFORMANCE_WARNING,
|
|
200
|
+
false,
|
|
201
|
+
);
|
|
202
|
+
run().catch((error) =>
|
|
203
|
+
this._view.alertService.alertUnhandledError(error),
|
|
204
|
+
);
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
],
|
|
208
|
+
windowConfig: {
|
|
209
|
+
...DEFAULT_ALERT_WINDOW_CONFIG,
|
|
210
|
+
width: 600,
|
|
211
|
+
height: 210,
|
|
212
|
+
minWidth: 300,
|
|
213
|
+
minHeight: 150,
|
|
214
|
+
},
|
|
215
|
+
});
|
|
143
216
|
} else {
|
|
144
|
-
await
|
|
217
|
+
await run();
|
|
145
218
|
}
|
|
146
|
-
|
|
147
|
-
runInAction(() => {
|
|
148
|
-
// hard reset the grid, this will force the grid to fetch data again
|
|
149
|
-
this.clientDataSource = new DataCubeGridClientServerSideDataSource(
|
|
150
|
-
this,
|
|
151
|
-
this._view,
|
|
152
|
-
);
|
|
153
|
-
});
|
|
154
219
|
}
|
|
155
220
|
|
|
156
221
|
setScrollHintText(val: string | undefined) {
|