@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.
Files changed (75) hide show
  1. package/index.css +19 -1
  2. package/index.css.map +1 -1
  3. package/package.json +3 -4
  4. package/src/AdaptableOptions/DashboardOptions.d.ts +2 -2
  5. package/src/AdaptableState/Common/AdaptablePredicate.js +1 -1
  6. package/src/AdaptableState/InitialState.d.ts +2 -2
  7. package/src/AdaptableState/LayoutState.d.ts +44 -0
  8. package/src/Api/CalendarApi.d.ts +15 -0
  9. package/src/Api/ColumnScopeApi.d.ts +5 -0
  10. package/src/Api/Implementation/CalendarApiImpl.d.ts +3 -0
  11. package/src/Api/Implementation/CalendarApiImpl.js +10 -0
  12. package/src/Api/Implementation/ColumnApiImpl.d.ts +1 -0
  13. package/src/Api/Implementation/ColumnApiImpl.js +14 -0
  14. package/src/Api/Implementation/ColumnScopeApiImpl.d.ts +1 -0
  15. package/src/Api/Implementation/ColumnScopeApiImpl.js +12 -0
  16. package/src/Api/Implementation/LayoutHelpers.js +12 -0
  17. package/src/Api/Internal/AlertInternalApi.js +4 -1
  18. package/src/Api/Internal/FormatColumnInternalApi.js +3 -3
  19. package/src/Strategy/FlashingCellModule.js +1 -0
  20. package/src/Strategy/PlusMinusModule.js +3 -3
  21. package/src/Strategy/SmartEditModule.js +1 -1
  22. package/src/Utilities/Constants/GeneralConstants.js +2 -1
  23. package/src/Utilities/ExpressionFunctions/booleanExpressionFunctions.d.ts +1 -1
  24. package/src/Utilities/ExpressionFunctions/booleanExpressionFunctions.js +41 -2
  25. package/src/Utilities/ExpressionFunctions/scalarExpressionFunctions.d.ts +1 -1
  26. package/src/Utilities/ExpressionFunctions/scalarExpressionFunctions.js +31 -2
  27. package/src/Utilities/Helpers/AdaptableHelper.js +30 -4
  28. package/src/Utilities/Services/Interface/IQueryLanguageService.d.ts +1 -0
  29. package/src/Utilities/Services/MetamodelService.js +18 -18
  30. package/src/Utilities/Services/QueryLanguageService.d.ts +2 -0
  31. package/src/Utilities/Services/QueryLanguageService.js +20 -8
  32. package/src/Utilities/Services/ValidationService.js +3 -1
  33. package/src/View/Components/EntityRulesEditor/index.js +1 -1
  34. package/src/View/Components/ModuleValueSelector/index.js +9 -1
  35. package/src/View/Components/ReorderDraggable/index.js +22 -36
  36. package/src/View/Components/ValueSelector/index.js +46 -50
  37. package/src/View/Dashboard/PinnedToolbarsSelector.js +1 -1
  38. package/src/View/Layout/Wizard/LayoutWizard.js +16 -1
  39. package/src/View/Layout/Wizard/sections/ColumnsSection.js +31 -19
  40. package/src/View/Layout/Wizard/sections/RowGroupingSection.js +1 -1
  41. package/src/View/Layout/Wizard/sections/RowSelectionSection.d.ts +8 -0
  42. package/src/View/Layout/Wizard/sections/RowSelectionSection.js +140 -0
  43. package/src/View/NamedQuery/Wizard/NamedQuerySettingsWizardSection.js +0 -1
  44. package/src/agGrid/AdaptableAgGrid.js +10 -0
  45. package/src/components/Dashboard/Dashboard.js +1 -1
  46. package/src/components/DragAndDropContext/ModuleManager.d.ts +1 -0
  47. package/src/components/DragAndDropContext/ModuleManager.js +12 -37
  48. package/src/components/DragAndDropContext/TabList.d.ts +11 -6
  49. package/src/components/DragAndDropContext/TabList.js +78 -36
  50. package/src/components/DragAndDropContext/UnusedPanel.js +10 -21
  51. package/src/components/ExpressionEditor/BaseEditorInput.d.ts +2 -0
  52. package/src/components/ExpressionEditor/BaseEditorInput.js +4 -0
  53. package/src/components/ExpressionEditor/EditorInput.d.ts +3 -1
  54. package/src/components/ExpressionEditor/EditorInput.js +20 -9
  55. package/src/components/ExpressionEditor/QueryBuilder/QueryBuilder.d.ts +2 -1
  56. package/src/components/ExpressionEditor/QueryBuilder/QueryBuilder.js +3 -12
  57. package/src/components/ExpressionEditor/QueryBuilder/QueryPredicateBuilder.js +17 -19
  58. package/src/components/ExpressionEditor/index.d.ts +2 -1
  59. package/src/components/ExpressionEditor/index.js +1 -1
  60. package/src/components/Tree/TreeDropdown/index.js +38 -27
  61. package/src/components/dnd/index.d.ts +3 -13
  62. package/src/components/dnd/index.js +4 -55
  63. package/src/env.js +2 -2
  64. package/src/layout-manager/src/LayoutManagerModel.d.ts +2 -1
  65. package/src/layout-manager/src/index.d.ts +10 -0
  66. package/src/layout-manager/src/index.js +156 -4
  67. package/src/layout-manager/src/normalizeLayoutModel.js +8 -0
  68. package/src/layout-manager/src/simplifyLayoutModel.js +6 -0
  69. package/src/metamodel/adaptable-metamodel-model.d.ts +22 -13
  70. package/src/metamodel/adaptable.metamodel.d.ts +3792 -5143
  71. package/src/metamodel/adaptable.metamodel.js +1 -1
  72. package/src/parser/src/parser.js +55 -1218
  73. package/src/parser/src/types.d.ts +5 -0
  74. package/src/types.d.ts +1 -1
  75. 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
- const { treeApi } = dataSourceApi;
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 * as React from 'react';
2
- import { DropResult, Draggable, DroppableProps, DragDropContextProps } from '@adaptabletools/react-beautiful-dnd';
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
- import * as React from 'react';
2
- import { DragDropContext as DDContext, Draggable, Droppable as DNDDroppable, } from '@adaptabletools/react-beautiful-dnd';
3
- import { useState } from 'react';
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: 1775828182886 || Date.now(),
4
- VERSION: "22.0.11" || '--current-version--',
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) => visibility[colId] === false || !columnOrderSet.has(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
- name: string;
4
- kind: 'A' | 'I' | 'C';
5
- desc: string;
6
- props?: MetamodelItemProperty[];
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: string;
10
- kind: MetamodelItemPropertyKind;
11
- desc: string;
12
- uiLabel?: string;
13
- ref?: string;
14
- isOpt?: boolean;
15
- defVal?: unknown;
16
- gridInfo?: 'item' | 'container';
17
- noCode?: 'item' | 'container';
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';