@finos/legend-query-builder 4.10.1 → 4.11.0
Sign up to get free protection for your applications and to get access to all the features.
- package/lib/__lib__/QueryBuilderDocumentation.d.ts +2 -1
- package/lib/__lib__/QueryBuilderDocumentation.d.ts.map +1 -1
- package/lib/__lib__/QueryBuilderDocumentation.js +1 -0
- package/lib/__lib__/QueryBuilderDocumentation.js.map +1 -1
- package/lib/__lib__/QueryBuilderEvent.d.ts +2 -1
- package/lib/__lib__/QueryBuilderEvent.d.ts.map +1 -1
- package/lib/__lib__/QueryBuilderEvent.js +1 -0
- package/lib/__lib__/QueryBuilderEvent.js.map +1 -1
- package/lib/components/QueryBuilderResultPanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderResultPanel.js +165 -57
- package/lib/components/QueryBuilderResultPanel.js.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.d.ts.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.js +2 -1
- package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.js.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.js +1 -1
- package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.js.map +1 -1
- package/lib/graph/QueryBuilderMetaModelConst.d.ts +22 -1
- package/lib/graph/QueryBuilderMetaModelConst.d.ts.map +1 -1
- package/lib/graph/QueryBuilderMetaModelConst.js +24 -0
- package/lib/graph/QueryBuilderMetaModelConst.js.map +1 -1
- package/lib/index.css +2 -2
- package/lib/index.css.map +1 -1
- package/lib/index.d.ts +2 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -1
- package/lib/index.js.map +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/QueryBuilderPreviewDataHelper.d.ts.map +1 -1
- package/lib/stores/QueryBuilderPreviewDataHelper.js +2 -1
- package/lib/stores/QueryBuilderPreviewDataHelper.js.map +1 -1
- package/lib/stores/QueryBuilderResultState.d.ts +8 -3
- package/lib/stores/QueryBuilderResultState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderResultState.js +11 -30
- package/lib/stores/QueryBuilderResultState.js.map +1 -1
- package/lib/stores/QueryBuilderState.d.ts +2 -0
- package/lib/stores/QueryBuilderState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderState.js +8 -0
- package/lib/stores/QueryBuilderState.js.map +1 -1
- package/lib/stores/QueryBuilderTypeaheadHelper.d.ts.map +1 -1
- package/lib/stores/QueryBuilderTypeaheadHelper.js +1 -1
- package/lib/stores/QueryBuilderTypeaheadHelper.js.map +1 -1
- package/lib/stores/fetch-structure/tds/QueryBuilderTDSHelper.d.ts +4 -1
- package/lib/stores/fetch-structure/tds/QueryBuilderTDSHelper.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/QueryBuilderTDSHelper.js +37 -3
- package/lib/stores/fetch-structure/tds/QueryBuilderTDSHelper.js.map +1 -1
- package/lib/stores/fetch-structure/tds/QueryResultSetModifierState.d.ts +1 -4
- package/lib/stores/fetch-structure/tds/QueryResultSetModifierState.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/QueryResultSetModifierState.js +1 -5
- package/lib/stores/fetch-structure/tds/QueryResultSetModifierState.js.map +1 -1
- package/lib/stores/fetch-structure/tds/aggregation/QueryBuilderAggregateOperator.d.ts +1 -1
- package/lib/stores/fetch-structure/tds/aggregation/QueryBuilderAggregateOperator.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/aggregation/QueryBuilderAggregateOperator.js +2 -2
- package/lib/stores/fetch-structure/tds/aggregation/QueryBuilderAggregateOperator.js.map +1 -1
- package/lib/stores/fetch-structure/tds/aggregation/QueryBuilderAggregationState.d.ts +3 -2
- package/lib/stores/fetch-structure/tds/aggregation/QueryBuilderAggregationState.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/aggregation/QueryBuilderAggregationState.js +9 -0
- package/lib/stores/fetch-structure/tds/aggregation/QueryBuilderAggregationState.js.map +1 -1
- package/lib/stores/fetch-structure/tds/aggregation/operators/QueryBuilderAggregateOperator_DistinctCount.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/aggregation/operators/QueryBuilderAggregateOperator_DistinctCount.js +2 -4
- package/lib/stores/fetch-structure/tds/aggregation/operators/QueryBuilderAggregateOperator_DistinctCount.js.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterOperator.d.ts +2 -1
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterOperator.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.d.ts +1 -15
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js +3 -44
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterStateBuilder.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterStateBuilder.js +13 -3
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterStateBuilder.js.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperatorValueSpecificationBuilder.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperatorValueSpecificationBuilder.js +3 -2
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperatorValueSpecificationBuilder.js.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_IsEmpty.d.ts +2 -1
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_IsEmpty.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_IsEmpty.js +2 -1
- package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_IsEmpty.js.map +1 -1
- package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionStateBuilder.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionStateBuilder.js +2 -2
- package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionStateBuilder.js.map +1 -1
- package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.js +3 -10
- package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.js.map +1 -1
- package/lib/stores/fetch-structure/tds/window/QueryBuilderWindowState.d.ts +1 -1
- package/lib/stores/fetch-structure/tds/window/QueryBuilderWindowState.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/__lib__/QueryBuilderDocumentation.ts +1 -0
- package/src/__lib__/QueryBuilderEvent.ts +1 -0
- package/src/components/QueryBuilderResultPanel.tsx +269 -90
- package/src/components/fetch-structure/QueryBuilderResultModifierPanel.tsx +2 -4
- package/src/components/fetch-structure/QueryBuilderTDSWindowPanel.tsx +1 -1
- package/src/graph/QueryBuilderMetaModelConst.ts +25 -0
- package/src/index.ts +9 -2
- package/src/stores/QueryBuilderPreviewDataHelper.ts +2 -4
- package/src/stores/QueryBuilderResultState.ts +17 -34
- package/src/stores/QueryBuilderState.ts +12 -0
- package/src/stores/QueryBuilderTypeaheadHelper.ts +2 -4
- package/src/stores/fetch-structure/tds/QueryBuilderTDSHelper.ts +58 -2
- package/src/stores/fetch-structure/tds/QueryResultSetModifierState.ts +1 -5
- package/src/stores/fetch-structure/tds/aggregation/QueryBuilderAggregateOperator.ts +5 -9
- package/src/stores/fetch-structure/tds/aggregation/QueryBuilderAggregationState.ts +16 -2
- package/src/stores/fetch-structure/tds/aggregation/operators/QueryBuilderAggregateOperator_DistinctCount.ts +2 -4
- package/src/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterOperator.ts +1 -1
- package/src/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.ts +1 -50
- package/src/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterStateBuilder.ts +22 -4
- package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperatorValueSpecificationBuilder.ts +4 -4
- package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_IsEmpty.ts +1 -1
- package/src/stores/fetch-structure/tds/projection/QueryBuilderProjectionStateBuilder.ts +5 -5
- package/src/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.ts +5 -15
- package/src/stores/fetch-structure/tds/window/QueryBuilderWindowState.ts +1 -1
@@ -37,6 +37,8 @@ import {
|
|
37
37
|
ModalFooterButton,
|
38
38
|
ModalHeader,
|
39
39
|
PanelDivider,
|
40
|
+
SquareIcon,
|
41
|
+
CheckSquareIcon,
|
40
42
|
} from '@finos/legend-art';
|
41
43
|
import { format as formatSQL } from 'sql-formatter';
|
42
44
|
import { observer } from 'mobx-react-lite';
|
@@ -52,6 +54,8 @@ import {
|
|
52
54
|
EnumValueInstanceValue,
|
53
55
|
EnumValueExplicitReference,
|
54
56
|
RelationalExecutionActivities,
|
57
|
+
getTDSRowRankByColumnInAsc,
|
58
|
+
PRIMITIVE_TYPE,
|
55
59
|
} from '@finos/legend-graph';
|
56
60
|
import {
|
57
61
|
ActionAlertActionType,
|
@@ -62,6 +66,8 @@ import {
|
|
62
66
|
import {
|
63
67
|
assertErrorThrown,
|
64
68
|
guaranteeNonNullable,
|
69
|
+
isBoolean,
|
70
|
+
type PlainObject,
|
65
71
|
prettyDuration,
|
66
72
|
filterByType,
|
67
73
|
isValidURL,
|
@@ -97,6 +103,7 @@ import { PARAMETER_SUBMIT_ACTION } from '../stores/shared/LambdaParameterState.j
|
|
97
103
|
import { QUERY_BUILDER_TEST_ID } from '../__lib__/QueryBuilderTesting.js';
|
98
104
|
import {
|
99
105
|
DataGrid,
|
106
|
+
type DataGridColumnApi,
|
100
107
|
type DataGridCellRendererParams,
|
101
108
|
type DataGridColumnDefinition,
|
102
109
|
} from '@finos/legend-lego/data-grid';
|
@@ -116,6 +123,8 @@ import {
|
|
116
123
|
} from '../stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_IsEmpty.js';
|
117
124
|
import { QueryUsageViewer } from './QueryUsageViewer.js';
|
118
125
|
import { DEFAULT_LOCALE } from '../graph-manager/QueryBuilderConst.js';
|
126
|
+
import { DocumentationLink } from '@finos/legend-lego/application';
|
127
|
+
import { QUERY_BUILDER_DOCUMENTATION_KEY } from '../__lib__/QueryBuilderDocumentation.js';
|
119
128
|
|
120
129
|
export const tryToFormatSql = (sql: string): string => {
|
121
130
|
try {
|
@@ -417,7 +426,9 @@ const QueryBuilderGridResultContextMenu = observer(
|
|
417
426
|
),
|
418
427
|
);
|
419
428
|
|
420
|
-
const
|
429
|
+
const findRowFromRowIndex = (
|
430
|
+
rowIndex: number,
|
431
|
+
): (string | number | boolean | null)[] => {
|
421
432
|
if (
|
422
433
|
!tdsState.queryBuilderState.resultState.executionResult ||
|
423
434
|
!(
|
@@ -425,31 +436,21 @@ const QueryBuilderGridResultContextMenu = observer(
|
|
425
436
|
TDSExecutionResult
|
426
437
|
)
|
427
438
|
) {
|
428
|
-
return '';
|
439
|
+
return [''];
|
429
440
|
}
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
.rowIndex,
|
441
|
+
return (
|
442
|
+
tdsState.queryBuilderState.resultState.executionResult.result.rows[
|
443
|
+
rowIndex
|
444
|
+
]?.values ?? ['']
|
435
445
|
);
|
436
|
-
// try to get the entire row value separated by comma
|
437
|
-
// rowData is in format of {columnName: value, columnName1: value, ...., rowNumber:value}
|
438
|
-
const valueArr: (string | number | boolean | null | undefined)[] = [];
|
439
|
-
if (rowData) {
|
440
|
-
Object.entries(rowData).forEach((entry) => {
|
441
|
-
if (entry[0] !== 'rowNumber') {
|
442
|
-
valueArr.push(entry[1]);
|
443
|
-
}
|
444
|
-
});
|
445
|
-
return valueArr.join(',');
|
446
|
-
}
|
447
|
-
return '';
|
448
446
|
};
|
449
447
|
|
450
448
|
const handleCopyRowValue = applicationStore.guardUnhandledError(() =>
|
451
449
|
applicationStore.clipboardService.copyTextToClipboard(
|
452
|
-
|
450
|
+
findRowFromRowIndex(
|
451
|
+
tdsState.queryBuilderState.resultState.selectedCells[0]?.coordinates
|
452
|
+
.rowIndex ?? 0,
|
453
|
+
).toString(),
|
453
454
|
),
|
454
455
|
);
|
455
456
|
|
@@ -507,18 +508,18 @@ const QueryResultCellRenderer = observer(
|
|
507
508
|
isString(cellValue) && isValidURL(cellValue) ? cellValue : undefined;
|
508
509
|
const columnName = params.column?.getColId() ?? '';
|
509
510
|
const findCoordinatesFromResultValue = (
|
510
|
-
|
511
|
+
colId: string,
|
511
512
|
rowNumber: number,
|
512
513
|
): QueryBuilderTDSResultCellCoordinate => {
|
513
514
|
const colIndex = tdsExecutionResult.result.columns.findIndex(
|
514
|
-
(col) => col ===
|
515
|
+
(col) => col === colId,
|
515
516
|
);
|
516
517
|
return { rowIndex: rowNumber, colIndex: colIndex };
|
517
518
|
};
|
518
519
|
|
519
520
|
const currentCellCoordinates = findCoordinatesFromResultValue(
|
520
521
|
columnName,
|
521
|
-
params.
|
522
|
+
params.rowIndex,
|
522
523
|
);
|
523
524
|
const cellInFilteredResults = resultState.selectedCells.some(
|
524
525
|
(result) =>
|
@@ -526,9 +527,9 @@ const QueryResultCellRenderer = observer(
|
|
526
527
|
result.coordinates.rowIndex === currentCellCoordinates.rowIndex,
|
527
528
|
);
|
528
529
|
|
529
|
-
const
|
530
|
+
const findColumnFromCoordinates = (
|
530
531
|
colIndex: number,
|
531
|
-
): string | undefined => {
|
532
|
+
): string | number | boolean | null | undefined => {
|
532
533
|
if (
|
533
534
|
!resultState.executionResult ||
|
534
535
|
!(resultState.executionResult instanceof TDSExecutionResult)
|
@@ -539,12 +540,30 @@ const QueryResultCellRenderer = observer(
|
|
539
540
|
};
|
540
541
|
|
541
542
|
const findResultValueFromCoordinates = (
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
543
|
+
resultCoordinate: [number, number],
|
544
|
+
): string | number | boolean | null | undefined => {
|
545
|
+
const rowIndex = resultCoordinate[0];
|
546
|
+
const colIndex = resultCoordinate[1];
|
547
|
+
|
548
|
+
if (
|
549
|
+
!resultState.executionResult ||
|
550
|
+
!(resultState.executionResult instanceof TDSExecutionResult)
|
551
|
+
) {
|
552
|
+
return undefined;
|
553
|
+
}
|
554
|
+
if (params.columnApi.getColumnState()[colIndex]?.sort === 'asc') {
|
555
|
+
resultState.executionResult.result.rows.sort((a, b) =>
|
556
|
+
getTDSRowRankByColumnInAsc(a, b, colIndex),
|
557
|
+
);
|
558
|
+
} else if (params.columnApi.getColumnState()[colIndex]?.sort === 'desc') {
|
559
|
+
resultState.executionResult.result.rows.sort((a, b) =>
|
560
|
+
getTDSRowRankByColumnInAsc(b, a, colIndex),
|
561
|
+
);
|
562
|
+
}
|
563
|
+
return resultState.executionResult.result.rows[rowIndex]?.values[
|
564
|
+
colIndex
|
565
|
+
];
|
566
|
+
};
|
548
567
|
|
549
568
|
const isCoordinatesSelected = (
|
550
569
|
resultCoordinate: QueryBuilderTDSResultCellCoordinate,
|
@@ -561,12 +580,12 @@ const QueryResultCellRenderer = observer(
|
|
561
580
|
if (event.shiftKey) {
|
562
581
|
const coordinates = findCoordinatesFromResultValue(
|
563
582
|
columnName,
|
564
|
-
params.
|
583
|
+
params.rowIndex,
|
565
584
|
);
|
566
|
-
const actualValue = findResultValueFromCoordinates(
|
585
|
+
const actualValue = findResultValueFromCoordinates([
|
567
586
|
coordinates.rowIndex,
|
568
|
-
|
569
|
-
);
|
587
|
+
coordinates.colIndex,
|
588
|
+
]);
|
570
589
|
resultState.addSelectedCell({
|
571
590
|
value: actualValue,
|
572
591
|
columnName: columnName,
|
@@ -580,12 +599,12 @@ const QueryResultCellRenderer = observer(
|
|
580
599
|
resultState.setSelectedCells([]);
|
581
600
|
const coordinates = findCoordinatesFromResultValue(
|
582
601
|
columnName,
|
583
|
-
params.
|
602
|
+
params.rowIndex,
|
584
603
|
);
|
585
|
-
const actualValue = findResultValueFromCoordinates(
|
604
|
+
const actualValue = findResultValueFromCoordinates([
|
586
605
|
coordinates.rowIndex,
|
587
|
-
|
588
|
-
);
|
606
|
+
coordinates.colIndex,
|
607
|
+
]);
|
589
608
|
resultState.setSelectedCells([
|
590
609
|
{
|
591
610
|
value: actualValue,
|
@@ -599,14 +618,14 @@ const QueryResultCellRenderer = observer(
|
|
599
618
|
if (event.button === 2) {
|
600
619
|
const coordinates = findCoordinatesFromResultValue(
|
601
620
|
columnName,
|
602
|
-
params.
|
621
|
+
params.rowIndex,
|
603
622
|
);
|
604
623
|
const isInSelected = isCoordinatesSelected(coordinates);
|
605
624
|
if (!isInSelected) {
|
606
|
-
const actualValue = findResultValueFromCoordinates(
|
625
|
+
const actualValue = findResultValueFromCoordinates([
|
607
626
|
coordinates.rowIndex,
|
608
|
-
|
609
|
-
);
|
627
|
+
coordinates.colIndex,
|
628
|
+
]);
|
610
629
|
resultState.setSelectedCells([
|
611
630
|
{
|
612
631
|
value: actualValue,
|
@@ -636,7 +655,7 @@ const QueryResultCellRenderer = observer(
|
|
636
655
|
const firstCorner = results.coordinates;
|
637
656
|
const secondCorner = findCoordinatesFromResultValue(
|
638
657
|
columnName,
|
639
|
-
params.
|
658
|
+
params.rowIndex,
|
640
659
|
);
|
641
660
|
|
642
661
|
resultState.setSelectedCells([results]);
|
@@ -648,13 +667,11 @@ const QueryResultCellRenderer = observer(
|
|
648
667
|
|
649
668
|
for (let x = minRow; x <= maxRow; x++) {
|
650
669
|
for (let y = minCol; y <= maxCol; y++) {
|
651
|
-
const actualValue = findResultValueFromCoordinates(
|
652
|
-
|
653
|
-
findColumnNameFromColumnIndex(y) as string,
|
654
|
-
);
|
670
|
+
const actualValue = findResultValueFromCoordinates([x, y]);
|
671
|
+
|
655
672
|
const valueAndColumnId = {
|
656
673
|
value: actualValue,
|
657
|
-
columnName:
|
674
|
+
columnName: findColumnFromCoordinates(y),
|
658
675
|
coordinates: {
|
659
676
|
rowIndex: x,
|
660
677
|
colIndex: y,
|
@@ -673,6 +690,7 @@ const QueryResultCellRenderer = observer(
|
|
673
690
|
}
|
674
691
|
}
|
675
692
|
}
|
693
|
+
|
676
694
|
resultState.setMouseOverCell(resultState.selectedCells[0] ?? null);
|
677
695
|
};
|
678
696
|
|
@@ -720,6 +738,40 @@ const QueryResultCellRenderer = observer(
|
|
720
738
|
},
|
721
739
|
);
|
722
740
|
|
741
|
+
const getColumnCustomizations = (
|
742
|
+
result: TDSExecutionResult,
|
743
|
+
columnName: string,
|
744
|
+
): object | undefined => {
|
745
|
+
const columnType = result.builder.columns.find(
|
746
|
+
(col) => col.name === columnName,
|
747
|
+
)?.type;
|
748
|
+
switch (columnType) {
|
749
|
+
case PRIMITIVE_TYPE.STRING:
|
750
|
+
return {
|
751
|
+
filter: 'agTextColumnFilter',
|
752
|
+
allowedAggFuncs: ['count'],
|
753
|
+
};
|
754
|
+
case PRIMITIVE_TYPE.DATE:
|
755
|
+
case PRIMITIVE_TYPE.DATETIME:
|
756
|
+
case PRIMITIVE_TYPE.STRICTDATE:
|
757
|
+
return {
|
758
|
+
filter: 'agDateColumnFilter',
|
759
|
+
allowedAggFuncs: ['count'],
|
760
|
+
};
|
761
|
+
case PRIMITIVE_TYPE.DECIMAL:
|
762
|
+
case PRIMITIVE_TYPE.INTEGER:
|
763
|
+
case PRIMITIVE_TYPE.FLOAT:
|
764
|
+
return {
|
765
|
+
filter: 'agNumberColumnFilter',
|
766
|
+
allowedAggFuncs: ['count', 'sum', 'max', 'min', 'avg'],
|
767
|
+
};
|
768
|
+
default:
|
769
|
+
return {
|
770
|
+
allowedAggFuncs: ['count'],
|
771
|
+
};
|
772
|
+
}
|
773
|
+
};
|
774
|
+
|
723
775
|
const QueryBuilderGridResult = observer(
|
724
776
|
(props: {
|
725
777
|
executionResult: TDSExecutionResult;
|
@@ -727,7 +779,79 @@ const QueryBuilderGridResult = observer(
|
|
727
779
|
}) => {
|
728
780
|
const { executionResult, queryBuilderState } = props;
|
729
781
|
|
782
|
+
const [columnAPi, setColumnApi] = useState<DataGridColumnApi | undefined>(
|
783
|
+
undefined,
|
784
|
+
);
|
730
785
|
const resultState = queryBuilderState.resultState;
|
786
|
+
const isAdvancedModeEnabled = queryBuilderState.isAdvancedModeEnabled;
|
787
|
+
const colDefs = isAdvancedModeEnabled
|
788
|
+
? executionResult.result.columns.map((colName) => {
|
789
|
+
const col = {
|
790
|
+
minWidth: 50,
|
791
|
+
sortable: true,
|
792
|
+
resizable: true,
|
793
|
+
field: colName,
|
794
|
+
flex: 1,
|
795
|
+
enablePivot: true,
|
796
|
+
enableRowGroup: true,
|
797
|
+
enableValue: true,
|
798
|
+
...getColumnCustomizations(executionResult, colName),
|
799
|
+
} as DataGridColumnDefinition;
|
800
|
+
const persistedColumn = resultState.gridConfig.columns.find(
|
801
|
+
(c) => c.colId === colName,
|
802
|
+
);
|
803
|
+
if (persistedColumn) {
|
804
|
+
if (persistedColumn.width) {
|
805
|
+
col.width = persistedColumn.width;
|
806
|
+
}
|
807
|
+
col.pinned = persistedColumn.pinned ?? null;
|
808
|
+
col.rowGroup = persistedColumn.rowGroup ?? false;
|
809
|
+
col.rowGroupIndex = persistedColumn.rowGroupIndex ?? null;
|
810
|
+
col.aggFunc = persistedColumn.aggFunc ?? null;
|
811
|
+
col.pivot = persistedColumn.pivot ?? false;
|
812
|
+
col.hide = persistedColumn.hide ?? false;
|
813
|
+
}
|
814
|
+
return col;
|
815
|
+
})
|
816
|
+
: executionResult.result.columns.map(
|
817
|
+
(colName) =>
|
818
|
+
({
|
819
|
+
minWidth: 50,
|
820
|
+
sortable: true,
|
821
|
+
resizable: true,
|
822
|
+
field: colName,
|
823
|
+
flex: 1,
|
824
|
+
cellRenderer: QueryResultCellRenderer,
|
825
|
+
cellRendererParams: {
|
826
|
+
resultState: resultState,
|
827
|
+
tdsExecutionResult: executionResult,
|
828
|
+
},
|
829
|
+
}) as DataGridColumnDefinition,
|
830
|
+
);
|
831
|
+
const sideBar = isAdvancedModeEnabled ? ['columns', 'filters'] : null;
|
832
|
+
|
833
|
+
const rowData = executionResult.result.rows.map((_row, rowIdx) => {
|
834
|
+
const row: PlainObject = {};
|
835
|
+
const cols = executionResult.result.columns;
|
836
|
+
_row.values.forEach((value, colIdx) => {
|
837
|
+
// `ag-grid` shows `false` value as empty string so we have
|
838
|
+
// call `.toString()` to avoid this behavior.
|
839
|
+
// See https://github.com/finos/legend-studio/issues/1008
|
840
|
+
row[cols[colIdx] as string] = isBoolean(value) ? String(value) : value;
|
841
|
+
});
|
842
|
+
|
843
|
+
row.rowNumber = rowIdx;
|
844
|
+
return row;
|
845
|
+
});
|
846
|
+
const onSaveGridColumnState = (): void => {
|
847
|
+
if (!columnAPi) {
|
848
|
+
return;
|
849
|
+
}
|
850
|
+
resultState.setGridConfig({
|
851
|
+
columns: columnAPi.getColumnState(),
|
852
|
+
isPivotModeEnabled: columnAPi.isPivotMode(),
|
853
|
+
});
|
854
|
+
};
|
731
855
|
|
732
856
|
return (
|
733
857
|
<div className="query-builder__result__values__table">
|
@@ -736,47 +860,57 @@ const QueryBuilderGridResult = observer(
|
|
736
860
|
'ag-theme-balham-dark query-builder__result__tds-grid',
|
737
861
|
)}
|
738
862
|
>
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
863
|
+
{isAdvancedModeEnabled ? (
|
864
|
+
<DataGrid
|
865
|
+
rowData={rowData}
|
866
|
+
onGridReady={(params): void => {
|
867
|
+
setColumnApi(params.columnApi);
|
868
|
+
params.columnApi.setPivotMode(
|
869
|
+
resultState.gridConfig.isPivotModeEnabled,
|
870
|
+
);
|
871
|
+
}}
|
872
|
+
gridOptions={{
|
873
|
+
suppressScrollOnNewData: true,
|
874
|
+
getRowId: (data) => data.data.rowNumber,
|
875
|
+
rowSelection: 'multiple',
|
876
|
+
pivotPanelShow: 'always',
|
877
|
+
rowGroupPanelShow: 'always',
|
878
|
+
}}
|
879
|
+
// NOTE: when column definition changed, we need to force refresh the cell to make sure the cell renderer is updated
|
880
|
+
// See https://stackoverflow.com/questions/56341073/how-to-refresh-an-ag-grid-when-a-change-occurs-inside-a-custom-cell-renderer-com
|
881
|
+
onRowDataUpdated={(params) => {
|
882
|
+
params.api.refreshCells({ force: true });
|
883
|
+
}}
|
884
|
+
suppressFieldDotNotation={true}
|
885
|
+
suppressContextMenu={!isAdvancedModeEnabled}
|
886
|
+
columnDefs={colDefs}
|
887
|
+
sideBar={sideBar}
|
888
|
+
onColumnVisible={onSaveGridColumnState}
|
889
|
+
onColumnPinned={onSaveGridColumnState}
|
890
|
+
onColumnResized={onSaveGridColumnState}
|
891
|
+
onColumnRowGroupChanged={onSaveGridColumnState}
|
892
|
+
onColumnValueChanged={onSaveGridColumnState}
|
893
|
+
onColumnPivotChanged={onSaveGridColumnState}
|
894
|
+
onColumnPivotModeChanged={onSaveGridColumnState}
|
895
|
+
/>
|
896
|
+
) : (
|
897
|
+
<DataGrid
|
898
|
+
rowData={rowData}
|
899
|
+
gridOptions={{
|
900
|
+
suppressScrollOnNewData: true,
|
901
|
+
getRowId: (data) => data.data.rowNumber,
|
902
|
+
rowSelection: 'multiple',
|
903
|
+
}}
|
904
|
+
// NOTE: when column definition changed, we need to force refresh the cell to make sure the cell renderer is updated
|
905
|
+
// See https://stackoverflow.com/questions/56341073/how-to-refresh-an-ag-grid-when-a-change-occurs-inside-a-custom-cell-renderer-com
|
906
|
+
onRowDataUpdated={(params) => {
|
907
|
+
params.api.refreshCells({ force: true });
|
908
|
+
}}
|
909
|
+
suppressFieldDotNotation={true}
|
910
|
+
suppressContextMenu={!isAdvancedModeEnabled}
|
911
|
+
columnDefs={colDefs}
|
912
|
+
/>
|
913
|
+
)}
|
780
914
|
</div>
|
781
915
|
</div>
|
782
916
|
);
|
@@ -893,6 +1027,11 @@ export const QueryBuilderResultPanel = observer(
|
|
893
1027
|
const isQueryValid =
|
894
1028
|
!queryBuilderState.isQuerySupported || isSupportedQueryValid;
|
895
1029
|
|
1030
|
+
const isQueryValidForAdvancedMode =
|
1031
|
+
isQueryValid &&
|
1032
|
+
queryBuilderState.fetchStructureState.implementation instanceof
|
1033
|
+
QueryBuilderTDSState;
|
1034
|
+
|
896
1035
|
const runQuery = (): void => {
|
897
1036
|
resultState.setSelectedCells([]);
|
898
1037
|
resultState.pressedRunQuery.inProgress();
|
@@ -923,6 +1062,7 @@ export const QueryBuilderResultPanel = observer(
|
|
923
1062
|
);
|
924
1063
|
|
925
1064
|
const allowSettingPreviewLimit = queryBuilderState.isQuerySupported;
|
1065
|
+
const allowSettingAdvancedMode = queryBuilderState.isQuerySupported;
|
926
1066
|
|
927
1067
|
const copyExpression = (value: string): void => {
|
928
1068
|
applicationStore.clipboardService
|
@@ -995,6 +1135,13 @@ export const QueryBuilderResultPanel = observer(
|
|
995
1135
|
}
|
996
1136
|
};
|
997
1137
|
|
1138
|
+
const toggleIsAdvancedModeEnabled = (): void => {
|
1139
|
+
resultState.setExecutionResult(undefined);
|
1140
|
+
queryBuilderState.setIsAdvancedModeEnabled(
|
1141
|
+
!queryBuilderState.isAdvancedModeEnabled,
|
1142
|
+
);
|
1143
|
+
};
|
1144
|
+
|
998
1145
|
return (
|
999
1146
|
<div
|
1000
1147
|
data-testid={QUERY_BUILDER_TEST_ID.QUERY_BUILDER_RESULT_PANEL}
|
@@ -1071,6 +1218,38 @@ export const QueryBuilderResultPanel = observer(
|
|
1071
1218
|
)}
|
1072
1219
|
</div>
|
1073
1220
|
<div className="panel__header__actions query-builder__result__header__actions">
|
1221
|
+
{allowSettingAdvancedMode && (
|
1222
|
+
<div className="query-builder__result__advanced__mode">
|
1223
|
+
<div className="query-builder__result__advanced__mode__label">
|
1224
|
+
Advanced Mode
|
1225
|
+
<DocumentationLink
|
1226
|
+
title="The grid in advanced mode performs all operations like grouping, sorting, filtering, etc after initial query execution locally withought reaching out to server. This limits the number of rows to smaller number so they can fit in memory"
|
1227
|
+
documentationKey={
|
1228
|
+
QUERY_BUILDER_DOCUMENTATION_KEY.QUESTION_HOW_TO_USE_ADVANCED_GRID_MODE
|
1229
|
+
}
|
1230
|
+
/>
|
1231
|
+
</div>
|
1232
|
+
<button
|
1233
|
+
className={clsx(
|
1234
|
+
'query-builder__result__advanced__mode__toggler__btn',
|
1235
|
+
{
|
1236
|
+
'query-builder__result__advanced__mode__toggler__btn--toggled':
|
1237
|
+
queryBuilderState.isAdvancedModeEnabled,
|
1238
|
+
},
|
1239
|
+
)}
|
1240
|
+
disabled={!isQueryValidForAdvancedMode}
|
1241
|
+
onClick={toggleIsAdvancedModeEnabled}
|
1242
|
+
tabIndex={-1}
|
1243
|
+
>
|
1244
|
+
{queryBuilderState.isAdvancedModeEnabled ? (
|
1245
|
+
<CheckSquareIcon />
|
1246
|
+
) : (
|
1247
|
+
<SquareIcon />
|
1248
|
+
)}
|
1249
|
+
</button>
|
1250
|
+
</div>
|
1251
|
+
)}
|
1252
|
+
|
1074
1253
|
{allowSettingPreviewLimit && (
|
1075
1254
|
<div className="query-builder__result__limit">
|
1076
1255
|
<div className="query-builder__result__limit__label">
|
@@ -32,14 +32,12 @@ import {
|
|
32
32
|
MenuContentItem,
|
33
33
|
ModalFooterButton,
|
34
34
|
} from '@finos/legend-art';
|
35
|
-
import {
|
36
|
-
COLUMN_SORT_TYPE,
|
37
|
-
SortColumnState,
|
38
|
-
} from '../../stores/fetch-structure/tds/QueryResultSetModifierState.js';
|
35
|
+
import { SortColumnState } from '../../stores/fetch-structure/tds/QueryResultSetModifierState.js';
|
39
36
|
import { guaranteeNonNullable } from '@finos/legend-shared';
|
40
37
|
import { useApplicationStore } from '@finos/legend-application';
|
41
38
|
import type { QueryBuilderTDSState } from '../../stores/fetch-structure/tds/QueryBuilderTDSState.js';
|
42
39
|
import type { QueryBuilderTDSColumnState } from '../../stores/fetch-structure/tds/QueryBuilderTDSColumnState.js';
|
40
|
+
import { COLUMN_SORT_TYPE } from '../../graph/QueryBuilderMetaModelConst.js';
|
43
41
|
|
44
42
|
const ColumnSortEditor = observer(
|
45
43
|
(props: { tdsState: QueryBuilderTDSState; sortState: SortColumnState }) => {
|
@@ -66,9 +66,9 @@ import {
|
|
66
66
|
import { QUERY_BUILDER_PROJECTION_COLUMN_DND_TYPE } from '../../stores/fetch-structure/tds/projection/QueryBuilderProjectionColumnState.js';
|
67
67
|
import type { QueryBuilderTDSColumnState } from '../../stores/fetch-structure/tds/QueryBuilderTDSColumnState.js';
|
68
68
|
import type { QueryBuilderTDSState } from '../../stores/fetch-structure/tds/QueryBuilderTDSState.js';
|
69
|
-
import { COLUMN_SORT_TYPE } from '../../stores/fetch-structure/tds/QueryResultSetModifierState.js';
|
70
69
|
import { QUERY_BUILDER_TEST_ID } from '../../__lib__/QueryBuilderTesting.js';
|
71
70
|
import { QueryBuilderPanelIssueCountBadge } from '../shared/QueryBuilderPanelIssueCountBadge.js';
|
71
|
+
import { COLUMN_SORT_TYPE } from '../../graph/QueryBuilderMetaModelConst.js';
|
72
72
|
|
73
73
|
// helpers
|
74
74
|
const createWindowColumnState = (
|
@@ -105,6 +105,7 @@ export enum QUERY_BUILDER_SUPPORTED_FUNCTIONS {
|
|
105
105
|
TDS_GROUP_BY = 'meta::pure::tds::groupBy',
|
106
106
|
TDS_SORT = 'meta::pure::tds::sort',
|
107
107
|
TDS_TAKE = 'meta::pure::tds::take',
|
108
|
+
TDS_RESTRICT = 'meta::pure::tds::restrict',
|
108
109
|
TDS_FUNC = 'meta::pure::tds::func',
|
109
110
|
|
110
111
|
// filter
|
@@ -149,4 +150,28 @@ export enum QUERY_BUILDER_SUPPORTED_FUNCTIONS {
|
|
149
150
|
FROM = 'meta::pure::mapping::from',
|
150
151
|
CHECKED = 'meta::pure::dataQuality::checked',
|
151
152
|
MERGERUNTIMES = 'meta::pure::runtime::mergeRuntimes',
|
153
|
+
|
154
|
+
// TOTDS
|
155
|
+
TABLE_TO_TDS = 'meta::pure::tds::tableToTDS',
|
156
|
+
TABLE_REFERENCE = 'meta::relational::functions::database::tableReference',
|
157
|
+
}
|
158
|
+
|
159
|
+
export enum TDS_COLUMN_GETTER {
|
160
|
+
GET_STRING = 'getString',
|
161
|
+
GET_NUMBER = 'getNumber',
|
162
|
+
GET_INTEGER = 'getInteger',
|
163
|
+
GET_FLOAT = 'getFloat',
|
164
|
+
GET_DECIMAL = 'getDecimal',
|
165
|
+
GET_DATE = 'getDate',
|
166
|
+
GET_DATETIME = 'getDateTime',
|
167
|
+
GET_STRICTDATE = 'getStrictDate',
|
168
|
+
GET_BOOLEAN = 'getBoolean',
|
169
|
+
GET_ENUM = 'getEnum',
|
170
|
+
IS_NULL = 'isNull',
|
171
|
+
IS_NOT_NULL = 'isNotNull',
|
172
|
+
}
|
173
|
+
|
174
|
+
export enum COLUMN_SORT_TYPE {
|
175
|
+
ASC = 'ASC',
|
176
|
+
DESC = 'DESC',
|
152
177
|
}
|
package/src/index.ts
CHANGED
@@ -29,7 +29,10 @@ export { QueryBuilderNavigationBlocker } from './components/QueryBuilderNavigati
|
|
29
29
|
export { QueryBuilder } from './components/QueryBuilder.js';
|
30
30
|
export { QUERY_BUILDER_COMPONENT_ELEMENT_ID } from './components/QueryBuilderComponentElement.js';
|
31
31
|
export { QueryBuilderState } from './stores/QueryBuilderState.js';
|
32
|
-
|
32
|
+
export {
|
33
|
+
getTDSColumnDerivedProperyFromType,
|
34
|
+
buildTDSSortTypeExpression,
|
35
|
+
} from './stores/fetch-structure/tds/QueryBuilderTDSHelper.js';
|
33
36
|
export { QueryBuilderPropertySearchState } from './stores/explorer/QueryBuilderPropertySearchState.js';
|
34
37
|
export {
|
35
38
|
QueryBuilderClassSelector,
|
@@ -43,7 +46,11 @@ export {
|
|
43
46
|
type ServiceExecutionContext,
|
44
47
|
ServiceQueryBuilderState,
|
45
48
|
} from './stores/workflows/ServiceQueryBuilderState.js';
|
46
|
-
export {
|
49
|
+
export {
|
50
|
+
TDS_COLUMN_GETTER,
|
51
|
+
COLUMN_SORT_TYPE,
|
52
|
+
QUERY_BUILDER_SUPPORTED_FUNCTIONS,
|
53
|
+
} from './graph/QueryBuilderMetaModelConst.js';
|
47
54
|
export { getQueryBuilderGraphManagerExtension } from './graph-manager/protocol/pure/QueryBuilder_PureGraphManagerExtension.js';
|
48
55
|
export type { ServiceExecutionAnalysisResult } from './graph-manager/action/analytics/ServiceExecutionAnalysis.js';
|
49
56
|
export type { MappingRuntimeCompatibilityAnalysisResult } from './graph-manager/action/analytics/MappingRuntimeCompatibilityAnalysis.js';
|
@@ -29,12 +29,10 @@ import { QueryBuilderAggregateOperator_StdDev_Sample } from './fetch-structure/t
|
|
29
29
|
import { QueryBuilderAggregateOperator_Sum } from './fetch-structure/tds/aggregation/operators/QueryBuilderAggregateOperator_Sum.js';
|
30
30
|
import { QueryBuilderSimpleProjectionColumnState } from './fetch-structure/tds/projection/QueryBuilderProjectionColumnState.js';
|
31
31
|
import type { QueryBuilderState } from './QueryBuilderState.js';
|
32
|
-
import {
|
33
|
-
COLUMN_SORT_TYPE,
|
34
|
-
SortColumnState,
|
35
|
-
} from './fetch-structure/tds/QueryResultSetModifierState.js';
|
32
|
+
import { SortColumnState } from './fetch-structure/tds/QueryResultSetModifierState.js';
|
36
33
|
import type { QueryBuilderAggregateOperator } from './fetch-structure/tds/aggregation/QueryBuilderAggregateOperator.js';
|
37
34
|
import { QueryBuilderTDSState } from './fetch-structure/tds/QueryBuilderTDSState.js';
|
35
|
+
import { COLUMN_SORT_TYPE } from '../graph/QueryBuilderMetaModelConst.js';
|
38
36
|
|
39
37
|
const PREVIEW_DATA_TAKE_LIMIT = 10;
|
40
38
|
const PREVIEW_DATA_NON_NUMERIC_VALUE_COLUMN_NAME = 'Value';
|