@adaptabletools/adaptable 22.0.11 → 22.1.0-canary.1
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/index.css +19 -1
- package/index.css.map +1 -1
- package/package.json +3 -4
- package/src/AdaptableOptions/DashboardOptions.d.ts +2 -2
- package/src/AdaptableState/Common/AdaptablePredicate.js +1 -1
- package/src/AdaptableState/InitialState.d.ts +2 -2
- package/src/AdaptableState/LayoutState.d.ts +44 -0
- package/src/Api/CalendarApi.d.ts +15 -0
- package/src/Api/ColumnScopeApi.d.ts +5 -0
- package/src/Api/Implementation/CalendarApiImpl.d.ts +3 -0
- package/src/Api/Implementation/CalendarApiImpl.js +10 -0
- package/src/Api/Implementation/ColumnApiImpl.d.ts +1 -0
- package/src/Api/Implementation/ColumnApiImpl.js +14 -0
- package/src/Api/Implementation/ColumnScopeApiImpl.d.ts +1 -0
- package/src/Api/Implementation/ColumnScopeApiImpl.js +12 -0
- package/src/Api/Implementation/LayoutHelpers.js +12 -0
- package/src/Api/Internal/AlertInternalApi.js +4 -1
- package/src/Api/Internal/FormatColumnInternalApi.js +3 -3
- package/src/Strategy/FlashingCellModule.js +1 -0
- package/src/Strategy/PlusMinusModule.js +3 -3
- package/src/Strategy/SmartEditModule.js +1 -1
- package/src/Utilities/Constants/GeneralConstants.js +2 -1
- package/src/Utilities/ExpressionFunctions/booleanExpressionFunctions.d.ts +1 -1
- package/src/Utilities/ExpressionFunctions/booleanExpressionFunctions.js +41 -2
- package/src/Utilities/ExpressionFunctions/scalarExpressionFunctions.d.ts +1 -1
- package/src/Utilities/ExpressionFunctions/scalarExpressionFunctions.js +31 -2
- package/src/Utilities/Helpers/AdaptableHelper.js +30 -4
- package/src/Utilities/Services/Interface/IQueryLanguageService.d.ts +1 -0
- package/src/Utilities/Services/MetamodelService.js +18 -18
- package/src/Utilities/Services/QueryLanguageService.d.ts +2 -0
- package/src/Utilities/Services/QueryLanguageService.js +20 -8
- package/src/Utilities/Services/ValidationService.js +3 -1
- package/src/View/Components/EntityRulesEditor/index.js +1 -1
- package/src/View/Components/ModuleValueSelector/index.js +9 -1
- package/src/View/Components/ReorderDraggable/index.js +22 -36
- package/src/View/Components/ValueSelector/index.js +46 -50
- package/src/View/Dashboard/PinnedToolbarsSelector.js +1 -1
- package/src/View/Layout/Wizard/LayoutWizard.js +16 -1
- package/src/View/Layout/Wizard/sections/ColumnsSection.js +31 -19
- package/src/View/Layout/Wizard/sections/RowGroupingSection.js +1 -1
- package/src/View/Layout/Wizard/sections/RowSelectionSection.d.ts +8 -0
- package/src/View/Layout/Wizard/sections/RowSelectionSection.js +140 -0
- package/src/View/NamedQuery/Wizard/NamedQuerySettingsWizardSection.js +0 -1
- package/src/agGrid/AdaptableAgGrid.js +10 -0
- package/src/components/Dashboard/Dashboard.js +1 -1
- package/src/components/DragAndDropContext/ModuleManager.d.ts +1 -0
- package/src/components/DragAndDropContext/ModuleManager.js +12 -37
- package/src/components/DragAndDropContext/TabList.d.ts +11 -6
- package/src/components/DragAndDropContext/TabList.js +78 -36
- package/src/components/DragAndDropContext/UnusedPanel.js +10 -21
- package/src/components/ExpressionEditor/BaseEditorInput.d.ts +2 -0
- package/src/components/ExpressionEditor/BaseEditorInput.js +4 -0
- package/src/components/ExpressionEditor/EditorInput.d.ts +3 -1
- package/src/components/ExpressionEditor/EditorInput.js +20 -9
- package/src/components/ExpressionEditor/QueryBuilder/QueryBuilder.d.ts +2 -1
- package/src/components/ExpressionEditor/QueryBuilder/QueryBuilder.js +3 -12
- package/src/components/ExpressionEditor/QueryBuilder/QueryPredicateBuilder.js +17 -19
- package/src/components/ExpressionEditor/index.d.ts +2 -1
- package/src/components/ExpressionEditor/index.js +1 -1
- package/src/components/Tree/TreeDropdown/index.js +38 -27
- package/src/components/dnd/index.d.ts +3 -13
- package/src/components/dnd/index.js +4 -55
- package/src/env.js +2 -2
- package/src/layout-manager/src/LayoutManagerModel.d.ts +2 -1
- package/src/layout-manager/src/index.d.ts +10 -0
- package/src/layout-manager/src/index.js +156 -4
- package/src/layout-manager/src/normalizeLayoutModel.js +8 -0
- package/src/layout-manager/src/simplifyLayoutModel.js +6 -0
- package/src/metamodel/adaptable-metamodel-model.d.ts +22 -13
- package/src/metamodel/adaptable.metamodel.d.ts +3792 -5143
- package/src/metamodel/adaptable.metamodel.js +1 -1
- package/src/parser/src/parser.js +55 -1218
- package/src/parser/src/types.d.ts +5 -0
- package/src/types.d.ts +1 -1
- package/tsconfig.esm.tsbuildinfo +1 -1
|
@@ -5,7 +5,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
|
5
5
|
import OverlayTrigger from '../../OverlayTrigger';
|
|
6
6
|
import NotifyResize from '../../NotifyResize';
|
|
7
7
|
import Input from '../../Input';
|
|
8
|
-
import { TreeSelectionState, withSelectedLeafNodesOnly, } from '../../InfiniteTable';
|
|
8
|
+
import { TreeSelectionState, useDataSourceState, withSelectedLeafNodesOnly, } from '../../InfiniteTable';
|
|
9
9
|
import SimpleButton from '../../SimpleButton';
|
|
10
10
|
import { CheckBox } from '../../CheckBox';
|
|
11
11
|
import { useLatest } from '../../utils/useLatest';
|
|
@@ -59,35 +59,46 @@ const getLabelColumn = (field, { includeExpandCollapseButton }) => {
|
|
|
59
59
|
} }));
|
|
60
60
|
},
|
|
61
61
|
renderHeader: ({ dataSourceApi, api, allRowsSelected, someRowsSelected }) => {
|
|
62
|
-
|
|
63
|
-
const allFirstLevelCollapsed = dataSourceApi
|
|
64
|
-
.getOriginalDataArray()
|
|
65
|
-
.every((item) => !treeApi.isNodeExpanded([item.id]));
|
|
66
|
-
return (React.createElement(Flex, { flexDirection: 'row', alignItems: 'center', className: "twa:w-full", onMouseDown: (e) => {
|
|
67
|
-
// so we can keep the focus on the Grid
|
|
68
|
-
e.preventDefault();
|
|
69
|
-
} },
|
|
70
|
-
React.createElement(CheckBox, { checked: someRowsSelected && !allRowsSelected ? null : allRowsSelected, className: "twa:mr-2", onChange: () => {
|
|
71
|
-
if (allRowsSelected) {
|
|
72
|
-
dataSourceApi.treeApi.deselectAll();
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
dataSourceApi.treeApi.selectAll();
|
|
76
|
-
}
|
|
77
|
-
api.focus();
|
|
78
|
-
} }, allRowsSelected ? '(Deselect All)' : '(Select All)'),
|
|
79
|
-
React.createElement(Flex, { className: "twa:flex-1" }),
|
|
80
|
-
includeExpandCollapseButton ? (React.createElement(SimpleButton, { label: "toggle-expand-collapse", icon: allFirstLevelCollapsed ? 'expand-all' : 'collapse-all', onMouseDown: () => {
|
|
81
|
-
if (allFirstLevelCollapsed) {
|
|
82
|
-
dataSourceApi.treeApi.expandAll();
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
dataSourceApi.treeApi.collapseAll();
|
|
86
|
-
}
|
|
87
|
-
}, iconPosition: "end" })) : null));
|
|
62
|
+
return (React.createElement(CustomHeader, { dataSourceApi: dataSourceApi, api: api, allRowsSelected: allRowsSelected, someRowsSelected: someRowsSelected, includeExpandCollapseButton: includeExpandCollapseButton }));
|
|
88
63
|
},
|
|
89
64
|
};
|
|
90
65
|
};
|
|
66
|
+
function useAllFirstLevelCollapsed(treeApi) {
|
|
67
|
+
const { originalDataArray } = useDataSourceState((state) => {
|
|
68
|
+
return {
|
|
69
|
+
originalDataArray: state.originalDataArray,
|
|
70
|
+
treeExpandState: state.treeExpandState,
|
|
71
|
+
};
|
|
72
|
+
});
|
|
73
|
+
return originalDataArray.every((item) => !treeApi.isNodeExpanded([item.id]));
|
|
74
|
+
}
|
|
75
|
+
function CustomHeader({ dataSourceApi, api, allRowsSelected, someRowsSelected, includeExpandCollapseButton, }) {
|
|
76
|
+
const { treeApi } = dataSourceApi;
|
|
77
|
+
const allFirstLevelCollapsed = useAllFirstLevelCollapsed(treeApi);
|
|
78
|
+
const checked = someRowsSelected && !allRowsSelected ? null : allRowsSelected;
|
|
79
|
+
return (React.createElement(Flex, { flexDirection: 'row', alignItems: 'center', className: "twa:w-full", onMouseDown: (e) => {
|
|
80
|
+
// so we can keep the focus on the Grid
|
|
81
|
+
e.preventDefault();
|
|
82
|
+
} },
|
|
83
|
+
React.createElement(CheckBox, { checked: checked, className: "twa:mr-2", onChange: () => {
|
|
84
|
+
if (allRowsSelected) {
|
|
85
|
+
dataSourceApi.treeApi.deselectAll();
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
dataSourceApi.treeApi.selectAll();
|
|
89
|
+
}
|
|
90
|
+
api.focus();
|
|
91
|
+
} }, allRowsSelected ? '(Deselect All)' : '(Select All)'),
|
|
92
|
+
React.createElement(Flex, { className: "twa:flex-1" }),
|
|
93
|
+
includeExpandCollapseButton ? (React.createElement(SimpleButton, { label: "toggle-expand-collapse", icon: allFirstLevelCollapsed ? 'expand-all' : 'collapse-all', onMouseDown: () => {
|
|
94
|
+
if (allFirstLevelCollapsed) {
|
|
95
|
+
dataSourceApi.treeApi.expandAll();
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
dataSourceApi.treeApi.collapseAll();
|
|
99
|
+
}
|
|
100
|
+
}, iconPosition: "end" })) : null));
|
|
101
|
+
}
|
|
91
102
|
const sizeFull = {
|
|
92
103
|
width: '100%',
|
|
93
104
|
height: '100%',
|
|
@@ -1,13 +1,3 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
* We're doing all this because the placeholder is not correctly displayed in react-beautiful-dnd
|
|
5
|
-
* with React 19.
|
|
6
|
-
* So we make sure it properly occupies the space of the dragged item, so the
|
|
7
|
-
* container won't flicker when we're dragging an item (as the drag item receives
|
|
8
|
-
* position: fixed while dragging, so content does not have the initial height anymore, therefore,
|
|
9
|
-
* the placeholder is included, with the computed height of the dragging element)
|
|
10
|
-
*/
|
|
11
|
-
declare const Droppable: (props: DroppableProps) => React.JSX.Element;
|
|
12
|
-
declare const DragDropContext: (props: DragDropContextProps) => React.JSX.Element;
|
|
13
|
-
export { type DropResult, Draggable, Droppable, DragDropContext };
|
|
1
|
+
import { DragProxyMoveParams } from '@infinite-table/infinite-react';
|
|
2
|
+
export { DragDropProvider, DragList, useDragDropProvider, useDragListContext, DRAG_ITEM_ATTRIBUTE, type DragListProps, type DragDropSourceAndTarget, } from '@infinite-table/infinite-react';
|
|
3
|
+
export declare function defaultDragProxyMove({ proxyElement, dx, dy }: DragProxyMoveParams): void;
|
|
@@ -1,55 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
* We're doing all this because the placeholder is not correctly displayed in react-beautiful-dnd
|
|
6
|
-
* with React 19.
|
|
7
|
-
* So we make sure it properly occupies the space of the dragged item, so the
|
|
8
|
-
* container won't flicker when we're dragging an item (as the drag item receives
|
|
9
|
-
* position: fixed while dragging, so content does not have the initial height anymore, therefore,
|
|
10
|
-
* the placeholder is included, with the computed height of the dragging element)
|
|
11
|
-
*/
|
|
12
|
-
const Droppable = (props) => {
|
|
13
|
-
const children = props.children;
|
|
14
|
-
const { placeholderStyle } = React.useContext(AdaptableDDContext);
|
|
15
|
-
return (React.createElement(DNDDroppable, { ...props }, (provided, snapshot) => {
|
|
16
|
-
provided.placeholder = (React.createElement("div", { key: "placeholder", style: placeholderStyle || {
|
|
17
|
-
visibility: 'hidden',
|
|
18
|
-
pointerEvents: 'none',
|
|
19
|
-
height: 0,
|
|
20
|
-
} }));
|
|
21
|
-
return children(provided, snapshot);
|
|
22
|
-
}));
|
|
23
|
-
};
|
|
24
|
-
const queryAttr = 'data-rbd-draggable-id';
|
|
25
|
-
const AdaptableDDContext = React.createContext({
|
|
26
|
-
placeholderStyle: null,
|
|
27
|
-
});
|
|
28
|
-
const DragDropContext = (props) => {
|
|
29
|
-
const getDraggedDom = (draggableId) => {
|
|
30
|
-
const domQuery = `[${queryAttr}='${draggableId}']`;
|
|
31
|
-
const draggedDOM = document.querySelector(domQuery);
|
|
32
|
-
return draggedDOM;
|
|
33
|
-
};
|
|
34
|
-
const [placeholderStyle, setPlaceholderStyle] = useState(null);
|
|
35
|
-
const handleDragStart = (initial, provided) => {
|
|
36
|
-
props.onDragStart?.(initial, provided);
|
|
37
|
-
const draggedDOM = getDraggedDom(initial.draggableId);
|
|
38
|
-
if (!draggedDOM) {
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
const { clientHeight, clientWidth } = draggedDOM;
|
|
42
|
-
const computedStyle = window.getComputedStyle(draggedDOM);
|
|
43
|
-
setPlaceholderStyle({
|
|
44
|
-
height: clientHeight + parseFloat(computedStyle.marginTop) + parseFloat(computedStyle.marginBottom),
|
|
45
|
-
width: clientWidth,
|
|
46
|
-
});
|
|
47
|
-
};
|
|
48
|
-
const handleDragEnd = (result, provided) => {
|
|
49
|
-
props.onDragEnd?.(result, provided);
|
|
50
|
-
setPlaceholderStyle(null);
|
|
51
|
-
};
|
|
52
|
-
return (React.createElement(AdaptableDDContext.Provider, { value: { placeholderStyle } },
|
|
53
|
-
React.createElement(DDContext, { ...props, onDragStart: handleDragStart, onDragEnd: handleDragEnd })));
|
|
54
|
-
};
|
|
55
|
-
export { Draggable, Droppable, DragDropContext };
|
|
1
|
+
export { DragDropProvider, DragList, useDragDropProvider, useDragListContext, DRAG_ITEM_ATTRIBUTE, } from '@infinite-table/infinite-react';
|
|
2
|
+
export function defaultDragProxyMove({ proxyElement, dx, dy }) {
|
|
3
|
+
proxyElement.style.transform = `translate3d(${Math.round(dx)}px, ${Math.round(dy)}px, 0)`;
|
|
4
|
+
}
|
package/src/env.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export default {
|
|
2
2
|
NEXT_PUBLIC_INFINITE_TABLE_LICENSE_KEY: "StartDate=2021-06-29|EndDate=2030-01-01|Owner=Adaptable|Type=distribution|TS=1624971462479|C=137829811,1004007071,2756196225,1839832928,3994409405,636616862" || '',
|
|
3
|
-
PUBLISH_TIMESTAMP:
|
|
4
|
-
VERSION: "22.0.
|
|
3
|
+
PUBLISH_TIMESTAMP: 1776672459689 || Date.now(),
|
|
4
|
+
VERSION: "22.1.0-canary.1" || '--current-version--',
|
|
5
5
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ColumnSizingMap } from '../../AdaptableState/LayoutState';
|
|
1
|
+
import { ColumnSizingMap, LayoutRowSelection } from '../../AdaptableState/LayoutState';
|
|
2
2
|
import { XOR } from '../../Utilities/Extensions/TypeExtensions';
|
|
3
3
|
/**
|
|
4
4
|
* Defines how a Column is sorted
|
|
@@ -112,6 +112,7 @@ export interface BaseLayoutModel {
|
|
|
112
112
|
ColumnPinning?: {
|
|
113
113
|
[columnId: string]: 'left' | 'right';
|
|
114
114
|
};
|
|
115
|
+
RowSelection?: LayoutRowSelection | false;
|
|
115
116
|
/**
|
|
116
117
|
* Display Grand Total Row of the Pivot Table
|
|
117
118
|
*/
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ColumnState, GridApi, GridOptions, GridState } from 'ag-grid-enterprise';
|
|
2
2
|
import { PivotLayoutModel, TableLayoutModel } from './LayoutManagerModel';
|
|
3
3
|
import { LMEmitter } from './LMEmitter';
|
|
4
|
+
import { LayoutRowSelection } from '../../AdaptableState/LayoutState';
|
|
4
5
|
export declare const PIVOT_ANY_TOTAL_COL_TYPE = "pivotAnyTotal";
|
|
5
6
|
export declare const PIVOT_GRAND_TOTAL_COL_TYPE = "pivotGrandTotal";
|
|
6
7
|
export declare const PIVOT_COLUMN_TOTAL_COL_TYPE = "pivotColumnTotal";
|
|
@@ -9,6 +10,7 @@ export type LayoutManagerOptions = {
|
|
|
9
10
|
gridApi: GridApi;
|
|
10
11
|
debugId: string;
|
|
11
12
|
layoutChangeDebounce?: number;
|
|
13
|
+
initialRowSelection?: GridOptions['rowSelection'];
|
|
12
14
|
};
|
|
13
15
|
type ApplyLayoutOptions = {
|
|
14
16
|
skipApplyRowGroupsExpandedState?: boolean;
|
|
@@ -26,6 +28,7 @@ export declare class LayoutManager<DATA_TYPE = any> extends LMEmitter {
|
|
|
26
28
|
private suppressGlobalAgGridEventListener;
|
|
27
29
|
private supressGlobalAgGridEventTimeoutId;
|
|
28
30
|
private layoutManagerDebugId;
|
|
31
|
+
private initialRowSelection;
|
|
29
32
|
constructor(options: LayoutManagerOptions);
|
|
30
33
|
destroy(): void;
|
|
31
34
|
private setupEvents;
|
|
@@ -69,6 +72,13 @@ export declare class LayoutManager<DATA_TYPE = any> extends LMEmitter {
|
|
|
69
72
|
private getLayoutDetailsAsString;
|
|
70
73
|
applyColumnDefsChanges(layout: TableLayoutModel | PivotLayoutModel): boolean;
|
|
71
74
|
private applyColumnSizingColumnDefsChanges;
|
|
75
|
+
static readonly SELECTION_COLUMN_ID = "ag-Grid-SelectionColumn";
|
|
76
|
+
static getGridOptionForRowSelectionFromLayout(layoutRowSelection: LayoutRowSelection | false | undefined, baseGridRowSelection: GridOptions['rowSelection']): GridOptions['rowSelection'] | undefined;
|
|
77
|
+
static isSelectionColumnInNonFirstPosition(tableColumns: string[] | undefined): boolean;
|
|
78
|
+
static shouldUnlockSelectionColumnPosition(layout: TableLayoutModel): boolean;
|
|
79
|
+
private ensureSelectionColumnPositionUnlocked;
|
|
80
|
+
private getRowSelectionFromGrid;
|
|
81
|
+
private applyRowSelection;
|
|
72
82
|
private applyTableLayout;
|
|
73
83
|
private getRowGroupNodePathsAs;
|
|
74
84
|
applyRowGroupValues(RowGroupValues: TableLayoutModel['RowGroupValues'], rowGroupedColumns: string[]): void;
|
|
@@ -138,6 +138,19 @@ function getDefaultColumnSizeStateForColDef(colId, colDef, options) {
|
|
|
138
138
|
}
|
|
139
139
|
return undefined;
|
|
140
140
|
}
|
|
141
|
+
function adjustColumnIdsForSelection(columnIds, layout) {
|
|
142
|
+
const selectionColPinning = layout.ColumnPinning?.[LayoutManager.SELECTION_COLUMN_ID];
|
|
143
|
+
if ((layout.RowSelection || selectionColPinning) &&
|
|
144
|
+
!columnIds.includes(LayoutManager.SELECTION_COLUMN_ID)) {
|
|
145
|
+
if (selectionColPinning === 'right') {
|
|
146
|
+
columnIds = [...columnIds, LayoutManager.SELECTION_COLUMN_ID];
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
columnIds = [LayoutManager.SELECTION_COLUMN_ID, ...columnIds];
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return columnIds;
|
|
153
|
+
}
|
|
141
154
|
export class LayoutManager extends LMEmitter {
|
|
142
155
|
gridApi;
|
|
143
156
|
fieldsToIds = {};
|
|
@@ -151,6 +164,7 @@ export class LayoutManager extends LMEmitter {
|
|
|
151
164
|
suppressGlobalAgGridEventListener = false;
|
|
152
165
|
supressGlobalAgGridEventTimeoutId = null;
|
|
153
166
|
layoutManagerDebugId;
|
|
167
|
+
initialRowSelection;
|
|
154
168
|
constructor(options) {
|
|
155
169
|
super({ debugId: options.debugId });
|
|
156
170
|
this.layoutChangeDebounce = options.layoutChangeDebounce ?? 0;
|
|
@@ -159,6 +173,7 @@ export class LayoutManager extends LMEmitter {
|
|
|
159
173
|
wait: this.layoutChangeDebounce,
|
|
160
174
|
}).bind(this);
|
|
161
175
|
}
|
|
176
|
+
this.initialRowSelection = options.initialRowSelection;
|
|
162
177
|
this.setOptions(options);
|
|
163
178
|
// this ensures the grand total columns are positioned correctly (before/after) even when changed at runtime
|
|
164
179
|
// see https://www.ag-grid.com/react-data-grid/pivoting-column-groups/#changing-data-filters-and-configurations
|
|
@@ -400,6 +415,7 @@ export class LayoutManager extends LMEmitter {
|
|
|
400
415
|
PivotGroupedColumns: layout.RowGroupedColumns,
|
|
401
416
|
PivotAggregationColumns: layout.TableAggregationColumns,
|
|
402
417
|
GrandTotalRow: layout.GrandTotalRow,
|
|
418
|
+
RowSelection: layout.RowSelection,
|
|
403
419
|
PivotExpandLevel: prevLayout?.PivotExpandLevel ?? -1,
|
|
404
420
|
};
|
|
405
421
|
if (storePivotResultColumns) {
|
|
@@ -431,7 +447,6 @@ export class LayoutManager extends LMEmitter {
|
|
|
431
447
|
}
|
|
432
448
|
getUndecidedLayoutModelFromGrid(columnState) {
|
|
433
449
|
let TableColumns = columnState.map((c) => c.colId);
|
|
434
|
-
// .filter((colId) => colId !== 'ag-Grid-SelectionColumn');
|
|
435
450
|
let ColumnSorts = [];
|
|
436
451
|
const RowGroupedColumns = [];
|
|
437
452
|
let RowGroupValues = undefined;
|
|
@@ -739,6 +754,7 @@ export class LayoutManager extends LMEmitter {
|
|
|
739
754
|
GrandTotalRow: this.gridApi.getGridOption('grandTotalRow'),
|
|
740
755
|
SuppressAggFuncInHeader: this.gridApi.getGridOption('suppressAggFuncInHeader'),
|
|
741
756
|
RowGroupDisplayType: this.gridApi.getGridOption('groupDisplayType') === 'multipleColumns' ? 'multi' : 'single',
|
|
757
|
+
RowSelection: this.getRowSelectionFromGrid(),
|
|
742
758
|
});
|
|
743
759
|
return layout;
|
|
744
760
|
}
|
|
@@ -806,13 +822,15 @@ export class LayoutManager extends LMEmitter {
|
|
|
806
822
|
layout.TableColumns = layout.TableColumns.filter((colId) => colId != undefined);
|
|
807
823
|
layout = normalizeTableLayoutModel(layout, { isTree: _options?.isTree ?? false });
|
|
808
824
|
const agGridState = {};
|
|
809
|
-
const columnIds = getColumnOrderIdsForAllColDefs(layout.TableColumns, colDefs);
|
|
825
|
+
const columnIds = adjustColumnIdsForSelection(getColumnOrderIdsForAllColDefs(layout.TableColumns, colDefs), layout);
|
|
810
826
|
agGridState.columnOrder = {
|
|
811
827
|
orderedColIds: columnIds,
|
|
812
828
|
};
|
|
813
829
|
const flatColDefs = flattenColDefs(colDefs);
|
|
814
830
|
const colDefsById = new Map(flatColDefs.map((colDef) => [colDef.colId ?? colDef.field, colDef]));
|
|
815
831
|
const getColDef = (colId) => colDefsById.get(colId);
|
|
832
|
+
// TODO to implement support for row selection in server-side row model
|
|
833
|
+
// agGridState.rowSelection = { ... }
|
|
816
834
|
agGridState.columnVisibility = {
|
|
817
835
|
hiddenColIds: flatColDefs
|
|
818
836
|
.filter((colDef) => {
|
|
@@ -1101,6 +1119,7 @@ export class LayoutManager extends LMEmitter {
|
|
|
1101
1119
|
else {
|
|
1102
1120
|
this.gridApi.setGridOption('grandTotalRow', null);
|
|
1103
1121
|
}
|
|
1122
|
+
this.applyRowSelection(layout);
|
|
1104
1123
|
this.applyColumnDefsChanges(layout);
|
|
1105
1124
|
if (isPivotLayoutModel(layout)) {
|
|
1106
1125
|
try {
|
|
@@ -1158,8 +1177,131 @@ export class LayoutManager extends LMEmitter {
|
|
|
1158
1177
|
}
|
|
1159
1178
|
return false;
|
|
1160
1179
|
}
|
|
1180
|
+
static SELECTION_COLUMN_ID = 'ag-Grid-SelectionColumn';
|
|
1181
|
+
static getGridOptionForRowSelectionFromLayout(layoutRowSelection, baseGridRowSelection) {
|
|
1182
|
+
if (layoutRowSelection === false) {
|
|
1183
|
+
return undefined;
|
|
1184
|
+
}
|
|
1185
|
+
if (layoutRowSelection == null) {
|
|
1186
|
+
return baseGridRowSelection;
|
|
1187
|
+
}
|
|
1188
|
+
const current = baseGridRowSelection && typeof baseGridRowSelection !== 'string'
|
|
1189
|
+
? baseGridRowSelection
|
|
1190
|
+
: {};
|
|
1191
|
+
const updated = { ...current };
|
|
1192
|
+
if (layoutRowSelection.Mode != null) {
|
|
1193
|
+
updated.mode = layoutRowSelection.Mode;
|
|
1194
|
+
}
|
|
1195
|
+
if (layoutRowSelection.Checkboxes != null) {
|
|
1196
|
+
updated.checkboxes = layoutRowSelection.Checkboxes;
|
|
1197
|
+
}
|
|
1198
|
+
if (layoutRowSelection.GroupSelectMode != null) {
|
|
1199
|
+
updated.groupSelects = layoutRowSelection.GroupSelectMode;
|
|
1200
|
+
}
|
|
1201
|
+
if (layoutRowSelection.SelectAllMode != null) {
|
|
1202
|
+
updated.selectAll = layoutRowSelection.SelectAllMode;
|
|
1203
|
+
}
|
|
1204
|
+
if (layoutRowSelection.HeaderCheckbox != null) {
|
|
1205
|
+
updated.headerCheckbox = layoutRowSelection.HeaderCheckbox;
|
|
1206
|
+
}
|
|
1207
|
+
if (layoutRowSelection.EnableClickSelection != null) {
|
|
1208
|
+
updated.enableClickSelection = layoutRowSelection.EnableClickSelection;
|
|
1209
|
+
}
|
|
1210
|
+
if (layoutRowSelection.CheckboxInGroupColumn != null) {
|
|
1211
|
+
updated.checkboxLocation = layoutRowSelection.CheckboxInGroupColumn
|
|
1212
|
+
? 'autoGroupColumn'
|
|
1213
|
+
: 'selectionColumn';
|
|
1214
|
+
}
|
|
1215
|
+
return updated;
|
|
1216
|
+
}
|
|
1217
|
+
static isSelectionColumnInNonFirstPosition(tableColumns) {
|
|
1218
|
+
if (!tableColumns) {
|
|
1219
|
+
return false;
|
|
1220
|
+
}
|
|
1221
|
+
const index = tableColumns.indexOf(LayoutManager.SELECTION_COLUMN_ID);
|
|
1222
|
+
return index > 0;
|
|
1223
|
+
}
|
|
1224
|
+
static shouldUnlockSelectionColumnPosition(layout) {
|
|
1225
|
+
const tableColumns = layout.TableColumns;
|
|
1226
|
+
if (!tableColumns) {
|
|
1227
|
+
return false;
|
|
1228
|
+
}
|
|
1229
|
+
const index = tableColumns.indexOf(LayoutManager.SELECTION_COLUMN_ID);
|
|
1230
|
+
if (index > 0) {
|
|
1231
|
+
return true;
|
|
1232
|
+
}
|
|
1233
|
+
const columnPinning = layout.ColumnPinning;
|
|
1234
|
+
if (columnPinning && columnPinning[LayoutManager.SELECTION_COLUMN_ID]) {
|
|
1235
|
+
return true;
|
|
1236
|
+
}
|
|
1237
|
+
return false;
|
|
1238
|
+
}
|
|
1239
|
+
ensureSelectionColumnPositionUnlocked(layout) {
|
|
1240
|
+
if (LayoutManager.shouldUnlockSelectionColumnPosition(layout)) {
|
|
1241
|
+
const current = this.gridApi.getGridOption('selectionColumnDef');
|
|
1242
|
+
if (!current || current.lockPosition !== false) {
|
|
1243
|
+
this.gridApi.setGridOption('selectionColumnDef', {
|
|
1244
|
+
...current,
|
|
1245
|
+
lockPosition: false,
|
|
1246
|
+
});
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
getRowSelectionFromGrid() {
|
|
1251
|
+
const gridRowSelection = this.gridApi.getGridOption('rowSelection');
|
|
1252
|
+
if (!gridRowSelection || typeof gridRowSelection === 'string') {
|
|
1253
|
+
return this.currentLayout?.RowSelection === false ? false : undefined;
|
|
1254
|
+
}
|
|
1255
|
+
const rs = gridRowSelection;
|
|
1256
|
+
const result = {
|
|
1257
|
+
Mode: rs.mode ?? 'singleRow',
|
|
1258
|
+
};
|
|
1259
|
+
if (rs.checkboxes != null) {
|
|
1260
|
+
result.Checkboxes = rs.checkboxes;
|
|
1261
|
+
}
|
|
1262
|
+
if (rs.mode === 'multiRow' && rs.groupSelects != null) {
|
|
1263
|
+
result.GroupSelectMode = rs.groupSelects;
|
|
1264
|
+
}
|
|
1265
|
+
if (rs.mode === 'multiRow' && rs.selectAll != null) {
|
|
1266
|
+
result.SelectAllMode = rs.selectAll;
|
|
1267
|
+
}
|
|
1268
|
+
if (rs.mode === 'multiRow' && rs.headerCheckbox != null) {
|
|
1269
|
+
result.HeaderCheckbox = rs.headerCheckbox;
|
|
1270
|
+
}
|
|
1271
|
+
if (rs.enableClickSelection != null) {
|
|
1272
|
+
result.EnableClickSelection =
|
|
1273
|
+
rs.enableClickSelection;
|
|
1274
|
+
}
|
|
1275
|
+
if (rs.checkboxLocation != null) {
|
|
1276
|
+
result.CheckboxInGroupColumn = rs.checkboxLocation === 'autoGroupColumn';
|
|
1277
|
+
}
|
|
1278
|
+
return result;
|
|
1279
|
+
}
|
|
1280
|
+
applyRowSelection(layout) {
|
|
1281
|
+
const rowSelection = LayoutManager.getGridOptionForRowSelectionFromLayout(layout.RowSelection, this.initialRowSelection);
|
|
1282
|
+
const prevRowSelection = this.gridApi.getGridOption('rowSelection');
|
|
1283
|
+
this.gridApi.setGridOption('rowSelection', rowSelection);
|
|
1284
|
+
// AG Grid does not always refresh already-rendered cells in the selection
|
|
1285
|
+
// column when `rowSelection.checkboxes` is changed at runtime via setGridOption
|
|
1286
|
+
// (e.g. toggling `checkboxes` or `headerCheckbox`).
|
|
1287
|
+
// In the React wrapper this is masked by React-driven re-renders, but in the vanilla integration
|
|
1288
|
+
// the selection column keeps showing stale content until a manual
|
|
1289
|
+
// `refreshCells` is triggered. We force the refresh here so
|
|
1290
|
+
// all integrations behave consistently.
|
|
1291
|
+
if (typeof prevRowSelection === 'object' &&
|
|
1292
|
+
typeof rowSelection === 'object' &&
|
|
1293
|
+
rowSelection.checkboxes !== prevRowSelection.checkboxes) {
|
|
1294
|
+
const selectionColumn = this.gridApi.getColumn(LayoutManager.SELECTION_COLUMN_ID);
|
|
1295
|
+
if (selectionColumn) {
|
|
1296
|
+
this.gridApi.refreshCells({
|
|
1297
|
+
columns: [LayoutManager.SELECTION_COLUMN_ID],
|
|
1298
|
+
});
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1161
1302
|
applyTableLayout(layout, options) {
|
|
1162
1303
|
this.withSuppressColumnAnimation(() => {
|
|
1304
|
+
this.ensureSelectionColumnPositionUnlocked(layout);
|
|
1163
1305
|
// if we apply the state here, before calling setGridOption for groupDisplayType
|
|
1164
1306
|
// the order is not always correctly applied
|
|
1165
1307
|
// this.gridApi.applyColumnState(state);
|
|
@@ -1477,10 +1619,20 @@ export class LayoutManager extends LMEmitter {
|
|
|
1477
1619
|
computeColumnOrderAndVisibility(layout, columnState) {
|
|
1478
1620
|
const visibility = layout.ColumnVisibility || {};
|
|
1479
1621
|
const columnOrderSet = new Set(layout.TableColumns);
|
|
1480
|
-
const isColHidden = (colId) =>
|
|
1622
|
+
const isColHidden = (colId) => {
|
|
1623
|
+
if (visibility[colId] === false) {
|
|
1624
|
+
return true;
|
|
1625
|
+
}
|
|
1626
|
+
// for the selection column, return true even
|
|
1627
|
+
// if not explicitly listed in the TableColumns
|
|
1628
|
+
if (colId === LayoutManager.SELECTION_COLUMN_ID && layout.RowSelection) {
|
|
1629
|
+
return false;
|
|
1630
|
+
}
|
|
1631
|
+
return !columnOrderSet.has(colId);
|
|
1632
|
+
};
|
|
1481
1633
|
columnState = columnState ?? {};
|
|
1482
1634
|
columnState.applyOrder = true;
|
|
1483
|
-
const columnIds = getColumnOrderIdsForAllColDefs(layout.TableColumns, this.gridApi.getColumnDefs());
|
|
1635
|
+
const columnIds = adjustColumnIdsForSelection(getColumnOrderIdsForAllColDefs(layout.TableColumns, this.gridApi.getColumnDefs()), layout);
|
|
1484
1636
|
columnState.state = columnIds.map((columnId) => {
|
|
1485
1637
|
return {
|
|
1486
1638
|
colId: columnId,
|
|
@@ -35,6 +35,10 @@ export function normalizeTableLayoutModel(layout, options) {
|
|
|
35
35
|
// make it an own property
|
|
36
36
|
layout.GrandTotalRow = undefined;
|
|
37
37
|
}
|
|
38
|
+
if (!('RowSelection' in layout)) {
|
|
39
|
+
// make it an own property
|
|
40
|
+
layout.RowSelection = undefined;
|
|
41
|
+
}
|
|
38
42
|
const ColumnOrderSet = new Set(layout.TableColumns);
|
|
39
43
|
if (layout.RowGroupedColumns && layout.RowGroupedColumns.length && layout.TableColumns) {
|
|
40
44
|
// the layout.TableColumns might not include the group columns
|
|
@@ -168,6 +172,10 @@ export function normalizePivotLayoutModel(layout) {
|
|
|
168
172
|
// make it an own property
|
|
169
173
|
layout.PivotColumnTotal = undefined;
|
|
170
174
|
}
|
|
175
|
+
if (!('RowSelection' in layout)) {
|
|
176
|
+
// make it an own property
|
|
177
|
+
layout.RowSelection = undefined;
|
|
178
|
+
}
|
|
171
179
|
// if (layout.PivotGroupedColumns && layout.PivotGroupedColumns.length) {
|
|
172
180
|
layout.RowGroupDisplayType = layout.RowGroupDisplayType || 'single';
|
|
173
181
|
// }
|
|
@@ -8,6 +8,9 @@ export function simplifyTableLayoutModel(layout) {
|
|
|
8
8
|
if (layout.ColumnSizing && !Object.keys(layout.ColumnSizing).length) {
|
|
9
9
|
delete layout.ColumnSizing;
|
|
10
10
|
}
|
|
11
|
+
if (layout.RowSelection == undefined) {
|
|
12
|
+
delete layout.RowSelection;
|
|
13
|
+
}
|
|
11
14
|
if (layout.ColumnSorts && !layout.ColumnSorts.length) {
|
|
12
15
|
delete layout.ColumnSorts;
|
|
13
16
|
}
|
|
@@ -72,6 +75,9 @@ export function simplifyPivotLayoutModel(layout) {
|
|
|
72
75
|
if (layout.ColumnSizing && !Object.keys(layout.ColumnSizing).length) {
|
|
73
76
|
delete layout.ColumnSizing;
|
|
74
77
|
}
|
|
78
|
+
if (layout.RowSelection == undefined) {
|
|
79
|
+
delete layout.RowSelection;
|
|
80
|
+
}
|
|
75
81
|
if (!layout.SuppressAggFuncInHeader) {
|
|
76
82
|
delete layout.SuppressAggFuncInHeader;
|
|
77
83
|
}
|
|
@@ -1,19 +1,28 @@
|
|
|
1
1
|
export type AdaptableMetamodel = Record<string, MetamodelItem>;
|
|
2
2
|
export interface MetamodelItem {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
/** Item kind: 'A' (type alias), 'I' (interface), 'C' (class) */
|
|
4
|
+
k: 'A' | 'I' | 'C';
|
|
5
|
+
/** Description (only present for noCode-tagged items) */
|
|
6
|
+
d?: string;
|
|
7
|
+
/** Properties of this item */
|
|
8
|
+
p?: MetamodelItemProperty[];
|
|
7
9
|
}
|
|
8
10
|
export interface MetamodelItemProperty {
|
|
9
|
-
name
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
/** Property name */
|
|
12
|
+
n: string;
|
|
13
|
+
/** Property kind / type */
|
|
14
|
+
k: MetamodelItemPropertyKind;
|
|
15
|
+
/** Description (only present for noCode-tagged properties) */
|
|
16
|
+
d?: string;
|
|
17
|
+
/** UI label override for display */
|
|
18
|
+
l?: string;
|
|
19
|
+
/** Reference to another MetamodelItem key */
|
|
20
|
+
r?: string;
|
|
21
|
+
/** Whether the property is optional */
|
|
22
|
+
o?: boolean;
|
|
23
|
+
/** Grid Info role: 'item' or 'container' */
|
|
24
|
+
g?: 'item' | 'container';
|
|
25
|
+
/** No-Code role: 'item' or 'container' */
|
|
26
|
+
nC?: 'item' | 'container';
|
|
18
27
|
}
|
|
19
28
|
export type MetamodelItemPropertyKind = 'R' | 'n' | 's' | 'b' | 'd' | 'f' | 'a' | 'i' | 'u';
|